PhysicsController.cpp 53 KB

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