Panda3D
pandaNode.I
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file pandaNode.I
10 * @author drose
11 * @date 2002-02-20
12 */
13
14/**
15 * Returns the number of parent nodes this node has. If this number is
16 * greater than 1, the node has been multiply instanced. The order of the
17 * parent nodes is not meaningful and is not related to the order in which the
18 * node was instanced to them.
19 */
20INLINE int PandaNode::
21get_num_parents(Thread *current_thread) const {
22 CDReader cdata(_cycler, current_thread);
23 return cdata->get_up()->size();
24}
25
26/**
27 * Returns the nth parent node of this node. See get_num_parents(). Also see
28 * get_parents(), if your intention is to iterate through the complete list of
29 * parents; get_parents() is preferable in this case.
30 */
32get_parent(int n, Thread *current_thread) const {
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();
37}
38
39/**
40 * Returns the index of the indicated parent node, if it is a parent, or -1 if
41 * it is not.
42 */
43INLINE int PandaNode::
44find_parent(PandaNode *node, Thread *current_thread) const {
45 CDReader cdata(_cycler, current_thread);
46 return do_find_parent(node, cdata);
47}
48
49/**
50 * Returns the number of child nodes this node has. The order of the child
51 * nodes *is* meaningful and is based on the sort number that was passed to
52 * add_child(), and also on the order in which the nodes were added.
53 */
54INLINE int PandaNode::
55get_num_children(Thread *current_thread) const {
56 CDReader cdata(_cycler, current_thread);
57 return cdata->get_down()->size();
58}
59
60/**
61 * Returns the nth child node of this node. See get_num_children(). Also see
62 * get_children(), if your intention is to iterate through the complete list
63 * of children; get_children() is preferable in this case.
64 */
66get_child(int n, Thread *current_thread) const {
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();
71}
72
73/**
74 * Returns the sort index of the nth child node of this node (that is, the
75 * number that was passed to add_child()). See get_num_children().
76 */
77INLINE int PandaNode::
78get_child_sort(int n, Thread *current_thread) const {
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();
83}
84
85/**
86 * Returns the index of the indicated child node, if it is a child, or -1 if
87 * it is not.
88 */
89INLINE int PandaNode::
90find_child(PandaNode *node, Thread *current_thread) const {
91 CDReader cdata(_cycler, current_thread);
92 return do_find_child(node, cdata->get_down());
93}
94
95/**
96 * Stashes the indicated child node. This removes the child from the list of
97 * active children and puts it on a special list of stashed children. This
98 * child node no longer contributes to the bounding volume of the PandaNode,
99 * and is not visited in normal traversals. It is invisible and uncollidable.
100 * The child may later be restored by calling unstash_child().
101 *
102 * This function returns true if the child node was successfully stashed, or
103 * false if it was not a child of the node in the first place (e.g. it was
104 * previously stashed).
105 */
106INLINE bool PandaNode::
107stash_child(PandaNode *child_node, Thread *current_thread) {
108 int child_index = find_child(child_node, current_thread);
109 if (child_index < 0) {
110 return false;
111 }
112 stash_child(child_index, current_thread);
113 return true;
114}
115
116/**
117 * Returns the indicated stashed node to normal child status. This removes
118 * the child from the list of stashed children and puts it on the normal list
119 * of active children. This child node once again contributes to the bounding
120 * volume of the PandaNode, and will be visited in normal traversals. It is
121 * visible and collidable.
122 *
123 * This function returns true if the child node was successfully stashed, or
124 * false if it was not a child of the node in the first place (e.g. it was
125 * previously stashed).
126 */
127INLINE bool PandaNode::
128unstash_child(PandaNode *child_node, Thread *current_thread) {
129 int stashed_index = find_stashed(child_node, current_thread);
130 if (stashed_index < 0) {
131 return false;
132 }
133 unstash_child(stashed_index, current_thread);
134 return true;
135}
136
137/**
138 * Returns the number of stashed nodes this node has. These are former
139 * children of the node that have been moved to the special stashed list via
140 * stash_child().
141 */
142INLINE int PandaNode::
143get_num_stashed(Thread *current_thread) const {
144 CDReader cdata(_cycler, current_thread);
145 return cdata->get_stashed()->size();
146}
147
148/**
149 * Returns the nth stashed child of this node. See get_num_stashed(). Also
150 * see get_stashed(), if your intention is to iterate through the complete
151 * list of stashed children; get_stashed() is preferable in this case.
152 */
154get_stashed(int n, Thread *current_thread) const {
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();
159}
160
161/**
162 * Returns the sort index of the nth stashed node of this node (that is, the
163 * number that was passed to add_child()). See get_num_stashed().
164 */
165INLINE int PandaNode::
166get_stashed_sort(int n, Thread *current_thread) const {
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();
171}
172
173/**
174 * Returns the index of the indicated stashed node, if it is a stashed child,
175 * or -1 if it is not.
176 */
177INLINE int PandaNode::
178find_stashed(PandaNode *node, Thread *current_thread) const {
179 CDReader cdata(_cycler, current_thread);
180 return do_find_child(node, cdata->get_stashed());
181}
182
183/**
184 * Returns the render attribute of the indicated type, if it is defined on the
185 * node, or NULL if it is not. This checks only what is set on this
186 * particular node level, and has nothing to do with what render attributes
187 * may be inherited from parent nodes.
188 */
189INLINE CPT(RenderAttrib) PandaNode::
190get_attrib(TypeHandle type) const {
191 CDReader cdata(_cycler);
192 return cdata->_state->get_attrib(type);
193}
194
195/**
196 * Returns the render attribute of the indicated type, if it is defined on the
197 * node, or NULL if it is not. This checks only what is set on this
198 * particular node level, and has nothing to do with what render attributes
199 * may be inherited from parent nodes.
200 */
201INLINE CPT(RenderAttrib) PandaNode::
202get_attrib(int slot) const {
203 CDReader cdata(_cycler);
204 return cdata->_state->get_attrib(slot);
205}
206
207/**
208 * Returns true if there is a render attribute of the indicated type defined
209 * on this node, or false if there is not.
210 */
211INLINE bool PandaNode::
212has_attrib(TypeHandle type) const {
213 CDReader cdata(_cycler);
214 return cdata->_state->has_attrib(type);
215}
216
217/**
218 * Returns true if there is a render attribute of the indicated type defined
219 * on this node, or false if there is not.
220 */
221INLINE bool PandaNode::
222has_attrib(int slot) const {
223 CDReader cdata(_cycler);
224 return cdata->_state->has_attrib(slot);
225}
226
227/**
228 * Removes the render attribute of the given type from this node. This node,
229 * and the subgraph below, will now inherit the indicated render attribute
230 * from the nodes above this one.
231 */
232INLINE void PandaNode::
233clear_attrib(TypeHandle type) {
235 int slot = reg->get_slot(type);
236 clear_attrib(slot);
237}
238
239/**
240 * Returns the render effect of the indicated type, if it is defined on the
241 * node, or NULL if it is not.
242 */
243INLINE CPT(RenderEffect) PandaNode::
244get_effect(TypeHandle type) const {
245 CDReader cdata(_cycler);
246 int index = cdata->_effects->find_effect(type);
247 if (index >= 0) {
248 return cdata->_effects->get_effect(index);
249 }
250 return nullptr;
251}
252
253/**
254 * Returns true if there is a render effect of the indicated type defined on
255 * this node, or false if there is not.
256 */
257INLINE bool PandaNode::
258has_effect(TypeHandle type) const {
259 CDReader cdata(_cycler);
260 int index = cdata->_effects->find_effect(type);
261 return (index >= 0);
262}
263
264/**
265 * Returns the complete RenderState that will be applied to all nodes at this
266 * level and below, as set on this node. This returns only the RenderState
267 * set on this particular node, and has nothing to do with state that might be
268 * inherited from above.
269 */
270INLINE CPT(RenderState) PandaNode::
271get_state(Thread *current_thread) const {
272 CDReader cdata(_cycler, current_thread);
273 return cdata->_state.p();
274}
275
276/**
277 * Resets this node to leave the render state alone. Nodes at this level and
278 * below will once again inherit their render state unchanged from the nodes
279 * above this level.
280 */
281INLINE void PandaNode::
282clear_state(Thread *current_thread) {
283 set_state(RenderState::make_empty(), current_thread);
284}
285
286/**
287 * Returns the complete RenderEffects that will be applied to this node.
288 */
289INLINE CPT(RenderEffects) PandaNode::
290get_effects(Thread *current_thread) const {
291 CDReader cdata(_cycler, current_thread);
292 return cdata->_effects;
293}
294
295/**
296 * Resets this node to have no render effects.
297 */
298INLINE void PandaNode::
299clear_effects(Thread *current_thread) {
300 set_effects(RenderEffects::make_empty(), current_thread);
301}
302
303/**
304 * Returns the transform that has been set on this particular node. This is
305 * not the net transform from the root, but simply the transform on this
306 * particular node.
307 */
308INLINE CPT(TransformState) PandaNode::
309get_transform(Thread *current_thread) const {
310 CDReader cdata(_cycler, current_thread);
311 return cdata->_transform.p();
312}
313
314/**
315 * Resets the transform on this node to the identity transform.
316 */
317INLINE void PandaNode::
318clear_transform(Thread *current_thread) {
319 set_transform(TransformState::make_identity(), current_thread);
320}
321
322/**
323 * Returns the transform that has been set as this node's "previous" position.
324 * See set_prev_transform().
325 */
326INLINE CPT(TransformState) PandaNode::
327get_prev_transform(Thread *current_thread) const {
328 CDReader cdata(_cycler, current_thread);
329 return cdata->_prev_transform.p();
330}
331
332/**
333 * Returns true if this node has the _dirty_prev_transform flag set, which
334 * indicates its _prev_transform is different from its _transform value (in
335 * pipeline stage 0). In this case, the node will be visited by
336 * reset_prev_transform().
337 */
338INLINE bool PandaNode::
339has_dirty_prev_transform() const {
340 return _dirty_prev_transform;
341}
342
343/**
344 * Retrieves the user-defined value that was previously set on this node for
345 * the particular key, if any. If no value has been previously set, returns
346 * the empty string.
347 */
348INLINE std::string PandaNode::
349get_tag(const std::string &key, Thread *current_thread) const {
350 CDReader cdata(_cycler, current_thread);
351 int index = cdata->_tag_data.find(key);
352 if (index >= 0) {
353 return cdata->_tag_data.get_data((size_t)index);
354 } else {
355 return std::string();
356 }
357}
358
359/**
360 * Returns true if a value has been defined on this node for the particular
361 * key (even if that value is the empty string), or false if no value has been
362 * set.
363 */
364INLINE bool PandaNode::
365has_tag(const std::string &key, Thread *current_thread) const {
366 CDReader cdata(_cycler, current_thread);
367 return cdata->_tag_data.find(key) >= 0;
368}
369
370/**
371 * Returns the number of tags applied to this node.
372 */
373INLINE size_t PandaNode::
374get_num_tags() const {
375 CDReader cdata(_cycler);
376 return cdata->_tag_data.size();
377}
378
379/**
380 * Returns the key of the nth tag applied to this node.
381 */
382INLINE std::string PandaNode::
383get_tag_key(size_t i) const {
384 CDReader cdata(_cycler);
385 return cdata->_tag_data.get_key(i);
386}
387
388/**
389 * Returns true if the node has any tags (or any Python tags) at all, false if
390 * it has none.
391 */
392INLINE bool PandaNode::
393has_tags() const {
394 CDReader cdata(_cycler);
395 if (!cdata->_tag_data.is_empty()) {
396 return true;
397 }
398#ifdef HAVE_PYTHON
399 // This is a bit awkward, since it doesn't catch cases where the Python tags
400 // are cleared. Maybe we should make this behavior deprecated, so that
401 // has_tags will not consider the Python tags.
402 if (!_python_tag_data.is_null()) {
403 return true;
404 }
405#endif // HAVE_PYTHON
406 return false;
407}
408
409/**
410 * Lists all the nodes at and below the current path hierarchically.
411 */
412INLINE void PandaNode::
413ls(std::ostream &out, int indent_level) const {
414 r_list_descendants(out, indent_level);
415}
416
417/**
418 * Returns the special bit that, when specifically cleared in the node's
419 * DrawMask, indicates that the node is hidden to all cameras, regardless of
420 * the remaining DrawMask bits.
421 */
422INLINE DrawMask PandaNode::
423get_overall_bit() {
424 return _overall_bit;
425}
426
427/**
428 * Returns a DrawMask that is appropriate for rendering to all cameras.
429 */
432 return ~_overall_bit;
433}
434
435/**
436 * Returns true if the node has been hidden to all cameras by clearing its
437 * overall bit.
438 */
439INLINE bool PandaNode::
440is_overall_hidden() const {
441 CDReader cdata(_cycler);
442 return ((cdata->_draw_show_mask | ~cdata->_draw_control_mask) & _overall_bit).is_zero();
443}
444
445/**
446 * Sets or clears the hidden flag. When the hidden flag is true, the node and
447 * all of its children are invisible to all cameras, regardless of the setting
448 * of any draw masks. Setting the hidden flag to false restores the previous
449 * visibility as established by the draw masks.
450 *
451 * This actually works by twiddling the reserved _overall_bit in the node's
452 * draw mask, which has special meaning.
453 */
454INLINE void PandaNode::
455set_overall_hidden(bool hidden) {
456 if (hidden) {
458 } else {
460 }
461}
462
463/**
464 * Returns the set of bits in draw_show_mask that are considered meaningful.
465 * See adjust_draw_mask().
466 */
468get_draw_control_mask() const {
469 CDReader cdata(_cycler);
470 return cdata->_draw_control_mask;
471}
472
473/**
474 * Returns the hide/show bits of this particular node. See
475 * adjust_draw_mask().
476 */
478get_draw_show_mask() const {
479 CDReader cdata(_cycler);
480 return cdata->_draw_show_mask;
481}
482
483/**
484 * Returns the "into" collide mask for this node.
485 */
487get_into_collide_mask() const {
488 CDReader cdata(_cycler);
489 return cdata->_into_collide_mask;
490}
491
492/**
493 * Reverses the effect of a previous call to set_bounds(), and allows the
494 * node's bounding volume to be automatically computed once more based on the
495 * contents of the node.
496 */
497INLINE void PandaNode::
498clear_bounds() {
499 set_bounds(nullptr);
500}
501
502/**
503 * Returns the node's internal bounding volume. This is the bounding volume
504 * around the node alone, without including children. If the user has called
505 * set_bounds(), it will be the specified bounding volume.
506 */
507INLINE CPT(BoundingVolume) PandaNode::
508get_internal_bounds(Thread *current_thread) const {
509 return get_internal_bounds(current_thread->get_pipeline_stage(),
510 current_thread);
511}
512
513/**
514 * Returns the total number of vertices that will be rendered by this
515 * particular node alone, not accounting for its children.
516 *
517 * This may not include all vertices for certain dynamic effects.
518 */
519INLINE int PandaNode::
520get_internal_vertices(Thread *current_thread) const {
521 return get_internal_vertices(current_thread->get_pipeline_stage(),
522 current_thread);
523}
524
525/**
526 * Returns true if the bounding volume of this node is stale and will be
527 * implicitly recomputed at the next call to get_bounds(), or false if it is
528 * fresh and need not be recomputed.
529 */
530bool PandaNode::
531is_bounds_stale() const {
532 CDReader cdata(_cycler);
533 return (cdata->_last_bounds_update != cdata->_next_update);
534}
535
536/**
537 * Sets the "final" flag on this PandaNode. If this is true, than no bounding
538 * volume need be tested below it; a positive intersection with this node's
539 * bounding volume is deemed to be a positive intersection with all geometry
540 * inside.
541 *
542 * This is useful to quickly force a larger bounding volume around a node when
543 * the GeomNodes themselves are inaccurate for some reason, without forcing a
544 * recompute of every nested bounding volume. It's also helpful when the
545 * bounding volume is tricked by some special properties, like billboards,
546 * that may move geometry out of its bounding volume otherwise.
547 */
548INLINE void PandaNode::
549set_final(bool flag) {
550 CDWriter cdata(_cycler);
551 cdata->_final_bounds = flag;
553}
554
555/**
556 * Returns the current state of the "final" flag. Initially, this flag is off
557 * (false), but it may be changed by an explicit call to set_final(). See
558 * set_final().
559 */
560INLINE bool PandaNode::
561is_final(Thread *current_thread) const {
562 CDReader cdata(_cycler, current_thread);
563 return cdata->_final_bounds;
564}
565
566/**
567 * Returns the union of all of the enum FancyBits values corresponding to the
568 * various "fancy" attributes that are set on the node. If this returns 0,
569 * the node has nothing interesting about it. This is intended to speed
570 * traversal by quickly skipping past nodes that don't particularly affect the
571 * render state.
572 */
573INLINE int PandaNode::
574get_fancy_bits(Thread *current_thread) const {
575 CDReader cdata(_cycler, current_thread);
576 return cdata->_fancy_bits;
577}
578
579/**
580 * Returns the node's user bounding volume. This is the bounding volume
581 * specified with get_bounds(). This will return NULL if the user bounding
582 * volume has never been set.
583 */
584INLINE CPT(BoundingVolume) PandaNode::
585get_user_bounds(int pipeline_stage, Thread *current_thread) const {
586 CDStageReader cdata(_cycler, pipeline_stage, current_thread);
587 return cdata->_user_bounds;
588}
589
590/**
591 * Indicates that the bounding volume, or something that influences the
592 * bounding volume (or any of the other things stored in CData, like
593 * net_collide_mask), may have changed for this node, and that it must be
594 * recomputed.
595 */
596INLINE void PandaNode::
597mark_bounds_stale(int pipeline_stage, Thread *current_thread) const {
598 // We check whether it is already marked stale. If so, we don't have to
599 // make the call to force_bounds_stale().
600 bool is_stale_bounds;
601 {
602 CDStageReader cdata(_cycler, pipeline_stage, current_thread);
603 is_stale_bounds = (cdata->_last_update != cdata->_next_update);
604 }
605 // It's important that we don't hold the lock during the call to
606 // force_bounds_stale().
607 if (!is_stale_bounds) {
608 ((PandaNode *)this)->force_bounds_stale(pipeline_stage, current_thread);
609 }
610}
611
612/**
613 * Should be called by a derived class to mark the internal bounding volume
614 * stale, so that recompute_internal_bounds() will be called when the bounding
615 * volume is next requested.
616 */
617INLINE void PandaNode::
618mark_internal_bounds_stale(int pipeline_stage, Thread *current_thread) {
619 {
620 CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
621 ++cdata->_internal_bounds_mark;
622 }
623 mark_bounds_stale(pipeline_stage, current_thread);
624}
625
626/**
627 * Returns an object that can be used to walk through the list of children of
628 * the node. When you intend to visit multiple children, using this is
629 * slightly faster than calling get_child() directly on the PandaNode, since
630 * this object avoids reopening the PipelineCycler each time.
631 *
632 * This object also protects you from self-modifying loops (e.g. adding or
633 * removing children during traversal), since a virtual copy of the children
634 * is made ahead of time. The virtual copy is fast--it is a form of copy-on-
635 * write, so the list is not actually copied unless it is modified during the
636 * traversal.
637 */
639get_children(Thread *current_thread) const {
640 CDReader cdata(_cycler, current_thread);
641 return Children(cdata);
642}
643
644/**
645 * Returns an object that can be used to walk through the list of children of
646 * the node. When you intend to visit multiple children, using this is
647 * slightly faster than calling get_stashed() directly on the PandaNode, since
648 * this object avoids reopening the PipelineCycler each time.
649 *
650 * This object also protects you from self-modifying loops (e.g. adding or
651 * removing children during traversal), since a virtual copy of the children
652 * is made ahead of time. The virtual copy is fast--it is a form of copy-on-
653 * write, so the list is not actually copied unless it is modified during the
654 * traversal.
655 */
657get_stashed(Thread *current_thread) const {
658 CDReader cdata(_cycler, current_thread);
659 return Stashed(cdata);
660}
661
662/**
663 * Returns an object that can be used to walk through the list of parents of
664 * the node, similar to get_children() and get_stashed().
665 */
667get_parents(Thread *current_thread) const {
668 CDReader cdata(_cycler, current_thread);
669 return Parents(cdata);
670}
671
672/**
673 * The private implementation of find_parent().
674 */
675INLINE int PandaNode::
676do_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()) {
680 return -1;
681 }
682 return ui - up->begin();
683}
684
685/**
686 * Ensures that attaching the indicated child node to this node would not
687 * introduce a cycle in the graph. Returns true if the attachment is valid,
688 * false otherwise.
689 */
690INLINE bool PandaNode::
691verify_child_no_cycles(PandaNode *child_node) {
692#ifndef NDEBUG
693 if (detect_graph_cycles) {
694 if (!find_node_above(child_node)) {
695 return true;
696 }
697 report_cycle(child_node);
698 return false;
699 }
700#endif // NDEBUG
701 return true;
702}
703
704/**
705 * Sets the dirty_prev_transform flag, and adds the node to the
706 * _dirty_prev_transforms chain. Assumes _dirty_prev_transforms._lock is
707 * already held.
708 */
709INLINE void PandaNode::
710do_set_dirty_prev_transform() {
711 nassertv(_dirty_prev_transforms._lock.debug_is_locked());
712 if (!_dirty_prev_transform) {
713 LinkedListNode::insert_before(&_dirty_prev_transforms);
714 _dirty_prev_transform = true;
715 }
716}
717
718/**
719 * Clears the dirty_prev_transform flag, and removes the node from the
720 * _dirty_prev_transforms chain. Assumes _dirty_prev_transforms._lock is
721 * already held.
722 */
723INLINE void PandaNode::
724do_clear_dirty_prev_transform() {
725 nassertv(_dirty_prev_transforms._lock.debug_is_locked());
726 if (_dirty_prev_transform) {
727 LinkedListNode::remove_from_list();
728 _dirty_prev_transform = false;
729 }
730}
731
732/**
733 *
734 */
735INLINE PandaNode::DownConnection::
736DownConnection(PandaNode *child, int sort) :
737 _child(child),
738 _sort(sort)
739{
740}
741
742/**
743 * Provides a partial ordering on the children of a node so that they are
744 * ranked first in sort order, and then (by virtue of the ordered_vector) in
745 * the order they were added.
746 */
748operator < (const DownConnection &other) const {
749 return _sort < other._sort;
750}
751
752/**
753 *
754 */
755INLINE PandaNode *PandaNode::DownConnection::
756get_child() const {
757 return _child;
758}
759
760/**
761 * This is only called by PandaNode::replace_child().
762 */
764set_child(PandaNode *child) {
765 _child = child;
766}
767
768/**
769 *
770 */
771INLINE int PandaNode::DownConnection::
772get_sort() const {
773 return _sort;
774}
775
776/**
777 *
778 */
779INLINE PandaNode::UpConnection::
780UpConnection(PandaNode *parent) :
781 _parent(parent)
782{
783}
784
785/**
786 * Sorts the up connections of a node by pointer. This is different from the
787 * down connections of a node, which are sorted by the specified _sort number.
788 * This makes it easy to locate a particular parent of a node by pointer, or
789 * to test for a parent-child relationship given two node pointers.
790 */
791INLINE bool PandaNode::UpConnection::
792operator < (const UpConnection &other) const {
793 return _parent < other._parent;
794}
795
796/**
797 *
798 */
799INLINE PandaNode *PandaNode::UpConnection::
800get_parent() const {
801 return _parent;
802}
803
804/**
805 *
806 */
807INLINE PandaNode::BoundsData::
808BoundsData() :
809 _internal_bounds(nullptr),
810 _internal_vertices(0)
811{
812 ++_internal_bounds_mark;
813}
814
815/**
816 *
817 */
818INLINE PandaNode::BoundsData::
819BoundsData(const PandaNode::BoundsData &copy) :
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)
824{
825}
826
827/**
828 * Copies just the BoundsData part of the structure.
829 */
830INLINE void PandaNode::BoundsData::
831copy_bounds(const PandaNode::BoundsData &copy) {
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;
836}
837
838/**
839 * Internal function to set (if value is true) or clear (if value is false)
840 * the indicated bit(s) in the _fancy_bits member.
841 */
842INLINE void PandaNode::CData::
843set_fancy_bit(int bits, bool value) {
844 if (value) {
845 _fancy_bits |= bits;
846 } else {
847 _fancy_bits &= ~bits;
848 }
849}
850
851/**
852 * Returns a read-only pointer to the _down list.
853 */
854INLINE CPT(PandaNode::Down) PandaNode::CData::
855get_down() const {
856 return _down.get_read_pointer();
857}
858
859/**
860 * Returns a modifiable, unique pointer to the _down list.
861 */
862INLINE PT(PandaNode::Down) PandaNode::CData::
863modify_down() {
864 return _down.get_write_pointer();
865}
866
867/**
868 * Returns a read-only pointer to the _stashed list.
869 */
870INLINE CPT(PandaNode::Down) PandaNode::CData::
871get_stashed() const {
872 return _stashed.get_read_pointer();
873}
874
875/**
876 * Returns a modifiable, unique pointer to the _stashed list.
877 */
878INLINE PT(PandaNode::Down) PandaNode::CData::
879modify_stashed() {
880 return _stashed.get_write_pointer();
881}
882
883/**
884 * Returns a read-only pointer to the _up list.
885 */
886INLINE CPT(PandaNode::Up) PandaNode::CData::
887get_up() const {
888 return _up.get_read_pointer();
889}
890
891/**
892 * Returns a modifiable, unique pointer to the _up list.
893 */
894INLINE PT(PandaNode::Up) PandaNode::CData::
895modify_up() {
896 return _up.get_write_pointer();
897}
898
899/**
900 *
901 */
902INLINE PandaNode::Children::
903Children() {
904}
905
906/**
907 *
908 */
909INLINE PandaNode::Children::
910Children(const PandaNode::CData *cdata) :
911 _down(cdata->get_down())
912{
913}
914
915/**
916 *
917 */
918INLINE PandaNode::Children::
919Children(const PandaNode::Children &copy) :
920 _down(copy._down)
921{
922}
923
924/**
925 *
926 */
927INLINE void PandaNode::Children::
928operator = (const PandaNode::Children &copy) {
929 _down = copy._down;
930}
931
932/**
933 *
934 */
935INLINE PandaNode::Children::
936Children(PandaNode::Children &&from) noexcept :
937 _down(std::move(from._down))
938{
939}
940
941/**
942 *
943 */
944INLINE void PandaNode::Children::
945operator = (PandaNode::Children &&from) noexcept {
946 _down = std::move(from._down);
947}
948
949/**
950 * Returns the number of children of the node.
951 */
953get_num_children() const {
954 nassertr(_down != nullptr, 0);
955 return _down->size();
956}
957
958/**
959 * Returns the nth child of the node.
960 */
962get_child(size_t n) const {
963 nassertr(_down != nullptr, nullptr);
964 nassertr(n < (size_t)_down->size(), nullptr);
965 return (*_down)[n].get_child();
966}
967
968/**
969 * Returns the sort index of the nth child node of this node (that is, the
970 * number that was passed to add_child()). See get_num_children().
971 */
973get_child_sort(size_t n) const {
974 nassertr(_down != nullptr, -1);
975 nassertr(n < _down->size(), -1);
976 return (*_down)[n].get_sort();
977}
978
979/**
980 *
981 */
982INLINE PandaNode::Stashed::
983Stashed() {
984}
985
986/**
987 *
988 */
989INLINE PandaNode::Stashed::
990Stashed(const PandaNode::CData *cdata) :
991 _stashed(cdata->get_stashed())
992{
993}
994
995/**
996 *
997 */
998INLINE PandaNode::Stashed::
999Stashed(const PandaNode::Stashed &copy) :
1000 _stashed(copy._stashed)
1001{
1002}
1003
1004/**
1005 *
1006 */
1007INLINE void PandaNode::Stashed::
1008operator = (const PandaNode::Stashed &copy) {
1009 _stashed = copy._stashed;
1010}
1011
1012/**
1013 *
1014 */
1015INLINE PandaNode::Stashed::
1016Stashed(PandaNode::Stashed &&from) noexcept :
1017 _stashed(std::move(from._stashed))
1018{
1019}
1020
1021/**
1022 *
1023 */
1024INLINE void PandaNode::Stashed::
1025operator = (PandaNode::Stashed &&from) noexcept {
1026 _stashed = std::move(from._stashed);
1027}
1028
1029/**
1030 * Returns the number of stashed children of the node.
1031 */
1033get_num_stashed() const {
1034 nassertr(_stashed != nullptr, 0);
1035 return _stashed->size();
1036}
1037
1038/**
1039 * Returns the nth stashed child of the node.
1040 */
1042get_stashed(size_t n) const {
1043 nassertr(_stashed != nullptr, nullptr);
1044 nassertr(n < _stashed->size(), nullptr);
1045 return (*_stashed)[n].get_child();
1046}
1047
1048/**
1049 * Returns the sort index of the nth child node of this node (that is, the
1050 * number that was passed to add_child()). See get_num_stashed().
1051 */
1053get_stashed_sort(size_t n) const {
1054 nassertr(_stashed != nullptr, -1);
1055 nassertr(n < _stashed->size(), -1);
1056 return (*_stashed)[n].get_sort();
1057}
1058
1059/**
1060 *
1061 */
1062INLINE PandaNode::Parents::
1063Parents() {
1064}
1065
1066/**
1067 *
1068 */
1069INLINE PandaNode::Parents::
1070Parents(const PandaNode::CData *cdata) :
1071 _up(cdata->get_up())
1072{
1073}
1074
1075/**
1076 *
1077 */
1078INLINE PandaNode::Parents::
1079Parents(const PandaNode::Parents &copy) :
1080 _up(copy._up)
1081{
1082}
1083
1084/**
1085 *
1086 */
1087INLINE void PandaNode::Parents::
1088operator = (const PandaNode::Parents &copy) {
1089 _up = copy._up;
1090}
1091
1092/**
1093 *
1094 */
1095INLINE PandaNode::Parents::
1096Parents(PandaNode::Parents &&from) noexcept :
1097 _up(std::move(from._up))
1098{
1099}
1100
1101/**
1102 *
1103 */
1104INLINE void PandaNode::Parents::
1105operator = (PandaNode::Parents &&from) noexcept {
1106 _up = std::move(from._up);
1107}
1108
1109/**
1110 * Returns the number of parents of the node.
1111 */
1113get_num_parents() const {
1114 nassertr(_up != nullptr, 0);
1115 return _up->size();
1116}
1117
1118/**
1119 * Returns the nth parent of the node.
1120 */
1122get_parent(size_t n) const {
1123 nassertr(_up != nullptr, nullptr);
1124 nassertr(n < _up->size(), nullptr);
1125 return (*_up)[n].get_parent();
1126}
1127
1128/**
1129 *
1130 */
1131INLINE PandaNodePipelineReader::
1132PandaNodePipelineReader(const PandaNode *node, Thread *current_thread) :
1133 _node(node),
1134 _current_thread(current_thread),
1135 _cdata(node->_cycler.read_unlocked(current_thread))
1136{
1137#ifdef _DEBUG
1138 nassertv(_node->test_ref_count_nonzero());
1139#endif // _DEBUG
1140
1141#ifdef DO_PIPELINING
1142 // We node_ref the CData pointer, so that if anyone makes changes to the
1143 // PandaNode while we hold this pointer, it will force a copy--so that this
1144 // object will remain unchanged (if out-of-date).
1145 _cdata->node_ref();
1146#endif // DO_PIPELINING
1147}
1148
1149/**
1150 *
1151 */
1152INLINE PandaNodePipelineReader::
1153PandaNodePipelineReader(const PandaNodePipelineReader &copy) :
1154 _node(copy._node),
1155 _current_thread(copy._current_thread),
1156 _cdata(copy._cdata)
1157{
1158#ifdef DO_PIPELINING
1159 _cdata->node_ref();
1160#endif // DO_PIPELINING
1161
1162 /*
1163 if (_cdata != (PandaNode::CData *)NULL) {
1164 _node->_cycler.increment_read(_cdata);
1165 }
1166 */
1167}
1168
1169/**
1170 *
1171 */
1172INLINE void PandaNodePipelineReader::
1173operator = (const PandaNodePipelineReader &copy) {
1174 nassertv(_current_thread == copy._current_thread);
1175
1176 /*
1177 if (_cdata != (PandaNode::CData *)NULL) {
1178 _node->_cycler.release_read(_cdata);
1179 }
1180 */
1181
1182#ifdef DO_PIPELINING
1183 node_unref_delete((CycleData *)_cdata);
1184#endif // DO_PIPELINING
1185
1186 _node = copy._node;
1187 _cdata = copy._cdata;
1188
1189#ifdef DO_PIPELINING
1190 _cdata->node_ref();
1191#endif // DO_PIPELINING
1192
1193 /*
1194 if (_cdata != (PandaNode::CData *)NULL) {
1195 _node->_cycler.increment_read(_cdata);
1196 }
1197 */
1198}
1199
1200/**
1201 *
1202 */
1203INLINE PandaNodePipelineReader::
1204~PandaNodePipelineReader() {
1205 /*
1206 if (_cdata != (PandaNode::CData *)NULL) {
1207 _node->_cycler.release_read(_cdata);
1208 }
1209 */
1210
1211#ifdef DO_PIPELINING
1212 node_unref_delete((CycleData *)_cdata);
1213#endif // DO_PIPELINING
1214
1215#ifdef _DEBUG
1216 _node = nullptr;
1217 _cdata = nullptr;
1218#endif // _DEBUG
1219}
1220
1221/**
1222 *
1223 */
1224INLINE const PandaNode *PandaNodePipelineReader::
1225get_node() const {
1226 return _node;
1227}
1228
1229/**
1230 *
1231 */
1232INLINE Thread *PandaNodePipelineReader::
1233get_current_thread() const {
1234 return _current_thread;
1235}
1236
1237/**
1238 * Releases the lock on this object. No future calls will be valid on this
1239 * object.
1240 */
1242release() {
1243 /*
1244 if (_cdata != (PandaNode::CData *)NULL) {
1245 _node->_cycler.release_read(_cdata);
1246 _cdata = NULL;
1247 }
1248 */
1249}
1250
1251/**
1252 * Computes the result of applying this node's draw masks to a running draw
1253 * mask, as during a traversal.
1254 */
1256compose_draw_mask(DrawMask &running_draw_mask) const {
1257 nassertv(_cdata != nullptr);
1258 running_draw_mask = (running_draw_mask & ~_cdata->_draw_control_mask) |
1259 (_cdata->_draw_show_mask & _cdata->_draw_control_mask);
1260}
1261
1262/**
1263 * Compares the running draw mask computed during a traversal with this node's
1264 * net draw masks. Returns true if the node should be traversed into, or
1265 * false if there is nothing at this level or below that will be visible to
1266 * the indicated camera_mask.
1267 */
1269compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const {
1270 nassertr(_cdata != nullptr, false);
1271 nassertr(_cdata->_last_update == _cdata->_next_update, false);
1272
1273 // As a special case, if net_draw_show_mask is all 0, it means either that
1274 // all nodes under this node are hidden to all cameras, or that none of them
1275 // are renderable nodes (or some combination). In either case, we might as
1276 // well short-circuit.
1277 if (_cdata->_net_draw_show_mask.is_zero()) {
1278 return false;
1279 }
1280
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;
1284
1285 // Now the bits that are not in net_draw_control_mask--that is, those bits
1286 // that are not changed by any of the nodes at this level and below--are
1287 // taken from running_draw_mask, which is inherited from above. On the
1288 // other hand, the bits that *are* in net_draw_control_mask--those bits that
1289 // are changed by any of the nodes at this level and below--are taken from
1290 // net_draw_show_mask, which is propagated upwards from below.
1291
1292 // This way, we will traverse into this node if it has any children which
1293 // want to be visited by the traversal, but we will avoid traversing into it
1294 // if all of its children are hidden to this camera.
1295 DrawMask compare_mask = (running_draw_mask & ~net_draw_control_mask) | (net_draw_show_mask & net_draw_control_mask);
1296
1297 return !((compare_mask & PandaNode::_overall_bit).is_zero()) && !((compare_mask & camera_mask).is_zero());
1298}
1299
1300/**
1301 * Returns the number of parent nodes this node has. If this number is
1302 * greater than 1, the node has been multiply instanced. The order of the
1303 * parent nodes is not meaningful and is not related to the order in which the
1304 * node was instanced to them.
1305 */
1307get_num_parents() const {
1308 return _cdata->get_up()->size();
1309}
1310
1311/**
1312 * Returns the nth parent node of this node. See get_num_parents(). Also see
1313 * get_parents(), if your intention is to iterate through the complete list of
1314 * parents; get_parents() is preferable in this case.
1315 */
1317get_parent(int n) const {
1318 CPT(PandaNode::Up) up = _cdata->get_up();
1319 nassertr(n >= 0 && n < (int)up->size(), nullptr);
1320 return (*up)[n].get_parent();
1321}
1322
1323/**
1324 * Returns the index of the indicated parent node, if it is a parent, or -1 if
1325 * it is not.
1326 */
1328find_parent(PandaNode *node) const {
1329 return _node->do_find_parent(node, _cdata);
1330}
1331
1332/**
1333 * Returns the number of child nodes this node has. The order of the child
1334 * nodes *is* meaningful and is based on the sort number that was passed to
1335 * add_child(), and also on the order in which the nodes were added.
1336 */
1338get_num_children() const {
1339 return _cdata->get_down()->size();
1340}
1341
1342/**
1343 * Returns the nth child node of this node. See get_num_children(). Also see
1344 * get_children(), if your intention is to iterate through the complete list
1345 * of children; get_children() is preferable in this case.
1346 */
1348get_child(int n) const {
1349 CPT(PandaNode::Down) down = _cdata->get_down();
1350 nassertr(n >= 0 && n < (int)down->size(), nullptr);
1351 return (*down)[n].get_child();
1352}
1353
1354/**
1355 * Returns the sort index of the nth child node of this node (that is, the
1356 * number that was passed to add_child()). See get_num_children().
1357 */
1359get_child_sort(int n) const {
1360 CPT(PandaNode::Down) down = _cdata->get_down();
1361 nassertr(n >= 0 && n < (int)down->size(), -1);
1362 return (*down)[n].get_sort();
1363}
1364
1365/**
1366 * Returns the index of the indicated child node, if it is a child, or -1 if
1367 * it is not.
1368 */
1370find_child(PandaNode *node) const {
1371 return _node->do_find_child(node, _cdata->get_down());
1372}
1373
1374/**
1375 * Returns the number of stashed nodes this node has. These are former
1376 * children of the node that have been moved to the special stashed list via
1377 * stash_child().
1378 */
1380get_num_stashed() const {
1381 return _cdata->get_stashed()->size();
1382}
1383
1384/**
1385 * Returns the nth stashed child of this node. See get_num_stashed(). Also
1386 * see get_stashed(), if your intention is to iterate through the complete
1387 * list of stashed children; get_stashed() is preferable in this case.
1388 */
1390get_stashed(int n) const {
1391 CPT(PandaNode::Down) stashed = _cdata->get_stashed();
1392 nassertr(n >= 0 && n < (int)stashed->size(), nullptr);
1393 return (*stashed)[n].get_child();
1394}
1395
1396/**
1397 * Returns the sort index of the nth stashed node of this node (that is, the
1398 * number that was passed to add_child()). See get_num_stashed().
1399 */
1401get_stashed_sort(int n) const {
1402 CPT(PandaNode::Down) stashed = _cdata->get_stashed();
1403 nassertr(n >= 0 && n < (int)stashed->size(), -1);
1404 return (*stashed)[n].get_sort();
1405}
1406
1407/**
1408 * Returns the index of the indicated stashed node, if it is a stashed child,
1409 * or -1 if it is not.
1410 */
1412find_stashed(PandaNode *node) const {
1413 return _node->do_find_child(node, _cdata->get_stashed());
1414}
1415
1416/**
1417 * Returns the complete RenderState that will be applied to all nodes at this
1418 * level and below, as set on this node. This returns only the RenderState
1419 * set on this particular node, and has nothing to do with state that might be
1420 * inherited from above.
1421 */
1423get_state() const {
1424 return _cdata->_state;
1425}
1426
1427/**
1428 * Returns the complete RenderEffects that will be applied to this node.
1429 */
1431get_effects() const {
1432 return _cdata->_effects;
1433}
1434
1435/**
1436 * Returns the transform that has been set on this particular node. This is
1437 * not the net transform from the root, but simply the transform on this
1438 * particular node.
1439 */
1441get_transform() const {
1442 return _cdata->_transform;
1443}
1444
1445/**
1446 * Returns the transform that has been set as this node's "previous" position.
1447 * See set_prev_transform().
1448 */
1450get_prev_transform() const {
1451 return _cdata->_prev_transform;
1452}
1453
1454/**
1455 * Retrieves the user-defined value that was previously set on this node for
1456 * the particular key, if any. If no value has been previously set, returns
1457 * the empty string.
1458 */
1460get_tag(const std::string &key) const {
1461 int index = _cdata->_tag_data.find(key);
1462 if (index >= 0) {
1463 return _cdata->_tag_data.get_data((size_t)index);
1464 } else {
1465 return std::string();
1466 }
1467}
1468
1469/**
1470 * Returns true if a value has been defined on this node for the particular
1471 * key (even if that value is the empty string), or false if no value has been
1472 * set.
1473 */
1475has_tag(const std::string &key) const {
1476 return _cdata->_tag_data.find(key) >= 0;
1477}
1478
1479/**
1480 * Returns the union of all into_collide_mask() values set at CollisionNodes
1481 * at this level and below.
1482 */
1484get_net_collide_mask() const {
1485 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_net_collide_mask);
1486 return _cdata->_net_collide_mask;
1487}
1488
1489/**
1490 * Returns a ClipPlaneAttrib which represents the union of all of the clip
1491 * planes that have been turned *off* at this level and below.
1492 */
1494get_off_clip_planes() const {
1495 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_off_clip_planes);
1496 return _cdata->_off_clip_planes;
1497}
1498
1499/**
1500 * Returns the external bounding volume of this node: a bounding volume that
1501 * contains the user bounding volume, the internal bounding volume, and all of
1502 * the children's bounding volumes.
1503 */
1505get_bounds() const {
1506 nassertr(_cdata->_last_bounds_update == _cdata->_next_update, _cdata->_external_bounds);
1507 return _cdata->_external_bounds;
1508}
1509
1510/**
1511 * Returns the total number of vertices that will be rendered by this node and
1512 * all of its descendents.
1513 *
1514 * This is not necessarily an accurate count of vertices that will actually be
1515 * rendered, since this will include all vertices of all LOD's, and it will
1516 * also include hidden nodes. It may also omit or only approximate certain
1517 * kinds of dynamic geometry. However, it will not include stashed nodes.
1518 */
1520get_nested_vertices() const {
1521 nassertr(_cdata->_last_bounds_update == _cdata->_next_update, _cdata->_nested_vertices);
1522 return _cdata->_nested_vertices;
1523}
1524
1525/**
1526 * Returns the current state of the "final" flag. Initially, this flag is off
1527 * (false), but it may be changed by an explicit call to set_final(). See
1528 * set_final().
1529 */
1531is_final() const {
1532 return _cdata->_final_bounds;
1533}
1534
1535
1536/**
1537 * Returns the union of all of the enum FancyBits values corresponding to the
1538 * various "fancy" attributes that are set on the node. If this returns 0,
1539 * the node has nothing interesting about it. This is intended to speed
1540 * traversal by quickly skipping past nodes that don't particularly affect the
1541 * render state.
1542 */
1544get_fancy_bits() const {
1545 return _cdata->_fancy_bits;
1546}
1547
1548/**
1549 * Returns an object that can be used to walk through the list of children of
1550 * the node. When you intend to visit multiple children, using this is
1551 * slightly faster than calling get_child() directly on the PandaNode, since
1552 * this object avoids reopening the PipelineCycler each time.
1553 *
1554 * This object also protects you from self-modifying loops (e.g. adding or
1555 * removing children during traversal), since a virtual copy of the children
1556 * is made ahead of time. The virtual copy is fast--it is a form of copy-on-
1557 * write, so the list is not actually copied unless it is modified during the
1558 * traversal.
1559 */
1561get_children() const {
1562 return PandaNode::Children(_cdata);
1563}
1564
1565/**
1566 * Returns an object that can be used to walk through the list of children of
1567 * the node. When you intend to visit multiple children, using this is
1568 * slightly faster than calling get_stashed() directly on the PandaNode, since
1569 * this object avoids reopening the PipelineCycler each time.
1570 *
1571 * This object also protects you from self-modifying loops (e.g. adding or
1572 * removing children during traversal), since a virtual copy of the children
1573 * is made ahead of time. The virtual copy is fast--it is a form of copy-on-
1574 * write, so the list is not actually copied unless it is modified during the
1575 * traversal.
1576 */
1578get_stashed() const {
1579 return PandaNode::Stashed(_cdata);
1580}
1581
1582/**
1583 * Returns an object that can be used to walk through the list of parents of
1584 * the node, similar to get_children() and get_stashed().
1585 */
1587get_parents() const {
1588 return PandaNode::Parents(_cdata);
1589}
1590
1591/**
1592 *
1593 */
1594INLINE PandaNode::BamReaderAuxDataDown::
1595BamReaderAuxDataDown() :
1596 _down_list(PandaNode::get_class_type())
1597{
1598}
static BitMask< uint32_t, nbits > all_off()
Returns a BitMask whose bits are all off.
Definition: bitMask.I:43
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
A single page of data maintained by a PipelineCycler.
Definition: cycleData.h:50
bool debug_is_locked() const
Returns true if the current thread has locked the LightMutex, false otherwise.
Encapsulates the data from a PandaNode, pre-fetched for one stage of the pipeline.
Definition: pandaNode.h:840
const TransformState * get_transform() const
Returns the transform that has been set on this particular node.
Definition: pandaNode.I:1441
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.
Definition: pandaNode.I:1412
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...
Definition: pandaNode.I:1359
void release()
Releases the lock on this object.
Definition: pandaNode.I:1242
const RenderEffects * get_effects() const
Returns the complete RenderEffects that will be applied to this node.
Definition: pandaNode.I:1431
const BoundingVolume * get_bounds() const
Returns the external bounding volume of this node: a bounding volume that contains the user bounding ...
Definition: pandaNode.I:1505
PandaNode * get_child(int n) const
Returns the nth child node of this node.
Definition: pandaNode.I:1348
const RenderState * get_state() const
Returns the complete RenderState that will be applied to all nodes at this level and below,...
Definition: pandaNode.I:1423
PandaNode * get_parent(int n) const
Returns the nth parent node of this node.
Definition: pandaNode.I:1317
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...
Definition: pandaNode.I:1401
int get_num_children() const
Returns the number of child nodes this node has.
Definition: pandaNode.I:1338
PandaNode::Stashed get_stashed() const
Returns an object that can be used to walk through the list of children of the node.
Definition: pandaNode.I:1578
int get_num_parents() const
Returns the number of parent nodes this node has.
Definition: pandaNode.I:1307
const TransformState * get_prev_transform() const
Returns the transform that has been set as this node's "previous" position.
Definition: pandaNode.I:1450
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.
Definition: pandaNode.I:1256
int get_num_stashed() const
Returns the number of stashed nodes this node has.
Definition: pandaNode.I:1380
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...
Definition: pandaNode.I:1475
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.
Definition: pandaNode.I:1269
PandaNode::Parents get_parents() const
Returns an object that can be used to walk through the list of parents of the node,...
Definition: pandaNode.I:1587
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,...
Definition: pandaNode.I:1460
PandaNode::Children get_children() const
Returns an object that can be used to walk through the list of children of the node.
Definition: pandaNode.I:1561
CollideMask get_net_collide_mask() const
Returns the union of all into_collide_mask() values set at CollisionNodes at this level and below.
Definition: pandaNode.I:1484
int get_nested_vertices() const
Returns the total number of vertices that will be rendered by this node and all of its descendents.
Definition: pandaNode.I:1520
const RenderAttrib * get_off_clip_planes() const
Returns a ClipPlaneAttrib which represents the union of all of the clip planes that have been turned ...
Definition: pandaNode.I:1494
int get_fancy_bits() const
Returns the union of all of the enum FancyBits values corresponding to the various "fancy" attributes...
Definition: pandaNode.I:1544
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.
Definition: pandaNode.I:1370
bool is_final() const
Returns the current state of the "final" flag.
Definition: pandaNode.I:1531
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.
Definition: pandaNode.I:1328
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...
Definition: pandaNode.I:973
PandaNode * get_child(size_t n) const
Returns the nth child of the node.
Definition: pandaNode.I:962
size_t get_num_children() const
Returns the number of children of the node.
Definition: pandaNode.I:953
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,...
Definition: pandaNode.I:748
void set_child(PandaNode *child)
This is only called by PandaNode::replace_child().
Definition: pandaNode.I:764
PandaNode * get_parent(size_t n) const
Returns the nth parent of the node.
Definition: pandaNode.I:1122
size_t get_num_parents() const
Returns the number of parents of the node.
Definition: pandaNode.I:1113
PandaNode * get_stashed(size_t n) const
Returns the nth stashed child of the node.
Definition: pandaNode.I:1042
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...
Definition: pandaNode.I:1053
size_t get_num_stashed() const
Returns the number of stashed children of the node.
Definition: pandaNode.I:1033
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
get_draw_control_mask
Returns the set of bits in draw_show_mask that are considered meaningful.
Definition: pandaNode.h:255
is_final
Returns the current state of the "final" flag.
Definition: pandaNode.h:314
bool unstash_child(PandaNode *child_node, Thread *current_thread=Thread::get_current_thread())
Returns the indicated stashed node to normal child status.
Definition: pandaNode.I:128
is_overall_hidden
Returns true if the node has been hidden to all cameras by clearing its overall bit.
Definition: pandaNode.h:248
set_overall_hidden
Sets or clears the hidden flag.
Definition: pandaNode.h:248
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.
Definition: pandaNode.I:178
get_num_parents
Returns the number of parent nodes this node has.
Definition: pandaNode.h:118
get_all_camera_mask
Returns a DrawMask that is appropriate for rendering to all cameras.
Definition: pandaNode.h:247
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.
Definition: pandaNode.I:90
void set_bounds(const BoundingVolume *volume)
Resets the bounding volume so that it is the indicated volume.
Definition: pandaNode.cxx:1907
set_effects
Sets the complete RenderEffects that will be applied this node.
Definition: pandaNode.h:178
get_into_collide_mask
Returns the "into" collide mask for this node.
Definition: pandaNode.h:264
get_parents
Returns an object that can be used to walk through the list of parents of the node,...
Definition: pandaNode.h:784
get_num_stashed
Returns the number of stashed nodes this node has.
Definition: pandaNode.h:148
void adjust_draw_mask(DrawMask show_mask, DrawMask hide_mask, DrawMask clear_mask)
Adjusts the hide/show bits of this particular node.
Definition: pandaNode.cxx:1585
get_draw_show_mask
Returns the hide/show bits of this particular node.
Definition: pandaNode.h:256
get_child
Returns the nth child node of this node.
Definition: pandaNode.h:124
set_state
Sets the complete RenderState that will be applied to all nodes at this level and below.
Definition: pandaNode.h:173
set_transform
Sets the transform that will be applied to this node and below.
Definition: pandaNode.h:183
bool stash_child(PandaNode *child_node, Thread *current_thread=Thread::get_current_thread())
Stashes the indicated child node.
Definition: pandaNode.I:107
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.
Definition: pandaNode.I:44
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...
Definition: pandaNode.I:78
get_stashed
Returns the nth stashed child of this node.
Definition: pandaNode.h:148
void clear_bounds()
Reverses the effect of a previous call to set_bounds(), and allows the node's bounding volume to be a...
Definition: pandaNode.I:498
get_children
Returns an object that can be used to walk through the list of children of the node.
Definition: pandaNode.h:782
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...
Definition: pandaNode.I:166
get_parent
Returns the nth parent node of this node.
Definition: pandaNode.h:118
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...
Definition: pandaNode.I:574
get_num_children
Returns the number of child nodes this node has.
Definition: pandaNode.h:124
This class is used to associate each RenderAttrib with a different slot index at runtime,...
static RenderAttribRegistry * quick_get_global_ptr()
Returns the global_ptr without first ensuring it has been initialized.
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...
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
This is the base class for a number of special render effects that may be set on scene graph nodes to...
Definition: renderEffect.h:48
This represents a unique collection of RenderEffect objects that correspond to a particular renderabl...
Definition: renderEffects.h:41
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:47
A thread; that is, a lightweight process.
Definition: thread.h:46
get_pipeline_stage
Returns the Pipeline stage number associated with this thread.
Definition: thread.h:105
Indicates a coordinate-system transform on vertices.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
void mark_bam_modified()
Increments the bam_modified counter, so that this object will be invalidated and retransmitted on any...
Definition: typedWritable.I:43
void node_unref_delete(RefCountType *ptr)
This global helper function will unref the given ReferenceCount object, and if the reference count re...
CPT(RenderAttrib) PandaNode
Returns the render attribute of the indicated type, if it is defined on the node, or NULL if it is no...
Definition: pandaNode.I:189