2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
19 #include "CcdPhysicsEnvironment.h"
20 #include "CcdPhysicsController.h"
23 #include "btBulletDynamicsCommon.h"
24 #include "LinearMath/btIDebugDraw.h"
25 #include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
28 #include "LinearMath/btQuickprof.h"
31 #include "PHY_IMotionState.h"
34 bool useIslands = true;
36 #ifdef NEW_BULLET_VEHICLE_SUPPORT
37 #include "BulletDynamics/Vehicle/btRaycastVehicle.h"
38 #include "BulletDynamics/Vehicle/btVehicleRaycaster.h"
39 #include "BulletDynamics/Vehicle/btWheelInfo.h"
40 #include "PHY_IVehicle.h"
41 btRaycastVehicle::btVehicleTuning gTuning;
43 #endif //NEW_BULLET_VEHICLE_SUPPORT
44 #include "LinearMath/btAabbUtil2.h"
48 void DrawRasterizerLine(const float* from,const float* to,int color);
52 #include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
57 #ifdef NEW_BULLET_VEHICLE_SUPPORT
58 class WrapperVehicle : public PHY_IVehicle
61 btRaycastVehicle* m_vehicle;
62 PHY_IPhysicsController* m_chassis;
66 WrapperVehicle(btRaycastVehicle* vehicle,PHY_IPhysicsController* chassis)
72 btRaycastVehicle* GetVehicle()
77 PHY_IPhysicsController* GetChassis()
82 virtual void AddWheel(
83 PHY_IMotionState* motionState,
84 PHY__Vector3 connectionPoint,
85 PHY__Vector3 downDirection,
86 PHY__Vector3 axleDirection,
87 float suspensionRestLength,
92 btVector3 connectionPointCS0(connectionPoint[0],connectionPoint[1],connectionPoint[2]);
93 btVector3 wheelDirectionCS0(downDirection[0],downDirection[1],downDirection[2]);
94 btVector3 wheelAxle(axleDirection[0],axleDirection[1],axleDirection[2]);
97 btWheelInfo& info = m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxle,
98 suspensionRestLength,wheelRadius,gTuning,hasSteering);
99 info.m_clientInfo = motionState;
105 int numWheels = GetNumWheels();
107 for (i=0;i<numWheels;i++)
109 btWheelInfo& info = m_vehicle->getWheelInfo(i);
110 PHY_IMotionState* motionState = (PHY_IMotionState*)info.m_clientInfo ;
111 // m_vehicle->updateWheelTransformsWS(info,false);
112 m_vehicle->updateWheelTransform(i,false);
113 btTransform trans = m_vehicle->getWheelInfo(i).m_worldTransform;
114 btQuaternion orn = trans.getRotation();
115 const btVector3& pos = trans.getOrigin();
116 motionState->setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]);
117 motionState->setWorldPosition(pos.x(),pos.y(),pos.z());
122 virtual int GetNumWheels() const
124 return m_vehicle->getNumWheels();
127 virtual void GetWheelPosition(int wheelIndex,float& posX,float& posY,float& posZ) const
129 btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex);
130 posX = trans.getOrigin().x();
131 posY = trans.getOrigin().y();
132 posZ = trans.getOrigin().z();
134 virtual void GetWheelOrientationQuaternion(int wheelIndex,float& quatX,float& quatY,float& quatZ,float& quatW) const
136 btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex);
137 btQuaternion quat = trans.getRotation();
138 btMatrix3x3 orn2(quat);
140 quatX = trans.getRotation().x();
141 quatY = trans.getRotation().y();
142 quatZ = trans.getRotation().z();
143 quatW = trans.getRotation()[3];
151 virtual float GetWheelRotation(int wheelIndex) const
153 float rotation = 0.f;
155 if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels()))
157 btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
158 rotation = info.m_rotation;
166 virtual int GetUserConstraintId() const
168 return m_vehicle->getUserConstraintId();
171 virtual int GetUserConstraintType() const
173 return m_vehicle->getUserConstraintType();
176 virtual void SetSteeringValue(float steering,int wheelIndex)
178 m_vehicle->setSteeringValue(steering,wheelIndex);
181 virtual void ApplyEngineForce(float force,int wheelIndex)
183 m_vehicle->applyEngineForce(force,wheelIndex);
186 virtual void ApplyBraking(float braking,int wheelIndex)
188 if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels()))
190 btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
191 info.m_brake = braking;
195 virtual void SetWheelFriction(float friction,int wheelIndex)
197 if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels()))
199 btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
200 info.m_frictionSlip = friction;
205 virtual void SetSuspensionStiffness(float suspensionStiffness,int wheelIndex)
207 if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels()))
209 btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
210 info.m_suspensionStiffness = suspensionStiffness;
215 virtual void SetSuspensionDamping(float suspensionDamping,int wheelIndex)
217 if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels()))
219 btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
220 info.m_wheelsDampingRelaxation = suspensionDamping;
224 virtual void SetSuspensionCompression(float suspensionCompression,int wheelIndex)
226 if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels()))
228 btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
229 info.m_wheelsDampingCompression = suspensionCompression;
235 virtual void SetRollInfluence(float rollInfluence,int wheelIndex)
237 if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels()))
239 btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
240 info.m_rollInfluence = rollInfluence;
244 virtual void SetCoordinateSystem(int rightIndex,int upIndex,int forwardIndex)
246 m_vehicle->setCoordinateSystem(rightIndex,upIndex,forwardIndex);
252 #endif //NEW_BULLET_VEHICLE_SUPPORT
255 void CcdPhysicsEnvironment::setDebugDrawer(btIDebugDraw* debugDrawer)
257 if (debugDrawer && m_dynamicsWorld)
258 m_dynamicsWorld->setDebugDrawer(debugDrawer);
259 m_debugDrawer = debugDrawer;
262 static void DrawAabb(btIDebugDraw* debugDrawer,const btVector3& from,const btVector3& to,const btVector3& color)
264 btVector3 halfExtents = (to-from)* 0.5f;
265 btVector3 center = (to+from) *0.5f;
268 btVector3 edgecoord(1.f,1.f,1.f),pa,pb;
273 pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
274 edgecoord[2]*halfExtents[2]);
277 int othercoord = j%3;
278 edgecoord[othercoord]*=-1.f;
279 pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
280 edgecoord[2]*halfExtents[2]);
283 debugDrawer->drawLine(pa,pb,color);
285 edgecoord = btVector3(-1.f,-1.f,-1.f);
298 CcdPhysicsEnvironment::CcdPhysicsEnvironment(btDispatcher* dispatcher,btOverlappingPairCache* pairCache)
299 :m_scalingPropagated(false),
301 m_numTimeSubSteps(1),
305 m_enableSatCollisionDetection(false)
308 for (int i=0;i<PHY_NUM_RESPONSE;i++)
310 m_triggerCallbacks[i] = 0;
313 dispatcher = new btCollisionDispatcher();
319 //todo: calculate/let user specify this world sizes
320 btVector3 worldMin(-10000,-10000,-10000);
321 btVector3 worldMax(10000,10000,10000);
323 pairCache = new btAxisSweep3(worldMin,worldMax);
325 //broadphase = new btSimpleBroadphase();
329 setSolverType(1);//issues with quickstep and memory allocations
331 m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,new btSequentialImpulseConstraintSolver());
333 m_gravity = btVector3(0.f,-10.f,0.f);
334 m_dynamicsWorld->setGravity(m_gravity);
339 void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
341 btRigidBody* body = ctrl->GetRigidBody();
343 //this m_userPointer is just used for triggers, see CallbackTriggers
344 body->setUserPointer(ctrl);
346 body->setGravity( m_gravity );
347 m_controllers.push_back(ctrl);
349 m_dynamicsWorld->addRigidBody(body);
350 if (body->isStaticOrKinematicObject())
352 body->setActivationState(ISLAND_SLEEPING);
356 //CollisionObject(body,ctrl->GetCollisionFilterGroup(),ctrl->GetCollisionFilterMask());
358 assert(body->getBroadphaseHandle());
360 btBroadphaseInterface* scene = getBroadphase();
363 btCollisionShape* shapeinterface = ctrl->GetCollisionShape();
365 assert(shapeinterface);
367 const btTransform& t = ctrl->GetRigidBody()->getCenterOfMassTransform();
370 btPoint3 minAabb,maxAabb;
372 shapeinterface->getAabb(t,minAabb,maxAabb);
374 float timeStep = 0.02f;
377 //extent it with the motion
379 btVector3 linMotion = body->getLinearVelocity()*timeStep;
381 float maxAabbx = maxAabb.getX();
382 float maxAabby = maxAabb.getY();
383 float maxAabbz = maxAabb.getZ();
384 float minAabbx = minAabb.getX();
385 float minAabby = minAabb.getY();
386 float minAabbz = minAabb.getZ();
388 if (linMotion.x() > 0.f)
389 maxAabbx += linMotion.x();
391 minAabbx += linMotion.x();
392 if (linMotion.y() > 0.f)
393 maxAabby += linMotion.y();
395 minAabby += linMotion.y();
396 if (linMotion.z() > 0.f)
397 maxAabbz += linMotion.z();
399 minAabbz += linMotion.z();
402 minAabb = btVector3(minAabbx,minAabby,minAabbz);
403 maxAabb = btVector3(maxAabbx,maxAabby,maxAabbz);
410 void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctrl)
413 //also remove constraint
417 m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody());
421 std::vector<CcdPhysicsController*>::iterator i =
422 std::find(m_controllers.begin(), m_controllers.end(), ctrl);
423 if (!(i == m_controllers.end()))
425 std::swap(*i, m_controllers.back());
426 m_controllers.pop_back();
430 //remove it from the triggers
432 std::vector<CcdPhysicsController*>::iterator i =
433 std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
434 if (!(i == m_triggerControllers.end()))
436 std::swap(*i, m_triggerControllers.back());
437 m_triggerControllers.pop_back();
445 void CcdPhysicsEnvironment::beginFrame()
451 bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
454 int i,numCtrl = GetNumControllers();
455 for (i=0;i<numCtrl;i++)
457 CcdPhysicsController* ctrl = GetPhysicsController(i);
458 ctrl->SynchronizeMotionStates(timeStep);
461 m_dynamicsWorld->stepSimulation(timeStep,0);//perform always a full simulation step
463 numCtrl = GetNumControllers();
464 for (i=0;i<numCtrl;i++)
466 CcdPhysicsController* ctrl = GetPhysicsController(i);
467 ctrl->SynchronizeMotionStates(timeStep);
470 for (i=0;i<m_wrapperVehicles.size();i++)
472 WrapperVehicle* veh = m_wrapperVehicles[i];
482 void CcdPhysicsEnvironment::setDebugMode(int debugMode)
485 m_debugDrawer->setDebugMode(debugMode);
489 void CcdPhysicsEnvironment::setNumIterations(int numIter)
491 m_numIterations = numIter;
493 void CcdPhysicsEnvironment::setDeactivationTime(float dTime)
495 gDeactivationTime = dTime;
497 void CcdPhysicsEnvironment::setDeactivationLinearTreshold(float linTresh)
499 gLinearSleepingTreshold = linTresh;
501 void CcdPhysicsEnvironment::setDeactivationAngularTreshold(float angTresh)
503 gAngularSleepingTreshold = angTresh;
506 void CcdPhysicsEnvironment::setContactBreakingTreshold(float contactBreakingTreshold)
508 gContactBreakingThreshold = contactBreakingTreshold;
513 void CcdPhysicsEnvironment::setCcdMode(int ccdMode)
519 void CcdPhysicsEnvironment::setSolverSorConstant(float sor)
521 m_solverInfo.m_sor = sor;
524 void CcdPhysicsEnvironment::setSolverTau(float tau)
526 m_solverInfo.m_tau = tau;
528 void CcdPhysicsEnvironment::setSolverDamping(float damping)
530 m_solverInfo.m_damping = damping;
534 void CcdPhysicsEnvironment::setLinearAirDamping(float damping)
536 gLinearAirDamping = damping;
539 void CcdPhysicsEnvironment::setUseEpa(bool epa)
544 void CcdPhysicsEnvironment::setSolverType(int solverType)
551 if (m_solverType != solverType)
554 m_solver = new btSequentialImpulseConstraintSolver();
562 if (m_solverType != solverType)
564 // m_solver = new OdeConstraintSolver();
571 m_solverType = solverType ;
579 void CcdPhysicsEnvironment::setGravity(float x,float y,float z)
581 m_gravity = btVector3(x,y,z);
582 m_dynamicsWorld->setGravity(m_gravity);
589 static int gConstraintUid = 1;
591 //Following the COLLADA physics specification for constraints
592 int CcdPhysicsEnvironment::createUniversalD6Constraint(
593 class PHY_IPhysicsController* ctrlRef,class PHY_IPhysicsController* ctrlOther,
594 btTransform& frameInA,
595 btTransform& frameInB,
596 const btVector3& linearMinLimits,
597 const btVector3& linearMaxLimits,
598 const btVector3& angularMinLimits,
599 const btVector3& angularMaxLimits
603 //we could either add some logic to recognize ball-socket and hinge, or let that up to the user
604 //perhaps some warning or hint that hinge/ball-socket is more efficient?
606 btGeneric6DofConstraint* genericConstraint = 0;
607 CcdPhysicsController* ctrl0 = (CcdPhysicsController*) ctrlRef;
608 CcdPhysicsController* ctrl1 = (CcdPhysicsController*) ctrlOther;
610 btRigidBody* rb0 = ctrl0->GetRigidBody();
611 btRigidBody* rb1 = ctrl1->GetRigidBody();
617 genericConstraint = new btGeneric6DofConstraint(
620 genericConstraint->setLinearLowerLimit(linearMinLimits);
621 genericConstraint->setLinearUpperLimit(linearMaxLimits);
622 genericConstraint->setAngularLowerLimit(angularMinLimits);
623 genericConstraint->setAngularUpperLimit(angularMaxLimits);
626 // TODO: Implement single body case...
627 //No, we can use a fixed rigidbody in above code, rather then unnecessary duplation of code
631 if (genericConstraint)
633 // m_constraints.push_back(genericConstraint);
634 m_dynamicsWorld->addConstraint(genericConstraint);
636 genericConstraint->setUserConstraintId(gConstraintUid++);
637 genericConstraint->setUserConstraintType(PHY_GENERIC_6DOF_CONSTRAINT);
638 //64 bit systems can't cast pointer to int. could use size_t instead.
639 return genericConstraint->getUserConstraintId();
646 void CcdPhysicsEnvironment::removeConstraint(int constraintId)
650 int numConstraints = m_dynamicsWorld->getNumConstraints();
651 for (i=0;i<numConstraints;i++)
653 btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i);
654 if (constraint->getUserConstraintId() == constraintId)
656 m_dynamicsWorld->removeConstraint(constraint);
663 struct FilterClosestRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
665 PHY_IPhysicsController* m_ignoreClient;
667 FilterClosestRayResultCallback (PHY_IPhysicsController* ignoreClient,const btVector3& rayFrom,const btVector3& rayTo)
668 : btCollisionWorld::ClosestRayResultCallback(rayFrom,rayTo),
669 m_ignoreClient(ignoreClient)
674 virtual ~FilterClosestRayResultCallback()
678 virtual float AddSingleResult( btCollisionWorld::LocalRayResult& rayResult)
680 CcdPhysicsController* curHit = static_cast<CcdPhysicsController*>(rayResult.m_collisionObject->getUserPointer());
682 if (curHit != m_ignoreClient)
685 return ClosestRayResultCallback::AddSingleResult(rayResult);
687 return m_closestHitFraction;
692 PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ,
693 float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
697 float minFraction = 1.f;
699 btVector3 rayFrom(fromX,fromY,fromZ);
700 btVector3 rayTo(toX,toY,toZ);
702 btVector3 hitPointWorld,normalWorld;
704 //Either Ray Cast with or without filtering
706 //btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
707 FilterClosestRayResultCallback rayCallback(ignoreClient,rayFrom,rayTo);
710 PHY_IPhysicsController* nearestHit = 0;
712 m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback);
713 if (rayCallback.HasHit())
715 nearestHit = static_cast<CcdPhysicsController*>(rayCallback.m_collisionObject->getUserPointer());
716 hitX = rayCallback.m_hitPointWorld.getX();
717 hitY = rayCallback.m_hitPointWorld.getY();
718 hitZ = rayCallback.m_hitPointWorld.getZ();
720 normalX = rayCallback.m_hitNormalWorld.getX();
721 normalY = rayCallback.m_hitNormalWorld.getY();
722 normalZ = rayCallback.m_hitNormalWorld.getZ();
732 int CcdPhysicsEnvironment::getNumContactPoints()
737 void CcdPhysicsEnvironment::getContactPoint(int i,float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
745 btBroadphaseInterface* CcdPhysicsEnvironment::getBroadphase()
747 return m_dynamicsWorld->getBroadphase();
753 CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
756 #ifdef NEW_BULLET_VEHICLE_SUPPORT
757 m_wrapperVehicles.clear();
758 #endif //NEW_BULLET_VEHICLE_SUPPORT
760 //m_broadphase->DestroyScene();
761 //delete broadphase ? release reference on broadphase ?
763 //first delete scene, then dispatcher, because pairs have to release manifolds on the dispatcher
764 //delete m_dispatcher;
765 delete m_dynamicsWorld;
772 int CcdPhysicsEnvironment::GetNumControllers()
774 return m_controllers.size();
778 CcdPhysicsController* CcdPhysicsEnvironment::GetPhysicsController( int index)
780 return m_controllers[index];
786 void CcdPhysicsEnvironment::setConstraintParam(int constraintId,int param,float value0,float value1)
788 btTypedConstraint* typedConstraint = getConstraintById(constraintId);
789 switch (typedConstraint->getUserConstraintType())
791 case PHY_GENERIC_6DOF_CONSTRAINT:
793 //param = 1..12, min0,max0,min1,max1...min6,max6
794 btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint;
795 genCons->SetLimit(param,value0,value1);
804 btTypedConstraint* CcdPhysicsEnvironment::getConstraintById(int constraintId)
807 int numConstraints = m_dynamicsWorld->getNumConstraints();
809 for (i=0;i<numConstraints;i++)
811 btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i);
812 if (constraint->getUserConstraintId()==constraintId)
821 void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
824 CcdPhysicsController* ctrl1 = (CcdPhysicsController* )ctrl;
825 std::vector<CcdPhysicsController*>::iterator i =
826 std::find(m_controllers.begin(), m_controllers.end(), ctrl);
827 if ((i == m_controllers.end()))
829 addCcdPhysicsController(ctrl1);
831 //force collision detection with everything, including static objects (might hurt performance!)
832 ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterMask = btBroadphaseProxy::AllFilter;
833 ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterGroup = btBroadphaseProxy::AllFilter;
834 //todo: make this 'sensor'!
836 requestCollisionCallback(ctrl);
837 //printf("addSensor\n");
840 void CcdPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl)
842 std::vector<CcdPhysicsController*>::iterator i =
843 std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
844 if (!(i == m_triggerControllers.end()))
846 std::swap(*i, m_triggerControllers.back());
847 m_triggerControllers.pop_back();
852 void CcdPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl)
854 removeCollisionCallback(ctrl);
855 //printf("removeSensor\n");
857 void CcdPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
859 /* printf("addTouchCallback\n(response class = %i)\n",response_class);
861 //map PHY_ convention into SM_ convention
862 switch (response_class)
864 case PHY_FH_RESPONSE:
865 printf("PHY_FH_RESPONSE\n");
867 case PHY_SENSOR_RESPONSE:
868 printf("PHY_SENSOR_RESPONSE\n");
870 case PHY_CAMERA_RESPONSE:
871 printf("PHY_CAMERA_RESPONSE\n");
873 case PHY_OBJECT_RESPONSE:
874 printf("PHY_OBJECT_RESPONSE\n");
876 case PHY_STATIC_RESPONSE:
877 printf("PHY_STATIC_RESPONSE\n");
885 m_triggerCallbacks[response_class] = callback;
886 m_triggerCallbacksUserPtrs[response_class] = user;
889 void CcdPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl)
891 CcdPhysicsController* ccdCtrl = static_cast<CcdPhysicsController*>(ctrl);
893 //printf("requestCollisionCallback\n");
894 m_triggerControllers.push_back(ccdCtrl);
898 void CcdPhysicsEnvironment::CallbackTriggers()
901 CcdPhysicsController* ctrl0=0,*ctrl1=0;
903 if (m_triggerCallbacks[PHY_OBJECT_RESPONSE] || (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)))
905 //walk over all overlapping pairs, and if one of the involved bodies is registered for trigger callback, perform callback
906 int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds();
907 for (int i=0;i<numManifolds;i++)
909 btPersistentManifold* manifold = m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
910 int numContacts = manifold->getNumContacts();
913 if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints))
915 for (int j=0;j<numContacts;j++)
917 btVector3 color(1,0,0);
918 const btManifoldPoint& cp = manifold->getContactPoint(j);
920 m_debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
923 btRigidBody* obj0 = static_cast<btRigidBody* >(manifold->getBody0());
924 btRigidBody* obj1 = static_cast<btRigidBody* >(manifold->getBody1());
926 //m_internalOwner is set in 'addPhysicsController'
927 CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->getUserPointer());
928 CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(obj1->getUserPointer());
930 std::vector<CcdPhysicsController*>::iterator i =
931 std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl0);
932 if (i == m_triggerControllers.end())
934 i = std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl1);
937 if (!(i == m_triggerControllers.end()))
939 m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE],
957 #ifdef NEW_BULLET_VEHICLE_SUPPORT
959 //complex constraint for vehicles
960 PHY_IVehicle* CcdPhysicsEnvironment::getVehicleConstraint(int constraintId)
964 int numVehicles = m_wrapperVehicles.size();
965 for (i=0;i<numVehicles;i++)
967 WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i];
968 if (wrapperVehicle->GetVehicle()->getUserConstraintId() == constraintId)
969 return wrapperVehicle;
975 #endif //NEW_BULLET_VEHICLE_SUPPORT
978 int currentController = 0;
979 int numController = 0;
984 PHY_IPhysicsController* CcdPhysicsEnvironment::CreateSphereController(float radius,const PHY__Vector3& position)
987 CcdConstructionInfo cinfo;
988 cinfo.m_collisionShape = new btSphereShape(radius);
989 cinfo.m_MotionState = 0;
990 cinfo.m_physicsEnv = this;
991 cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_KINEMATIC_OBJECT;
992 DefaultMotionState* motionState = new DefaultMotionState();
993 cinfo.m_MotionState = motionState;
994 motionState->m_worldTransform.setIdentity();
995 motionState->m_worldTransform.setOrigin(btVector3(position[0],position[1],position[2]));
997 CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo);
1000 return sphereController;
1003 int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl0,class PHY_IPhysicsController* ctrl1,PHY_ConstraintType type,
1004 float pivotX,float pivotY,float pivotZ,
1005 float axisX,float axisY,float axisZ,
1006 float axis1X,float axis1Y,float axis1Z,
1007 float axis2X,float axis2Y,float axis2Z
1012 CcdPhysicsController* c0 = (CcdPhysicsController*)ctrl0;
1013 CcdPhysicsController* c1 = (CcdPhysicsController*)ctrl1;
1015 btRigidBody* rb0 = c0 ? c0->GetRigidBody() : 0;
1016 btRigidBody* rb1 = c1 ? c1->GetRigidBody() : 0;
1018 bool rb0static = rb0 ? rb0->isStaticOrKinematicObject() : true;
1019 bool rb1static = rb1 ? rb1->isStaticOrKinematicObject() : true;
1022 if (rb0static && rb1static)
1025 btVector3 pivotInA(pivotX,pivotY,pivotZ);
1026 btVector3 pivotInB = rb1 ? rb1->getCenterOfMassTransform().inverse()(rb0->getCenterOfMassTransform()(pivotInA)) :
1027 rb0->getCenterOfMassTransform() * pivotInA;
1028 btVector3 axisInA(axisX,axisY,axisZ);
1029 btVector3 axisInB = rb1 ?
1030 (rb1->getCenterOfMassTransform().getBasis().inverse()*(rb0->getCenterOfMassTransform().getBasis() * axisInA)) :
1031 rb0->getCenterOfMassTransform().getBasis() * axisInA;
1033 bool angularOnly = false;
1037 case PHY_POINT2POINT_CONSTRAINT:
1040 btPoint2PointConstraint* p2p = 0;
1044 p2p = new btPoint2PointConstraint(*rb0,
1045 *rb1,pivotInA,pivotInB);
1048 p2p = new btPoint2PointConstraint(*rb0,
1052 m_dynamicsWorld->addConstraint(p2p);
1053 // m_constraints.push_back(p2p);
1055 p2p->setUserConstraintId(gConstraintUid++);
1056 p2p->setUserConstraintType(type);
1057 //64 bit systems can't cast pointer to int. could use size_t instead.
1058 return p2p->getUserConstraintId();
1063 case PHY_GENERIC_6DOF_CONSTRAINT:
1065 btGeneric6DofConstraint* genericConstraint = 0;
1069 btTransform frameInA;
1070 btTransform frameInB;
1072 btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z);
1073 if (axis1.length() == 0.0)
1075 btPlaneSpace1( axisInA, axis1, axis2 );
1078 frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(),
1079 axisInA.y(), axis1.y(), axis2.y(),
1080 axisInA.z(), axis1.z(), axis2.z() );
1083 btPlaneSpace1( axisInB, axis1, axis2 );
1084 frameInB.getBasis().setValue( axisInB.x(), axis1.x(), axis2.x(),
1085 axisInB.y(), axis1.y(), axis2.y(),
1086 axisInB.z(), axis1.z(), axis2.z() );
1088 frameInA.setOrigin( pivotInA );
1089 frameInB.setOrigin( pivotInB );
1091 genericConstraint = new btGeneric6DofConstraint(
1098 static btRigidBody s_fixedObject2( 0,0,0);
1099 btTransform frameInA;
1100 btTransform frameInB;
1102 btVector3 axis1, axis2;
1103 btPlaneSpace1( axisInA, axis1, axis2 );
1105 frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(),
1106 axisInA.y(), axis1.y(), axis2.y(),
1107 axisInA.z(), axis1.z(), axis2.z() );
1110 btPlaneSpace1( axisInB, axis1, axis2 );
1111 frameInB.getBasis().setValue( axisInB.x(), axis1.x(), axis2.x(),
1112 axisInB.y(), axis1.y(), axis2.y(),
1113 axisInB.z(), axis1.z(), axis2.z() );
1115 frameInA.setOrigin( pivotInA );
1116 frameInB.setOrigin( pivotInB );
1119 genericConstraint = new btGeneric6DofConstraint(
1120 *rb0,s_fixedObject2,
1124 if (genericConstraint)
1126 //m_constraints.push_back(genericConstraint);
1127 m_dynamicsWorld->addConstraint(genericConstraint);
1128 genericConstraint->setUserConstraintId(gConstraintUid++);
1129 genericConstraint->setUserConstraintType(type);
1130 //64 bit systems can't cast pointer to int. could use size_t instead.
1131 return genericConstraint->getUserConstraintId();
1136 case PHY_ANGULAR_CONSTRAINT:
1140 case PHY_LINEHINGE_CONSTRAINT:
1142 btHingeConstraint* hinge = 0;
1146 hinge = new btHingeConstraint(
1148 *rb1,pivotInA,pivotInB,axisInA,axisInB);
1153 hinge = new btHingeConstraint(*rb0,
1157 hinge->setAngularOnly(angularOnly);
1159 //m_constraints.push_back(hinge);
1160 m_dynamicsWorld->addConstraint(hinge);
1161 hinge->setUserConstraintId(gConstraintUid++);
1162 hinge->setUserConstraintType(type);
1163 //64 bit systems can't cast pointer to int. could use size_t instead.
1164 return hinge->getUserConstraintId();
1167 #ifdef NEW_BULLET_VEHICLE_SUPPORT
1169 case PHY_VEHICLE_CONSTRAINT:
1171 btRaycastVehicle::btVehicleTuning* tuning = new btRaycastVehicle::btVehicleTuning();
1172 btRigidBody* chassis = rb0;
1173 btDefaultVehicleRaycaster* raycaster = new btDefaultVehicleRaycaster(m_dynamicsWorld);
1174 btRaycastVehicle* vehicle = new btRaycastVehicle(*tuning,chassis,raycaster);
1175 WrapperVehicle* wrapperVehicle = new WrapperVehicle(vehicle,ctrl0);
1176 m_wrapperVehicles.push_back(wrapperVehicle);
1177 m_dynamicsWorld->addVehicle(vehicle);
1178 vehicle->setUserConstraintId(gConstraintUid++);
1179 vehicle->setUserConstraintType(type);
1180 return vehicle->getUserConstraintId();
1184 #endif //NEW_BULLET_VEHICLE_SUPPORT
1191 //btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB
1199 PHY_IPhysicsController* CcdPhysicsEnvironment::CreateConeController(float coneradius,float coneheight)
1201 CcdConstructionInfo cinfo;
1202 cinfo.m_collisionShape = new btConeShape(coneradius,coneheight);
1203 cinfo.m_MotionState = 0;
1204 cinfo.m_physicsEnv = this;
1205 cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
1206 DefaultMotionState* motionState = new DefaultMotionState();
1207 cinfo.m_MotionState = motionState;
1208 motionState->m_worldTransform.setIdentity();
1209 // motionState->m_worldTransform.setOrigin(btVector3(position[0],position[1],position[2]));
1211 CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo);
1214 return sphereController;
1217 float CcdPhysicsEnvironment::getAppliedImpulse(int constraintid)
1220 int numConstraints = m_dynamicsWorld->getNumConstraints();
1221 for (i=0;i<numConstraints;i++)
1223 btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i);
1224 if (constraint->getUserConstraintId() == constraintid)
1226 return constraint->getAppliedImpulse();