diff --git a/panda/src/pgraph/cullTraverser.cxx b/panda/src/pgraph/cullTraverser.cxx index 6cdb419f07..aa1979f1b1 100644 --- a/panda/src/pgraph/cullTraverser.cxx +++ b/panda/src/pgraph/cullTraverser.cxx @@ -115,7 +115,7 @@ traverse(const NodePath &root, bool python_cull_control) { CullTraverserData data(root, TransformState::make_identity(), _initial_state, _view_frustum, - _guard_band); + _guard_band, _current_thread); traverse(data); @@ -133,7 +133,7 @@ traverse(const NodePath &root, bool python_cull_control) { } else { CullTraverserData data(root, TransformState::make_identity(), _initial_state, _view_frustum, - _guard_band); + _guard_band, _current_thread); traverse(data); } @@ -153,16 +153,17 @@ traverse(CullTraverserData &data) { // 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, _current_thread)) { + if (data.is_in_view(_camera_mask)) { if (pgraph_cat.is_spam()) { pgraph_cat.spam() << "\n" << data._node_path << " " << data._draw_mask << "\n"; } + PandaNodePipelineReader *node_reader = data.node_reader(); PandaNode *node = data.node(); - const RenderEffects *node_effects = node->get_effects(_current_thread); + const RenderEffects *node_effects = node_reader->get_effects(); if (node_effects->has_show_bounds()) { // If we should show the bounding volume for this node, make it // up now. @@ -171,7 +172,7 @@ traverse(CullTraverserData &data) { data.apply_transform_and_state(this); - const FogAttrib *fog = node->get_state(_current_thread)->get_fog(); + const FogAttrib *fog = node_reader->get_state()->get_fog(); if (fog != (const FogAttrib *)NULL && fog->get_fog() != (Fog *)NULL) { // If we just introduced a FogAttrib here, call adjust_to_camera() // now. This maybe isn't the perfect time to call it, but it's @@ -200,11 +201,12 @@ traverse(CullTraverserData &data) { void CullTraverser:: traverse_below(CullTraverserData &data) { _nodes_pcollector.add_level(1); + PandaNodePipelineReader *node_reader = data.node_reader(); PandaNode *node = data.node(); bool this_node_hidden = data.is_this_node_hidden(this); - const RenderEffects *node_effects = node->get_effects(_current_thread); + const RenderEffects *node_effects = node_reader->get_effects(); bool has_decal = !this_node_hidden && node_effects->has_decal(); if (has_decal && !_depth_offset_decals) { // Start the three-pass decal rendering if we're not using @@ -252,7 +254,8 @@ traverse_below(CullTraverserData &data) { } // Now visit all the node's children. - PandaNode::Children children = node->get_children(_current_thread); + PandaNode::Children children = node_reader->get_children(); + node_reader->release(); int num_children = children.get_num_children(); if (node->has_selective_visibility()) { int i = node->get_first_visible_child(); @@ -523,6 +526,8 @@ start_decal(const CullTraverserData &data) { return; } + const PandaNodePipelineReader *node_reader = data.node_reader(); + // Build a chain of CullableObjects. The head of the chain will be // all of the base Geoms in order, followed by an empty // CullableObject node, followed by all of the decal Geoms, in @@ -531,7 +536,7 @@ start_decal(const CullTraverserData &data) { // Since the CullableObject is a linked list which gets built in // LIFO order, we start with the decals. CullableObject *decals = (CullableObject *)NULL; - PandaNode::Children cr = node->get_children(_current_thread); + PandaNode::Children cr = node_reader->get_children(); int num_children = cr.get_num_children(); if (node->has_selective_visibility()) { int i = node->get_first_visible_child(); @@ -592,10 +597,11 @@ start_decal(const CullTraverserData &data) { //////////////////////////////////////////////////////////////////// CullableObject *CullTraverser:: r_get_decals(CullTraverserData &data, CullableObject *decals) { - if (data.is_in_view(_camera_mask, _current_thread)) { + if (data.is_in_view(_camera_mask)) { + PandaNodePipelineReader *node_reader = data.node_reader(); PandaNode *node = data.node(); - const RenderEffects *node_effects = node->get_effects(); + const RenderEffects *node_effects = node_reader->get_effects(); if (node_effects->has_show_bounds()) { // If we should show the bounding volume for this node, make it // up now. @@ -605,18 +611,18 @@ r_get_decals(CullTraverserData &data, CullableObject *decals) { data.apply_transform_and_state(this); // First, visit all of the node's children. - int num_children = node->get_num_children(); + int num_children = node_reader->get_num_children(); if (node->has_selective_visibility()) { int i = node->get_first_visible_child(); while (i < num_children) { - CullTraverserData next_data(data, node->get_child(i)); + CullTraverserData next_data(data, node_reader->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--) { - CullTraverserData next_data(data, node->get_child(i)); + CullTraverserData next_data(data, node_reader->get_child(i)); decals = r_get_decals(next_data, decals); } } diff --git a/panda/src/pgraph/cullTraverserData.I b/panda/src/pgraph/cullTraverserData.I index 30e2393178..c6e6aab6b8 100644 --- a/panda/src/pgraph/cullTraverserData.I +++ b/panda/src/pgraph/cullTraverserData.I @@ -26,8 +26,10 @@ CullTraverserData(const NodePath &start, const TransformState *net_transform, const RenderState *state, GeometricBoundingVolume *view_frustum, - GeometricBoundingVolume *guard_band) : + GeometricBoundingVolume *guard_band, + Thread *current_thread) : _node_path(start), + _node_reader(start.node(), current_thread), _net_transform(net_transform), _state(state), _view_frustum(view_frustum), @@ -35,6 +37,7 @@ CullTraverserData(const NodePath &start, _cull_planes(CullPlanes::make_empty()), _draw_mask(DrawMask::all_on()) { + _node_reader.check_bounds(); } //////////////////////////////////////////////////////////////////// @@ -45,6 +48,7 @@ CullTraverserData(const NodePath &start, INLINE CullTraverserData:: CullTraverserData(const CullTraverserData ©) : _node_path(copy._node_path), + _node_reader(copy._node_reader), _net_transform(copy._net_transform), _state(copy._state), _view_frustum(copy._view_frustum), @@ -62,6 +66,7 @@ CullTraverserData(const CullTraverserData ©) : INLINE void CullTraverserData:: operator = (const CullTraverserData ©) { _node_path = copy._node_path; + _node_reader = copy._node_reader; _net_transform = copy._net_transform; _state = copy._state; _view_frustum = copy._view_frustum; @@ -79,6 +84,7 @@ operator = (const CullTraverserData ©) { INLINE CullTraverserData:: CullTraverserData(const CullTraverserData &parent, PandaNode *child) : _node_path(parent._node_path, child), + _node_reader(child, parent._node_reader.get_current_thread()), _net_transform(parent._net_transform), _state(parent._state), _view_frustum(parent._view_frustum), @@ -86,6 +92,7 @@ CullTraverserData(const CullTraverserData &parent, PandaNode *child) : _cull_planes(parent._cull_planes), _draw_mask(parent._draw_mask) { + _node_reader.check_bounds(); } //////////////////////////////////////////////////////////////////// @@ -107,6 +114,28 @@ node() const { return _node_path.node(); } +//////////////////////////////////////////////////////////////////// +// Function: CullTraverserData::node_reader +// Access: Public +// Description: Returns the PipelineReader for the node traversed to +// so far. +//////////////////////////////////////////////////////////////////// +INLINE PandaNodePipelineReader *CullTraverserData:: +node_reader() { + return &_node_reader; +} + +//////////////////////////////////////////////////////////////////// +// Function: CullTraverserData::node_reader +// Access: Public +// Description: Returns the PipelineReader for the node traversed to +// so far. +//////////////////////////////////////////////////////////////////// +INLINE const PandaNodePipelineReader *CullTraverserData:: +node_reader() const { + return &_node_reader; +} + //////////////////////////////////////////////////////////////////// // Function: CullTraverserData::get_net_transform // Access: Public @@ -128,13 +157,13 @@ get_net_transform(const CullTraverser *) const { // work for future nodes. //////////////////////////////////////////////////////////////////// INLINE bool CullTraverserData:: -is_in_view(const DrawMask &camera_mask, Thread *current_thread) { - if (node()->get_transform(current_thread)->is_invalid()) { +is_in_view(const DrawMask &camera_mask) { + if (_node_reader.get_transform()->is_invalid()) { // If the transform is invalid, forget it. return false; } - if (!node()->compare_draw_mask(_draw_mask, camera_mask, current_thread)) { + if (!_node_reader.compare_draw_mask(_draw_mask, camera_mask)) { // If there are no draw bits in common with the camera, the node // is out. return false; @@ -148,7 +177,7 @@ is_in_view(const DrawMask &camera_mask, Thread *current_thread) { } // Otherwise, compare the bounding volume to the frustum. - return is_in_view_impl(current_thread); + return is_in_view_impl(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/cullTraverserData.cxx b/panda/src/pgraph/cullTraverserData.cxx index dbcda04aee..13dfa8aaa5 100644 --- a/panda/src/pgraph/cullTraverserData.cxx +++ b/panda/src/pgraph/cullTraverserData.cxx @@ -51,24 +51,22 @@ get_modelview_transform(const CullTraverser *trav) const { //////////////////////////////////////////////////////////////////// void CullTraverserData:: apply_transform_and_state(CullTraverser *trav) { - Thread *current_thread = trav->get_current_thread(); - PandaNode *node = _node_path.node(); - CPT(RenderState) node_state = node->get_state(current_thread); + CPT(RenderState) node_state = _node_reader.get_state(); if (trav->has_tag_state_key() && - node->has_tag(trav->get_tag_state_key(), current_thread)) { + _node_reader.has_tag(trav->get_tag_state_key())) { // Here's a node that has been tagged with the special key for our // current camera. This indicates some special state transition // for this node, which is unique to this camera. const Camera *camera = trav->get_scene()->get_camera_node(); - string tag_state = node->get_tag(trav->get_tag_state_key(), current_thread); + string tag_state = _node_reader.get_tag(trav->get_tag_state_key()); node_state = node_state->compose(camera->get_tag_state(tag_state)); } - node->compose_draw_mask(_draw_mask, current_thread); + _node_reader.compose_draw_mask(_draw_mask); - apply_transform_and_state(trav, node->get_transform(current_thread), - node_state, node->get_effects(current_thread), - node->get_off_clip_planes(current_thread)); + apply_transform_and_state(trav, _node_reader.get_transform(), + node_state, _node_reader.get_effects(), + _node_reader.get_off_clip_planes()); } //////////////////////////////////////////////////////////////////// @@ -137,8 +135,8 @@ apply_transform_and_state(CullTraverser *trav, // Description: The private implementation of is_in_view(). //////////////////////////////////////////////////////////////////// bool CullTraverserData:: -is_in_view_impl(Thread *current_thread) { - CPT(BoundingVolume) node_volume = node()->get_bounds(current_thread); +is_in_view_impl() { + CPT(BoundingVolume) node_volume = _node_reader.get_bounds(); nassertr(node_volume->is_of_type(GeometricBoundingVolume::get_class_type()), false); const GeometricBoundingVolume *node_gbv = DCAST(GeometricBoundingVolume, node_volume); @@ -173,7 +171,7 @@ is_in_view_impl(Thread *current_thread) { } else { // The node is partially, but not completely, within the viewing // frustum. - if (node()->is_final(current_thread)) { + if (_node_reader.is_final()) { // Normally we'd keep testing child bounding volumes as we // continue down. But this node has the "final" flag, so the // user is claiming that there is some important reason we @@ -207,7 +205,7 @@ is_in_view_impl(Thread *current_thread) { } else { // The node is partially within one or more clip planes. - if (node()->is_final(current_thread)) { + if (_node_reader.is_final()) { // Even though the node is only partially within the clip // planes, stop culling against them. _cull_planes = CullPlanes::make_empty(); @@ -230,7 +228,7 @@ test_within_clip_planes_impl(const CullTraverser *trav, int result = BoundingVolume::IF_all | BoundingVolume::IF_possible | BoundingVolume::IF_some; - const BoundingVolume *node_volume = node()->get_bounds(); + const BoundingVolume *node_volume = _node_reader.get_bounds(); nassertr(node_volume->is_of_type(GeometricBoundingVolume::get_class_type()), result); const GeometricBoundingVolume *node_gbv = DCAST(GeometricBoundingVolume, node_volume); diff --git a/panda/src/pgraph/cullTraverserData.h b/panda/src/pgraph/cullTraverserData.h index 27437cd79f..854807361e 100644 --- a/panda/src/pgraph/cullTraverserData.h +++ b/panda/src/pgraph/cullTraverserData.h @@ -51,7 +51,8 @@ public: const TransformState *net_transform, const RenderState *state, GeometricBoundingVolume *view_frustum, - GeometricBoundingVolume *guard_band); + GeometricBoundingVolume *guard_band, + Thread *current_thread); INLINE CullTraverserData(const CullTraverserData ©); INLINE void operator = (const CullTraverserData ©); INLINE CullTraverserData(const CullTraverserData &parent, @@ -59,11 +60,13 @@ public: INLINE ~CullTraverserData(); INLINE PandaNode *node() const; + INLINE PandaNodePipelineReader *node_reader(); + INLINE const PandaNodePipelineReader *node_reader() const; CPT(TransformState) get_modelview_transform(const CullTraverser *trav) const; INLINE const TransformState *get_net_transform(const CullTraverser *trav) const; - INLINE bool is_in_view(const DrawMask &camera_mask, Thread *current_thread); + INLINE bool is_in_view(const DrawMask &camera_mask); INLINE bool is_this_node_hidden(const CullTraverser *trav) const; void apply_transform_and_state(CullTraverser *trav); @@ -74,6 +77,7 @@ public: const RenderAttrib *off_clip_planes); WorkingNodePath _node_path; + PandaNodePipelineReader _node_reader; CPT(TransformState) _net_transform; CPT(RenderState) _state; PT(GeometricBoundingVolume) _view_frustum; @@ -82,7 +86,7 @@ public: DrawMask _draw_mask; private: - bool is_in_view_impl(Thread *current_thread); + bool is_in_view_impl(); int test_within_clip_planes_impl(const CullTraverser *trav, const ClipPlaneAttrib *cpa) const; diff --git a/panda/src/pgraph/cullableObject.cxx b/panda/src/pgraph/cullableObject.cxx index 6981071cf2..7c2ef022ce 100644 --- a/panda/src/pgraph/cullableObject.cxx +++ b/panda/src/pgraph/cullableObject.cxx @@ -56,13 +56,13 @@ munge_geom(GraphicsStateGuardianBase *gsg, GeomPipelineReader geom_reader(_geom, current_thread); _munged_data = geom_reader.get_vertex_data(); -#ifndef NDEBUG +#ifdef _DEBUG { GeomVertexDataPipelineReader data_reader(_munged_data, current_thread); data_reader.check_array_readers(); nassertv(geom_reader.check_valid(&data_reader)); } -#endif // NDEBUG +#endif // _DEBUG int geom_rendering = geom_reader.get_geom_rendering(); geom_rendering = _state->get_geom_rendering(geom_rendering); diff --git a/panda/src/pgraph/pandaNode.I b/panda/src/pgraph/pandaNode.I index db96739379..d1dd3bda5d 100644 --- a/panda/src/pgraph/pandaNode.I +++ b/panda/src/pgraph/pandaNode.I @@ -17,63 +17,6 @@ //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::compose_draw_mask -// Access: Public -// Description: Computes the result of applying this node's draw -// masks to a running draw mask, as during a traversal. -//////////////////////////////////////////////////////////////////// -INLINE void PandaNode:: -compose_draw_mask(DrawMask &running_draw_mask, - Thread *current_thread) const { - CDHeavyReader cdata(_cycler_heavy, current_thread); - running_draw_mask = (running_draw_mask & ~cdata->_draw_control_mask) | - (cdata->_draw_show_mask & cdata->_draw_control_mask); -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::compare_draw_mask -// Access: Public -// Description: Compares the running draw mask computed during a -// traversal with this node's net draw masks. Returns -// true if the node should be traversed into, or false -// if there is nothing at this level or below that will -// be visible to the indicated camera_mask. -//////////////////////////////////////////////////////////////////// -INLINE bool PandaNode:: -compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask, - Thread *current_thread) const { - DrawMask net_draw_control_mask, net_draw_show_mask; - - int pipeline_stage = current_thread->get_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); - if (cdata->_last_update != cdata->_next_update) { - // The cache is stale; it needs to be rebuilt. - CDBoundsStageWriter cdataw = ((PandaNode *)this)->update_bounds(pipeline_stage, cdata); - net_draw_control_mask = cdataw->_net_draw_control_mask; - net_draw_show_mask = cdataw->_net_draw_show_mask; - } else { - net_draw_control_mask = cdata->_net_draw_control_mask; - net_draw_show_mask = cdata->_net_draw_show_mask; - } - - // Now the bits that are not in net_draw_control_mask--that is, - // those bits that are not changed by any of the nodes at this level - // and below--are taken from running_draw_mask, which is inherited - // from above. On the other hand, the bits that *are* in - // net_draw_control_mask--those bits that are changed by any of the - // nodes at this level and below--are taken from net_draw_show_mask, - // which is propagated upwards from below. - - // This way, we will traverse into this node if it has any children - // which want to be visited by the traversal, but we will avoid - // traversing into it if all of its children are hidden to this - // camera. - DrawMask compare_mask = (running_draw_mask & ~net_draw_control_mask) | (net_draw_show_mask & net_draw_control_mask); - - return !((compare_mask & _overall_bit).is_zero()) && !((compare_mask & camera_mask).is_zero()); -} - //////////////////////////////////////////////////////////////////// // Function: PandaNode::get_num_parents @@ -86,7 +29,7 @@ compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask, //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: get_num_parents(Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); return cdata->get_up()->size(); } @@ -100,7 +43,7 @@ get_num_parents(Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE PandaNode *PandaNode:: get_parent(int n, Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); const Up &up = *cdata->get_up(); nassertr(n >= 0 && n < (int)up.size(), NULL); return up[n].get_parent(); @@ -114,7 +57,7 @@ get_parent(int n, Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: find_parent(PandaNode *node, Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); return do_find_parent(node, cdata); } @@ -128,7 +71,7 @@ find_parent(PandaNode *node, Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: get_num_children(Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); return cdata->get_down()->size(); } @@ -142,7 +85,7 @@ get_num_children(Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE PandaNode *PandaNode:: get_child(int n, Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); const Down &down = *cdata->get_down(); nassertr(n >= 0 && n < (int)down.size(), NULL); return down[n].get_child(); @@ -157,7 +100,7 @@ get_child(int n, Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: get_child_sort(int n, Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); const Down &down = *cdata->get_down(); nassertr(n >= 0 && n < (int)down.size(), -1); return down[n].get_sort(); @@ -171,7 +114,7 @@ get_child_sort(int n, Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: find_child(PandaNode *node, Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); return do_find_child(node, cdata); } @@ -236,7 +179,7 @@ unstash_child(PandaNode *child_node, Thread *current_thread) { //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: get_num_stashed(Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); return cdata->get_stashed()->size(); } @@ -251,7 +194,7 @@ get_num_stashed(Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE PandaNode *PandaNode:: get_stashed(int n, Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); const Down &stashed = *cdata->get_stashed(); nassertr(n >= 0 && n < (int)stashed.size(), NULL); return stashed[n].get_child(); @@ -266,7 +209,7 @@ get_stashed(int n, Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: get_stashed_sort(int n, Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); const Down &stashed = *cdata->get_stashed(); nassertr(n >= 0 && n < (int)stashed.size(), -1); return stashed[n].get_sort(); @@ -280,7 +223,7 @@ get_stashed_sort(int n, Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: find_stashed(PandaNode *node, Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); return do_find_stashed(node, cdata); } @@ -295,7 +238,7 @@ find_stashed(PandaNode *node, Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE const RenderAttrib *PandaNode:: get_attrib(TypeHandle type) const { - CDLightReader cdata(_cycler_light); + CDReader cdata(_cycler); int index = cdata->_state->find_attrib(type); if (index >= 0) { return cdata->_state->get_attrib(index); @@ -312,7 +255,7 @@ get_attrib(TypeHandle type) const { //////////////////////////////////////////////////////////////////// INLINE bool PandaNode:: has_attrib(TypeHandle type) const { - CDLightReader cdata(_cycler_light); + CDReader cdata(_cycler); int index = cdata->_state->find_attrib(type); return (index >= 0); } @@ -325,7 +268,7 @@ has_attrib(TypeHandle type) const { //////////////////////////////////////////////////////////////////// INLINE const RenderEffect *PandaNode:: get_effect(TypeHandle type) const { - CDHeavyReader cdata(_cycler_heavy); + CDReader cdata(_cycler); int index = cdata->_effects->find_effect(type); if (index >= 0) { return cdata->_effects->get_effect(index); @@ -342,7 +285,7 @@ get_effect(TypeHandle type) const { //////////////////////////////////////////////////////////////////// INLINE bool PandaNode:: has_effect(TypeHandle type) const { - CDHeavyReader cdata(_cycler_heavy); + CDReader cdata(_cycler); int index = cdata->_effects->find_effect(type); return (index >= 0); } @@ -358,7 +301,7 @@ has_effect(TypeHandle type) const { //////////////////////////////////////////////////////////////////// INLINE const RenderState *PandaNode:: get_state(Thread *current_thread) const { - CDLightReader cdata(_cycler_light, current_thread); + CDReader cdata(_cycler, current_thread); return cdata->_state; } @@ -383,7 +326,7 @@ clear_state(Thread *current_thread) { //////////////////////////////////////////////////////////////////// INLINE const RenderEffects *PandaNode:: get_effects(Thread *current_thread) const { - CDHeavyReader cdata(_cycler_heavy, current_thread); + CDReader cdata(_cycler, current_thread); return cdata->_effects; } @@ -407,7 +350,7 @@ clear_effects(Thread *current_thread) { //////////////////////////////////////////////////////////////////// INLINE const TransformState *PandaNode:: get_transform(Thread *current_thread) const { - CDLightReader cdata(_cycler_light, current_thread); + CDReader cdata(_cycler, current_thread); return cdata->_transform; } @@ -431,7 +374,7 @@ clear_transform(Thread *current_thread) { //////////////////////////////////////////////////////////////////// const TransformState *PandaNode:: get_prev_transform(Thread *current_thread) const { - CDLightReader cdata(_cycler_light, current_thread); + CDReader cdata(_cycler, current_thread); return cdata->_prev_transform; } @@ -459,7 +402,7 @@ has_dirty_prev_transform() const { //////////////////////////////////////////////////////////////////// INLINE string PandaNode:: get_tag(const string &key, Thread *current_thread) const { - CDHeavyReader cdata(_cycler_heavy, current_thread); + CDReader cdata(_cycler, current_thread); TagData::const_iterator ti; ti = cdata->_tag_data.find(key); if (ti != cdata->_tag_data.end()) { @@ -477,7 +420,7 @@ get_tag(const string &key, Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE bool PandaNode:: has_tag(const string &key, Thread *current_thread) const { - CDHeavyReader cdata(_cycler_heavy, current_thread); + CDReader cdata(_cycler, current_thread); TagData::const_iterator ti; ti = cdata->_tag_data.find(key); return (ti != cdata->_tag_data.end()); @@ -491,7 +434,7 @@ has_tag(const string &key, Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE bool PandaNode:: has_tags() const { - CDHeavyReader cdata(_cycler_heavy); + CDReader cdata(_cycler); if (!cdata->_tag_data.empty()) { return true; } @@ -535,7 +478,7 @@ get_overall_bit() { //////////////////////////////////////////////////////////////////// INLINE bool PandaNode:: is_overall_hidden() const { - CDHeavyReader cdata(_cycler_heavy); + CDReader cdata(_cycler); return ((cdata->_draw_show_mask | ~cdata->_draw_control_mask) & _overall_bit).is_zero(); } @@ -570,7 +513,7 @@ set_overall_hidden(bool hidden) { //////////////////////////////////////////////////////////////////// INLINE DrawMask PandaNode:: get_draw_control_mask() const { - CDHeavyReader cdata(_cycler_heavy); + CDReader cdata(_cycler); return cdata->_draw_control_mask; } @@ -582,7 +525,7 @@ get_draw_control_mask() const { //////////////////////////////////////////////////////////////////// INLINE DrawMask PandaNode:: get_draw_show_mask() const { - CDHeavyReader cdata(_cycler_heavy); + CDReader cdata(_cycler); return cdata->_draw_show_mask; } @@ -593,7 +536,7 @@ get_draw_show_mask() const { //////////////////////////////////////////////////////////////////// INLINE CollideMask PandaNode:: get_into_collide_mask() const { - CDHeavyReader cdata(_cycler_heavy); + CDReader cdata(_cycler); return cdata->_into_collide_mask; } @@ -645,7 +588,7 @@ get_internal_bounds() const { //////////////////////////////////////////////////////////////////// INLINE void PandaNode:: set_final(bool flag) { - CDHeavyWriter cdata(_cycler_heavy); + CDWriter cdata(_cycler); cdata->_final_bounds = flag; } @@ -659,7 +602,7 @@ set_final(bool flag) { //////////////////////////////////////////////////////////////////// INLINE bool PandaNode:: is_final(Thread *current_thread) const { - CDHeavyReader cdata(_cycler_heavy, current_thread); + CDReader cdata(_cycler, current_thread); return cdata->_final_bounds; } @@ -673,7 +616,7 @@ is_final(Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE CPT(BoundingVolume) PandaNode:: get_user_bounds(int pipeline_stage, Thread *current_thread) const { - CDHeavyStageReader cdata(_cycler_heavy, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); return cdata->_user_bounds; } @@ -682,7 +625,7 @@ get_user_bounds(int pipeline_stage, Thread *current_thread) const { // Access: Protected // Description: Indicates that the bounding volume, or something that // influences the bounding volume (or any of the other -// things stored in CDataBounds, like net_collide_mask), +// things stored in CData, like net_collide_mask), // may have changed for this node, and that it must be // recomputed. //////////////////////////////////////////////////////////////////// @@ -692,7 +635,7 @@ mark_bounds_stale(int pipeline_stage, Thread *current_thread) const { // force_bounds_stale(). bool is_stale_bounds; { - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); is_stale_bounds = (cdata->_last_update != cdata->_next_update); } if (!is_stale_bounds) { @@ -712,7 +655,7 @@ mark_bounds_stale(int pipeline_stage, Thread *current_thread) const { INLINE void PandaNode:: mark_internal_bounds_stale(int pipeline_stage, Thread *current_thread) { { - CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread); + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); cdata->_internal_bounds_stale = true; } mark_bounds_stale(pipeline_stage, current_thread); @@ -737,7 +680,7 @@ mark_internal_bounds_stale(int pipeline_stage, Thread *current_thread) { //////////////////////////////////////////////////////////////////// INLINE PandaNode::Children PandaNode:: get_children(Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); return Children(cdata); } @@ -760,7 +703,7 @@ get_children(Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE PandaNode::Stashed PandaNode:: get_stashed(Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); return Stashed(cdata); } @@ -773,7 +716,7 @@ get_stashed(Thread *current_thread) const { //////////////////////////////////////////////////////////////////// INLINE PandaNode::Parents PandaNode:: get_parents(Thread *current_thread) const { - CDLinksReader cdata(_cycler_links, current_thread); + CDReader cdata(_cycler, current_thread); return Parents(cdata); } @@ -783,7 +726,7 @@ get_parents(Thread *current_thread) const { // Description: The private implementation of find_parent(). //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: -do_find_parent(PandaNode *node, const CDataLinks *cdata) const { +do_find_parent(PandaNode *node, const CData *cdata) const { const Up &up = *cdata->get_up(); Up::const_iterator ui = up.find(UpConnection(node)); if (ui == up.end()) { @@ -918,77 +861,22 @@ get_parent() const { } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLight::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE PandaNode::CDataLight:: -CDataLight() { - _state = RenderState::make_empty(); - _transform = TransformState::make_identity(); - _prev_transform = TransformState::make_identity(); -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataHeavy::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE PandaNode::CDataHeavy:: -CDataHeavy() { - _effects = RenderEffects::make_empty(); - _draw_control_mask = DrawMask::all_off(); - _draw_show_mask = DrawMask::all_on(); - _into_collide_mask = CollideMask::all_off(); - _user_bounds = NULL; - _internal_bounds = NULL; - _internal_bounds_stale = true; - _final_bounds = false; -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataBounds::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE PandaNode::CDataBounds:: -CDataBounds() { - _net_collide_mask = CollideMask::all_off(); - _net_draw_control_mask = DrawMask::all_off(); - _net_draw_show_mask = DrawMask::all_off(); - ++_next_update; -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE PandaNode::CDataLinks:: -CDataLinks() : - _down(new PandaNode::Down), - _stashed(new PandaNode::Down), - _up(new PandaNode::Up) -{ -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::get_down +// Function: PandaNode::CData::get_down // Access: Public // Description: Returns a read-only pointer to the _down list. //////////////////////////////////////////////////////////////////// -INLINE const PandaNode::Down *PandaNode::CDataLinks:: +INLINE const PandaNode::Down *PandaNode::CData:: get_down() const { return _down; } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::modify_down +// Function: PandaNode::CData::modify_down // Access: Public // Description: Returns a modifiable, unique pointer to the _down // list. //////////////////////////////////////////////////////////////////// -INLINE PandaNode::Down *PandaNode::CDataLinks:: +INLINE PandaNode::Down *PandaNode::CData:: modify_down() { if (_down->get_ref_count() > 1) { _down = new Down(*_down); @@ -997,22 +885,22 @@ modify_down() { } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::get_stashed +// Function: PandaNode::CData::get_stashed // Access: Public // Description: Returns a read-only pointer to the _stashed list. //////////////////////////////////////////////////////////////////// -INLINE const PandaNode::Down *PandaNode::CDataLinks:: +INLINE const PandaNode::Down *PandaNode::CData:: get_stashed() const { return _stashed; } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::modify_stashed +// Function: PandaNode::CData::modify_stashed // Access: Public // Description: Returns a modifiable, unique pointer to the _stashed // list. //////////////////////////////////////////////////////////////////// -INLINE PandaNode::Down *PandaNode::CDataLinks:: +INLINE PandaNode::Down *PandaNode::CData:: modify_stashed() { if (_stashed->get_ref_count() > 1) { _stashed = new Down(*_stashed); @@ -1021,22 +909,22 @@ modify_stashed() { } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::get_up +// Function: PandaNode::CData::get_up // Access: Public // Description: Returns a read-only pointer to the _up list. //////////////////////////////////////////////////////////////////// -INLINE const PandaNode::Up *PandaNode::CDataLinks:: +INLINE const PandaNode::Up *PandaNode::CData:: get_up() const { return _up; } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::modify_up +// Function: PandaNode::CData::modify_up // Access: Public // Description: Returns a modifiable, unique pointer to the _up // list. //////////////////////////////////////////////////////////////////// -INLINE PandaNode::Up *PandaNode::CDataLinks:: +INLINE PandaNode::Up *PandaNode::CData:: modify_up() { if (_up->get_ref_count() > 1) { _up = new Up(*_up); @@ -1059,7 +947,7 @@ Children() { // Description: //////////////////////////////////////////////////////////////////// INLINE PandaNode::Children:: -Children(const PandaNode::CDataLinks *cdata) : +Children(const PandaNode::CData *cdata) : _down(cdata->get_down()) { } @@ -1137,7 +1025,7 @@ Stashed() { // Description: //////////////////////////////////////////////////////////////////// INLINE PandaNode::Stashed:: -Stashed(const PandaNode::CDataLinks *cdata) : +Stashed(const PandaNode::CData *cdata) : _stashed(cdata->get_stashed()) { } @@ -1215,7 +1103,7 @@ Parents() { // Description: //////////////////////////////////////////////////////////////////// INLINE PandaNode::Parents:: -Parents(const PandaNode::CDataLinks *cdata) : +Parents(const PandaNode::CData *cdata) : _up(cdata->get_up()) { } @@ -1263,3 +1151,514 @@ get_parent(int n) const { nassertr(n >= 0 && n < (int)_up->size(), NULL); return (*_up)[n].get_parent(); } + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PandaNodePipelineReader:: +PandaNodePipelineReader(const PandaNode *object, Thread *current_thread) : + _object(object), + _current_thread(current_thread), + _cdata(object->_cycler.read(current_thread)) +{ +#ifdef _DEBUG + nassertv(_object->test_ref_count_nonzero()); +#ifdef DO_PIPELINING + nassertv(_cdata->test_ref_count_nonzero()); +#endif // DO_PIPELINING +#endif // _DEBUG +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PandaNodePipelineReader:: +PandaNodePipelineReader(const PandaNodePipelineReader ©) : + _object(copy._object), + _current_thread(copy._current_thread), + _cdata(copy._cdata) +{ + if (_cdata != (PandaNode::CData *)NULL) { + _object->_cycler.increment_read(_cdata); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::Copy Assignment Operator +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void PandaNodePipelineReader:: +operator = (const PandaNodePipelineReader ©) { + nassertv(_current_thread == copy._current_thread); + + if (_cdata != (PandaNode::CData *)NULL) { + _object->_cycler.release_read(_cdata); + } + + _object = copy._object; + _cdata = copy._cdata; + + if (_cdata != (PandaNode::CData *)NULL) { + _object->_cycler.increment_read(_cdata); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PandaNodePipelineReader:: +~PandaNodePipelineReader() { + if (_cdata != (PandaNode::CData *)NULL) { + _object->_cycler.release_read(_cdata); + } + +#ifdef _DEBUG + _object = NULL; + _cdata = NULL; +#endif // _DEBUG +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_object +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE const PandaNode *PandaNodePipelineReader:: +get_object() const { + return _object; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_current_thread +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE Thread *PandaNodePipelineReader:: +get_current_thread() const { + return _current_thread; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::release +// Access: Public +// Description: Releases the lock on this object. No future calls +// will be valid on this object. +//////////////////////////////////////////////////////////////////// +INLINE void PandaNodePipelineReader:: +release() { + if (_cdata != (PandaNode::CData *)NULL) { + _object->_cycler.release_read(_cdata); + _cdata = NULL; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::check_bounds +// Access: Public +// Description: Ensures that the bounding volume is properly computed +// on this node. +//////////////////////////////////////////////////////////////////// +INLINE void PandaNodePipelineReader:: +check_bounds() const { + nassertv(_cdata != (PandaNode::CData *)NULL); + if (_cdata->_last_update != _cdata->_next_update) { + // The cache is stale; it needs to be rebuilt. + + // We should technically drop _cdata while we do this operation, + // but at the moment, it doesn't really matter. + int pipeline_stage = _current_thread->get_pipeline_stage(); + PandaNode::CDStageReader fresh_cdata(_object->_cycler, pipeline_stage, _current_thread); + ((PandaNode *)_object)->update_bounds(pipeline_stage, fresh_cdata); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::compose_draw_mask +// Access: Public +// Description: Computes the result of applying this node's draw +// masks to a running draw mask, as during a traversal. +//////////////////////////////////////////////////////////////////// +INLINE void PandaNodePipelineReader:: +compose_draw_mask(DrawMask &running_draw_mask) const { + nassertv(_cdata != (PandaNode::CData *)NULL); + running_draw_mask = (running_draw_mask & ~_cdata->_draw_control_mask) | + (_cdata->_draw_show_mask & _cdata->_draw_control_mask); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::compare_draw_mask +// Access: Public +// Description: Compares the running draw mask computed during a +// traversal with this node's net draw masks. Returns +// true if the node should be traversed into, or false +// if there is nothing at this level or below that will +// be visible to the indicated camera_mask. +//////////////////////////////////////////////////////////////////// +INLINE bool PandaNodePipelineReader:: +compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const { + nassertr(_cdata != (PandaNode::CData *)NULL, false); + nassertr(_cdata->_last_update == _cdata->_next_update, false); + + DrawMask net_draw_control_mask, net_draw_show_mask; + net_draw_control_mask = _cdata->_net_draw_control_mask; + net_draw_show_mask = _cdata->_net_draw_show_mask; + + // Now the bits that are not in net_draw_control_mask--that is, + // those bits that are not changed by any of the nodes at this level + // and below--are taken from running_draw_mask, which is inherited + // from above. On the other hand, the bits that *are* in + // net_draw_control_mask--those bits that are changed by any of the + // nodes at this level and below--are taken from net_draw_show_mask, + // which is propagated upwards from below. + + // This way, we will traverse into this node if it has any children + // which want to be visited by the traversal, but we will avoid + // traversing into it if all of its children are hidden to this + // camera. + DrawMask compare_mask = (running_draw_mask & ~net_draw_control_mask) | (net_draw_show_mask & net_draw_control_mask); + + return !((compare_mask & PandaNode::_overall_bit).is_zero()) && !((compare_mask & camera_mask).is_zero()); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_num_parents +// Access: Published +// Description: Returns the number of parent nodes this node has. If +// this number is greater than 1, the node has been +// multiply instanced. The order of the parent nodes is +// not meaningful and is not related to the order in +// which the node was instanced to them. +//////////////////////////////////////////////////////////////////// +INLINE int PandaNodePipelineReader:: +get_num_parents() const { + return _cdata->get_up()->size(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_parent +// Access: Published +// Description: Returns the nth parent node of this node. See +// get_num_parents(). Also see get_parents(), if your +// intention is to iterate through the complete list of +// parents; get_parents() is preferable in this case. +//////////////////////////////////////////////////////////////////// +INLINE PandaNode *PandaNodePipelineReader:: +get_parent(int n) const { + const PandaNode::Up &up = *_cdata->get_up(); + nassertr(n >= 0 && n < (int)up.size(), NULL); + return up[n].get_parent(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::find_parent +// Access: Published +// Description: Returns the index of the indicated parent node, if it +// is a parent, or -1 if it is not. +//////////////////////////////////////////////////////////////////// +INLINE int PandaNodePipelineReader:: +find_parent(PandaNode *node) const { + return _object->do_find_parent(node, _cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_num_children +// Access: Published +// Description: Returns the number of child nodes this node has. The +// order of the child nodes *is* meaningful and is based +// on the sort number that was passed to add_child(), +// and also on the order in which the nodes were added. +//////////////////////////////////////////////////////////////////// +INLINE int PandaNodePipelineReader:: +get_num_children() const { + return _cdata->get_down()->size(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_child +// Access: Published +// Description: Returns the nth child node of this node. See +// get_num_children(). Also see get_children(), if your +// intention is to iterate through the complete list of +// children; get_children() is preferable in this case. +//////////////////////////////////////////////////////////////////// +INLINE PandaNode *PandaNodePipelineReader:: +get_child(int n) const { + const PandaNode::Down &down = *_cdata->get_down(); + nassertr(n >= 0 && n < (int)down.size(), NULL); + return down[n].get_child(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_child_sort +// Access: Published +// Description: Returns the sort index of the nth child node of this +// node (that is, the number that was passed to +// add_child()). See get_num_children(). +//////////////////////////////////////////////////////////////////// +INLINE int PandaNodePipelineReader:: +get_child_sort(int n) const { + const PandaNode::Down &down = *_cdata->get_down(); + nassertr(n >= 0 && n < (int)down.size(), -1); + return down[n].get_sort(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::find_child +// Access: Published +// Description: Returns the index of the indicated child node, if it +// is a child, or -1 if it is not. +//////////////////////////////////////////////////////////////////// +INLINE int PandaNodePipelineReader:: +find_child(PandaNode *node) const { + return _object->do_find_child(node, _cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_num_stashed +// Access: Published +// Description: Returns the number of stashed nodes this node has. +// These are former children of the node that have been +// moved to the special stashed list via stash_child(). +//////////////////////////////////////////////////////////////////// +INLINE int PandaNodePipelineReader:: +get_num_stashed() const { + return _cdata->get_stashed()->size(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_stashed +// Access: Published +// Description: Returns the nth stashed child of this node. See +// get_num_stashed(). Also see get_stashed(), if your +// intention is to iterate through the complete list of +// stashed children; get_stashed() is preferable in this +// case. +//////////////////////////////////////////////////////////////////// +INLINE PandaNode *PandaNodePipelineReader:: +get_stashed(int n) const { + const PandaNode::Down &stashed = *_cdata->get_stashed(); + nassertr(n >= 0 && n < (int)stashed.size(), NULL); + return stashed[n].get_child(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_stashed_sort +// Access: Published +// Description: Returns the sort index of the nth stashed node of this +// node (that is, the number that was passed to +// add_child()). See get_num_stashed(). +//////////////////////////////////////////////////////////////////// +INLINE int PandaNodePipelineReader:: +get_stashed_sort(int n) const { + const PandaNode::Down &stashed = *_cdata->get_stashed(); + nassertr(n >= 0 && n < (int)stashed.size(), -1); + return stashed[n].get_sort(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::find_stashed +// Access: Published +// Description: Returns the index of the indicated stashed node, if +// it is a stashed child, or -1 if it is not. +//////////////////////////////////////////////////////////////////// +INLINE int PandaNodePipelineReader:: +find_stashed(PandaNode *node) const { + return _object->do_find_stashed(node, _cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_state +// Access: Published +// Description: Returns the complete RenderState that will be applied +// to all nodes at this level and below, as set on this +// node. This returns only the RenderState set on this +// particular node, and has nothing to do with state +// that might be inherited from above. +//////////////////////////////////////////////////////////////////// +INLINE const RenderState *PandaNodePipelineReader:: +get_state() const { + return _cdata->_state; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_effects +// Access: Published +// Description: Returns the complete RenderEffects that will be +// applied to this node. +//////////////////////////////////////////////////////////////////// +INLINE const RenderEffects *PandaNodePipelineReader:: +get_effects() const { + return _cdata->_effects; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_transform +// Access: Published +// Description: Returns the transform that has been set on this +// particular node. This is not the net transform from +// the root, but simply the transform on this particular +// node. +//////////////////////////////////////////////////////////////////// +INLINE const TransformState *PandaNodePipelineReader:: +get_transform() const { + return _cdata->_transform; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_prev_transform +// Access: Published +// Description: Returns the transform that has been set as this +// node's "previous" position. See +// set_prev_transform(). +//////////////////////////////////////////////////////////////////// +const TransformState *PandaNodePipelineReader:: +get_prev_transform() const { + return _cdata->_prev_transform; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_tag +// Access: Published +// Description: Retrieves the user-defined value that was previously +// set on this node for the particular key, if any. If +// no value has been previously set, returns the empty +// string. +//////////////////////////////////////////////////////////////////// +INLINE string PandaNodePipelineReader:: +get_tag(const string &key) const { + PandaNode::TagData::const_iterator ti; + ti = _cdata->_tag_data.find(key); + if (ti != _cdata->_tag_data.end()) { + return (*ti).second; + } + return string(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::has_tag +// Access: Published +// Description: Returns true if a value has been defined on this node +// for the particular key (even if that value is the +// empty string), or false if no value has been set. +//////////////////////////////////////////////////////////////////// +INLINE bool PandaNodePipelineReader:: +has_tag(const string &key) const { + PandaNode::TagData::const_iterator ti; + ti = _cdata->_tag_data.find(key); + return (ti != _cdata->_tag_data.end()); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_net_collide_mask +// Access: Published +// Description: Returns the union of all into_collide_mask() values +// set at CollisionNodes at this level and below. +//////////////////////////////////////////////////////////////////// +INLINE CollideMask PandaNodePipelineReader:: +get_net_collide_mask() const { + nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_net_collide_mask); + return _cdata->_net_collide_mask; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_off_clip_planes +// Access: Published +// Description: Returns a ClipPlaneAttrib which represents the union +// of all of the clip planes that have been turned *off* +// at this level and below. +//////////////////////////////////////////////////////////////////// +INLINE CPT(RenderAttrib) PandaNodePipelineReader:: +get_off_clip_planes() const { + nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_off_clip_planes); + return _cdata->_off_clip_planes; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_bounds +// Access: Published +// Description: Returns the external bounding volume of this node: a +// bounding volume that contains the user bounding +// volume, the internal bounding volume, and all of the +// children's bounding volumes. +//////////////////////////////////////////////////////////////////// +INLINE CPT(BoundingVolume) PandaNodePipelineReader:: +get_bounds() const { + nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_external_bounds); + return _cdata->_external_bounds; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::is_final +// Access: Published +// Description: Returns the current state of the "final" flag. +// Initially, this flag is off (false), but it may be +// changed by an explicit call to set_final(). See +// set_final(). +//////////////////////////////////////////////////////////////////// +INLINE bool PandaNodePipelineReader:: +is_final() const { + return _cdata->_final_bounds; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_children +// Access: Public +// Description: Returns an object that can be used to walk through +// the list of children of the node. When you intend to +// visit multiple children, using this is slightly +// faster than calling get_child() directly on the +// PandaNode, since this object avoids reopening the +// PipelineCycler each time. +// +// This object also protects you from self-modifying +// loops (e.g. adding or removing children during +// traversal), since a virtual copy of the children is +// made ahead of time. The virtual copy is fast--it is +// a form of copy-on-write, so the list is not actually +// copied unless it is modified during the traversal. +//////////////////////////////////////////////////////////////////// +INLINE PandaNode::Children PandaNodePipelineReader:: +get_children() const { + return PandaNode::Children(_cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_stashed +// Access: Public +// Description: Returns an object that can be used to walk through +// the list of children of the node. When you intend to +// visit multiple children, using this is slightly +// faster than calling get_stashed() directly on the +// PandaNode, since this object avoids reopening the +// PipelineCycler each time. +// +// This object also protects you from self-modifying +// loops (e.g. adding or removing children during +// traversal), since a virtual copy of the children is +// made ahead of time. The virtual copy is fast--it is +// a form of copy-on-write, so the list is not actually +// copied unless it is modified during the traversal. +//////////////////////////////////////////////////////////////////// +INLINE PandaNode::Stashed PandaNodePipelineReader:: +get_stashed() const { + return PandaNode::Stashed(_cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNodePipelineReader::get_parents +// Access: Public +// Description: Returns an object that can be used to walk through +// the list of parents of the node, similar to +// get_children() and get_stashed(). +//////////////////////////////////////////////////////////////////// +INLINE PandaNode::Parents PandaNodePipelineReader:: +get_parents() const { + return PandaNode::Parents(_cdata); +} diff --git a/panda/src/pgraph/pandaNode.cxx b/panda/src/pgraph/pandaNode.cxx index 42c00cd4e4..38d16d0266 100644 --- a/panda/src/pgraph/pandaNode.cxx +++ b/panda/src/pgraph/pandaNode.cxx @@ -102,7 +102,7 @@ PandaNode:: // there's a refcount fault somewhere. #ifndef NDEBUG { - CDLinksReader cdata(_cycler_links); + CDReader cdata(_cycler); nassertv(cdata->get_up()->empty()); } #endif // NDEBUG @@ -136,8 +136,8 @@ PandaNode(const PandaNode ©) : // Copy the other node's state. { - CDLightReader copy_cdata(copy._cycler_light); - CDLightWriter cdata(_cycler_light, true); + CDReader copy_cdata(copy._cycler); + CDWriter cdata(_cycler, true); cdata->_state = copy_cdata->_state; cdata->_transform = copy_cdata->_transform; cdata->_prev_transform = copy_cdata->_prev_transform; @@ -146,8 +146,8 @@ PandaNode(const PandaNode ©) : } } { - CDHeavyReader copy_cdata(copy._cycler_heavy); - CDHeavyWriter cdata(_cycler_heavy, true); + CDReader copy_cdata(copy._cycler); + CDWriter cdata(_cycler, true); cdata->_effects = copy_cdata->_effects; cdata->_tag_data = copy_cdata->_tag_data; cdata->_draw_control_mask = copy_cdata->_draw_control_mask; @@ -577,19 +577,19 @@ add_child(PandaNode *child_node, int sort, Thread *current_thread) { // Apply this operation to the current stage as well as to all // upstream stages. - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links, current_thread) { - CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); + CDStageWriter cdata_child(child_node->_cycler, pipeline_stage, current_thread); cdata->modify_down()->insert(DownConnection(child_node, sort)); cdata_child->modify_up()->insert(UpConnection(this)); } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); - OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) { + OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler, current_thread) { new_connection(this, child_node, pipeline_stage, current_thread); } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler); force_bounds_stale(); children_changed(); @@ -606,12 +606,12 @@ remove_child(int child_index, Thread *current_thread) { int pipeline_stage = current_thread->get_pipeline_stage(); nassertv(pipeline_stage == 0); - CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); Down &down = *cdata->modify_down(); nassertv(child_index >= 0 && child_index < (int)down.size()); PT(PandaNode) child_node = down[child_index].get_child(); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, + CDStageWriter cdata_child(child_node->_cycler, pipeline_stage, current_thread); Up &up = *cdata_child->modify_up(); @@ -645,7 +645,7 @@ remove_child(PandaNode *child_node, Thread *current_thread) { // We have to do this for each upstream pipeline stage. bool any_removed = false; - OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) { + OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler, current_thread) { if (stage_remove_child(child_node, pipeline_stage, current_thread)) { any_removed = true; @@ -653,7 +653,7 @@ remove_child(PandaNode *child_node, Thread *current_thread) { force_bounds_stale(pipeline_stage, current_thread); } } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler); if (any_removed) { // Call callback hooks. @@ -690,12 +690,12 @@ replace_child(PandaNode *orig_child, PandaNode *new_child, // We have to do this for each upstream pipeline stage. bool any_replaced = false; - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links, current_thread) { + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { if (stage_replace_child(orig_child, new_child, pipeline_stage, current_thread)) { any_replaced = true; } } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); if (any_replaced) { children_changed(); @@ -736,8 +736,8 @@ stash_child(int child_index, Thread *current_thread) { remove_child(child_index); { - CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); + CDStageWriter cdata_child(child_node->_cycler, pipeline_stage, current_thread); cdata->modify_stashed()->insert(DownConnection(child_node, sort)); cdata_child->modify_up()->insert(UpConnection(this)); @@ -782,8 +782,8 @@ unstash_child(int stashed_index, Thread *current_thread) { remove_stashed(stashed_index); { - CDLinksWriter cdata(_cycler_links); - CDLinksWriter cdata_child(child_node->_cycler_links); + CDWriter cdata(_cycler); + CDWriter cdata_child(child_node->_cycler); cdata->modify_down()->insert(DownConnection(child_node, sort)); cdata_child->modify_up()->insert(UpConnection(this)); @@ -820,8 +820,8 @@ add_stashed(PandaNode *child_node, int sort, Thread *current_thread) { remove_child(child_node); { - CDLinksWriter cdata(_cycler_links); - CDLinksWriter cdata_child(child_node->_cycler_links); + CDWriter cdata(_cycler); + CDWriter cdata_child(child_node->_cycler); cdata->modify_stashed()->insert(DownConnection(child_node, sort)); cdata_child->modify_up()->insert(UpConnection(this)); @@ -844,12 +844,12 @@ remove_stashed(int child_index, Thread *current_thread) { int pipeline_stage = current_thread->get_pipeline_stage(); nassertv(pipeline_stage == 0); - CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); Down &stashed = *cdata->modify_stashed(); nassertv(child_index >= 0 && child_index < (int)stashed.size()); PT(PandaNode) child_node = stashed[child_index].get_child(); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); + CDStageWriter cdata_child(child_node->_cycler, pipeline_stage, current_thread); stashed.erase(stashed.begin() + child_index); int num_erased = cdata_child->modify_up()->erase(UpConnection(this)); @@ -874,13 +874,13 @@ remove_stashed(int child_index, Thread *current_thread) { void PandaNode:: remove_all_children(Thread *current_thread) { // We have to do this for each upstream pipeline stage. - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links, current_thread) { - CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); Down &down = *cdata->modify_down(); Down::iterator di; for (di = down.begin(); di != down.end(); ++di) { PT(PandaNode) child_node = (*di).get_child(); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, + CDStageWriter cdata_child(child_node->_cycler, pipeline_stage, current_thread); cdata_child->modify_up()->erase(UpConnection(this)); @@ -892,7 +892,7 @@ remove_all_children(Thread *current_thread) { Down &stashed = *cdata->modify_stashed(); for (di = stashed.begin(); di != stashed.end(); ++di) { PT(PandaNode) child_node = (*di).get_child(); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, + CDStageWriter cdata_child(child_node->_cycler, pipeline_stage, current_thread); cdata_child->modify_up()->erase(UpConnection(this)); @@ -901,7 +901,7 @@ remove_all_children(Thread *current_thread) { } stashed.clear(); } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); force_bounds_stale(); children_changed(); @@ -988,8 +988,8 @@ set_attrib(const RenderAttrib *attrib, int override) { // upstream stages. bool any_changed = false; Thread *current_thread = Thread::get_current_thread(); - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) { - CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); CPT(RenderState) new_state = cdata->_state->add_attrib(attrib, override); if (cdata->_state != new_state) { @@ -997,7 +997,7 @@ set_attrib(const RenderAttrib *attrib, int override) { any_changed = true; } } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); // Maybe we changed a ClipPlaneAttrib. if (any_changed) { @@ -1019,8 +1019,8 @@ clear_attrib(TypeHandle type) { bool any_changed = false; Thread *current_thread = Thread::get_current_thread(); - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) { - CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); CPT(RenderState) new_state = cdata->_state->remove_attrib(type); if (cdata->_state != new_state) { @@ -1028,7 +1028,7 @@ clear_attrib(TypeHandle type) { any_changed = true; } } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); // We mark the bounds stale when the state changes, in case // we have changed a ClipPlaneAttrib. @@ -1050,11 +1050,11 @@ set_effect(const RenderEffect *effect) { // Apply this operation to the current stage as well as to all // upstream stages. Thread *current_thread = Thread::get_current_thread(); - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) { - CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); cdata->_effects = cdata->_effects->add_effect(effect); } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); } //////////////////////////////////////////////////////////////////// @@ -1066,11 +1066,11 @@ set_effect(const RenderEffect *effect) { void PandaNode:: clear_effect(TypeHandle type) { Thread *current_thread = Thread::get_current_thread(); - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) { - CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); cdata->_effects = cdata->_effects->remove_effect(type); } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); } //////////////////////////////////////////////////////////////////// @@ -1088,14 +1088,14 @@ set_state(const RenderState *state, Thread *current_thread) { // Apply this operation to the current stage as well as to all // upstream stages. bool any_changed = false; - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) { - CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); if (cdata->_state != state) { cdata->_state = state; any_changed = true; } } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); // Maybe we have changed a ClipPlaneAttrib. if (any_changed) { @@ -1116,11 +1116,11 @@ void PandaNode:: set_effects(const RenderEffects *effects, Thread *current_thread) { // Apply this operation to the current stage as well as to all // upstream stages. - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) { - CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); cdata->_effects = effects; } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); } //////////////////////////////////////////////////////////////////// @@ -1135,8 +1135,8 @@ set_transform(const TransformState *transform, Thread *current_thread) { // Apply this operation to the current stage as well as to all // upstream stages. bool any_changed = false; - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) { - CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); if (cdata->_transform != transform) { cdata->_transform = transform; any_changed = true; @@ -1148,7 +1148,7 @@ set_transform(const TransformState *transform, Thread *current_thread) { } } } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); if (any_changed) { mark_bounds_stale(current_thread); @@ -1168,8 +1168,8 @@ void PandaNode:: set_prev_transform(const TransformState *transform, Thread *current_thread) { // Apply this operation to the current stage as well as to all // upstream stages. - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) { - CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); cdata->_prev_transform = transform; if (pipeline_stage == 0) { if (cdata->_transform != cdata->_prev_transform) { @@ -1179,7 +1179,7 @@ set_prev_transform(const TransformState *transform, Thread *current_thread) { } } } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); } //////////////////////////////////////////////////////////////////// @@ -1196,11 +1196,11 @@ reset_prev_transform(Thread *current_thread) { // upstream stages. clear_dirty_prev_transform(); - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) { - CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); cdata->_prev_transform = cdata->_transform; } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); } //////////////////////////////////////////////////////////////////// @@ -1225,7 +1225,7 @@ reset_all_prev_transform(Thread *current_thread) { nassertv(panda_node->_dirty_prev_transform); panda_node->_dirty_prev_transform = false; - CDLightStageWriter cdata(panda_node->_cycler_light, 0, current_thread); + CDStageWriter cdata(panda_node->_cycler, 0, current_thread); cdata->_prev_transform = cdata->_transform; list_node = panda_node->_next; @@ -1256,11 +1256,11 @@ void PandaNode:: set_tag(const string &key, const string &value, Thread *current_thread) { // Apply this operation to the current stage as well as to all // upstream stages. - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) { - CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); cdata->_tag_data[key] = value; } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); } //////////////////////////////////////////////////////////////////// @@ -1272,11 +1272,11 @@ set_tag(const string &key, const string &value, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void PandaNode:: clear_tag(const string &key, Thread *current_thread) { - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) { - CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); cdata->_tag_data.erase(key); } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); } #ifdef HAVE_PYTHON @@ -1300,7 +1300,7 @@ set_python_tag(const string &key, PyObject *value) { int pipeline_stage = current_thread->get_pipeline_stage(); nassertv(pipeline_stage == 0); - CDHeavyWriter cdata(_cycler_heavy); + CDWriter cdata(_cycler); Py_XINCREF(value); pair result; @@ -1329,7 +1329,7 @@ set_python_tag(const string &key, PyObject *value) { //////////////////////////////////////////////////////////////////// PyObject *PandaNode:: get_python_tag(const string &key) const { - CDHeavyReader cdata(_cycler_heavy); + CDReader cdata(_cycler); PythonTagData::const_iterator ti; ti = cdata->_python_tag_data.find(key); if (ti != cdata->_python_tag_data.end()) { @@ -1351,7 +1351,7 @@ get_python_tag(const string &key) const { //////////////////////////////////////////////////////////////////// bool PandaNode:: has_python_tag(const string &key) const { - CDHeavyReader cdata(_cycler_heavy); + CDReader cdata(_cycler); PythonTagData::const_iterator ti; ti = cdata->_python_tag_data.find(key); return (ti != cdata->_python_tag_data.end()); @@ -1373,7 +1373,7 @@ clear_python_tag(const string &key) { int pipeline_stage = current_thread->get_pipeline_stage(); nassertv(pipeline_stage == 0); - CDHeavyWriter cdata(_cycler_heavy, current_thread); + CDWriter cdata(_cycler, current_thread); PythonTagData::iterator ti; ti = cdata->_python_tag_data.find(key); if (ti != cdata->_python_tag_data.end()) { @@ -1402,9 +1402,9 @@ copy_tags(PandaNode *other) { // Apply this operation to the current stage as well as to all // upstream stages. Thread *current_thread = Thread::get_current_thread(); - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) { - CDHeavyStageWriter cdataw(_cycler_heavy, pipeline_stage, current_thread); - CDHeavyStageReader cdatar(other->_cycler_heavy, pipeline_stage, + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdataw(_cycler, pipeline_stage, current_thread); + CDStageReader cdatar(other->_cycler, pipeline_stage, current_thread); TagData::const_iterator ti; @@ -1439,7 +1439,7 @@ copy_tags(PandaNode *other) { } #endif // HAVE_PYTHON } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); } //////////////////////////////////////////////////////////////////// @@ -1456,7 +1456,7 @@ copy_tags(PandaNode *other) { //////////////////////////////////////////////////////////////////// void PandaNode:: list_tags(ostream &out, const string &separator) const { - CDHeavyReader cdata(_cycler_heavy); + CDReader cdata(_cycler); if (!cdata->_tag_data.empty()) { TagData::const_iterator ti = cdata->_tag_data.begin(); out << (*ti).first; @@ -1526,8 +1526,8 @@ adjust_draw_mask(DrawMask show_mask, DrawMask hide_mask, DrawMask clear_mask) { bool any_changed = false; Thread *current_thread = Thread::get_current_thread(); - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) { - CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); DrawMask draw_control_mask = (cdata->_draw_control_mask | show_mask | hide_mask) & ~clear_mask; DrawMask draw_show_mask = (cdata->_draw_show_mask | show_mask) & ~hide_mask; @@ -1541,7 +1541,7 @@ adjust_draw_mask(DrawMask show_mask, DrawMask hide_mask, DrawMask clear_mask) { any_changed = true; } } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); if (any_changed) { mark_bounds_stale(current_thread); @@ -1565,10 +1565,10 @@ DrawMask PandaNode:: get_net_draw_control_mask() const { Thread *current_thread = Thread::get_current_thread(); int pipeline_stage = current_thread->get_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); if (cdata->_last_update != cdata->_next_update) { // The cache is stale; it needs to be rebuilt. - CDBoundsStageWriter cdataw = + CDStageWriter cdataw = ((PandaNode *)this)->update_bounds(pipeline_stage, cdata); return cdataw->_net_draw_control_mask; } @@ -1595,10 +1595,10 @@ DrawMask PandaNode:: get_net_draw_show_mask() const { Thread *current_thread = Thread::get_current_thread(); int pipeline_stage = current_thread->get_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); if (cdata->_last_update != cdata->_next_update) { // The cache is stale; it needs to be rebuilt. - CDBoundsStageWriter cdataw = + CDStageWriter cdataw = ((PandaNode *)this)->update_bounds(pipeline_stage, cdata); return cdataw->_net_draw_show_mask; } @@ -1628,14 +1628,14 @@ set_into_collide_mask(CollideMask mask) { bool any_changed = false; Thread *current_thread = Thread::get_current_thread(); - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) { - CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); if (cdata->_into_collide_mask != mask) { cdata->_into_collide_mask = mask; any_changed = true; } } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); if (any_changed) { mark_bounds_stale(current_thread); @@ -1667,10 +1667,10 @@ get_legal_collide_mask() const { CollideMask PandaNode:: get_net_collide_mask(Thread *current_thread) const { int pipeline_stage = current_thread->get_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); if (cdata->_last_update != cdata->_next_update) { // The cache is stale; it needs to be rebuilt. - CDBoundsStageWriter cdataw = + CDStageWriter cdataw = ((PandaNode *)this)->update_bounds(pipeline_stage, cdata); return cdataw->_net_collide_mask; } @@ -1687,10 +1687,10 @@ get_net_collide_mask(Thread *current_thread) const { CPT(RenderAttrib) PandaNode:: get_off_clip_planes(Thread *current_thread) const { int pipeline_stage = current_thread->get_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); if (cdata->_last_update != cdata->_next_update) { // The cache is stale; it needs to be rebuilt. - CDBoundsStageWriter cdataw = + CDStageWriter cdataw = ((PandaNode *)this)->update_bounds(pipeline_stage, cdata); return cdataw->_off_clip_planes; } @@ -1772,15 +1772,15 @@ write(ostream &out, int indent_level) const { void PandaNode:: set_bounds(const BoundingVolume *volume) { Thread *current_thread = Thread::get_current_thread(); - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) { - CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); if (volume == NULL) { cdata->_user_bounds = NULL; } else { cdata->_user_bounds = volume->make_copy(); } } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); mark_internal_bounds_stale(); } @@ -1808,12 +1808,12 @@ set_bound(const BoundingVolume *volume) { CPT(BoundingVolume) PandaNode:: get_bounds(Thread *current_thread) const { int pipeline_stage = current_thread->get_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); if (cdata->_last_update != cdata->_next_update) { // The cache is stale; it needs to be rebuilt. CPT(BoundingVolume) result; { - CDBoundsStageWriter cdataw = + CDStageWriter cdataw = ((PandaNode *)this)->update_bounds(pipeline_stage, cdata); result = cdataw->_external_bounds; } @@ -1827,7 +1827,7 @@ get_bounds(Thread *current_thread) const { // Access: Published // Description: Indicates that the bounding volume, or something that // influences the bounding volume (or any of the other -// things stored in CDataBounds, like net_collide_mask), +// things stored in CData, like net_collide_mask), // may have changed for this node, and that it must be // recomputed. // @@ -1842,10 +1842,10 @@ get_bounds(Thread *current_thread) const { //////////////////////////////////////////////////////////////////// void PandaNode:: mark_bounds_stale(Thread *current_thread) const { - OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) { + OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler, current_thread) { mark_bounds_stale(pipeline_stage, current_thread); } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler); } //////////////////////////////////////////////////////////////////// @@ -1900,9 +1900,9 @@ as_light() { //////////////////////////////////////////////////////////////////// CPT(BoundingVolume) PandaNode:: get_internal_bounds(int pipeline_stage, Thread *current_thread) const { - CDHeavyStageReader cdata(_cycler_heavy, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); if (cdata->_internal_bounds_stale) { - CDHeavyStageWriter cdataw(((PandaNode *)this)->_cycler_heavy, pipeline_stage, cdata); + CDStageWriter cdataw(((PandaNode *)this)->_cycler, pipeline_stage, cdata); if (cdataw->_user_bounds != (BoundingVolume *)NULL) { cdataw->_internal_bounds = cdataw->_user_bounds; } else { @@ -1926,12 +1926,12 @@ get_internal_bounds(int pipeline_stage, Thread *current_thread) const { void PandaNode:: set_internal_bounds(const BoundingVolume *volume) { Thread *current_thread = Thread::get_current_thread(); - OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) { - CDHeavyStageWriter cdataw(_cycler_heavy, pipeline_stage, current_thread); + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { + CDStageWriter cdataw(_cycler, pipeline_stage, current_thread); cdataw->_internal_bounds = volume; cdataw->_internal_bounds_stale = false; } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler); mark_bounds_stale(current_thread); } @@ -1948,10 +1948,10 @@ set_internal_bounds(const BoundingVolume *volume) { //////////////////////////////////////////////////////////////////// void PandaNode:: force_bounds_stale(Thread *current_thread) { - OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) { + OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler, current_thread) { force_bounds_stale(pipeline_stage, current_thread); } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler); } //////////////////////////////////////////////////////////////////// @@ -1964,7 +1964,7 @@ force_bounds_stale(Thread *current_thread) { void PandaNode:: force_bounds_stale(int pipeline_stage, Thread *current_thread) { { - CDBoundsStageWriter cdata(_cycler_bounds, pipeline_stage, current_thread); + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); ++cdata->_next_update; // It is important that we allow this lock to be dropped before we @@ -1977,7 +1977,7 @@ force_bounds_stale(int pipeline_stage, Thread *current_thread) { // through the parents list directly on the node. Parents parents; { - CDLinksStageReader cdata(_cycler_links, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); parents = Parents(cdata); } int num_parents = parents.get_num_parents(); @@ -2001,10 +2001,10 @@ force_bounds_stale(int pipeline_stage, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void PandaNode:: mark_internal_bounds_stale(Thread *current_thread) { - OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) { + OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler, current_thread) { mark_internal_bounds_stale(pipeline_stage, current_thread); } - CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links); + CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler); } //////////////////////////////////////////////////////////////////// @@ -2123,7 +2123,7 @@ r_copy_subgraph(PandaNode::InstanceMap &inst_map, Thread *current_thread) const void PandaNode:: r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map, Thread *current_thread) { - CDLinksReader from_cdata(from->_cycler_links, current_thread); + CDReader from_cdata(from->_cycler, current_thread); const Down &from_down = *from_cdata->get_down(); Down::const_iterator di; for (di = from_down.begin(); di != from_down.end(); ++di) { @@ -2154,7 +2154,7 @@ r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map, // Description: The private implementation of find_child(). //////////////////////////////////////////////////////////////////// int PandaNode:: -do_find_child(PandaNode *node, const CDataLinks *cdata) const { +do_find_child(PandaNode *node, const CData *cdata) const { nassertr(node != (PandaNode *)NULL, -1); // We have to search for the child by brute force, since we don't @@ -2176,7 +2176,7 @@ do_find_child(PandaNode *node, const CDataLinks *cdata) const { // Description: The private implementation of find_stashed(). //////////////////////////////////////////////////////////////////// int PandaNode:: -do_find_stashed(PandaNode *node, const CDataLinks *cdata) const { +do_find_stashed(PandaNode *node, const CData *cdata) const { nassertr(node != (PandaNode *)NULL, -1); // We have to search for the child by brute force, since we don't @@ -2202,11 +2202,11 @@ do_find_stashed(PandaNode *node, const CDataLinks *cdata) const { bool PandaNode:: stage_remove_child(PandaNode *child_node, int pipeline_stage, Thread *current_thread) { - CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); // First, look for the parent in the child's up list, to ensure the // child is known. - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, + CDStageWriter cdata_child(child_node->_cycler, pipeline_stage, current_thread); int parent_index = child_node->do_find_parent(this, cdata_child); if (parent_index < 0) { @@ -2251,9 +2251,9 @@ bool PandaNode:: stage_replace_child(PandaNode *orig_child, PandaNode *new_child, int pipeline_stage, Thread *current_thread) { { - CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); - CDLinksStageWriter cdata_orig_child(orig_child->_cycler_links, pipeline_stage, current_thread); - CDLinksStageWriter cdata_new_child(new_child->_cycler_links, pipeline_stage, current_thread); + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); + CDStageWriter cdata_orig_child(orig_child->_cycler, pipeline_stage, current_thread); + CDStageWriter cdata_new_child(new_child->_cycler, pipeline_stage, current_thread); // First, look for the parent in the child's up list, to ensure the // child is known. @@ -2392,8 +2392,8 @@ detach_one_stage(NodePathComponent *child, int pipeline_stage, PT(PandaNode) child_node = child->get_node(); PT(PandaNode) parent_node = child->get_next(pipeline_stage, current_thread)->get_node(); - CDLinksStageWriter cdata_parent(parent_node->_cycler_links, pipeline_stage, current_thread); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); + CDStageWriter cdata_parent(parent_node->_cycler, pipeline_stage, current_thread); + CDStageWriter cdata_child(child_node->_cycler, pipeline_stage, current_thread); int parent_index = child_node->do_find_parent(parent_node, cdata_child); if (parent_index >= 0) { // Now look for the child and break the actual connection. @@ -2498,7 +2498,7 @@ reparent_one_stage(NodePathComponent *new_parent, NodePathComponent *child, PandaNode *parent_node = new_parent->get_node(); { - CDLinksStageReader cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); + CDStageReader cdata_child(child_node->_cycler, pipeline_stage, current_thread); int parent_index = child_node->do_find_parent(parent_node, cdata_child); if (parent_index >= 0) { @@ -2512,8 +2512,8 @@ reparent_one_stage(NodePathComponent *new_parent, NodePathComponent *child, // Now reattach the child node at the indicated sort position. { - CDLinksStageWriter cdata_parent(parent_node->_cycler_links, pipeline_stage, current_thread); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); + CDStageWriter cdata_parent(parent_node->_cycler, pipeline_stage, current_thread); + CDStageWriter cdata_child(child_node->_cycler, pipeline_stage, current_thread); if (as_stashed) { cdata_parent->modify_stashed()->insert(DownConnection(child_node, sort)); @@ -2566,7 +2566,7 @@ get_component(NodePathComponent *parent, PandaNode *child_node, // We don't already have a NodePathComponent referring to this // parent-child relationship. Are they actually related? - CDLinksStageReader cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); + CDStageReader cdata_child(child_node->_cycler, pipeline_stage, current_thread); int parent_index = child_node->do_find_parent(parent_node, cdata_child); if (parent_index >= 0) { @@ -2668,7 +2668,7 @@ r_get_generic_component(bool accept_ambiguity, bool &ambiguity_detected, PT(PandaNode) parent_node; { - CDLinksStageReader cdata(_cycler_links, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); int num_parents = cdata->get_up()->size(); if (num_parents == 0) { @@ -2813,7 +2813,7 @@ fix_path_lengths(int pipeline_stage, Thread *current_thread) { Children children; Stashed stashed; { - CDLinksStageReader cdata(_cycler_links, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); children = Children(cdata); stashed = Stashed(cdata); } @@ -2867,8 +2867,8 @@ r_list_descendants(ostream &out, int indent_level) const { // The old value should be passed in; it will be // released. The new value is returned. //////////////////////////////////////////////////////////////////// -PandaNode::CDBoundsStageWriter PandaNode:: -update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { +PandaNode::CDStageWriter PandaNode:: +update_bounds(int pipeline_stage, PandaNode::CDStageReader &cdata) { // We might need to try this a couple of times, in case someone else // steps on our result. if (drawmask_cat.is_debug()) { @@ -2881,8 +2881,8 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { // Grab the last_update counter, then release the lock. UpdateSeq last_update = cdata->_last_update; UpdateSeq next_update = cdata->_next_update; - nassertr(last_update != next_update, CDBoundsStageWriter(_cycler_bounds, pipeline_stage, cdata)); - _cycler_bounds.release_read_stage(pipeline_stage, cdata.take_pointer()); + nassertr(last_update != next_update, CDStageWriter(_cycler, pipeline_stage, cdata)); + _cycler.release_read_stage(pipeline_stage, cdata.take_pointer()); // Start with a clean slate, or at least with the contents of the // node itself. @@ -2891,7 +2891,7 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { DrawMask draw_control_mask, draw_show_mask; bool renderable = is_renderable(); { - CDHeavyStageReader cdata(_cycler_heavy, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); net_collide_mask = cdata->_into_collide_mask; draw_control_mask = net_draw_control_mask = cdata->_draw_control_mask; draw_show_mask = net_draw_show_mask = cdata->_draw_show_mask; @@ -2916,7 +2916,7 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { } CPT(RenderAttrib) off_clip_planes; { - CDLightStageReader cdata(_cycler_light, pipeline_stage, current_thread); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); off_clip_planes = cdata->_state->get_clip_plane(); } if (off_clip_planes == (RenderAttrib *)NULL) { @@ -2945,10 +2945,10 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { const ClipPlaneAttrib *orig_cp = DCAST(ClipPlaneAttrib, off_clip_planes); - CDBoundsStageReader child_cdata(child->_cycler_bounds, pipeline_stage, current_thread); + CDStageReader child_cdata(child->_cycler, pipeline_stage, current_thread); if (child_cdata->_last_update != child_cdata->_next_update) { // Child needs update. - CDBoundsStageWriter child_cdataw = child->update_bounds(pipeline_stage, child_cdata); + CDStageWriter child_cdataw = child->update_bounds(pipeline_stage, child_cdata); net_collide_mask |= child_cdataw->_net_collide_mask; @@ -3028,7 +3028,7 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { { // Now grab the write lock on this node. - CDBoundsStageWriter cdataw(_cycler_bounds, pipeline_stage, current_thread); + CDStageWriter cdataw(_cycler, pipeline_stage, current_thread); if (last_update == cdataw->_last_update && next_update == cdataw->_next_update) { // Great, no one has monkeyed with these while we were computing @@ -3089,12 +3089,12 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { // We need to go around again. Release the write lock, and grab // the read lock back. - cdata = CDBoundsStageReader(_cycler_bounds, pipeline_stage, current_thread); + cdata = CDStageReader(_cycler, pipeline_stage, current_thread); if (cdata->_last_update == cdata->_next_update) { // Someone else has computed the cache for us while we were // diddling with the locks. OK. - return CDBoundsStageWriter(_cycler_bounds, pipeline_stage, cdata); + return CDStageWriter(_cycler, pipeline_stage, cdata); } } while (true); @@ -3122,9 +3122,7 @@ write_datagram(BamWriter *manager, Datagram &dg) { TypedWritable::write_datagram(manager, dg); dg.add_string(get_name()); - manager->write_cdata(dg, _cycler_light); - manager->write_cdata(dg, _cycler_heavy); - manager->write_cdata(dg, _cycler_links); + manager->write_cdata(dg, _cycler); } //////////////////////////////////////////////////////////////////// @@ -3182,9 +3180,7 @@ fillin(DatagramIterator &scan, BamReader *manager) { string name = scan.get_string(); set_name(name); - manager->read_cdata(scan, _cycler_light); - manager->read_cdata(scan, _cycler_heavy); - manager->read_cdata(scan, _cycler_links); + manager->read_cdata(scan, _cycler); } //////////////////////////////////////////////////////////////////// @@ -3203,60 +3199,143 @@ fillin_recorder(DatagramIterator &scan, BamReader *) { } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLight::Copy Constructor +// Function: PandaNode::CData::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -PandaNode::CDataLight:: -CDataLight(const PandaNode::CDataLight ©) : +PandaNode::CData:: +CData() { + _state = RenderState::make_empty(); + _transform = TransformState::make_identity(); + _prev_transform = TransformState::make_identity(); + + _effects = RenderEffects::make_empty(); + _draw_control_mask = DrawMask::all_off(); + _draw_show_mask = DrawMask::all_on(); + _into_collide_mask = CollideMask::all_off(); + _user_bounds = NULL; + _internal_bounds = NULL; + _internal_bounds_stale = true; + _final_bounds = false; + + _net_collide_mask = CollideMask::all_off(); + _net_draw_control_mask = DrawMask::all_off(); + _net_draw_show_mask = DrawMask::all_off(); + ++_next_update; + + _down = new PandaNode::Down; + _stashed = new PandaNode::Down; + _up = new PandaNode::Up; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::CData::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +PandaNode::CData:: +CData(const PandaNode::CData ©) : _state(copy._state), _transform(copy._transform), - _prev_transform(copy._prev_transform) + _prev_transform(copy._prev_transform), + + _effects(copy._effects), + _tag_data(copy._tag_data), + _draw_control_mask(copy._draw_control_mask), + _draw_show_mask(copy._draw_show_mask), + _into_collide_mask(copy._into_collide_mask), + _user_bounds(copy._user_bounds), + _internal_bounds(copy._internal_bounds), + _internal_bounds_stale(copy._internal_bounds_stale), + _final_bounds(copy._final_bounds), + + _net_collide_mask(copy._net_collide_mask), + _net_draw_control_mask(copy._net_draw_control_mask), + _net_draw_show_mask(copy._net_draw_show_mask), + _off_clip_planes(copy._off_clip_planes), + _external_bounds(copy._external_bounds), + _last_update(copy._last_update), + _next_update(copy._next_update), + + _down(copy._down), + _stashed(copy._stashed), + _up(copy._up) { // Note that this copy constructor is not used by the PandaNode copy // constructor! Any elements that must be copied between nodes // should also be explicitly copied there. + +#ifdef HAVE_PYTHON + // Copy and increment all of the Python objects held by the other + // node. + _python_tag_data = _python_tag_data; + inc_py_refs(); +#endif // HAVE_PYTHON } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLight::Destructor +// Function: PandaNode::CData::Destructor // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -PandaNode::CDataLight:: -~CDataLight() { +PandaNode::CData:: +~CData() { +#ifdef HAVE_PYTHON + // Free all of the Python objects held by this node. + dec_py_refs(); +#endif // HAVE_PYTHON } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLight::make_copy +// Function: PandaNode::CData::make_copy // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -CycleData *PandaNode::CDataLight:: +CycleData *PandaNode::CData:: make_copy() const { - return new CDataLight(*this); + return new CData(*this); } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLight::write_datagram +// Function: PandaNode::CData::write_datagram // Access: Public, Virtual // Description: Writes the contents of this object to the datagram // for shipping out to a Bam file. //////////////////////////////////////////////////////////////////// -void PandaNode::CDataLight:: +void PandaNode::CData:: write_datagram(BamWriter *manager, Datagram &dg) const { manager->write_pointer(dg, _state); manager->write_pointer(dg, _transform); + + // + manager->write_pointer(dg, _effects); + + dg.add_uint32(_draw_control_mask.get_word()); + dg.add_uint32(_draw_show_mask.get_word()); + dg.add_uint32(_into_collide_mask.get_word()); + + dg.add_uint32(_tag_data.size()); + TagData::const_iterator ti; + for (ti = _tag_data.begin(); ti != _tag_data.end(); ++ti) { + dg.add_string((*ti).first); + dg.add_string((*ti).second); + } + + // + write_up_list(*get_up(), manager, dg); + write_down_list(*get_down(), manager, dg); + write_down_list(*get_stashed(), manager, dg); + } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLight::complete_pointers +// Function: PandaNode::CData::complete_pointers // Access: Public, Virtual // Description: Receives an array of pointers, one for each time // manager->read_pointer() was called in fillin(). // Returns the number of pointers processed. //////////////////////////////////////////////////////////////////// -int PandaNode::CDataLight:: +int PandaNode::CData:: complete_pointers(TypedWritable **p_list, BamReader *manager) { int pi = CycleData::complete_pointers(p_list, manager); @@ -3276,107 +3355,7 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { manager->finalize_now((RenderState *)_state.p()); manager->finalize_now((TransformState *)_transform.p()); - return pi; -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLight::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 PandaNode. -//////////////////////////////////////////////////////////////////// -void PandaNode::CDataLight:: -fillin(DatagramIterator &scan, BamReader *manager) { - // Read the state and transform pointers. - manager->read_pointer(scan); - manager->read_pointer(scan); -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataHeavy::Copy Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -PandaNode::CDataHeavy:: -CDataHeavy(const PandaNode::CDataHeavy ©) : - _effects(copy._effects), - _tag_data(copy._tag_data), - _draw_control_mask(copy._draw_control_mask), - _draw_show_mask(copy._draw_show_mask), - _into_collide_mask(copy._into_collide_mask), - _user_bounds(copy._user_bounds), - _internal_bounds(copy._internal_bounds), - _internal_bounds_stale(copy._internal_bounds_stale), - _final_bounds(copy._final_bounds) -{ - // Note that this copy constructor is not used by the PandaNode copy - // constructor! Any elements that must be copied between nodes - // should also be explicitly copied there. - -#ifdef HAVE_PYTHON - // Copy and increment all of the Python objects held by the other - // node. - _python_tag_data = _python_tag_data; - inc_py_refs(); -#endif // HAVE_PYTHON -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataHeavy::Destructor -// Access: Public, Virtual -// Description: -//////////////////////////////////////////////////////////////////// -PandaNode::CDataHeavy:: -~CDataHeavy() { -#ifdef HAVE_PYTHON - // Free all of the Python objects held by this node. - dec_py_refs(); -#endif // HAVE_PYTHON -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataHeavy::make_copy -// Access: Public, Virtual -// Description: -//////////////////////////////////////////////////////////////////// -CycleData *PandaNode::CDataHeavy:: -make_copy() const { - return new CDataHeavy(*this); -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataHeavy::write_datagram -// Access: Public, Virtual -// Description: Writes the contents of this object to the datagram -// for shipping out to a Bam file. -//////////////////////////////////////////////////////////////////// -void PandaNode::CDataHeavy:: -write_datagram(BamWriter *manager, Datagram &dg) const { - manager->write_pointer(dg, _effects); - - dg.add_uint32(_draw_control_mask.get_word()); - dg.add_uint32(_draw_show_mask.get_word()); - dg.add_uint32(_into_collide_mask.get_word()); - - dg.add_uint32(_tag_data.size()); - TagData::const_iterator ti; - for (ti = _tag_data.begin(); ti != _tag_data.end(); ++ti) { - dg.add_string((*ti).first); - dg.add_string((*ti).second); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataHeavy::complete_pointers -// Access: Public, Virtual -// Description: Receives an array of pointers, one for each time -// manager->read_pointer() was called in fillin(). -// Returns the number of pointers processed. -//////////////////////////////////////////////////////////////////// -int PandaNode::CDataHeavy:: -complete_pointers(TypedWritable **p_list, BamReader *manager) { - int pi = CycleData::complete_pointers(p_list, manager); + // // Get the effects pointer. _effects = DCAST(RenderEffects, p_list[pi++]); @@ -3391,18 +3370,30 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { // leak (see the comments in TransformState::finalize(), etc.). manager->finalize_now((RenderEffects *)_effects.p()); + // + + // Get the parent and child pointers. + pi += complete_up_list(*modify_up(), p_list + pi, manager); + pi += complete_down_list(*modify_down(), p_list + pi, manager); + pi += complete_down_list(*modify_stashed(), p_list + pi, manager); + return pi; } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataHeavy::fillin +// Function: PandaNode::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 PandaNode. //////////////////////////////////////////////////////////////////// -void PandaNode::CDataHeavy:: +void PandaNode::CData:: fillin(DatagramIterator &scan, BamReader *manager) { + // Read the state and transform pointers. + manager->read_pointer(scan); + manager->read_pointer(scan); + + // // Read the effects pointer. manager->read_pointer(scan); @@ -3441,16 +3432,22 @@ fillin(DatagramIterator &scan, BamReader *manager) { string value = scan.get_string(); _tag_data[key] = value; } + + // + fillin_up_list(*modify_up(), scan, manager); + fillin_down_list(*modify_down(), scan, manager); + fillin_down_list(*modify_stashed(), scan, manager); + } #ifdef HAVE_PYTHON //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataHeavy::inc_py_refs +// Function: PandaNode::CData::inc_py_refs // Access: Public // Description: Increments the reference counts on all held Python // objects. //////////////////////////////////////////////////////////////////// -void PandaNode::CDataHeavy:: +void PandaNode::CData:: inc_py_refs() { PythonTagData::const_iterator ti; for (ti = _python_tag_data.begin(); @@ -3464,12 +3461,12 @@ inc_py_refs() { #ifdef HAVE_PYTHON //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataHeavy::dec_py_refs +// Function: PandaNode::CData::dec_py_refs // Access: Public // Description: Decrements the reference counts on all held Python // objects. //////////////////////////////////////////////////////////////////// -void PandaNode::CDataHeavy:: +void PandaNode::CData:: dec_py_refs() { PythonTagData::const_iterator ti; for (ti = _python_tag_data.begin(); @@ -3482,132 +3479,12 @@ dec_py_refs() { #endif // HAVE_PYTHON //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataBounds::Copy Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -PandaNode::CDataBounds:: -CDataBounds(const PandaNode::CDataBounds ©) : - _net_collide_mask(copy._net_collide_mask), - _net_draw_control_mask(copy._net_draw_control_mask), - _net_draw_show_mask(copy._net_draw_show_mask), - _off_clip_planes(copy._off_clip_planes), - _external_bounds(copy._external_bounds), - _last_update(copy._last_update), - _next_update(copy._next_update) -{ - // Note that this copy constructor is not used by the PandaNode copy - // constructor! Any elements that must be copied between nodes - // should also be explicitly copied there. -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataBounds::Destructor -// Access: Public, Virtual -// Description: -//////////////////////////////////////////////////////////////////// -PandaNode::CDataBounds:: -~CDataBounds() { -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataBounds::make_copy -// Access: Public, Virtual -// Description: -//////////////////////////////////////////////////////////////////// -CycleData *PandaNode::CDataBounds:: -make_copy() const { - return new CDataBounds(*this); -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::Copy Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -PandaNode::CDataLinks:: -CDataLinks(const PandaNode::CDataLinks ©) : - _down(copy._down), - _stashed(copy._stashed), - _up(copy._up) -{ - // Note that this copy constructor is not used by the PandaNode copy - // constructor! Any elements that must be copied between nodes - // should also be explicitly copied there. -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::Destructor -// Access: Public, Virtual -// Description: -//////////////////////////////////////////////////////////////////// -PandaNode::CDataLinks:: -~CDataLinks() { -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::make_copy -// Access: Public, Virtual -// Description: -//////////////////////////////////////////////////////////////////// -CycleData *PandaNode::CDataLinks:: -make_copy() const { - return new CDataLinks(*this); -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::write_datagram -// Access: Public, Virtual -// Description: Writes the contents of this object to the datagram -// for shipping out to a Bam file. -//////////////////////////////////////////////////////////////////// -void PandaNode::CDataLinks:: -write_datagram(BamWriter *manager, Datagram &dg) const { - write_up_list(*get_up(), manager, dg); - write_down_list(*get_down(), manager, dg); - write_down_list(*get_stashed(), manager, dg); -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::complete_pointers -// Access: Public, Virtual -// Description: Receives an array of pointers, one for each time -// manager->read_pointer() was called in fillin(). -// Returns the number of pointers processed. -//////////////////////////////////////////////////////////////////// -int PandaNode::CDataLinks:: -complete_pointers(TypedWritable **p_list, BamReader *manager) { - int pi = CycleData::complete_pointers(p_list, manager); - - // Get the parent and child pointers. - pi += complete_up_list(*modify_up(), p_list + pi, manager); - pi += complete_down_list(*modify_down(), p_list + pi, manager); - pi += complete_down_list(*modify_stashed(), p_list + pi, manager); - - return pi; -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::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 PandaNode. -//////////////////////////////////////////////////////////////////// -void PandaNode::CDataLinks:: -fillin(DatagramIterator &scan, BamReader *manager) { - fillin_up_list(*modify_up(), scan, manager); - fillin_down_list(*modify_down(), scan, manager); - fillin_down_list(*modify_stashed(), scan, manager); -} - -//////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::write_up_list +// Function: PandaNode::CData::write_up_list // Access: Public // Description: Writes the indicated list of parent node pointers to // the datagram. //////////////////////////////////////////////////////////////////// -void PandaNode::CDataLinks:: +void PandaNode::CData:: write_up_list(const PandaNode::Up &up_list, BamWriter *manager, Datagram &dg) const { // When we write a PandaNode, we write out its complete list of @@ -3638,12 +3515,12 @@ write_up_list(const PandaNode::Up &up_list, } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::write_down_list +// Function: PandaNode::CData::write_down_list // Access: Public // Description: Writes the indicated list of child node pointers to // the datagram. //////////////////////////////////////////////////////////////////// -void PandaNode::CDataLinks:: +void PandaNode::CData:: write_down_list(const PandaNode::Down &down_list, BamWriter *manager, Datagram &dg) const { int num_children = down_list.size(); @@ -3662,12 +3539,12 @@ write_down_list(const PandaNode::Down &down_list, } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::complete_up_list +// Function: PandaNode::CData::complete_up_list // Access: Public // Description: Calls complete_pointers() on the list of parent node // pointers. //////////////////////////////////////////////////////////////////// -int PandaNode::CDataLinks:: +int PandaNode::CData:: complete_up_list(PandaNode::Up &up_list, TypedWritable **p_list, BamReader *manager) { int pi = 0; @@ -3694,12 +3571,12 @@ complete_up_list(PandaNode::Up &up_list, } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::complete_down_list +// Function: PandaNode::CData::complete_down_list // Access: Public // Description: Calls complete_pointers() on the list of child node // pointers. //////////////////////////////////////////////////////////////////// -int PandaNode::CDataLinks:: +int PandaNode::CData:: complete_down_list(PandaNode::Down &down_list, TypedWritable **p_list, BamReader *manager) { int pi = 0; @@ -3719,13 +3596,13 @@ complete_down_list(PandaNode::Down &down_list, } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::fillin_up_list +// Function: PandaNode::CData::fillin_up_list // Access: Public // Description: Reads the indicated list parent node pointers from // the datagram (or at least calls read_pointer() for // each one). //////////////////////////////////////////////////////////////////// -void PandaNode::CDataLinks:: +void PandaNode::CData:: fillin_up_list(PandaNode::Up &up_list, DatagramIterator &scan, BamReader *manager) { int num_parents = scan.get_uint16(); @@ -3738,13 +3615,13 @@ fillin_up_list(PandaNode::Up &up_list, } //////////////////////////////////////////////////////////////////// -// Function: PandaNode::CDataLinks::fillin_down_list +// Function: PandaNode::CData::fillin_down_list // Access: Public // Description: Reads the indicated list child node pointers from // the datagram (or at least calls read_pointer() for // each one). //////////////////////////////////////////////////////////////////// -void PandaNode::CDataLinks:: +void PandaNode::CData:: fillin_down_list(PandaNode::Down &down_list, DatagramIterator &scan, BamReader *manager) { int num_children = scan.get_uint16(); diff --git a/panda/src/pgraph/pandaNode.h b/panda/src/pgraph/pandaNode.h index 66624917ce..444d6fda85 100644 --- a/panda/src/pgraph/pandaNode.h +++ b/panda/src/pgraph/pandaNode.h @@ -110,12 +110,6 @@ public: virtual int get_visible_child() const; virtual bool is_renderable() const; - INLINE void compose_draw_mask(DrawMask &running_draw_mask, - Thread *current_thread) const; - INLINE bool compare_draw_mask(DrawMask running_draw_mask, - DrawMask camera_mask, - Thread *current_thread) const; - PUBLISHED: PT(PandaNode) copy_subgraph(Thread *current_thread = Thread::get_current_thread()) const; @@ -280,14 +274,11 @@ protected: Thread *current_thread); private: - class CDataLight; - class CDataHeavy; - class CDataBounds; - class CDataLinks; + class CData; - INLINE int do_find_parent(PandaNode *node, const CDataLinks *cdata) const; - int do_find_child(PandaNode *node, const CDataLinks *cdata) const; - int do_find_stashed(PandaNode *node, const CDataLinks *cdata) const; + INLINE int do_find_parent(PandaNode *node, const CData *cdata) const; + int do_find_child(PandaNode *node, const CData *cdata) const; + int do_find_stashed(PandaNode *node, const CData *cdata) const; bool stage_remove_child(PandaNode *child_node, int pipeline_stage, Thread *current_thread); bool stage_replace_child(PandaNode *orig_child, PandaNode *new_child, @@ -387,21 +378,14 @@ private: #endif // HAVE_PYTHON - // This is the data that must be cycled between pipeline stages. We - // store it in several different CData objects, in an attempt to - // minimize overhead caused by cycling data unnecessarily. The - // things that are likely to change often (and at the same time) are - // grouped into the same CData object; things that change less often - // are grouped into a different one. + // This is the data that must be cycled between pipeline stages. - // The CDataLight object stores the lightweight parts of the node - // that are likely to change fairly often: transform and state. - class EXPCL_PANDA CDataLight : public CycleData { + class EXPCL_PANDA CData : public CycleData { public: - INLINE CDataLight(); - CDataLight(const CDataLight ©); - virtual ~CDataLight(); - ALLOC_DELETED_CHAIN(CDataLight); + CData(); + CData(const CData ©); + virtual ~CData(); + ALLOC_DELETED_CHAIN(CData); virtual CycleData *make_copy() const; virtual void write_datagram(BamWriter *manager, Datagram &dg) const; @@ -411,34 +395,18 @@ private: return PandaNode::get_class_type(); } + public: + // This section contains the lightweight parts of the node that + // are likely to change fairly often: transform and state. + NCPT(RenderState) _state; NCPT(TransformState) _transform; NCPT(TransformState) _prev_transform; - }; - PipelineCycler _cycler_light; - typedef CycleDataReader CDLightReader; - typedef CycleDataWriter CDLightWriter; - typedef CycleDataStageReader CDLightStageReader; - typedef CycleDataStageWriter CDLightStageWriter; - - // The CDataHeavy object stores the heavierweight parts of the node - // that are less likely to change as often: tags, collide mask. - class EXPCL_PANDA CDataHeavy : public CycleData { public: - INLINE CDataHeavy(); - CDataHeavy(const CDataHeavy ©); - virtual ~CDataHeavy(); - ALLOC_DELETED_CHAIN(CDataHeavy); - - virtual CycleData *make_copy() const; - virtual void write_datagram(BamWriter *manager, Datagram &dg) const; - virtual int complete_pointers(TypedWritable **plist, BamReader *manager); - virtual void fillin(DatagramIterator &scan, BamReader *manager); - virtual TypeHandle get_parent_type() const { - return PandaNode::get_class_type(); - } - + // This section contains the heavierweight parts of the node that + // are less likely to change as often: tags, collide mask. + #ifdef HAVE_PYTHON void inc_py_refs(); void dec_py_refs(); @@ -475,29 +443,12 @@ private: // This is true if the external bounds of this node should be // deemed "final". See set_final(). bool _final_bounds; - }; - PipelineCycler _cycler_heavy; - typedef CycleDataReader CDHeavyReader; - typedef CycleDataWriter CDHeavyWriter; - typedef CycleDataStageReader CDHeavyStageReader; - typedef CycleDataStageWriter CDHeavyStageWriter; - - // The CDataBounds object stores the data that is accumulated upward - // from the node's children: that is, the external bounding volume, - // and conceptually similar things like the net_collide_mask, etc. - // None of the data in this object is preserved in a bam file. - class EXPCL_PANDA CDataBounds : public CycleData { public: - INLINE CDataBounds(); - CDataBounds(const CDataBounds ©); - virtual ~CDataBounds(); - ALLOC_DELETED_CHAIN(CDataBounds); - - virtual CycleData *make_copy() const; - virtual TypeHandle get_parent_type() const { - return PandaNode::get_class_type(); - } + // This section contains the data that is accumulated upward from + // the node's children: that is, the external bounding volume, and + // conceptually similar things like the net_collide_mask, etc. + // None of the data in this object is preserved in a bam file. // This is the union of all into_collide_mask bits for any nodes // at and below this level. @@ -518,30 +469,10 @@ private: // When _last_update != _next_update, this cache is stale. UpdateSeq _last_update, _next_update; - }; - PipelineCycler _cycler_bounds; - typedef CycleDataReader CDBoundsReader; - typedef CycleDataWriter CDBoundsWriter; - typedef CycleDataStageReader CDBoundsStageReader; - typedef CycleDataStageWriter CDBoundsStageWriter; - - // The CDataLinks object stores the links to other nodes above and - // below this node in the graph. - class EXPCL_PANDA CDataLinks : public CycleData { public: - INLINE CDataLinks(); - CDataLinks(const CDataLinks ©); - virtual ~CDataLinks(); - ALLOC_DELETED_CHAIN(CDataLinks); - - virtual CycleData *make_copy() const; - virtual void write_datagram(BamWriter *manager, Datagram &dg) const; - virtual int complete_pointers(TypedWritable **plist, BamReader *manager); - virtual void fillin(DatagramIterator &scan, BamReader *manager); - virtual TypeHandle get_parent_type() const { - return PandaNode::get_class_type(); - } + // This section stores the links to other nodes above and below + // this node in the graph. void write_up_list(const Up &up_list, BamWriter *manager, Datagram &dg) const; @@ -571,14 +502,13 @@ private: PT(Up) _up; }; - PipelineCycler _cycler_links; - typedef CycleDataReader CDLinksReader; - typedef CycleDataWriter CDLinksWriter; - typedef CycleDataStageReader CDLinksStageReader; - typedef CycleDataStageWriter CDLinksStageWriter; + PipelineCycler _cycler; + typedef CycleDataReader CDReader; + typedef CycleDataWriter CDWriter; + typedef CycleDataStageReader CDStageReader; + typedef CycleDataStageWriter CDStageWriter; - CDBoundsStageWriter update_bounds(int pipeline_stage, - CDBoundsStageReader &cdata); + CDStageWriter update_bounds(int pipeline_stage, CDStageReader &cdata); static DrawMask _overall_bit; @@ -595,7 +525,7 @@ public: class EXPCL_PANDA Children { public: INLINE Children(); - INLINE Children(const CDataLinks *cdata); + INLINE Children(const CData *cdata); INLINE Children(const Children ©); INLINE void operator = (const Children ©); @@ -611,7 +541,7 @@ public: class EXPCL_PANDA Stashed { public: INLINE Stashed(); - INLINE Stashed(const CDataLinks *cdata); + INLINE Stashed(const CData *cdata); INLINE Stashed(const Stashed ©); INLINE void operator = (const Stashed ©); @@ -627,7 +557,7 @@ public: class EXPCL_PANDA Parents { public: INLINE Parents(); - INLINE Parents(const CDataLinks *cdata); + INLINE Parents(const CData *cdata); INLINE Parents(const Parents ©); INLINE void operator = (const Parents ©); @@ -678,6 +608,70 @@ private: friend class NodePath; friend class NodePathComponent; friend class WorkingNodePath; + friend class PandaNodePipelineReader; +}; + +//////////////////////////////////////////////////////////////////// +// Class : PandaNodePipelineReader +// Description : Encapsulates the data from a PandaNode, +// pre-fetched for one stage of the pipeline. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA PandaNodePipelineReader { +public: + INLINE PandaNodePipelineReader(const PandaNode *object, Thread *current_thread); + INLINE PandaNodePipelineReader(const PandaNodePipelineReader ©); + INLINE void operator = (const PandaNodePipelineReader ©); + +public: + INLINE ~PandaNodePipelineReader(); + ALLOC_DELETED_CHAIN(PandaNodePipelineReader); + + INLINE const PandaNode *get_object() const; + INLINE Thread *get_current_thread() const; + + INLINE void release(); + + INLINE void check_bounds() const; + + INLINE void compose_draw_mask(DrawMask &running_draw_mask) const; + INLINE bool compare_draw_mask(DrawMask running_draw_mask, + DrawMask camera_mask) const; + + INLINE int get_num_parents() const; + INLINE PandaNode *get_parent(int n) const; + INLINE int find_parent(PandaNode *node) const; + + INLINE int get_num_children() const; + INLINE PandaNode *get_child(int n) const; + INLINE int get_child_sort(int n) const; + INLINE int find_child(PandaNode *node) const; + + INLINE int get_num_stashed() const; + INLINE PandaNode *get_stashed(int n) const; + INLINE int get_stashed_sort(int n) const; + INLINE int find_stashed(PandaNode *node) const; + + INLINE const RenderState *get_state() const; + INLINE const RenderEffects *get_effects() const; + INLINE const TransformState *get_transform() const; + INLINE const TransformState *get_prev_transform() const; + + INLINE string get_tag(const string &key) const; + INLINE bool has_tag(const string &key) const; + + INLINE CollideMask get_net_collide_mask() const; + INLINE CPT(RenderAttrib) get_off_clip_planes() const; + INLINE CPT(BoundingVolume) get_bounds() const; + INLINE bool is_final() const; + + INLINE PandaNode::Children get_children() const; + INLINE PandaNode::Stashed get_stashed() const; + INLINE PandaNode::Parents get_parents() const; + +private: + const PandaNode *_object; + Thread *_current_thread; + const PandaNode::CData *_cdata; }; INLINE ostream &operator << (ostream &out, const PandaNode &node) { diff --git a/panda/src/pgraph/portalNode.cxx b/panda/src/pgraph/portalNode.cxx index 1bffe6ef56..5c3c5cbf1a 100755 --- a/panda/src/pgraph/portalNode.cxx +++ b/panda/src/pgraph/portalNode.cxx @@ -253,6 +253,8 @@ has_cull_callback() const { //////////////////////////////////////////////////////////////////// bool PortalNode:: cull_callback(CullTraverser *trav, CullTraverserData &data) { + Thread *current_thread = trav->get_current_thread(); + PortalClipper *portal_viewer = trav->get_portal_clipper(); set_visible(false); if (is_open() && !_cell_out.is_empty() && portal_viewer) { @@ -312,7 +314,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { CullTraverserData next_data(_cell_out, cell_transform, - next_state, new_bh, NULL); + next_state, new_bh, NULL, + current_thread); // data._state, new_bh, NULL); // Make this cell show with the reduced frustum