1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #ifdef _WIN32 //needed for glut.h
17 #include <windows.h>
18 #endif
19
20 #include "../OpenGLWindow/OpenGL2Include.h"
21
22 #include "GL_ShapeDrawer.h"
23 #include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
24 #include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
25 #include "BulletCollision/CollisionShapes/btBoxShape.h"
26 #include "BulletCollision/CollisionShapes/btSphereShape.h"
27 #include "BulletCollision/CollisionShapes/btConeShape.h"
28 #include "BulletCollision/CollisionShapes/btCylinderShape.h"
29 #include "BulletCollision/CollisionShapes/btTetrahedronShape.h"
30 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
31 #include "BulletCollision/CollisionShapes/btCapsuleShape.h"
32 #include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h"
33 #include "BulletCollision/CollisionShapes/btUniformScalingShape.h"
34 #include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
35 #include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
36 #include "BulletCollision/CollisionShapes/btConvexPolyhedron.h"
37 #include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
38 #include "BulletDynamics/Dynamics/btRigidBody.h"
39 #include "LinearMath/btDefaultMotionState.h"
40
41 ///
42 #include "BulletCollision/CollisionShapes/btShapeHull.h"
43
44 #include "LinearMath/btTransformUtil.h"
45
46 #include "LinearMath/btIDebugDraw.h"
47 //for debugmodes
48
49 #include <stdio.h> //printf debugging
50
51 #include <cmath>
52
53 #if defined(BT_USE_DOUBLE_PRECISION)
54 #define btglLoadMatrix glLoadMatrixd
55 #define btglMultMatrix glMultMatrixd
56 #define btglColor3 glColor3d
57 #define btglVertex3 glVertex3d
58 #else
59 #define btglLoadMatrix glLoadMatrixf
60 #define btglMultMatrix glMultMatrixf
61 #define btglColor3 glColor3f
62 #define btglVertex3 glVertex3d
63 #endif
64
drawCoordSystem()65 void GL_ShapeDrawer::drawCoordSystem()
66 {
67 glBegin(GL_LINES);
68 glColor3f(1, 0, 0);
69 glVertex3d(0, 0, 0);
70 glVertex3d(1, 0, 0);
71 glColor3f(0, 1, 0);
72 glVertex3d(0, 0, 0);
73 glVertex3d(0, 1, 0);
74 glColor3f(0, 0, 1);
75 glVertex3d(0, 0, 0);
76 glVertex3d(0, 0, 1);
77 glEnd();
78 }
79
80 class GlDrawcallback : public btTriangleCallback
81 {
82 public:
83 bool m_wireframe;
84
GlDrawcallback()85 GlDrawcallback()
86 : m_wireframe(false)
87 {
88 }
89
processTriangle(btVector3 * triangle,int partId,int triangleIndex)90 virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
91 {
92 (void)triangleIndex;
93 (void)partId;
94
95 if (m_wireframe)
96 {
97 glBegin(GL_LINES);
98 glColor3f(1, 0, 0);
99 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
100 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
101 glColor3f(0, 1, 0);
102 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
103 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
104 glColor3f(0, 0, 1);
105 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
106 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
107 glEnd();
108 }
109 else
110 {
111 glBegin(GL_TRIANGLES);
112 //glColor3f(1, 1, 1);
113
114 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
115 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
116 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
117
118 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
119 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
120 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
121 glEnd();
122 }
123 }
124 };
125
126 class TriangleGlDrawcallback : public btInternalTriangleIndexCallback
127 {
128 public:
internalProcessTriangleIndex(btVector3 * triangle,int partId,int triangleIndex)129 virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
130 {
131 (void)triangleIndex;
132 (void)partId;
133
134 glBegin(GL_TRIANGLES); //LINES);
135 glColor3f(1, 0, 0);
136 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
137 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
138 glColor3f(0, 1, 0);
139 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
140 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
141 glColor3f(0, 0, 1);
142 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
143 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
144 glEnd();
145 }
146 };
147
drawSphere(btScalar radius,int lats,int longs)148 void GL_ShapeDrawer::drawSphere(btScalar radius, int lats, int longs)
149 {
150 int i, j;
151 for (i = 0; i <= lats; i++)
152 {
153 btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar)(i - 1) / lats);
154 btScalar z0 = radius * std::sin(lat0);
155 btScalar zr0 = radius * std::cos(lat0);
156
157 btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar)i / lats);
158 btScalar z1 = radius * std::sin(lat1);
159 btScalar zr1 = radius * std::cos(lat1);
160
161 glBegin(GL_QUAD_STRIP);
162 for (j = 0; j <= longs; j++)
163 {
164 btScalar lng = 2 * SIMD_PI * (btScalar)(j - 1) / longs;
165 btScalar x = std::cos(lng);
166 btScalar y = std::sin(lng);
167 glNormal3f(x * zr1, y * zr1, z1);
168 glVertex3f(x * zr1, y * zr1, z1);
169 glNormal3f(x * zr0, y * zr0, z0);
170 glVertex3f(x * zr0, y * zr0, z0);
171 }
172 glEnd();
173 }
174 }
175
cache(btConvexShape * shape)176 GL_ShapeDrawer::ShapeCache* GL_ShapeDrawer::cache(btConvexShape* shape)
177 {
178 ShapeCache* sc = (ShapeCache*)shape->getUserPointer();
179 if (!sc)
180 {
181 sc = new (btAlignedAlloc(sizeof(ShapeCache), 16)) ShapeCache(shape);
182 sc->m_shapehull.buildHull(shape->getMargin());
183 m_shapecaches.push_back(sc);
184 shape->setUserPointer(sc);
185 /* Build edges */
186 const int ni = sc->m_shapehull.numIndices();
187 const int nv = sc->m_shapehull.numVertices();
188 const unsigned int* pi = sc->m_shapehull.getIndexPointer();
189 const btVector3* pv = sc->m_shapehull.getVertexPointer();
190 btAlignedObjectArray<ShapeCache::Edge*> edges;
191 sc->m_edges.reserve(ni);
192 edges.resize(nv * nv, 0);
193 for (int i = 0; i < ni; i += 3)
194 {
195 const unsigned int* ti = pi + i;
196 const btVector3 nrm = btCross(pv[ti[1]] - pv[ti[0]], pv[ti[2]] - pv[ti[0]]).normalized();
197 for (int j = 2, k = 0; k < 3; j = k++)
198 {
199 const unsigned int a = ti[j];
200 const unsigned int b = ti[k];
201 ShapeCache::Edge*& e = edges[btMin(a, b) * nv + btMax(a, b)];
202 if (!e)
203 {
204 sc->m_edges.push_back(ShapeCache::Edge());
205 e = &sc->m_edges[sc->m_edges.size() - 1];
206 e->n[0] = nrm;
207 e->n[1] = -nrm;
208 e->v[0] = a;
209 e->v[1] = b;
210 }
211 else
212 {
213 e->n[1] = nrm;
214 }
215 }
216 }
217 }
218 return (sc);
219 }
220
renderSquareA(float x,float y,float z)221 void renderSquareA(float x, float y, float z)
222 {
223 glBegin(GL_LINE_LOOP);
224 glVertex3f(x, y, z);
225 glVertex3f(x + 10.f, y, z);
226 glVertex3f(x + 10.f, y + 10.f, z);
227 glVertex3f(x, y + 10.f, z);
228 glEnd();
229 }
230
glDrawVector(const btVector3 & v)231 inline void glDrawVector(const btVector3& v) { glVertex3d(v[0], v[1], v[2]); }
232
drawOpenGL(btScalar * m,const btCollisionShape * shape,const btVector3 & color,int debugMode,const btVector3 & worldBoundsMin,const btVector3 & worldBoundsMax)233 void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color, int debugMode, const btVector3& worldBoundsMin, const btVector3& worldBoundsMax)
234 {
235 if (shape->getShapeType() == CUSTOM_CONVEX_SHAPE_TYPE)
236 {
237 btVector3 org(m[12], m[13], m[14]);
238 btVector3 dx(m[0], m[1], m[2]);
239 btVector3 dy(m[4], m[5], m[6]);
240 // btVector3 dz(m[8], m[9], m[10]);
241 const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
242 btVector3 halfExtent = boxShape->getHalfExtentsWithMargin();
243 dx *= halfExtent[0];
244 dy *= halfExtent[1];
245 // dz *= halfExtent[2];
246 glColor3f(1, 1, 1);
247 glDisable(GL_LIGHTING);
248 glLineWidth(2);
249
250 glBegin(GL_LINE_LOOP);
251 glDrawVector(org - dx - dy);
252 glDrawVector(org - dx + dy);
253 glDrawVector(org + dx + dy);
254 glDrawVector(org + dx - dy);
255 glEnd();
256 return;
257 }
258 else if ((shape->getShapeType() == BOX_SHAPE_PROXYTYPE) && (debugMode & btIDebugDraw::DBG_FastWireframe))
259 {
260 btVector3 org(m[12], m[13], m[14]);
261 btVector3 dx(m[0], m[1], m[2]);
262 btVector3 dy(m[4], m[5], m[6]);
263 btVector3 dz(m[8], m[9], m[10]);
264 const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
265 btVector3 halfExtent = boxShape->getHalfExtentsWithMargin();
266 dx *= halfExtent[0];
267 dy *= halfExtent[1];
268 dz *= halfExtent[2];
269 glBegin(GL_LINE_LOOP);
270 glDrawVector(org - dx - dy - dz);
271 glDrawVector(org + dx - dy - dz);
272 glDrawVector(org + dx + dy - dz);
273 glDrawVector(org - dx + dy - dz);
274 glDrawVector(org - dx + dy + dz);
275 glDrawVector(org + dx + dy + dz);
276 glDrawVector(org + dx - dy + dz);
277 glDrawVector(org - dx - dy + dz);
278 glEnd();
279 glBegin(GL_LINES);
280 glDrawVector(org + dx - dy - dz);
281 glDrawVector(org + dx - dy + dz);
282 glDrawVector(org + dx + dy - dz);
283 glDrawVector(org + dx + dy + dz);
284 glDrawVector(org - dx - dy - dz);
285 glDrawVector(org - dx + dy - dz);
286 glDrawVector(org - dx - dy + dz);
287 glDrawVector(org - dx + dy + dz);
288 glEnd();
289 return;
290 }
291
292 glPushMatrix();
293 btglMultMatrix(m);
294
295 if (shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE)
296 {
297 const btUniformScalingShape* scalingShape = static_cast<const btUniformScalingShape*>(shape);
298 const btConvexShape* convexShape = scalingShape->getChildShape();
299 float scalingFactor = (float)scalingShape->getUniformScalingFactor();
300 {
301 btScalar tmpScaling[4][4] = {{scalingFactor, 0, 0, 0},
302 {0, scalingFactor, 0, 0},
303 {0, 0, scalingFactor, 0},
304 {0, 0, 0, 1}};
305
306 drawOpenGL((btScalar*)tmpScaling, convexShape, color, debugMode, worldBoundsMin, worldBoundsMax);
307 }
308 glPopMatrix();
309 return;
310 }
311
312 if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
313 {
314 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
315 for (int i = compoundShape->getNumChildShapes() - 1; i >= 0; i--)
316 {
317 btTransform childTrans = compoundShape->getChildTransform(i);
318 const btCollisionShape* colShape = compoundShape->getChildShape(i);
319 ATTRIBUTE_ALIGNED16(btScalar)
320 childMat[16];
321 childTrans.getOpenGLMatrix(childMat);
322 drawOpenGL(childMat, colShape, color, debugMode, worldBoundsMin, worldBoundsMax);
323 }
324 }
325 else
326 {
327 if (m_textureenabled && (!m_textureinitialized))
328 {
329 GLubyte* image = new GLubyte[256 * 256 * 4];
330 for (int y = 0; y < 256; ++y)
331 {
332 const int t = y >> 4;
333 GLubyte* pi = image + y * 256 * 3;
334 for (int x = 0; x < 256; ++x)
335 {
336 const int s = x >> 4;
337 const GLubyte b = 180;
338 GLubyte c = b + ((s + (t & 1)) & 1) * (255 - b);
339 pi[0] = pi[1] = pi[2] = pi[3] = c;
340 pi += 3;
341 }
342 }
343
344 glGenTextures(1, (GLuint*)&m_texturehandle);
345 glBindTexture(GL_TEXTURE_2D, m_texturehandle);
346
347 glGenTextures(1, (GLuint*)&m_texturehandle);
348 glBindTexture(GL_TEXTURE_2D, m_texturehandle);
349 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
350 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
351 glTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
352 //glGenerateMipmap(GL_TEXTURE_2D);
353 delete[] image;
354 }
355
356 glMatrixMode(GL_TEXTURE);
357 glLoadIdentity();
358 glScalef(0.025f, 0.025f, 0.025f);
359 glMatrixMode(GL_MODELVIEW);
360
361 static const GLfloat planex[] = {1, 0, 0, 0};
362 // static const GLfloat planey[]={0,1,0,0};
363 static const GLfloat planez[] = {0, 0, 1, 0};
364 glTexGenfv(GL_S, GL_OBJECT_PLANE, planex);
365 glTexGenfv(GL_T, GL_OBJECT_PLANE, planez);
366 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
367 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
368 glEnable(GL_TEXTURE_GEN_S);
369 glEnable(GL_TEXTURE_GEN_T);
370 glEnable(GL_TEXTURE_GEN_R);
371 m_textureinitialized = true;
372
373 //drawCoordSystem();
374
375 //glPushMatrix();
376 glEnable(GL_COLOR_MATERIAL);
377 if (m_textureenabled)
378 {
379 glEnable(GL_TEXTURE_2D);
380 glBindTexture(GL_TEXTURE_2D, m_texturehandle);
381 }
382 else
383 {
384 glDisable(GL_TEXTURE_2D);
385 }
386
387 glColor3f(color.x(), color.y(), color.z());
388
389 //bool useWireframeFallback = true;
390
391 if (!(debugMode & btIDebugDraw::DBG_DrawWireframe))
392 {
393 ///you can comment out any of the specific cases, and use the default
394
395 ///the benefit of 'default' is that it approximates the actual collision shape including collision margin
396 //int shapetype=m_textureenabled?MAX_BROADPHASE_COLLISION_TYPES:shape->getShapeType();
397 int shapetype = shape->getShapeType();
398 switch (shapetype)
399 {
400 case SPHERE_SHAPE_PROXYTYPE:
401 {
402 const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
403 float radius = sphereShape->getMargin(); //radius doesn't include the margin, so draw with margin
404 drawSphere(radius, 10, 10);
405 //useWireframeFallback = false;
406 break;
407 }
408
409 case BOX_SHAPE_PROXYTYPE:
410 {
411 const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
412 btVector3 halfExtent = boxShape->getHalfExtentsWithMargin();
413
414 static int indices[36] = {
415 0, 1, 2,
416 3, 2, 1,
417 4, 0, 6,
418 6, 0, 2,
419 5, 1, 4,
420 4, 1, 0,
421 7, 3, 1,
422 7, 1, 5,
423 5, 4, 7,
424 7, 4, 6,
425 7, 2, 3,
426 7, 6, 2};
427
428 btVector3 vertices[8] = {
429 btVector3(halfExtent[0], halfExtent[1], halfExtent[2]),
430 btVector3(-halfExtent[0], halfExtent[1], halfExtent[2]),
431 btVector3(halfExtent[0], -halfExtent[1], halfExtent[2]),
432 btVector3(-halfExtent[0], -halfExtent[1], halfExtent[2]),
433 btVector3(halfExtent[0], halfExtent[1], -halfExtent[2]),
434 btVector3(-halfExtent[0], halfExtent[1], -halfExtent[2]),
435 btVector3(halfExtent[0], -halfExtent[1], -halfExtent[2]),
436 btVector3(-halfExtent[0], -halfExtent[1], -halfExtent[2])};
437 #if 1
438 glBegin(GL_TRIANGLES);
439 int si = 36;
440 for (int i = 0; i < si; i += 3)
441 {
442 const btVector3& v1 = vertices[indices[i]];
443 ;
444 const btVector3& v2 = vertices[indices[i + 1]];
445 const btVector3& v3 = vertices[indices[i + 2]];
446 btVector3 normal = (v3 - v1).cross(v2 - v1);
447 normal.normalize();
448 glNormal3f(normal.getX(), normal.getY(), normal.getZ());
449 glVertex3f(v1.x(), v1.y(), v1.z());
450 glVertex3f(v2.x(), v2.y(), v2.z());
451 glVertex3f(v3.x(), v3.y(), v3.z());
452 }
453 glEnd();
454 #endif
455
456 //useWireframeFallback = false;
457 break;
458 }
459
460 #if 0
461
462 case CONE_SHAPE_PROXYTYPE:
463 {
464 const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
465 int upIndex = coneShape->getConeUpIndex();
466 float radius = coneShape->getRadius();//+coneShape->getMargin();
467 float height = coneShape->getHeight();//+coneShape->getMargin();
468 switch (upIndex)
469 {
470 case 0:
471 glRotatef(90.0, 0.0, 1.0, 0.0);
472 break;
473 case 1:
474 glRotatef(-90.0, 1.0, 0.0, 0.0);
475 break;
476 case 2:
477 break;
478 default:
479 {
480 }
481 };
482
483 glTranslatef(0.0, 0.0, -0.5*height);
484 glutSolidCone(radius,height,10,10);
485 //useWireframeFallback = false;
486 break;
487
488 }
489 #endif
490
491 case STATIC_PLANE_PROXYTYPE:
492 {
493 const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
494 btScalar planeConst = staticPlaneShape->getPlaneConstant();
495 const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
496 btVector3 planeOrigin = planeNormal * planeConst;
497 btVector3 vec0, vec1;
498 btPlaneSpace1(planeNormal, vec0, vec1);
499 btScalar vecLen = 100.f;
500 btVector3 pt0 = planeOrigin + vec0 * vecLen;
501 btVector3 pt1 = planeOrigin - vec0 * vecLen;
502 btVector3 pt2 = planeOrigin + vec1 * vecLen;
503 btVector3 pt3 = planeOrigin - vec1 * vecLen;
504 glBegin(GL_LINES);
505 glVertex3f(pt0.getX(), pt0.getY(), pt0.getZ());
506 glVertex3f(pt1.getX(), pt1.getY(), pt1.getZ());
507 glVertex3f(pt2.getX(), pt2.getY(), pt2.getZ());
508 glVertex3f(pt3.getX(), pt3.getY(), pt3.getZ());
509 glEnd();
510
511 break;
512 }
513
514 case MULTI_SPHERE_SHAPE_PROXYTYPE:
515 {
516 const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
517
518 btTransform childTransform;
519 childTransform.setIdentity();
520
521 for (int i = multiSphereShape->getSphereCount() - 1; i >= 0; i--)
522 {
523 btSphereShape sc(multiSphereShape->getSphereRadius(i));
524 childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
525 ATTRIBUTE_ALIGNED16(btScalar)
526 childMat[16];
527 childTransform.getOpenGLMatrix(childMat);
528 drawOpenGL(childMat, &sc, color, debugMode, worldBoundsMin, worldBoundsMax);
529 }
530
531 break;
532 }
533
534 default:
535 {
536 if (shape->isConvex())
537 {
538 const btConvexPolyhedron* poly = shape->isPolyhedral() ? ((btPolyhedralConvexShape*)shape)->getConvexPolyhedron() : 0;
539 if (poly)
540 {
541 int i;
542 glBegin(GL_TRIANGLES);
543 for (i = 0; i < poly->m_faces.size(); i++)
544 {
545 btVector3 centroid(0, 0, 0);
546 int numVerts = poly->m_faces[i].m_indices.size();
547 if (numVerts > 2)
548 {
549 btVector3 v1 = poly->m_vertices[poly->m_faces[i].m_indices[0]];
550 for (int v = 0; v < poly->m_faces[i].m_indices.size() - 2; v++)
551 {
552 btVector3 v2 = poly->m_vertices[poly->m_faces[i].m_indices[v + 1]];
553 btVector3 v3 = poly->m_vertices[poly->m_faces[i].m_indices[v + 2]];
554 btVector3 normal = (v3 - v1).cross(v2 - v1);
555 normal.normalize();
556 glNormal3f(normal.getX(), normal.getY(), normal.getZ());
557 glVertex3f(v1.x(), v1.y(), v1.z());
558 glVertex3f(v2.x(), v2.y(), v2.z());
559 glVertex3f(v3.x(), v3.y(), v3.z());
560 }
561 }
562 }
563 glEnd();
564 }
565 else
566 {
567 ShapeCache* sc = cache((btConvexShape*)shape);
568 //glutSolidCube(1.0);
569 btShapeHull* hull = &sc->m_shapehull /*(btShapeHull*)shape->getUserPointer()*/;
570
571 if (hull->numTriangles() > 0)
572 {
573 int index = 0;
574 const unsigned int* idx = hull->getIndexPointer();
575 const btVector3* vtx = hull->getVertexPointer();
576
577 glBegin(GL_TRIANGLES);
578
579 for (int i = 0; i < hull->numTriangles(); i++)
580 {
581 int i1 = index++;
582 int i2 = index++;
583 int i3 = index++;
584 btAssert(i1 < hull->numIndices() &&
585 i2 < hull->numIndices() &&
586 i3 < hull->numIndices());
587
588 int index1 = idx[i1];
589 int index2 = idx[i2];
590 int index3 = idx[i3];
591 btAssert(index1 < hull->numVertices() &&
592 index2 < hull->numVertices() &&
593 index3 < hull->numVertices());
594
595 btVector3 v1 = vtx[index1];
596 btVector3 v2 = vtx[index2];
597 btVector3 v3 = vtx[index3];
598 btVector3 normal = (v3 - v1).cross(v2 - v1);
599 normal.normalize();
600 glNormal3f(normal.getX(), normal.getY(), normal.getZ());
601 glVertex3f(v1.x(), v1.y(), v1.z());
602 glVertex3f(v2.x(), v2.y(), v2.z());
603 glVertex3f(v3.x(), v3.y(), v3.z());
604 }
605 glEnd();
606 }
607 }
608 }
609 }
610 }
611 }
612
613 glNormal3f(0, 1, 0);
614
615 /// for polyhedral shapes
616 if (debugMode == btIDebugDraw::DBG_DrawFeaturesText && (shape->isPolyhedral()))
617 {
618 btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*)shape;
619
620 {
621 glColor3f(1.f, 1.f, 1.f);
622 int i;
623 for (i = 0; i < polyshape->getNumVertices(); i++)
624 {
625 btVector3 vtx;
626 polyshape->getVertex(i, vtx);
627 char buf[12];
628 sprintf(buf, " %d", i);
629 //btDrawString(BMF_GetFont(BMF_kHelvetica10),buf);
630 }
631
632 for (i = 0; i < polyshape->getNumPlanes(); i++)
633 {
634 btVector3 normal;
635 btVector3 vtx;
636 polyshape->getPlane(normal, vtx, i);
637 //btScalar d = vtx.dot(normal);
638
639 //char buf[12];
640 //sprintf(buf," plane %d",i);
641 //btDrawString(BMF_GetFont(BMF_kHelvetica10),buf);
642 }
643 }
644 }
645 }
646 glPopMatrix();
647
648 glDisable(GL_TEXTURE_2D);
649 }
650
651 //
drawShadow(btScalar * m,const btVector3 & extrusion,const btCollisionShape * shape,const btVector3 & worldBoundsMin,const btVector3 & worldBoundsMax)652 void GL_ShapeDrawer::drawShadow(btScalar* m, const btVector3& extrusion, const btCollisionShape* shape, const btVector3& worldBoundsMin, const btVector3& worldBoundsMax)
653 {
654 glPushMatrix();
655 btglMultMatrix(m);
656 if (shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE)
657 {
658 const btUniformScalingShape* scalingShape = static_cast<const btUniformScalingShape*>(shape);
659 const btConvexShape* convexShape = scalingShape->getChildShape();
660 float scalingFactor = (float)scalingShape->getUniformScalingFactor();
661 btScalar tmpScaling[4][4] = {{scalingFactor, 0, 0, 0},
662 {0, scalingFactor, 0, 0},
663 {0, 0, scalingFactor, 0},
664 {0, 0, 0, 1}};
665 drawShadow((btScalar*)tmpScaling, extrusion, convexShape, worldBoundsMin, worldBoundsMax);
666 glPopMatrix();
667 return;
668 }
669 else if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
670 {
671 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
672 for (int i = compoundShape->getNumChildShapes() - 1; i >= 0; i--)
673 {
674 btTransform childTrans = compoundShape->getChildTransform(i);
675 const btCollisionShape* colShape = compoundShape->getChildShape(i);
676 ATTRIBUTE_ALIGNED16(btScalar)
677 childMat[16];
678 childTrans.getOpenGLMatrix(childMat);
679 drawShadow(childMat, extrusion * childTrans.getBasis(), colShape, worldBoundsMin, worldBoundsMax);
680 }
681 }
682 else
683 {
684 // bool useWireframeFallback = true;
685 if (shape->isConvex())
686 {
687 ShapeCache* sc = cache((btConvexShape*)shape);
688 btShapeHull* hull = &sc->m_shapehull;
689 glBegin(GL_QUADS);
690 for (int i = 0; i < sc->m_edges.size(); ++i)
691 {
692 const btScalar d = btDot(sc->m_edges[i].n[0], extrusion);
693 if ((d * btDot(sc->m_edges[i].n[1], extrusion)) < 0)
694 {
695 const int q = d < 0 ? 1 : 0;
696 const btVector3& a = hull->getVertexPointer()[sc->m_edges[i].v[q]];
697 const btVector3& b = hull->getVertexPointer()[sc->m_edges[i].v[1 - q]];
698 glVertex3f(a[0], a[1], a[2]);
699 glVertex3f(b[0], b[1], b[2]);
700 glVertex3f(b[0] + extrusion[0], b[1] + extrusion[1], b[2] + extrusion[2]);
701 glVertex3f(a[0] + extrusion[0], a[1] + extrusion[1], a[2] + extrusion[2]);
702 }
703 }
704 glEnd();
705 }
706 }
707
708 if (shape->isConcave()) //>getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
709 // if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
710 {
711 btConcaveShape* concaveMesh = (btConcaveShape*)shape;
712
713 GlDrawcallback drawCallback;
714 drawCallback.m_wireframe = false;
715
716 concaveMesh->processAllTriangles(&drawCallback, worldBoundsMin, worldBoundsMax);
717 }
718 glPopMatrix();
719 }
720
721 //
GL_ShapeDrawer()722 GL_ShapeDrawer::GL_ShapeDrawer()
723 {
724 m_texturehandle = 0;
725 m_textureenabled = false;
726 m_textureinitialized = false;
727 }
728
~GL_ShapeDrawer()729 GL_ShapeDrawer::~GL_ShapeDrawer()
730 {
731 int i;
732 for (i = 0; i < m_shapecaches.size(); i++)
733 {
734 m_shapecaches[i]->~ShapeCache();
735 btAlignedFree(m_shapecaches[i]);
736 }
737 m_shapecaches.clear();
738 if (m_textureinitialized)
739 {
740 glDeleteTextures(1, (const GLuint*)&m_texturehandle);
741 }
742 }
743
drawSceneInternal(const btDiscreteDynamicsWorld * dynamicsWorld,int pass,int cameraUpAxis)744 void GL_ShapeDrawer::drawSceneInternal(const btDiscreteDynamicsWorld* dynamicsWorld, int pass, int cameraUpAxis)
745 {
746 btAssert(dynamicsWorld);
747
748 btScalar m[16];
749 btMatrix3x3 rot;
750 rot.setIdentity();
751 const int numObjects = dynamicsWorld->getNumCollisionObjects();
752 btVector3 wireColor(1, 0, 0);
753 //glDisable(GL_CULL_FACE);
754
755 for (int i = 0; i < numObjects; i++)
756 {
757 const btCollisionObject* colObj = dynamicsWorld->getCollisionObjectArray()[i];
758 const btRigidBody* body = btRigidBody::upcast(colObj);
759 if (body && body->getMotionState())
760 {
761 btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState();
762 myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m);
763 rot = myMotionState->m_graphicsWorldTrans.getBasis();
764 }
765 else
766 {
767 colObj->getWorldTransform().getOpenGLMatrix(m);
768 rot = colObj->getWorldTransform().getBasis();
769 }
770 btVector3 wireColor(1.f, 1.0f, 0.5f); //wants deactivation
771 if (i & 1) wireColor = btVector3(0.f, 0.0f, 1.f);
772 ///color differently for active, sleeping, wantsdeactivation states
773 if (colObj->getActivationState() == 1) //active
774 {
775 if (i & 1)
776 {
777 wireColor += btVector3(1.f, 0.f, 0.f);
778 }
779 else
780 {
781 wireColor += btVector3(.5f, 0.f, 0.f);
782 }
783 }
784 if (colObj->getActivationState() == 2) //ISLAND_SLEEPING
785 {
786 if (i & 1)
787 {
788 wireColor += btVector3(0.f, 1.f, 0.f);
789 }
790 else
791 {
792 wireColor += btVector3(0.f, 0.5f, 0.f);
793 }
794 }
795
796 btVector3 aabbMin(0, 0, 0), aabbMax(0, 0, 0);
797 //m_dynamicsWorld->getBroadphase()->getBroadphaseAabb(aabbMin,aabbMax);
798
799 aabbMin -= btVector3(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT);
800 aabbMax += btVector3(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT);
801 // printf("aabbMin=(%f,%f,%f)\n",aabbMin.getX(),aabbMin.getY(),aabbMin.getZ());
802 // printf("aabbMax=(%f,%f,%f)\n",aabbMax.getX(),aabbMax.getY(),aabbMax.getZ());
803 // m_dynamicsWorld->getDebugDrawer()->drawAabb(aabbMin,aabbMax,btVector3(1,1,1));
804
805 //switch(pass)
806
807 //if (!(getDebugMode()& btIDebugDraw::DBG_DrawWireframe))
808 int debugMode = 0; //getDebugMode()
809 //btVector3 m_sundirection(-1,-1,-1);
810
811 btVector3 m_sundirection(btVector3(1, -2, 1) * 1000);
812 if (cameraUpAxis == 2)
813 {
814 m_sundirection = btVector3(1, 1, -2) * 1000;
815 }
816
817 switch (pass)
818 {
819 case 0:
820 drawOpenGL(m, colObj->getCollisionShape(), wireColor, debugMode, aabbMin, aabbMax);
821 break;
822 case 1:
823 drawShadow(m, m_sundirection * rot, colObj->getCollisionShape(), aabbMin, aabbMax);
824 break;
825 case 2:
826 drawOpenGL(m, colObj->getCollisionShape(), wireColor * btScalar(0.3), 0, aabbMin, aabbMax);
827 break;
828 }
829 }
830 }
831
832 //this GL_ShapeDrawer will be removed, in the meanwhile directly access this global 'useShadoMaps'
833 extern bool useShadowMap;
drawScene(const btDiscreteDynamicsWorld * dynamicsWorld,bool useShadows1,int cameraUpAxis)834 void GL_ShapeDrawer::drawScene(const btDiscreteDynamicsWorld* dynamicsWorld, bool useShadows1, int cameraUpAxis)
835 {
836 bool useShadows = useShadowMap;
837 GLfloat light_ambient[] = {btScalar(0.2), btScalar(0.2), btScalar(0.2), btScalar(1.0)};
838 GLfloat light_diffuse[] = {btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0)};
839 GLfloat light_specular[] = {btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0)};
840 /* light_position is NOT default value */
841 GLfloat light_position0[] = {btScalar(1.0), btScalar(10.0), btScalar(1.0), btScalar(0.0)};
842 GLfloat light_position1[] = {btScalar(-1.0), btScalar(-10.0), btScalar(-1.0), btScalar(0.0)};
843
844 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
845 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
846 glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
847 glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
848
849 glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
850 glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
851 glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
852 glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
853
854 glEnable(GL_LIGHTING);
855 glEnable(GL_LIGHT0);
856 glEnable(GL_LIGHT1);
857
858 glShadeModel(GL_SMOOTH);
859 glEnable(GL_DEPTH_TEST);
860 glDepthFunc(GL_LESS);
861
862 glClearColor(btScalar(0.7), btScalar(0.7), btScalar(0.7), btScalar(0));
863
864 if (useShadows)
865 {
866 glClear(GL_STENCIL_BUFFER_BIT);
867 glEnable(GL_CULL_FACE);
868 drawSceneInternal(dynamicsWorld, 0, cameraUpAxis);
869
870 glDisable(GL_LIGHTING);
871 glDepthMask(GL_FALSE);
872 glDepthFunc(GL_LEQUAL);
873 glEnable(GL_STENCIL_TEST);
874 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
875 glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFFL);
876 glFrontFace(GL_CCW);
877 glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
878 drawSceneInternal(dynamicsWorld, 1, cameraUpAxis);
879 glFrontFace(GL_CW);
880 glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
881 drawSceneInternal(dynamicsWorld, 1, cameraUpAxis);
882 glFrontFace(GL_CCW);
883
884 glPolygonMode(GL_FRONT, GL_FILL);
885 glPolygonMode(GL_BACK, GL_FILL);
886 glShadeModel(GL_SMOOTH);
887 glEnable(GL_DEPTH_TEST);
888 glDepthFunc(GL_LESS);
889 glEnable(GL_LIGHTING);
890 glDepthMask(GL_TRUE);
891 glCullFace(GL_BACK);
892 glFrontFace(GL_CCW);
893 glEnable(GL_CULL_FACE);
894 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
895
896 glDepthFunc(GL_LEQUAL);
897 glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFFL);
898 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
899 glDisable(GL_LIGHTING);
900 drawSceneInternal(dynamicsWorld, 2, cameraUpAxis);
901 glEnable(GL_LIGHTING);
902 glDepthFunc(GL_LESS);
903 glDisable(GL_STENCIL_TEST);
904 glDisable(GL_CULL_FACE);
905 }
906 else
907 {
908 glDisable(GL_CULL_FACE);
909 drawSceneInternal(dynamicsWorld, 0, cameraUpAxis);
910 }
911 }
912