22 CDReader cdata(_cycler, current_thread);
23 return cdata->get_up()->size();
33 CDReader cdata(_cycler, current_thread);
34 CPT(Up) up = cdata->get_up();
35 nassertr(n >= 0 && n < (
int)up->size(),
nullptr);
36 return (*up)[n].get_parent();
45 CDReader cdata(_cycler, current_thread);
46 return do_find_parent(node, cdata);
56 CDReader cdata(_cycler, current_thread);
57 return cdata->get_down()->size();
67 CDReader cdata(_cycler, current_thread);
68 CPT(Down) down = cdata->get_down();
69 nassertr(n >= 0 && n < (
int)down->size(),
nullptr);
70 return (*down)[n].get_child();
79 CDReader cdata(_cycler, current_thread);
80 CPT(
Down) down = cdata->get_down();
81 nassertr(n >= 0 && n < (
int)down->size(), -1);
82 return (*down)[n].get_sort();
91 CDReader cdata(_cycler, current_thread);
92 return do_find_child(node, cdata->get_down());
108 int child_index =
find_child(child_node, current_thread);
109 if (child_index < 0) {
129 int stashed_index =
find_stashed(child_node, current_thread);
130 if (stashed_index < 0) {
144 CDReader cdata(_cycler, current_thread);
145 return cdata->get_stashed()->size();
155 CDReader cdata(_cycler, current_thread);
156 CPT(Down) stashed = cdata->get_stashed();
157 nassertr(n >= 0 && n < (
int)stashed->size(),
nullptr);
158 return (*stashed)[n].get_child();
167 CDReader cdata(_cycler, current_thread);
168 CPT(
Down) stashed = cdata->get_stashed();
169 nassertr(n >= 0 && n < (
int)stashed->size(), -1);
170 return (*stashed)[n].get_sort();
179 CDReader cdata(_cycler, current_thread);
180 return do_find_child(node, cdata->get_stashed());
191 CDReader cdata(_cycler);
192 return cdata->_state->get_attrib(type);
202 get_attrib(
int slot)
const {
203 CDReader cdata(_cycler);
204 return cdata->_state->get_attrib(slot);
211 INLINE
bool PandaNode::
213 CDReader cdata(_cycler);
214 return cdata->_state->has_attrib(type);
221 INLINE
bool PandaNode::
222 has_attrib(
int slot)
const {
223 CDReader cdata(_cycler);
224 return cdata->_state->has_attrib(slot);
232 INLINE
void PandaNode::
245 CDReader cdata(_cycler);
246 int index = cdata->_effects->find_effect(type);
248 return cdata->_effects->get_effect(index);
257 INLINE
bool PandaNode::
259 CDReader cdata(_cycler);
260 int index = cdata->_effects->find_effect(type);
271 get_state(
Thread *current_thread)
const {
272 CDReader cdata(_cycler, current_thread);
273 return cdata->_state.p();
281 INLINE
void PandaNode::
282 clear_state(
Thread *current_thread) {
283 set_state(RenderState::make_empty(), current_thread);
290 get_effects(
Thread *current_thread)
const {
291 CDReader cdata(_cycler, current_thread);
292 return cdata->_effects;
298 INLINE
void PandaNode::
299 clear_effects(
Thread *current_thread) {
300 set_effects(RenderEffects::make_empty(), current_thread);
309 get_transform(
Thread *current_thread)
const {
310 CDReader cdata(_cycler, current_thread);
311 return cdata->_transform.p();
317 INLINE
void PandaNode::
318 clear_transform(
Thread *current_thread) {
319 set_transform(TransformState::make_identity(), current_thread);
327 get_prev_transform(
Thread *current_thread)
const {
328 CDReader cdata(_cycler, current_thread);
329 return cdata->_prev_transform.p();
338 INLINE
bool PandaNode::
339 has_dirty_prev_transform()
const {
340 return _dirty_prev_transform;
348 INLINE std::string PandaNode::
349 get_tag(
const std::string &key,
Thread *current_thread)
const {
350 CDReader cdata(_cycler, current_thread);
351 int index = cdata->_tag_data.find(key);
353 return cdata->_tag_data.get_data((
size_t)index);
355 return std::string();
364 INLINE
bool PandaNode::
365 has_tag(
const std::string &key,
Thread *current_thread)
const {
366 CDReader cdata(_cycler, current_thread);
367 return cdata->_tag_data.find(key) >= 0;
373 INLINE
size_t PandaNode::
374 get_num_tags()
const {
375 CDReader cdata(_cycler);
376 return cdata->_tag_data.size();
382 INLINE std::string PandaNode::
383 get_tag_key(
size_t i)
const {
384 CDReader cdata(_cycler);
385 return cdata->_tag_data.get_key(i);
392 INLINE
bool PandaNode::
394 CDReader cdata(_cycler);
395 if (!cdata->_tag_data.is_empty()) {
402 if (!_python_tag_data.is_null()) {
405 #endif // HAVE_PYTHON 412 INLINE
void PandaNode::
413 ls(std::ostream &out,
int indent_level)
const {
414 r_list_descendants(out, indent_level);
431 get_all_camera_mask() {
432 return ~_overall_bit;
439 INLINE
bool PandaNode::
440 is_overall_hidden()
const {
441 CDReader cdata(_cycler);
442 return ((cdata->_draw_show_mask | ~cdata->_draw_control_mask) & _overall_bit).is_zero();
468 get_draw_control_mask()
const {
469 CDReader cdata(_cycler);
470 return cdata->_draw_control_mask;
478 get_draw_show_mask()
const {
479 CDReader cdata(_cycler);
480 return cdata->_draw_show_mask;
487 get_into_collide_mask()
const {
488 CDReader cdata(_cycler);
489 return cdata->_into_collide_mask;
508 get_internal_bounds(
Thread *current_thread)
const {
519 INLINE
int PandaNode::
520 get_internal_vertices(
Thread *current_thread)
const {
531 is_bounds_stale()
const {
532 CDReader cdata(_cycler);
533 return (cdata->_last_bounds_update != cdata->_next_update);
548 INLINE
void PandaNode::
549 set_final(
bool flag) {
550 CDWriter cdata(_cycler);
551 cdata->_final_bounds = flag;
562 CDReader cdata(_cycler, current_thread);
563 return cdata->_final_bounds;
575 CDReader cdata(_cycler, current_thread);
576 return cdata->_fancy_bits;
585 get_user_bounds(
int pipeline_stage,
Thread *current_thread)
const {
586 CDStageReader cdata(_cycler, pipeline_stage, current_thread);
587 return cdata->_user_bounds;
596 INLINE
void PandaNode::
597 mark_bounds_stale(
int pipeline_stage,
Thread *current_thread)
const {
600 bool is_stale_bounds;
602 CDStageReader cdata(_cycler, pipeline_stage, current_thread);
603 is_stale_bounds = (cdata->_last_update != cdata->_next_update);
607 if (!is_stale_bounds) {
608 ((
PandaNode *)
this)->force_bounds_stale(pipeline_stage, current_thread);
617 INLINE
void PandaNode::
618 mark_internal_bounds_stale(
int pipeline_stage,
Thread *current_thread) {
620 CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
621 ++cdata->_internal_bounds_mark;
623 mark_bounds_stale(pipeline_stage, current_thread);
640 CDReader cdata(_cycler, current_thread);
641 return Children(cdata);
658 CDReader cdata(_cycler, current_thread);
659 return Stashed(cdata);
668 CDReader cdata(_cycler, current_thread);
669 return Parents(cdata);
675 INLINE
int PandaNode::
676 do_find_parent(
PandaNode *node,
const CData *cdata)
const {
677 CPT(Up) up = cdata->get_up();
678 Up::const_iterator ui = up->find(UpConnection(node));
679 if (ui == up->end()) {
682 return ui - up->begin();
690 INLINE
bool PandaNode::
691 verify_child_no_cycles(
PandaNode *child_node) {
693 if (detect_graph_cycles) {
694 if (!find_node_above(child_node)) {
697 report_cycle(child_node);
709 INLINE
void PandaNode::
710 do_set_dirty_prev_transform() {
712 if (!_dirty_prev_transform) {
713 LinkedListNode::insert_before(&_dirty_prev_transforms);
714 _dirty_prev_transform =
true;
723 INLINE
void PandaNode::
724 do_clear_dirty_prev_transform() {
726 if (_dirty_prev_transform) {
727 LinkedListNode::remove_from_list();
728 _dirty_prev_transform =
false;
735 INLINE PandaNode::DownConnection::
736 DownConnection(
PandaNode *child,
int sort) :
749 return _sort < other._sort;
755 INLINE
PandaNode *PandaNode::DownConnection::
771 INLINE
int PandaNode::DownConnection::
779 INLINE PandaNode::UpConnection::
791 INLINE
bool PandaNode::UpConnection::
792 operator < (
const UpConnection &other)
const {
793 return _parent < other._parent;
799 INLINE
PandaNode *PandaNode::UpConnection::
807 INLINE PandaNode::BoundsData::
809 _internal_bounds(nullptr),
810 _internal_vertices(0)
812 ++_internal_bounds_mark;
818 INLINE PandaNode::BoundsData::
819 BoundsData(
const PandaNode::BoundsData ©) :
820 _internal_bounds(copy._internal_bounds),
821 _internal_vertices(copy._internal_vertices),
822 _internal_bounds_mark(copy._internal_bounds_mark),
823 _internal_bounds_computed(copy._internal_bounds_computed)
830 INLINE
void PandaNode::BoundsData::
831 copy_bounds(
const PandaNode::BoundsData ©) {
832 _internal_bounds = copy._internal_bounds;
833 _internal_vertices = copy._internal_vertices;
834 _internal_bounds_mark = copy._internal_bounds_mark;
835 _internal_bounds_computed = copy._internal_bounds_computed;
842 INLINE
void PandaNode::CData::
843 set_fancy_bit(
int bits,
bool value) {
847 _fancy_bits &= ~bits;
856 return _down.get_read_pointer();
864 return _down.get_write_pointer();
871 get_stashed()
const {
872 return _stashed.get_read_pointer();
880 return _stashed.get_write_pointer();
888 return _up.get_read_pointer();
896 return _up.get_write_pointer();
902 INLINE PandaNode::Children::
909 INLINE PandaNode::Children::
910 Children(
const PandaNode::CData *cdata) :
911 _down(cdata->get_down())
918 INLINE PandaNode::Children::
927 INLINE
void PandaNode::Children::
935 INLINE PandaNode::Children::
937 _down(std::move(from._down))
944 INLINE
void PandaNode::Children::
946 _down = std::move(from._down);
954 nassertr(_down !=
nullptr, 0);
955 return _down->size();
963 nassertr(_down !=
nullptr,
nullptr);
964 nassertr(n < (
size_t)_down->size(),
nullptr);
965 return (*_down)[n].get_child();
974 nassertr(_down !=
nullptr, -1);
975 nassertr(n < _down->size(), -1);
976 return (*_down)[n].get_sort();
982 INLINE PandaNode::Stashed::
989 INLINE PandaNode::Stashed::
990 Stashed(
const PandaNode::CData *cdata) :
998 INLINE PandaNode::Stashed::
1000 _stashed(copy._stashed)
1007 INLINE
void PandaNode::Stashed::
1009 _stashed = copy._stashed;
1015 INLINE PandaNode::Stashed::
1017 _stashed(std::move(from._stashed))
1024 INLINE
void PandaNode::Stashed::
1026 _stashed = std::move(from._stashed);
1034 nassertr(_stashed !=
nullptr, 0);
1035 return _stashed->size();
1043 nassertr(_stashed !=
nullptr,
nullptr);
1044 nassertr(n < _stashed->size(),
nullptr);
1045 return (*_stashed)[n].get_child();
1054 nassertr(_stashed !=
nullptr, -1);
1055 nassertr(n < _stashed->size(), -1);
1056 return (*_stashed)[n].get_sort();
1062 INLINE PandaNode::Parents::
1069 INLINE PandaNode::Parents::
1070 Parents(
const PandaNode::CData *cdata) :
1071 _up(cdata->get_up())
1078 INLINE PandaNode::Parents::
1087 INLINE
void PandaNode::Parents::
1095 INLINE PandaNode::Parents::
1097 _up(std::move(from._up))
1104 INLINE
void PandaNode::Parents::
1106 _up = std::move(from._up);
1114 nassertr(_up !=
nullptr, 0);
1123 nassertr(_up !=
nullptr,
nullptr);
1124 nassertr(n < _up->size(),
nullptr);
1125 return (*_up)[n].get_parent();
1131 INLINE PandaNodePipelineReader::
1132 PandaNodePipelineReader(
const PandaNode *node,
Thread *current_thread) :
1134 _current_thread(current_thread),
1135 _cdata(node->_cycler.read_unlocked(current_thread))
1138 nassertv(_node->test_ref_count_nonzero());
1141 #ifdef DO_PIPELINING 1146 #endif // DO_PIPELINING 1152 INLINE PandaNodePipelineReader::
1155 _current_thread(copy._current_thread),
1158 #ifdef DO_PIPELINING 1160 #endif // DO_PIPELINING 1172 INLINE
void PandaNodePipelineReader::
1174 nassertv(_current_thread == copy._current_thread);
1182 #ifdef DO_PIPELINING 1184 #endif // DO_PIPELINING 1187 _cdata = copy._cdata;
1189 #ifdef DO_PIPELINING 1191 #endif // DO_PIPELINING 1203 INLINE PandaNodePipelineReader::
1204 ~PandaNodePipelineReader() {
1211 #ifdef DO_PIPELINING 1213 #endif // DO_PIPELINING 1224 INLINE
const PandaNode *PandaNodePipelineReader::
1232 INLINE
Thread *PandaNodePipelineReader::
1233 get_current_thread()
const {
1234 return _current_thread;
1257 nassertv(_cdata !=
nullptr);
1258 running_draw_mask = (running_draw_mask & ~_cdata->_draw_control_mask) |
1259 (_cdata->_draw_show_mask & _cdata->_draw_control_mask);
1270 nassertr(_cdata !=
nullptr,
false);
1271 nassertr(_cdata->_last_update == _cdata->_next_update,
false);
1277 if (_cdata->_net_draw_show_mask.is_zero()) {
1281 DrawMask net_draw_control_mask, net_draw_show_mask;
1282 net_draw_control_mask = _cdata->_net_draw_control_mask;
1283 net_draw_show_mask = _cdata->_net_draw_show_mask;
1295 DrawMask compare_mask = (running_draw_mask & ~net_draw_control_mask) | (net_draw_show_mask & net_draw_control_mask);
1297 return !((compare_mask & PandaNode::_overall_bit).is_zero()) && !((compare_mask & camera_mask).is_zero());
1308 return _cdata->get_up()->size();
1319 nassertr(n >= 0 && n < (
int)up->size(),
nullptr);
1320 return (*up)[n].get_parent();
1329 return _node->do_find_parent(node, _cdata);
1339 return _cdata->get_down()->size();
1350 nassertr(n >= 0 && n < (
int)down->size(),
nullptr);
1351 return (*down)[n].get_child();
1361 nassertr(n >= 0 && n < (
int)down->size(), -1);
1362 return (*down)[n].get_sort();
1371 return _node->do_find_child(node, _cdata->get_down());
1381 return _cdata->get_stashed()->size();
1392 nassertr(n >= 0 && n < (
int)stashed->size(),
nullptr);
1393 return (*stashed)[n].get_child();
1403 nassertr(n >= 0 && n < (
int)stashed->size(), -1);
1404 return (*stashed)[n].get_sort();
1413 return _node->do_find_child(node, _cdata->
get_stashed());
1424 return _cdata->_state;
1432 return _cdata->_effects;
1442 return _cdata->_transform;
1451 return _cdata->_prev_transform;
1461 int index = _cdata->_tag_data.find(key);
1463 return _cdata->_tag_data.get_data((
size_t)index);
1465 return std::string();
1476 return _cdata->_tag_data.find(key) >= 0;
1485 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_net_collide_mask);
1486 return _cdata->_net_collide_mask;
1495 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_off_clip_planes);
1496 return _cdata->_off_clip_planes;
1506 nassertr(_cdata->_last_bounds_update == _cdata->_next_update, _cdata->_external_bounds);
1507 return _cdata->_external_bounds;
1521 nassertr(_cdata->_last_bounds_update == _cdata->_next_update, _cdata->_nested_vertices);
1522 return _cdata->_nested_vertices;
1532 return _cdata->_final_bounds;
1545 return _cdata->_fancy_bits;
1594 INLINE PandaNode::BamReaderAuxDataDown::
1595 BamReaderAuxDataDown() :
PandaNode::Stashed get_stashed() const
Returns an object that can be used to walk through the list of children of the node.
bool is_final() const
Returns the current state of the "final" flag.
A basic node of the scene graph or data graph.
PandaNode * get_stashed(size_t n) const
Returns the nth stashed child of the node.
bool debug_is_locked() const
Returns true if the current thread has locked the LightMutex, false otherwise.
const RenderEffects * get_effects() const
Returns the complete RenderEffects that will be applied to this node.
const TransformState * get_transform() const
Returns the transform that has been set on this particular node.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
int find_child(PandaNode *node) const
Returns the index of the indicated child node, if it is a child, or -1 if it is not.
set_state
Sets the complete RenderState that will be applied to all nodes at this level and below.
PandaNode * get_child(size_t n) const
Returns the nth child of the node.
int get_child_sort(int n) const
Returns the sort index of the nth child node of this node (that is, the number that was passed to add...
void set_bounds(const BoundingVolume *volume)
Resets the bounding volume so that it is the indicated volume.
get_num_parents
Returns the number of parent nodes this node has.
bool stash_child(PandaNode *child_node, Thread *current_thread=Thread::get_current_thread())
Stashes the indicated child node.
PandaNode * get_parent(size_t n) const
Returns the nth parent of the node.
bool unstash_child(PandaNode *child_node, Thread *current_thread=Thread::get_current_thread())
Returns the indicated stashed node to normal child status.
const RenderState * get_state() const
Returns the complete RenderState that will be applied to all nodes at this level and below,...
A single page of data maintained by a PipelineCycler.
void compose_draw_mask(DrawMask &running_draw_mask) const
Computes the result of applying this node's draw masks to a running draw mask, as during a traversal.
int get_nested_vertices() const
Returns the total number of vertices that will be rendered by this node and all of its descendents.
bool has_tag(const std::string &key) const
Returns true if a value has been defined on this node for the particular key (even if that value is t...
bool compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const
Compares the running draw mask computed during a traversal with this node's net draw masks.
const TransformState * get_prev_transform() const
Returns the transform that has been set as this node's "previous" position.
PandaNode * get_parent(int n) const
Returns the nth parent node of this node.
PandaNode::Children get_children() const
Returns an object that can be used to walk through the list of children of the node.
void adjust_draw_mask(DrawMask show_mask, DrawMask hide_mask, DrawMask clear_mask)
Adjusts the hide/show bits of this particular node.
static BitMask< uint32_t, nbits > all_off()
Returns a BitMask whose bits are all off.
PandaNode::Parents get_parents() const
Returns an object that can be used to walk through the list of parents of the node,...
This is the base class for a number of special render effects that may be set on scene graph nodes to...
int get_stashed_sort(int n) const
Returns the sort index of the nth stashed node of this node (that is, the number that was passed to a...
get_pipeline_stage
Returns the Pipeline stage number associated with this thread.
is_final
Returns the current state of the "final" flag.
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
set_overall_hidden
Sets or clears the hidden flag.
set_transform
Sets the transform that will be applied to this node and below.
bool operator<(const DownConnection &other) const
Provides a partial ordering on the children of a node so that they are ranked first in sort order,...
get_parents
Returns an object that can be used to walk through the list of parents of the node,...
int find_parent(PandaNode *node) const
Returns the index of the indicated parent node, if it is a parent, or -1 if it is not.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
CPT(RenderAttrib) PandaNode
Returns the render attribute of the indicated type, if it is defined on the node, or NULL if it is no...
int find_stashed(PandaNode *node) const
Returns the index of the indicated stashed node, if it is a stashed child, or -1 if it is not.
get_num_children
Returns the number of child nodes this node has.
void release()
Releases the lock on this object.
set_effects
Sets the complete RenderEffects that will be applied this node.
int get_slot(TypeHandle type_handle) const
Returns the slot number assigned to the indicated TypeHandle, or 0 if no slot number has been assigne...
int get_fancy_bits(Thread *current_thread=Thread::get_current_thread()) const
Returns the union of all of the enum FancyBits values corresponding to the various "fancy" attributes...
const RenderAttrib * get_off_clip_planes() const
Returns a ClipPlaneAttrib which represents the union of all of the clip planes that have been turned ...
size_t get_num_children() const
Returns the number of children of the node.
This class is used to associate each RenderAttrib with a different slot index at runtime,...
void clear_bounds()
Reverses the effect of a previous call to set_bounds(), and allows the node's bounding volume to be a...
void set_child(PandaNode *child)
This is only called by PandaNode::replace_child().
int get_child_sort(size_t n) const
Returns the sort index of the nth child node of this node (that is, the number that was passed to add...
int find_parent(PandaNode *node, Thread *current_thread=Thread::get_current_thread()) const
Returns the index of the indicated parent node, if it is a parent, or -1 if it is not.
int find_child(PandaNode *node, Thread *current_thread=Thread::get_current_thread()) const
Returns the index of the indicated child node, if it is a child, or -1 if it is not.
get_children
Returns an object that can be used to walk through the list of children of the node.
std::string get_tag(const std::string &key) const
Retrieves the user-defined value that was previously set on this node for the particular key,...
int get_child_sort(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns the sort index of the nth child node of this node (that is, the number that was passed to add...
const BoundingVolume * get_bounds() const
Returns the external bounding volume of this node: a bounding volume that contains the user bounding ...
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
get_parent
Returns the nth parent node of this node.
get_stashed
Returns the nth stashed child of this node.
int get_num_children() const
Returns the number of child nodes this node has.
A thread; that is, a lightweight process.
int get_num_stashed() const
Returns the number of stashed nodes this node has.
int get_stashed_sort(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns the sort index of the nth stashed node of this node (that is, the number that was passed to a...
Encapsulates the data from a PandaNode, pre-fetched for one stage of the pipeline.
size_t get_num_stashed() const
Returns the number of stashed children of the node.
int get_fancy_bits() const
Returns the union of all of the enum FancyBits values corresponding to the various "fancy" attributes...
PandaNode * get_child(int n) const
Returns the nth child node of this node.
get_child
Returns the nth child node of this node.
TypeHandle is the identifier used to differentiate C++ class types.
CollideMask get_net_collide_mask() const
Returns the union of all into_collide_mask() values set at CollisionNodes at this level and below.
int get_num_parents() const
Returns the number of parent nodes this node has.
int find_stashed(PandaNode *node, Thread *current_thread=Thread::get_current_thread()) const
Returns the index of the indicated stashed node, if it is a stashed child, or -1 if it is not.
size_t get_num_parents() const
Returns the number of parents of the node.
This represents a unique collection of RenderEffect objects that correspond to a particular renderabl...
int get_stashed_sort(size_t n) const
Returns the sort index of the nth child node of this node (that is, the number that was passed to add...
static RenderAttribRegistry * quick_get_global_ptr()
Returns the global_ptr without first ensuring it has been initialized.
void mark_bam_modified()
Increments the bam_modified counter, so that this object will be invalidated and retransmitted on any...
void node_unref_delete(RefCountType *ptr)
This global helper function will unref the given ReferenceCount object, and if the reference count re...
get_num_stashed
Returns the number of stashed nodes this node has.