PhysicsController.cpp 24 KB

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