OpenGLGuiHelper.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. #include "OpenGLGuiHelper.h"
  2. #include "btBulletDynamicsCommon.h"
  3. #include "../CommonInterfaces/CommonGraphicsAppInterface.h"
  4. #include "../CommonInterfaces/CommonRenderInterface.h"
  5. #include "Bullet3Common/b3Scalar.h"
  6. #include "BulletCollision/CollisionShapes/btShapeHull.h"//to create a tesselation of a generic btConvexShape
  7. #include "../OpenGLWindow/GLInstanceGraphicsShape.h"
  8. //backwards compatibility
  9. #include "GL_ShapeDrawer.h"
  10. #define BT_LINE_BATCH_SIZE 512
  11. struct MyDebugVec3
  12. {
  13. MyDebugVec3(const btVector3& org)
  14. :x(org.x()),
  15. y(org.y()),
  16. z(org.z())
  17. {
  18. }
  19. float x;
  20. float y;
  21. float z;
  22. };
  23. class MyDebugDrawer : public btIDebugDraw
  24. {
  25. CommonGraphicsApp* m_glApp;
  26. int m_debugMode;
  27. btAlignedObjectArray<MyDebugVec3> m_linePoints;
  28. btAlignedObjectArray<unsigned int> m_lineIndices;
  29. btVector3 m_currentLineColor;
  30. DefaultColors m_ourColors;
  31. public:
  32. MyDebugDrawer(CommonGraphicsApp* app)
  33. : m_glApp(app)
  34. ,m_debugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb),
  35. m_currentLineColor(-1,-1,-1)
  36. {
  37. }
  38. virtual DefaultColors getDefaultColors() const
  39. {
  40. return m_ourColors;
  41. }
  42. ///the default implementation for setDefaultColors has no effect. A derived class can implement it and store the colors.
  43. virtual void setDefaultColors(const DefaultColors& colors)
  44. {
  45. m_ourColors = colors;
  46. }
  47. virtual void drawLine(const btVector3& from1,const btVector3& to1,const btVector3& color1)
  48. {
  49. //float from[4] = {from1[0],from1[1],from1[2],from1[3]};
  50. //float to[4] = {to1[0],to1[1],to1[2],to1[3]};
  51. //float color[4] = {color1[0],color1[1],color1[2],color1[3]};
  52. //m_glApp->m_instancingRenderer->drawLine(from,to,color);
  53. if (m_currentLineColor!=color1 || m_linePoints.size() >= BT_LINE_BATCH_SIZE)
  54. {
  55. flushLines();
  56. m_currentLineColor = color1;
  57. }
  58. MyDebugVec3 from(from1);
  59. MyDebugVec3 to(to1);
  60. m_linePoints.push_back(from);
  61. m_linePoints.push_back(to);
  62. m_lineIndices.push_back(m_lineIndices.size());
  63. m_lineIndices.push_back(m_lineIndices.size());
  64. }
  65. virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)
  66. {
  67. drawLine(PointOnB,PointOnB+normalOnB,color);
  68. }
  69. virtual void reportErrorWarning(const char* warningString)
  70. {
  71. }
  72. virtual void draw3dText(const btVector3& location,const char* textString)
  73. {
  74. }
  75. virtual void setDebugMode(int debugMode)
  76. {
  77. m_debugMode = debugMode;
  78. }
  79. virtual int getDebugMode() const
  80. {
  81. return m_debugMode;
  82. }
  83. virtual void flushLines()
  84. {
  85. int sz = m_linePoints.size();
  86. if (sz)
  87. {
  88. float debugColor[4];
  89. debugColor[0] = m_currentLineColor.x();
  90. debugColor[1] = m_currentLineColor.y();
  91. debugColor[2] = m_currentLineColor.z();
  92. debugColor[3] = 1.f;
  93. m_glApp->m_renderer->drawLines(&m_linePoints[0].x,debugColor,
  94. m_linePoints.size(),sizeof(MyDebugVec3),
  95. &m_lineIndices[0],
  96. m_lineIndices.size(),
  97. 1);
  98. m_linePoints.clear();
  99. m_lineIndices.clear();
  100. }
  101. }
  102. };
  103. static btVector4 sColors[4] =
  104. {
  105. btVector4(0.3,0.3,1,1),
  106. btVector4(0.6,0.6,1,1),
  107. btVector4(0,1,0,1),
  108. btVector4(0,1,1,1),
  109. //btVector4(1,1,0,1),
  110. };
  111. struct OpenGLGuiHelperInternalData
  112. {
  113. struct CommonGraphicsApp* m_glApp;
  114. class MyDebugDrawer* m_debugDraw;
  115. GL_ShapeDrawer* m_gl2ShapeDrawer;
  116. };
  117. OpenGLGuiHelper::OpenGLGuiHelper(CommonGraphicsApp* glApp, bool useOpenGL2)
  118. {
  119. m_data = new OpenGLGuiHelperInternalData;
  120. m_data->m_glApp = glApp;
  121. m_data->m_debugDraw = 0;
  122. m_data->m_gl2ShapeDrawer = 0;
  123. if (useOpenGL2)
  124. {
  125. m_data->m_gl2ShapeDrawer = new GL_ShapeDrawer();
  126. }
  127. }
  128. OpenGLGuiHelper::~OpenGLGuiHelper()
  129. {
  130. delete m_data->m_gl2ShapeDrawer;
  131. delete m_data;
  132. }
  133. struct CommonRenderInterface* OpenGLGuiHelper::getRenderInterface()
  134. {
  135. return m_data->m_glApp->m_renderer;
  136. }
  137. void OpenGLGuiHelper::createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color)
  138. {
  139. createCollisionObjectGraphicsObject(body,color);
  140. }
  141. void OpenGLGuiHelper::createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color)
  142. {
  143. if (body->getUserIndex()<0)
  144. {
  145. btCollisionShape* shape = body->getCollisionShape();
  146. btTransform startTransform = body->getWorldTransform();
  147. int graphicsShapeId = shape->getUserIndex();
  148. if (graphicsShapeId>=0)
  149. {
  150. // btAssert(graphicsShapeId >= 0);
  151. //the graphics shape is already scaled
  152. btVector3 localScaling(1,1,1);
  153. int graphicsInstanceId = m_data->m_glApp->m_renderer->registerGraphicsInstance(graphicsShapeId, startTransform.getOrigin(), startTransform.getRotation(), color, localScaling);
  154. body->setUserIndex(graphicsInstanceId);
  155. }
  156. }
  157. }
  158. int OpenGLGuiHelper::registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices)
  159. {
  160. int shapeId = m_data->m_glApp->m_renderer->registerShape(vertices, numvertices,indices,numIndices);
  161. return shapeId;
  162. }
  163. int OpenGLGuiHelper::registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)
  164. {
  165. return m_data->m_glApp->m_renderer->registerGraphicsInstance(shapeIndex,position,quaternion,color,scaling);
  166. }
  167. static void createCollisionShapeGraphicsObjectInternal(btCollisionShape* collisionShape, const btTransform& parentTransform, btAlignedObjectArray<GLInstanceVertex>& verticesOut, btAlignedObjectArray<int>& indicesOut)
  168. {
  169. //todo: support all collision shape types
  170. switch (collisionShape->getShapeType())
  171. {
  172. case SOFTBODY_SHAPE_PROXYTYPE:
  173. {
  174. //skip the soft body collision shape for now
  175. break;
  176. }
  177. case STATIC_PLANE_PROXYTYPE:
  178. {
  179. //draw a box, oriented along the plane normal
  180. const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(collisionShape);
  181. btScalar planeConst = staticPlaneShape->getPlaneConstant();
  182. const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
  183. btVector3 planeOrigin = planeNormal * planeConst;
  184. btVector3 vec0,vec1;
  185. btPlaneSpace1(planeNormal,vec0,vec1);
  186. btScalar vecLen = 100.f;
  187. btVector3 verts[4];
  188. verts[0] = planeOrigin + vec0*vecLen + vec1*vecLen;
  189. verts[1] = planeOrigin - vec0*vecLen + vec1*vecLen;
  190. verts[2] = planeOrigin - vec0*vecLen - vec1*vecLen;
  191. verts[3] = planeOrigin + vec0*vecLen - vec1*vecLen;
  192. int startIndex = verticesOut.size();
  193. indicesOut.push_back(startIndex+0);
  194. indicesOut.push_back(startIndex+1);
  195. indicesOut.push_back(startIndex+2);
  196. indicesOut.push_back(startIndex+0);
  197. indicesOut.push_back(startIndex+2);
  198. indicesOut.push_back(startIndex+3);
  199. btVector3 triNormal = parentTransform.getBasis()*planeNormal;
  200. for (int i=0;i<4;i++)
  201. {
  202. GLInstanceVertex vtx;
  203. btVector3 pos =parentTransform*verts[i];
  204. vtx.xyzw[0] = pos.x();
  205. vtx.xyzw[1] = pos.y();
  206. vtx.xyzw[2] = pos.z();
  207. vtx.xyzw[3] = 0.f;
  208. vtx.normal[0] =triNormal.x();
  209. vtx.normal[1] =triNormal.y();
  210. vtx.normal[2] =triNormal.z();
  211. vtx.uv[0] = 0.5f;
  212. vtx.uv[1] = 0.5f;
  213. verticesOut.push_back(vtx);
  214. }
  215. break;
  216. }
  217. case TRIANGLE_MESH_SHAPE_PROXYTYPE:
  218. {
  219. btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*) collisionShape;
  220. btVector3 trimeshScaling = trimesh->getLocalScaling();
  221. btStridingMeshInterface* meshInterface = trimesh->getMeshInterface();
  222. btAlignedObjectArray<btVector3> vertices;
  223. btAlignedObjectArray<int> indices;
  224. for (int partId=0;partId<meshInterface->getNumSubParts();partId++)
  225. {
  226. const unsigned char *vertexbase = 0;
  227. int numverts = 0;
  228. PHY_ScalarType type = PHY_INTEGER;
  229. int stride = 0;
  230. const unsigned char *indexbase = 0;
  231. int indexstride = 0;
  232. int numfaces = 0;
  233. PHY_ScalarType indicestype = PHY_INTEGER;
  234. //PHY_ScalarType indexType=0;
  235. btVector3 triangleVerts[3];
  236. meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
  237. btVector3 aabbMin,aabbMax;
  238. for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
  239. {
  240. unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
  241. for (int j=2;j>=0;j--)
  242. {
  243. int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
  244. if (type == PHY_FLOAT)
  245. {
  246. float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
  247. triangleVerts[j] = btVector3(
  248. graphicsbase[0]*trimeshScaling.getX(),
  249. graphicsbase[1]*trimeshScaling.getY(),
  250. graphicsbase[2]*trimeshScaling.getZ());
  251. }
  252. else
  253. {
  254. double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
  255. triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*trimeshScaling.getX()),
  256. btScalar(graphicsbase[1]*trimeshScaling.getY()),
  257. btScalar(graphicsbase[2]*trimeshScaling.getZ()));
  258. }
  259. }
  260. indices.push_back(vertices.size());
  261. vertices.push_back(triangleVerts[0]);
  262. indices.push_back(vertices.size());
  263. vertices.push_back(triangleVerts[1]);
  264. indices.push_back(vertices.size());
  265. vertices.push_back(triangleVerts[2]);
  266. btVector3 triNormal = (triangleVerts[1]-triangleVerts[0]).cross(triangleVerts[2]-triangleVerts[0]);
  267. triNormal.normalize();
  268. for (int v=0;v<3;v++)
  269. {
  270. GLInstanceVertex vtx;
  271. btVector3 pos =parentTransform*triangleVerts[v];
  272. vtx.xyzw[0] = pos.x();
  273. vtx.xyzw[1] = pos.y();
  274. vtx.xyzw[2] = pos.z();
  275. vtx.xyzw[3] = 0.f;
  276. vtx.normal[0] =triNormal.x();
  277. vtx.normal[1] =triNormal.y();
  278. vtx.normal[2] =triNormal.z();
  279. vtx.uv[0] = 0.5f;
  280. vtx.uv[1] = 0.5f;
  281. indicesOut.push_back(verticesOut.size());
  282. verticesOut.push_back(vtx);
  283. }
  284. }
  285. }
  286. break;
  287. }
  288. default:
  289. {
  290. if (collisionShape->isConvex())
  291. {
  292. btConvexShape* convex = (btConvexShape*)collisionShape;
  293. {
  294. btShapeHull* hull = new btShapeHull(convex);
  295. hull->buildHull(0.0);
  296. {
  297. //int strideInBytes = 9*sizeof(float);
  298. //int numVertices = hull->numVertices();
  299. //int numIndices =hull->numIndices();
  300. for (int t=0;t<hull->numTriangles();t++)
  301. {
  302. btVector3 triNormal;
  303. int index0 = hull->getIndexPointer()[t*3+0];
  304. int index1 = hull->getIndexPointer()[t*3+1];
  305. int index2 = hull->getIndexPointer()[t*3+2];
  306. btVector3 pos0 =parentTransform*hull->getVertexPointer()[index0];
  307. btVector3 pos1 =parentTransform*hull->getVertexPointer()[index1];
  308. btVector3 pos2 =parentTransform*hull->getVertexPointer()[index2];
  309. triNormal = (pos1-pos0).cross(pos2-pos0);
  310. triNormal.normalize();
  311. for (int v=0;v<3;v++)
  312. {
  313. int index = hull->getIndexPointer()[t*3+v];
  314. GLInstanceVertex vtx;
  315. btVector3 pos =parentTransform*hull->getVertexPointer()[index];
  316. vtx.xyzw[0] = pos.x();
  317. vtx.xyzw[1] = pos.y();
  318. vtx.xyzw[2] = pos.z();
  319. vtx.xyzw[3] = 0.f;
  320. vtx.normal[0] =triNormal.x();
  321. vtx.normal[1] =triNormal.y();
  322. vtx.normal[2] =triNormal.z();
  323. vtx.uv[0] = 0.5f;
  324. vtx.uv[1] = 0.5f;
  325. indicesOut.push_back(verticesOut.size());
  326. verticesOut.push_back(vtx);
  327. }
  328. }
  329. }
  330. }
  331. } else
  332. {
  333. if (collisionShape->isCompound())
  334. {
  335. btCompoundShape* compound = (btCompoundShape*) collisionShape;
  336. for (int i=0;i<compound->getNumChildShapes();i++)
  337. {
  338. btTransform childWorldTrans = parentTransform * compound->getChildTransform(i);
  339. createCollisionShapeGraphicsObjectInternal(compound->getChildShape(i),childWorldTrans,verticesOut,indicesOut);
  340. }
  341. } else
  342. {
  343. btAssert(0);
  344. }
  345. }
  346. }
  347. };
  348. }
  349. void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
  350. {
  351. //already has a graphics object?
  352. if (collisionShape->getUserIndex()>=0)
  353. return;
  354. btAlignedObjectArray<GLInstanceVertex> vertices;
  355. btAlignedObjectArray<int> indices;
  356. btTransform startTrans;startTrans.setIdentity();
  357. createCollisionShapeGraphicsObjectInternal(collisionShape,startTrans,vertices,indices);
  358. if (vertices.size() && indices.size())
  359. {
  360. int shapeId = m_data->m_glApp->m_renderer->registerShape(&vertices[0].xyzw[0],vertices.size(),&indices[0],indices.size());
  361. collisionShape->setUserIndex(shapeId);
  362. }
  363. }
  364. void OpenGLGuiHelper::syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)
  365. {
  366. int numCollisionObjects = rbWorld->getNumCollisionObjects();
  367. for (int i = 0; i<numCollisionObjects; i++)
  368. {
  369. btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i];
  370. btVector3 pos = colObj->getWorldTransform().getOrigin();
  371. btQuaternion orn = colObj->getWorldTransform().getRotation();
  372. int index = colObj->getUserIndex();
  373. if (index >= 0)
  374. {
  375. m_data->m_glApp->m_renderer->writeSingleInstanceTransformToCPU(pos, orn, index);
  376. }
  377. }
  378. m_data->m_glApp->m_renderer->writeTransforms();
  379. }
  380. void OpenGLGuiHelper::render(const btDiscreteDynamicsWorld* rbWorld)
  381. {
  382. m_data->m_glApp->m_renderer->renderScene();
  383. //backwards compatible OpenGL2 rendering
  384. if (m_data->m_gl2ShapeDrawer && rbWorld)
  385. {
  386. m_data->m_gl2ShapeDrawer->enableTexture(true);
  387. m_data->m_gl2ShapeDrawer->drawScene(rbWorld,true);
  388. }
  389. }
  390. void OpenGLGuiHelper::createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld)
  391. {
  392. btAssert(rbWorld);
  393. m_data->m_debugDraw = new MyDebugDrawer(m_data->m_glApp);
  394. rbWorld->setDebugDrawer(m_data->m_debugDraw );
  395. m_data->m_debugDraw->setDebugMode(
  396. btIDebugDraw::DBG_DrawWireframe
  397. +btIDebugDraw::DBG_DrawAabb
  398. //btIDebugDraw::DBG_DrawContactPoints
  399. );
  400. }
  401. struct Common2dCanvasInterface* OpenGLGuiHelper::get2dCanvasInterface()
  402. {
  403. return m_data->m_glApp->m_2dCanvasInterface;
  404. }
  405. CommonParameterInterface* OpenGLGuiHelper::getParameterInterface()
  406. {
  407. return m_data->m_glApp->m_parameterInterface;
  408. }
  409. void OpenGLGuiHelper::setUpAxis(int axis)
  410. {
  411. m_data->m_glApp->setUpAxis(axis);
  412. }
  413. void OpenGLGuiHelper::resetCamera(float camDist, float pitch, float yaw, float camPosX,float camPosY, float camPosZ)
  414. {
  415. if (getRenderInterface() && getRenderInterface()->getActiveCamera())
  416. {
  417. getRenderInterface()->getActiveCamera()->setCameraDistance(camDist);
  418. getRenderInterface()->getActiveCamera()->setCameraPitch(pitch);
  419. getRenderInterface()->getActiveCamera()->setCameraYaw(yaw);
  420. getRenderInterface()->getActiveCamera()->setCameraTargetPosition(camPosX,camPosY,camPosZ);
  421. }
  422. }
  423. struct MyConvertPointerSizeT
  424. {
  425. union
  426. {
  427. const void* m_ptr;
  428. size_t m_int;
  429. };
  430. };
  431. bool shapePointerCompareFunc(const btCollisionObject* colA, const btCollisionObject* colB)
  432. {
  433. MyConvertPointerSizeT a,b;
  434. a.m_ptr = colA->getCollisionShape();
  435. b.m_ptr = colB->getCollisionShape();
  436. return (a.m_int<b.m_int);
  437. }
  438. void OpenGLGuiHelper::autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
  439. {
  440. //sort the collision objects based on collision shape, the gfx library requires instances that re-use a shape to be added after eachother
  441. btAlignedObjectArray<btCollisionObject*> sortedObjects;
  442. sortedObjects.reserve(rbWorld->getNumCollisionObjects());
  443. for (int i=0;i<rbWorld->getNumCollisionObjects();i++)
  444. {
  445. btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i];
  446. sortedObjects.push_back(colObj);
  447. }
  448. sortedObjects.quickSort(shapePointerCompareFunc);
  449. for (int i=0;i<sortedObjects.size();i++)
  450. {
  451. btCollisionObject* colObj = sortedObjects[i];
  452. //btRigidBody* body = btRigidBody::upcast(colObj);
  453. //does this also work for btMultiBody/btMultiBodyLinkCollider?
  454. createCollisionShapeGraphicsObject(colObj->getCollisionShape());
  455. int colorIndex = colObj->getBroadphaseHandle()->getUid() & 3;
  456. btVector3 color= sColors[colorIndex];
  457. createCollisionObjectGraphicsObject(colObj,color);
  458. }
  459. }
  460. void OpenGLGuiHelper::drawText3D( const char* txt, float posX, float posY, float posZ, float size)
  461. {
  462. btAssert(m_data->m_glApp);
  463. m_data->m_glApp->drawText3D(txt,posX,posY,posZ,size);
  464. }
  465. struct CommonGraphicsApp* OpenGLGuiHelper::getAppInterface()
  466. {
  467. return m_data->m_glApp;
  468. }