PhysicsController.cpp 51 KB

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