2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
16 #ifndef BT_IDEBUG_DRAW__H
17 #define BT_IDEBUG_DRAW__H
19 #include "btVector3.h"
20 #include "btTransform.h"
22 ///The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
23 ///Typical use case: create a debug drawer object, and assign it to a btCollisionWorld or btDynamicsWorld using setDebugDrawer and call debugDrawWorld.
24 ///A class that implements the btIDebugDraw interface will need to provide non-empty implementations of the the drawLine and getDebugMode methods at a minimum.
25 ///For color arguments the X,Y,Z components refer to Red, Green and Blue each in the range [0..1]
29 ATTRIBUTE_ALIGNED16(struct)
32 btVector3 m_activeObject;
33 btVector3 m_deactivatedObject;
34 btVector3 m_wantsDeactivationObject;
35 btVector3 m_disabledDeactivationObject;
36 btVector3 m_disabledSimulationObject;
38 btVector3 m_contactPoint;
41 : m_activeObject(1, 1, 1),
42 m_deactivatedObject(0, 1, 0),
43 m_wantsDeactivationObject(0, 1, 1),
44 m_disabledDeactivationObject(1, 0, 0),
45 m_disabledSimulationObject(1, 1, 0),
47 m_contactPoint(1, 1, 0)
55 DBG_DrawWireframe = 1,
57 DBG_DrawFeaturesText = 4,
58 DBG_DrawContactPoints = 8,
59 DBG_NoDeactivation = 16,
62 DBG_ProfileTimings = 128,
63 DBG_EnableSatComparison = 256,
64 DBG_DisableBulletLCP = 512,
66 DBG_DrawConstraints = (1 << 11),
67 DBG_DrawConstraintLimits = (1 << 12),
68 DBG_FastWireframe = (1 << 13),
69 DBG_DrawNormals = (1 << 14),
70 DBG_DrawFrames = (1 << 15),
71 DBG_MAX_DEBUG_DRAW_MODE
74 virtual ~btIDebugDraw(){};
76 virtual DefaultColors getDefaultColors() const
81 ///the default implementation for setDefaultColors has no effect. A derived class can implement it and store the colors.
82 virtual void setDefaultColors(const DefaultColors& /*colors*/) {}
84 virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& color) = 0;
86 virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
89 drawLine(from, to, fromColor);
92 virtual void drawSphere(btScalar radius, const btTransform& transform, const btVector3& color)
94 btVector3 center = transform.getOrigin();
95 btVector3 up = transform.getBasis().getColumn(1);
96 btVector3 axis = transform.getBasis().getColumn(0);
97 btScalar minTh = -SIMD_HALF_PI;
98 btScalar maxTh = SIMD_HALF_PI;
99 btScalar minPs = -SIMD_HALF_PI;
100 btScalar maxPs = SIMD_HALF_PI;
101 btScalar stepDegrees = 30.f;
102 drawSpherePatch(center, up, axis, radius, minTh, maxTh, minPs, maxPs, color, stepDegrees, false);
103 drawSpherePatch(center, up, -axis, radius, minTh, maxTh, minPs, maxPs, color, stepDegrees, false);
106 virtual void drawSphere(const btVector3& p, btScalar radius, const btVector3& color)
111 drawSphere(radius, tr, color);
114 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)
116 drawTriangle(v0, v1, v2, color, alpha);
118 virtual void drawTriangle(const btVector3& v0, const btVector3& v1, const btVector3& v2, const btVector3& color, btScalar /*alpha*/)
120 drawLine(v0, v1, color);
121 drawLine(v1, v2, color);
122 drawLine(v2, v0, color);
125 virtual void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) = 0;
127 virtual void reportErrorWarning(const char* warningString) = 0;
129 virtual void draw3dText(const btVector3& location, const char* textString) = 0;
131 virtual void setDebugMode(int debugMode) = 0;
133 virtual int getDebugMode() const = 0;
135 virtual void drawAabb(const btVector3& from, const btVector3& to, const btVector3& color)
137 btVector3 halfExtents = (to - from) * 0.5f;
138 btVector3 center = (to + from) * 0.5f;
141 btVector3 edgecoord(1.f, 1.f, 1.f), pa, pb;
142 for (i = 0; i < 4; i++)
144 for (j = 0; j < 3; j++)
146 pa = btVector3(edgecoord[0] * halfExtents[0], edgecoord[1] * halfExtents[1],
147 edgecoord[2] * halfExtents[2]);
150 int othercoord = j % 3;
151 edgecoord[othercoord] *= -1.f;
152 pb = btVector3(edgecoord[0] * halfExtents[0], edgecoord[1] * halfExtents[1],
153 edgecoord[2] * halfExtents[2]);
156 drawLine(pa, pb, color);
158 edgecoord = btVector3(-1.f, -1.f, -1.f);
160 edgecoord[i] *= -1.f;
163 virtual void drawTransform(const btTransform& transform, btScalar orthoLen)
165 btVector3 start = transform.getOrigin();
166 drawLine(start, start + transform.getBasis() * btVector3(orthoLen, 0, 0), btVector3(btScalar(1.), btScalar(0.3), btScalar(0.3)));
167 drawLine(start, start + transform.getBasis() * btVector3(0, orthoLen, 0), btVector3(btScalar(0.3), btScalar(1.), btScalar(0.3)));
168 drawLine(start, start + transform.getBasis() * btVector3(0, 0, orthoLen), btVector3(btScalar(0.3), btScalar(0.3), btScalar(1.)));
171 virtual void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle,
172 const btVector3& color, bool drawSect, btScalar stepDegrees = btScalar(10.f))
174 const btVector3& vx = axis;
175 btVector3 vy = normal.cross(axis);
176 btScalar step = stepDegrees * SIMD_RADS_PER_DEG;
177 int nSteps = (int)btFabs((maxAngle - minAngle) / step);
178 if (!nSteps) nSteps = 1;
179 btVector3 prev = center + radiusA * vx * btCos(minAngle) + radiusB * vy * btSin(minAngle);
182 drawLine(center, prev, color);
184 for (int i = 1; i <= nSteps; i++)
186 btScalar angle = minAngle + (maxAngle - minAngle) * btScalar(i) / btScalar(nSteps);
187 btVector3 next = center + radiusA * vx * btCos(angle) + radiusB * vy * btSin(angle);
188 drawLine(prev, next, color);
193 drawLine(center, prev, color);
196 virtual void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius,
197 btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3& color, btScalar stepDegrees = btScalar(10.f), bool drawCenter = true)
201 btVector3 *pvA = vA, *pvB = vB, *pT;
202 btVector3 npole = center + up * radius;
203 btVector3 spole = center - up * radius;
205 btScalar step = stepDegrees * SIMD_RADS_PER_DEG;
206 const btVector3& kv = up;
207 const btVector3& iv = axis;
208 btVector3 jv = kv.cross(iv);
211 if (minTh <= -SIMD_HALF_PI)
213 minTh = -SIMD_HALF_PI + step;
216 if (maxTh >= SIMD_HALF_PI)
218 maxTh = SIMD_HALF_PI - step;
223 minTh = -SIMD_HALF_PI + step;
224 maxTh = SIMD_HALF_PI - step;
225 drawN = drawS = true;
227 int n_hor = (int)((maxTh - minTh) / step) + 1;
228 if (n_hor < 2) n_hor = 2;
229 btScalar step_h = (maxTh - minTh) / btScalar(n_hor - 1);
230 bool isClosed = false;
233 minPs = -SIMD_PI + step;
237 else if ((maxPs - minPs) >= SIMD_PI * btScalar(2.f))
245 int n_vert = (int)((maxPs - minPs) / step) + 1;
246 if (n_vert < 2) n_vert = 2;
247 btScalar step_v = (maxPs - minPs) / btScalar(n_vert - 1);
248 for (int i = 0; i < n_hor; i++)
250 btScalar th = minTh + btScalar(i) * step_h;
251 btScalar sth = radius * btSin(th);
252 btScalar cth = radius * btCos(th);
253 for (int j = 0; j < n_vert; j++)
255 btScalar psi = minPs + btScalar(j) * step_v;
256 btScalar sps = btSin(psi);
257 btScalar cps = btCos(psi);
258 pvB[j] = center + cth * cps * iv + cth * sps * jv + sth * kv;
261 drawLine(pvA[j], pvB[j], color);
265 drawLine(spole, pvB[j], color);
269 drawLine(pvB[j - 1], pvB[j], color);
275 if ((i == (n_hor - 1)) && drawN)
277 drawLine(npole, pvB[j], color);
284 if (j == (n_vert - 1))
286 drawLine(arcStart, pvB[j], color);
291 if (((!i) || (i == (n_hor - 1))) && ((!j) || (j == (n_vert - 1))))
293 drawLine(center, pvB[j], color);
304 virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color)
306 drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
307 drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
308 drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
309 drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
310 drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
311 drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
312 drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
313 drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
314 drawLine(btVector3(bbMin[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
315 drawLine(btVector3(bbMax[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
316 drawLine(btVector3(bbMax[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
317 drawLine(btVector3(bbMin[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
319 virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btTransform& trans, const btVector3& color)
321 drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
322 drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
323 drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
324 drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
325 drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
326 drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
327 drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
328 drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
329 drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
330 drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
331 drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
332 drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
335 virtual void drawCapsule(btScalar radius, btScalar halfHeight, int upAxis, const btTransform& transform, const btVector3& color)
337 int stepDegrees = 30;
339 btVector3 capStart(0.f, 0.f, 0.f);
340 capStart[upAxis] = -halfHeight;
342 btVector3 capEnd(0.f, 0.f, 0.f);
343 capEnd[upAxis] = halfHeight;
347 btTransform childTransform = transform;
348 childTransform.getOrigin() = transform * capStart;
350 btVector3 center = childTransform.getOrigin();
351 btVector3 up = childTransform.getBasis().getColumn((upAxis + 1) % 3);
352 btVector3 axis = -childTransform.getBasis().getColumn(upAxis);
353 btScalar minTh = -SIMD_HALF_PI;
354 btScalar maxTh = SIMD_HALF_PI;
355 btScalar minPs = -SIMD_HALF_PI;
356 btScalar maxPs = SIMD_HALF_PI;
358 drawSpherePatch(center, up, axis, radius, minTh, maxTh, minPs, maxPs, color, btScalar(stepDegrees), false);
363 btTransform childTransform = transform;
364 childTransform.getOrigin() = transform * capEnd;
366 btVector3 center = childTransform.getOrigin();
367 btVector3 up = childTransform.getBasis().getColumn((upAxis + 1) % 3);
368 btVector3 axis = childTransform.getBasis().getColumn(upAxis);
369 btScalar minTh = -SIMD_HALF_PI;
370 btScalar maxTh = SIMD_HALF_PI;
371 btScalar minPs = -SIMD_HALF_PI;
372 btScalar maxPs = SIMD_HALF_PI;
373 drawSpherePatch(center, up, axis, radius, minTh, maxTh, minPs, maxPs, color, btScalar(stepDegrees), false);
377 // Draw some additional lines
378 btVector3 start = transform.getOrigin();
380 for (int i = 0; i < 360; i += stepDegrees)
382 capEnd[(upAxis + 1) % 3] = capStart[(upAxis + 1) % 3] = btSin(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
383 capEnd[(upAxis + 2) % 3] = capStart[(upAxis + 2) % 3] = btCos(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
384 drawLine(start + transform.getBasis() * capStart, start + transform.getBasis() * capEnd, color);
388 virtual void drawCylinder(btScalar radius, btScalar halfHeight, int upAxis, const btTransform& transform, const btVector3& color)
390 btVector3 start = transform.getOrigin();
391 btVector3 offsetHeight(0, 0, 0);
392 offsetHeight[upAxis] = halfHeight;
393 int stepDegrees = 30;
394 btVector3 capStart(0.f, 0.f, 0.f);
395 capStart[upAxis] = -halfHeight;
396 btVector3 capEnd(0.f, 0.f, 0.f);
397 capEnd[upAxis] = halfHeight;
399 for (int i = 0; i < 360; i += stepDegrees)
401 capEnd[(upAxis + 1) % 3] = capStart[(upAxis + 1) % 3] = btSin(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
402 capEnd[(upAxis + 2) % 3] = capStart[(upAxis + 2) % 3] = btCos(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
403 drawLine(start + transform.getBasis() * capStart, start + transform.getBasis() * capEnd, color);
405 // Drawing top and bottom caps of the cylinder
406 btVector3 yaxis(0, 0, 0);
407 yaxis[upAxis] = btScalar(1.0);
408 btVector3 xaxis(0, 0, 0);
409 xaxis[(upAxis + 1) % 3] = btScalar(1.0);
410 drawArc(start - transform.getBasis() * (offsetHeight), transform.getBasis() * yaxis, transform.getBasis() * xaxis, radius, radius, 0, SIMD_2_PI, color, false, btScalar(10.0));
411 drawArc(start + transform.getBasis() * (offsetHeight), transform.getBasis() * yaxis, transform.getBasis() * xaxis, radius, radius, 0, SIMD_2_PI, color, false, btScalar(10.0));
414 virtual void drawCone(btScalar radius, btScalar height, int upAxis, const btTransform& transform, const btVector3& color)
416 int stepDegrees = 30;
417 btVector3 start = transform.getOrigin();
419 btVector3 offsetHeight(0, 0, 0);
420 btScalar halfHeight = height * btScalar(0.5);
421 offsetHeight[upAxis] = halfHeight;
422 btVector3 offsetRadius(0, 0, 0);
423 offsetRadius[(upAxis + 1) % 3] = radius;
424 btVector3 offset2Radius(0, 0, 0);
425 offset2Radius[(upAxis + 2) % 3] = radius;
427 btVector3 capEnd(0.f, 0.f, 0.f);
428 capEnd[upAxis] = -halfHeight;
430 for (int i = 0; i < 360; i += stepDegrees)
432 capEnd[(upAxis + 1) % 3] = btSin(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
433 capEnd[(upAxis + 2) % 3] = btCos(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
434 drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * capEnd, color);
437 drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight + offsetRadius), color);
438 drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight - offsetRadius), color);
439 drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight + offset2Radius), color);
440 drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight - offset2Radius), color);
442 // Drawing the base of the cone
443 btVector3 yaxis(0, 0, 0);
444 yaxis[upAxis] = btScalar(1.0);
445 btVector3 xaxis(0, 0, 0);
446 xaxis[(upAxis + 1) % 3] = btScalar(1.0);
447 drawArc(start - transform.getBasis() * (offsetHeight), transform.getBasis() * yaxis, transform.getBasis() * xaxis, radius, radius, 0, SIMD_2_PI, color, false, 10.0);
450 virtual void drawPlane(const btVector3& planeNormal, btScalar planeConst, const btTransform& transform, const btVector3& color)
452 btVector3 planeOrigin = planeNormal * planeConst;
453 btVector3 vec0, vec1;
454 btPlaneSpace1(planeNormal, vec0, vec1);
455 btScalar vecLen = 100.f;
456 btVector3 pt0 = planeOrigin + vec0 * vecLen;
457 btVector3 pt1 = planeOrigin - vec0 * vecLen;
458 btVector3 pt2 = planeOrigin + vec1 * vecLen;
459 btVector3 pt3 = planeOrigin - vec1 * vecLen;
460 drawLine(transform * pt0, transform * pt1, color);
461 drawLine(transform * pt2, transform * pt3, color);
464 virtual void clearLines()
468 virtual void flushLines()
473 #endif //BT_IDEBUG_DRAW__H