Changeset View
Changeset View
Standalone View
Standalone View
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
| Context not available. | |||||
| void CcdPhysicsEnvironment::CallbackTriggers() | void CcdPhysicsEnvironment::CallbackTriggers() | ||||
| { | { | ||||
| if (m_triggerCallbacks[PHY_OBJECT_RESPONSE] || (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints))) | bool draw_contact_points = m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints); | ||||
| { | |||||
| //walk over all overlapping pairs, and if one of the involved bodies is registered for trigger callback, perform callback | |||||
| btDispatcher* dispatcher = m_dynamicsWorld->getDispatcher(); | |||||
| int numManifolds = dispatcher->getNumManifolds(); | |||||
| for (int i=0;i<numManifolds;i++) | |||||
| { | |||||
| btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i); | |||||
| int numContacts = manifold->getNumContacts(); | |||||
| if (numContacts) | |||||
| { | |||||
| const btRigidBody* rb0 = static_cast<const btRigidBody*>(manifold->getBody0()); | |||||
| const btRigidBody* rb1 = static_cast<const btRigidBody*>(manifold->getBody1()); | |||||
| if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)) | |||||
| { | |||||
| for (int j=0;j<numContacts;j++) | |||||
| { | |||||
| btVector3 color(1,0,0); | |||||
| const btManifoldPoint& cp = manifold->getContactPoint(j); | |||||
| if (m_debugDrawer) | |||||
| m_debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color); | |||||
| } | |||||
| } | |||||
| const btRigidBody* obj0 = rb0; | |||||
| const btRigidBody* obj1 = rb1; | |||||
| //m_internalOwner is set in 'addPhysicsController' | if (!m_triggerCallbacks[PHY_OBJECT_RESPONSE] && !draw_contact_points) | ||||
| CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->getUserPointer()); | return; | ||||
| CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(obj1->getUserPointer()); | |||||
| std::set<CcdPhysicsController*>::const_iterator i = m_triggerControllers.find(ctrl0); | //walk over all overlapping pairs, and if one of the involved bodies is registered for trigger callback, perform callback | ||||
| if (i == m_triggerControllers.end()) | btDispatcher* dispatcher = m_dynamicsWorld->getDispatcher(); | ||||
| { | int numManifolds = dispatcher->getNumManifolds(); | ||||
| i = m_triggerControllers.find(ctrl1); | for (int i=0;i<numManifolds;i++) | ||||
| } | { | ||||
| btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i); | |||||
| int numContacts = manifold->getNumContacts(); | |||||
| if (!numContacts) continue; | |||||
| if (!(i == m_triggerControllers.end())) | const btRigidBody* rb0 = static_cast<const btRigidBody*>(manifold->getBody0()); | ||||
| { | const btRigidBody* rb1 = static_cast<const btRigidBody*>(manifold->getBody1()); | ||||
| m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE], | if (draw_contact_points) | ||||
| ctrl0,ctrl1,0); | { | ||||
| } | for (int j=0;j<numContacts;j++) | ||||
| // Bullet does not refresh the manifold contact point for object without contact response | { | ||||
| // may need to remove this when a newer Bullet version is integrated | btVector3 color(1,0,0); | ||||
| if (!dispatcher->needsResponse(rb0, rb1)) | const btManifoldPoint& cp = manifold->getContactPoint(j); | ||||
| { | m_debugDrawer->drawContactPoint(cp.m_positionWorldOnB, | ||||
| // Refresh algorithm fails sometimes when there is penetration | cp.m_normalWorldOnB, | ||||
| // (usuall the case with ghost and sensor objects) | cp.getDistance(), | ||||
| // Let's just clear the manifold, in any case, it is recomputed on each frame. | cp.getLifeTime(), | ||||
| manifold->clearManifold(); //refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform()); | color); | ||||
| } | |||||
| } | } | ||||
| } | } | ||||
| //m_internalOwner is set in 'addPhysicsController' | |||||
| CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(rb0->getUserPointer()); | |||||
| CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(rb1->getUserPointer()); | |||||
| std::set<CcdPhysicsController*>::const_iterator iter = m_triggerControllers.find(ctrl0); | |||||
| if (iter == m_triggerControllers.end()) | |||||
| { | |||||
| iter = m_triggerControllers.find(ctrl1); | |||||
| } | |||||
| if (iter != m_triggerControllers.end()) | |||||
| { | |||||
| m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE], | |||||
| ctrl0,ctrl1,0); | |||||
| } | |||||
| // Bullet does not refresh the manifold contact point for object without contact response | |||||
| // may need to remove this when a newer Bullet version is integrated | |||||
| if (!dispatcher->needsResponse(rb0, rb1)) | |||||
| { | |||||
| // Refresh algorithm fails sometimes when there is penetration | |||||
| // (usuall the case with ghost and sensor objects) | |||||
| // Let's just clear the manifold, in any case, it is recomputed on each frame. | |||||
| manifold->clearManifold(); //refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform()); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| // This call back is called before a pair is added in the cache | // This call back is called before a pair is added in the cache | ||||
| Context not available. | |||||