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