open_toontown_panda3d/panda/src/bullet/bulletDebugNode.cxx

466 lines
15 KiB
C++

// Filename: bulletDebugNode.cxx
// Created by: enn0x (23Jan10)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "bulletDebugNode.h"
#include "geomLines.h"
#include "geomVertexData.h"
#include "geomTriangles.h"
#include "geomVertexFormat.h"
#include "geomVertexWriter.h"
#include "omniBoundingVolume.h"
TypeHandle BulletDebugNode::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
BulletDebugNode::
BulletDebugNode(const char *name) : GeomNode(name) {
_wireframe = true;
_constraints = true;
_bounds = false;
_drawer._normals = true;
CPT (BoundingVolume) bounds = new OmniBoundingVolume();
set_bounds(bounds);
set_final(true);
set_overall_hidden(true);
// Lines
{
PT(GeomVertexData) vdata;
PT(Geom) geom;
PT(GeomLines) prim;
vdata = new GeomVertexData("", GeomVertexFormat::get_v3c4(), Geom::UH_stream);
prim = new GeomLines(Geom::UH_stream);
prim->set_shade_model(Geom::SM_uniform);
geom = new Geom(vdata);
geom->add_primitive(prim);
add_geom(geom);
}
// Triangles
{
PT(GeomVertexData) vdata;
PT(Geom) geom;
PT(GeomTriangles) prim;
vdata = new GeomVertexData("", GeomVertexFormat::get_v3c4(), Geom::UH_stream);
prim = new GeomTriangles(Geom::UH_stream);
prim->set_shade_model(Geom::SM_uniform);
geom = new Geom(vdata);
geom->add_primitive(prim);
add_geom(geom);
}
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::safe_to_flatten
// Access: Public, Virtual
// Description: Returns true if it is generally safe to flatten out
// this particular kind of Node by duplicating
// instances, false otherwise (for instance, a Camera
// cannot be safely flattened, because the Camera
// pointer itself is meaningful).
////////////////////////////////////////////////////////////////////
bool BulletDebugNode::
safe_to_flatten() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::safe_to_transform
// Access: Public, Virtual
// Description: Returns true if it is generally safe to transform
// this particular kind of Node by calling the xform()
// method, false otherwise. For instance, it's usually
// a bad idea to attempt to xform a Character.
////////////////////////////////////////////////////////////////////
bool BulletDebugNode::
safe_to_transform() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::safe_to_modify_transform
// Access: Public, Virtual
// Description: Returns true if it is safe to automatically adjust
// the transform on this kind of node. Usually, this is
// only a bad idea if the user expects to find a
// particular transform on the node.
//
// ModelNodes with the preserve_transform flag set are
// presently the only kinds of nodes that should not
// have their transform even adjusted.
////////////////////////////////////////////////////////////////////
bool BulletDebugNode::
safe_to_modify_transform() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::safe_to_combine
// Access: Public, Virtual
// Description: Returns true if it is generally safe to combine this
// particular kind of PandaNode with other kinds of
// PandaNodes of compatible type, adding children or
// whatever. For instance, an LODNode should not be
// combined with any other PandaNode, because its set of
// children is meaningful.
////////////////////////////////////////////////////////////////////
bool BulletDebugNode::
safe_to_combine() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::safe_to_combine_children
// Access: Public, Virtual
// Description: Returns true if it is generally safe to combine the
// children of this PandaNode with each other. For
// instance, an LODNode's children should not be
// combined with each other, because the set of children
// is meaningful.
////////////////////////////////////////////////////////////////////
bool BulletDebugNode::
safe_to_combine_children() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::safe_to_flatten_below
// Access: Public, Virtual
// Description: Returns true if a flatten operation may safely
// continue past this node, or false if nodes below this
// node may not be molested.
////////////////////////////////////////////////////////////////////
bool BulletDebugNode::
safe_to_flatten_below() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::draw_mask_changed
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void BulletDebugNode::
draw_mask_changed() {
if (is_overall_hidden()) {
_drawer.setDebugMode(DebugDraw::DBG_NoDebug);
}
else {
int mode = DebugDraw::DBG_DrawText |
DebugDraw::DBG_DrawFeaturesText |
DebugDraw::DBG_DrawContactPoints;
if (_wireframe) {
mode |= DebugDraw::DBG_DrawWireframe;
}
if (_constraints) {
mode |= DebugDraw::DBG_DrawConstraints;
mode |= DebugDraw::DBG_DrawConstraintLimits;
}
if (_bounds) {
mode |= DebugDraw::DBG_DrawAabb;
}
_drawer.setDebugMode(mode);
}
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::sync_b2p
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void BulletDebugNode::
sync_b2p(btDynamicsWorld *world) {
if (is_overall_hidden()) return;
nassertv(get_num_geoms() == 2);
// Collect debug geometry data
_drawer._lines.clear();
_drawer._triangles.clear();
world->debugDrawWorld();
// Get inverse of this node's net transform
NodePath np = NodePath::any_path((PandaNode *)this);
LMatrix4 m = np.get_net_transform()->get_mat();
m.invert_in_place();
// Render lines
{
PT(GeomVertexData) vdata;
PT(Geom) geom;
PT(GeomLines) prim;
vdata = new GeomVertexData("", GeomVertexFormat::get_v3c4(), Geom::UH_stream);
prim = new GeomLines(Geom::UH_stream);
prim->set_shade_model(Geom::SM_uniform);
GeomVertexWriter vwriter = GeomVertexWriter(vdata, InternalName::get_vertex());
GeomVertexWriter cwriter = GeomVertexWriter(vdata, InternalName::get_color());
int v = 0;
pvector<Line>::const_iterator lit;
for (lit = _drawer._lines.begin(); lit != _drawer._lines.end(); lit++) {
Line line = *lit;
vwriter.add_data3(m.xform_point(line._p0));
vwriter.add_data3(m.xform_point(line._p1));
cwriter.add_data4(LVecBase4(line._color));
cwriter.add_data4(LVecBase4(line._color));
prim->add_vertex(v++);
prim->add_vertex(v++);
prim->close_primitive();
}
geom = new Geom(vdata);
geom->add_primitive(prim);
set_geom(0, geom);
}
// Render triangles
{
PT(GeomVertexData) vdata;
PT(Geom) geom;
PT(GeomTriangles) prim;
vdata = new GeomVertexData("", GeomVertexFormat::get_v3c4(), Geom::UH_stream);
prim = new GeomTriangles(Geom::UH_stream);
prim->set_shade_model(Geom::SM_uniform);
GeomVertexWriter vwriter = GeomVertexWriter(vdata, InternalName::get_vertex());
GeomVertexWriter cwriter = GeomVertexWriter(vdata, InternalName::get_color());
int v = 0;
pvector<Triangle>::const_iterator tit;
for (tit = _drawer._triangles.begin(); tit != _drawer._triangles.end(); tit++) {
Triangle tri = *tit;
vwriter.add_data3(m.xform_point(tri._p0));
vwriter.add_data3(m.xform_point(tri._p1));
vwriter.add_data3(m.xform_point(tri._p2));
cwriter.add_data4(LVecBase4(tri._color));
cwriter.add_data4(LVecBase4(tri._color));
cwriter.add_data4(LVecBase4(tri._color));
prim->add_vertex(v++);
prim->add_vertex(v++);
prim->add_vertex(v++);
prim->close_primitive();
}
geom = new Geom(vdata);
geom->add_primitive(prim);
set_geom(1, geom);
}
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::DebugDraw::setDebugMode
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletDebugNode::DebugDraw::
setDebugMode(int mode) {
_mode = mode;
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::DebugDraw::getDebugMode
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
int BulletDebugNode::DebugDraw::
getDebugMode() const {
return _mode;
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::DebugDraw::reportErrorWarning
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletDebugNode::DebugDraw::
reportErrorWarning(const char *warning) {
bullet_cat.error() << warning << endl;
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::DebugDraw::drawLine
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletDebugNode::DebugDraw::
drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color) {
PN_stdfloat r = color.getX();
PN_stdfloat g = color.getY();
PN_stdfloat b = color.getZ();
// Hack to get rid of triangle normals. The hack is based on the
// assumption that only normals are drawn in yellow.
if (_normals==false && r==1.0f && g==1.0f && b==0.0f) return;
Line line;
line._p0 = LVecBase3((PN_stdfloat)from.getX(),
(PN_stdfloat)from.getY(),
(PN_stdfloat)from.getZ());
line._p1 = LVecBase3((PN_stdfloat)to.getX(),
(PN_stdfloat)to.getY(),
(PN_stdfloat)to.getZ());
line._color = UnalignedLVecBase4((PN_stdfloat)r,
(PN_stdfloat)g,
(PN_stdfloat)b, 1.0f);
_lines.push_back(line);
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::DebugDraw::drawTriangle
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletDebugNode::DebugDraw::
drawTriangle(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &color, btScalar) {
btScalar r = color.getX();
btScalar g = color.getY();
btScalar b = color.getZ();
Triangle tri;
tri._p0 = LVecBase3((PN_stdfloat)v0.getX(),
(PN_stdfloat)v0.getY(),
(PN_stdfloat)v0.getZ());
tri._p1 = LVecBase3((PN_stdfloat)v1.getX(),
(PN_stdfloat)v1.getY(),
(PN_stdfloat)v1.getZ());
tri._p2 = LVecBase3((PN_stdfloat)v2.getX(),
(PN_stdfloat)v2.getY(),
(PN_stdfloat)v2.getZ());
tri._color = UnalignedLVecBase4((PN_stdfloat)r,
(PN_stdfloat)g,
(PN_stdfloat)b, 1.0f);
_triangles.push_back(tri);
// Draw the triangle's normal
/*
btVector3 x1 = v1 - v0;
btVector3 x2 = v2 - v0;
btVector3 normal = v1.cross(v2).normalize();
btVector3 from = (v0 + v1 + v2) * 0.3333;
btVector3 to = from + normal;
drawLine(from, to, color);
*/
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::DebugDraw::drawTriangle
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletDebugNode::DebugDraw::
drawTriangle(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &n0, const btVector3 &n1, const btVector3 &n2, const btVector3 &color, btScalar alpha) {
bullet_cat.debug() << "drawTriangle(2) - not yet implemented!" << endl;
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::DebugDraw::drawContactPoint
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletDebugNode::DebugDraw::
drawContactPoint(const btVector3 &point, const btVector3 &normal, btScalar distance, int lifetime, const btVector3 &color) {
const btVector3 to = point + normal * distance;
const btVector3 &from = point;
drawLine(from, to, color);
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::DebugDraw::draw3dText
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletDebugNode::DebugDraw::
draw3dText(const btVector3 &location, const char *text) {
bullet_cat.debug() << "draw3dText - not yet implemented!" << endl;
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::DebugDraw::drawSphere
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletDebugNode::DebugDraw::
drawSphere(btScalar radius, const btTransform &transform, const btVector3 &color) {
btVector3 center = transform.getOrigin();
const btVector3 xoffs = transform.getBasis() * btVector3(1, 0, 0);
const btVector3 yoffs = transform.getBasis() * btVector3(0, 1, 0);
const btVector3 zoffs = transform.getBasis() * btVector3(0, 0, 1);
drawArc(center, xoffs, yoffs, radius, radius, 0, SIMD_2_PI, color, false, 10.0);
drawArc(center, yoffs, zoffs, radius, radius, 0, SIMD_2_PI, color, false, 10.0);
drawArc(center, zoffs, xoffs, radius, radius, 0, SIMD_2_PI, color, false, 10.0);
}