visualize PlaneNodes

This commit is contained in:
David Rose 2006-03-14 01:32:58 +00:00
parent 71cbcb72d7
commit efc319c451
5 changed files with 237 additions and 18 deletions

View File

@ -171,6 +171,17 @@ dist_to_plane(const FLOATNAME(LPoint3) &point) const {
return (_v.v._0 * point[0] + _v.v._1 * point[1] + _v.v._2 * point[2] + _v.v._3); return (_v.v._0 * point[0] + _v.v._1 * point[1] + _v.v._2 * point[2] + _v.v._3);
} }
////////////////////////////////////////////////////////////////////
// Function: Plane::project
// Access: Published
// Description: Returns the point within the plane nearest to the
// indicated point in space.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL FLOATNAME(LPoint3) FLOATNAME(Plane)::
project(const FLOATNAME(LPoint3) &point) const {
return point - get_normal() * dist_to_plane(point);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Plane::intersects_line // Function: Plane::intersects_line
// Access: Published // Access: Published

View File

@ -45,6 +45,9 @@ PUBLISHED:
FLOATNAME(LPoint3) get_point() const; FLOATNAME(LPoint3) get_point() const;
INLINE_MATHUTIL FLOATTYPE dist_to_plane(const FLOATNAME(LPoint3) &point) const; INLINE_MATHUTIL FLOATTYPE dist_to_plane(const FLOATNAME(LPoint3) &point) const;
INLINE_MATHUTIL FLOATNAME(LPoint3) project(const FLOATNAME(LPoint3) &point) const;
INLINE_MATHUTIL bool intersects_line(FLOATNAME(LPoint3) &intersection_point, INLINE_MATHUTIL bool intersects_line(FLOATNAME(LPoint3) &intersection_point,
const FLOATNAME(LPoint3) &p1, const FLOATNAME(LPoint3) &p1,
const FLOATNAME(LPoint3) &p2) const; const FLOATNAME(LPoint3) &p2) const;

View File

@ -23,7 +23,9 @@
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE PlaneNode::CData:: INLINE PlaneNode::CData::
CData() { CData() :
_viz_scale(100.0f)
{
// The default plane (perpendicular to the Z-axis) is used until // The default plane (perpendicular to the Z-axis) is used until
// another one is specified explicitly. // another one is specified explicitly.
} }
@ -35,12 +37,15 @@ CData() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE PlaneNode::CData:: INLINE PlaneNode::CData::
CData(const PlaneNode::CData &copy) : CData(const PlaneNode::CData &copy) :
_plane(copy._plane) _plane(copy._plane),
_front_viz(copy._front_viz),
_back_viz(copy._back_viz),
_viz_scale(copy._viz_scale)
{ {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: set_plane // Function: PlaneNode::set_plane
// Access: Public // Access: Public
// Description: Sets the particular plane represented by the // Description: Sets the particular plane represented by the
// PlaneNode. // PlaneNode.
@ -48,11 +53,15 @@ CData(const PlaneNode::CData &copy) :
INLINE void PlaneNode:: INLINE void PlaneNode::
set_plane(const Planef &plane) { set_plane(const Planef &plane) {
CDWriter cdata(_cycler); CDWriter cdata(_cycler);
cdata->_plane = plane; if (cdata->_plane != plane) {
cdata->_plane = plane;
cdata->_front_viz = NULL;
cdata->_back_viz = NULL;
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: get_plane // Function: PlaneNode::get_plane
// Access: Public // Access: Public
// Description: Returns the plane represented by the PlaneNode. // Description: Returns the plane represented by the PlaneNode.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -61,6 +70,34 @@ get_plane() const {
CDReader cdata(_cycler); CDReader cdata(_cycler);
return cdata->_plane; return cdata->_plane;
} }
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::set_viz_scale
// Access: Public
// Description: Specifies the size of the visual representation of
// the plane that is drawn if the PlaneNode is shown.
////////////////////////////////////////////////////////////////////
INLINE void PlaneNode::
set_viz_scale(float viz_scale) {
CDWriter cdata(_cycler);
if (cdata->_viz_scale != viz_scale) {
cdata->_viz_scale = viz_scale;
cdata->_front_viz = NULL;
cdata->_back_viz = NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::get_viz_scale
// Access: Public
// Description: Returns the size of the visual representation of
// the plane that is drawn if the PlaneNode is shown.
////////////////////////////////////////////////////////////////////
INLINE float PlaneNode::
get_viz_scale() const {
CDReader cdata(_cycler);
return cdata->_viz_scale;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PlaneNode::set_priority // Function: PlaneNode::set_priority

View File

@ -22,6 +22,13 @@
#include "bamReader.h" #include "bamReader.h"
#include "datagram.h" #include "datagram.h"
#include "datagramIterator.h" #include "datagramIterator.h"
#include "geomVertexWriter.h"
#include "geomVertexData.h"
#include "geomLines.h"
#include "geom.h"
#include "cullableObject.h"
#include "cullHandler.h"
#include "boundingPlane.h"
UpdateSeq PlaneNode::_sort_seq; UpdateSeq PlaneNode::_sort_seq;
@ -70,6 +77,9 @@ PlaneNode(const string &name, const Planef &plane) :
PandaNode(name), PandaNode(name),
_priority(0) _priority(0)
{ {
// PlaneNodes are hidden by default.
set_draw_mask(DrawMask::all_off());
set_plane(plane); set_plane(plane);
} }
@ -86,6 +96,17 @@ PlaneNode(const PlaneNode &copy) :
{ {
} }
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void PlaneNode::
output(ostream &out) const {
PandaNode::output(out);
out << " " << get_plane();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PlaneNode::make_copy // Function: PlaneNode::make_copy
// Access: Public, Virtual // Access: Public, Virtual
@ -111,28 +132,155 @@ xform(const LMatrix4f &mat) {
PandaNode::xform(mat); PandaNode::xform(mat);
CDWriter cdata(_cycler); CDWriter cdata(_cycler);
cdata->_plane = cdata->_plane * mat; cdata->_plane = cdata->_plane * mat;
cdata->_front_viz = NULL;
cdata->_back_viz = NULL;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PlaneNode::output // Function: PlaneNode::has_cull_callback
// Access: Public, Virtual // Access: Public, Virtual
// Description: // Description: Should be overridden by derived classes to return
// true if cull_callback() has been defined. Otherwise,
// returns false to indicate cull_callback() does not
// need to be called for this node during the cull
// traversal.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void PlaneNode:: bool PlaneNode::
output(ostream &out) const { has_cull_callback() const {
PandaNode::output(out); return true;
out << " " << get_plane();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PlaneNode::write // Function: PlaneNode::cull_callback
// Access: Public, Virtual // Access: Public, Virtual
// Description: // Description: If has_cull_callback() returns true, this function
// will be called during the cull traversal to perform
// any additional operations that should be performed at
// cull time. This may include additional manipulation
// of render state or additional visible/invisible
// decisions, or any other arbitrary operation.
//
// By the time this function is called, the node has
// already passed the bounding-volume test for the
// viewing frustum, and the node's transform and state
// have already been applied to the indicated
// CullTraverserData object.
//
// The return value is true if this node should be
// visible, or false if it should be culled.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void PlaneNode:: bool PlaneNode::
write(ostream &out, int indent_level) const { cull_callback(CullTraverser *trav, CullTraverserData &data) {
PandaNode::write(out, indent_level); // Normally, a PlaneNode is invisible. But if someone shows it, we
get_plane().write(out, indent_level + 2); // will draw a visualization, a nice yellow wireframe.
CullableObject *plane_viz =
new CullableObject(get_viz(trav, data), data._state,
data._modelview_transform);
trav->get_cull_handler()->record_object(plane_viz, trav);
// Now carry on to render our child nodes.
return true;
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::compute_internal_bounds
// Access: Protected, Virtual
// Description: Returns a newly-allocated BoundingVolume that
// represents the internal contents of the node. Should
// be overridden by PandaNode classes that contain
// something internally.
////////////////////////////////////////////////////////////////////
PT(BoundingVolume) PlaneNode::
compute_internal_bounds(int pipeline_stage) const {
CDStageReader cdata(_cycler, pipeline_stage);
return new BoundingPlane(cdata->_plane);
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::get_viz
// Access: Protected
// Description: Returns a Geom that represents the visualization of
// the PlaneNode.
////////////////////////////////////////////////////////////////////
PT(Geom) PlaneNode::
get_viz(CullTraverser *trav, CullTraverserData &data) {
CDReader cdata(_cycler);
// Figure out whether we are looking at the front or the back of the
// plane.
const Lens *lens = trav->get_scene()->get_lens();
Planef eye_plane = cdata->_plane * data._modelview_transform->get_mat();
bool front = (eye_plane.dist_to_plane(lens->get_nodal_point()) >= 0.0f);
if (cdata->_front_viz != (Geom *)NULL) {
return front ? cdata->_front_viz : cdata->_back_viz;
}
if (pgraph_cat.is_debug()) {
pgraph_cat.debug()
<< "Recomputing viz for " << *this << "\n";
}
CDWriter cdataw(_cycler, cdata, false);
const Planef &plane = cdataw->_plane;
PT(GeomVertexData) vdata = new GeomVertexData
(get_name(), GeomVertexFormat::get_v3cp(), Geom::UH_static);
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
PT(GeomLines) lines = new GeomLines(Geom::UH_static);
LVector3f a, b;
if (fabs(plane[0]) > fabs(plane[1])) {
// X > Y
if (fabs(plane[0]) > fabs(plane[2])) {
// X > Y && X > Z. X is the largest.
a.set(0, 1, 0);
b.set(0, 0, 1);
} else {
// X > Y && Z > X. Z is the largest.
a.set(1, 0, 0);
b.set(0, 1, 0);
}
} else {
// Y > X
if (fabs(plane[1]) > fabs(plane[2])) {
// Y > X && Y > Z. Y is the largest.
a.set(1, 0, 0);
b.set(0, 0, 1);
} else {
// Y > X && Z > Y. Z is the largest.
a.set(1, 0, 0);
b.set(0, 1, 0);
}
}
static const int num_segs = 10;
a *= cdataw->_viz_scale / (num_segs * 2);
b *= cdataw->_viz_scale / (num_segs * 2);
for (int x = -num_segs; x <= num_segs; ++x) {
vertex.add_data3f(plane.project(a * x - b * num_segs));
vertex.add_data3f(plane.project(a * x + b * num_segs));
lines->add_next_vertices(2);
lines->close_primitive();
}
for (int y = -num_segs; y <= num_segs; ++y) {
vertex.add_data3f(plane.project(b * y - a * num_segs));
vertex.add_data3f(plane.project(b * y + a * num_segs));
lines->add_next_vertices(2);
lines->close_primitive();
}
cdataw->_front_viz = new Geom(vdata->set_color(Colorf(1.0f, 1.0f, 0.0f, 1.0f)));
cdataw->_front_viz->add_primitive(lines);
cdataw->_back_viz = new Geom(vdata->set_color(Colorf(0.4f, 0.4f, 0.0f, 1.0f)));
cdataw->_back_viz->add_primitive(lines);
return front ? cdataw->_front_viz : cdataw->_back_viz;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -24,6 +24,13 @@
#include "plane.h" #include "plane.h"
#include "pandaNode.h" #include "pandaNode.h"
#include "updateSeq.h" #include "updateSeq.h"
#include "geom.h"
#include "cycleData.h"
#include "cycleDataReader.h"
#include "cycleDataWriter.h"
#include "cycleDataStageReader.h"
#include "cycleDataStageWriter.h"
#include "pipelineCycler.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : PlaneNode // Class : PlaneNode
@ -40,20 +47,29 @@ protected:
PlaneNode(const PlaneNode &copy); PlaneNode(const PlaneNode &copy);
public: public:
virtual void output(ostream &out) const; virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level = 0) const;
virtual PandaNode *make_copy() const; virtual PandaNode *make_copy() const;
virtual void xform(const LMatrix4f &mat); virtual void xform(const LMatrix4f &mat);
virtual bool has_cull_callback() const;
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
PUBLISHED: PUBLISHED:
INLINE void set_plane(const Planef &plane); INLINE void set_plane(const Planef &plane);
INLINE const Planef &get_plane() const; INLINE const Planef &get_plane() const;
INLINE void set_viz_scale(float viz_scale);
INLINE float get_viz_scale() const;
INLINE void set_priority(int priority); INLINE void set_priority(int priority);
INLINE int get_priority() const; INLINE int get_priority() const;
public: public:
INLINE static UpdateSeq get_sort_seq(); INLINE static UpdateSeq get_sort_seq();
protected:
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const;
PT(Geom) get_viz(CullTraverser *trav, CullTraverserData &data);
private: private:
// The priority is not cycled, because there's no real reason to do // The priority is not cycled, because there's no real reason to do
@ -75,11 +91,15 @@ private:
} }
Planef _plane; Planef _plane;
PT(Geom) _front_viz, _back_viz;
float _viz_scale;
}; };
PipelineCycler<CData> _cycler; PipelineCycler<CData> _cycler;
typedef CycleDataReader<CData> CDReader; typedef CycleDataReader<CData> CDReader;
typedef CycleDataWriter<CData> CDWriter; typedef CycleDataWriter<CData> CDWriter;
typedef CycleDataStageReader<CData> CDStageReader;
typedef CycleDataStageWriter<CData> CDStageWriter;
public: public:
static void register_with_read_factory(); static void register_with_read_factory();