mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
visualize PlaneNodes
This commit is contained in:
parent
71cbcb72d7
commit
efc319c451
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 ©) :
|
||||
_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 ©) :
|
||||
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
|
||||
|
@ -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 ©) :
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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 ©);
|
||||
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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user