bullet: Update to current svn, r2636
[blender.git] / extern / bullet2 / src / LinearMath / btIDebugDraw.h
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans  http://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
17 #ifndef BT_IDEBUG_DRAW__H
18 #define BT_IDEBUG_DRAW__H
19
20 #include "btVector3.h"
21 #include "btTransform.h"
22
23
24 ///The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
25 ///Typical use case: create a debug drawer object, and assign it to a btCollisionWorld or btDynamicsWorld using setDebugDrawer and call debugDrawWorld.
26 ///A class that implements the btIDebugDraw interface has to implement the drawLine method at a minimum.
27 ///For color arguments the X,Y,Z components refer to Red, Green and Blue each in the range [0..1]
28 class   btIDebugDraw
29 {
30         public:
31
32         enum    DebugDrawModes
33         {
34                 DBG_NoDebug=0,
35                 DBG_DrawWireframe = 1,
36                 DBG_DrawAabb=2,
37                 DBG_DrawFeaturesText=4,
38                 DBG_DrawContactPoints=8,
39                 DBG_NoDeactivation=16,
40                 DBG_NoHelpText = 32,
41                 DBG_DrawText=64,
42                 DBG_ProfileTimings = 128,
43                 DBG_EnableSatComparison = 256,
44                 DBG_DisableBulletLCP = 512,
45                 DBG_EnableCCD = 1024,
46                 DBG_DrawConstraints = (1 << 11),
47                 DBG_DrawConstraintLimits = (1 << 12),
48                 DBG_FastWireframe = (1<<13),
49         DBG_DrawNormals = (1<<14),
50                 DBG_MAX_DEBUG_DRAW_MODE
51         };
52
53         virtual ~btIDebugDraw() {};
54
55         virtual void    drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0;
56                 
57         virtual void    drawLine(const btVector3& from,const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
58         {
59         (void) toColor;
60                 drawLine (from, to, fromColor);
61         }
62
63         virtual void    drawSphere(btScalar radius, const btTransform& transform, const btVector3& color)
64         {
65                 btVector3 start = transform.getOrigin();
66
67                 const btVector3 xoffs = transform.getBasis() * btVector3(radius,0,0);
68                 const btVector3 yoffs = transform.getBasis() * btVector3(0,radius,0);
69                 const btVector3 zoffs = transform.getBasis() * btVector3(0,0,radius);
70
71                 // XY 
72                 drawLine(start-xoffs, start+yoffs, color);
73                 drawLine(start+yoffs, start+xoffs, color);
74                 drawLine(start+xoffs, start-yoffs, color);
75                 drawLine(start-yoffs, start-xoffs, color);
76
77                 // XZ
78                 drawLine(start-xoffs, start+zoffs, color);
79                 drawLine(start+zoffs, start+xoffs, color);
80                 drawLine(start+xoffs, start-zoffs, color);
81                 drawLine(start-zoffs, start-xoffs, color);
82
83                 // YZ
84                 drawLine(start-yoffs, start+zoffs, color);
85                 drawLine(start+zoffs, start+yoffs, color);
86                 drawLine(start+yoffs, start-zoffs, color);
87                 drawLine(start-zoffs, start-yoffs, color);
88         }
89         
90         virtual void    drawSphere (const btVector3& p, btScalar radius, const btVector3& color)
91         {
92                 btTransform tr;
93                 tr.setIdentity();
94                 tr.setOrigin(p);
95                 drawSphere(radius,tr,color);
96         }
97         
98         virtual void    drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& /*n0*/,const btVector3& /*n1*/,const btVector3& /*n2*/,const btVector3& color, btScalar alpha)
99         {
100                 drawTriangle(v0,v1,v2,color,alpha);
101         }
102         virtual void    drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& color, btScalar /*alpha*/)
103         {
104                 drawLine(v0,v1,color);
105                 drawLine(v1,v2,color);
106                 drawLine(v2,v0,color);
107         }
108
109         virtual void    drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)=0;
110
111         virtual void    reportErrorWarning(const char* warningString) = 0;
112
113         virtual void    draw3dText(const btVector3& location,const char* textString) = 0;
114         
115         virtual void    setDebugMode(int debugMode) =0;
116         
117         virtual int             getDebugMode() const = 0;
118
119         virtual void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color)
120         {
121
122                 btVector3 halfExtents = (to-from)* 0.5f;
123                 btVector3 center = (to+from) *0.5f;
124                 int i,j;
125
126                 btVector3 edgecoord(1.f,1.f,1.f),pa,pb;
127                 for (i=0;i<4;i++)
128                 {
129                         for (j=0;j<3;j++)
130                         {
131                                 pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],                
132                                         edgecoord[2]*halfExtents[2]);
133                                 pa+=center;
134
135                                 int othercoord = j%3;
136                                 edgecoord[othercoord]*=-1.f;
137                                 pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],        
138                                         edgecoord[2]*halfExtents[2]);
139                                 pb+=center;
140
141                                 drawLine(pa,pb,color);
142                         }
143                         edgecoord = btVector3(-1.f,-1.f,-1.f);
144                         if (i<3)
145                                 edgecoord[i]*=-1.f;
146                 }
147         }
148         virtual void drawTransform(const btTransform& transform, btScalar orthoLen)
149         {
150                 btVector3 start = transform.getOrigin();
151                 drawLine(start, start+transform.getBasis() * btVector3(orthoLen, 0, 0), btVector3(0.7f,0,0));
152                 drawLine(start, start+transform.getBasis() * btVector3(0, orthoLen, 0), btVector3(0,0.7f,0));
153                 drawLine(start, start+transform.getBasis() * btVector3(0, 0, orthoLen), btVector3(0,0,0.7f));
154         }
155
156         virtual void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle, 
157                                 const btVector3& color, bool drawSect, btScalar stepDegrees = btScalar(10.f))
158         {
159                 const btVector3& vx = axis;
160                 btVector3 vy = normal.cross(axis);
161                 btScalar step = stepDegrees * SIMD_RADS_PER_DEG;
162                 int nSteps = (int)((maxAngle - minAngle) / step);
163                 if(!nSteps) nSteps = 1;
164                 btVector3 prev = center + radiusA * vx * btCos(minAngle) + radiusB * vy * btSin(minAngle);
165                 if(drawSect)
166                 {
167                         drawLine(center, prev, color);
168                 }
169                 for(int i = 1; i <= nSteps; i++)
170                 {
171                         btScalar angle = minAngle + (maxAngle - minAngle) * btScalar(i) / btScalar(nSteps);
172                         btVector3 next = center + radiusA * vx * btCos(angle) + radiusB * vy * btSin(angle);
173                         drawLine(prev, next, color);
174                         prev = next;
175                 }
176                 if(drawSect)
177                 {
178                         drawLine(center, prev, color);
179                 }
180         }
181         virtual void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius, 
182                 btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3& color, btScalar stepDegrees = btScalar(10.f))
183         {
184                 btVector3 vA[74];
185                 btVector3 vB[74];
186                 btVector3 *pvA = vA, *pvB = vB, *pT;
187                 btVector3 npole = center + up * radius;
188                 btVector3 spole = center - up * radius;
189                 btVector3 arcStart;
190                 btScalar step = stepDegrees * SIMD_RADS_PER_DEG;
191                 const btVector3& kv = up;
192                 const btVector3& iv = axis;
193                 btVector3 jv = kv.cross(iv);
194                 bool drawN = false;
195                 bool drawS = false;
196                 if(minTh <= -SIMD_HALF_PI)
197                 {
198                         minTh = -SIMD_HALF_PI + step;
199                         drawN = true;
200                 }
201                 if(maxTh >= SIMD_HALF_PI)
202                 {
203                         maxTh = SIMD_HALF_PI - step;
204                         drawS = true;
205                 }
206                 if(minTh > maxTh)
207                 {
208                         minTh = -SIMD_HALF_PI + step;
209                         maxTh =  SIMD_HALF_PI - step;
210                         drawN = drawS = true;
211                 }
212                 int n_hor = (int)((maxTh - minTh) / step) + 1;
213                 if(n_hor < 2) n_hor = 2;
214                 btScalar step_h = (maxTh - minTh) / btScalar(n_hor - 1);
215                 bool isClosed = false;
216                 if(minPs > maxPs)
217                 {
218                         minPs = -SIMD_PI + step;
219                         maxPs =  SIMD_PI;
220                         isClosed = true;
221                 }
222                 else if((maxPs - minPs) >= SIMD_PI * btScalar(2.f))
223                 {
224                         isClosed = true;
225                 }
226                 else
227                 {
228                         isClosed = false;
229                 }
230                 int n_vert = (int)((maxPs - minPs) / step) + 1;
231                 if(n_vert < 2) n_vert = 2;
232                 btScalar step_v = (maxPs - minPs) / btScalar(n_vert - 1);
233                 for(int i = 0; i < n_hor; i++)
234                 {
235                         btScalar th = minTh + btScalar(i) * step_h;
236                         btScalar sth = radius * btSin(th);
237                         btScalar cth = radius * btCos(th);
238                         for(int j = 0; j < n_vert; j++)
239                         {
240                                 btScalar psi = minPs + btScalar(j) * step_v;
241                                 btScalar sps = btSin(psi);
242                                 btScalar cps = btCos(psi);
243                                 pvB[j] = center + cth * cps * iv + cth * sps * jv + sth * kv;
244                                 if(i)
245                                 {
246                                         drawLine(pvA[j], pvB[j], color);
247                                 }
248                                 else if(drawS)
249                                 {
250                                         drawLine(spole, pvB[j], color);
251                                 }
252                                 if(j)
253                                 {
254                                         drawLine(pvB[j-1], pvB[j], color);
255                                 }
256                                 else
257                                 {
258                                         arcStart = pvB[j];
259                                 }
260                                 if((i == (n_hor - 1)) && drawN)
261                                 {
262                                         drawLine(npole, pvB[j], color);
263                                 }
264                                 if(isClosed)
265                                 {
266                                         if(j == (n_vert-1))
267                                         {
268                                                 drawLine(arcStart, pvB[j], color);
269                                         }
270                                 }
271                                 else
272                                 {
273                                         if(((!i) || (i == (n_hor-1))) && ((!j) || (j == (n_vert-1))))
274                                         {
275                                                 drawLine(center, pvB[j], color);
276                                         }
277                                 }
278                         }
279                         pT = pvA; pvA = pvB; pvB = pT;
280                 }
281         }
282         
283   
284         virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color)
285         {
286                 drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
287                 drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
288                 drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
289                 drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
290                 drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
291                 drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
292                 drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
293                 drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
294                 drawLine(btVector3(bbMin[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
295                 drawLine(btVector3(bbMax[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
296                 drawLine(btVector3(bbMax[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
297                 drawLine(btVector3(bbMin[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
298         }
299         virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btTransform& trans, const btVector3& color)
300         {
301                 drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
302                 drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
303                 drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
304                 drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
305                 drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
306                 drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
307                 drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
308                 drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
309                 drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
310                 drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
311                 drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
312                 drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
313         }
314
315         virtual void drawCapsule(btScalar radius, btScalar halfHeight, int upAxis, const btTransform& transform, const btVector3& color)
316         {
317                 btVector3 capStart(0.f,0.f,0.f);
318                 capStart[upAxis] = -halfHeight;
319
320                 btVector3 capEnd(0.f,0.f,0.f);
321                 capEnd[upAxis] = halfHeight;
322
323                 // Draw the ends
324                 {
325
326                         btTransform childTransform = transform;
327                         childTransform.getOrigin() = transform * capStart;
328                         drawSphere(radius, childTransform, color);
329                 }
330
331                 {
332                         btTransform childTransform = transform;
333                         childTransform.getOrigin() = transform * capEnd;
334                         drawSphere(radius, childTransform, color);
335                 }
336
337                 // Draw some additional lines
338                 btVector3 start = transform.getOrigin();
339
340                 capStart[(upAxis+1)%3] = radius;
341                 capEnd[(upAxis+1)%3] = radius;
342                 drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color);
343                 capStart[(upAxis+1)%3] = -radius;
344                 capEnd[(upAxis+1)%3] = -radius;
345                 drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color);
346
347                 capStart[(upAxis+1)%3] = 0.f;
348                 capEnd[(upAxis+1)%3] = 0.f;
349
350                 capStart[(upAxis+2)%3] = radius;
351                 capEnd[(upAxis+2)%3] = radius;
352                 drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color);
353                 capStart[(upAxis+2)%3] = -radius;
354                 capEnd[(upAxis+2)%3] = -radius;
355                 drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color);
356         }
357
358         virtual void drawCylinder(btScalar radius, btScalar halfHeight, int upAxis, const btTransform& transform, const btVector3& color)
359         {
360                 btVector3 start = transform.getOrigin();
361                 btVector3       offsetHeight(0,0,0);
362                 offsetHeight[upAxis] = halfHeight;
363                 btVector3       offsetRadius(0,0,0);
364                 offsetRadius[(upAxis+1)%3] = radius;
365                 drawLine(start+transform.getBasis() * (offsetHeight+offsetRadius),start+transform.getBasis() * (-offsetHeight+offsetRadius),color);
366                 drawLine(start+transform.getBasis() * (offsetHeight-offsetRadius),start+transform.getBasis() * (-offsetHeight-offsetRadius),color);
367
368                 // Drawing top and bottom caps of the cylinder
369                 btVector3 yaxis(0,0,0);
370                 yaxis[upAxis] = btScalar(1.0);
371                 btVector3 xaxis(0,0,0);
372                 xaxis[(upAxis+1)%3] = btScalar(1.0);
373                 drawArc(start-transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0));
374                 drawArc(start+transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0));
375         }
376
377         virtual void drawCone(btScalar radius, btScalar height, int upAxis, const btTransform& transform, const btVector3& color)
378         {
379
380                 btVector3 start = transform.getOrigin();
381
382                 btVector3       offsetHeight(0,0,0);
383                 offsetHeight[upAxis] = height * btScalar(0.5);
384                 btVector3       offsetRadius(0,0,0);
385                 offsetRadius[(upAxis+1)%3] = radius;
386                 btVector3       offset2Radius(0,0,0);
387                 offset2Radius[(upAxis+2)%3] = radius;
388
389                 drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight+offsetRadius),color);
390                 drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight-offsetRadius),color);
391                 drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight+offset2Radius),color);
392                 drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight-offset2Radius),color);
393
394                 // Drawing the base of the cone
395                 btVector3 yaxis(0,0,0);
396                 yaxis[upAxis] = btScalar(1.0);
397                 btVector3 xaxis(0,0,0);
398                 xaxis[(upAxis+1)%3] = btScalar(1.0);
399                 drawArc(start-transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,10.0);
400         }
401
402         virtual void drawPlane(const btVector3& planeNormal, btScalar planeConst, const btTransform& transform, const btVector3& color)
403         {
404                 btVector3 planeOrigin = planeNormal * planeConst;
405                 btVector3 vec0,vec1;
406                 btPlaneSpace1(planeNormal,vec0,vec1);
407                 btScalar vecLen = 100.f;
408                 btVector3 pt0 = planeOrigin + vec0*vecLen;
409                 btVector3 pt1 = planeOrigin - vec0*vecLen;
410                 btVector3 pt2 = planeOrigin + vec1*vecLen;
411                 btVector3 pt3 = planeOrigin - vec1*vecLen;
412                 drawLine(transform*pt0,transform*pt1,color);
413                 drawLine(transform*pt2,transform*pt3,color);
414         }
415 };
416
417
418 #endif //BT_IDEBUG_DRAW__H
419