pgraph viz collision solids

This commit is contained in:
David Rose 2002-03-21 04:34:47 +00:00
parent c7fc395bcb
commit c1fe4c1938
14 changed files with 402 additions and 26 deletions

View File

@ -27,16 +27,17 @@
#include "config_collide.h"
#include "pointerToArray.h"
#include "geomNode.h"
#include "qpgeomNode.h"
#include "geom.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "omniBoundingVolume.h"
#include "geomQuad.h"
#include "geomNode.h"
TypeHandle CollisionPlane::_type_handle;
////////////////////////////////////////////////////////////////////
@ -357,6 +358,76 @@ recompute_viz(Node *parent) {
add_wireframe_viz(parent, viz);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPlane::fill_viz_geom
// Access: Protected, Virtual
// Description: Fills the _viz_geom GeomNode up with Geoms suitable
// for rendering this solid.
////////////////////////////////////////////////////////////////////
void CollisionPlane::
fill_viz_geom() {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Recomputing viz for " << *this << "\n";
}
// Since we can't represent an infinite plane, we'll have to be
// satisfied with drawing a big polygon. Choose four points on the
// plane to be the corners of the polygon.
// We must choose four points fairly reasonably spread apart on
// the plane. We'll start with a center point and one corner
// point, and then use cross products to find the remaining three
// corners of a square.
// The center point will be on the axis with the largest
// coefficent. The first corner will be diagonal in the other two
// dimensions.
LPoint3f cp;
LVector3f p1, p2, p3, p4;
LVector3f normal = get_normal();
float D = _plane._d;
if (fabs(normal[0]) > fabs(normal[1]) &&
fabs(normal[0]) > fabs(normal[2])) {
// X has the largest coefficient.
cp.set(-D / normal[0], 0.0f, 0.0f);
p1 = LPoint3f(-(normal[1] + normal[2] + D)/normal[0], 1.0f, 1.0f) - cp;
} else if (fabs(normal[1]) > fabs(normal[2])) {
// Y has the largest coefficient.
cp.set(0.0f, -D / normal[1], 0.0f);
p1 = LPoint3f(1.0f, -(normal[0] + normal[2] + D)/normal[1], 1.0f) - cp;
} else {
// Z has the largest coefficient.
cp.set(0.0f, 0.0f, -D / normal[2]);
p1 = LPoint3f(1.0f, 1.0f, -(normal[0] + normal[1] + D)/normal[2]) - cp;
}
p1.normalize();
p2 = cross(normal, p1);
p3 = cross(normal, p2);
p4 = cross(normal, p3);
static const double plane_scale = 10.0;
PTA_Vertexf verts;
verts.push_back(cp + p1 * plane_scale);
verts.push_back(cp + p2 * plane_scale);
verts.push_back(cp + p3 * plane_scale);
verts.push_back(cp + p4 * plane_scale);
GeomQuad *quad = new GeomQuad;
quad->set_coords(verts);
quad->set_num_prims(1);
_viz_geom->add_geom(quad, get_solid_viz_state());
_viz_geom->add_geom(quad, get_wireframe_viz_state());
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPlane::write_datagram
// Access: Public

View File

@ -81,6 +81,7 @@ protected:
const qpCollisionEntry &entry) const;
virtual void recompute_viz(Node *parent);
virtual void fill_viz_geom();
private:
Planef _plane;

View File

@ -29,7 +29,7 @@
#include "boundingSphere.h"
#include "pointerToArray.h"
#include "geomNode.h"
#include "qpgeomNode.h"
#include "geom.h"
#include "datagram.h"
#include "datagramIterator.h"
@ -37,6 +37,8 @@
#include "bamWriter.h"
#include "geomPolygon.h"
#include "geomNode.h"
#include <algorithm>
TypeHandle CollisionPolygon::_type_handle;
@ -697,6 +699,48 @@ recompute_viz(Node *parent) {
add_wireframe_viz(parent, viz);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPolygon::fill_viz_geom
// Access: Protected, Virtual
// Description: Fills the _viz_geom GeomNode up with Geoms suitable
// for rendering this solid.
////////////////////////////////////////////////////////////////////
void CollisionPolygon::
fill_viz_geom() {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Recomputing viz for " << *this << "\n";
}
if (_points.size() < 3) {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "(Degenerate poly, ignoring.)\n";
}
return;
}
PTA_Vertexf verts;
Points::const_iterator pi;
for (pi = _points.begin(); pi != _points.end(); ++pi) {
verts.push_back(to_3d(*pi));
}
if (_reversed) {
reverse(verts.begin(), verts.end());
}
PTA_int lengths;
lengths.push_back(_points.size());
GeomPolygon *polygon = new GeomPolygon;
polygon->set_coords(verts);
polygon->set_num_prims(1);
polygon->set_lengths(lengths);
_viz_geom->add_geom(polygon, get_solid_viz_state());
_viz_geom->add_geom(polygon, get_wireframe_viz_state());
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPolygon::is_inside
// Access: Private

View File

@ -90,6 +90,7 @@ protected:
const qpCollisionEntry &entry) const;
virtual void recompute_viz(Node *parent);
virtual void fill_viz_geom();
private:
bool is_inside(const LPoint2f &p) const;

View File

@ -23,13 +23,15 @@
#include "qpcollisionEntry.h"
#include "config_collide.h"
#include "geom.h"
#include "geomNode.h"
#include "qpgeomNode.h"
#include "geomLinestrip.h"
#include "boundingLine.h"
#include "lensNode.h"
#include "qplensNode.h"
#include "lens.h"
#include "lensNode.h"
#include "geomNode.h"
TypeHandle CollisionRay::_type_handle;
@ -219,3 +221,41 @@ recompute_viz(Node *parent) {
viz->add_geom(ray);
add_other_viz(parent, viz);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::fill_viz_geom
// Access: Protected, Virtual
// Description: Fills the _viz_geom GeomNode up with Geoms suitable
// for rendering this solid.
////////////////////////////////////////////////////////////////////
void CollisionRay::
fill_viz_geom() {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Recomputing viz for " << *this << "\n";
}
GeomLinestrip *ray = new GeomLinestrip;
PTA_Vertexf verts;
PTA_Colorf colors;
PTA_int lengths;
#define NUM_POINTS 100
verts.reserve(NUM_POINTS);
colors.reserve(NUM_POINTS);
for (int i = 0; i < NUM_POINTS; i++) {
verts.push_back(_origin + (double)i * _direction);
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f)+
((double)i / 100.0) * Colorf(0.0f, 0.0f, 0.0f, -1.0f));
}
ray->set_coords(verts);
ray->set_colors(colors, G_PER_VERTEX);
lengths.push_back(NUM_POINTS-1);
ray->set_lengths(lengths);
ray->set_num_prims(1);
_viz_geom->add_geom(ray, get_other_viz_state());
}

View File

@ -80,6 +80,7 @@ protected:
protected:
virtual void recompute_viz(Node *parent);
virtual void fill_viz_geom();
private:
LPoint3f _origin;

View File

@ -25,14 +25,15 @@
#include "config_collide.h"
#include "geom.h"
#include "geomNode.h"
#include "lensNode.h"
#include "qplensNode.h"
#include "qpgeomNode.h"
#include "lens.h"
#include "geomLine.h"
#include "geometricBoundingVolume.h"
#include "geomNode.h"
#include "lensNode.h"
TypeHandle CollisionSegment::_type_handle;
@ -213,3 +214,30 @@ recompute_viz(Node *parent) {
viz->add_geom(segment);
add_other_viz(parent, viz);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::fill_viz_geom
// Access: Protected, Virtual
// Description: Fills the _viz_geom GeomNode up with Geoms suitable
// for rendering this solid.
////////////////////////////////////////////////////////////////////
void CollisionSegment::
fill_viz_geom() {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Recomputing viz for " << *this << "\n";
}
GeomLine *segment = new GeomLine;
PTA_Vertexf verts;
PTA_Colorf colors;
verts.push_back(_a);
verts.push_back(_b);
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
segment->set_coords(verts);
segment->set_colors(colors, G_OVERALL);
segment->set_num_prims(1);
_viz_geom->add_geom(segment, get_other_viz_state());
}

View File

@ -83,6 +83,7 @@ protected:
protected:
virtual void recompute_viz(Node *parent);
virtual void fill_viz_geom();
private:
LPoint3f _a, _b;

View File

