diff options
Diffstat (limited to 'source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp')
-rw-r--r-- | source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp | 155 |
1 files changed, 87 insertions, 68 deletions
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 38e7df6c573..f450e3ac12f 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -174,26 +174,27 @@ public: virtual void GetWheelPosition(int wheelIndex,float& posX,float& posY,float& posZ) const { - btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex); - posX = trans.getOrigin().x(); - posY = trans.getOrigin().y(); - posZ = trans.getOrigin().z(); + if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) + { + btVector3 origin = m_vehicle->getWheelTransformWS(wheelIndex).getOrigin(); + + posX = origin.x(); + posY = origin.y(); + posZ = origin.z(); + } } + virtual void GetWheelOrientationQuaternion(int wheelIndex,float& quatX,float& quatY,float& quatZ,float& quatW) const { - btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex); - btQuaternion quat = trans.getRotation(); - btMatrix3x3 orn2(quat); - - quatX = trans.getRotation().x(); - quatY = trans.getRotation().y(); - quatZ = trans.getRotation().z(); - quatW = trans.getRotation()[3]; - - - //printf("test"); - + if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) + { + btQuaternion quat = m_vehicle->getWheelTransformWS(wheelIndex).getRotation(); + quatX = quat.x(); + quatY = quat.y(); + quatZ = quat.z(); + quatW = quat.w(); + } } virtual float GetWheelRotation(int wheelIndex) const @@ -205,8 +206,8 @@ public: btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); rotation = info.m_rotation; } - return rotation; + return rotation; } @@ -223,12 +224,16 @@ public: virtual void SetSteeringValue(float steering,int wheelIndex) { - m_vehicle->setSteeringValue(steering,wheelIndex); + if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) { + m_vehicle->setSteeringValue(steering,wheelIndex); + } } virtual void ApplyEngineForce(float force,int wheelIndex) { - m_vehicle->applyEngineForce(force,wheelIndex); + if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) { + m_vehicle->applyEngineForce(force,wheelIndex); + } } virtual void ApplyBraking(float braking,int wheelIndex) @@ -2251,64 +2256,77 @@ bool CcdPhysicsEnvironment::RequestCollisionCallback(PHY_IPhysicsController* ctr void CcdPhysicsEnvironment::CallbackTriggers() { - if (m_triggerCallbacks[PHY_OBJECT_RESPONSE] || (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; + bool draw_contact_points = m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints); - //m_internalOwner is set in 'addPhysicsController' - CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->getUserPointer()); - CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(obj1->getUserPointer()); + if (!m_triggerCallbacks[PHY_OBJECT_RESPONSE] && !draw_contact_points) + return; - std::set<CcdPhysicsController*>::const_iterator i = m_triggerControllers.find(ctrl0); - if (i == m_triggerControllers.end()) - { - i = m_triggerControllers.find(ctrl1); - } + //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++) + { + bool colliding_ctrl0 = true; + btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i); + int numContacts = manifold->getNumContacts(); + if (!numContacts) continue; - if (!(i == 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()); - } + const btRigidBody* rb0 = static_cast<const btRigidBody*>(manifold->getBody0()); + const btRigidBody* rb1 = static_cast<const btRigidBody*>(manifold->getBody1()); + if (draw_contact_points) + { + for (int j=0;j<numContacts;j++) + { + btVector3 color(1,1,0); + const btManifoldPoint& cp = manifold->getContactPoint(j); + m_debugDrawer->drawContactPoint(cp.m_positionWorldOnB, + cp.m_normalWorldOnB, + cp.getDistance(), + cp.getLifeTime(), + 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); + colliding_ctrl0 = false; + } - } + if (iter != m_triggerControllers.end()) + { + static PHY_CollData coll_data; + const btManifoldPoint &cp = manifold->getContactPoint(0); + /* Make sure that "point1" is always on the object we report on, and + * "point2" on the other object. Also ensure the normal is oriented + * correctly. */ + btVector3 point1 = colliding_ctrl0 ? cp.m_positionWorldOnA : cp.m_positionWorldOnB; + btVector3 point2 = colliding_ctrl0 ? cp.m_positionWorldOnB : cp.m_positionWorldOnA; + btVector3 normal = colliding_ctrl0 ? -cp.m_normalWorldOnB : cp.m_normalWorldOnB; + coll_data.m_point1 = MT_Vector3(point1.m_floats); + coll_data.m_point2 = MT_Vector3(point2.m_floats); + coll_data.m_normal = MT_Vector3(normal.m_floats); + + m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE], + ctrl0, ctrl1, &coll_data); + } + // 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 @@ -2999,7 +3017,8 @@ struct BlenderDebugDraw : public btIDebugDraw virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color) { - //not yet + drawLine(PointOnB, PointOnB + normalOnB, color); + drawSphere(PointOnB, 0.1, color); } virtual void setDebugMode(int debugMode) |