PhysicsController.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  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. }
  264. PhysicsRigidBody* PhysicsController::getRigidBody(const btCollisionObject* collisionObject)
  265. {
  266. // Find the rigid body and remove it from the world.
  267. for (unsigned int i = 0; i < _bodies.size(); i++)
  268. {
  269. if (_bodies[i]->_body == collisionObject)
  270. return _bodies[i];
  271. }
  272. return NULL;
  273. }
  274. btCollisionShape* PhysicsController::createBox(const Vector3& min, const Vector3& max, const btVector3& scale)
  275. {
  276. 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));
  277. btBoxShape* box = bullet_new<btBoxShape>(halfExtents);
  278. _shapes.push_back(box);
  279. return box;
  280. }
  281. btCollisionShape* PhysicsController::createSphere(float radius, const btVector3& scale)
  282. {
  283. // Since sphere shapes depend only on the radius, the best we can do is take
  284. // the largest dimension and apply that as the uniform scale to the rigid body.
  285. float uniformScale = scale.x();
  286. if (uniformScale < scale.y())
  287. uniformScale = scale.y();
  288. if (uniformScale < scale.z())
  289. uniformScale = scale.z();
  290. btSphereShape* sphere = bullet_new<btSphereShape>(uniformScale * radius);
  291. _shapes.push_back(sphere);
  292. return sphere;
  293. }
  294. btCollisionShape* PhysicsController::createMesh(PhysicsRigidBody* body)
  295. {
  296. // Retrieve the mesh rigid body data from the loaded scene.
  297. const SceneLoader::MeshRigidBodyData* data = SceneLoader::getMeshRigidBodyData(body->_node->getId());
  298. // Copy the scaled vertex position data to the rigid body's local buffer.
  299. Matrix m;
  300. Matrix::createScale(body->_node->getScaleX(), body->_node->getScaleY(), body->_node->getScaleZ(), &m);
  301. unsigned int vertexCount = data->mesh->getVertexCount();
  302. body->_vertexData = new float[vertexCount * 3];
  303. Vector3 v;
  304. int vertexStride = data->mesh->getVertexFormat()->getVertexSize();
  305. for (unsigned int i = 0; i < vertexCount; i++)
  306. {
  307. v.set(*((float*)&data->vertexData[i * vertexStride + 0 * sizeof(float)]),
  308. *((float*)&data->vertexData[i * vertexStride + 1 * sizeof(float)]),
  309. *((float*)&data->vertexData[i * vertexStride + 2 * sizeof(float)]));
  310. v *= m;
  311. memcpy(&(body->_vertexData[i * 3]), &v, sizeof(float) * 3);
  312. }
  313. btTriangleIndexVertexArray* meshInterface = bullet_new<btTriangleIndexVertexArray>();
  314. if (data->mesh->getPartCount() > 0)
  315. {
  316. PHY_ScalarType indexType = PHY_UCHAR;
  317. int indexStride = 0;
  318. MeshPart* meshPart = NULL;
  319. for (unsigned int i = 0; i < data->mesh->getPartCount(); i++)
  320. {
  321. meshPart = data->mesh->getPart(i);
  322. switch (meshPart->getIndexFormat())
  323. {
  324. case Mesh::INDEX8:
  325. indexType = PHY_UCHAR;
  326. indexStride = 1;
  327. break;
  328. case Mesh::INDEX16:
  329. indexType = PHY_SHORT;
  330. indexStride = 2;
  331. break;
  332. case Mesh::INDEX32:
  333. indexType = PHY_INTEGER;
  334. indexStride = 4;
  335. break;
  336. }
  337. // Copy the index data to the rigid body's local buffer.
  338. unsigned int indexDataSize = meshPart->getIndexCount() * indexStride;
  339. unsigned char* indexData = new unsigned char[indexDataSize];
  340. memcpy(indexData, data->indexData[i], indexDataSize);
  341. body->_indexData.push_back(indexData);
  342. // Create a btIndexedMesh object for the current mesh part.
  343. btIndexedMesh indexedMesh;
  344. indexedMesh.m_indexType = indexType;
  345. indexedMesh.m_numTriangles = meshPart->getIndexCount() / 3;
  346. indexedMesh.m_numVertices = meshPart->getIndexCount();
  347. indexedMesh.m_triangleIndexBase = (const unsigned char*)body->_indexData[i];
  348. indexedMesh.m_triangleIndexStride = indexStride;
  349. indexedMesh.m_vertexBase = (const unsigned char*)body->_vertexData;
  350. indexedMesh.m_vertexStride = sizeof(float)*3;
  351. indexedMesh.m_vertexType = PHY_FLOAT;
  352. // Add the indexed mesh data to the mesh interface.
  353. meshInterface->addIndexedMesh(indexedMesh, indexType);
  354. }
  355. }
  356. else
  357. {
  358. // Generate index data for the mesh locally in the rigid body.
  359. unsigned int* indexData = new unsigned int[data->mesh->getVertexCount()];
  360. for (unsigned int i = 0; i < data->mesh->getVertexCount(); i++)
  361. {
  362. indexData[i] = i;
  363. }
  364. body->_indexData.push_back((unsigned char*)indexData);
  365. // Create a single btIndexedMesh object for the mesh interface.
  366. btIndexedMesh indexedMesh;
  367. indexedMesh.m_indexType = PHY_INTEGER;
  368. indexedMesh.m_numTriangles = data->mesh->getVertexCount() / 3;
  369. indexedMesh.m_numVertices = data->mesh->getVertexCount();
  370. indexedMesh.m_triangleIndexBase = body->_indexData[0];
  371. indexedMesh.m_triangleIndexStride = sizeof(unsigned int);
  372. indexedMesh.m_vertexBase = (const unsigned char*)body->_vertexData;
  373. indexedMesh.m_vertexStride = sizeof(float)*3;
  374. indexedMesh.m_vertexType = PHY_FLOAT;
  375. // Set the data in the mesh interface.
  376. meshInterface->addIndexedMesh(indexedMesh, indexedMesh.m_indexType);
  377. }
  378. btBvhTriangleMeshShape* shape = bullet_new<btBvhTriangleMeshShape>(meshInterface, true);
  379. _shapes.push_back(shape);
  380. return shape;
  381. }
  382. void PhysicsController::addConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b, PhysicsConstraint* constraint)
  383. {
  384. a->addConstraint(constraint);
  385. if (b)
  386. {
  387. b->addConstraint(constraint);
  388. }
  389. _world->addConstraint(constraint->_constraint);
  390. }
  391. bool PhysicsController::checkConstraintRigidBodies(PhysicsRigidBody* a, PhysicsRigidBody* b)
  392. {
  393. if (!a->supportsConstraints())
  394. {
  395. WARN_VARG("Rigid body '%s' does not support constraints; unexpected behavior may occur.", a->_node->getId());
  396. return false;
  397. }
  398. if (b && !b->supportsConstraints())
  399. {
  400. WARN_VARG("Rigid body '%s' does not support constraints; unexpected behavior may occur.", b->_node->getId());
  401. return false;
  402. }
  403. return true;
  404. }
  405. void PhysicsController::removeConstraint(PhysicsConstraint* constraint)
  406. {
  407. // Find the constraint and remove it from the physics world.
  408. for (int i = _world->getNumConstraints() - 1; i >= 0; i--)
  409. {
  410. btTypedConstraint* currentConstraint = _world->getConstraint(i);
  411. if (constraint->_constraint == currentConstraint)
  412. {
  413. _world->removeConstraint(currentConstraint);
  414. break;
  415. }
  416. }
  417. }
  418. PhysicsController::DebugDrawer::DebugDrawer()
  419. : _mode(btIDebugDraw::DBG_DrawAabb | btIDebugDraw::DBG_DrawConstraintLimits | btIDebugDraw::DBG_DrawConstraints |
  420. btIDebugDraw::DBG_DrawContactPoints | btIDebugDraw::DBG_DrawWireframe), _effect(NULL), _positionAttrib(0), _colorAttrib(0),
  421. _viewProjectionMatrixUniform(NULL), _viewProjection(NULL), _vertexData(NULL), _vertexCount(0), _vertexDataSize(0)
  422. {
  423. // Unused
  424. }
  425. PhysicsController::DebugDrawer::~DebugDrawer()
  426. {
  427. SAFE_RELEASE(_effect);
  428. SAFE_DELETE_ARRAY(_vertexData);
  429. }
  430. void PhysicsController::DebugDrawer::begin(const Matrix& viewProjection)
  431. {
  432. _viewProjection = &viewProjection;
  433. _vertexCount = 0;
  434. }
  435. void PhysicsController::DebugDrawer::end()
  436. {
  437. // Lazy load the effect for drawing.
  438. if (!_effect)
  439. {
  440. // Vertex shader for drawing colored lines.
  441. const char* vs_str =
  442. {
  443. "uniform mat4 u_viewProjectionMatrix;\n"
  444. "attribute vec4 a_position;\n"
  445. "attribute vec4 a_color;\n"
  446. "varying vec4 v_color;\n"
  447. "void main(void) {\n"
  448. " v_color = a_color;\n"
  449. " gl_Position = u_viewProjectionMatrix * a_position;\n"
  450. "}"
  451. };
  452. // Fragment shader for drawing colored lines.
  453. const char* fs_str =
  454. {
  455. #ifdef OPENGL_ES
  456. "precision highp float;\n"
  457. #endif
  458. "varying vec4 v_color;\n"
  459. "void main(void) {\n"
  460. " gl_FragColor = v_color;\n"
  461. "}"
  462. };
  463. _effect = Effect::createFromSource(vs_str, fs_str);
  464. _positionAttrib = _effect->getVertexAttribute("a_position");
  465. _colorAttrib = _effect->getVertexAttribute("a_color");
  466. _viewProjectionMatrixUniform = _effect->getUniform("u_viewProjectionMatrix");
  467. }
  468. // Bind the effect and set the vertex attributes.
  469. _effect->bind();
  470. GL_ASSERT( glEnableVertexAttribArray(_positionAttrib) );
  471. GL_ASSERT( glEnableVertexAttribArray(_colorAttrib) );
  472. GL_ASSERT( glVertexAttribPointer(_positionAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 7, _vertexData) );
  473. GL_ASSERT( glVertexAttribPointer(_colorAttrib, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 7, &_vertexData[3]) );
  474. // Set the camera's view projection matrix and draw.
  475. _effect->setValue( _viewProjectionMatrixUniform, _viewProjection);
  476. GL_ASSERT( glDrawArrays(GL_LINES, 0, _vertexCount / 7) );
  477. }
  478. void PhysicsController::DebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
  479. {
  480. // Allocate extra space in the vertex data batch if it is needed.
  481. if (_vertexDataSize - _vertexCount < 14)
  482. {
  483. if (_vertexDataSize > 0)
  484. {
  485. unsigned int newVertexDataSize = _vertexDataSize * 2;
  486. float* newVertexData = new float[newVertexDataSize];
  487. memcpy(newVertexData, _vertexData, _vertexDataSize * sizeof(float));
  488. SAFE_DELETE_ARRAY(_vertexData);
  489. _vertexData = newVertexData;
  490. _vertexDataSize = newVertexDataSize;
  491. }
  492. else
  493. {
  494. _vertexDataSize = INITIAL_CAPACITY;
  495. _vertexData = new float[_vertexDataSize];
  496. }
  497. }
  498. // Create the vertex data for the line and copy it into the batch.
  499. float vertexData[] =
  500. {
  501. from.getX(), from.getY(), from.getZ(),
  502. fromColor.getX(), fromColor.getY(), fromColor.getZ(), 1.0f,
  503. to.getX(), to.getY(), to.getZ(),
  504. toColor.getX(), toColor.getY(), toColor.getZ(), 1.0f
  505. };
  506. memcpy(&_vertexData[_vertexCount], vertexData, sizeof(float) * 14);
  507. _vertexCount += 14;
  508. }
  509. void PhysicsController::DebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
  510. {
  511. drawLine(from, to, color, color);
  512. }
  513. void PhysicsController::DebugDrawer::drawContactPoint(const btVector3& pointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color)
  514. {
  515. drawLine(pointOnB, pointOnB + normalOnB, color);
  516. }
  517. void PhysicsController::DebugDrawer::reportErrorWarning(const char* warningString)
  518. {
  519. WARN(warningString);
  520. }
  521. void PhysicsController::DebugDrawer::draw3dText(const btVector3& location, const char* textString)
  522. {
  523. WARN("Physics debug drawing: 3D text is not supported.");
  524. }
  525. void PhysicsController::DebugDrawer::setDebugMode(int mode)
  526. {
  527. _mode = mode;
  528. }
  529. int PhysicsController::DebugDrawer::getDebugMode() const
  530. {
  531. return _mode;
  532. }
  533. }