PhysicsController.cpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255
  1. #include "Base.h"
  2. #include "PhysicsController.h"
  3. #include "PhysicsRigidBody.h"
  4. #include "PhysicsCharacter.h"
  5. #include "PhysicsMotionState.h"
  6. #include "Game.h"
  7. #include "MeshPart.h"
  8. #include "Bundle.h"
  9. #include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
  10. // The initial capacity of the Bullet debug drawer's vertex batch.
  11. #define INITIAL_CAPACITY 280
  12. namespace gameplay
  13. {
  14. const int PhysicsController::DIRTY = 0x01;
  15. const int PhysicsController::COLLISION = 0x02;
  16. const int PhysicsController::REGISTERED = 0x04;
  17. const int PhysicsController::REMOVE = 0x08;
  18. PhysicsController::PhysicsController()
  19. : _collisionConfiguration(NULL), _dispatcher(NULL),
  20. _overlappingPairCache(NULL), _solver(NULL), _world(NULL), _ghostPairCallback(NULL),
  21. _debugDrawer(NULL), _status(PhysicsController::Listener::DEACTIVATED), _listeners(NULL),
  22. _gravity(btScalar(0.0), btScalar(-9.8), btScalar(0.0))
  23. {
  24. // Default gravity is 9.8 along the negative Y axis.
  25. }
  26. PhysicsController::~PhysicsController()
  27. {
  28. SAFE_DELETE(_ghostPairCallback);
  29. SAFE_DELETE(_debugDrawer);
  30. SAFE_DELETE(_listeners);
  31. }
  32. void PhysicsController::addStatusListener(Listener* listener)
  33. {
  34. if (!_listeners)
  35. _listeners = new std::vector<Listener*>();
  36. _listeners->push_back(listener);
  37. }
  38. PhysicsFixedConstraint* PhysicsController::createFixedConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b)
  39. {
  40. checkConstraintRigidBodies(a, b);
  41. PhysicsFixedConstraint* constraint = new PhysicsFixedConstraint(a, b);
  42. addConstraint(a, b, constraint);
  43. return constraint;
  44. }
  45. PhysicsGenericConstraint* PhysicsController::createGenericConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b)
  46. {
  47. checkConstraintRigidBodies(a, b);
  48. PhysicsGenericConstraint* constraint = new PhysicsGenericConstraint(a, b);
  49. addConstraint(a, b, constraint);
  50. return constraint;
  51. }
  52. PhysicsGenericConstraint* PhysicsController::createGenericConstraint(PhysicsRigidBody* a,
  53. const Quaternion& rotationOffsetA, const Vector3& translationOffsetA, PhysicsRigidBody* b,
  54. const Quaternion& rotationOffsetB, const Vector3& translationOffsetB)
  55. {
  56. checkConstraintRigidBodies(a, b);
  57. PhysicsGenericConstraint* constraint = new PhysicsGenericConstraint(a, rotationOffsetA, translationOffsetA, b, rotationOffsetB, translationOffsetB);
  58. addConstraint(a, b, constraint);
  59. return constraint;
  60. }
  61. PhysicsHingeConstraint* PhysicsController::createHingeConstraint(PhysicsRigidBody* a,
  62. const Quaternion& rotationOffsetA, const Vector3& translationOffsetA, PhysicsRigidBody* b,
  63. const Quaternion& rotationOffsetB, const Vector3& translationOffsetB)
  64. {
  65. checkConstraintRigidBodies(a, b);
  66. PhysicsHingeConstraint* constraint = new PhysicsHingeConstraint(a, rotationOffsetA, translationOffsetA, b, rotationOffsetB, translationOffsetB);
  67. addConstraint(a, b, constraint);
  68. return constraint;
  69. }
  70. PhysicsSocketConstraint* PhysicsController::createSocketConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b)
  71. {
  72. checkConstraintRigidBodies(a, b);
  73. PhysicsSocketConstraint* constraint = new PhysicsSocketConstraint(a, b);
  74. addConstraint(a, b, constraint);
  75. return constraint;
  76. }
  77. PhysicsSocketConstraint* PhysicsController::createSocketConstraint(PhysicsRigidBody* a,
  78. const Vector3& translationOffsetA, PhysicsRigidBody* b, const Vector3& translationOffsetB)
  79. {
  80. checkConstraintRigidBodies(a, b);
  81. PhysicsSocketConstraint* constraint = new PhysicsSocketConstraint(a,translationOffsetA, b, translationOffsetB);
  82. addConstraint(a, b, constraint);
  83. return constraint;
  84. }
  85. PhysicsSpringConstraint* PhysicsController::createSpringConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b)
  86. {
  87. checkConstraintRigidBodies(a, b);
  88. PhysicsSpringConstraint* constraint = new PhysicsSpringConstraint(a, b);
  89. addConstraint(a, b, constraint);
  90. return constraint;
  91. }
  92. PhysicsSpringConstraint* PhysicsController::createSpringConstraint(PhysicsRigidBody* a, const Quaternion& rotationOffsetA, const Vector3& translationOffsetA,
  93. PhysicsRigidBody* b, const Quaternion& rotationOffsetB, const Vector3& translationOffsetB)
  94. {
  95. checkConstraintRigidBodies(a, b);
  96. PhysicsSpringConstraint* constraint = new PhysicsSpringConstraint(a, rotationOffsetA, translationOffsetA, b, rotationOffsetB, translationOffsetB);
  97. addConstraint(a, b, constraint);
  98. return constraint;
  99. }
  100. const Vector3& PhysicsController::getGravity() const
  101. {
  102. return _gravity;
  103. }
  104. void PhysicsController::setGravity(const Vector3& gravity)
  105. {
  106. _gravity = gravity;
  107. if (_world)
  108. _world->setGravity(BV(_gravity));
  109. }
  110. void PhysicsController::drawDebug(const Matrix& viewProjection)
  111. {
  112. _debugDrawer->begin(viewProjection);
  113. _world->debugDrawWorld();
  114. _debugDrawer->end();
  115. }
  116. bool PhysicsController::rayTest(const Ray& ray, float distance, PhysicsController::HitResult* result)
  117. {
  118. btCollisionWorld::ClosestRayResultCallback callback(BV(ray.getOrigin()), BV(distance * ray.getDirection()));
  119. _world->rayTest(BV(ray.getOrigin()), BV(distance * ray.getDirection()), callback);
  120. if (callback.hasHit())
  121. {
  122. if (result)
  123. {
  124. result->object = getCollisionObject(callback.m_collisionObject);
  125. result->point.set(callback.m_hitPointWorld.x(), callback.m_hitPointWorld.y(), callback.m_hitPointWorld.z());
  126. result->fraction = callback.m_closestHitFraction;
  127. result->normal.set(callback.m_hitNormalWorld.x(), callback.m_hitNormalWorld.y(), callback.m_hitNormalWorld.z());
  128. }
  129. return true;
  130. }
  131. return false;
  132. }
  133. bool PhysicsController::sweepTest(PhysicsCollisionObject* object, const Vector3& endPosition, PhysicsController::HitResult* result)
  134. {
  135. class SweepTestCallback : public btCollisionWorld::ClosestConvexResultCallback
  136. {
  137. public:
  138. SweepTestCallback(PhysicsCollisionObject* me)
  139. : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)), me(me)
  140. {
  141. }
  142. btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult, bool normalInWorldSpace)
  143. {
  144. PhysicsCollisionObject* object = reinterpret_cast<PhysicsCollisionObject*>(convexResult.m_hitCollisionObject->getUserPointer());
  145. if (object == me)
  146. return 1.0f;
  147. return ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
  148. }
  149. PhysicsCollisionObject* me;
  150. };
  151. PhysicsCollisionShape* shape = object->getCollisionShape();
  152. PhysicsCollisionShape::Type type = shape->getType();
  153. if (type != PhysicsCollisionShape::SHAPE_BOX && type != PhysicsCollisionShape::SHAPE_SPHERE && type != PhysicsCollisionShape::SHAPE_CAPSULE)
  154. return false; // unsupported type
  155. // Define the start transform
  156. btTransform start;
  157. if (object->getNode())
  158. start.setFromOpenGLMatrix(object->getNode()->getWorldMatrix().m);
  159. else
  160. start.setIdentity();
  161. // Define the end transform
  162. btTransform end(start);
  163. end.setOrigin(BV(endPosition));
  164. // Perform bullet convex sweep test
  165. SweepTestCallback callback(object);
  166. // If the object is represented by a ghost object, use the ghost object's convex sweep test
  167. // since it is much faster than the world's version.
  168. /*switch (object->getType())
  169. {
  170. case PhysicsCollisionObject::GHOST_OBJECT:
  171. case PhysicsCollisionObject::CHARACTER:
  172. static_cast<PhysicsGhostObject*>(object)->_ghostObject->convexSweepTest(static_cast<btConvexShape*>(shape->getShape()), start, end, callback, _world->getDispatchInfo().m_allowedCcdPenetration);
  173. break;
  174. default:
  175. _world->convexSweepTest(static_cast<btConvexShape*>(shape->getShape()), start, end, callback, _world->getDispatchInfo().m_allowedCcdPenetration);
  176. break;
  177. }
  178. */
  179. _world->convexSweepTest(static_cast<btConvexShape*>(shape->getShape()), start, end, callback, _world->getDispatchInfo().m_allowedCcdPenetration);
  180. // Check for hits and store results
  181. if (callback.hasHit())
  182. {
  183. if (result)
  184. {
  185. result->object = getCollisionObject(callback.m_hitCollisionObject);
  186. result->point.set(callback.m_hitPointWorld.x(), callback.m_hitPointWorld.y(), callback.m_hitPointWorld.z());
  187. result->fraction = callback.m_closestHitFraction;
  188. result->normal.set(callback.m_hitNormalWorld.x(), callback.m_hitNormalWorld.y(), callback.m_hitNormalWorld.z());
  189. }
  190. return true;
  191. }
  192. return false;
  193. }
  194. btScalar PhysicsController::addSingleResult(btManifoldPoint& cp, const btCollisionObject* a, int partIdA, int indexA,
  195. const btCollisionObject* b, int partIdB, int indexB)
  196. {
  197. // Get pointers to the PhysicsCollisionObject objects.
  198. PhysicsCollisionObject* rbA = Game::getInstance()->getPhysicsController()->getCollisionObject(a);
  199. PhysicsCollisionObject* rbB = Game::getInstance()->getPhysicsController()->getCollisionObject(b);
  200. // If the given rigid body pair has collided in the past, then
  201. // we notify the listeners only if the pair was not colliding
  202. // during the previous frame. Otherwise, it's a new pair, so add a
  203. // new entry to the cache with the appropriate listeners and notify them.
  204. PhysicsCollisionObject::CollisionPair pair(rbA, rbB);
  205. CollisionInfo* collisionInfo;
  206. if (_collisionStatus.count(pair) > 0)
  207. {
  208. collisionInfo = &_collisionStatus[pair];
  209. }
  210. else
  211. {
  212. // Add a new collision pair for these objects
  213. collisionInfo = &_collisionStatus[pair];
  214. // Add the appropriate listeners.
  215. PhysicsCollisionObject::CollisionPair p1(pair.objectA, NULL);
  216. if (_collisionStatus.count(p1) > 0)
  217. {
  218. const CollisionInfo& ci = _collisionStatus[p1];
  219. std::vector<PhysicsCollisionObject::CollisionListener*>::const_iterator iter = ci._listeners.begin();
  220. for (; iter != ci._listeners.end(); iter++)
  221. {
  222. collisionInfo->_listeners.push_back(*iter);
  223. }
  224. }
  225. PhysicsCollisionObject::CollisionPair p2(pair.objectB, NULL);
  226. if (_collisionStatus.count(p2) > 0)
  227. {
  228. const CollisionInfo& ci = _collisionStatus[p2];
  229. std::vector<PhysicsCollisionObject::CollisionListener*>::const_iterator iter = ci._listeners.begin();
  230. for (; iter != ci._listeners.end(); iter++)
  231. {
  232. collisionInfo->_listeners.push_back(*iter);
  233. }
  234. }
  235. }
  236. // Fire collision event
  237. if ((collisionInfo->_status & COLLISION) == 0)
  238. {
  239. std::vector<PhysicsCollisionObject::CollisionListener*>::const_iterator iter = collisionInfo->_listeners.begin();
  240. for (; iter != collisionInfo->_listeners.end(); iter++)
  241. {
  242. if ((collisionInfo->_status & REMOVE) == 0)
  243. {
  244. (*iter)->collisionEvent(PhysicsCollisionObject::CollisionListener::COLLIDING, pair, Vector3(cp.getPositionWorldOnA().x(), cp.getPositionWorldOnA().y(), cp.getPositionWorldOnA().z()),
  245. Vector3(cp.getPositionWorldOnB().x(), cp.getPositionWorldOnB().y(), cp.getPositionWorldOnB().z()));
  246. }
  247. }
  248. }
  249. // Update the collision status cache (we remove the dirty bit
  250. // set in the controller's update so that this particular collision pair's
  251. // status is not reset to 'no collision' when the controller's update completes).
  252. collisionInfo->_status &= ~DIRTY;
  253. collisionInfo->_status |= COLLISION;
  254. return 0.0f;
  255. }
  256. void PhysicsController::initialize()
  257. {
  258. _collisionConfiguration = new btDefaultCollisionConfiguration();
  259. _dispatcher = new btCollisionDispatcher(_collisionConfiguration);
  260. _overlappingPairCache = new btDbvtBroadphase();
  261. _solver = new btSequentialImpulseConstraintSolver();
  262. // Create the world.
  263. _world = new btDiscreteDynamicsWorld(_dispatcher, _overlappingPairCache, _solver, _collisionConfiguration);
  264. _world->setGravity(BV(_gravity));
  265. // Register ghost pair callback so bullet detects collisions with ghost objects (used for character collisions).
  266. _ghostPairCallback = bullet_new<btGhostPairCallback>();
  267. _world->getPairCache()->setInternalGhostPairCallback(_ghostPairCallback);
  268. _world->getDispatchInfo().m_allowedCcdPenetration = 0.0001f;
  269. // Set up debug drawing.
  270. _debugDrawer = new DebugDrawer();
  271. _world->setDebugDrawer(_debugDrawer);
  272. }
  273. void PhysicsController::finalize()
  274. {
  275. // Clean up the world and its various components.
  276. SAFE_DELETE(_world);
  277. SAFE_DELETE(_ghostPairCallback);
  278. SAFE_DELETE(_solver);
  279. SAFE_DELETE(_overlappingPairCache);
  280. SAFE_DELETE(_dispatcher);
  281. SAFE_DELETE(_collisionConfiguration);
  282. }
  283. void PhysicsController::pause()
  284. {
  285. // Unused
  286. }
  287. void PhysicsController::resume()
  288. {
  289. // Unused
  290. }
  291. void PhysicsController::update(long elapsedTime)
  292. {
  293. // Update the physics simulation, with a maximum
  294. // of 10 simulation steps being performed in a given frame.
  295. //
  296. // Note that stepSimulation takes elapsed time in seconds
  297. // so we divide by 1000 to convert from milliseconds.
  298. _world->stepSimulation((float)elapsedTime * 0.001, 10);
  299. // If we have status listeners, then check if our status has changed.
  300. if (_listeners)
  301. {
  302. Listener::EventType oldStatus = _status;
  303. if (_status == Listener::DEACTIVATED)
  304. {
  305. for (int i = 0; i < _world->getNumCollisionObjects(); i++)
  306. {
  307. if (_world->getCollisionObjectArray()[i]->isActive())
  308. {
  309. _status = Listener::ACTIVATED;
  310. break;
  311. }
  312. }
  313. }
  314. else
  315. {
  316. bool allInactive = true;
  317. for (int i = 0; i < _world->getNumCollisionObjects(); i++)
  318. {
  319. if (_world->getCollisionObjectArray()[i]->isActive())
  320. {
  321. allInactive = false;
  322. break;
  323. }
  324. }
  325. if (allInactive)
  326. _status = Listener::DEACTIVATED;
  327. }
  328. // If the status has changed, notify our listeners.
  329. if (oldStatus != _status)
  330. {
  331. for (unsigned int k = 0; k < _listeners->size(); k++)
  332. {
  333. (*_listeners)[k]->statusEvent(_status);
  334. }
  335. }
  336. }
  337. // All statuses are set with the DIRTY bit before collision processing occurs.
  338. // During collision processing, if a collision occurs, the status is
  339. // set to COLLISION and the DIRTY bit is cleared. Then, after collision processing
  340. // is finished, if a given status is still dirty, the COLLISION bit is cleared.
  341. //
  342. // If an entry was marked for removal in the last frame, remove it now.
  343. // Dirty the collision status cache entries.
  344. std::map<PhysicsCollisionObject::CollisionPair, CollisionInfo>::iterator iter = _collisionStatus.begin();
  345. for (; iter != _collisionStatus.end();)
  346. {
  347. if ((iter->second._status & REMOVE) != 0)
  348. {
  349. std::map<PhysicsCollisionObject::CollisionPair, CollisionInfo>::iterator eraseIter = iter;
  350. iter++;
  351. _collisionStatus.erase(eraseIter);
  352. }
  353. else
  354. {
  355. iter->second._status |= DIRTY;
  356. iter++;
  357. }
  358. }
  359. // Go through the collision status cache and perform all registered collision tests.
  360. iter = _collisionStatus.begin();
  361. for (; iter != _collisionStatus.end(); iter++)
  362. {
  363. // If this collision pair was one that was registered for listening, then perform the collision test.
  364. // (In the case where we register for all collisions with a rigid body, there will be a lot
  365. // of collision pairs in the status cache that we did not explicitly register for.)
  366. if ((iter->second._status & REGISTERED) != 0 && (iter->second._status & REMOVE) == 0)
  367. {
  368. if (iter->first.objectB)
  369. _world->contactPairTest(iter->first.objectA->getCollisionObject(), iter->first.objectB->getCollisionObject(), *this);
  370. else
  371. _world->contactTest(iter->first.objectA->getCollisionObject(), *this);
  372. }
  373. }
  374. // Update all the collision status cache entries.
  375. iter = _collisionStatus.begin();
  376. for (; iter != _collisionStatus.end(); iter++)
  377. {
  378. if ((iter->second._status & DIRTY) != 0)
  379. {
  380. if ((iter->second._status & COLLISION) != 0 && iter->first.objectB)
  381. {
  382. unsigned int size = iter->second._listeners.size();
  383. for (unsigned int i = 0; i < size; i++)
  384. {
  385. iter->second._listeners[i]->collisionEvent(PhysicsCollisionObject::CollisionListener::NOT_COLLIDING, iter->first);
  386. }
  387. }
  388. iter->second._status &= ~COLLISION;
  389. }
  390. }
  391. }
  392. void PhysicsController::addCollisionListener(PhysicsCollisionObject::CollisionListener* listener, PhysicsCollisionObject* objectA, PhysicsCollisionObject* objectB)
  393. {
  394. PhysicsCollisionObject::CollisionPair pair(objectA, objectB);
  395. // Add the listener and ensure the status includes that this collision pair is registered.
  396. CollisionInfo& info = _collisionStatus[pair];
  397. info._listeners.push_back(listener);
  398. info._status |= PhysicsController::REGISTERED;
  399. }
  400. void PhysicsController::removeCollisionListener(PhysicsCollisionObject::CollisionListener* listener, PhysicsCollisionObject* objectA, PhysicsCollisionObject* objectB)
  401. {
  402. // Mark the collision pair for these objects for removal
  403. PhysicsCollisionObject::CollisionPair pair(objectA, objectB);
  404. if (_collisionStatus.count(pair) > 0)
  405. {
  406. _collisionStatus[pair]._status |= REMOVE;
  407. }
  408. }
  409. void PhysicsController::addCollisionObject(PhysicsCollisionObject* object)
  410. {
  411. // Assign user pointer for the bullet collision object to allow efficient
  412. // lookups of bullet objects -> gameplay objects.
  413. object->getCollisionObject()->setUserPointer(object);
  414. // Add the object to the physics world
  415. switch (object->getType())
  416. {
  417. case PhysicsCollisionObject::RIGID_BODY:
  418. _world->addRigidBody(static_cast<btRigidBody*>(object->getCollisionObject()), btBroadphaseProxy::DefaultFilter, btBroadphaseProxy::DefaultFilter | btBroadphaseProxy::StaticFilter | btBroadphaseProxy::CharacterFilter | btBroadphaseProxy::AllFilter);
  419. break;
  420. case PhysicsCollisionObject::CHARACTER:
  421. _world->addCollisionObject(object->getCollisionObject(), btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::DefaultFilter | btBroadphaseProxy::StaticFilter | btBroadphaseProxy::CharacterFilter | btBroadphaseProxy::AllFilter);
  422. break;
  423. case PhysicsCollisionObject::GHOST_OBJECT:
  424. _world->addCollisionObject(object->getCollisionObject(), btBroadphaseProxy::DefaultFilter, btBroadphaseProxy::DefaultFilter | btBroadphaseProxy::StaticFilter | btBroadphaseProxy::CharacterFilter | btBroadphaseProxy::AllFilter);
  425. break;
  426. default:
  427. assert(0); // unexpected (new type?)
  428. break;
  429. }
  430. }
  431. void PhysicsController::removeCollisionObject(PhysicsCollisionObject* object)
  432. {
  433. // Remove the collision object from the world
  434. if (object->getCollisionObject())
  435. {
  436. switch (object->getType())
  437. {
  438. case PhysicsCollisionObject::RIGID_BODY:
  439. _world->removeRigidBody(static_cast<btRigidBody*>(object->getCollisionObject()));
  440. break;
  441. case PhysicsCollisionObject::CHARACTER:
  442. case PhysicsCollisionObject::GHOST_OBJECT:
  443. _world->removeCollisionObject(object->getCollisionObject());
  444. break;
  445. default:
  446. assert(0); // unexpected (new type?)
  447. break;
  448. }
  449. }
  450. // Find all references to the object in the collision status cache and mark them for removal.
  451. std::map<PhysicsCollisionObject::CollisionPair, CollisionInfo>::iterator iter = _collisionStatus.begin();
  452. for (; iter != _collisionStatus.end(); iter++)
  453. {
  454. if (iter->first.objectA == object || iter->first.objectB == object)
  455. iter->second._status |= REMOVE;
  456. }
  457. }
  458. PhysicsCollisionObject* PhysicsController::getCollisionObject(const btCollisionObject* collisionObject) const
  459. {
  460. // Gameplay rigid bodies are stored in the userPointer data of bullet collision objects
  461. return reinterpret_cast<PhysicsCollisionObject*>(collisionObject->getUserPointer());
  462. }
  463. void getBoundingBox(Node* node, BoundingBox* out, bool merge = false)
  464. {
  465. if (node->getModel())
  466. {
  467. if (merge)
  468. out->merge(node->getModel()->getMesh()->getBoundingBox());
  469. else
  470. {
  471. out->set(node->getModel()->getMesh()->getBoundingBox());
  472. merge = true;
  473. }
  474. }
  475. Node* child = node->getFirstChild();
  476. while (child)
  477. {
  478. getBoundingBox(child, out, merge);
  479. child = child->getNextSibling();
  480. }
  481. }
  482. void getBoundingSphere(Node* node, BoundingSphere* out, bool merge = false)
  483. {
  484. if (node->getModel())
  485. {
  486. if (merge)
  487. out->merge(node->getModel()->getMesh()->getBoundingSphere());
  488. else
  489. {
  490. out->set(node->getModel()->getMesh()->getBoundingSphere());
  491. merge = true;
  492. }
  493. }
  494. Node* child = node->getFirstChild();
  495. while (child)
  496. {
  497. getBoundingSphere(child, out, merge);
  498. child = child->getNextSibling();
  499. }
  500. }
  501. void computeCenterOfMass(const Vector3& center, const Vector3& scale, Vector3* centerOfMassOffset)
  502. {
  503. // Update center of mass offset
  504. *centerOfMassOffset = center;
  505. centerOfMassOffset->x *= scale.x;
  506. centerOfMassOffset->y *= scale.y;
  507. centerOfMassOffset->z *= scale.z;
  508. centerOfMassOffset->negate();
  509. }
  510. PhysicsCollisionShape* PhysicsController::createShape(Node* node, const PhysicsCollisionShape::Definition& shape, Vector3* centerOfMassOffset)
  511. {
  512. PhysicsCollisionShape* collisionShape = NULL;
  513. // Get the node's world scale (we need to apply this during creation since rigid bodies don't scale dynamically).
  514. Vector3 scale;
  515. node->getWorldMatrix().getScale(&scale);
  516. switch (shape.type)
  517. {
  518. case PhysicsCollisionShape::SHAPE_BOX:
  519. {
  520. if (shape.isExplicit)
  521. {
  522. // Use the passed in box information
  523. collisionShape = createBox(Vector3(shape.data.box.extents), Vector3::one());
  524. if (shape.centerAbsolute)
  525. {
  526. computeCenterOfMass(Vector3(shape.data.box.center), Vector3::one(), centerOfMassOffset);
  527. }
  528. else
  529. {
  530. BoundingBox box;
  531. getBoundingBox(node, &box);
  532. computeCenterOfMass(box.getCenter() + Vector3(shape.data.box.center), scale, centerOfMassOffset);
  533. }
  534. }
  535. else
  536. {
  537. // Automatically compute bounding box from mesh's bounding box
  538. BoundingBox box;
  539. getBoundingBox(node, &box);
  540. collisionShape = createBox(Vector3(std::abs(box.max.x - box.min.x), std::abs(box.max.y - box.min.y), std::abs(box.max.z - box.min.z)), scale);
  541. computeCenterOfMass(box.getCenter(), scale, centerOfMassOffset);
  542. }
  543. }
  544. break;
  545. case PhysicsCollisionShape::SHAPE_SPHERE:
  546. {
  547. if (shape.isExplicit)
  548. {
  549. // Use the passed in sphere information
  550. collisionShape = createSphere(shape.data.sphere.radius, Vector3::one());
  551. if (shape.centerAbsolute)
  552. {
  553. computeCenterOfMass(Vector3(shape.data.sphere.center), Vector3::one(), centerOfMassOffset);
  554. }
  555. else
  556. {
  557. BoundingSphere sphere;
  558. getBoundingSphere(node, &sphere);
  559. computeCenterOfMass(sphere.center + Vector3(shape.data.sphere.center), scale, centerOfMassOffset);
  560. }
  561. }
  562. else
  563. {
  564. // Automatically compute bounding sphere from mesh's bounding sphere
  565. BoundingSphere sphere;
  566. getBoundingSphere(node, &sphere);
  567. collisionShape = createSphere(sphere.radius, scale);
  568. computeCenterOfMass(sphere.center, scale, centerOfMassOffset);
  569. }
  570. }
  571. break;
  572. case PhysicsCollisionShape::SHAPE_CAPSULE:
  573. {
  574. if (shape.isExplicit)
  575. {
  576. // Use the passed in capsule information
  577. collisionShape = createCapsule(shape.data.capsule.radius, shape.data.capsule.height, Vector3::one());
  578. if (shape.centerAbsolute)
  579. {
  580. computeCenterOfMass(Vector3(shape.data.capsule.center), Vector3::one(), centerOfMassOffset);
  581. }
  582. else
  583. {
  584. BoundingBox box;
  585. getBoundingBox(node, &box);
  586. computeCenterOfMass(box.getCenter() + Vector3(shape.data.capsule.center), scale, centerOfMassOffset);
  587. }
  588. }
  589. else
  590. {
  591. // Compute a capsule shape that roughly matches the bounding box of the mesh
  592. BoundingBox box;
  593. getBoundingBox(node, &box);
  594. float radius = std::max((box.max.x - box.min.x) * 0.5f, (box.max.z - box.min.z) * 0.5f);
  595. float height = box.max.y - box.min.y;
  596. collisionShape = createCapsule(radius, height, scale);
  597. computeCenterOfMass(box.getCenter(), scale, centerOfMassOffset);
  598. }
  599. }
  600. break;
  601. case PhysicsCollisionShape::SHAPE_HEIGHTFIELD:
  602. {
  603. // Build heightfield rigid body from the passed in shape
  604. collisionShape = createHeightfield(node, shape.data.heightfield, centerOfMassOffset);
  605. }
  606. break;
  607. case PhysicsCollisionShape::SHAPE_MESH:
  608. {
  609. // Build mesh from passed in shape
  610. collisionShape = createMesh(shape.data.mesh, scale);
  611. }
  612. break;
  613. }
  614. return collisionShape;
  615. }
  616. PhysicsCollisionShape* PhysicsController::createBox(const Vector3& extents, const Vector3& scale)
  617. {
  618. btVector3 halfExtents(scale.x * 0.5 * extents.x, scale.y * 0.5 * extents.y, scale.z * 0.5 * extents.z);
  619. PhysicsCollisionShape* shape;
  620. // Return the box shape from the cache if it already exists.
  621. for (unsigned int i = 0; i < _shapes.size(); ++i)
  622. {
  623. shape = _shapes[i];
  624. if (shape->getType() == PhysicsCollisionShape::SHAPE_BOX)
  625. {
  626. btBoxShape* box = static_cast<btBoxShape*>(shape->_shape);
  627. if (box->getHalfExtentsWithMargin() == halfExtents)
  628. {
  629. shape->addRef();
  630. return shape;
  631. }
  632. }
  633. }
  634. // Create the box shape and add it to the cache.
  635. shape = new PhysicsCollisionShape(PhysicsCollisionShape::SHAPE_BOX, bullet_new<btBoxShape>(halfExtents));
  636. _shapes.push_back(shape);
  637. return shape;
  638. }
  639. PhysicsCollisionShape* PhysicsController::createSphere(float radius, const Vector3& scale)
  640. {
  641. // Since sphere shapes depend only on the radius, the best we can do is take
  642. // the largest dimension and apply that as the uniform scale to the rigid body.
  643. float uniformScale = scale.x;
  644. if (uniformScale < scale.y)
  645. uniformScale = scale.y;
  646. if (uniformScale < scale.z)
  647. uniformScale = scale.z;
  648. float scaledRadius = radius * uniformScale;
  649. PhysicsCollisionShape* shape;
  650. // Return the sphere shape from the cache if it already exists.
  651. for (unsigned int i = 0; i < _shapes.size(); ++i)
  652. {
  653. shape = _shapes[i];
  654. if (shape->getType() == PhysicsCollisionShape::SHAPE_SPHERE)
  655. {
  656. btSphereShape* sphere = static_cast<btSphereShape*>(shape->_shape);
  657. if (sphere->getRadius() == scaledRadius)
  658. {
  659. shape->addRef();
  660. return shape;
  661. }
  662. }
  663. }
  664. // Create the sphere shape and add it to the cache.
  665. shape = new PhysicsCollisionShape(PhysicsCollisionShape::SHAPE_SPHERE, bullet_new<btSphereShape>(scaledRadius));
  666. _shapes.push_back(shape);
  667. return shape;
  668. }
  669. PhysicsCollisionShape* PhysicsController::createCapsule(float radius, float height, const Vector3& scale)
  670. {
  671. float girthScale = scale.x;
  672. if (girthScale < scale.z)
  673. girthScale = scale.z;
  674. float scaledRadius = radius * girthScale;
  675. float scaledHeight = height * scale.y - radius * 2;
  676. PhysicsCollisionShape* shape;
  677. // Return the capsule shape from the cache if it already exists.
  678. for (unsigned int i = 0; i < _shapes.size(); i++)
  679. {
  680. shape = _shapes[i];
  681. if (shape->getType() == PhysicsCollisionShape::SHAPE_CAPSULE)
  682. {
  683. btCapsuleShape* capsule = static_cast<btCapsuleShape*>(shape->_shape);
  684. if (capsule->getRadius() == scaledRadius && capsule->getHalfHeight() == 0.5f * scaledHeight)
  685. {
  686. shape->addRef();
  687. return shape;
  688. }
  689. }
  690. }
  691. // Create the capsule shape and add it to the cache.
  692. shape = new PhysicsCollisionShape(PhysicsCollisionShape::SHAPE_CAPSULE, bullet_new<btCapsuleShape>(scaledRadius, scaledHeight));
  693. _shapes.push_back(shape);
  694. return shape;
  695. }
  696. PhysicsCollisionShape* PhysicsController::createHeightfield(Node* node, Image* image, Vector3* centerOfMassOffset)
  697. {
  698. // Get the dimensions of the heightfield.
  699. // If the node has a mesh defined, use the dimensions of the bounding box for the mesh.
  700. // Otherwise simply use the image dimensions (with a max height of 255).
  701. float width, length, minHeight, maxHeight;
  702. if (node->getModel() && node->getModel()->getMesh())
  703. {
  704. const BoundingBox& box = node->getModel()->getMesh()->getBoundingBox();
  705. width = box.max.x - box.min.x;
  706. length = box.max.z - box.min.z;
  707. minHeight = box.min.y;
  708. maxHeight = box.max.y;
  709. }
  710. else
  711. {
  712. width = image->getWidth();
  713. length = image->getHeight();
  714. minHeight = 0.0f;
  715. maxHeight = 255.0f;
  716. }
  717. // Get the size in bytes of a pixel (we ensure that the image's
  718. // pixel format is actually supported before calling this constructor).
  719. unsigned int pixelSize = 0;
  720. switch (image->getFormat())
  721. {
  722. case Image::RGB:
  723. pixelSize = 3;
  724. break;
  725. case Image::RGBA:
  726. pixelSize = 4;
  727. break;
  728. default:
  729. LOG_ERROR("Unsupported pixel format for heightmap image.");
  730. return NULL;
  731. }
  732. // Calculate the heights for each pixel.
  733. float* heights = new float[image->getWidth() * image->getHeight()];
  734. unsigned char* data = image->getData();
  735. for (unsigned int x = 0, w = image->getWidth(); x < w; ++x)
  736. {
  737. for (unsigned int y = 0, h = image->getHeight(); y < h; ++y)
  738. {
  739. heights[x + y * w] = ((((float)data[(x + y * h) * pixelSize + 0]) +
  740. ((float)data[(x + y * h) * pixelSize + 1]) +
  741. ((float)data[(x + y * h) * pixelSize + 2])) / 768.0f) * (maxHeight - minHeight) + minHeight;
  742. }
  743. }
  744. PhysicsCollisionShape::HeightfieldData* heightfieldData = new PhysicsCollisionShape::HeightfieldData();
  745. heightfieldData->heightData = NULL;
  746. heightfieldData->inverseIsDirty = true;
  747. // Generate the heightmap data needed for physics (one height per world unit).
  748. unsigned int sizeWidth = width;
  749. unsigned int sizeHeight = length;
  750. heightfieldData->width = sizeWidth + 1;
  751. heightfieldData->height = sizeHeight + 1;
  752. heightfieldData->heightData = new float[heightfieldData->width * heightfieldData->height];
  753. unsigned int heightIndex = 0;
  754. float widthImageFactor = (float)(image->getWidth() - 1) / sizeWidth;
  755. float heightImageFactor = (float)(image->getHeight() - 1) / sizeHeight;
  756. float x = 0.0f;
  757. float z = 0.0f;
  758. for (unsigned int row = 0, z = 0.0f; row <= sizeHeight; row++, z += 1.0f)
  759. {
  760. for (unsigned int col = 0, x = 0.0f; col <= sizeWidth; col++, x += 1.0f)
  761. {
  762. heightIndex = row * heightfieldData->width + col;
  763. heightfieldData->heightData[heightIndex] = calculateHeight(heights, image->getWidth(), image->getHeight(), x * widthImageFactor, (sizeHeight - z) * heightImageFactor);
  764. }
  765. }
  766. SAFE_DELETE_ARRAY(heights);
  767. // Offset the heightmap's center of mass according to the way that Bullet calculates the origin
  768. // of its heightfield collision shape; see documentation for the btHeightfieldTerrainShape for more info.
  769. Vector3 s;
  770. node->getWorldMatrix().getScale(&s);
  771. centerOfMassOffset->set(0.0f, -(maxHeight - (0.5f * (maxHeight - minHeight))) / s.y, 0.0f);
  772. // Create the bullet terrain shape
  773. btHeightfieldTerrainShape* terrainShape = bullet_new<btHeightfieldTerrainShape>(
  774. heightfieldData->width, heightfieldData->height, heightfieldData->heightData, 1.0f, minHeight, maxHeight, 1, PHY_FLOAT, false);
  775. // Create our collision shape object and store heightfieldData in it
  776. PhysicsCollisionShape* shape = new PhysicsCollisionShape(PhysicsCollisionShape::SHAPE_HEIGHTFIELD, terrainShape);
  777. shape->_shapeData.heightfieldData = heightfieldData;
  778. _shapes.push_back(shape);
  779. return shape;
  780. }
  781. PhysicsCollisionShape* PhysicsController::createMesh(Mesh* mesh, const Vector3& scale)
  782. {
  783. assert(mesh);
  784. // Only support meshes with triangle list primitive types
  785. bool triMesh = true;
  786. if (mesh->getPartCount() > 0)
  787. {
  788. for (unsigned int i = 0; i < mesh->getPartCount(); ++i)
  789. {
  790. if (mesh->getPart(i)->getPrimitiveType() != Mesh::TRIANGLES)
  791. {
  792. triMesh = false;
  793. break;
  794. }
  795. }
  796. }
  797. else
  798. {
  799. triMesh = mesh->getPrimitiveType() == Mesh::TRIANGLES;
  800. }
  801. if (!triMesh)
  802. {
  803. LOG_ERROR("Mesh rigid bodies are currently only supported on meshes with TRIANGLES primitive type.");
  804. return NULL;
  805. }
  806. // The mesh must have a valid URL (i.e. it must have been loaded from a Bundle)
  807. // in order to fetch mesh data for computing mesh rigid body.
  808. if (strlen(mesh->getUrl()) == 0)
  809. {
  810. LOG_ERROR("Cannot create mesh rigid body for mesh without valid URL.");
  811. return NULL;
  812. }
  813. Bundle::MeshData* data = Bundle::readMeshData(mesh->getUrl());
  814. if (data == NULL)
  815. {
  816. return NULL;
  817. }
  818. // Create mesh data to be populated and store in returned collision shape
  819. PhysicsCollisionShape::MeshData* shapeMeshData = new PhysicsCollisionShape::MeshData();
  820. shapeMeshData->vertexData = NULL;
  821. // Copy the scaled vertex position data to the rigid body's local buffer.
  822. Matrix m;
  823. Matrix::createScale(scale, &m);
  824. unsigned int vertexCount = data->vertexCount;
  825. shapeMeshData->vertexData = new float[vertexCount * 3];
  826. Vector3 v;
  827. int vertexStride = data->vertexFormat.getVertexSize();
  828. for (unsigned int i = 0; i < data->vertexCount; i++)
  829. {
  830. v.set(*((float*)&data->vertexData[i * vertexStride + 0 * sizeof(float)]),
  831. *((float*)&data->vertexData[i * vertexStride + 1 * sizeof(float)]),
  832. *((float*)&data->vertexData[i * vertexStride + 2 * sizeof(float)]));
  833. v *= m;
  834. memcpy(&(shapeMeshData->vertexData[i * 3]), &v, sizeof(float) * 3);
  835. }
  836. btTriangleIndexVertexArray* meshInterface = bullet_new<btTriangleIndexVertexArray>();
  837. unsigned int partCount = data->parts.size();
  838. if (partCount > 0)
  839. {
  840. PHY_ScalarType indexType = PHY_UCHAR;
  841. int indexStride = 0;
  842. Bundle::MeshPartData* meshPart = NULL;
  843. for (unsigned int i = 0; i < partCount; i++)
  844. {
  845. meshPart = data->parts[i];
  846. switch (meshPart->indexFormat)
  847. {
  848. case Mesh::INDEX8:
  849. indexType = PHY_UCHAR;
  850. indexStride = 1;
  851. break;
  852. case Mesh::INDEX16:
  853. indexType = PHY_SHORT;
  854. indexStride = 2;
  855. break;
  856. case Mesh::INDEX32:
  857. indexType = PHY_INTEGER;
  858. indexStride = 4;
  859. break;
  860. }
  861. // Move the index data into the rigid body's local buffer.
  862. // Set it to NULL in the MeshPartData so it is not released when the data is freed.
  863. shapeMeshData->indexData.push_back(meshPart->indexData);
  864. meshPart->indexData = NULL;
  865. // Create a btIndexedMesh object for the current mesh part.
  866. btIndexedMesh indexedMesh;
  867. indexedMesh.m_indexType = indexType;
  868. indexedMesh.m_numTriangles = meshPart->indexCount / 3; // assume TRIANGLES primitive type
  869. indexedMesh.m_numVertices = meshPart->indexCount;
  870. indexedMesh.m_triangleIndexBase = (const unsigned char*)shapeMeshData->indexData[i];
  871. indexedMesh.m_triangleIndexStride = indexStride*3;
  872. indexedMesh.m_vertexBase = (const unsigned char*)shapeMeshData->vertexData;
  873. indexedMesh.m_vertexStride = sizeof(float)*3;
  874. indexedMesh.m_vertexType = PHY_FLOAT;
  875. // Add the indexed mesh data to the mesh interface.
  876. meshInterface->addIndexedMesh(indexedMesh, indexType);
  877. }
  878. }
  879. else
  880. {
  881. // Generate index data for the mesh locally in the rigid body.
  882. unsigned int* indexData = new unsigned int[data->vertexCount];
  883. for (unsigned int i = 0; i < data->vertexCount; i++)
  884. {
  885. indexData[i] = i;
  886. }
  887. shapeMeshData->indexData.push_back((unsigned char*)indexData);
  888. // Create a single btIndexedMesh object for the mesh interface.
  889. btIndexedMesh indexedMesh;
  890. indexedMesh.m_indexType = PHY_INTEGER;
  891. indexedMesh.m_numTriangles = data->vertexCount / 3; // assume TRIANGLES primitive type
  892. indexedMesh.m_numVertices = data->vertexCount;
  893. indexedMesh.m_triangleIndexBase = shapeMeshData->indexData[0];
  894. indexedMesh.m_triangleIndexStride = sizeof(unsigned int);
  895. indexedMesh.m_vertexBase = (const unsigned char*)shapeMeshData->vertexData;
  896. indexedMesh.m_vertexStride = sizeof(float)*3;
  897. indexedMesh.m_vertexType = PHY_FLOAT;
  898. // Set the data in the mesh interface.
  899. meshInterface->addIndexedMesh(indexedMesh, indexedMesh.m_indexType);
  900. }
  901. // Create our collision shape object and store shapeMeshData in it
  902. PhysicsCollisionShape* shape = new PhysicsCollisionShape(PhysicsCollisionShape::SHAPE_MESH, bullet_new<btBvhTriangleMeshShape>(meshInterface, true));
  903. shape->_shapeData.meshData = shapeMeshData;
  904. _shapes.push_back(shape);
  905. // Free the temporary mesh data now that it's stored in physics system
  906. SAFE_DELETE(data);
  907. return shape;
  908. }
  909. void PhysicsController::destroyShape(PhysicsCollisionShape* shape)
  910. {
  911. if (shape)
  912. {
  913. if (shape->getRefCount() == 1)
  914. {
  915. // Remove shape from shape cache
  916. std::vector<PhysicsCollisionShape*>::iterator shapeItr = std::find(_shapes.begin(), _shapes.end(), shape);
  917. if (shapeItr != _shapes.end())
  918. _shapes.erase(shapeItr);
  919. }
  920. // Release the shape
  921. shape->release();
  922. }
  923. }
  924. float PhysicsController::calculateHeight(float* data, unsigned int width, unsigned int height, float x, float y)
  925. {
  926. unsigned int x1 = x;
  927. unsigned int y1 = y;
  928. unsigned int x2 = x1 + 1;
  929. unsigned int y2 = y1 + 1;
  930. float tmp;
  931. float xFactor = modf(x, &tmp);
  932. float yFactor = modf(y, &tmp);
  933. float xFactorI = 1.0f - xFactor;
  934. float yFactorI = 1.0f - yFactor;
  935. if (x2 >= width && y2 >= height)
  936. {
  937. return data[x1 + y1 * width];
  938. }
  939. else if (x2 >= width)
  940. {
  941. return data[x1 + y1 * width] * yFactorI + data[x1 + y2 * width] * yFactor;
  942. }
  943. else if (y2 >= height)
  944. {
  945. return data[x1 + y1 * width] * xFactorI + data[x2 + y1 * width] * xFactor;
  946. }
  947. else
  948. {
  949. return data[x1 + y1 * width] * xFactorI * yFactorI + data[x1 + y2 * width] * xFactorI * yFactor +
  950. data[x2 + y2 * width] * xFactor * yFactor + data[x2 + y1 * width] * xFactor * yFactorI;
  951. }
  952. }
  953. void PhysicsController::addConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b, PhysicsConstraint* constraint)
  954. {
  955. a->addConstraint(constraint);
  956. if (b)
  957. {
  958. b->addConstraint(constraint);
  959. }
  960. _world->addConstraint(constraint->_constraint);
  961. }
  962. bool PhysicsController::checkConstraintRigidBodies(PhysicsRigidBody* a, PhysicsRigidBody* b)
  963. {
  964. if (!a->supportsConstraints())
  965. {
  966. WARN_VARG("Rigid body '%s' does not support constraints; unexpected behavior may occur.", a->_node->getId());
  967. return false;
  968. }
  969. if (b && !b->supportsConstraints())
  970. {
  971. WARN_VARG("Rigid body '%s' does not support constraints; unexpected behavior may occur.", b->_node->getId());
  972. return false;
  973. }
  974. return true;
  975. }
  976. void PhysicsController::removeConstraint(PhysicsConstraint* constraint)
  977. {
  978. // Find the constraint and remove it from the physics world.
  979. for (int i = _world->getNumConstraints() - 1; i >= 0; i--)
  980. {
  981. btTypedConstraint* currentConstraint = _world->getConstraint(i);
  982. if (constraint->_constraint == currentConstraint)
  983. {
  984. _world->removeConstraint(currentConstraint);
  985. break;
  986. }
  987. }
  988. }
  989. PhysicsController::DebugDrawer::DebugDrawer()
  990. : _mode(btIDebugDraw::DBG_DrawAabb | btIDebugDraw::DBG_DrawConstraintLimits | btIDebugDraw::DBG_DrawConstraints |
  991. btIDebugDraw::DBG_DrawContactPoints | btIDebugDraw::DBG_DrawWireframe), _viewProjection(NULL), _meshBatch(NULL)
  992. {
  993. // Vertex shader for drawing colored lines.
  994. const char* vs_str =
  995. {
  996. "uniform mat4 u_viewProjectionMatrix;\n"
  997. "attribute vec4 a_position;\n"
  998. "attribute vec4 a_color;\n"
  999. "varying vec4 v_color;\n"
  1000. "void main(void) {\n"
  1001. " v_color = a_color;\n"
  1002. " gl_Position = u_viewProjectionMatrix * a_position;\n"
  1003. "}"
  1004. };
  1005. // Fragment shader for drawing colored lines.
  1006. const char* fs_str =
  1007. {
  1008. #ifdef OPENGL_ES
  1009. "precision highp float;\n"
  1010. #endif
  1011. "varying vec4 v_color;\n"
  1012. "void main(void) {\n"
  1013. " gl_FragColor = v_color;\n"
  1014. "}"
  1015. };
  1016. Effect* effect = Effect::createFromSource(vs_str, fs_str);
  1017. Material* material = Material::create(effect);
  1018. material->getStateBlock()->setDepthTest(true);
  1019. VertexFormat::Element elements[] =
  1020. {
  1021. VertexFormat::Element(VertexFormat::POSITION, 3),
  1022. VertexFormat::Element(VertexFormat::COLOR, 4),
  1023. };
  1024. _meshBatch = MeshBatch::create(VertexFormat(elements, 2), Mesh::LINES, material, false);
  1025. SAFE_RELEASE(material);
  1026. SAFE_RELEASE(effect);
  1027. }
  1028. PhysicsController::DebugDrawer::~DebugDrawer()
  1029. {
  1030. SAFE_DELETE(_meshBatch);
  1031. }
  1032. void PhysicsController::DebugDrawer::begin(const Matrix& viewProjection)
  1033. {
  1034. _viewProjection = &viewProjection;
  1035. _meshBatch->begin();
  1036. }
  1037. void PhysicsController::DebugDrawer::end()
  1038. {
  1039. _meshBatch->end();
  1040. _meshBatch->getMaterial()->getParameter("u_viewProjectionMatrix")->setValue(_viewProjection);
  1041. _meshBatch->draw();
  1042. }
  1043. void PhysicsController::DebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
  1044. {
  1045. static DebugDrawer::DebugVertex fromVertex, toVertex;
  1046. fromVertex.x = from.getX();
  1047. fromVertex.y = from.getY();
  1048. fromVertex.z = from.getZ();
  1049. fromVertex.r = fromColor.getX();
  1050. fromVertex.g = fromColor.getY();
  1051. fromVertex.b = fromColor.getZ();
  1052. fromVertex.a = 1.0f;
  1053. toVertex.x = to.getX();
  1054. toVertex.y = to.getY();
  1055. toVertex.z = to.getZ();
  1056. toVertex.r = toColor.getX();
  1057. toVertex.g = toColor.getY();
  1058. toVertex.b = toColor.getZ();
  1059. toVertex.a = 1.0f;
  1060. _meshBatch->add(&fromVertex, 1);
  1061. _meshBatch->add(&toVertex, 1);
  1062. }
  1063. void PhysicsController::DebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
  1064. {
  1065. drawLine(from, to, color, color);
  1066. }
  1067. void PhysicsController::DebugDrawer::drawContactPoint(const btVector3& pointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color)
  1068. {
  1069. drawLine(pointOnB, pointOnB + normalOnB, color);
  1070. }
  1071. void PhysicsController::DebugDrawer::reportErrorWarning(const char* warningString)
  1072. {
  1073. WARN(warningString);
  1074. }
  1075. void PhysicsController::DebugDrawer::draw3dText(const btVector3& location, const char* textString)
  1076. {
  1077. WARN("Physics debug drawing: 3D text is not supported.");
  1078. }
  1079. void PhysicsController::DebugDrawer::setDebugMode(int mode)
  1080. {
  1081. _mode = mode;
  1082. }
  1083. int PhysicsController::DebugDrawer::getDebugMode() const
  1084. {
  1085. return _mode;
  1086. }
  1087. }