PhysicsController.cpp 57 KB

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