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