typename BVolCollision<BasicTraits,BVOL>::ResultT BVolCollision<BasicTraits,BVOL>::BVolBVolCollision (GroupType* g0, GroupType* g1) { ++m_numBVolBVolTests; // perform BV-BV overlap test Real t = bvolIntersect(g0->getBVol(), g1->getBVol()); if (t < 0.0f) { return DoubleTraverserBase<BasicTraits>::QUIT; } const DoubleTraverserFixedBase<BasicTraits>* trav = dynamic_cast<const DoubleTraverserFixedBase<BasicTraits>*>(getTraverser()); if (trav != NULL && trav->getDepth0() == getCurrentDepth0(trav, g0) && trav->getDepth1() == getCurrentDepth1(trav, g1)) { // Keep track of colliding pairs // check if first collision already found if (getNumContacts() == 0) { m_contacts.push_back(CollisionPair((AdapterType*)g0->findLeaf(), (AdapterType*)g1->findLeaf())); CollisionInterface<OpenSGTriangleBase<BasicTraits>,Real> result(m_contacts[m_contacts.size()-1]); result.getData() = t; } CollisionInterface<OpenSGTriangleBase<BasicTraits>,Real> result(m_contacts[0]); if (t < result.getData()) { result.getData() = t; m_contacts[0].setFirst((AdapterType*)g0->findLeaf()); m_contacts[0].setSecond((AdapterType*)g1->findLeaf()); } } return DoubleTraverserBase<BasicTraits>::CONTINUE; }
typename BVolCollision<BasicTraits,BVOL>::ResultT BVolCollision<BasicTraits,BVOL>::PrimPrimCollision (AdapterType* p0, AdapterType* p1) { ++m_numPrimPrimTests; #if defined(GV_BVOLS_IN_MIXEDTESTS) Real t = (this->*f_primIntersect)(p0, p1); if (t >= 0.0f) { // Keep track of colliding pairs // check if first collision already found if (!getStopFirst() || getNumContacts() == 0) { m_contacts.push_back(CollisionPair(p0, p1)); CollisionInterface<OpenSGTriangleBase<BasicTraits>,Real> result(m_contacts[m_contacts.size()-1]); result.getData() = t; } CollisionInterface<OpenSGTriangleBase<BasicTraits>,Real> result(m_contacts[0]); if (t < result.getData()) { result.getData() = t; m_contacts[0].setFirst(p0); m_contacts[0].setSecond(p1); } } #else // Transform from model space 1 to model space 0 PointClass d0, d1, d2; m_M1ToM0.mult(p1->getPosition(0), d0); m_M1ToM0.mult(p1->getPosition(1), d1); m_M1ToM0.mult(p1->getPosition(2), d2); // Perform triangle-triangle overlap test if (genvis::triTriOverlap(p0->getPosition(0), p0->getPosition(1), p0->getPosition(2), d0, d1, d2)) { // Keep track of colliding pairs m_contacts.push_back(CollisionPair(p0, p1)); } #endif return DoubleTraverserBase<BasicTraits>::CONTINUE; }
typename ContactDistanceCalc<BasicTraits,BVOL,Metric>::ResultT ContactDistanceCalc<BasicTraits,BVOL,Metric>::PrimPrimCollision (AdapterType* p0, AdapterType* p1) { // Transform from model space 1 to model space 0 PointClass tp1[3]; m_M1ToM0.mult(p1->getPosition(0), tp1[0]); m_M1ToM0.mult(p1->getPosition(1), tp1[1]); m_M1ToM0.mult(p1->getPosition(2), tp1[2]); // perform triangle-triangle distance calculation ++m_numPrimPrimTests; PointClass min0, min1; Real dist = genvis::triTriDistance(min0, min1, p0->getPosition(), tp1); if (dist <= getTolerance()) { // update minimum distance if (dist < getDistance()) { setDistance(dist); // keep track of contact pairs m_contacts.insert(m_contacts.begin(), CollisionPair(p0, p1)); //m_contacts[0].setData(new Distance()); CollisionInterface<OpenSGTriangleBase<BasicTraits>,Distance> result(m_contacts[0]); result.getData().distance = dist; m_M0.mult(min0, result.getData().p1); m_M0.mult(min1, result.getData().p2); #ifdef GV_WITH_LINEGEOMETRY if (getLineGeometry() != NullFC) { beginEditCP(getLineGeometry()); getLineGeometry()->setValue(result.getData().p1, 1); getLineGeometry()->setValue(result.getData().p2, 0); endEditCP(getLineGeometry()); } #endif } else { // keep track of contact pairs m_contacts.push_back(CollisionPair(p0, p1)); //m_contacts[m_contacts.size()-1].setData(new Distance()); CollisionInterface<OpenSGTriangleBase<BasicTraits>,Distance> result(m_contacts[m_contacts.size()-1]); result.getData().distance = dist; } } return DoubleTraverserBase<BasicTraits>::CONTINUE; }
uint32 NarrowPhaseDetector::detect(CollisionContext& context) { for ( uint32 i = 0; i < context.numBroadPhaseCollisions; ++i ) { CollisionPair& pair = context.broadPhaseCollisions[i]; Collider& first = context.colliders.get(pair.first); Collider& second = context.colliders.get(pair.second); if ( first.colliderType == CT_CIRCLE && second.colliderType == CT_CIRCLE ) { if ( intersectCircleCircle(first,second)) { context.narrowPhaseCollisions[context.numNarrowPhaseCollisions++] = CollisionPair(first.id,second.id); } } } return context.numNarrowPhaseCollisions; }
typename BVolCollision<BasicTraits,BVOL>::ResultT BVolCollision<BasicTraits,BVOL>::PrimBVolCollision (AdapterType* p0, GroupType* g1) { ++m_numPrimBVolTests; // perform BV-BV overlap test #if defined(GV_BVOLS_IN_MIXEDTESTS) Real t = bvolIntersect(p0->getBVol(), g1->getBVol()); if (t < 0.0f) { return DoubleTraverserBase<BasicTraits>::QUIT; } const DoubleTraverserFixedBase<BasicTraits>* trav = dynamic_cast<const DoubleTraverserFixedBase<BasicTraits>*>(getTraverser()); if (trav != NULL && trav->getDepth1() == getCurrentDepth1(trav, g1)) { // Keep track of colliding pairs // check if first collision already found if (getNumContacts() == 0) { m_contacts.push_back(CollisionPair(p0, (AdapterType*)g1->findLeaf())); CollisionInterface<OpenSGTriangleBase<BasicTraits>,Real> result(m_contacts[m_contacts.size()-1]); result.getData() = t; } CollisionInterface<OpenSGTriangleBase<BasicTraits>,Real> result(m_contacts[0]); if (t < result.getData()) { result.getData() = t; m_contacts[0].setFirst(p0); m_contacts[0].setSecond((AdapterType*)g1->findLeaf()); } } #else // Transform from model space 0 to model space 1 PointClass d0, d1, d2; m_M0ToM1.mult(p0->getPosition(0), d0); m_M0ToM1.mult(p0->getPosition(1), d1); m_M0ToM1.mult(p0->getPosition(2), d2); if (!g1->getBVol().checkIntersect(d0, d1, d2)) { return DoubleTraverserBase<BasicTraits>::QUIT; } #endif return DoubleTraverserBase<BasicTraits>::CONTINUE; }
typename PrecomputedAlignCollision<BasicTraits,BVOL>::ResultT PrecomputedAlignCollision<BasicTraits,BVOL>::PrimPrimCollision (AdapterType* p0, AdapterType* p1) { // Transform from model space 1 to model space 0 PointClass d0, d1, d2; m_M1ToM0.mult(p1->getPosition(0), d0); m_M1ToM0.mult(p1->getPosition(1), d1); m_M1ToM0.mult(p1->getPosition(2), d2); // Perform triangle-triangle overlap test ++m_numPrimPrimTests; if (genvis::triTriOverlap(p0->getPosition(0), p0->getPosition(1), p0->getPosition(2), d0, d1, d2)) { // Keep track of colliding pairs m_contacts.push_back(CollisionPair(p0, p1)); } return DoubleTraverserBase<BasicTraits>::CONTINUE; }
std::vector<CollisionPair> PhysicsManager::CoarseCollisionDetection(const std::deque<Entity*>& availableCollideables) { Entity* curEnt; std::vector<CollisionPair> possibleCollisions; for (UINT i = 0 ; i < sceneCollideables.size() ; ++i) { curEnt = sceneCollideables[i]; for (UINT j = i + 1 ; j < sceneCollideables.size() ; ++j) { if (curEnt->type != sceneCollideables[j]->type && curEnt->TestAABBIntersection(sceneCollideables[j]->AABB)) { //Collision between two entities has occured. if (curEnt->rigidBody->isAwake && sceneCollideables[j]->rigidBody->isAwake) { if (CheckCollisionIsUnique(possibleCollisions, sceneCollideables[j], curEnt)) { possibleCollisions.push_back(CollisionPair(curEnt, sceneCollideables[j])); } } } } } return possibleCollisions; }
/** Adds information about a collision to this vector. */ void push_back(const UserPointer *a, const btVector3 &contact_point_a, const UserPointer *b, const btVector3 &contact_point_b) { push_back(CollisionPair(a, contact_point_a, b, contact_point_b)); }
void CollisionEngine::CalculateCollisions() { _collidedObjects->clear(); //calc collidedPoints.clear(); Vector4 point1; Vector4 point2; Vector4 linePoint1; Vector4 linePoint2; Vector4 intersectionPoint; Vector4 intersectionPointTmp; for (int j = 0; j < _objectMeshes->GetCount(); j++) { CollisionObject *mesh = _objectMeshes->objectAtIndex(j); if (mesh->GetCollisionObjectPointsCount() > _pointBuffer->GetSize()) _pointBuffer->Resize(mesh->GetCollisionObjectPointsCount()); { //transform points Matrix4 transform = mesh->GetCollisionObjectTransform(); for (int i = 0; i < mesh->GetCollisionObjectPointsCount(); i++) _pointBuffer->GetArrayPointer()[i] = Matrix4MultiplyVector4(transform, mesh->GetCollisionObjectPoints()[i]); } Vector4 tmp =_pointBuffer->objectAtIndex(2); tmp = tmp; for (int i = 0; i < _objectPoints->GetCount(); i++) { CollisionObject *point = _objectPoints->objectAtIndex(i); if (collidedPoints.indexOf(point) != -1) continue; point1 = Vector4MakeWithVector3(Matrix4GetTranslation(point->GetCollisionObjectPreviousTransform()), 1); point2 = Vector4MakeWithVector3(Matrix4GetTranslation(point->GetCollisionObjectTransform()), 1); int lineCount = mesh->GetCollisionObjectPointsCount() / 2; float intersectonRange = 1000; bool foundIntersection = false; for (int p = 0; p < lineCount; p++) { linePoint1 = _pointBuffer->objectAtIndex(p * 2); linePoint2 = _pointBuffer->objectAtIndex(p * 2 + 1); if (intersection(linePoint1, linePoint2, point1, point2, &intersectionPointTmp)) { foundIntersection = true; float currentIntersectonRange = Vector3LengthSquired(Vector3Make(point1.x - intersectionPointTmp.x, point1.y - intersectionPointTmp.y, point1.z - intersectionPointTmp.z)); if (currentIntersectonRange < intersectonRange) { intersectionPoint = intersectionPointTmp; intersectonRange = currentIntersectonRange; } } } if (foundIntersection) { _collidedObjects->addObject(CollisionPair(mesh, point)); break; //only 1 collision - much more easy } } } //updateObjects for (int i = 0; i < _objectPoints->GetCount(); i++) _objectPoints->objectAtIndex(i)->Update(); for (int i = 0; i < _objectMeshes->GetCount(); i++) _objectMeshes->objectAtIndex(i)->Update(); }