PhysicsController.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. #include "Base.h"
  2. #include "Game.h"
  3. #include "MeshPart.h"
  4. #include "PhysicsController.h"
  5. #include "PhysicsMotionState.h"
  6. #include "SceneLoader.h"
  7. // The initial capacity of the Bullet debug drawer's vertex batch.
  8. #define INITIAL_CAPACITY 280
  9. namespace gameplay
  10. {
  11. PhysicsController::PhysicsController()
  12. : _collisionConfiguration(NULL), _dispatcher(NULL),
  13. _overlappingPairCache(NULL), _solver(NULL), _world(NULL), _debugDrawer(NULL),
  14. _status(PhysicsController::Listener::DEACTIVATED), _listeners(NULL),
  15. _gravity(btScalar(0.0), btScalar(-9.8), btScalar(0.0))
  16. {
  17. // Default gravity is 9.8 along the negative Y axis.
  18. }
  19. PhysicsController::~PhysicsController()
  20. {
  21. SAFE_DELETE(_debugDrawer);
  22. SAFE_DELETE(_listeners);
  23. }
  24. void PhysicsController::addStatusListener(Listener* listener)
  25. {
  26. if (!_listeners)
  27. _listeners = new std::vector<Listener*>();
  28. _listeners->push_back(listener);
  29. }
  30. PhysicsFixedConstraint* PhysicsController::createFixedConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b)
  31. {
  32. checkConstraintRigidBodies(a, b);
  33. PhysicsFixedConstraint* constraint = new PhysicsFixedConstraint(a, b);
  34. addConstraint(a, b, constraint);
  35. return constraint;
  36. }
  37. PhysicsGenericConstraint* PhysicsController::createGenericConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b)
  38. {
  39. checkConstraintRigidBodies(a, b);
  40. PhysicsGenericConstraint* constraint = new PhysicsGenericConstraint(a, b);
  41. addConstraint(a, b, constraint);
  42. return constraint;
  43. }
  44. PhysicsGenericConstraint* PhysicsController::createGenericConstraint(PhysicsRigidBody* a,
  45. const Quaternion& rotationOffsetA, const Vector3& translationOffsetA, PhysicsRigidBody* b,
  46. const Quaternion& rotationOffsetB, const Vector3& translationOffsetB)
  47. {
  48. checkConstraintRigidBodies(a, b);
  49. PhysicsGenericConstraint* constraint = new PhysicsGenericConstraint(a, rotationOffsetA, translationOffsetA, b, rotationOffsetB, translationOffsetB);
  50. addConstraint(a, b, constraint);
  51. return constraint;
  52. }
  53. PhysicsHingeConstraint* PhysicsController::createHingeConstraint(PhysicsRigidBody* a,
  54. const Quaternion& rotationOffsetA, const Vector3& translationOffsetA, PhysicsRigidBody* b,
  55. const Quaternion& rotationOffsetB, const Vector3& translationOffsetB)
  56. {
  57. checkConstraintRigidBodies(a, b);
  58. PhysicsHingeConstraint* constraint = new PhysicsHingeConstraint(a, rotationOffsetA, translationOffsetA, b, rotationOffsetB, translationOffsetB);
  59. addConstraint(a, b, constraint);
  60. return constraint;
  61. }
  62. PhysicsSocketConstraint* PhysicsController::createSocketConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b)
  63. {
  64. checkConstraintRigidBodies(a, b);
  65. PhysicsSocketConstraint* constraint = new PhysicsSocketConstraint(a, b);
  66. addConstraint(a, b, constraint);
  67. return constraint;
  68. }
  69. PhysicsSocketConstraint* PhysicsController::createSocketConstraint(PhysicsRigidBody* a,
  70. const Vector3& translationOffsetA, PhysicsRigidBody* b, const Vector3& translationOffsetB)
  71. {
  72. checkConstraintRigidBodies(a, b);
  73. PhysicsSocketConstraint* constraint = new PhysicsSocketConstraint(a,translationOffsetA, b, translationOffsetB);
  74. addConstraint(a, b, constraint);
  75. return constraint;
  76. }
  77. PhysicsSpringConstraint* PhysicsController::createSpringConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b)
  78. {
  79. checkConstraintRigidBodies(a, b);
  80. PhysicsSpringConstraint* constraint = new PhysicsSpringConstraint(a, b);
  81. addConstraint(a, b, constraint);
  82. return constraint;
  83. }
  84. PhysicsSpringConstraint* PhysicsController::createSpringConstraint(PhysicsRigidBody* a, const Quaternion& rotationOffsetA, const Vector3& translationOffsetA,
  85. PhysicsRigidBody* b, const Quaternion& rotationOffsetB, const Vector3& translationOffsetB)
  86. {
  87. checkConstraintRigidBodies(a, b);
  88. PhysicsSpringConstraint* constraint = new PhysicsSpringConstraint(a, rotationOffsetA, translationOffsetA, b, rotationOffsetB, translationOffsetB);
  89. addConstraint(a, b, constraint);
  90. return constraint;
  91. }
  92. const Vector3& PhysicsController::getGravity(const Vector3& gravity) const
  93. {
  94. return _gravity;
  95. }
  96. void PhysicsController::setGravity(const Vector3& gravity)
  97. {
  98. _gravity = gravity;
  99. if (_world)
  100. _world->setGravity(btVector3(_gravity.x, _gravity.y, _gravity.z));
  101. }
  102. void PhysicsController::drawDebug(const Matrix& viewProjection)
  103. {
  104. _debugDrawer->begin(viewProjection);
  105. _world->debugDrawWorld();
  106. _debugDrawer->end();
  107. }
  108. void PhysicsController::initialize()
  109. {
  110. _collisionConfiguration = new btDefaultCollisionConfiguration();
  111. _dispatcher = new btCollisionDispatcher(_collisionConfiguration);
  112. _overlappingPairCache = new btDbvtBroadphase();
  113. _solver = new btSequentialImpulseConstraintSolver();
  114. // Create the world.
  115. _world = new btDiscreteDynamicsWorld(_dispatcher, _overlappingPairCache, _solver, _collisionConfiguration);
  116. _world->setGravity(btVector3(_gravity.x, _gravity.y, _gravity.z));
  117. // Set up debug drawing.
  118. _debugDrawer = new DebugDrawer();
  119. _world->setDebugDrawer(_debugDrawer);
  120. }
  121. void PhysicsController::finalize()
  122. {
  123. // Clean up the world and its various components.
  124. SAFE_DELETE(_world);
  125. SAFE_DELETE(_solver);
  126. SAFE_DELETE(_overlappingPairCache);
  127. SAFE_DELETE(_dispatcher);
  128. SAFE_DELETE(_collisionConfiguration);
  129. }
  130. void PhysicsController::pause()
  131. {
  132. // Unused
  133. }
  134. void PhysicsController::resume()
  135. {
  136. // Unused
  137. }
  138. void PhysicsController::update(long elapsedTime)
  139. {
  140. // Update the physics simulation, with a maximum
  141. // of 10 simulation steps being performed in a given frame.
  142. //
  143. // Note that stepSimulation takes elapsed time in seconds
  144. // so we divide by 1000 to convert from milliseconds.
  145. _world->stepSimulation((float)elapsedTime * 0.001, 10);
  146. // If we have status listeners, then check if our status has changed.
  147. if (_listeners)
  148. {
  149. Listener::EventType oldStatus = _status;
  150. if (_status = Listener::DEACTIVATED)
  151. {
  152. for (int i = 0; i < _world->getNumCollisionObjects(); i++)
  153. {
  154. if (_world->getCollisionObjectArray()[i]->isActive())
  155. {
  156. _status = Listener::ACTIVATED;
  157. break;
  158. }
  159. }
  160. }
  161. else
  162. {
  163. bool allInactive = true;
  164. for (int i = 0; i < _world->getNumCollisionObjects(); i++)
  165. {
  166. if (_world->getCollisionObjectArray()[i]->isActive())
  167. {
  168. allInactive = false;
  169. break;
  170. }
  171. }
  172. if (allInactive)
  173. _status = Listener::DEACTIVATED;
  174. }
  175. // If the status has changed, notify our listeners.
  176. if (oldStatus != _status)
  177. {
  178. for (unsigned int k = 0; k < _listeners->size(); k++)
  179. {
  180. (*_listeners)[k]->statusEvent(_status);
  181. }
  182. }
  183. }
  184. // All statuses are set with the DIRTY bit before collision processing occurs.
  185. // During collision processing, if a collision occurs, the status is
  186. // set to COLLISION and the DIRTY bit is cleared. Then, after collision processing
  187. // is finished, if a given status is still dirty, the COLLISION bit is cleared.
  188. // Dirty all the collision listeners' collision status caches.
  189. for (unsigned int i = 0; i < _bodies.size(); i++)
  190. {
  191. if (_bodies[i]->_listeners)
  192. {
  193. for (unsigned int k = 0; k < _bodies[i]->_listeners->size(); k++)
  194. {
  195. std::map<PhysicsRigidBody::CollisionPair, int>::iterator iter = (*_bodies[i]->_listeners)[k]->_collisionStatus.begin();
  196. for (; iter != (*_bodies[i]->_listeners)[k]->_collisionStatus.end(); iter++)
  197. {
  198. iter->second |= PhysicsRigidBody::Listener::DIRTY;
  199. }
  200. }
  201. }
  202. }
  203. // Go through the physics rigid bodies and update the collision listeners.
  204. for (unsigned int i = 0; i < _bodies.size(); i++)
  205. {
  206. if (_bodies[i]->_listeners)
  207. {
  208. for (unsigned int k = 0; k < _bodies[i]->_listeners->size(); k++)
  209. {
  210. std::map<PhysicsRigidBody::CollisionPair, int>::iterator iter = (*_bodies[i]->_listeners)[k]->_collisionStatus.begin();
  211. for (; iter != (*_bodies[i]->_listeners)[k]->_collisionStatus.end(); iter++)
  212. {
  213. // If this collision pair was one that was registered for listening, then perform the collision test.
  214. // (In the case where we register for all collisions with a rigid body, there will be a lot
  215. // of collision pairs in the status cache that we did not explicitly register for.)
  216. if ((iter->second & PhysicsRigidBody::Listener::REGISTERED) != 0)
  217. {
  218. if (iter->first._rbB)
  219. Game::getInstance()->getPhysicsController()->_world->contactPairTest(iter->first._rbA->_body, iter->first._rbB->_body, *(*_bodies[i]->_listeners)[k]);
  220. else
  221. Game::getInstance()->getPhysicsController()->_world->contactTest(iter->first._rbA->_body, *(*_bodies[i]->_listeners)[k]);
  222. }
  223. }
  224. }
  225. }
  226. }
  227. // Go through all the collision listeners and update their collision status caches.
  228. for (unsigned int i = 0; i < _bodies.size(); i++)
  229. {
  230. if (_bodies[i]->_listeners)
  231. {
  232. for (unsigned int k = 0; k < _bodies[i]->_listeners->size(); k++)
  233. {
  234. std::map<PhysicsRigidBody::CollisionPair, int>::iterator iter = (*_bodies[i]->_listeners)[k]->_collisionStatus.begin();
  235. for (; iter != (*_bodies[i]->_listeners)[k]->_collisionStatus.end(); iter++)
  236. {
  237. if ((iter->second & PhysicsRigidBody::Listener::DIRTY) != 0)
  238. {
  239. iter->second &= ~PhysicsRigidBody::Listener::COLLISION;
  240. }
  241. }
  242. }
  243. }
  244. }
  245. }
  246. void PhysicsController::addRigidBody(PhysicsRigidBody* body)
  247. {
  248. _world->addRigidBody(body->_body);
  249. _bodies.push_back(body);
  250. }
  251. void PhysicsController::removeRigidBody(PhysicsRigidBody* rigidBody)
  252. {
  253. // Find the rigid body and remove it from the world.
  254. for (int i = _world->getNumCollisionObjects() - 1; i >= 0 ; i--)
  255. {
  256. btCollisionObject* obj = _world->getCollisionObjectArray()[i];
  257. if (rigidBody->_body == obj)
  258. {
  259. _world->removeCollisionObject(obj);
  260. break;
  261. }
  262. }
  263. // Find the rigid body's collision shape and release the rigid body's reference to it.
  264. for (unsigned int i = 0; i < _shapes.size(); i++)
  265. {
  266. if (_shapes[i]->_shape == rigidBody->_shape)
  267. {
  268. if (_shapes[i]->getRefCount() == 1)
  269. {
  270. _shapes[i]->release();
  271. _shapes.erase(_shapes.begin() + i);
  272. }
  273. else
  274. _shapes[i]->release();
  275. return;
  276. }
  277. }
  278. }
  279. PhysicsRigidBody* PhysicsController::getRigidBody(const btCollisionObject* collisionObject)
  280. {
  281. // Find the rigid body and remove it from the world.
  282. for (unsigned int i = 0; i < _bodies.size(); i++)
  283. {
  284. if (_bodies[i]->_body == collisionObject)
  285. return _bodies[i];
  286. }
  287. return NULL;
  288. }
  289. btCollisionShape* PhysicsController::createBox(const Vector3& min, const Vector3& max, const btVector3& scale)
  290. {
  291. btVector3 halfExtents(scale.x() * 0.5 * abs(max.x - min.x), scale.y() * 0.5 * abs(max.y - min.y), scale.z() * 0.5 * abs(max.z - min.z));
  292. // Return the box shape from the cache if it already exists.
  293. for (unsigned int i = 0; i < _shapes.size(); i++)
  294. {
  295. if (_shapes[i]->_shape->getShapeType() == BOX_SHAPE_PROXYTYPE)
  296. {
  297. btBoxShape* box = static_cast<btBoxShape*>(_shapes[i]->_shape);
  298. if (box->getHalfExtentsWithMargin() == halfExtents)
  299. {
  300. _shapes[i]->addRef();
  301. return box;
  302. }
  303. }
  304. }
  305. // Create the box shape and add it to the cache.
  306. btBoxShape* box = bullet_new<btBoxShape>(halfExtents);
  307. _shapes.push_back(new PhysicsCollisionShape(box));
  308. return box;
  309. }
  310. btCollisionShape* PhysicsController::createCapsule(float radius, float height)
  311. {
  312. // Return the capsule shape from the cache if it already exists.
  313. for (unsigned int i = 0; i < _shapes.size(); i++)
  314. {
  315. if (_shapes[i]->_shape->getShapeType() == CAPSULE_SHAPE_PROXYTYPE)
  316. {
  317. btCapsuleShape* capsule = static_cast<btCapsuleShape*>(_shapes[i]->_shape);
  318. if (capsule->getRadius() == radius && capsule->getHalfHeight() == 0.5f * height)
  319. {
  320. _shapes[i]->addRef();
  321. return capsule;
  322. }
  323. }
  324. }
  325. // Create the capsule shape and add it to the cache.
  326. btCapsuleShape* capsule = bullet_new<btCapsuleShape>(radius, height);
  327. _shapes.push_back(new PhysicsCollisionShape(capsule));
  328. return capsule;
  329. }
  330. btCollisionShape* PhysicsController::createSphere(float radius, const btVector3& scale)
  331. {
  332. // Since sphere shapes depend only on the radius, the best we can do is take
  333. // the largest dimension and apply that as the uniform scale to the rigid body.
  334. float uniformScale = scale.x();
  335. if (uniformScale < scale.y())
  336. uniformScale = scale.y();
  337. if (uniformScale < scale.z())
  338. uniformScale = scale.z();
  339. // Return the sphere shape from the cache if it already exists.
  340. for (unsigned int i = 0; i < _shapes.size(); i++)
  341. {
  342. if (_shapes[i]->_shape->getShapeType() == SPHERE_SHAPE_PROXYTYPE)
  343. {
  344. btSphereShape* sphere = static_cast<btSphereShape*>(_shapes[i]->_shape);
  345. if (sphere->getRadius() == uniformScale * radius)
  346. {
  347. _shapes[i]->addRef();
  348. return sphere;
  349. }
  350. }
  351. }
  352. // Create the sphere shape and add it to the cache.
  353. btSphereShape* sphere = bullet_new<btSphereShape>(uniformScale * radius);
  354. _shapes.push_back(new PhysicsCollisionShape(sphere));
  355. return sphere;
  356. }
  357. btCollisionShape* PhysicsController::createMesh(PhysicsRigidBody* body)
  358. {
  359. // Retrieve the mesh rigid body data from the loaded scene.
  360. const SceneLoader::MeshRigidBodyData* data = SceneLoader::getMeshRigidBodyData(body->_node->getId());
  361. // Copy the scaled vertex position data to the rigid body's local buffer.
  362. Matrix m;
  363. Matrix::createScale(body->_node->getScaleX(), body->_node->getScaleY(), body->_node->getScaleZ(), &m);
  364. unsigned int vertexCount = data->mesh->getVertexCount();
  365. body->_vertexData = new float[vertexCount * 3];
  366. Vector3 v;
  367. int vertexStride = data->mesh->getVertexFormat().getVertexSize();
  368. for (unsigned int i = 0; i < vertexCount; i++)
  369. {
  370. v.set(*((float*)&data->vertexData[i * vertexStride + 0 * sizeof(float)]),
  371. *((float*)&data->vertexData[i * vertexStride + 1 * sizeof(float)]),
  372. *((float*)&data->vertexData[i * vertexStride + 2 * sizeof(float)]));
  373. v *= m;
  374. memcpy(&(body->_vertexData[i * 3]), &v, sizeof(float) * 3);
  375. }
  376. btTriangleIndexVertexArray* meshInterface = bullet_new<btTriangleIndexVertexArray>();
  377. if (data->mesh->getPartCount() > 0)
  378. {
  379. PHY_ScalarType indexType = PHY_UCHAR;
  380. int indexStride = 0;
  381. MeshPart* meshPart = NULL;
  382. for (unsigned int i = 0; i < data->mesh->getPartCount(); i++)
  383. {
  384. meshPart = data->mesh->getPart(i);
  385. switch (meshPart->getIndexFormat())
  386. {
  387. case Mesh::INDEX8:
  388. indexType = PHY_UCHAR;
  389. indexStride = 1;
  390. break;
  391. case Mesh::INDEX16:
  392. indexType = PHY_SHORT;
  393. indexStride = 2;
  394. break;
  395. case Mesh::INDEX32:
  396. indexType = PHY_INTEGER;
  397. indexStride = 4;
  398. break;
  399. }
  400. // Copy the index data to the rigid body's local buffer.
  401. unsigned int indexDataSize = meshPart->getIndexCount() * indexStride;
  402. unsigned char* indexData = new unsigned char[indexDataSize];
  403. memcpy(indexData, data->indexData[i], indexDataSize);
  404. body->_indexData.push_back(indexData);
  405. // Create a btIndexedMesh object for the current mesh part.
  406. btIndexedMesh indexedMesh;
  407. indexedMesh.m_indexType = indexType;
  408. indexedMesh.m_numTriangles = meshPart->getIndexCount() / 3;
  409. indexedMesh.m_numVertices = meshPart->getIndexCount();
  410. indexedMesh.m_triangleIndexBase = (const unsigned char*)body->_indexData[i];
  411. indexedMesh.m_triangleIndexStride = indexStride;
  412. indexedMesh.m_vertexBase = (const unsigned char*)body->_vertexData;
  413. indexedMesh.m_vertexStride = sizeof(float)*3;
  414. indexedMesh.m_vertexType = PHY_FLOAT;
  415. // Add the indexed mesh data to the mesh interface.
  416. meshInterface->addIndexedMesh(indexedMesh, indexType);
  417. }
  418. }
  419. else
  420. {
  421. // Generate index data for the mesh locally in the rigid body.
  422. unsigned int* indexData = new unsigned int[data->mesh->getVertexCount()];
  423. for (unsigned int i = 0; i < data->mesh->getVertexCount(); i++)
  424. {
  425. indexData[i] = i;
  426. }
  427. body->_indexData.push_back((unsigned char*)indexData);
  428. // Create a single btIndexedMesh object for the mesh interface.
  429. btIndexedMesh indexedMesh;
  430. indexedMesh.m_indexType = PHY_INTEGER;
  431. indexedMesh.m_numTriangles = data->mesh->getVertexCount() / 3;
  432. indexedMesh.m_numVertices = data->mesh->getVertexCount();
  433. indexedMesh.m_triangleIndexBase = body->_indexData[0];
  434. indexedMesh.m_triangleIndexStride = sizeof(unsigned int);
  435. indexedMesh.m_vertexBase = (const unsigned char*)body->_vertexData;
  436. indexedMesh.m_vertexStride = sizeof(float)*3;
  437. indexedMesh.m_vertexType = PHY_FLOAT;
  438. // Set the data in the mesh interface.
  439. meshInterface->addIndexedMesh(indexedMesh, indexedMesh.m_indexType);
  440. }
  441. btBvhTriangleMeshShape* shape = bullet_new<btBvhTriangleMeshShape>(meshInterface, true);
  442. _shapes.push_back(new PhysicsCollisionShape(shape));
  443. return shape;
  444. }
  445. void PhysicsController::addConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b, PhysicsConstraint* constraint)
  446. {
  447. a->addConstraint(constraint);
  448. if (b)
  449. {
  450. b->addConstraint(constraint);
  451. }
  452. _world->addConstraint(constraint->_constraint);
  453. }
  454. bool PhysicsController::checkConstraintRigidBodies(PhysicsRigidBody* a, PhysicsRigidBody* b)
  455. {
  456. if (!a->supportsConstraints())
  457. {
  458. WARN_VARG("Rigid body '%s' does not support constraints; unexpected behavior may occur.", a->_node->getId());
  459. return false;
  460. }
  461. if (b && !b->supportsConstraints())
  462. {
  463. WARN_VARG("Rigid body '%s' does not support constraints; unexpected behavior may occur.", b->_node->getId());
  464. return false;
  465. }
  466. return true;
  467. }
  468. void PhysicsController::removeConstraint(PhysicsConstraint* constraint)
  469. {
  470. // Find the constraint and remove it from the physics world.
  471. for (int i = _world->getNumConstraints() - 1; i >= 0; i--)
  472. {
  473. btTypedConstraint* currentConstraint = _world->getConstraint(i);
  474. if (constraint->_constraint == currentConstraint)
  475. {
  476. _world->removeConstraint(currentConstraint);
  477. break;
  478. }
  479. }
  480. }
  481. PhysicsController::DebugDrawer::DebugDrawer()
  482. : _mode(btIDebugDraw::DBG_DrawAabb | btIDebugDraw::DBG_DrawConstraintLimits | btIDebugDraw::DBG_DrawConstraints |
  483. btIDebugDraw::DBG_DrawContactPoints | btIDebugDraw::DBG_DrawWireframe), _viewProjection(NULL), _meshBatch(NULL)
  484. {
  485. // Vertex shader for drawing colored lines.
  486. const char* vs_str =
  487. {
  488. "uniform mat4 u_viewProjectionMatrix;\n"
  489. "attribute vec4 a_position;\n"
  490. "attribute vec4 a_color;\n"
  491. "varying vec4 v_color;\n"
  492. "void main(void) {\n"
  493. " v_color = a_color;\n"
  494. " gl_Position = u_viewProjectionMatrix * a_position;\n"
  495. "}"
  496. };
  497. // Fragment shader for drawing colored lines.
  498. const char* fs_str =
  499. {
  500. #ifdef OPENGL_ES
  501. "precision highp float;\n"
  502. #endif
  503. "varying vec4 v_color;\n"
  504. "void main(void) {\n"
  505. " gl_FragColor = v_color;\n"
  506. "}"
  507. };
  508. Effect* effect = Effect::createFromSource(vs_str, fs_str);
  509. Material* material = Material::create(effect);
  510. VertexFormat::Element elements[] =
  511. {
  512. VertexFormat::Element(VertexFormat::POSITION, 3),
  513. VertexFormat::Element(VertexFormat::COLOR, 4),
  514. };
  515. _meshBatch = MeshBatch::create(VertexFormat(elements, 2), Mesh::LINES, material, false);
  516. SAFE_RELEASE(material);
  517. SAFE_RELEASE(effect);
  518. }
  519. PhysicsController::DebugDrawer::~DebugDrawer()
  520. {
  521. SAFE_DELETE(_meshBatch);
  522. }
  523. void PhysicsController::DebugDrawer::begin(const Matrix& viewProjection)
  524. {
  525. _viewProjection = &viewProjection;
  526. _meshBatch->begin();
  527. }
  528. void PhysicsController::DebugDrawer::end()
  529. {
  530. _meshBatch->getMaterial()->getParameter("u_viewProjectionMatrix")->setValue(_viewProjection);
  531. _meshBatch->draw();
  532. _meshBatch->end();
  533. }
  534. void PhysicsController::DebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
  535. {
  536. static DebugDrawer::DebugVertex fromVertex, toVertex;
  537. fromVertex.x = from.getX();
  538. fromVertex.y = from.getY();
  539. fromVertex.z = from.getZ();
  540. fromVertex.r = fromColor.getX();
  541. fromVertex.g = fromColor.getY();
  542. fromVertex.b = fromColor.getZ();
  543. fromVertex.a = 1.0f;
  544. toVertex.x = to.getX();
  545. toVertex.y = to.getY();
  546. toVertex.z = to.getZ();
  547. toVertex.r = toColor.getX();
  548. toVertex.g = toColor.getY();
  549. toVertex.b = toColor.getZ();
  550. toVertex.a = 1.0f;
  551. _meshBatch->add(&fromVertex, 1);
  552. _meshBatch->add(&toVertex, 1);
  553. }
  554. void PhysicsController::DebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
  555. {
  556. drawLine(from, to, color, color);
  557. }
  558. void PhysicsController::DebugDrawer::drawContactPoint(const btVector3& pointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color)
  559. {
  560. drawLine(pointOnB, pointOnB + normalOnB, color);
  561. }
  562. void PhysicsController::DebugDrawer::reportErrorWarning(const char* warningString)
  563. {
  564. WARN(warningString);
  565. }
  566. void PhysicsController::DebugDrawer::draw3dText(const btVector3& location, const char* textString)
  567. {
  568. WARN("Physics debug drawing: 3D text is not supported.");
  569. }
  570. void PhysicsController::DebugDrawer::setDebugMode(int mode)
  571. {
  572. _mode = mode;
  573. }
  574. int PhysicsController::DebugDrawer::getDebugMode() const
  575. {
  576. return _mode;
  577. }
  578. }