2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
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:
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.
16 #ifdef _WIN32 //needed for glut.h
19 #include "GLDebugFont.h"
23 #include "GlutStuff.h"
24 #include "GL_ShapeDrawer.h"
25 #include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
26 #include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
27 #include "BulletCollision/CollisionShapes/btBoxShape.h"
28 #include "BulletCollision/CollisionShapes/btSphereShape.h"
29 #include "BulletCollision/CollisionShapes/btConeShape.h"
30 #include "BulletCollision/CollisionShapes/btCylinderShape.h"
31 #include "BulletCollision/CollisionShapes/btTetrahedronShape.h"
32 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
33 #include "BulletCollision/CollisionShapes/btCapsuleShape.h"
34 #include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h"
35 #include "BulletCollision/CollisionShapes/btUniformScalingShape.h"
36 #include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
37 #include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
38 #include "BulletCollision/CollisionShapes/btConvexPolyhedron.h"
42 #include "BulletCollision/CollisionShapes/btShapeHull.h"
44 #include "LinearMath/btTransformUtil.h"
47 #include "LinearMath/btIDebugDraw.h"
50 #include <stdio.h> //printf debugging
52 //#define USE_DISPLAY_LISTS 1
53 #ifdef USE_DISPLAY_LISTS
59 //Set for storing Display list per trimesh
62 btCollisionShape* m_shape;
63 GLuint m_dlist;//OpenGL display list
66 typedef map<unsigned long,TRIMESH_KEY> TRIMESH_KEY_MAP;
68 typedef pair<unsigned long,TRIMESH_KEY> TRIMESH_KEY_PAIR;
70 TRIMESH_KEY_MAP g_display_lists;
72 class GlDisplaylistDrawcallback : public btTriangleCallback
76 virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
79 btVector3 diff1 = triangle[1] - triangle[0];
80 btVector3 diff2 = triangle[2] - triangle[0];
81 btVector3 normal = diff1.cross(diff2);
85 glBegin(GL_TRIANGLES);
87 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
88 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
91 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
92 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
95 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
96 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
101 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
102 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
103 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
104 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
106 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
107 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
108 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
109 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
111 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
112 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
113 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
114 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
121 GLuint OGL_get_displaylist_for_shape(btCollisionShape * shape)
123 TRIMESH_KEY_MAP::iterator map_iter;
125 unsigned long key = (unsigned long)shape;
126 map_iter = g_display_lists.find(key);
127 if(map_iter!=g_display_lists.end())
129 return map_iter->second.m_dlist;
135 void OGL_displaylist_clean()
137 TRIMESH_KEY_MAP::iterator map_iter,map_itend;
139 map_iter = g_display_lists.begin();
141 while(map_iter!=map_itend)
143 glDeleteLists(map_iter->second.m_dlist,1);
147 g_display_lists.clear();
151 void OGL_displaylist_register_shape(btCollisionShape * shape)
153 btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
154 btVector3 aabbMin(-btScalar(BT_LARGE_FLOAT),-btScalar(BT_LARGE_FLOAT),-btScalar(BT_LARGE_FLOAT));
155 GlDisplaylistDrawcallback drawCallback;
158 dlist.m_dlist = glGenLists(1);
159 dlist.m_shape = shape;
161 unsigned long key = (unsigned long)shape;
163 g_display_lists.insert(TRIMESH_KEY_PAIR(key,dlist));
165 glNewList(dlist.m_dlist,GL_COMPILE);
167 // glEnable(GL_CULL_FACE);
171 if (shape->isConcave())
173 btConcaveShape* concaveMesh = (btConcaveShape*) shape;
174 //todo pass camera, for some culling
175 concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
178 // glDisable(GL_CULL_FACE);
182 #endif //USE_DISPLAY_LISTS
184 void GL_ShapeDrawer::drawCoordSystem() {
203 class GlDrawcallback : public btTriangleCallback
215 virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
226 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
227 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
229 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
230 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
232 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
233 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
237 glBegin(GL_TRIANGLES);
238 //glColor3f(1, 1, 1);
241 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
242 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
243 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
245 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
246 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
247 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
253 class TriangleGlDrawcallback : public btInternalTriangleIndexCallback
256 virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
262 glBegin(GL_TRIANGLES);//LINES);
264 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
265 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
267 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
268 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
270 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
271 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
277 void GL_ShapeDrawer::drawSphere(btScalar radius, int lats, int longs)
280 for(i = 0; i <= lats; i++) {
281 btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar) (i - 1) / lats);
282 btScalar z0 = radius*sin(lat0);
283 btScalar zr0 = radius*cos(lat0);
285 btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar) i / lats);
286 btScalar z1 = radius*sin(lat1);
287 btScalar zr1 = radius*cos(lat1);
289 glBegin(GL_QUAD_STRIP);
290 for(j = 0; j <= longs; j++) {
291 btScalar lng = 2 * SIMD_PI * (btScalar) (j - 1) / longs;
292 btScalar x = cos(lng);
293 btScalar y = sin(lng);
294 glNormal3f(x * zr1, y * zr1, z1);
295 glVertex3f(x * zr1, y * zr1, z1);
296 glNormal3f(x * zr0, y * zr0, z0);
297 glVertex3f(x * zr0, y * zr0, z0);
303 void GL_ShapeDrawer::drawCylinder(float radius,float halfHeight, int upAxis)
311 glRotatef(-90.0, 0.0, 1.0, 0.0);
312 glTranslatef(0.0, 0.0, -halfHeight);
315 glRotatef(-90.0, 1.0, 0.0, 0.0);
316 glTranslatef(0.0, 0.0, -halfHeight);
320 glTranslatef(0.0, 0.0, -halfHeight);
329 GLUquadricObj *quadObj = gluNewQuadric();
331 //The gluCylinder subroutine draws a cylinder that is oriented along the z axis.
332 //The base of the cylinder is placed at z = 0; the top of the cylinder is placed at z=height.
333 //Like a sphere, the cylinder is subdivided around the z axis into slices and along the z axis into stacks.
335 gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL);
336 gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH);
338 gluDisk(quadObj,0,radius,15, 10);
340 gluCylinder(quadObj, radius, radius, 2.f*halfHeight, 15, 10);
341 glTranslatef(0.0f, 0.0f, 2.f*halfHeight);
342 glRotatef(-180.0f, 0.0f, 1.0f, 0.0f);
343 gluDisk(quadObj,0.f,radius,15, 10);
346 gluDeleteQuadric(quadObj);
349 GL_ShapeDrawer::ShapeCache* GL_ShapeDrawer::cache(btConvexShape* shape)
351 ShapeCache* sc=(ShapeCache*)shape->getUserPointer();
354 sc=new(btAlignedAlloc(sizeof(ShapeCache),16)) ShapeCache(shape);
356 m_shapecaches.push_back(sc);
357 shape->setUserPointer(sc);
359 const btConvexPolyhedron* poly = shape->isPolyhedral() ? ((btPolyhedralConvexShape*) shape)->getConvexPolyhedron() : 0;
364 const int nv= poly->m_vertices.size();
367 const btVector3* pv=&poly->m_vertices[0];
368 btAlignedObjectArray<ShapeCache::Edge*> edges;
369 edges.resize(nv*nv,0);
372 for (i=0;i<poly->m_faces.size();i++)
374 maxIndices += poly->m_faces[i].m_indices.size();
376 sc->m_edges.reserve(maxIndices);
378 for (i=0;i<poly->m_faces.size();i++)
380 int numVerts = poly->m_faces[i].m_indices.size();
383 int index0 = poly->m_faces[i].m_indices[0];
384 int index1 = poly->m_faces[i].m_indices[1];
385 int index2 = poly->m_faces[i].m_indices[2];
386 int j = poly->m_faces[i].m_indices.size()-1;
387 const btVector3 nrm=btCross(pv[index1]-pv[index0],pv[index2]-pv[index0]).normalized();
389 for (int v=0;v<poly->m_faces[i].m_indices.size();j=v++)
392 const unsigned int a=poly->m_faces[i].m_indices[j];
393 const unsigned int b=poly->m_faces[i].m_indices[v];
394 int edgeIndex = btMin(a,b)*nv+btMax(a,b);
395 ShapeCache::Edge*& e=edges[edgeIndex];
398 sc->m_edges.push_back(ShapeCache::Edge());
399 e=&sc->m_edges[sc->m_edges.size()-1];
400 e->n[0]=nrm;e->n[1]=-nrm;
416 sc->m_shapehull.buildHull(shape->getMargin());
420 const int ni=sc->m_shapehull.numIndices();
421 const int nv=sc->m_shapehull.numVertices();
422 const unsigned int* pi=sc->m_shapehull.getIndexPointer();
423 const btVector3* pv=sc->m_shapehull.getVertexPointer();
424 btAlignedObjectArray<ShapeCache::Edge*> edges;
425 sc->m_edges.reserve(ni);
426 edges.resize(nv*nv,0);
427 for(int i=0;i<ni;i+=3)
429 const unsigned int* ti=pi+i;
430 const btVector3 nrm=btCross(pv[ti[1]]-pv[ti[0]],pv[ti[2]]-pv[ti[0]]).normalized();
431 for(int j=2,k=0;k<3;j=k++)
433 const unsigned int a=ti[j];
434 const unsigned int b=ti[k];
435 ShapeCache::Edge*& e=edges[btMin(a,b)*nv+btMax(a,b)];
438 sc->m_edges.push_back(ShapeCache::Edge());
439 e=&sc->m_edges[sc->m_edges.size()-1];
440 e->n[0]=nrm;e->n[1]=-nrm;
454 void renderSquareA(float x, float y, float z)
456 glBegin(GL_LINE_LOOP);
458 glVertex3f(x + 10.f, y, z);
459 glVertex3f(x + 10.f, y + 10.f, z);
460 glVertex3f(x, y + 10.f, z);
464 inline void glDrawVector(const btVector3& v) { glVertex3d(v[0], v[1], v[2]); }
467 void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax)
470 if (shape->getShapeType() == CUSTOM_CONVEX_SHAPE_TYPE)
472 btVector3 org(m[12], m[13], m[14]);
473 btVector3 dx(m[0], m[1], m[2]);
474 btVector3 dy(m[4], m[5], m[6]);
475 // btVector3 dz(m[8], m[9], m[10]);
476 const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
477 btVector3 halfExtent = boxShape->getHalfExtentsWithMargin();
480 // dz *= halfExtent[2];
482 glDisable(GL_LIGHTING);
485 glBegin(GL_LINE_LOOP);
486 glDrawVector(org - dx - dy);
487 glDrawVector(org - dx + dy);
488 glDrawVector(org + dx + dy);
489 glDrawVector(org + dx - dy);
493 else if((shape->getShapeType() == BOX_SHAPE_PROXYTYPE) && (debugMode & btIDebugDraw::DBG_FastWireframe))
495 btVector3 org(m[12], m[13], m[14]);
496 btVector3 dx(m[0], m[1], m[2]);
497 btVector3 dy(m[4], m[5], m[6]);
498 btVector3 dz(m[8], m[9], m[10]);
499 const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
500 btVector3 halfExtent = boxShape->getHalfExtentsWithMargin();
504 glBegin(GL_LINE_LOOP);
505 glDrawVector(org - dx - dy - dz);
506 glDrawVector(org + dx - dy - dz);
507 glDrawVector(org + dx + dy - dz);
508 glDrawVector(org - dx + dy - dz);
509 glDrawVector(org - dx + dy + dz);
510 glDrawVector(org + dx + dy + dz);
511 glDrawVector(org + dx - dy + dz);
512 glDrawVector(org - dx - dy + dz);
515 glDrawVector(org + dx - dy - dz);
516 glDrawVector(org + dx - dy + dz);
517 glDrawVector(org + dx + dy - dz);
518 glDrawVector(org + dx + dy + dz);
519 glDrawVector(org - dx - dy - dz);
520 glDrawVector(org - dx + dy - dz);
521 glDrawVector(org - dx - dy + dz);
522 glDrawVector(org - dx + dy + dz);
531 if (shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE)
533 const btUniformScalingShape* scalingShape = static_cast<const btUniformScalingShape*>(shape);
534 const btConvexShape* convexShape = scalingShape->getChildShape();
535 float scalingFactor = (float)scalingShape->getUniformScalingFactor();
537 btScalar tmpScaling[4][4]={{scalingFactor,0,0,0},
538 {0,scalingFactor,0,0},
539 {0,0,scalingFactor,0},
542 drawOpenGL( (btScalar*)tmpScaling,convexShape,color,debugMode,worldBoundsMin,worldBoundsMax);
548 if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
550 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
551 for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
553 btTransform childTrans = compoundShape->getChildTransform(i);
554 const btCollisionShape* colShape = compoundShape->getChildShape(i);
555 btScalar childMat[16];
556 childTrans.getOpenGLMatrix(childMat);
557 drawOpenGL(childMat,colShape,color,debugMode,worldBoundsMin,worldBoundsMax);
562 if(m_textureenabled&&(!m_textureinitialized))
564 GLubyte* image=new GLubyte[256*256*3];
565 for(int y=0;y<256;++y)
568 GLubyte* pi=image+y*256*3;
569 for(int x=0;x<256;++x)
573 GLubyte c=b+((s+t&1)&1)*(255-b);
574 pi[0]=pi[1]=pi[2]=c;pi+=3;
578 glGenTextures(1,(GLuint*)&m_texturehandle);
579 glBindTexture(GL_TEXTURE_2D,m_texturehandle);
580 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
581 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
582 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
583 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
584 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
585 gluBuild2DMipmaps(GL_TEXTURE_2D,3,256,256,GL_RGB,GL_UNSIGNED_BYTE,image);
591 glMatrixMode(GL_TEXTURE);
593 glScalef(0.025f,0.025f,0.025f);
594 glMatrixMode(GL_MODELVIEW);
596 static const GLfloat planex[]={1,0,0,0};
597 // static const GLfloat planey[]={0,1,0,0};
598 static const GLfloat planez[]={0,0,1,0};
599 glTexGenfv(GL_S,GL_OBJECT_PLANE,planex);
600 glTexGenfv(GL_T,GL_OBJECT_PLANE,planez);
601 glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
602 glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
603 glEnable(GL_TEXTURE_GEN_S);
604 glEnable(GL_TEXTURE_GEN_T);
605 glEnable(GL_TEXTURE_GEN_R);
606 m_textureinitialized=true;
614 glEnable(GL_COLOR_MATERIAL);
617 glEnable(GL_TEXTURE_2D);
618 glBindTexture(GL_TEXTURE_2D,m_texturehandle);
621 glDisable(GL_TEXTURE_2D);
625 glColor3f(color.x(),color.y(), color.z());
627 bool useWireframeFallback = true;
629 if (!(debugMode & btIDebugDraw::DBG_DrawWireframe))
631 ///you can comment out any of the specific cases, and use the default
633 ///the benefit of 'default' is that it approximates the actual collision shape including collision margin
634 //int shapetype=m_textureenabled?MAX_BROADPHASE_COLLISION_TYPES:shape->getShapeType();
635 int shapetype=shape->getShapeType();
639 case SPHERE_SHAPE_PROXYTYPE:
641 const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
642 float radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
643 drawSphere(radius,10,10);
644 useWireframeFallback = false;
648 case BOX_SHAPE_PROXYTYPE:
650 const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
651 btVector3 halfExtent = boxShape->getHalfExtentsWithMargin();
653 static int indices[36] = {
667 btVector3 vertices[8]={
668 btVector3(halfExtent[0],halfExtent[1],halfExtent[2]),
669 btVector3(-halfExtent[0],halfExtent[1],halfExtent[2]),
670 btVector3(halfExtent[0],-halfExtent[1],halfExtent[2]),
671 btVector3(-halfExtent[0],-halfExtent[1],halfExtent[2]),
672 btVector3(halfExtent[0],halfExtent[1],-halfExtent[2]),
673 btVector3(-halfExtent[0],halfExtent[1],-halfExtent[2]),
674 btVector3(halfExtent[0],-halfExtent[1],-halfExtent[2]),
675 btVector3(-halfExtent[0],-halfExtent[1],-halfExtent[2])};
677 glBegin (GL_TRIANGLES);
679 for (int i=0;i<si;i+=3)
681 const btVector3& v1 = vertices[indices[i]];;
682 const btVector3& v2 = vertices[indices[i+1]];
683 const btVector3& v3 = vertices[indices[i+2]];
684 btVector3 normal = (v3-v1).cross(v2-v1);
686 glNormal3f(normal.getX(),normal.getY(),normal.getZ());
687 glVertex3f (v1.x(), v1.y(), v1.z());
688 glVertex3f (v2.x(), v2.y(), v2.z());
689 glVertex3f (v3.x(), v3.y(), v3.z());
695 useWireframeFallback = false;
703 case CONE_SHAPE_PROXYTYPE:
705 const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
706 int upIndex = coneShape->getConeUpIndex();
707 float radius = coneShape->getRadius();//+coneShape->getMargin();
708 float height = coneShape->getHeight();//+coneShape->getMargin();
712 glRotatef(90.0, 0.0, 1.0, 0.0);
715 glRotatef(-90.0, 1.0, 0.0, 0.0);
724 glTranslatef(0.0, 0.0, -0.5*height);
725 glutSolidCone(radius,height,10,10);
726 useWireframeFallback = false;
732 case STATIC_PLANE_PROXYTYPE:
734 const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
735 btScalar planeConst = staticPlaneShape->getPlaneConstant();
736 const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
737 btVector3 planeOrigin = planeNormal * planeConst;
739 btPlaneSpace1(planeNormal,vec0,vec1);
740 btScalar vecLen = 100.f;
741 btVector3 pt0 = planeOrigin + vec0*vecLen;
742 btVector3 pt1 = planeOrigin - vec0*vecLen;
743 btVector3 pt2 = planeOrigin + vec1*vecLen;
744 btVector3 pt3 = planeOrigin - vec1*vecLen;
746 glVertex3f(pt0.getX(),pt0.getY(),pt0.getZ());
747 glVertex3f(pt1.getX(),pt1.getY(),pt1.getZ());
748 glVertex3f(pt2.getX(),pt2.getY(),pt2.getZ());
749 glVertex3f(pt3.getX(),pt3.getY(),pt3.getZ());
758 case CYLINDER_SHAPE_PROXYTYPE:
760 const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
761 int upAxis = cylinder->getUpAxis();
764 float radius = cylinder->getRadius();
765 float halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
767 drawCylinder(radius,halfHeight,upAxis);
773 case MULTI_SPHERE_SHAPE_PROXYTYPE:
775 const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
777 btTransform childTransform;
778 childTransform.setIdentity();
781 for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
783 btSphereShape sc(multiSphereShape->getSphereRadius(i));
784 childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
785 btScalar childMat[16];
786 childTransform.getOpenGLMatrix(childMat);
787 drawOpenGL(childMat,&sc,color,debugMode,worldBoundsMin,worldBoundsMax);
795 if (shape->isConvex())
797 const btConvexPolyhedron* poly = shape->isPolyhedral() ? ((btPolyhedralConvexShape*) shape)->getConvexPolyhedron() : 0;
801 glBegin (GL_TRIANGLES);
802 for (i=0;i<poly->m_faces.size();i++)
804 btVector3 centroid(0,0,0);
805 int numVerts = poly->m_faces[i].m_indices.size();
808 btVector3 v1 = poly->m_vertices[poly->m_faces[i].m_indices[0]];
809 for (int v=0;v<poly->m_faces[i].m_indices.size()-2;v++)
812 btVector3 v2 = poly->m_vertices[poly->m_faces[i].m_indices[v+1]];
813 btVector3 v3 = poly->m_vertices[poly->m_faces[i].m_indices[v+2]];
814 btVector3 normal = (v3-v1).cross(v2-v1);
816 glNormal3f(normal.getX(),normal.getY(),normal.getZ());
817 glVertex3f (v1.x(), v1.y(), v1.z());
818 glVertex3f (v2.x(), v2.y(), v2.z());
819 glVertex3f (v3.x(), v3.y(), v3.z());
826 ShapeCache* sc=cache((btConvexShape*)shape);
827 //glutSolidCube(1.0);
828 btShapeHull* hull = &sc->m_shapehull/*(btShapeHull*)shape->getUserPointer()*/;
830 if (hull && hull->numTriangles () > 0)
833 const unsigned int* idx = hull->getIndexPointer();
834 const btVector3* vtx = hull->getVertexPointer();
836 glBegin (GL_TRIANGLES);
838 for (int i = 0; i < hull->numTriangles (); i++)
843 btAssert(i1 < hull->numIndices () &&
844 i2 < hull->numIndices () &&
845 i3 < hull->numIndices ());
847 int index1 = idx[i1];
848 int index2 = idx[i2];
849 int index3 = idx[i3];
850 btAssert(index1 < hull->numVertices () &&
851 index2 < hull->numVertices () &&
852 index3 < hull->numVertices ());
854 btVector3 v1 = vtx[index1];
855 btVector3 v2 = vtx[index2];
856 btVector3 v3 = vtx[index3];
857 btVector3 normal = (v3-v1).cross(v2-v1);
859 glNormal3f(normal.getX(),normal.getY(),normal.getZ());
860 glVertex3f (v1.x(), v1.y(), v1.z());
861 glVertex3f (v2.x(), v2.y(), v2.z());
862 glVertex3f (v3.x(), v3.y(), v3.z());
879 /// for polyhedral shapes
880 if (debugMode==btIDebugDraw::DBG_DrawFeaturesText && (shape->isPolyhedral()))
882 btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
886 glColor3f(1.f, 1.f, 1.f);
888 for (i=0;i<polyshape->getNumVertices();i++)
891 polyshape->getVertex(i,vtx);
893 sprintf(buf," %d",i);
894 //btDrawString(BMF_GetFont(BMF_kHelvetica10),buf);
897 for (i=0;i<polyshape->getNumPlanes();i++)
901 polyshape->getPlane(normal,vtx,i);
902 //btScalar d = vtx.dot(normal);
905 //sprintf(buf," plane %d",i);
906 //btDrawString(BMF_GetFont(BMF_kHelvetica10),buf);
914 #ifdef USE_DISPLAY_LISTS
916 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
918 GLuint dlist = OGL_get_displaylist_for_shape((btCollisionShape * )shape);
926 if (shape->isConcave() && !shape->isInfinite())
928 btConcaveShape* concaveMesh = (btConcaveShape*) shape;
930 GlDrawcallback drawCallback;
931 drawCallback.m_wireframe = (debugMode & btIDebugDraw::DBG_DrawWireframe)!=0;
933 concaveMesh->processAllTriangles(&drawCallback,worldBoundsMin,worldBoundsMax);
938 #ifdef USE_DISPLAY_LISTS
953 void GL_ShapeDrawer::drawShadow(btScalar* m,const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax)
957 if(shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE)
959 const btUniformScalingShape* scalingShape = static_cast<const btUniformScalingShape*>(shape);
960 const btConvexShape* convexShape = scalingShape->getChildShape();
961 float scalingFactor = (float)scalingShape->getUniformScalingFactor();
962 btScalar tmpScaling[4][4]={ {scalingFactor,0,0,0},
963 {0,scalingFactor,0,0},
964 {0,0,scalingFactor,0},
966 drawShadow((btScalar*)tmpScaling,extrusion,convexShape,worldBoundsMin,worldBoundsMax);
970 else if(shape->getShapeType()==COMPOUND_SHAPE_PROXYTYPE)
972 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
973 for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
975 btTransform childTrans = compoundShape->getChildTransform(i);
976 const btCollisionShape* colShape = compoundShape->getChildShape(i);
977 btScalar childMat[16];
978 childTrans.getOpenGLMatrix(childMat);
979 drawShadow(childMat,extrusion*childTrans.getBasis(),colShape,worldBoundsMin,worldBoundsMax);
984 // bool useWireframeFallback = true;
985 if (shape->isConvex())
988 const btConvexPolyhedron* poly = shape->isPolyhedral() ? ((btPolyhedralConvexShape*) shape)->getConvexPolyhedron() : 0;
989 ShapeCache* sc=cache((btConvexShape*)shape);
990 btShapeHull* hull =&sc->m_shapehull;
991 const btVector3* vertexPointer = 0;
993 vertexPointer = (poly && poly->m_vertices.size())? &poly->m_vertices[0] : 0;
995 vertexPointer = hull->numVertices() ? hull->getVertexPointer():0;
1000 for(int i=0;i<sc->m_edges.size();++i)
1002 const btScalar d=btDot(sc->m_edges[i].n[0],extrusion);
1003 if((d*btDot(sc->m_edges[i].n[1],extrusion))<0)
1005 const int q= d<0?1:0;
1006 const btVector3& a= vertexPointer[sc->m_edges[i].v[q]];
1007 const btVector3& b= vertexPointer[sc->m_edges[i].v[1-q]];
1008 glVertex3f(a[0],a[1],a[2]);
1009 glVertex3f(b[0],b[1],b[2]);
1010 glVertex3f(b[0]+extrusion[0],b[1]+extrusion[1],b[2]+extrusion[2]);
1011 glVertex3f(a[0]+extrusion[0],a[1]+extrusion[1],a[2]+extrusion[2]);
1020 if (shape->isConcave())//>getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
1021 // if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
1023 btConcaveShape* concaveMesh = (btConcaveShape*) shape;
1025 GlDrawcallback drawCallback;
1026 drawCallback.m_wireframe = false;
1028 concaveMesh->processAllTriangles(&drawCallback,worldBoundsMin,worldBoundsMax);
1036 GL_ShapeDrawer::GL_ShapeDrawer()
1038 m_texturehandle = 0;
1039 m_textureenabled = false;
1040 m_textureinitialized = false;
1043 GL_ShapeDrawer::~GL_ShapeDrawer()
1046 for (i=0;i<m_shapecaches.size();i++)
1048 m_shapecaches[i]->~ShapeCache();
1049 btAlignedFree(m_shapecaches[i]);
1051 m_shapecaches.clear();
1052 if(m_textureinitialized)
1054 glDeleteTextures(1,(const GLuint*) &m_texturehandle);