bool Ned3DObjectManager::enforcePositions(GameObject &obj1, GameObject &obj2) { const AABB3 &box1 = obj1.getBoundingBox(), &box2 = obj2.getBoundingBox(); AABB3 intersectBox; if(AABB3::intersect(box1, box2, &intersectBox)) { // Collision: Knock back both objects // - Kludge method: Push back on smallest dimension Vector3 delta = intersectBox.size(); Vector3 obj1Pos = obj1.getPosition(), obj2Pos = obj2.getPosition(); if(delta.x <= delta.y) if(delta.x <= delta.z) { // Push back on x float dx = (box1.min.x < box2.min.x) ? -delta.x : delta.x; obj1Pos.x += dx; obj2Pos.x -= dx; } else { // Push back on z float dz = (box1.min.z < box2.min.z) ? -delta.z : delta.z; obj1Pos.z += dz; obj2Pos.z -= dz; } else if(delta.y <= delta.z) { // Push back on y float dy = (box1.min.y < box2.min.y) ? -delta.y : delta.y; obj1Pos.y += dy; obj2Pos.y -= dy; } else { // Push back on z float dz = (box1.min.z < box2.min.z) ? -delta.z : delta.z; obj1Pos.z += dz; obj2Pos.z -= dz; } obj1.setPosition(obj1Pos); obj2.setPosition(obj2Pos); return true; } return false; }
bool Ned3DObjectManager::enforcePosition(GameObject &moving, GameObject &stationary) { const AABB3 &box1 = moving.getBoundingBox(), &box2 = stationary.getBoundingBox(); AABB3 intersectBox; if(AABB3::intersect(box1, box2, &intersectBox)) { // Collision: Knock back obj1 // - Kludge method: Push back on smallest dimension Vector3 delta = intersectBox.size(); Vector3 obj1Pos = moving.getPosition(), obj2Pos = stationary.getPosition(); if(delta.x <= delta.y) if(delta.x <= delta.z) { // Push back on x obj1Pos.x += (box1.min.x < box2.min.x) ? -delta.x : delta.x; } else { // Push back on z obj1Pos.z += (box1.min.z < box2.min.z) ? -delta.z : delta.z; } else if(delta.y <= delta.z) { // Push back on y obj1Pos.y += (box1.min.y < box2.min.y) ? -delta.y : delta.y; } else { // Push back on z obj1Pos.z += (box1.min.z < box2.min.z) ? -delta.z : delta.z; } moving.setPosition(obj1Pos); return true; } return false; }
bool Ned3DObjectManager::enforcePositions(GameObject &obj1, GameObject &obj2) { // TODO: replace with http://code.google.com/p/bullet/source/browse/trunk/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp HullAgainstHull for OOBBs /* // Bullet stuff: btVector3 v(0.0f,0.0f,0.0f); const btConvexPolyhedron* cP = NULL; const btConvexPolyhedron* cP2 = NULL; if ( obj1.colOb->getCollisionShape()->isPolyhedral() ) { btPolyhedralConvexShape* pCS = ((btPolyhedralConvexShape*) obj1.colOb->getCollisionShape()); //pCS->initializePolyhedralFeatures(); cP = pCS->getConvexPolyhedron(); } if (obj2.colOb->getCollisionShape()->isPolyhedral() ) { btPolyhedralConvexShape* pCS = ((btPolyhedralConvexShape*) obj2.colOb->getCollisionShape()); //pCS->initializePolyhedralFeatures(); cP2 = pCS->getConvexPolyhedron(); } bool collision = false; if (cP && cP2) { collision = btPolyhedralContactClipping::findSeparatingAxis(*cP,*cP2, obj1.colOb->getWorldTransform(),obj2.colOb->getWorldTransform(), v,renderCallback); } btVector3 v1 = obj1.colOb->getWorldTransform().getOrigin(); btVector3 v2 = obj2.colOb->getWorldTransform().getOrigin(); bool invert = false; if (obj1.getType() == ObjectTypes::BOX || obj2.getType() == ObjectTypes::BOX) { invert = true; } if (collision) { if (!invert) { //normal collision stuff } else { } } return collision;*/ bool invert = false; if (obj1.getType() == ObjectTypes::BOX || obj2.getType() == ObjectTypes::BOX) { invert = true; } const AABB3 &box1 = obj1.getBoundingBox(), &box2 = obj2.getBoundingBox(); AABB3 intersectBox; if(! invert && AABB3::intersect(box1, box2, &intersectBox)) { // Collision: Knock back both objects // - Kludge method: Push back on smallest dimension Vector3 delta = intersectBox.size(); Vector3 obj1Pos = obj1.getPosition(), obj2Pos = obj2.getPosition(); if(delta.x <= delta.y) if(delta.x <= delta.z) { // Push back on x float dx = (box1.min.x < box2.min.x) ? -delta.x : delta.x; obj1Pos.x += dx; obj2Pos.x -= dx; } else { // Push back on z float dz = (box1.min.z < box2.min.z) ? -delta.z : delta.z; obj1Pos.z += dz; obj2Pos.z -= dz; } else if(delta.y <= delta.z) { // Push back on y float dy = (box1.min.y < box2.min.y) ? -delta.y : delta.y; obj1Pos.y += dy; obj2Pos.y -= dy; } else { // Push back on z float dz = (box1.min.z < box2.min.z) ? -delta.z : delta.z; obj1Pos.z += dz; obj2Pos.z -= dz; } obj1.setPPosition(obj1Pos); obj2.setPPosition(obj2Pos); return true; } else if (AABB3::intersect(box1, box2, &intersectBox) ) { // inverted bounding box collision) char* tp = (char*)malloc(sizeof(char*)*500); // allocate char sprintf_s(tp,500,"hello world %f\n\0",box1.min.x); Vector3 delta = intersectBox.size(); Vector3 obj1Pos = obj1.getPosition(), obj2Pos = obj2.getPosition(); float dx,dy,dz=0.0f; dx=dy=dz=0.0f; // check if plane should leave the box GameObject* p = &obj2; BoxObject* b = (BoxObject*)p; p = &obj1; PlaneObject* plane = (PlaneObject*)p; bool posChanged = false; // since one is much bigger than the other, we can use maxes to determine relative position: if (box1.min.x < box2.min.x + 1.0f) { // move obj2 to the left and move obj1 to the right dx = box2.min.x - box1.min.x; //obj1Pos.x += dx; posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_LEFT; //OutputDebugString(tp); if (b->l == BoxObject::LEFT) { setNextBox(b,b->left); return true; } } if (box1.min.x < box2.min.x) { // move obj2 to the left and move obj1 to the right dx = box2.min.x - box1.min.x; obj1Pos.x += dx; posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_LEFT; //OutputDebugString(tp); if (b->l == BoxObject::LEFT) { setNextBox(b,b->left); return true; } } if (box1.max.x + 1.0f > box2.max.x) { dx = box2.max.x - box1.max.x; //obj1Pos.x += dx; //OutputDebugString(tp); posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_RIGHT; if (b->l == BoxObject::RIGHT) { setNextBox(b,b->right); return true; } } if (box1.max.x > box2.max.x) { dx = box2.max.x - box1.max.x; obj1Pos.x += dx; //OutputDebugString(tp); posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_RIGHT; if (b->l == BoxObject::RIGHT) { setNextBox(b,b->right); return true; } } if (box1.min.y < box2.min.y + 1.0f) { // move obj2 to the left and move obj1 to the right dy = box2.min.y - box1.min.y; //obj1Pos.y += dy; //OutputDebugString(tp); posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_DOWN; if (b->l == BoxObject::BOTTOM) { setNextBox(b,b->bottom); return true; } } if (box1.min.y < box2.min.y) { // TODO: Make plane not able to go slightly over // move obj2 to the left and move obj1 to the right dy = box2.min.y - box1.min.y; obj1Pos.y += dy; //OutputDebugString(tp); posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_DOWN; if (b->l == BoxObject::BOTTOM) { setNextBox(b,b->bottom); return true; } } if (box1.max.y + 1.0f > box2.max.y) { dy = box2.max.y - box1.max.y; //obj1Pos.y += dy; //OutputDebugString(tp); posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_UP; if (b->l == BoxObject::TOP) { setNextBox(b,b->top); return true; } } if (box1.max.y > box2.max.y) { dy = box2.max.y - box1.max.y; obj1Pos.y += dy; //OutputDebugString(tp); posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_UP; if (b->l == BoxObject::TOP) { setNextBox(b,b->top); return true; } } if (box1.min.z < box2.min.z + 1.0f) { // move obj2 to the left and move obj1 to the right dz = box2.min.z - box1.min.z; //obj1Pos.z += dz; posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_NEAR; if (b->l == BoxObject::FRONT) { setNextBox(b,b->back); return true; } } if (box1.min.z < box2.min.z) { // move obj2 to the left and move obj1 to the right dz = box2.min.z - box1.min.z; obj1Pos.z += dz; posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_NEAR; if (b->l == BoxObject::FRONT) { setNextBox(b,b->back); return true; } } if (box1.max.z + 1.0f > box2.max.z) { dz = box2.max.z - box1.max.z; //obj1Pos.z += dz; //char* tp = (char*)malloc(sizeof(char*)*500); // allocate char //sprintf_s(tp,500,"In with the new?????\n\0"); //OutputDebugString(tp); posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_FAR; if (b->l == BoxObject::BACK) { setNextBox(b,b->front); return true; } } if (box1.max.z > box2.max.z) { dz = box2.max.z - box1.max.z; obj1Pos.z += dz; posChanged = true; plane->m_stopState = plane->m_stopState | PlaneObject::STOP_FAR; if (b->l == BoxObject::BACK) { setNextBox(b,b->front); return true; } } if (!posChanged) { // No walls hit, so plane can move normally plane->m_stopState = PlaneObject::NO_STOP; } obj1.setPPosition(obj1Pos); return true; } return false; }
bool Ned3DObjectManager::enforcePosition(GameObject &moving, GameObject &stationary) { // Bullet stuff: //collisionWorld->contactPairTest(moving.colOb,stationary.colOb, *renderCallback); /* btVector3 v(0.0f,0.0f,0.0f); const btConvexPolyhedron* cP = NULL; const btConvexPolyhedron* cP2 = NULL; if ( moving.colOb->getCollisionShape()->isPolyhedral() ) { btPolyhedralConvexShape* pCS = ((btPolyhedralConvexShape*) moving.colOb->getCollisionShape()); //pCS->initializePolyhedralFeatures(); // TODO wasn't doing this on startup, now I am cP = pCS->getConvexPolyhedron(); } if (stationary.colOb->getCollisionShape()->isPolyhedral() ) { btPolyhedralConvexShape* pCS = ((btPolyhedralConvexShape*) stationary.colOb->getCollisionShape()); //pCS->initializePolyhedralFeatures(); // TODO wasn't doing this on startup, now I am cP2 = pCS->getConvexPolyhedron(); } bool collision = false; if (cP && cP2) { collision = btPolyhedralContactClipping::findSeparatingAxis(*cP,*cP2, moving.colOb->getWorldTransform(),stationary.colOb->getWorldTransform(), v,renderCallback); } btVector3 v2 = moving.colOb->getWorldTransform().getOrigin(); if (collision) { char* tp = (char*)malloc(sizeof(char*)*500); // allocate char sprintf_s(tp,500,"hello world %f %f %f\n\0",v2.getX(),v2.getY(),v2.getZ()); OutputDebugString(tp); delete tp; } return collision;*/ const AABB3 &box1 = moving.getBoundingBox(), &box2 = stationary.getBoundingBox(); AABB3 intersectBox; if(AABB3::intersect(box1, box2, &intersectBox)) { // Collision: Knock back obj1 // - Kludge method: Push back on smallest dimension Vector3 delta = intersectBox.size(); Vector3 obj1Pos = moving.getPosition(), obj2Pos = stationary.getPosition(); if(delta.x <= delta.y) if(delta.x <= delta.z) { // Push back on x obj1Pos.x += (box1.min.x < box2.min.x) ? -delta.x : delta.x; } else { // Push back on z obj1Pos.z += (box1.min.z < box2.min.z) ? -delta.z : delta.z; } else if(delta.y <= delta.z) { // Push back on y obj1Pos.y += (box1.min.y < box2.min.y) ? -delta.y : delta.y; } else { // Push back on z obj1Pos.z += (box1.min.z < box2.min.z) ? -delta.z : delta.z; } moving.setPPosition(obj1Pos); return true; } return false; }