@ -60,4 +60,5 @@ is_tangible() const {
INLINE void CollisionSolid::
mark_viz_stale() {
_viz_stale = true;
_viz_geom_stale = true;
}

View File

@ -24,20 +24,25 @@
#include "collisionRay.h"
#include "collisionSegment.h"
#include <renderRelation.h>
#include <geomNode.h>
#include <datagram.h>
#include <datagramIterator.h>
#include <bamReader.h>
#include <bamWriter.h>
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "indent.h"
#include "cullFaceAttrib.h"
#include "colorAttrib.h"
#include "renderModeAttrib.h"
#include "transparencyAttrib.h"
#include "qpgeomNode.h"
#include <indent.h>
#include <cullFaceTransition.h>
#include <colorTransition.h>
#include <renderModeTransition.h>
#include <lightTransition.h>
#include <transparencyTransition.h>
#include <textureTransition.h>
#include "renderRelation.h"
#include "geomNode.h"
#include "cullFaceTransition.h"
#include "colorTransition.h"
#include "renderModeTransition.h"
#include "lightTransition.h"
#include "transparencyTransition.h"
#include "textureTransition.h"
TypeHandle CollisionSolid::_type_handle;
@ -49,6 +54,7 @@ TypeHandle CollisionSolid::_type_handle;
CollisionSolid::
CollisionSolid() {
_viz_stale = true;
_viz_geom_stale = true;
_tangible = true;
}
@ -63,6 +69,7 @@ CollisionSolid(const CollisionSolid &copy) :
{
// Actually, there's not a whole lot here we want to copy.
_viz_stale = true;
_viz_geom_stale = true;
}
////////////////////////////////////////////////////////////////////
@ -89,6 +96,26 @@ update_viz(Node *parent) {
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::get_viz
// Access: Public
// Description: Returns a GeomNode that may be rendered to visualize
// the CollisionSolid.
////////////////////////////////////////////////////////////////////
qpGeomNode *CollisionSolid::
get_viz() {
if (_viz_geom_stale) {
if (_viz_geom == (qpGeomNode *)NULL) {
_viz_geom = new qpGeomNode("viz");
} else {
_viz_geom->remove_all_geoms();
}
fill_viz_geom();
_viz_geom_stale = false;
}
return _viz_geom;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::output
// Access: Public, Virtual
@ -330,3 +357,116 @@ add_other_viz(Node *parent, GeomNode *viz) {
_other_viz_arcs.push_back(arc);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::fill_viz_geom
// Access: Protected, Virtual
// Description: Fills the _viz_geom GeomNode up with Geoms suitable
// for rendering this solid.
////////////////////////////////////////////////////////////////////
void CollisionSolid::
fill_viz_geom() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::get_solid_viz_state
// Access: Protected
// Description: Returns a RenderState for rendering collision
// visualizations in solid. This automatically returns
// the appropriate state according to the setting of
// _tangible.
////////////////////////////////////////////////////////////////////
CPT(RenderState) CollisionSolid::
get_solid_viz_state() {
// Once someone asks for this pointer, we hold its reference count
// and never free it.
static CPT(RenderState) base_state = (const RenderState *)NULL;
if (base_state == (const RenderState *)NULL) {
base_state = RenderState::make
(CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
RenderModeAttrib::make(RenderModeAttrib::M_filled),
TransparencyAttrib::make(TransparencyAttrib::M_alpha));
}
if (_tangible) {
static CPT(RenderState) tangible_state = (const RenderState *)NULL;
if (tangible_state == (const RenderState *)NULL) {
tangible_state = base_state->add_attrib
(ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 1.0f, 0.5f)));
}
return tangible_state;
} else {
static CPT(RenderState) intangible_state = (const RenderState *)NULL;
if (intangible_state == (const RenderState *)NULL) {
intangible_state = base_state->add_attrib
(ColorAttrib::make_flat(Colorf(1.0f, 0.3f, 0.5f, 0.5f)));
}
return intangible_state;
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::get_wireframe_viz_state
// Access: Protected
// Description: Returns a RenderState for rendering collision
// visualizations in wireframe. This automatically returns
// the appropriate state according to the setting of
// _tangible.
////////////////////////////////////////////////////////////////////
CPT(RenderState) CollisionSolid::
get_wireframe_viz_state() {
// Once someone asks for this pointer, we hold its reference count
// and never free it.
static CPT(RenderState) base_state = (const RenderState *)NULL;
if (base_state == (const RenderState *)NULL) {
base_state = RenderState::make
(CullFaceAttrib::make(CullFaceAttrib::M_cull_none),
RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
TransparencyAttrib::make(TransparencyAttrib::M_none));
}
if (_tangible) {
static CPT(RenderState) tangible_state = (const RenderState *)NULL;
if (tangible_state == (const RenderState *)NULL) {
tangible_state = base_state->add_attrib
(ColorAttrib::make_flat(Colorf(0.0f, 0.0f, 1.0f, 1.0f)));
}
return tangible_state;
} else {
static CPT(RenderState) intangible_state = (const RenderState *)NULL;
if (intangible_state == (const RenderState *)NULL) {
intangible_state = base_state->add_attrib
(ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 0.0f, 1.0f)));
}
return intangible_state;
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::get_other_viz_state
// Access: Protected
// Description: Returns a RenderState for rendering collision
// visualizations for things that are neither solid nor
// exactly wireframe, like rays and segments.
////////////////////////////////////////////////////////////////////
CPT(RenderState) CollisionSolid::
get_other_viz_state() {
// Once someone asks for this pointer, we hold its reference count
// and never free it.
static CPT(RenderState) base_state = (const RenderState *)NULL;
if (base_state == (const RenderState *)NULL) {
base_state = RenderState::make
(CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
RenderModeAttrib::make(RenderModeAttrib::M_filled),
TransparencyAttrib::make(TransparencyAttrib::M_alpha));
}
// We don't bother to make a distinction here between tangible and
// intangible.
return base_state;
}

View File

@ -24,8 +24,10 @@
#include "typedWritableReferenceCount.h"
#include "boundedObject.h"
#include "luse.h"
#include "nodeRelation.h"
#include "pointerTo.h"
#include "renderState.h"
#include "nodeRelation.h"
#include "node.h"
#include "vector_PT_NodeRelation.h"
@ -36,6 +38,7 @@ class qpCollisionEntry;
class CollisionSphere;
class Node;
class GeomNode;
class qpGeomNode;
class CollisionNode;
class qpCollisionNode;
@ -79,6 +82,7 @@ public:
virtual void xform(const LMatrix4f &mat)=0;
void update_viz(Node *parent);
qpGeomNode *get_viz();
PUBLISHED:
virtual void output(ostream &out) const;
@ -115,12 +119,20 @@ protected:
void add_other_viz(Node *parent, GeomNode *viz);
virtual void recompute_viz(Node *parent)=0;
virtual void fill_viz_geom();
CPT(RenderState) get_solid_viz_state();
CPT(RenderState) get_wireframe_viz_state();
CPT(RenderState) get_other_viz_state();
typedef vector_PT_NodeRelation VizArcs;
VizArcs _solid_viz_arcs;
VizArcs _wireframe_viz_arcs;
VizArcs _other_viz_arcs;
PT(qpGeomNode) _viz_geom;
bool _viz_stale;
bool _viz_geom_stale;
bool _tangible;
public:

View File

@ -433,6 +433,29 @@ recompute_viz(Node *parent) {
// add_wireframe_viz(parent, viz);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSphere::fill_viz_geom
// Access: Protected, Virtual
// Description: Fills the _viz_geom GeomNode up with Geoms suitable
// for rendering this solid.
////////////////////////////////////////////////////////////////////
void CollisionSphere::
fill_viz_geom() {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Recomputing viz for " << *this << "\n";
}
GeomSphere *sphere = new GeomSphere;
PTA_Vertexf verts;
verts.push_back(_center);
verts.push_back(_center + LVector3f(_radius, 0.0f, 0.0f));
sphere->set_coords(verts);
sphere->set_num_prims(1);
_viz_geom->add_geom(sphere, get_solid_viz_state());
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSphere::intersects_line
// Access: Protected

View File

@ -84,6 +84,7 @@ protected:
const qpCollisionEntry &entry) const;
virtual void recompute_viz(Node *parent);
virtual void fill_viz_geom();
bool intersects_line(double &t1, double &t2,
const LPoint3f &from, const LVector3f &delta) const;

View File

@ -19,6 +19,9 @@
#include "collisionNode.h"
#include "config_collide.h"
#include "qpgeomNode.h"
#include "cullTraverserData.h"
#include "qpcullTraverser.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
@ -194,13 +197,22 @@ has_cull_callback() const {
// visible, or false if it should be culled.
////////////////////////////////////////////////////////////////////
bool qpCollisionNode::
cull_callback(qpCullTraverser *, CullTraverserData &) {
/*
cull_callback(qpCullTraverser *trav, CullTraverserData &data) {
// Append our collision vizzes to the drawing, even though they're
// not actually part of the scene graph.
Solids::iterator si;
for (si = _solids.begin(); si != _solids.end(); ++si) {
(*si)->update_viz(this);
CollisionSolid *solid = (*si);
PandaNode *node = solid->get_viz();
CullTraverserData next_data(data, node);
// We don't want to inherit the render state from above for these
// guys.
next_data._state = RenderState::make_empty();
trav->traverse(next_data);
}
*/
// Now carry on to render our child nodes.
return true;
}