add show_switch() debugging mode
This commit is contained in:
parent
d596a4a2af
commit
3d415c4e0f
|
|
@ -152,6 +152,34 @@ get_cull_center() const {
|
|||
return _cull_center;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Camera::set_lod_center
|
||||
// Access: Published
|
||||
// Description: Specifies the point from which the LOD distances
|
||||
// are measured. Normally, this is the same as the
|
||||
// camera, and that is the default if this is not
|
||||
// specified; but it may sometimes be useful to perform
|
||||
// the distance test from some other viewpoint. This
|
||||
// may be used, for instance, to reduce LOD popping when
|
||||
// the camera rotates in a small circle about an avatar.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void Camera::
|
||||
set_lod_center(const NodePath &lod_center) {
|
||||
_lod_center = lod_center;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Camera::get_lod_center
|
||||
// Access: Published
|
||||
// Description: Returns the point from which the LOD distances will
|
||||
// be measured, if it was set by set_lod_center(), or
|
||||
// the empty NodePath otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const NodePath &Camera::
|
||||
get_lod_center() const {
|
||||
return _lod_center;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Camera::set_initial_state
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@ PUBLISHED:
|
|||
INLINE void set_cull_center(const NodePath &cull_center);
|
||||
INLINE const NodePath &get_cull_center() const;
|
||||
|
||||
INLINE void set_lod_center(const NodePath &lod_center);
|
||||
INLINE const NodePath &get_lod_center() const;
|
||||
|
||||
INLINE void set_initial_state(const RenderState *state);
|
||||
INLINE CPT(RenderState) get_initial_state() const;
|
||||
|
||||
|
|
@ -91,6 +94,7 @@ private:
|
|||
bool _active;
|
||||
NodePath _scene;
|
||||
NodePath _cull_center;
|
||||
NodePath _lod_center;
|
||||
|
||||
DrawMask _camera_mask;
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,10 @@ make_copy() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool FadeLODNode::
|
||||
cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
if (is_any_shown()) {
|
||||
return show_switches_cull_callback(trav, data);
|
||||
}
|
||||
|
||||
Camera *camera = trav->get_scene()->get_camera_node();
|
||||
NodePath this_np = data._node_path.get_node_path();
|
||||
FadeLODNodeData *ldata =
|
||||
|
|
|
|||
|
|
@ -17,126 +17,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODNode::CData::
|
||||
CData() :
|
||||
_center(0.0f, 0.0f, 0.0f),
|
||||
_lowest(0),
|
||||
_highest(0),
|
||||
_got_force_switch(false),
|
||||
_force_switch(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODNode::CData::
|
||||
CData(const LODNode::CData ©) :
|
||||
_center(copy._center),
|
||||
_switch_vector(copy._switch_vector),
|
||||
_lowest(copy._lowest),
|
||||
_highest(copy._highest),
|
||||
_got_force_switch(copy._got_force_switch),
|
||||
_force_switch(copy._force_switch)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODNode::Switch::
|
||||
Switch(float in, float out) {
|
||||
set_range(in, out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::get_in
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float LODNode::Switch::
|
||||
get_in() const {
|
||||
return _in;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::get_out
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float LODNode::Switch::
|
||||
get_out() const {
|
||||
return _out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::set_range
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
set_range(float in, float out) {
|
||||
_in = in;
|
||||
_out = out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::in_range
|
||||
// Access: Public
|
||||
// Description: Computes the distance between two points and returns
|
||||
// true if the result is within the range for the LOD.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LODNode::Switch::
|
||||
in_range(float dist) const {
|
||||
return (dist >= _out && dist < _in);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::rescale
|
||||
// Access: Public
|
||||
// Description: Scales the switching distances by the indicated factor.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
rescale(float factor) {
|
||||
_in *= factor;
|
||||
_out *= factor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::write_datagram
|
||||
// Access: Public
|
||||
// Description: Writes the contents of the Switch out to the
|
||||
// datagram, presumably in preparation to writing to a
|
||||
// Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
write_datagram(Datagram &destination) const {
|
||||
destination.add_float32(_in);
|
||||
destination.add_float32(_out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::read_datagram
|
||||
// Access: Public
|
||||
// Description: Reads the contents of the Switch from the datagram,
|
||||
// presumably in response to reading a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
read_datagram(DatagramIterator &source) {
|
||||
_in = source.get_float32();
|
||||
_out = source.get_float32();
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Constructor
|
||||
|
|
@ -179,6 +59,10 @@ add_switch(float in, float out) {
|
|||
CDWriter cdata(_cycler);
|
||||
cdata->_switch_vector.push_back(Switch(in, out));
|
||||
cdata->check_limits();
|
||||
|
||||
if (cdata->_num_shown != 0) {
|
||||
mark_internal_bounds_stale();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -193,6 +77,11 @@ set_switch(int index, float in, float out) {
|
|||
nassertr(index >= 0 && index < (int)cdata->_switch_vector.size(), false);
|
||||
cdata->_switch_vector[index].set_range(in, out);
|
||||
cdata->check_limits();
|
||||
|
||||
if (cdata->_num_shown != 0) {
|
||||
mark_internal_bounds_stale();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -209,6 +98,10 @@ clear_switches() {
|
|||
cdata->_switch_vector.clear();
|
||||
cdata->_lowest = 0;
|
||||
cdata->_highest = 0;
|
||||
|
||||
if (cdata->_num_shown != 0) {
|
||||
mark_internal_bounds_stale();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -319,6 +212,10 @@ INLINE void LODNode::
|
|||
set_center(const LPoint3f ¢er) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_center = center;
|
||||
|
||||
if (cdata->_num_shown != 0) {
|
||||
mark_internal_bounds_stale();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -333,3 +230,216 @@ get_center() const {
|
|||
CDReader cdata(_cycler);
|
||||
return cdata->_center;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::is_any_shown
|
||||
// Access: Published
|
||||
// Description: Returns true if any switch has been shown with
|
||||
// show_switch(), indicating the LODNode is in debug
|
||||
// show mode; or false if it is in the normal mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LODNode::
|
||||
is_any_shown() const {
|
||||
CDReader cdata(_cycler);
|
||||
return (cdata->_num_shown != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODNode::CData::
|
||||
CData() :
|
||||
_center(0.0f, 0.0f, 0.0f),
|
||||
_lowest(0),
|
||||
_highest(0),
|
||||
_got_force_switch(false),
|
||||
_force_switch(0),
|
||||
_num_shown(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODNode::CData::
|
||||
CData(const LODNode::CData ©) :
|
||||
_center(copy._center),
|
||||
_switch_vector(copy._switch_vector),
|
||||
_lowest(copy._lowest),
|
||||
_highest(copy._highest),
|
||||
_got_force_switch(copy._got_force_switch),
|
||||
_force_switch(copy._force_switch),
|
||||
_num_shown(copy._num_shown)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODNode::Switch::
|
||||
Switch(float in, float out) : _shown(false) {
|
||||
set_range(in, out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::get_in
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float LODNode::Switch::
|
||||
get_in() const {
|
||||
return _in;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::get_out
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float LODNode::Switch::
|
||||
get_out() const {
|
||||
return _out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::set_range
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
set_range(float in, float out) {
|
||||
_in = in;
|
||||
_out = out;
|
||||
_ring_viz.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::in_range
|
||||
// Access: Public
|
||||
// Description: Returns true if the indicated distance is within the
|
||||
// range for the LOD.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LODNode::Switch::
|
||||
in_range(float dist) const {
|
||||
return (dist >= _out && dist < _in);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::in_range_2
|
||||
// Access: Public
|
||||
// Description: Returns true if the indicated distance squared is
|
||||
// within the range for the LOD. (The distance value is
|
||||
// understood to be the square of the distance from the
|
||||
// camera to the object.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LODNode::Switch::
|
||||
in_range_2(float dist2) const {
|
||||
return (dist2 >= _out * _out && dist2 < _in * _in);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::rescale
|
||||
// Access: Public
|
||||
// Description: Scales the switching distances by the indicated factor.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
rescale(float factor) {
|
||||
_in *= factor;
|
||||
_out *= factor;
|
||||
_ring_viz.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::is_shown
|
||||
// Access: Public
|
||||
// Description: Returns true if show() has been called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LODNode::Switch::
|
||||
is_shown() const {
|
||||
return _shown;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::show
|
||||
// Access: Public
|
||||
// Description: Shows this ring in debug mode using the indicated
|
||||
// color.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
show(const Colorf &color) {
|
||||
_shown = true;
|
||||
_show_color = color;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::hide
|
||||
// Access: Public
|
||||
// Description: Undoes a previous call to show().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
hide() {
|
||||
_shown = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::get_ring_viz
|
||||
// Access: Public
|
||||
// Description: Returns a PandaNode suitable for rendering the ring
|
||||
// associated with this switch.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *LODNode::Switch::
|
||||
get_ring_viz() const {
|
||||
if (_ring_viz.is_null()) {
|
||||
((Switch *)this)->compute_ring_viz();
|
||||
}
|
||||
|
||||
return _ring_viz;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::get_viz_model_state
|
||||
// Access: Public
|
||||
// Description: Returns a RenderState suitable for drawing the
|
||||
// visible children of this switch level when the
|
||||
// show_switch() debugging mode is enabled.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const RenderState *LODNode::Switch::
|
||||
get_viz_model_state() const {
|
||||
if (_viz_model_state.is_null()) {
|
||||
((Switch *)this)->compute_ring_viz();
|
||||
}
|
||||
|
||||
return _viz_model_state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::write_datagram
|
||||
// Access: Public
|
||||
// Description: Writes the contents of the Switch out to the
|
||||
// datagram, presumably in preparation to writing to a
|
||||
// Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
write_datagram(Datagram &destination) const {
|
||||
destination.add_float32(_in);
|
||||
destination.add_float32(_out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::read_datagram
|
||||
// Access: Public
|
||||
// Description: Reads the contents of the Switch from the datagram,
|
||||
// presumably in response to reading a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
read_datagram(DatagramIterator &source) {
|
||||
_in = source.get_float32();
|
||||
_out = source.get_float32();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,82 +20,25 @@
|
|||
#include "cullTraverserData.h"
|
||||
#include "cullTraverser.h"
|
||||
#include "config_pgraph.h"
|
||||
#include "geomVertexData.h"
|
||||
#include "geomVertexWriter.h"
|
||||
#include "geomVertexFormat.h"
|
||||
#include "geomTristrips.h"
|
||||
#include "mathNumbers.h"
|
||||
#include "geom.h"
|
||||
#include "geomNode.h"
|
||||
#include "transformState.h"
|
||||
#include "material.h"
|
||||
#include "materialAttrib.h"
|
||||
#include "materialPool.h"
|
||||
#include "renderState.h"
|
||||
#include "cullFaceAttrib.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "boundingSphere.h"
|
||||
#include "look_at.h"
|
||||
|
||||
TypeHandle LODNode::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *LODNode::CData::
|
||||
make_copy() const {
|
||||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::check_limits
|
||||
// Access: Public
|
||||
// Description: Ensures that the _lowest and _highest members are set
|
||||
// appropriately after a change to the set of switches.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::CData::
|
||||
check_limits() {
|
||||
_lowest = 0;
|
||||
_highest = 0;
|
||||
for (size_t i = 1; i < _switch_vector.size(); ++i) {
|
||||
if (_switch_vector[i].get_out() > _switch_vector[_lowest].get_out()) {
|
||||
_lowest = i;
|
||||
}
|
||||
if (_switch_vector[i].get_in() < _switch_vector[_highest].get_in()) {
|
||||
_highest = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::CData::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) const {
|
||||
_center.write_datagram(dg);
|
||||
|
||||
dg.add_uint16(_switch_vector.size());
|
||||
|
||||
SwitchVector::const_iterator si;
|
||||
for (si = _switch_vector.begin();
|
||||
si != _switch_vector.end();
|
||||
++si) {
|
||||
(*si).write_datagram(dg);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::fillin
|
||||
// Access: Public, Virtual
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new LODNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::CData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
_center.read_datagram(scan);
|
||||
|
||||
_switch_vector.clear();
|
||||
|
||||
int num_switches = scan.get_uint16();
|
||||
_switch_vector.reserve(num_switches);
|
||||
for (int i = 0; i < num_switches; i++) {
|
||||
Switch sw(0, 0);
|
||||
sw.read_datagram(scan);
|
||||
|
||||
_switch_vector.push_back(sw);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::make_copy
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -185,6 +128,10 @@ has_cull_callback() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool LODNode::
|
||||
cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
if (is_any_shown()) {
|
||||
return show_switches_cull_callback(trav, data);
|
||||
}
|
||||
|
||||
int index = compute_child(trav, data);
|
||||
if (index >= 0 && index < get_num_children()) {
|
||||
CullTraverserData next_data(data, get_child(index));
|
||||
|
|
@ -235,6 +182,93 @@ is_lod_node() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::show_switch
|
||||
// Access: Published
|
||||
// Description: This is provided as a debugging aid. show_switch()
|
||||
// will put the LODNode into a special mode where rather
|
||||
// than computing and drawing the appropriate level of
|
||||
// the LOD, a ring is drawn around the LODNode center
|
||||
// indicating the switch distances from the camera for
|
||||
// the indicated level, and the geometry of the
|
||||
// indicated level is drawn in wireframe.
|
||||
//
|
||||
// Multiple different levels can be visualized this way
|
||||
// at once. Call hide_switch() or hide_all_switches() to
|
||||
// undo this mode and restore the LODNode to its normal
|
||||
// behavior.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::
|
||||
show_switch(int index) {
|
||||
CDWriter cdata(_cycler);
|
||||
do_show_switch(cdata, index, get_default_show_color(index));
|
||||
mark_internal_bounds_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::show_switch
|
||||
// Access: Published
|
||||
// Description: This is provided as a debugging aid. show_switch()
|
||||
// will put the LODNode into a special mode where rather
|
||||
// than computing and drawing the appropriate level of
|
||||
// the LOD, a ring is drawn around the LODNode center
|
||||
// indicating the switch distances from the camera for
|
||||
// the indicated level, and the geometry of the
|
||||
// indicated level is drawn in wireframe.
|
||||
//
|
||||
// Multiple different levels can be visualized this way
|
||||
// at once. Call hide_switch() or hide_all_switches() to
|
||||
// undo this mode and restore the LODNode to its normal
|
||||
// behavior.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::
|
||||
show_switch(int index, const Colorf &color) {
|
||||
CDWriter cdata(_cycler);
|
||||
do_show_switch(cdata, index, color);
|
||||
mark_internal_bounds_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::hide_switch
|
||||
// Access: Published
|
||||
// Description: Disables a previous call to show_switch().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::
|
||||
hide_switch(int index) {
|
||||
CDWriter cdata(_cycler);
|
||||
do_hide_switch(cdata, index);
|
||||
mark_internal_bounds_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::show_all_switches
|
||||
// Access: Published
|
||||
// Description: Shows all levels in their default colors.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::
|
||||
show_all_switches() {
|
||||
CDWriter cdata(_cycler);
|
||||
for (int i = 0; i < (int)cdata->_switch_vector.size(); ++i) {
|
||||
do_show_switch(cdata, i, get_default_show_color(i));
|
||||
}
|
||||
mark_internal_bounds_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::hide_all_switches
|
||||
// Access: Published
|
||||
// Description: Hides all levels, restoring the LODNode to normal
|
||||
// operation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::
|
||||
hide_all_switches() {
|
||||
CDWriter cdata(_cycler);
|
||||
for (int i = 0; i < (int)cdata->_switch_vector.size(); ++i) {
|
||||
do_hide_switch(cdata, i);
|
||||
}
|
||||
mark_internal_bounds_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::compute_child
|
||||
// Access: Protected
|
||||
|
|
@ -255,27 +289,42 @@ compute_child(CullTraverser *trav, CullTraverserData &data) {
|
|||
if (cdata->_got_force_switch) {
|
||||
return cdata->_force_switch;
|
||||
}
|
||||
|
||||
// Get a pointer to the camera node.
|
||||
Camera *camera = trav->get_scene()->get_camera_node();
|
||||
|
||||
// Get the LOD center in camera space
|
||||
// CPT(TransformState) rel_transform =
|
||||
// trav->get_camera_transform()->invert_compose(data._net_transform);
|
||||
// Get the LOD center in camera space. If the camera has a special
|
||||
// LOD center defined, use that; otherwise, if it has a cull center,
|
||||
// use that; otherwise, use the modelview transform (which is camera
|
||||
// space).
|
||||
CPT(TransformState) rel_transform;
|
||||
|
||||
// CPT(TransformState) rel_transform =
|
||||
// trav->get_scene()->get_cull_center().get_net_transform()->
|
||||
// invert_compose(data._net_transform);
|
||||
NodePath lod_center = camera->get_lod_center();
|
||||
if (!lod_center.is_empty()) {
|
||||
rel_transform =
|
||||
lod_center.get_net_transform()->invert_compose(data.get_net_transform(trav));
|
||||
} else {
|
||||
NodePath cull_center = camera->get_cull_center();
|
||||
if (!cull_center.is_empty()) {
|
||||
rel_transform =
|
||||
cull_center.get_net_transform()->invert_compose(data.get_net_transform(trav));
|
||||
} else {
|
||||
rel_transform = data.get_modelview_transform(trav);
|
||||
}
|
||||
}
|
||||
|
||||
CPT(TransformState) rel_transform = data.get_modelview_transform(trav);
|
||||
LPoint3f center = cdata->_center * rel_transform->get_mat();
|
||||
|
||||
// Determine which child to traverse
|
||||
float dist = fabs(dot(center, LVector3f::forward()));
|
||||
// Now measure the distance to the LOD center, and use that to
|
||||
// determine which child to display.
|
||||
float dist2 = center.dot(center);
|
||||
|
||||
for (int index = 0; index < (int)cdata->_switch_vector.size(); index++) {
|
||||
if (cdata->_switch_vector[index].in_range(dist)) {
|
||||
if (cdata->_switch_vector[index].in_range_2(dist2)) {
|
||||
if (pgraph_cat.is_debug()) {
|
||||
pgraph_cat.debug()
|
||||
<< data._node_path << " at distance " << dist << ", selected child "
|
||||
<< index << "\n";
|
||||
<< data._node_path << " at distance " << sqrt(dist2)
|
||||
<< ", selected child " << index << "\n";
|
||||
}
|
||||
|
||||
return index;
|
||||
|
|
@ -284,12 +333,194 @@ compute_child(CullTraverser *trav, CullTraverserData &data) {
|
|||
|
||||
if (pgraph_cat.is_debug()) {
|
||||
pgraph_cat.debug()
|
||||
<< data._node_path << " at distance " << dist << ", no children in range.\n";
|
||||
<< data._node_path << " at distance " << sqrt(dist2)
|
||||
<< ", no children in range.\n";
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::show_switches_cull_callback
|
||||
// Access: Protected
|
||||
// Description: A special version of cull_callback() that is to be
|
||||
// invoked when the LODNode is in show_switch() mode.
|
||||
// This just draws the rings and the wireframe geometry
|
||||
// for the selected switches.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool LODNode::
|
||||
show_switches_cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
// Get a pointer to the camera node.
|
||||
Camera *camera = trav->get_scene()->get_camera_node();
|
||||
|
||||
// Get the camera space transform. This bit is the same as the code
|
||||
// in compute_child(), above.
|
||||
CPT(TransformState) rel_transform;
|
||||
|
||||
NodePath lod_center = camera->get_lod_center();
|
||||
if (!lod_center.is_empty()) {
|
||||
rel_transform =
|
||||
lod_center.get_net_transform()->invert_compose(data.get_net_transform(trav));
|
||||
} else {
|
||||
NodePath cull_center = camera->get_cull_center();
|
||||
if (!cull_center.is_empty()) {
|
||||
rel_transform =
|
||||
cull_center.get_net_transform()->invert_compose(data.get_net_transform(trav));
|
||||
} else {
|
||||
rel_transform = data.get_modelview_transform(trav);
|
||||
}
|
||||
}
|
||||
|
||||
LPoint3f center = cdata->_center * rel_transform->get_mat();
|
||||
float dist2 = center.dot(center);
|
||||
|
||||
// Now orient the disk(s) in camera space such that their origin is
|
||||
// at center, and the (0, 0, 0) point in camera space is on the disk.
|
||||
LMatrix4f mat;
|
||||
look_at(mat, -center, LVector3f(0.0f, 0.0f, 1.0f));
|
||||
mat.set_row(3, center);
|
||||
CPT(TransformState) viz_transform = TransformState::make_mat(mat);
|
||||
|
||||
viz_transform = rel_transform->invert_compose(viz_transform);
|
||||
viz_transform = data.get_net_transform(trav)->compose(viz_transform);
|
||||
|
||||
SwitchVector::const_iterator si;
|
||||
for (si = cdata->_switch_vector.begin();
|
||||
si != cdata->_switch_vector.end();
|
||||
++si) {
|
||||
const Switch &sw = (*si);
|
||||
if (sw.is_shown()) {
|
||||
PT(PandaNode) ring_viz = sw.get_ring_viz();
|
||||
CullTraverserData next_data(data, ring_viz);
|
||||
next_data._net_transform = viz_transform;
|
||||
|
||||
trav->traverse(next_data);
|
||||
|
||||
if (sw.in_range_2(dist2)) {
|
||||
// This switch level is in range. Draw its children in the
|
||||
// funny wireframe mode.
|
||||
int index = (si - cdata->_switch_vector.begin());
|
||||
if (index < get_num_children()) {
|
||||
CullTraverserData next_data(data, get_child(index));
|
||||
next_data._state = next_data._state->compose(sw.get_viz_model_state());
|
||||
trav->traverse(next_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, draw the visible child(ren) in the appropriate state as
|
||||
// well.
|
||||
|
||||
for (int index = 0; index < (int)cdata->_switch_vector.size(); index++) {
|
||||
if (cdata->_switch_vector[index].in_range_2(dist2)) {
|
||||
}
|
||||
}
|
||||
|
||||
// Now return false indicating that we have already taken care of
|
||||
// the traversal from here.
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::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) LODNode::
|
||||
compute_internal_bounds(int pipeline_stage, Thread *current_thread) const {
|
||||
// First, get ourselves a fresh, empty bounding volume.
|
||||
PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread);
|
||||
nassertr(bound != (BoundingVolume *)NULL, bound);
|
||||
|
||||
// If we have any visible rings, those count in the bounding volume.
|
||||
if (is_any_shown()) {
|
||||
// Now actually compute the bounding volume by putting it around all
|
||||
// of our geoms' bounding volumes.
|
||||
pvector<const BoundingVolume *> child_volumes;
|
||||
pvector<PT(BoundingVolume) > pt_volumes;
|
||||
|
||||
CDStageReader cdata(_cycler, pipeline_stage, current_thread);
|
||||
|
||||
SwitchVector::const_iterator si;
|
||||
for (si = cdata->_switch_vector.begin();
|
||||
si != cdata->_switch_vector.end();
|
||||
++si) {
|
||||
const Switch &sw = (*si);
|
||||
if (sw.is_shown()) {
|
||||
PT(BoundingVolume) sphere = new BoundingSphere(cdata->_center, sw.get_in());
|
||||
child_volumes.push_back(sphere);
|
||||
pt_volumes.push_back(sphere);
|
||||
}
|
||||
}
|
||||
|
||||
const BoundingVolume **child_begin = &child_volumes[0];
|
||||
const BoundingVolume **child_end = child_begin + child_volumes.size();
|
||||
|
||||
bound->around(child_begin, child_end);
|
||||
}
|
||||
|
||||
return bound;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::do_show_switch
|
||||
// Access: Private
|
||||
// Description: The private implementation of show_switch().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::
|
||||
do_show_switch(LODNode::CData *cdata, int index, const Colorf &color) {
|
||||
nassertv(index >= 0 && index < (int)cdata->_switch_vector.size());
|
||||
|
||||
if (!cdata->_switch_vector[index].is_shown()) {
|
||||
++cdata->_num_shown;
|
||||
}
|
||||
cdata->_switch_vector[index].show(color);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::do_hide_switch
|
||||
// Access: Private
|
||||
// Description: The private implementation of hide_switch().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::
|
||||
do_hide_switch(LODNode::CData *cdata, int index) {
|
||||
nassertv(index >= 0 && index < (int)cdata->_switch_vector.size());
|
||||
|
||||
if (cdata->_switch_vector[index].is_shown()) {
|
||||
--cdata->_num_shown;
|
||||
}
|
||||
cdata->_switch_vector[index].hide();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::get_default_show_color
|
||||
// Access: Private, Static
|
||||
// Description: Returns a default color appropriate for showing the
|
||||
// indicated level.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const Colorf &LODNode::
|
||||
get_default_show_color(int index) {
|
||||
static Colorf default_colors[] = {
|
||||
Colorf(1.0f, 0.0f, 0.0f, 0.7f),
|
||||
Colorf(0.0f, 1.0f, 0.0f, 0.7f),
|
||||
Colorf(0.0f, 0.0f, 1.0f, 0.7f),
|
||||
Colorf(0.0f, 1.0f, 1.0f, 0.7f),
|
||||
Colorf(1.0f, 0.0f, 1.0f, 0.7f),
|
||||
Colorf(1.0f, 1.0f, 0.0f, 0.7f),
|
||||
};
|
||||
static const int num_default_colors = sizeof(default_colors) / sizeof(Colorf);
|
||||
|
||||
return default_colors[index % num_default_colors];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
|
|
@ -345,3 +576,214 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
|||
PandaNode::fillin(scan, manager);
|
||||
manager->read_cdata(scan, _cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *LODNode::CData::
|
||||
make_copy() const {
|
||||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::check_limits
|
||||
// Access: Public
|
||||
// Description: Ensures that the _lowest and _highest members are set
|
||||
// appropriately after a change to the set of switches.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::CData::
|
||||
check_limits() {
|
||||
_lowest = 0;
|
||||
_highest = 0;
|
||||
for (size_t i = 1; i < _switch_vector.size(); ++i) {
|
||||
if (_switch_vector[i].get_out() > _switch_vector[_lowest].get_out()) {
|
||||
_lowest = i;
|
||||
}
|
||||
if (_switch_vector[i].get_in() < _switch_vector[_highest].get_in()) {
|
||||
_highest = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::CData::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) const {
|
||||
_center.write_datagram(dg);
|
||||
|
||||
dg.add_uint16(_switch_vector.size());
|
||||
|
||||
SwitchVector::const_iterator si;
|
||||
for (si = _switch_vector.begin();
|
||||
si != _switch_vector.end();
|
||||
++si) {
|
||||
(*si).write_datagram(dg);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::fillin
|
||||
// Access: Public, Virtual
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new LODNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::CData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
_center.read_datagram(scan);
|
||||
|
||||
_switch_vector.clear();
|
||||
|
||||
int num_switches = scan.get_uint16();
|
||||
_switch_vector.reserve(num_switches);
|
||||
for (int i = 0; i < num_switches; i++) {
|
||||
Switch sw(0, 0);
|
||||
sw.read_datagram(scan);
|
||||
|
||||
_switch_vector.push_back(sw);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::compute_ring_viz
|
||||
// Access: Private
|
||||
// Description: Computes a Geom suitable for rendering the ring
|
||||
// associated with this switch.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::Switch::
|
||||
compute_ring_viz() {
|
||||
static const int num_slices = 50;
|
||||
static const int num_rings = 1;
|
||||
static const float edge_ratio = 0.1; // ratio of edge height to diameter.
|
||||
|
||||
const GeomVertexFormat *format = GeomVertexFormat::get_v3n3cp();
|
||||
PT(GeomVertexData) vdata = new GeomVertexData("LOD", format, Geom::UH_static);
|
||||
|
||||
// Fill up the vertex table with all of the vertices.
|
||||
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
GeomVertexWriter normal(vdata, InternalName::get_normal());
|
||||
GeomVertexWriter color(vdata, InternalName::get_color());
|
||||
|
||||
// First, the vertices for the flat ring.
|
||||
int ri, si;
|
||||
for (ri = 0; ri <= num_rings; ++ri) {
|
||||
// r is in the range [0.0, 1.0].
|
||||
float r = (float)ri / (float)num_rings;
|
||||
|
||||
// d is in the range [_out, _in].
|
||||
float d = r * (_in - _out) + _out;
|
||||
|
||||
for (si = 0; si < num_slices; ++si) {
|
||||
// s is in the range [0.0, 1.0).
|
||||
float s = (float)si / (float)num_slices;
|
||||
|
||||
// t is in the range [0.0, 2pi).
|
||||
float t = MathNumbers::pi_f * 2.0f * s;
|
||||
|
||||
float x = cosf(t);
|
||||
float y = sinf(t);
|
||||
vertex.add_data3f(x * d, y * d, 0.0f);
|
||||
normal.add_data3f(0.0f, 0.0f, 1.0f);
|
||||
color.add_data4f(_show_color);
|
||||
}
|
||||
}
|
||||
|
||||
// Next, the vertices for the inner and outer edges.
|
||||
for (ri = 0; ri <= 1; ++ri) {
|
||||
float r = (float)ri;
|
||||
float d = r * (_in - _out) + _out;
|
||||
|
||||
// Invert the direction of Z on the outer ring, to invert the
|
||||
// vertex winding order (and thereby invert the facing of the
|
||||
// polygons). We want the outer ring to face inward, and the
|
||||
// inner ring to face outward.
|
||||
float sign = 1.0f - (ri * 2);
|
||||
|
||||
for (si = 0; si < num_slices; ++si) {
|
||||
float s = (float)si / (float)num_slices;
|
||||
float t = MathNumbers::pi_f * 2.0f * s;
|
||||
|
||||
float x = cosf(t);
|
||||
float y = sinf(t);
|
||||
|
||||
vertex.add_data3f(x * d, y * d, 0.5f * edge_ratio * d * sign);
|
||||
normal.add_data3f(x * sign, y * sign, 0.0f);
|
||||
color.add_data4f(_show_color);
|
||||
}
|
||||
|
||||
for (si = 0; si < num_slices; ++si) {
|
||||
float s = (float)si / (float)num_slices;
|
||||
float t = MathNumbers::pi_f * 2.0f * s;
|
||||
|
||||
float x = cosf(t);
|
||||
float y = sinf(t);
|
||||
|
||||
vertex.add_data3f(x * d, y * d, -0.5f * edge_ratio * d * sign);
|
||||
normal.add_data3f(x * sign, y * sign, 0.0f);
|
||||
color.add_data4f(_show_color);
|
||||
}
|
||||
}
|
||||
|
||||
// Now create the triangle strips. One tristrip for each ring.
|
||||
PT(GeomTristrips) strips = new GeomTristrips(Geom::UH_static);
|
||||
for (ri = 0; ri < num_rings; ++ri) {
|
||||
for (si = 0; si < num_slices; ++si) {
|
||||
strips->add_vertex(ri * num_slices + si);
|
||||
strips->add_vertex((ri + 1) * num_slices + si);
|
||||
}
|
||||
strips->add_vertex(ri * num_slices);
|
||||
strips->add_vertex((ri + 1) * num_slices);
|
||||
strips->close_primitive();
|
||||
}
|
||||
|
||||
// And then one triangle strip for each of the inner and outer
|
||||
// edges.
|
||||
for (ri = 0; ri <= 1; ++ri) {
|
||||
for (si = 0; si < num_slices; ++si) {
|
||||
strips->add_vertex((num_rings + 1 + ri * 2) * num_slices + si);
|
||||
strips->add_vertex((num_rings + 1 + ri * 2 + 1) * num_slices + si);
|
||||
}
|
||||
strips->add_vertex((num_rings + 1 + ri * 2) * num_slices);
|
||||
strips->add_vertex((num_rings + 1 + ri * 2 + 1) * num_slices);
|
||||
strips->close_primitive();
|
||||
}
|
||||
|
||||
PT(Geom) ring_geom = new Geom(vdata);
|
||||
ring_geom->add_primitive(strips);
|
||||
|
||||
PT(GeomNode) geom_node = new GeomNode("ring");
|
||||
geom_node->add_geom(ring_geom);
|
||||
|
||||
// Get a material for two-sided lighting.
|
||||
PT(Material) material = new Material();
|
||||
material->set_twoside(true);
|
||||
material = MaterialPool::get_material(material);
|
||||
|
||||
CPT(RenderState) viz_state = RenderState::make(CullFaceAttrib::make(CullFaceAttrib::M_cull_none),
|
||||
TextureAttrib::make_off(),
|
||||
MaterialAttrib::make(material),
|
||||
RenderState::get_max_priority());
|
||||
if (_show_color[3] != 1.0f) {
|
||||
viz_state = viz_state->add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha),
|
||||
RenderState::get_max_priority());
|
||||
}
|
||||
|
||||
geom_node->set_state(viz_state);
|
||||
|
||||
_ring_viz = geom_node.p();
|
||||
|
||||
// Also compute a RenderState for rendering the children in
|
||||
// wireframe mode.
|
||||
|
||||
_viz_model_state = RenderState::make(RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
|
||||
TextureAttrib::make_off(),
|
||||
ColorAttrib::make_flat(_show_color),
|
||||
TransparencyAttrib::make(TransparencyAttrib::M_none),
|
||||
RenderState::get_max_priority());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
#include "pandaNode.h"
|
||||
#include "luse.h"
|
||||
#include "pvector.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : LODNode
|
||||
|
|
@ -70,9 +72,26 @@ PUBLISHED:
|
|||
INLINE void set_center(const LPoint3f ¢er);
|
||||
INLINE const LPoint3f &get_center() const;
|
||||
|
||||
void show_switch(int index);
|
||||
void show_switch(int index, const Colorf &color);
|
||||
void hide_switch(int index);
|
||||
void show_all_switches();
|
||||
void hide_all_switches();
|
||||
INLINE bool is_any_shown() const;
|
||||
|
||||
protected:
|
||||
int compute_child(CullTraverser *trav, CullTraverserData &data);
|
||||
|
||||
bool show_switches_cull_callback(CullTraverser *trav, CullTraverserData &data);
|
||||
virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const;
|
||||
|
||||
private:
|
||||
class CData;
|
||||
void do_show_switch(CData *cdata, int index, const Colorf &color);
|
||||
void do_hide_switch(CData *cdata, int index);
|
||||
|
||||
static const Colorf &get_default_show_color(int index);
|
||||
|
||||
protected:
|
||||
class Switch {
|
||||
public:
|
||||
|
|
@ -82,18 +101,34 @@ protected:
|
|||
|
||||
INLINE void set_range(float in, float out);
|
||||
INLINE bool in_range(float dist) const;
|
||||
|
||||
INLINE bool in_range_2(float dist2) const;
|
||||
|
||||
INLINE void rescale(float factor);
|
||||
|
||||
INLINE bool is_shown() const;
|
||||
INLINE void show(const Colorf &color);
|
||||
INLINE void hide();
|
||||
|
||||
INLINE PandaNode *get_ring_viz() const;
|
||||
INLINE const RenderState *get_viz_model_state() const;
|
||||
|
||||
INLINE void write_datagram(Datagram &destination) const;
|
||||
INLINE void read_datagram(DatagramIterator &source);
|
||||
|
||||
private:
|
||||
void compute_ring_viz();
|
||||
|
||||
private:
|
||||
float _in;
|
||||
float _out;
|
||||
bool _shown;
|
||||
Colorf _show_color;
|
||||
PT(PandaNode) _ring_viz;
|
||||
CPT(RenderState) _viz_model_state;
|
||||
};
|
||||
typedef pvector<Switch> SwitchVector;
|
||||
|
||||
private:
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
public:
|
||||
INLINE CData();
|
||||
|
|
@ -114,11 +149,14 @@ protected:
|
|||
|
||||
bool _got_force_switch;
|
||||
int _force_switch;
|
||||
int _num_shown;
|
||||
};
|
||||
|
||||
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…
Reference in New Issue