bool VolMeshIO::fitmesh(VolMesh* vm, const AABB& toBox) { if(!toBox.isValid()) return false; AABB curBox = vm->computeAABB(); vec3f s = vec3f::div(toBox.extent(), curBox.extent()); double minScaleFactor = MATHMIN(MATHMIN(s.x, s.y), s.z); vec3d scale(minScaleFactor); vec3f t = toBox.lower() - curBox.lower(); vec3d translate(t.x, t.y, t.z); //first translate all nodes for(U32 i=0; i < vm->countNodes(); i++) { NODE& p = vm->nodeAt(i); //translate p.pos = p.pos + translate; p.restpos = p.restpos + translate; //scale p.pos = p.pos * minScaleFactor; p.restpos = p.restpos * minScaleFactor; } return true; }
void AABBRenderer::add(const AABB& aabb) { AABBData data; data.middle = aabb.middle(); data.extent = aabb.extent(); m_aabbs.push_back(data); }
bool PhysicsCollision::sweptCCD(vector<AABB*> boxes, Octree* octree, float &timeOfImpact) { /****************************************************** * Function Name: sweptCCD() * Programmer: Josh Archer * * Determines if there was a collision at any point * between the previous position and current position * of two AABB's. * * Also assigns a normalized time of impact value * to pass-by-reference parameter "timeOfImpact" * ******************************************************/ vector<AABBPair> bps; bool collisionOccurred = false; _octree->potentialBoxBoxCollision(bps, boxes, octree); for(unsigned int i = 0; i < bps.size(); i++) { _octree->add(boxes[i]); AABBPair bp = bps[i]; AABB* boxA = bp.aabb1; AABB* boxB = bp.aabb2; //Check if box A and box B were already overlapping in their previous positions: D3DXVECTOR3 AB_separation = boxA->centerPointPrevious - boxB->centerPointPrevious; if( (fabs(AB_separation.x) <= fabs(boxA->extent().x + boxB->extent().x)) && (fabs(AB_separation.y) <= fabs(boxA->extent().y + boxB->extent().y)) && (fabs(AB_separation.z) <= fabs(boxA->extent().z + boxB->extent().z)) ) { //The boxes were already overlapping at their previous positions collisionOccurred = true; core._collisions->currentCollision.boxA_ID = boxA->ID; core._collisions->currentCollision.boxB_ID = boxB->ID; core._collisions->currentCollision.impactPoint.x = -FLT_MAX; core._collisions->currentCollision.impactPoint.y = -FLT_MAX; core._collisions->currentCollision.impactPoint.z = -FLT_MAX; core._collisions->currentCollision.timeOfImpact = 0.0f; core._collisions->currentCollision.boxA_movementVector = boxA->center() - boxA->centerPointPrevious; core._collisions->currentCollision.boxB_movementVector = boxB->center() - boxB->centerPointPrevious; core._collisions->addToList(); timeOfImpact = 0.0f; } //We know they weren't overlapping at thier previous positions, so let's set up for detecting potential times of impact D3DXVECTOR3 displacementA = boxA->center() - boxA->centerPointPrevious; //Displacement of box A between previous and current positions D3DXVECTOR3 displacementB = boxB->center() - boxB->centerPointPrevious; //Displacement of box B between previous and current positions D3DXVECTOR3 relativeVelocity = displacementB - displacementA; //Relative velocity between box A and box B D3DXVECTOR3 aMin = boxA->centerPointPrevious - boxA->extent(); //Previous min point of box A D3DXVECTOR3 aMax = boxA->centerPointPrevious + boxA->extent(); //Previous max point of box A D3DXVECTOR3 bMin = boxB->centerPointPrevious - boxB->extent(); //Previous min point of box B D3DXVECTOR3 bMax = boxB->centerPointPrevious + boxB->extent(); //Previous max point of box B //First time of overlap along all axes D3DXVECTOR3 t0; t0.x, t0.y, t0.z = 0, 0, 0; //Last time of overlap along all axes D3DXVECTOR3 t1; t1.x, t1.y, t1.z = 1, 1, 1; for(int i = 0; i < 3; i++) { if(i = 0) { //Test x axis //Test for earliest time of impact: if( (aMax.x < bMin.x) && (relativeVelocity.x < 0) ) { t0.x = (aMax.x - bMin.x) / relativeVelocity.x; //Potential time of impact, normalized } else if( (bMax.x < aMin.x) && (relativeVelocity.x > 0) ) { t0.x = (aMin.x - bMax.x) / relativeVelocity.x; //Potential time of impact, normalized } //Test for last time of impact: if( (bMax.x > aMin.x) && (relativeVelocity.x < 0) ) { t1.x = (aMin.x - bMax.x) / relativeVelocity.x; //Potential time of impact, normalized } else if( (aMax.x > bMin.x) && (relativeVelocity.x > 0) ) { t1.x = (aMax.x - bMin.x) / relativeVelocity.x; } } else if(i = 1) { //Test y axis //Test for earliest time of impact: if( (aMax.y < bMin.y) && (relativeVelocity.y < 0) ) { t0.y = (aMax.y - bMin.y) / relativeVelocity.y; //Potential time of impact, normalized } else if( (bMax.y < aMin.y) && (relativeVelocity.y > 0) ) { t0.y = (aMin.y - bMax.y) / relativeVelocity.y; //Potential time of impact, normalized } //Test for last time of impact: if( (bMax.y > aMin.y) && (relativeVelocity.y < 0) ) { t1.y = (aMin.y - bMax.y) / relativeVelocity.y; //Potential time of impact, normalized } else if( (aMax.y > bMin.y) && (relativeVelocity.y > 0) ) { t1.y = (aMax.y - bMin.y) / relativeVelocity.y; } } else { //Test z axis //Test for earliest time of impact: if( (aMax.z < bMin.z) && (relativeVelocity.z < 0) ) { t0.z = (aMax.z - bMin.z) / relativeVelocity.z; //Potential time of impact, normalized } else if( (bMax.z < aMin.z) && (relativeVelocity.z > 0) ) { t0.z = (aMin.z - bMax.z) / relativeVelocity.z; //Potential time of impact, normalized } //Test for last time of impact: if( (bMax.z > aMin.z) && (relativeVelocity.z < 0) ) { t1.z = (aMin.z - bMax.z) / relativeVelocity.z; //Potential time of impact, normalized } else if( (aMax.z > bMin.z) && (relativeVelocity.z > 0) ) { t1.z = (aMax.z - bMin.z) / relativeVelocity.z; } } } float tMin, tMax; //Store our earliest and latest impact times (normalized) //Potential time of first impact tMin = max(t0.x, max(t0.y, t0.z)); //Potential time of last impact tMax = min(t1.x, min(t1.y, t1.z)); //An impact has only occurred if the time of first impact is less than or equal to the time of last impact if(tMin <= tMax) { collisionOccurred = true; core._collisions->currentCollision.boxA_ID = boxA->ID; core._collisions->currentCollision.boxB_ID = boxB->ID; core._collisions->currentCollision.impactPoint.x = -FLT_MAX; core._collisions->currentCollision.impactPoint.y = -FLT_MAX; core._collisions->currentCollision.impactPoint.z = -FLT_MAX; core._collisions->currentCollision.timeOfImpact = tMin; core._collisions->currentCollision.boxA_movementVector = boxA->center() - boxA->centerPointPrevious; core._collisions->currentCollision.boxB_movementVector = boxB->center() - boxB->centerPointPrevious; core._collisions->addToList(); timeOfImpact = tMin; } } if(collisionOccurred) { return true; } else { return false; } }