Panda3D
 All Classes Functions Variables Enumerations
bulletDebugNode.cxx
1 // Filename: bulletDebugNode.cxx
2 // Created by: enn0x (23Jan10)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "bulletDebugNode.h"
16 
17 #include "geomLines.h"
18 #include "geomVertexData.h"
19 #include "geomTriangles.h"
20 #include "geomVertexFormat.h"
21 #include "geomVertexWriter.h"
22 #include "omniBoundingVolume.h"
23 
24 TypeHandle BulletDebugNode::_type_handle;
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: BulletDebugNode::Constructor
28 // Access: Published
29 // Description:
30 ////////////////////////////////////////////////////////////////////
31 BulletDebugNode::
32 BulletDebugNode(const char *name) : GeomNode(name) {
33 
34  _wireframe = true;
35  _constraints = true;
36  _bounds = false;
37  _drawer._normals = true;
38 
39  CPT (BoundingVolume) bounds = new OmniBoundingVolume();
40  set_bounds(bounds);
41  set_final(true);
42  set_overall_hidden(true);
43 
44  // Lines
45  {
46  PT(GeomVertexData) vdata;
47  PT(Geom) geom;
48  PT(GeomLines) prim;
49 
50  vdata = new GeomVertexData("", GeomVertexFormat::get_v3c4(), Geom::UH_stream);
51 
52  prim = new GeomLines(Geom::UH_stream);
53  prim->set_shade_model(Geom::SM_uniform);
54 
55  geom = new Geom(vdata);
56  geom->add_primitive(prim);
57 
58  add_geom(geom);
59  }
60 
61  // Triangles
62  {
63  PT(GeomVertexData) vdata;
64  PT(Geom) geom;
65  PT(GeomTriangles) prim;
66 
67  vdata = new GeomVertexData("", GeomVertexFormat::get_v3c4(), Geom::UH_stream);
68 
69  prim = new GeomTriangles(Geom::UH_stream);
70  prim->set_shade_model(Geom::SM_uniform);
71 
72  geom = new Geom(vdata);
73  geom->add_primitive(prim);
74 
75  add_geom(geom);
76  }
77 }
78 
79 ////////////////////////////////////////////////////////////////////
80 // Function: BulletDebugNode::safe_to_flatten
81 // Access: Public, Virtual
82 // Description: Returns true if it is generally safe to flatten out
83 // this particular kind of Node by duplicating
84 // instances, false otherwise (for instance, a Camera
85 // cannot be safely flattened, because the Camera
86 // pointer itself is meaningful).
87 ////////////////////////////////////////////////////////////////////
88 bool BulletDebugNode::
89 safe_to_flatten() const {
90 
91  return false;
92 }
93 
94 ////////////////////////////////////////////////////////////////////
95 // Function: BulletDebugNode::safe_to_transform
96 // Access: Public, Virtual
97 // Description: Returns true if it is generally safe to transform
98 // this particular kind of Node by calling the xform()
99 // method, false otherwise. For instance, it's usually
100 // a bad idea to attempt to xform a Character.
101 ////////////////////////////////////////////////////////////////////
104 
105  return false;
106 }
107 
108 ////////////////////////////////////////////////////////////////////
109 // Function: BulletDebugNode::safe_to_modify_transform
110 // Access: Public, Virtual
111 // Description: Returns true if it is safe to automatically adjust
112 // the transform on this kind of node. Usually, this is
113 // only a bad idea if the user expects to find a
114 // particular transform on the node.
115 //
116 // ModelNodes with the preserve_transform flag set are
117 // presently the only kinds of nodes that should not
118 // have their transform even adjusted.
119 ////////////////////////////////////////////////////////////////////
122 
123  return false;
124 }
125 
126 ////////////////////////////////////////////////////////////////////
127 // Function: BulletDebugNode::safe_to_combine
128 // Access: Public, Virtual
129 // Description: Returns true if it is generally safe to combine this
130 // particular kind of PandaNode with other kinds of
131 // PandaNodes of compatible type, adding children or
132 // whatever. For instance, an LODNode should not be
133 // combined with any other PandaNode, because its set of
134 // children is meaningful.
135 ////////////////////////////////////////////////////////////////////
138 
139  return false;
140 }
141 
142 ////////////////////////////////////////////////////////////////////
143 // Function: BulletDebugNode::safe_to_combine_children
144 // Access: Public, Virtual
145 // Description: Returns true if it is generally safe to combine the
146 // children of this PandaNode with each other. For
147 // instance, an LODNode's children should not be
148 // combined with each other, because the set of children
149 // is meaningful.
150 ////////////////////////////////////////////////////////////////////
153 
154  return false;
155 }
156 
157 ////////////////////////////////////////////////////////////////////
158 // Function: BulletDebugNode::safe_to_flatten_below
159 // Access: Public, Virtual
160 // Description: Returns true if a flatten operation may safely
161 // continue past this node, or false if nodes below this
162 // node may not be molested.
163 ////////////////////////////////////////////////////////////////////
166 
167  return false;
168 }
169 
170 ////////////////////////////////////////////////////////////////////
171 // Function: BulletDebugNode::draw_mask_changed
172 // Access: Published
173 // Description:
174 ////////////////////////////////////////////////////////////////////
177 
178  if (is_overall_hidden()) {
179  _drawer.setDebugMode(DebugDraw::DBG_NoDebug);
180  }
181  else {
182  int mode = DebugDraw::DBG_DrawText |
183  DebugDraw::DBG_DrawFeaturesText |
184  DebugDraw::DBG_DrawContactPoints;
185 
186  if (_wireframe) {
187  mode |= DebugDraw::DBG_DrawWireframe;
188  }
189 
190  if (_constraints) {
191  mode |= DebugDraw::DBG_DrawConstraints;
192  mode |= DebugDraw::DBG_DrawConstraintLimits;
193  }
194 
195  if (_bounds) {
196  mode |= DebugDraw::DBG_DrawAabb;
197  }
198 
199  _drawer.setDebugMode(mode);
200  }
201 }
202 
203 ////////////////////////////////////////////////////////////////////
204 // Function: BulletDebugNode::sync_b2p
205 // Access: Private
206 // Description:
207 ////////////////////////////////////////////////////////////////////
208 void BulletDebugNode::
209 sync_b2p(btDynamicsWorld *world) {
210 
211  if (is_overall_hidden()) return;
212 
213  nassertv(get_num_geoms() == 2);
214 
215  // Collect debug geometry data
216  _drawer._lines.clear();
217  _drawer._triangles.clear();
218 
219  world->debugDrawWorld();
220 
221  // Get inverse of this node's net transform
222  NodePath np = NodePath::any_path((PandaNode *)this);
223  LMatrix4 m = np.get_net_transform()->get_mat();
224  m.invert_in_place();
225 
226  // Render lines
227  {
228  PT(GeomVertexData) vdata;
229  PT(Geom) geom;
230  PT(GeomLines) prim;
231 
232  vdata = new GeomVertexData("", GeomVertexFormat::get_v3c4(), Geom::UH_stream);
233 
234  prim = new GeomLines(Geom::UH_stream);
235  prim->set_shade_model(Geom::SM_uniform);
236 
237  GeomVertexWriter vwriter = GeomVertexWriter(vdata, InternalName::get_vertex());
238  GeomVertexWriter cwriter = GeomVertexWriter(vdata, InternalName::get_color());
239 
240  int v = 0;
241 
242  pvector<Line>::const_iterator lit;
243  for (lit = _drawer._lines.begin(); lit != _drawer._lines.end(); lit++) {
244  Line line = *lit;
245 
246  vwriter.add_data3(m.xform_point(line._p0));
247  vwriter.add_data3(m.xform_point(line._p1));
248  cwriter.add_data4(LVecBase4(line._color));
249  cwriter.add_data4(LVecBase4(line._color));
250 
251  prim->add_vertex(v++);
252  prim->add_vertex(v++);
253  prim->close_primitive();
254  }
255 
256  geom = new Geom(vdata);
257  geom->add_primitive(prim);
258 
259  set_geom(0, geom);
260  }
261 
262  // Render triangles
263  {
264  PT(GeomVertexData) vdata;
265  PT(Geom) geom;
266  PT(GeomTriangles) prim;
267 
268  vdata = new GeomVertexData("", GeomVertexFormat::get_v3c4(), Geom::UH_stream);
269 
270  prim = new GeomTriangles(Geom::UH_stream);
271  prim->set_shade_model(Geom::SM_uniform);
272 
273  GeomVertexWriter vwriter = GeomVertexWriter(vdata, InternalName::get_vertex());
274  GeomVertexWriter cwriter = GeomVertexWriter(vdata, InternalName::get_color());
275 
276  int v = 0;
277 
278  pvector<Triangle>::const_iterator tit;
279  for (tit = _drawer._triangles.begin(); tit != _drawer._triangles.end(); tit++) {
280  Triangle tri = *tit;
281 
282  vwriter.add_data3(m.xform_point(tri._p0));
283  vwriter.add_data3(m.xform_point(tri._p1));
284  vwriter.add_data3(m.xform_point(tri._p2));
285  cwriter.add_data4(LVecBase4(tri._color));
286  cwriter.add_data4(LVecBase4(tri._color));
287  cwriter.add_data4(LVecBase4(tri._color));
288 
289  prim->add_vertex(v++);
290  prim->add_vertex(v++);
291  prim->add_vertex(v++);
292  prim->close_primitive();
293  }
294 
295  geom = new Geom(vdata);
296  geom->add_primitive(prim);
297 
298  set_geom(1, geom);
299  }
300 }
301 
302 ////////////////////////////////////////////////////////////////////
303 // Function: BulletDebugNode::DebugDraw::setDebugMode
304 // Access: Public
305 // Description:
306 ////////////////////////////////////////////////////////////////////
307 void BulletDebugNode::DebugDraw::
308 setDebugMode(int mode) {
309 
310  _mode = mode;
311 }
312 
313 ////////////////////////////////////////////////////////////////////
314 // Function: BulletDebugNode::DebugDraw::getDebugMode
315 // Access: Public
316 // Description:
317 ////////////////////////////////////////////////////////////////////
318 int BulletDebugNode::DebugDraw::
319 getDebugMode() const {
320 
321  return _mode;
322 }
323 
324 ////////////////////////////////////////////////////////////////////
325 // Function: BulletDebugNode::DebugDraw::reportErrorWarning
326 // Access: Public
327 // Description:
328 ////////////////////////////////////////////////////////////////////
329 void BulletDebugNode::DebugDraw::
330 reportErrorWarning(const char *warning) {
331 
332  bullet_cat.error() << warning << endl;
333 }
334 
335 ////////////////////////////////////////////////////////////////////
336 // Function: BulletDebugNode::DebugDraw::drawLine
337 // Access: Public
338 // Description:
339 ////////////////////////////////////////////////////////////////////
340 void BulletDebugNode::DebugDraw::
341 drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color) {
342 
343  PN_stdfloat r = color.getX();
344  PN_stdfloat g = color.getY();
345  PN_stdfloat b = color.getZ();
346 
347  // Hack to get rid of triangle normals. The hack is based on the
348  // assumption that only normals are drawn in yellow.
349  if (_normals==false && r==1.0f && g==1.0f && b==0.0f) return;
350 
351  Line line;
352 
353  line._p0 = LVecBase3((PN_stdfloat)from.getX(),
354  (PN_stdfloat)from.getY(),
355  (PN_stdfloat)from.getZ());
356  line._p1 = LVecBase3((PN_stdfloat)to.getX(),
357  (PN_stdfloat)to.getY(),
358  (PN_stdfloat)to.getZ());
359  line._color = UnalignedLVecBase4((PN_stdfloat)r,
360  (PN_stdfloat)g,
361  (PN_stdfloat)b, 1.0f);
362 
363  _lines.push_back(line);
364 }
365 
366 ////////////////////////////////////////////////////////////////////
367 // Function: BulletDebugNode::DebugDraw::drawTriangle
368 // Access: Public
369 // Description:
370 ////////////////////////////////////////////////////////////////////
371 void BulletDebugNode::DebugDraw::
372 drawTriangle(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &color, btScalar) {
373 
374  btScalar r = color.getX();
375  btScalar g = color.getY();
376  btScalar b = color.getZ();
377 
378  Triangle tri;
379 
380  tri._p0 = LVecBase3((PN_stdfloat)v0.getX(),
381  (PN_stdfloat)v0.getY(),
382  (PN_stdfloat)v0.getZ());
383 
384  tri._p1 = LVecBase3((PN_stdfloat)v1.getX(),
385  (PN_stdfloat)v1.getY(),
386  (PN_stdfloat)v1.getZ());
387 
388  tri._p2 = LVecBase3((PN_stdfloat)v2.getX(),
389  (PN_stdfloat)v2.getY(),
390  (PN_stdfloat)v2.getZ());
391 
392  tri._color = UnalignedLVecBase4((PN_stdfloat)r,
393  (PN_stdfloat)g,
394  (PN_stdfloat)b, 1.0f);
395 
396  _triangles.push_back(tri);
397 
398 
399  // Draw the triangle's normal
400 /*
401  btVector3 x1 = v1 - v0;
402  btVector3 x2 = v2 - v0;
403  btVector3 normal = v1.cross(v2).normalize();
404 
405  btVector3 from = (v0 + v1 + v2) * 0.3333;
406  btVector3 to = from + normal;
407  drawLine(from, to, color);
408 */
409 }
410 
411 ////////////////////////////////////////////////////////////////////
412 // Function: BulletDebugNode::DebugDraw::drawTriangle
413 // Access: Public
414 // Description:
415 ////////////////////////////////////////////////////////////////////
416 void BulletDebugNode::DebugDraw::
417 drawTriangle(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &n0, const btVector3 &n1, const btVector3 &n2, const btVector3 &color, btScalar alpha) {
418 
419  bullet_cat.debug() << "drawTriangle(2) - not yet implemented!" << endl;
420 }
421 
422 ////////////////////////////////////////////////////////////////////
423 // Function: BulletDebugNode::DebugDraw::drawContactPoint
424 // Access: Public
425 // Description:
426 ////////////////////////////////////////////////////////////////////
427 void BulletDebugNode::DebugDraw::
428 drawContactPoint(const btVector3 &point, const btVector3 &normal, btScalar distance, int lifetime, const btVector3 &color) {
429 
430  const btVector3 to = point + normal * distance;
431  const btVector3 &from = point;
432 
433  drawLine(from, to, color);
434 }
435 
436 ////////////////////////////////////////////////////////////////////
437 // Function: BulletDebugNode::DebugDraw::draw3dText
438 // Access: Public
439 // Description:
440 ////////////////////////////////////////////////////////////////////
441 void BulletDebugNode::DebugDraw::
442 draw3dText(const btVector3 &location, const char *text) {
443 
444  bullet_cat.debug() << "draw3dText - not yet implemented!" << endl;
445 }
446 
447 ////////////////////////////////////////////////////////////////////
448 // Function: BulletDebugNode::DebugDraw::drawSphere
449 // Access: Public
450 // Description:
451 ////////////////////////////////////////////////////////////////////
452 void BulletDebugNode::DebugDraw::
453 drawSphere(btScalar radius, const btTransform &transform, const btVector3 &color) {
454 
455  btVector3 center = transform.getOrigin();
456 
457  const btVector3 xoffs = transform.getBasis() * btVector3(1, 0, 0);
458  const btVector3 yoffs = transform.getBasis() * btVector3(0, 1, 0);
459  const btVector3 zoffs = transform.getBasis() * btVector3(0, 0, 1);
460 
461  drawArc(center, xoffs, yoffs, radius, radius, 0, SIMD_2_PI, color, false, 10.0);
462  drawArc(center, yoffs, zoffs, radius, radius, 0, SIMD_2_PI, color, false, 10.0);
463  drawArc(center, zoffs, xoffs, radius, radius, 0, SIMD_2_PI, color, false, 10.0);
464 }
465 
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
virtual void draw_mask_changed()
Called after the node&#39;s DrawMask has been changed for any reason, this just provides a hook so derive...
This is an &quot;unaligned&quot; LVecBase4.
Definition: lvecBase4.h:299
virtual bool safe_to_flatten_below() const
Returns true if a flatten operation may safely continue past this node, or false if nodes below this ...
static NodePath any_path(PandaNode *node, Thread *current_thread=Thread::get_current_thread())
Returns a new NodePath that represents any arbitrary path from the root to the indicated node...
Definition: nodePath.I:77
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:39
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
Definition: geom.h:58
virtual bool safe_to_combine_children() const
Returns true if it is generally safe to combine the children of this PandaNode with each other...
Defines a series of disconnected line segments.
Definition: geomLines.h:25
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
virtual bool safe_to_transform() const
Returns true if it is generally safe to transform this particular kind of Node by calling the xform()...
bool invert_in_place()
Inverts the current matrix.
Definition: lmatrix.h:2288
Defines a series of disconnected triangles.
Definition: geomTriangles.h:25
This is a special kind of GeometricBoundingVolume that fills all of space.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
const LMatrix4 & get_mat() const
Returns the transform matrix that has been applied to the referenced node, or the identity matrix if ...
Definition: nodePath.I:965
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:165
virtual bool safe_to_modify_transform() const
Returns true if it is safe to automatically adjust the transform on this kind of node.
A node that holds Geom objects, renderable pieces of geometry.
Definition: geomNode.h:37
LVecBase3f xform_point(const LVecBase3f &v) const
The matrix transforms a 3-component point (including translation component) and returns the result...
Definition: lmatrix.h:1667
virtual bool safe_to_combine() const
Returns true if it is generally safe to combine this particular kind of PandaNode with other kinds of...