several pgraph refinements
This commit is contained in:
parent
ec278a4f0f
commit
d210511b8b
|
|
@ -281,8 +281,7 @@ do_cull(CullHandler *cull_handler, const qpNodePath &camera,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
trav.traverse(scene.node());
|
||||
trav.traverse(scene);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -104,6 +104,10 @@ BoundingVolume *BoundedObject::
|
|||
recompute_bound() {
|
||||
CDWriter cdata(_cycler);
|
||||
switch (cdata->_bound_type) {
|
||||
case BVT_static:
|
||||
// Don't change it if it's a static volume.
|
||||
break;
|
||||
|
||||
case BVT_dynamic_sphere:
|
||||
cdata->_bound = new BoundingSphere;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class Filename;
|
|||
// common scene graph files.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA BamFile {
|
||||
public:
|
||||
PUBLISHED:
|
||||
BamFile();
|
||||
~BamFile();
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
materialAttrib.I materialAttrib.h \
|
||||
qpmodelNode.I qpmodelNode.h \
|
||||
qpmodelRoot.I qpmodelRoot.h \
|
||||
qpnodePath.I qpnodePath.h \
|
||||
qpnodePath.I qpnodePath.h qpnodePath.cxx \
|
||||
qpnodePathCollection.I qpnodePathCollection.h \
|
||||
qpnodePathComponent.I qpnodePathComponent.h \
|
||||
qpnodePathLerps.h \
|
||||
|
|
|
|||
|
|
@ -23,11 +23,13 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CullTraverserData::
|
||||
CullTraverserData(const TransformState *render_transform,
|
||||
CullTraverserData(const qpNodePath &start,
|
||||
const TransformState *render_transform,
|
||||
const TransformState *net_transform,
|
||||
const RenderState *state,
|
||||
GeometricBoundingVolume *view_frustum,
|
||||
GeometricBoundingVolume *guard_band) :
|
||||
_node_path(start),
|
||||
_render_transform(render_transform),
|
||||
_net_transform(net_transform),
|
||||
_state(state),
|
||||
|
|
@ -37,32 +39,42 @@ CullTraverserData(const TransformState *render_transform,
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverserData::Copy Constructor
|
||||
// Function: CullTraverserData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description: This constructor creates a CullTraverserData object
|
||||
// that reflects the next node down in the traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CullTraverserData::
|
||||
CullTraverserData(const CullTraverserData ©) :
|
||||
_render_transform(copy._render_transform),
|
||||
_net_transform(copy._net_transform),
|
||||
_state(copy._state),
|
||||
_view_frustum(copy._view_frustum),
|
||||
_guard_band(copy._guard_band)
|
||||
CullTraverserData(const CullTraverserData &parent, PandaNode *child) :
|
||||
_node_path(parent._node_path, child),
|
||||
_render_transform(parent._render_transform),
|
||||
_net_transform(parent._net_transform),
|
||||
_state(parent._state),
|
||||
_view_frustum(parent._view_frustum),
|
||||
_guard_band(parent._guard_band)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverserData::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: Do not copy CullTraverserData objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CullTraverserData::
|
||||
CullTraverserData(const CullTraverserData ©) :
|
||||
_node_path(qpNodePath())
|
||||
{
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverserData::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Access: Private
|
||||
// Description: Do not copy CullTraverserData objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CullTraverserData::
|
||||
operator = (const CullTraverserData ©) {
|
||||
_render_transform = copy._render_transform;
|
||||
_net_transform = copy._net_transform;
|
||||
_state = copy._state;
|
||||
_view_frustum = copy._view_frustum;
|
||||
_guard_band = copy._guard_band;
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -74,18 +86,33 @@ INLINE CullTraverserData::
|
|||
~CullTraverserData() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverserData::node
|
||||
// Access: Public
|
||||
// Description: Returns the node traversed to so far.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *CullTraverserData::
|
||||
node() const {
|
||||
return _node_path.node();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverserData::is_in_view
|
||||
// Access: Public
|
||||
// Description: Returns true if the node is within the view frustum,
|
||||
// false otherwise. If the node's bounding volume falls
|
||||
// completely within the view frustum, this will also
|
||||
// reset the view frustum pointer, saving some work for
|
||||
// future nodes.
|
||||
// Description: Returns true if the current node is within the view
|
||||
// frustum, false otherwise. If the node's bounding
|
||||
// volume falls completely within the view frustum, this
|
||||
// will also reset the view frustum pointer, saving some
|
||||
// work for future nodes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CullTraverserData::
|
||||
is_in_view(PandaNode *node, const DrawMask &camera_mask) {
|
||||
if ((node->get_draw_mask() & camera_mask).is_zero()) {
|
||||
is_in_view(const DrawMask &camera_mask) {
|
||||
if (node()->get_transform()->is_invalid()) {
|
||||
// If the transform is invalid, forget it.
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((node()->get_draw_mask() & camera_mask).is_zero()) {
|
||||
// If there are no draw bits in common with the camera, the node
|
||||
// is out.
|
||||
return false;
|
||||
|
|
@ -98,5 +125,5 @@ is_in_view(PandaNode *node, const DrawMask &camera_mask) {
|
|||
}
|
||||
|
||||
// Otherwise, compare the bounding volume to the frustum.
|
||||
return is_in_view_impl(node);
|
||||
return is_in_view_impl();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverserData::apply_transform_and_state
|
||||
// Access: Public
|
||||
// Description: Applies the transform and state from the indicated
|
||||
// Description: Applies the transform and state from the current
|
||||
// node onto the current data. This also evaluates
|
||||
// billboards, etc.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CullTraverserData::
|
||||
apply_transform_and_state(qpCullTraverser *trav, PandaNode *node) {
|
||||
const TransformState *node_transform = node->get_transform();
|
||||
apply_transform_and_state(qpCullTraverser *trav) {
|
||||
const TransformState *node_transform = node()->get_transform();
|
||||
if (!node_transform->is_identity()) {
|
||||
_render_transform = _render_transform->compose(node_transform);
|
||||
_net_transform = _net_transform->compose(node_transform);
|
||||
|
|
@ -69,9 +69,9 @@ apply_transform_and_state(qpCullTraverser *trav, PandaNode *node) {
|
|||
}
|
||||
}
|
||||
|
||||
_state = _state->compose(node->get_state());
|
||||
_state = _state->compose(node()->get_state());
|
||||
|
||||
const RenderEffects *node_effects = node->get_effects();
|
||||
const RenderEffects *node_effects = node()->get_effects();
|
||||
const BillboardEffect *billboard = node_effects->get_billboard();
|
||||
if (billboard != (const BillboardEffect *)NULL) {
|
||||
// Got to apply a billboard transform here.
|
||||
|
|
@ -94,11 +94,11 @@ apply_transform_and_state(qpCullTraverser *trav, PandaNode *node) {
|
|||
// Description: The private implementation of is_in_view().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CullTraverserData::
|
||||
is_in_view_impl(PandaNode *node) {
|
||||
is_in_view_impl() {
|
||||
// By the time we get here, we know we have a viewing frustum.
|
||||
nassertr(_view_frustum != (GeometricBoundingVolume *)NULL, true);
|
||||
|
||||
const BoundingVolume &node_volume = node->get_bound();
|
||||
const BoundingVolume &node_volume = node()->get_bound();
|
||||
nassertr(node_volume.is_of_type(GeometricBoundingVolume::get_class_type()), false);
|
||||
const GeometricBoundingVolume *node_gbv =
|
||||
DCAST(GeometricBoundingVolume, &node_volume);
|
||||
|
|
@ -123,7 +123,7 @@ is_in_view_impl(PandaNode *node) {
|
|||
_view_frustum = (GeometricBoundingVolume *)NULL;
|
||||
|
||||
} else {
|
||||
if (node->is_final()) {
|
||||
if (node()->is_final()) {
|
||||
// The bounding volume is partially, but not completely,
|
||||
// within the viewing frustum. Normally we'd keep testing
|
||||
// child bounding volumes as we continue down. But this node
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "workingNodePath.h"
|
||||
#include "renderState.h"
|
||||
#include "transformState.h"
|
||||
#include "geometricBoundingVolume.h"
|
||||
|
|
@ -46,18 +47,28 @@ class qpCullTraverser;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA CullTraverserData {
|
||||
public:
|
||||
INLINE CullTraverserData(const TransformState *render_transform,
|
||||
INLINE CullTraverserData(const qpNodePath &start,
|
||||
const TransformState *render_transform,
|
||||
const TransformState *net_transform,
|
||||
const RenderState *state,
|
||||
GeometricBoundingVolume *view_frustum,
|
||||
GeometricBoundingVolume *guard_band);
|
||||
INLINE CullTraverserData(const CullTraverserData &parent,
|
||||
PandaNode *child);
|
||||
|
||||
private:
|
||||
INLINE CullTraverserData(const CullTraverserData ©);
|
||||
INLINE void operator = (const CullTraverserData ©);
|
||||
INLINE void operator = (const CullTraverserData ©);
|
||||
|
||||
public:
|
||||
INLINE ~CullTraverserData();
|
||||
|
||||
INLINE bool is_in_view(PandaNode *node, const DrawMask &camera_mask);
|
||||
void apply_transform_and_state(qpCullTraverser *trav, PandaNode *node);
|
||||
INLINE PandaNode *node() const;
|
||||
|
||||
INLINE bool is_in_view(const DrawMask &camera_mask);
|
||||
void apply_transform_and_state(qpCullTraverser *trav);
|
||||
|
||||
WorkingNodePath _node_path;
|
||||
CPT(TransformState) _render_transform;
|
||||
CPT(TransformState) _net_transform;
|
||||
CPT(RenderState) _state;
|
||||
|
|
@ -65,7 +76,7 @@ public:
|
|||
PT(GeometricBoundingVolume) _guard_band;
|
||||
|
||||
private:
|
||||
bool is_in_view_impl(PandaNode *node);
|
||||
bool is_in_view_impl();
|
||||
static CPT(RenderState) get_fake_view_frustum_cull_effect();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -739,7 +739,7 @@ get_bound() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const BoundingVolume &PandaNode::
|
||||
get_internal_bound() const {
|
||||
if (_internal_bound.is_bound_stale()) {
|
||||
if (is_bound_stale() || _internal_bound.is_bound_stale()) {
|
||||
((PandaNode *)this)->recompute_internal_bound();
|
||||
}
|
||||
return _internal_bound.get_bound();
|
||||
|
|
|
|||
|
|
@ -1157,17 +1157,21 @@ propagate_stale_bound() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
BoundingVolume *PandaNode::
|
||||
recompute_bound() {
|
||||
// First, get ourselves a fresh, empty bounding volume.
|
||||
// Get the internal bound before we do anything else, since the
|
||||
// is_bound_stale() flag may also apply to this.
|
||||
const BoundingVolume *internal_bound = &get_internal_bound();
|
||||
|
||||
// Now, get ourselves a fresh, empty bounding volume. This will
|
||||
// reset the is_bound_stale() flag if it was set.
|
||||
BoundingVolume *bound = BoundedObject::recompute_bound();
|
||||
nassertr(bound != (BoundingVolume*)NULL, bound);
|
||||
|
||||
// Now actually compute the bounding volume by putting it around all
|
||||
// of our child bounding volumes.
|
||||
|
||||
pvector<const BoundingVolume *> child_volumes;
|
||||
|
||||
// It goes around this node's internal bounding volume . . .
|
||||
child_volumes.push_back(&get_internal_bound());
|
||||
child_volumes.push_back(internal_bound);
|
||||
|
||||
CDReader cdata(_cycler);
|
||||
Down::const_iterator di;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include "materialAttrib.cxx"
|
||||
#include "qpmodelNode.cxx"
|
||||
#include "qpmodelRoot.cxx"
|
||||
#include "qpnodePath.cxx"
|
||||
#include "qpnodePathCollection.cxx"
|
||||
#include "qpnodePathComponent.cxx"
|
||||
#include "qpnodePathLerps.cxx"
|
||||
|
|
|
|||
|
|
@ -65,44 +65,39 @@ qpCullTraverser(const qpCullTraverser ©) :
|
|||
// Description: Begins the traversal from the indicated node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpCullTraverser::
|
||||
traverse(PandaNode *root) {
|
||||
traverse(qpNodePath &root) {
|
||||
nassertv(_cull_handler != (CullHandler *)NULL);
|
||||
|
||||
CullTraverserData data(_render_transform, TransformState::make_identity(),
|
||||
CullTraverserData data(root,
|
||||
_render_transform, TransformState::make_identity(),
|
||||
_initial_state, _view_frustum, _guard_band);
|
||||
traverse(root, data);
|
||||
traverse(data);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpCullTraverser::traverse
|
||||
// Access: Public
|
||||
// Description: Traverses from the indicated node with the given
|
||||
// data, which has not yet been converted into the
|
||||
// node's space.
|
||||
// Description: Traverses from the next node with the given
|
||||
// data, which has been constructed with the node but
|
||||
// has not yet been converted into the node's space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpCullTraverser::
|
||||
traverse(PandaNode *node, const CullTraverserData &data) {
|
||||
traverse(CullTraverserData &data) {
|
||||
// Most nodes will have no transform or state, and will not
|
||||
// contain decals or require a special cull callback. As an
|
||||
// optimization, we should tag nodes with these properties as
|
||||
// being "fancy", and skip this processing for non-fancy nodes.
|
||||
if (data.is_in_view(_camera_mask)) {
|
||||
data.apply_transform_and_state(this);
|
||||
|
||||
if (node->get_transform()->is_invalid()) {
|
||||
// If the transform is invalid, forget it.
|
||||
return;
|
||||
}
|
||||
|
||||
CullTraverserData next_data(data);
|
||||
if (next_data.is_in_view(node, _camera_mask)) {
|
||||
next_data.apply_transform_and_state(this, node);
|
||||
|
||||
PandaNode *node = data.node();
|
||||
if (node->has_cull_callback()) {
|
||||
if (!node->cull_callback(this, next_data)) {
|
||||
if (!node->cull_callback(this, data)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
traverse_below(node, next_data);
|
||||
traverse_below(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,10 +109,11 @@ traverse(PandaNode *node, const CullTraverserData &data) {
|
|||
// node's space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpCullTraverser::
|
||||
traverse_below(PandaNode *node, const CullTraverserData &data) {
|
||||
traverse_below(const CullTraverserData &data) {
|
||||
PandaNode *node = data.node();
|
||||
const RenderEffects *node_effects = node->get_effects();
|
||||
if (node_effects->has_decal()) {
|
||||
start_decal(node, data);
|
||||
start_decal(data);
|
||||
|
||||
} else {
|
||||
if (node->is_geom_node()) {
|
||||
|
|
@ -139,13 +135,15 @@ traverse_below(PandaNode *node, const CullTraverserData &data) {
|
|||
if (node->has_selective_visibility()) {
|
||||
int i = node->get_first_visible_child();
|
||||
while (i < num_children) {
|
||||
traverse(node->get_child(i), data);
|
||||
CullTraverserData next_data(data, node->get_child(i));
|
||||
traverse(next_data);
|
||||
i = node->get_next_visible_child(i);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
traverse(node->get_child(i), data);
|
||||
CullTraverserData next_data(data, node->get_child(i));
|
||||
traverse(next_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -159,7 +157,8 @@ traverse_below(PandaNode *node, const CullTraverserData &data) {
|
|||
// to find all the decal geoms.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpCullTraverser::
|
||||
start_decal(PandaNode *node, const CullTraverserData &data) {
|
||||
start_decal(const CullTraverserData &data) {
|
||||
PandaNode *node = data.node();
|
||||
if (!node->is_geom_node()) {
|
||||
pgraph_cat.error()
|
||||
<< "DecalEffect applied to " << *node << ", not a GeomNode.\n";
|
||||
|
|
@ -179,13 +178,15 @@ start_decal(PandaNode *node, const CullTraverserData &data) {
|
|||
if (node->has_selective_visibility()) {
|
||||
int i = node->get_first_visible_child();
|
||||
while (i < num_children) {
|
||||
decals = r_get_decals(cr.get_child(i), data, decals);
|
||||
CullTraverserData next_data(data, cr.get_child(i));
|
||||
decals = r_get_decals(next_data, decals);
|
||||
i = node->get_next_visible_child(i);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (int i = num_children - 1; i >= 0; i--) {
|
||||
decals = r_get_decals(cr.get_child(i), data, decals);
|
||||
CullTraverserData next_data(data, cr.get_child(i));
|
||||
decals = r_get_decals(next_data, decals);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -219,30 +220,26 @@ start_decal(PandaNode *node, const CullTraverserData &data) {
|
|||
// they were encountered in the scene graph).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CullableObject *qpCullTraverser::
|
||||
r_get_decals(PandaNode *node, const CullTraverserData &data,
|
||||
CullableObject *decals) {
|
||||
if (node->get_transform()->is_invalid()) {
|
||||
// If the transform is invalid, forget it.
|
||||
return decals;
|
||||
}
|
||||
r_get_decals(CullTraverserData &data, CullableObject *decals) {
|
||||
if (data.is_in_view(_camera_mask)) {
|
||||
data.apply_transform_and_state(this);
|
||||
|
||||
CullTraverserData next_data(data);
|
||||
if (next_data.is_in_view(node, _camera_mask)) {
|
||||
next_data.apply_transform_and_state(this, node);
|
||||
PandaNode *node = data.node();
|
||||
|
||||
// First, visit all of the node's children.
|
||||
PandaNode::Children cr = node->get_children();
|
||||
int num_children = cr.get_num_children();
|
||||
int num_children = node->get_num_children();
|
||||
if (node->has_selective_visibility()) {
|
||||
int i = node->get_first_visible_child();
|
||||
while (i < num_children) {
|
||||
decals = r_get_decals(cr.get_child(i), next_data, decals);
|
||||
CullTraverserData next_data(data, node->get_child(i));
|
||||
decals = r_get_decals(next_data, decals);
|
||||
i = node->get_next_visible_child(i);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (int i = num_children - 1; i >= 0; i--) {
|
||||
decals = r_get_decals(cr.get_child(i), next_data, decals);
|
||||
CullTraverserData next_data(data, node->get_child(i));
|
||||
decals = r_get_decals(next_data, decals);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -252,7 +249,7 @@ r_get_decals(PandaNode *node, const CullTraverserData &data,
|
|||
|
||||
int num_geoms = geom_node->get_num_geoms();
|
||||
for (int i = num_geoms - 1; i >= 0; i--) {
|
||||
decals = new CullableObject(next_data, geom_node, i, decals);
|
||||
decals = new CullableObject(data, geom_node, i, decals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class PandaNode;
|
|||
class CullHandler;
|
||||
class CullTraverserData;
|
||||
class CullableObject;
|
||||
class qpNodePath;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CullTraverser
|
||||
|
|
@ -67,14 +68,13 @@ public:
|
|||
INLINE void set_cull_handler(CullHandler *cull_handler);
|
||||
INLINE CullHandler *get_cull_handler() const;
|
||||
|
||||
void traverse(PandaNode *root);
|
||||
void traverse(PandaNode *node, const CullTraverserData &data);
|
||||
void traverse_below(PandaNode *node, const CullTraverserData &data);
|
||||
void traverse(qpNodePath &root);
|
||||
void traverse(CullTraverserData &data);
|
||||
void traverse_below(const CullTraverserData &data);
|
||||
|
||||
private:
|
||||
void start_decal(PandaNode *node, const CullTraverserData &data);
|
||||
CullableObject *r_get_decals(PandaNode *node,
|
||||
const CullTraverserData &data,
|
||||
void start_decal(const CullTraverserData &data);
|
||||
CullableObject *r_get_decals(CullTraverserData &data,
|
||||
CullableObject *decals);
|
||||
|
||||
CPT(RenderState) _initial_state;
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ write_geoms(ostream &out, int indent_level) const {
|
|||
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||
const GeomEntry &entry = (*gi);
|
||||
indent(out, indent_level + 2)
|
||||
<< *entry._geom << " (" << *entry._state << ")\n";
|
||||
<< *entry._geom << " " << *entry._state << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,7 +253,7 @@ write_verbose(ostream &out, int indent_level) const {
|
|||
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||
const GeomEntry &entry = (*gi);
|
||||
indent(out, indent_level + 2)
|
||||
<< *entry._geom << " (" << *entry._state << ")\n";
|
||||
<< *entry._geom << " " << *entry._state << "\n";
|
||||
entry._geom->write_verbose(out, indent_level + 4);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,5 +63,8 @@ operator < (const qpGeomTransformer::SourceTexCoords &other) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomTransformer::SourceColors::
|
||||
operator < (const qpGeomTransformer::SourceColors &other) const {
|
||||
if (_colors != other._colors) {
|
||||
return _colors < other._colors;
|
||||
}
|
||||
return (_scale.compare_to(other._scale) < 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -296,6 +296,7 @@ transform_colors(Geom *geom, const LVecBase4f &scale) {
|
|||
// transformed this array?
|
||||
SourceColors sc;
|
||||
sc._scale = scale;
|
||||
sc._colors = colors;
|
||||
|
||||
PTA_Colorf &new_colors = _tcolors[sc];
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,21 @@ make_copy() const {
|
|||
return new qpLODNode(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpLODNode::safe_to_combine
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if it is generally safe to combine this
|
||||
// particular kind of PandaNode with other kinds of
|
||||
// PandaNodes, adding children or whatever. For
|
||||
// instance, an LODNode should not be combined with any
|
||||
// other PandaNode, because its set of children is
|
||||
// meaningful.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpLODNode::
|
||||
safe_to_combine() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpLODNode::xform
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ protected:
|
|||
INLINE qpLODNode(const qpLODNode ©);
|
||||
public:
|
||||
virtual PandaNode *make_copy() const;
|
||||
virtual bool safe_to_combine() const;
|
||||
virtual void xform(const LMatrix4f &mat);
|
||||
virtual bool has_cull_callback() const;
|
||||
virtual bool cull_callback(qpCullTraverser *trav, CullTraverserData &data);
|
||||
|
|
|
|||
|
|
@ -65,6 +65,21 @@ safe_to_transform() const {
|
|||
return !_preserve_transform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpModelNode::safe_to_combine
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if it is generally safe to combine this
|
||||
// particular kind of PandaNode with other kinds of
|
||||
// PandaNodes, adding children or whatever. For
|
||||
// instance, an LODNode should not be combined with any
|
||||
// other PandaNode, because its set of children is
|
||||
// meaningful.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpModelNode::
|
||||
safe_to_combine() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpModelNode::preserve_name
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ public:
|
|||
|
||||
virtual bool safe_to_flatten() const;
|
||||
virtual bool safe_to_transform() const;
|
||||
virtual bool safe_to_combine() const;
|
||||
virtual bool preserve_name() const;
|
||||
|
||||
PUBLISHED:
|
||||
|
|
|
|||
|
|
@ -597,34 +597,6 @@ get_mat() const {
|
|||
return node()->get_transform()->get_mat();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::has_color_scale
|
||||
// Access: Published
|
||||
// Description: Returns true if a color scale has been applied
|
||||
// to the referenced node, false otherwise. It is still
|
||||
// possible that color at this node might have been
|
||||
// scaled by an ancestor node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpNodePath::
|
||||
has_color_scale() const {
|
||||
nassertr(false, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::clear_color_scale
|
||||
// Access: Published
|
||||
// Description: Completely removes any color scale from the
|
||||
// referenced node. This is preferable to simply
|
||||
// setting the color scale to identity, as it also
|
||||
// removes the overhead associated with having a color
|
||||
// scale at all.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpNodePath::
|
||||
clear_color_scale() {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::set_color_scale
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -721,6 +721,35 @@ set_mat(const LMatrix4f &mat) {
|
|||
set_transform(TransformState::make_mat(mat));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::has_color_scale
|
||||
// Access: Published
|
||||
// Description: Returns true if a color scale has been applied
|
||||
// to the referenced node, false otherwise. It is still
|
||||
// possible that color at this node might have been
|
||||
// scaled by an ancestor node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpNodePath::
|
||||
has_color_scale() const {
|
||||
nassertr_always(!is_empty(), false);
|
||||
return node()->has_attrib(ColorScaleAttrib::get_class_type());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::clear_color_scale
|
||||
// Access: Published
|
||||
// Description: Completely removes any color scale from the
|
||||
// referenced node. This is preferable to simply
|
||||
// setting the color scale to identity, as it also
|
||||
// removes the overhead associated with having a color
|
||||
// scale at all.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePath::
|
||||
clear_color_scale() {
|
||||
nassertv_always(!is_empty());
|
||||
node()->clear_attrib(ColorScaleAttrib::get_class_type());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::set_color_scale
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -284,9 +284,8 @@ PUBLISHED:
|
|||
INLINE bool has_mat() const;
|
||||
INLINE const LMatrix4f &get_mat() const;
|
||||
|
||||
INLINE bool has_color_scale() const;
|
||||
INLINE void clear_color_scale();
|
||||
|
||||
bool has_color_scale() const;
|
||||
void clear_color_scale();
|
||||
void set_color_scale(const LVecBase4f &scale);
|
||||
INLINE void set_color_scale(float sx, float sy, float sz, float sa);
|
||||
INLINE void set_sr(float sr);
|
||||
|
|
|
|||
|
|
@ -23,8 +23,10 @@
|
|||
#include "colorScaleAttrib.h"
|
||||
|
||||
#include "qpgeomNode.h"
|
||||
#include "pointerTo.h"
|
||||
#include "geom.h"
|
||||
#include "indent.h"
|
||||
#include "plist.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpSceneGraphReducer::AccumulatedAttribs::write
|
||||
|
|
@ -487,7 +489,9 @@ r_flatten(PandaNode *grandparent_node, PandaNode *parent_node,
|
|||
// saved above is no longer accurate, so hereafter we must ask the
|
||||
// node for its real child list.
|
||||
if (combine_siblings && parent_node->get_num_children() >= 2) {
|
||||
num_nodes += flatten_siblings(parent_node);
|
||||
if (parent_node->safe_to_combine()) {
|
||||
num_nodes += flatten_siblings(parent_node);
|
||||
}
|
||||
}
|
||||
|
||||
if (parent_node->get_num_children() == 1) {
|
||||
|
|
@ -646,7 +650,7 @@ consider_child(PandaNode *grandparent_node, PandaNode *parent_node,
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpSceneGraphReducer::consider_siblings
|
||||
// Function: qpSceneGraphReducer:c:onsider_siblings
|
||||
// Access: Protected, Virtual
|
||||
// Description: Decides whether or not the indicated sibling nodes
|
||||
// should be collapsed into a single node or not.
|
||||
|
|
|
|||
|
|
@ -32,6 +32,21 @@ make_copy() const {
|
|||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpSequenceNode::safe_to_combine
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if it is generally safe to combine this
|
||||
// particular kind of PandaNode with other kinds of
|
||||
// PandaNodes, adding children or whatever. For
|
||||
// instance, an LODNode should not be combined with any
|
||||
// other PandaNode, because its set of children is
|
||||
// meaningful.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpSequenceNode::
|
||||
safe_to_combine() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpSequenceNode::CData::write_datagram
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ public:
|
|||
qpSequenceNode(const qpSequenceNode ©);
|
||||
|
||||
virtual PandaNode *make_copy() const;
|
||||
virtual bool safe_to_combine() const;
|
||||
|
||||
virtual bool has_cull_callback() const;
|
||||
virtual bool cull_callback(qpCullTraverser *trav, CullTraverserData &data);
|
||||
|
|
|
|||
|
|
@ -70,3 +70,13 @@ get_node_path() const {
|
|||
nassertr(result._head != (qpNodePathComponent *)NULL, qpNodePath::fail());
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WorkingNodePath::node
|
||||
// Access: Public
|
||||
// Description: Returns the node traversed to so far.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *WorkingNodePath::
|
||||
node() const {
|
||||
return _node;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public:
|
|||
INLINE ~WorkingNodePath();
|
||||
|
||||
INLINE qpNodePath get_node_path() const;
|
||||
INLINE PandaNode *node() const;
|
||||
|
||||
private:
|
||||
PT(qpNodePathComponent) r_get_node_path() const;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "pandaNode.h"
|
||||
#include "transparencyAttrib.h"
|
||||
#include "pointerTo.h"
|
||||
#include "qpnodePath.h"
|
||||
|
||||
#include "geomNode.h"
|
||||
#include "transparencyProperty.h"
|
||||
|
|
@ -168,16 +169,16 @@ generate_into(Node *node, const LVecBase4f &frame) {
|
|||
// indicated size, and parents it to the indicated node,
|
||||
// with a scene graph sort order of -1.
|
||||
//
|
||||
// The return value is the generated node, if any, or
|
||||
// NULL if nothing is generated.
|
||||
// The return value is the generated NodePath, if any,
|
||||
// or an empty NodePath if nothing is generated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *PGFrameStyle::
|
||||
generate_into(PandaNode *node, const LVecBase4f &frame) {
|
||||
qpNodePath PGFrameStyle::
|
||||
generate_into(const qpNodePath &parent, const LVecBase4f &frame) {
|
||||
PT(PandaNode) new_node;
|
||||
|
||||
switch (_type) {
|
||||
case T_none:
|
||||
return (PandaNode *)NULL;
|
||||
return qpNodePath();
|
||||
|
||||
case T_flat:
|
||||
new_node = qpgenerate_flat_geom(frame);
|
||||
|
|
@ -209,8 +210,7 @@ generate_into(PandaNode *node, const LVecBase4f &frame) {
|
|||
}
|
||||
|
||||
// Adding the node to the parent keeps the reference count.
|
||||
node->add_child(new_node);
|
||||
return new_node;
|
||||
return parent.attach_new_node(new_node);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
class NodeRelation;
|
||||
class Node;
|
||||
class PandaNode;
|
||||
class qpNodePath;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PGFrameStyle
|
||||
|
|
@ -65,7 +66,7 @@ PUBLISHED:
|
|||
public:
|
||||
bool xform(const LMatrix4f &mat);
|
||||
NodeRelation *generate_into(Node *node, const LVecBase4f &frame);
|
||||
PandaNode *generate_into(PandaNode *node, const LVecBase4f &frame);
|
||||
qpNodePath generate_into(const qpNodePath &parent, const LVecBase4f &frame);
|
||||
|
||||
private:
|
||||
PT_Node generate_flat_geom(const LVecBase4f &frame);
|
||||
|
|
|
|||
|
|
@ -186,10 +186,10 @@ setup(const string &label) {
|
|||
PT(PandaNode) rollover = new PandaNode("rollover");
|
||||
PT(PandaNode) inactive = new PandaNode("inactive");
|
||||
|
||||
get_state_def(S_ready)->add_child(ready);
|
||||
get_state_def(S_depressed)->add_child(depressed);
|
||||
get_state_def(S_rollover)->add_child(rollover);
|
||||
get_state_def(S_inactive)->add_child(inactive);
|
||||
get_state_def(S_ready).attach_new_node(ready);
|
||||
get_state_def(S_depressed).attach_new_node(depressed);
|
||||
get_state_def(S_rollover).attach_new_node(rollover);
|
||||
get_state_def(S_inactive).attach_new_node(inactive);
|
||||
|
||||
ready->add_child(geom);
|
||||
depressed->add_child(geom);
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ get_blink_rate() const {
|
|||
// the cursor. You can attach suitable cursor geometry
|
||||
// to this node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *qpPGEntry::
|
||||
INLINE const qpNodePath &qpPGEntry::
|
||||
get_cursor_def() {
|
||||
return _cursor_def;
|
||||
}
|
||||
|
|
@ -204,7 +204,8 @@ get_cursor_def() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpPGEntry::
|
||||
clear_cursor_def() {
|
||||
get_cursor_def()->remove_all_children();
|
||||
_cursor_def.remove_node();
|
||||
_cursor_def = _text_render_root.attach_new_node("cursor");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "pgMouseWatcherParameter.h"
|
||||
|
||||
#include "qpcullTraverser.h"
|
||||
#include "cullTraverserData.h"
|
||||
#include "throw_event.h"
|
||||
#include "transformState.h"
|
||||
#include "mouseWatcherParameter.h"
|
||||
|
|
@ -50,10 +51,8 @@ qpPGEntry(const string &name) :
|
|||
_blink_start = 0.0f;
|
||||
_blink_rate = 1.0f;
|
||||
|
||||
_text_render_root = new PandaNode("text_root");
|
||||
_current_text_node = (PandaNode *)NULL;
|
||||
_cursor_def = new PandaNode("cursor");
|
||||
_text_render_root->add_child(_cursor_def);
|
||||
_text_render_root = qpNodePath("text_root");
|
||||
_cursor_def = _text_render_root.attach_new_node("cursor");
|
||||
_cursor_visible = true;
|
||||
|
||||
_cursor_keys_active = true;
|
||||
|
|
@ -149,8 +148,8 @@ cull_callback(qpCullTraverser *trav, CullTraverserData &data) {
|
|||
update_cursor();
|
||||
|
||||
// Now render the text.
|
||||
nassertr(_text_render_root != (PandaNode *)NULL, true);
|
||||
trav->traverse(_text_render_root, data);
|
||||
CullTraverserData next_data(data, _text_render_root.node());
|
||||
trav->traverse(next_data);
|
||||
|
||||
// Now continue to render everything else below this node.
|
||||
return true;
|
||||
|
|
@ -596,12 +595,12 @@ setup(float width, int num_lines) {
|
|||
ls.set_color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
ls.move_to(0.0f, 0.0f, -0.15f * line_height);
|
||||
ls.draw_to(0.0f, 0.0f, 0.85f * line_height);
|
||||
get_cursor_def()->add_child(ls.create());
|
||||
get_cursor_def().attach_new_node(ls.create());
|
||||
|
||||
/*
|
||||
// An underscore cursor would work too.
|
||||
text_node->set_text("_");
|
||||
get_cursor_def()->add_child(text_node->generate());
|
||||
get_cursor_def().attach_new_node(text_node->generate());
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
@ -782,11 +781,11 @@ update_text() {
|
|||
line._left = _last_text_def->get_left();
|
||||
}
|
||||
|
||||
if (_current_text_node != (PandaNode *)NULL) {
|
||||
_text_render_root->remove_child(_current_text_node);
|
||||
if (!_current_text.is_empty()) {
|
||||
_current_text.remove_node();
|
||||
}
|
||||
_current_text_node = _last_text_def->generate();
|
||||
_text_render_root->add_child(_current_text_node);
|
||||
_current_text =
|
||||
_text_render_root.attach_new_node(_last_text_def->generate());
|
||||
_text_geom_stale = false;
|
||||
_cursor_stale = true;
|
||||
}
|
||||
|
|
@ -824,7 +823,7 @@ update_cursor() {
|
|||
float line_height = _last_text_def->get_line_height();
|
||||
|
||||
LVecBase3f trans(_ww_lines[row]._left + width, 0.0f, -line_height * row);
|
||||
_cursor_def->set_transform(TransformState::make_pos(trans));
|
||||
_cursor_def.set_pos(trans);
|
||||
|
||||
_cursor_stale = false;
|
||||
}
|
||||
|
|
@ -851,11 +850,9 @@ void qpPGEntry::
|
|||
show_hide_cursor(bool visible) {
|
||||
if (visible != _cursor_visible) {
|
||||
if (visible) {
|
||||
// Reveal the cursor.
|
||||
_cursor_def->set_draw_mask(DrawMask::all_on());
|
||||
_cursor_def.show();
|
||||
} else {
|
||||
// Hide the cursor.
|
||||
_cursor_def->set_draw_mask(DrawMask::all_off());
|
||||
_cursor_def.hide();
|
||||
}
|
||||
_cursor_visible = visible;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ PUBLISHED:
|
|||
INLINE void set_blink_rate(float blink_rate);
|
||||
INLINE float get_blink_rate() const;
|
||||
|
||||
INLINE PandaNode *get_cursor_def();
|
||||
INLINE const qpNodePath &get_cursor_def();
|
||||
INLINE void clear_cursor_def();
|
||||
|
||||
INLINE void set_cursor_keys_active(bool flag);
|
||||
|
|
@ -139,13 +139,12 @@ private:
|
|||
typedef pvector< PT(qpTextNode) > TextDefs;
|
||||
TextDefs _text_defs;
|
||||
|
||||
// This node is the root of the subgraph that renders both the text
|
||||
// and the cursor.
|
||||
PT(PandaNode) _text_render_root;
|
||||
// This is the subgraph that renders both the text and the cursor.
|
||||
qpNodePath _text_render_root;
|
||||
|
||||
// This is the node for rendering the actual text that is parented
|
||||
// to the above node when the text is generated.
|
||||
PT(PandaNode) _current_text_node;
|
||||
qpNodePath _current_text;
|
||||
qpTextNode *_last_text_def;
|
||||
bool _text_geom_stale;
|
||||
|
||||
|
|
@ -163,7 +162,7 @@ private:
|
|||
// This is the node that represents the cursor geometry. It is also
|
||||
// attached to the above node, and is transformed around and/or
|
||||
// hidden according to the cursor's position and blink state.
|
||||
PandaNode *_cursor_def;
|
||||
qpNodePath _cursor_def;
|
||||
|
||||
double _blink_start;
|
||||
double _blink_rate;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "string_utils.h"
|
||||
#include "qpnodePath.h"
|
||||
#include "qpcullTraverser.h"
|
||||
#include "cullTraverserData.h"
|
||||
|
||||
#ifdef HAVE_AUDIO
|
||||
#include "audioSound.h"
|
||||
|
|
@ -118,15 +119,13 @@ xform(const LMatrix4f &mat) {
|
|||
// Transform the individual states and their frame styles.
|
||||
StateDefs::iterator di;
|
||||
for (di = _state_defs.begin(); di != _state_defs.end(); ++di) {
|
||||
PandaNode *node = (*di)._node;
|
||||
if (node != (PandaNode *)NULL) {
|
||||
// Apply the matrix to the previous transform.
|
||||
node->set_transform(node->get_transform()->compose(TransformState::make_mat(mat)));
|
||||
qpNodePath &root = (*di)._root;
|
||||
// Apply the matrix to the previous transform.
|
||||
root.set_transform(root.get_transform()->compose(TransformState::make_mat(mat)));
|
||||
|
||||
// Now flatten the transform into the subgraph.
|
||||
qpSceneGraphReducer gr;
|
||||
gr.apply_attribs(node);
|
||||
}
|
||||
// Now flatten the transform into the subgraph.
|
||||
qpSceneGraphReducer gr;
|
||||
gr.apply_attribs(root.node());
|
||||
|
||||
// Transform the frame style too.
|
||||
if ((*di)._frame_style.xform(mat)) {
|
||||
|
|
@ -193,8 +192,9 @@ cull_callback(qpCullTraverser *trav, CullTraverserData &data) {
|
|||
if (has_state_def(get_state())) {
|
||||
// This item has a current state definition that we should use
|
||||
// to render the item.
|
||||
PandaNode *def = get_state_def(get_state());
|
||||
trav->traverse(def, data);
|
||||
qpNodePath &root = get_state_def(get_state());
|
||||
CullTraverserData next_data(data, root.node());
|
||||
trav->traverse(next_data);
|
||||
}
|
||||
|
||||
// Now continue to render everything else below this node.
|
||||
|
|
@ -223,9 +223,9 @@ recompute_internal_bound() {
|
|||
// get_state_def() on each one, to ensure that the frames are
|
||||
// updated correctly before we measure their bounding volumes.
|
||||
for (int i = 0; i < (int)_state_defs.size(); i++) {
|
||||
PandaNode *node = get_state_def(i);
|
||||
if (node != (PandaNode *)NULL) {
|
||||
child_volumes.push_back(&node->get_bound());
|
||||
qpNodePath &root = get_state_def(i);
|
||||
if (!root.is_empty()) {
|
||||
child_volumes.push_back(&root.node()->get_bound());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -582,7 +582,7 @@ has_state_def(int state) const {
|
|||
if (state < 0 || state >= (int)_state_defs.size()) {
|
||||
return false;
|
||||
}
|
||||
return (_state_defs[state]._node != (PandaNode *)NULL);
|
||||
return (!_state_defs[state]._root.is_empty());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -598,12 +598,8 @@ clear_state_def(int state) {
|
|||
return;
|
||||
}
|
||||
|
||||
PandaNode *node = _state_defs[state]._node;
|
||||
if (node != (PandaNode *)NULL) {
|
||||
node->remove_all_children();
|
||||
}
|
||||
|
||||
_state_defs[state]._frame_node = (PandaNode *)NULL;
|
||||
_state_defs[state]._root = qpNodePath();
|
||||
_state_defs[state]._frame = qpNodePath();
|
||||
_state_defs[state]._frame_stale = true;
|
||||
|
||||
mark_bound_stale();
|
||||
|
|
@ -617,14 +613,14 @@ clear_state_def(int state) {
|
|||
// indicated state. The first time this is called for a
|
||||
// particular state index, it may create the Node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *qpPGItem::
|
||||
qpNodePath &qpPGItem::
|
||||
get_state_def(int state) {
|
||||
nassertr(state >= 0 && state < 1000, (PandaNode *)NULL); // Sanity check.
|
||||
nassertr(state >= 0 && state < 1000, get_state_def(0)); // Sanity check.
|
||||
slot_state_def(state);
|
||||
|
||||
if (_state_defs[state]._node == (PandaNode *)NULL) {
|
||||
if (_state_defs[state]._root.is_empty()) {
|
||||
// Create a new node.
|
||||
_state_defs[state]._node = new PandaNode("state_" + format_string(state));
|
||||
_state_defs[state]._root = qpNodePath("state_" + format_string(state));
|
||||
_state_defs[state]._frame_stale = true;
|
||||
}
|
||||
|
||||
|
|
@ -632,7 +628,7 @@ get_state_def(int state) {
|
|||
update_frame(state);
|
||||
}
|
||||
|
||||
return _state_defs[state]._node;
|
||||
return _state_defs[state]._root;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -641,16 +637,16 @@ get_state_def(int state) {
|
|||
// Description: Parents an instance of the bottom node of the
|
||||
// indicated NodePath to the indicated state index.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpPGItem::
|
||||
qpNodePath qpPGItem::
|
||||
instance_to_state_def(int state, const qpNodePath &path) {
|
||||
if (path.is_empty()) {
|
||||
// If the path is empty, quietly do nothing.
|
||||
return;
|
||||
// If the source is empty, quietly do nothing.
|
||||
return qpNodePath();
|
||||
}
|
||||
|
||||
get_state_def(state)->add_child(path.node());
|
||||
|
||||
mark_bound_stale();
|
||||
|
||||
return path.instance_to(get_state_def(state));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -677,8 +673,8 @@ void qpPGItem::
|
|||
set_frame_style(int state, const PGFrameStyle &style) {
|
||||
// Get the state def node, mainly to ensure that this state is
|
||||
// slotted and listed as having been defined.
|
||||
PandaNode *def = get_state_def(state);
|
||||
nassertv(def != (PandaNode *)NULL);
|
||||
qpNodePath &root = get_state_def(state);
|
||||
nassertv(!root.is_empty());
|
||||
|
||||
_state_defs[state]._frame_style = style;
|
||||
_state_defs[state]._frame_stale = true;
|
||||
|
|
@ -799,13 +795,7 @@ void qpPGItem::
|
|||
update_frame(int state) {
|
||||
// First, remove the old frame geometry, if any.
|
||||
if (state >= 0 && state < (int)_state_defs.size()) {
|
||||
PandaNode *old_frame = _state_defs[state]._frame_node;
|
||||
if (old_frame != (PandaNode *)NULL) {
|
||||
PandaNode *node = _state_defs[state]._node;
|
||||
nassertv(node != (PandaNode *)NULL);
|
||||
node->remove_child(old_frame);
|
||||
_state_defs[state]._frame_node = (PandaNode *)NULL;
|
||||
}
|
||||
_state_defs[state]._frame.remove_node();
|
||||
}
|
||||
|
||||
// We must turn off the stale flag first, before we call
|
||||
|
|
@ -815,10 +805,9 @@ update_frame(int state) {
|
|||
|
||||
// Now create new frame geometry.
|
||||
if (has_frame()) {
|
||||
PandaNode *node = get_state_def(state);
|
||||
nassertv(node != (PandaNode *)NULL);
|
||||
_state_defs[state]._frame_node =
|
||||
_state_defs[state]._frame_style.generate_into(node, _frame);
|
||||
qpNodePath &root = get_state_def(state);
|
||||
_state_defs[state]._frame =
|
||||
_state_defs[state]._frame_style.generate_into(root, _frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -834,14 +823,7 @@ mark_frames_stale() {
|
|||
StateDefs::iterator di;
|
||||
for (di = _state_defs.begin(); di != _state_defs.end(); ++di) {
|
||||
// Remove the old frame, if any.
|
||||
PandaNode *old_frame = (*di)._frame_node;
|
||||
if (old_frame != (PandaNode *)NULL) {
|
||||
PandaNode *node = (*di)._node;
|
||||
nassertv(node != (PandaNode *)NULL);
|
||||
node->remove_child(old_frame);
|
||||
(*di)._frame_node = (PandaNode *)NULL;
|
||||
}
|
||||
|
||||
(*di)._frame.remove_node();
|
||||
(*di)._frame_stale = true;
|
||||
}
|
||||
mark_bound_stale();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "pgFrameStyle.h"
|
||||
|
||||
#include "pandaNode.h"
|
||||
#include "qpnodePath.h"
|
||||
#include "luse.h"
|
||||
#include "pointerTo.h"
|
||||
#include "qptextNode.h"
|
||||
|
|
@ -34,7 +35,6 @@
|
|||
class PGTop;
|
||||
class MouseWatcherParameter;
|
||||
class AudioSound;
|
||||
class qpNodePath;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpPGItem
|
||||
|
|
@ -108,8 +108,8 @@ PUBLISHED:
|
|||
int get_num_state_defs() const;
|
||||
void clear_state_def(int state);
|
||||
bool has_state_def(int state) const;
|
||||
PandaNode *get_state_def(int state);
|
||||
void instance_to_state_def(int state, const qpNodePath &chain);
|
||||
qpNodePath &get_state_def(int state);
|
||||
qpNodePath instance_to_state_def(int state, const qpNodePath &path);
|
||||
|
||||
PGFrameStyle get_frame_style(int state);
|
||||
void set_frame_style(int state, const PGFrameStyle &style);
|
||||
|
|
@ -171,9 +171,9 @@ private:
|
|||
|
||||
class StateDef {
|
||||
public:
|
||||
PT(PandaNode) _node;
|
||||
qpNodePath _root;
|
||||
PGFrameStyle _frame_style;
|
||||
PT(PandaNode) _frame_node;
|
||||
qpNodePath _frame;
|
||||
bool _frame_stale;
|
||||
};
|
||||
typedef pvector<StateDef> StateDefs;
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ cull_callback(qpCullTraverser *trav, CullTraverserData &data) {
|
|||
// PGTop node, for the convenience of PGItems to register themselves
|
||||
// as they are drawn.
|
||||
PGCullTraverser pg_trav(this, trav);
|
||||
pg_trav.traverse_below(this, data);
|
||||
pg_trav.traverse_below(data);
|
||||
|
||||
// We've taken care of the traversal, thank you.
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ qpPGWaitBar(const string &name) : qpPGItem(name)
|
|||
_range = 100.0;
|
||||
_value = 0.0;
|
||||
_bar_state = -1;
|
||||
_bar_node = (PandaNode *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -58,7 +57,6 @@ qpPGWaitBar(const qpPGWaitBar ©) :
|
|||
_value(copy._value)
|
||||
{
|
||||
_bar_state = -1;
|
||||
_bar_node = (PandaNode *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -155,16 +153,12 @@ update() {
|
|||
}
|
||||
|
||||
// Remove the old bar geometry, if any.
|
||||
if (_bar_node != (PandaNode *)NULL) {
|
||||
PandaNode *parent_node = _bar_node->get_parent(0);
|
||||
parent_node->remove_child(_bar_node);
|
||||
_bar_node = (PandaNode *)NULL;
|
||||
}
|
||||
_bar.remove_node();
|
||||
|
||||
// Now create new bar geometry.
|
||||
if (_value != 0.0 && _range != 0.0) {
|
||||
PandaNode *node = get_state_def(state);
|
||||
nassertv(node != (PandaNode *)NULL);
|
||||
qpNodePath &root = get_state_def(state);
|
||||
nassertv(!root.is_empty());
|
||||
|
||||
PGFrameStyle style = get_frame_style(state);
|
||||
const LVecBase4f &frame = get_frame();
|
||||
|
|
@ -181,7 +175,7 @@ update() {
|
|||
frac = max(min(frac, 1.0f), 0.0f);
|
||||
bar_frame[1] = bar_frame[0] + frac * (bar_frame[1] - bar_frame[0]);
|
||||
|
||||
_bar_node = _bar_style.generate_into(node, bar_frame);
|
||||
_bar = _bar_style.generate_into(root, bar_frame);
|
||||
}
|
||||
|
||||
// Indicate that the bar is current for this state.
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ private:
|
|||
float _range, _value;
|
||||
int _bar_state;
|
||||
PGFrameStyle _bar_style;
|
||||
PT(PandaNode) _bar_node;
|
||||
qpNodePath _bar;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue