Tizen 2.1 base
[platform/upstream/libbullet.git] / Extras / RigidBodyGpuPipeline / dynamics / testbed / GL_ShapeDrawer.cpp
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
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 #include "GLDebugFont.h"
20
21
22
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"
39
40
41 ///
42 #include "BulletCollision/CollisionShapes/btShapeHull.h"
43
44 #include "LinearMath/btTransformUtil.h"
45
46
47 #include "LinearMath/btIDebugDraw.h"
48 //for debugmodes
49
50 #include <stdio.h> //printf debugging
51
52 //#define USE_DISPLAY_LISTS 1
53 #ifdef USE_DISPLAY_LISTS
54
55 #include <map>
56
57 using namespace std;
58
59 //Set for storing Display list per trimesh
60 struct TRIMESH_KEY
61 {
62         btCollisionShape* m_shape;
63         GLuint m_dlist;//OpenGL display list    
64 };
65
66 typedef map<unsigned long,TRIMESH_KEY> TRIMESH_KEY_MAP;
67
68 typedef pair<unsigned long,TRIMESH_KEY> TRIMESH_KEY_PAIR;
69
70 TRIMESH_KEY_MAP g_display_lists;
71
72 class GlDisplaylistDrawcallback : public btTriangleCallback
73 {
74 public:
75
76         virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
77         {
78
79                 btVector3 diff1 = triangle[1] - triangle[0];
80                 btVector3 diff2 = triangle[2] - triangle[0];
81                 btVector3 normal = diff1.cross(diff2);
82
83                 normal.normalize();
84
85                 glBegin(GL_TRIANGLES);
86                 glColor3f(1, 1, 1);
87                 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
88                 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
89
90                 //glColor3f(0, 1, 0);
91                 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
92                 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
93
94                 //glColor3f(0, 1, 0);
95                 glNormal3d(normal.getX(),normal.getY(),normal.getZ());
96                 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
97                 glEnd();
98
99                 /*glBegin(GL_LINES);
100                 glColor3f(1, 1, 0);
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());
105                 glColor3f(1, 1, 0);
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());
110                 glColor3f(1, 1, 0);
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());
115                 glEnd();*/
116
117
118         }
119 };
120
121 GLuint  OGL_get_displaylist_for_shape(btCollisionShape * shape)
122 {
123         TRIMESH_KEY_MAP::iterator map_iter;
124
125         unsigned long key = (unsigned long)shape;
126         map_iter = g_display_lists.find(key);
127         if(map_iter!=g_display_lists.end())
128         {
129                 return map_iter->second.m_dlist;
130         }
131
132         return 0;
133 }
134
135 void OGL_displaylist_clean()
136 {
137         TRIMESH_KEY_MAP::iterator map_iter,map_itend;
138
139         map_iter = g_display_lists.begin();
140
141         while(map_iter!=map_itend)
142         {
143                 glDeleteLists(map_iter->second.m_dlist,1);              
144                 map_iter++;
145         }
146
147         g_display_lists.clear();
148 }
149
150
151 void OGL_displaylist_register_shape(btCollisionShape * shape)
152 {
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;
156         TRIMESH_KEY dlist;
157
158         dlist.m_dlist = glGenLists(1);
159         dlist.m_shape = shape;
160
161         unsigned long key = (unsigned long)shape;
162
163         g_display_lists.insert(TRIMESH_KEY_PAIR(key,dlist));
164
165         glNewList(dlist.m_dlist,GL_COMPILE);
166
167 //      glEnable(GL_CULL_FACE);
168
169         glCullFace(GL_BACK);
170
171         if (shape->isConcave())
172         {
173                 btConcaveShape* concaveMesh = (btConcaveShape*) shape;                  
174                 //todo pass camera, for some culling            
175                 concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
176         }
177
178 //      glDisable(GL_CULL_FACE);        
179
180         glEndList();
181 }
182 #endif //USE_DISPLAY_LISTS
183
184 void GL_ShapeDrawer::drawCoordSystem()  {
185         glBegin(GL_LINES);
186         glColor3f(1, 0, 0);
187         glVertex3d(0, 0, 0);
188         glVertex3d(1, 0, 0);
189         glColor3f(0, 1, 0);
190         glVertex3d(0, 0, 0);
191         glVertex3d(0, 1, 0);
192         glColor3f(0, 0, 1);
193         glVertex3d(0, 0, 0);
194         glVertex3d(0, 0, 1);
195         glEnd();
196
197 }
198
199
200
201
202
203 class GlDrawcallback : public btTriangleCallback
204 {
205
206 public:
207
208         bool    m_wireframe;
209
210         GlDrawcallback()
211                 :m_wireframe(false)
212         {
213         }
214
215         virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
216         {
217
218                 (void)triangleIndex;
219                 (void)partId;
220
221
222                 if (m_wireframe)
223                 {
224                         glBegin(GL_LINES);
225                         glColor3f(1, 0, 0);
226                         glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
227                         glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
228                         glColor3f(0, 1, 0);
229                         glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
230                         glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
231                         glColor3f(0, 0, 1);
232                         glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
233                         glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
234                         glEnd();
235                 } else
236                 {
237                         glBegin(GL_TRIANGLES);
238                         //glColor3f(1, 1, 1);
239                         
240                         
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());
244
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());
248                         glEnd();
249                 }
250         }
251 };
252
253 class TriangleGlDrawcallback : public btInternalTriangleIndexCallback
254 {
255 public:
256         virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
257         {
258                 (void)triangleIndex;
259                 (void)partId;
260
261
262                 glBegin(GL_TRIANGLES);//LINES);
263                 glColor3f(1, 0, 0);
264                 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
265                 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
266                 glColor3f(0, 1, 0);
267                 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
268                 glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
269                 glColor3f(0, 0, 1);
270                 glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
271                 glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
272                 glEnd();
273         }
274 };
275
276
277 void GL_ShapeDrawer::drawSphere(btScalar radius, int lats, int longs) 
278 {
279         int i, j;
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);
284
285                 btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar) i / lats);
286                 btScalar z1 = radius*sin(lat1);
287                 btScalar zr1 = radius*cos(lat1);
288
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);
298                 }
299                 glEnd();
300         }
301 }
302
303 void GL_ShapeDrawer::drawCylinder(float radius,float halfHeight, int upAxis)
304 {
305
306
307         glPushMatrix();
308         switch (upAxis)
309         {
310         case 0:
311                 glRotatef(-90.0, 0.0, 1.0, 0.0);
312                 glTranslatef(0.0, 0.0, -halfHeight);
313                 break;
314         case 1:
315                 glRotatef(-90.0, 1.0, 0.0, 0.0);
316                 glTranslatef(0.0, 0.0, -halfHeight);
317                 break;
318         case 2:
319
320                 glTranslatef(0.0, 0.0, -halfHeight);
321                 break;
322         default:
323                 {
324                         btAssert(0);
325                 }
326
327         }
328
329         GLUquadricObj *quadObj = gluNewQuadric();
330
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.
334
335         gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL);
336         gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH);
337
338         gluDisk(quadObj,0,radius,15, 10);
339
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);
344
345         glPopMatrix();
346         gluDeleteQuadric(quadObj);
347 }
348
349 GL_ShapeDrawer::ShapeCache*             GL_ShapeDrawer::cache(btConvexShape* shape)
350 {
351         ShapeCache*             sc=(ShapeCache*)shape->getUserPointer();
352         if(!sc)
353         {
354                 sc=new(btAlignedAlloc(sizeof(ShapeCache),16)) ShapeCache(shape);
355                 
356                 m_shapecaches.push_back(sc);
357                 shape->setUserPointer(sc);
358
359                 const btConvexPolyhedron* poly = shape->isPolyhedral() ? ((btPolyhedralConvexShape*) shape)->getConvexPolyhedron() : 0;
360                 if (poly)
361                 {
362                         int i;
363                         /* Build edges  */ 
364                         const int                       nv=                     poly->m_vertices.size();
365                         if (nv)
366                         {
367                                 const btVector3*        pv=&poly->m_vertices[0];
368                                 btAlignedObjectArray<ShapeCache::Edge*> edges;
369                                 edges.resize(nv*nv,0);
370                                 
371                                 int maxIndices = 0;
372                                 for (i=0;i<poly->m_faces.size();i++)
373                                 {
374                                         maxIndices += poly->m_faces[i].m_indices.size();
375                                 }
376                                 sc->m_edges.reserve(maxIndices);
377
378                                 for (i=0;i<poly->m_faces.size();i++)
379                                 {
380                                         int numVerts = poly->m_faces[i].m_indices.size();
381                                         if (numVerts>2)
382                                         {
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();
388
389                                                 for (int v=0;v<poly->m_faces[i].m_indices.size();j=v++)
390                                                 {
391                                                         {
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];
396                                                                 if(!e)
397                                                                 {
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;
401                                                                         e->v[0]=a;e->v[1]=b;
402                                                                 }
403                                                                 else
404                                                                 {
405                                                                         e->n[1]=nrm;
406                                                                 }
407                                                         }
408                                                 }
409                                         }
410                                 }
411                         }
412
413                 } else
414                 {
415
416                         sc->m_shapehull.buildHull(shape->getMargin());
417
418
419                         /* Build edges  */ 
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)
428                         {
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++)
432                                 {
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)];
436                                         if(!e)
437                                         {
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;
441                                                 e->v[0]=a;e->v[1]=b;
442                                         }
443                                         else
444                                         {
445                                                 e->n[1]=nrm;
446                                         }
447                                 }
448                         }
449                 }
450         }
451         return(sc);
452 }
453
454 void renderSquareA(float x, float y, float z)
455 {
456         glBegin(GL_LINE_LOOP);
457         glVertex3f(x, y, z);
458         glVertex3f(x + 10.f, y, z);
459         glVertex3f(x + 10.f, y + 10.f, z);
460         glVertex3f(x, y + 10.f, z);
461         glEnd();
462 }
463
464 inline void glDrawVector(const btVector3& v) { glVertex3d(v[0], v[1], v[2]); }
465
466
467 void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int  debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax)
468 {
469         
470         if (shape->getShapeType() == CUSTOM_CONVEX_SHAPE_TYPE)
471         {
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();
478                 dx *= halfExtent[0];
479                 dy *= halfExtent[1];
480 //              dz *= halfExtent[2];
481                 glColor3f(1,1,1);
482                 glDisable(GL_LIGHTING);
483                 glLineWidth(2);
484
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);
490                 glEnd();
491                 return;
492         } 
493         else if((shape->getShapeType() == BOX_SHAPE_PROXYTYPE) && (debugMode & btIDebugDraw::DBG_FastWireframe))
494         {
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();
501                 dx *= halfExtent[0];
502                 dy *= halfExtent[1];
503                 dz *= halfExtent[2];
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);
513                 glEnd();
514                 glBegin(GL_LINES);
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);
523                 glEnd();
524                 return;
525         }
526
527         glPushMatrix(); 
528         btglMultMatrix(m);
529
530
531         if (shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE)
532         {
533                 const btUniformScalingShape* scalingShape = static_cast<const btUniformScalingShape*>(shape);
534                 const btConvexShape* convexShape = scalingShape->getChildShape();
535                 float   scalingFactor = (float)scalingShape->getUniformScalingFactor();
536                 {
537                         btScalar tmpScaling[4][4]={{scalingFactor,0,0,0},
538                         {0,scalingFactor,0,0},
539                         {0,0,scalingFactor,0},
540                         {0,0,0,1}};
541
542                         drawOpenGL( (btScalar*)tmpScaling,convexShape,color,debugMode,worldBoundsMin,worldBoundsMax);
543                 }
544                 glPopMatrix();
545                 return;
546         }
547
548         if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
549         {
550                 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
551                 for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
552                 {
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);
558                 }
559
560         } else
561         {
562                 if(m_textureenabled&&(!m_textureinitialized))
563                 {
564                         GLubyte*        image=new GLubyte[256*256*3];
565                         for(int y=0;y<256;++y)
566                         {
567                                 const int       t=y>>4;
568                                 GLubyte*        pi=image+y*256*3;
569                                 for(int x=0;x<256;++x)
570                                 {
571                                         const int               s=x>>4;
572                                         const GLubyte   b=180;                                  
573                                         GLubyte                 c=b+((s+t&1)&1)*(255-b);
574                                         pi[0]=pi[1]=pi[2]=c;pi+=3;
575                                 }
576                         }
577
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);
586                         delete[] image;
587         
588                         
589                 }
590
591                 glMatrixMode(GL_TEXTURE);
592                 glLoadIdentity();
593                 glScalef(0.025f,0.025f,0.025f);
594                 glMatrixMode(GL_MODELVIEW);
595
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;
607
608                 
609                         
610
611                 //drawCoordSystem();
612
613                 //glPushMatrix();
614                 glEnable(GL_COLOR_MATERIAL);
615                 if(m_textureenabled) 
616                 {
617                         glEnable(GL_TEXTURE_2D);
618                         glBindTexture(GL_TEXTURE_2D,m_texturehandle);
619                 } else
620                 {
621                         glDisable(GL_TEXTURE_2D);
622                 }
623
624
625                 glColor3f(color.x(),color.y(), color.z());              
626
627                 bool useWireframeFallback = true;
628
629                 if (!(debugMode & btIDebugDraw::DBG_DrawWireframe))
630                 {
631                         ///you can comment out any of the specific cases, and use the default
632
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();
636                         switch (shapetype)
637                         {
638
639                                 case SPHERE_SHAPE_PROXYTYPE:
640                                 {
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;
645                                         break;
646                                 }
647
648                                 case BOX_SHAPE_PROXYTYPE:
649                                 {
650                                         const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
651                                         btVector3 halfExtent = boxShape->getHalfExtentsWithMargin();
652                                         
653                                         static int indices[36] = {
654                                                 0,1,2,
655                                                 3,2,1,
656                                                 4,0,6,
657                                                 6,0,2,
658                                                 5,1,4,
659                                                 4,1,0,
660                                                 7,3,1,
661                                                 7,1,5,
662                                                 5,4,7,
663                                                 7,4,6,
664                                                 7,2,3,
665                                                 7,6,2};
666
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])};
676 #if 1
677                                         glBegin (GL_TRIANGLES);
678                                         int si=36;
679                                         for (int i=0;i<si;i+=3)
680                                         {
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);
685                                                 normal.normalize ();
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());
690                                                 
691                                         }
692                                         glEnd();
693 #endif
694
695                                         useWireframeFallback = false;
696                                         break;
697                                 }
698
699
700
701 #if 0
702                         
703                         case CONE_SHAPE_PROXYTYPE:
704                                 {
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();
709                                         switch (upIndex)
710                                         {
711                                         case 0:
712                                                 glRotatef(90.0, 0.0, 1.0, 0.0);
713                                                 break;
714                                         case 1:
715                                                 glRotatef(-90.0, 1.0, 0.0, 0.0);
716                                                 break;
717                                         case 2:
718                                                 break;
719                                         default:
720                                                 {
721                                                 }
722                                         };
723
724                                         glTranslatef(0.0, 0.0, -0.5*height);
725                                         glutSolidCone(radius,height,10,10);
726                                         useWireframeFallback = false;
727                                         break;
728
729                                 }
730 #endif
731
732                         case STATIC_PLANE_PROXYTYPE:
733                                 {
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;
738                                         btVector3 vec0,vec1;
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;
745                                         glBegin(GL_LINES);
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());
750                                         glEnd();
751
752
753                                         break;
754
755                                 }
756
757 /*
758                         case CYLINDER_SHAPE_PROXYTYPE:
759                                 {
760                                         const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
761                                         int upAxis = cylinder->getUpAxis();
762
763
764                                         float radius = cylinder->getRadius();
765                                         float halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
766
767                                         drawCylinder(radius,halfHeight,upAxis);
768
769                                         break;
770                                 }
771 */
772
773                         case MULTI_SPHERE_SHAPE_PROXYTYPE:
774                         {
775                                 const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
776
777                                 btTransform childTransform;
778                                 childTransform.setIdentity();
779
780                                 
781                                 for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
782                                 {
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);
788                                 }
789
790                                 break;
791                         }
792
793                         default:
794                                 {
795                                         if (shape->isConvex())
796                                         {
797                                                 const btConvexPolyhedron* poly = shape->isPolyhedral() ? ((btPolyhedralConvexShape*) shape)->getConvexPolyhedron() : 0;
798                                                 if (poly)
799                                                 {
800                                                         int i;
801                                                         glBegin (GL_TRIANGLES);
802                                                         for (i=0;i<poly->m_faces.size();i++)
803                                                         {
804                                                                 btVector3 centroid(0,0,0);
805                                                                 int numVerts = poly->m_faces[i].m_indices.size();
806                                                                 if (numVerts>2)
807                                                                 {
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++)
810                                                                         {
811                                                                                 
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);
815                                                                                 normal.normalize ();
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());
820                                                                         }
821                                                                 }
822                                                         }
823                                                         glEnd ();
824                                                 } else
825                                                 {
826                                                         ShapeCache*     sc=cache((btConvexShape*)shape);
827                                                         //glutSolidCube(1.0);
828                                                         btShapeHull* hull = &sc->m_shapehull/*(btShapeHull*)shape->getUserPointer()*/;
829
830                                                         if (hull && hull->numTriangles () > 0)
831                                                         {
832                                                                 int index = 0;
833                                                                 const unsigned int* idx = hull->getIndexPointer();
834                                                                 const btVector3* vtx = hull->getVertexPointer();
835
836                                                                 glBegin (GL_TRIANGLES);
837
838                                                                 for (int i = 0; i < hull->numTriangles (); i++)
839                                                                 {
840                                                                         int i1 = index++;
841                                                                         int i2 = index++;
842                                                                         int i3 = index++;
843                                                                         btAssert(i1 < hull->numIndices () &&
844                                                                                 i2 < hull->numIndices () &&
845                                                                                 i3 < hull->numIndices ());
846
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 ());
853
854                                                                         btVector3 v1 = vtx[index1];
855                                                                         btVector3 v2 = vtx[index2];
856                                                                         btVector3 v3 = vtx[index3];
857                                                                         btVector3 normal = (v3-v1).cross(v2-v1);
858                                                                         normal.normalize ();
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());
863
864                                                                 }
865                                                                 glEnd ();
866
867                                                         }
868                                                 }
869                                         }
870                                 }
871                         }
872
873                 }
874
875
876                 glNormal3f(0,1,0);
877         
878
879                 /// for polyhedral shapes
880                 if (debugMode==btIDebugDraw::DBG_DrawFeaturesText && (shape->isPolyhedral()))
881                 {
882                         btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
883
884                         {
885
886                                 glColor3f(1.f, 1.f, 1.f);
887                                 int i;
888                                 for (i=0;i<polyshape->getNumVertices();i++)
889                                 {
890                                         btVector3 vtx;
891                                         polyshape->getVertex(i,vtx);
892                                         char buf[12];
893                                         sprintf(buf," %d",i);
894                                         //btDrawString(BMF_GetFont(BMF_kHelvetica10),buf);
895                                 }
896
897                                 for (i=0;i<polyshape->getNumPlanes();i++)
898                                 {
899                                         btVector3 normal;
900                                         btVector3 vtx;
901                                         polyshape->getPlane(normal,vtx,i);
902                                         //btScalar d = vtx.dot(normal);
903
904                                         //char buf[12];
905                                         //sprintf(buf," plane %d",i);
906                                         //btDrawString(BMF_GetFont(BMF_kHelvetica10),buf);
907
908                                 }
909                         }
910
911                 }
912
913
914 #ifdef USE_DISPLAY_LISTS
915
916                 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
917                 {
918                         GLuint dlist =   OGL_get_displaylist_for_shape((btCollisionShape * )shape);
919                         if (dlist)
920                         {
921                                 glCallList(dlist);
922                         }
923                         else
924                         {
925 #else           
926                 if (shape->isConcave() && !shape->isInfinite())
927                 {
928                         btConcaveShape* concaveMesh = (btConcaveShape*) shape;
929
930                         GlDrawcallback drawCallback;
931                         drawCallback.m_wireframe = (debugMode & btIDebugDraw::DBG_DrawWireframe)!=0;
932
933                         concaveMesh->processAllTriangles(&drawCallback,worldBoundsMin,worldBoundsMax);
934
935                 }
936 #endif
937
938 #ifdef USE_DISPLAY_LISTS
939         }
940 }
941 #endif
942
943
944
945
946
947         }
948         glPopMatrix();
949
950 }
951
952 //
953 void            GL_ShapeDrawer::drawShadow(btScalar* m,const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax)
954 {
955         glPushMatrix(); 
956         btglMultMatrix(m);
957         if(shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE)
958         {
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},
965                 {0,0,0,1}};
966                 drawShadow((btScalar*)tmpScaling,extrusion,convexShape,worldBoundsMin,worldBoundsMax);
967                 glPopMatrix();
968                 return;
969         }
970         else if(shape->getShapeType()==COMPOUND_SHAPE_PROXYTYPE)
971         {
972                 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
973                 for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
974                 {
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);
980                 }
981         }
982         else
983         {
984         //      bool useWireframeFallback = true;
985                 if (shape->isConvex())
986                 {
987                         
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;
992                         
993                         vertexPointer = (poly && poly->m_vertices.size())? &poly->m_vertices[0] : 0;
994                         if (!vertexPointer)
995                                 vertexPointer = hull->numVertices() ? hull->getVertexPointer():0;
996
997                         if (vertexPointer)
998                         {
999                                 glBegin(GL_QUADS);
1000                                 for(int i=0;i<sc->m_edges.size();++i)
1001                                 {                       
1002                                         const btScalar          d=btDot(sc->m_edges[i].n[0],extrusion);
1003                                         if((d*btDot(sc->m_edges[i].n[1],extrusion))<0)
1004                                         {
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]);
1012                                         }
1013                                 }
1014                                 glEnd();
1015                         }
1016                 }
1017         }
1018
1019
1020         if (shape->isConcave())//>getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
1021                 //              if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
1022         {
1023                 btConcaveShape* concaveMesh = (btConcaveShape*) shape;
1024
1025                 GlDrawcallback drawCallback;
1026                 drawCallback.m_wireframe = false;
1027
1028                 concaveMesh->processAllTriangles(&drawCallback,worldBoundsMin,worldBoundsMax);
1029
1030         }
1031         glPopMatrix();
1032
1033 }
1034
1035 //
1036 GL_ShapeDrawer::GL_ShapeDrawer()
1037 {
1038         m_texturehandle                 =       0;
1039         m_textureenabled                =       false;
1040         m_textureinitialized    =       false;
1041 }
1042
1043 GL_ShapeDrawer::~GL_ShapeDrawer()
1044 {
1045         int i;
1046         for (i=0;i<m_shapecaches.size();i++)
1047         {
1048                 m_shapecaches[i]->~ShapeCache();
1049                 btAlignedFree(m_shapecaches[i]);
1050         }
1051         m_shapecaches.clear();
1052         if(m_textureinitialized)
1053         {
1054                 glDeleteTextures(1,(const GLuint*) &m_texturehandle);
1055         }
1056 }
1057
1058