Bullet Collision Detection & Physics Library
btIDebugDraw.h
Go to the documentation of this file.
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 
29 {
30  public:
31 
33  {
45  DBG_EnableCCD = 1024,
46  DBG_DrawConstraints = (1 << 11),
48  DBG_FastWireframe = (1<<13),
49  DBG_DrawNormals = (1<<14),
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