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);
}
////////////////////////////////////////////////////////////////////
// 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
// Access: Published

View File

@ -45,6 +45,9 @@ PUBLISHED:
FLOATNAME(LPoint3) get_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,
const FLOATNAME(LPoint3) &p1,
const FLOATNAME(LPoint3) &p2) const;

View File

@ -23,7 +23,9 @@
// Description:
////////////////////////////////////////////////////////////////////
INLINE PlaneNode::CData::
CData() {
CData() :
_viz_scale(100.0f)
{
// The default plane (perpendicular to the Z-axis) is used until
// another one is specified explicitly.
}
@ -35,12 +37,15 @@ CData() {
////////////////////////////////////////////////////////////////////
INLINE PlaneNode::CData::
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
// Description: Sets the particular plane represented by the
// PlaneNode.
@ -48,11 +53,15 @@ CData(const PlaneNode::CData &copy) :
INLINE void PlaneNode::
set_plane(const Planef &plane) {
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
// Description: Returns the plane represented by the PlaneNode.
////////////////////////////////////////////////////////////////////
@ -61,6 +70,34 @@ get_plane() const {
CDReader cdata(_cycler);
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

View File

@ -22,6 +22,13 @@
#include "bamReader.h"
#include "datagram.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;
@ -70,6 +77,9 @@ PlaneNode(const string &name, const Planef &plane) :
PandaNode(name),
_priority(0)
{
// PlaneNodes are hidden by default.
set_draw_mask(DrawMask::all_off());
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
// Access: Public, Virtual
@ -111,28 +132,155 @@ xform(const LMatrix4f &mat) {
PandaNode::xform(mat);
CDWriter cdata(_cycler);
cdata->_plane = cdata->_plane * mat;
cdata->_front_viz = NULL;
cdata->_back_viz = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::output
// Function: PlaneNode::has_cull_callback
// 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::
output(ostream &out) const {
PandaNode::output(out);
out << " " << get_plane();
bool PlaneNode::
has_cull_callback() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: PlaneNode::write
// Function: PlaneNode::cull_callback
// 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::
write(ostream &out, int indent_level) const {
PandaNode::write(out, indent_level);
get_plane().write(out, indent_level + 2);
bool PlaneNode::
cull_callback(CullTraverser *trav, CullTraverserData &data) {
// Normally, a PlaneNode is invisible. But if someone shows it, we
// 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 "pandaNode.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
@ -40,20 +47,29 @@ protected:
PlaneNode(const PlaneNode &copy);
public:
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level = 0) const;
virtual PandaNode *make_copy() const;
virtual void xform(const LMatrix4f &mat);
virtual bool has_cull_callback() const;
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
PUBLISHED:
INLINE void set_plane(const Planef &plane);
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 int get_priority() const;
public:
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:
// The priority is not cycled, because there's no real reason to do
@ -75,11 +91,15 @@ private:
}
Planef _plane;
PT(Geom) _front_viz, _back_viz;
float _viz_scale;
};
PipelineCycler<CData> _cycler;
typedef CycleDataReader<CData> CDReader;
typedef CycleDataWriter<CData> CDWriter;
typedef CycleDataStageReader<CData> CDStageReader;
typedef CycleDataStageWriter<CData> CDStageWriter;
public:
static void register_with_read_factory();