Panda3D
 All Classes Functions Variables Enumerations
pandaNode.I
00001 // Filename: pandaNode.I
00002 // Created by:  drose (20Feb02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 
00016 ////////////////////////////////////////////////////////////////////
00017 //     Function: PandaNode::get_num_parents
00018 //       Access: Published
00019 //  Description: Returns the number of parent nodes this node has.  If
00020 //               this number is greater than 1, the node has been
00021 //               multiply instanced.  The order of the parent nodes is
00022 //               not meaningful and is not related to the order in
00023 //               which the node was instanced to them.
00024 ////////////////////////////////////////////////////////////////////
00025 INLINE int PandaNode::
00026 get_num_parents(Thread *current_thread) const {
00027   CDReader cdata(_cycler, current_thread);
00028   return cdata->get_up()->size();
00029 }
00030 
00031 ////////////////////////////////////////////////////////////////////
00032 //     Function: PandaNode::get_parent
00033 //       Access: Published
00034 //  Description: Returns the nth parent node of this node.  See
00035 //               get_num_parents().  Also see get_parents(), if your
00036 //               intention is to iterate through the complete list of
00037 //               parents; get_parents() is preferable in this case.
00038 ////////////////////////////////////////////////////////////////////
00039 INLINE PandaNode *PandaNode::
00040 get_parent(int n, Thread *current_thread) const {
00041   CDReader cdata(_cycler, current_thread);
00042   CPT(Up) up = cdata->get_up();
00043   nassertr(n >= 0 && n < (int)up->size(), NULL);
00044   return (*up)[n].get_parent();
00045 }
00046 
00047 ////////////////////////////////////////////////////////////////////
00048 //     Function: PandaNode::find_parent
00049 //       Access: Published
00050 //  Description: Returns the index of the indicated parent node, if it
00051 //               is a parent, or -1 if it is not.
00052 ////////////////////////////////////////////////////////////////////
00053 INLINE int PandaNode::
00054 find_parent(PandaNode *node, Thread *current_thread) const {
00055   CDReader cdata(_cycler, current_thread);
00056   return do_find_parent(node, cdata);
00057 }
00058 
00059 ////////////////////////////////////////////////////////////////////
00060 //     Function: PandaNode::get_num_children
00061 //       Access: Published
00062 //  Description: Returns the number of child nodes this node has.  The
00063 //               order of the child nodes *is* meaningful and is based
00064 //               on the sort number that was passed to add_child(),
00065 //               and also on the order in which the nodes were added.
00066 ////////////////////////////////////////////////////////////////////
00067 INLINE int PandaNode::
00068 get_num_children(Thread *current_thread) const {
00069   CDReader cdata(_cycler, current_thread);
00070   return cdata->get_down()->size();
00071 }
00072 
00073 ////////////////////////////////////////////////////////////////////
00074 //     Function: PandaNode::get_child
00075 //       Access: Published
00076 //  Description: Returns the nth child node of this node.  See
00077 //               get_num_children().  Also see get_children(), if your
00078 //               intention is to iterate through the complete list of
00079 //               children; get_children() is preferable in this case.
00080 ////////////////////////////////////////////////////////////////////
00081 INLINE PandaNode *PandaNode::
00082 get_child(int n, Thread *current_thread) const {
00083   CDReader cdata(_cycler, current_thread);
00084   CPT(Down) down = cdata->get_down();
00085   nassertr(n >= 0 && n < (int)down->size(), NULL);
00086   return (*down)[n].get_child();
00087 }
00088 
00089 ////////////////////////////////////////////////////////////////////
00090 //     Function: PandaNode::get_child_sort
00091 //       Access: Published
00092 //  Description: Returns the sort index of the nth child node of this
00093 //               node (that is, the number that was passed to
00094 //               add_child()).  See get_num_children().
00095 ////////////////////////////////////////////////////////////////////
00096 INLINE int PandaNode::
00097 get_child_sort(int n, Thread *current_thread) const {
00098   CDReader cdata(_cycler, current_thread);
00099   CPT(Down) down = cdata->get_down();
00100   nassertr(n >= 0 && n < (int)down->size(), -1);
00101   return (*down)[n].get_sort();
00102 }
00103 
00104 ////////////////////////////////////////////////////////////////////
00105 //     Function: PandaNode::find_child
00106 //       Access: Published
00107 //  Description: Returns the index of the indicated child node, if it
00108 //               is a child, or -1 if it is not.
00109 ////////////////////////////////////////////////////////////////////
00110 INLINE int PandaNode::
00111 find_child(PandaNode *node, Thread *current_thread) const {
00112   CDReader cdata(_cycler, current_thread);
00113   return do_find_child(node, cdata->get_down());
00114 }
00115 
00116 ////////////////////////////////////////////////////////////////////
00117 //     Function: PandaNode::stash_child
00118 //       Access: Published
00119 //  Description: Stashes the indicated child node.  This removes the
00120 //               child from the list of active children and puts it on
00121 //               a special list of stashed children.  This child node
00122 //               no longer contributes to the bounding volume of the
00123 //               PandaNode, and is not visited in normal traversals.
00124 //               It is invisible and uncollidable.  The child may
00125 //               later be restored by calling unstash_child().
00126 //
00127 //               This function returns true if the child node was
00128 //               successfully stashed, or false if it was not a child
00129 //               of the node in the first place (e.g. it was
00130 //               previously stashed).
00131 ////////////////////////////////////////////////////////////////////
00132 INLINE bool PandaNode::
00133 stash_child(PandaNode *child_node, Thread *current_thread) {
00134   int child_index = find_child(child_node, current_thread);
00135   if (child_index < 0) {
00136     return false;
00137   }
00138   stash_child(child_index, current_thread);
00139   return true;
00140 }
00141 
00142 ////////////////////////////////////////////////////////////////////
00143 //     Function: PandaNode::unstash_child
00144 //       Access: Published
00145 //  Description: Returns the indicated stashed node to normal child
00146 //               status.  This removes the child from the list of
00147 //               stashed children and puts it on the normal list of
00148 //               active children.  This child node once again
00149 //               contributes to the bounding volume of the PandaNode,
00150 //               and will be visited in normal traversals.  It is
00151 //               visible and collidable.
00152 //
00153 //               This function returns true if the child node was
00154 //               successfully stashed, or false if it was not a child
00155 //               of the node in the first place (e.g. it was
00156 //               previously stashed).
00157 ////////////////////////////////////////////////////////////////////
00158 INLINE bool PandaNode::
00159 unstash_child(PandaNode *child_node, Thread *current_thread) {
00160   int stashed_index = find_stashed(child_node, current_thread);
00161   if (stashed_index < 0) {
00162     return false;
00163   }
00164   unstash_child(stashed_index, current_thread);
00165   return true;
00166 }
00167 
00168 ////////////////////////////////////////////////////////////////////
00169 //     Function: PandaNode::get_num_stashed
00170 //       Access: Published
00171 //  Description: Returns the number of stashed nodes this node has.
00172 //               These are former children of the node that have been
00173 //               moved to the special stashed list via stash_child().
00174 ////////////////////////////////////////////////////////////////////
00175 INLINE int PandaNode::
00176 get_num_stashed(Thread *current_thread) const {
00177   CDReader cdata(_cycler, current_thread);
00178   return cdata->get_stashed()->size();
00179 }
00180 
00181 ////////////////////////////////////////////////////////////////////
00182 //     Function: PandaNode::get_stashed
00183 //       Access: Published
00184 //  Description: Returns the nth stashed child of this node.  See
00185 //               get_num_stashed().  Also see get_stashed(), if your
00186 //               intention is to iterate through the complete list of
00187 //               stashed children; get_stashed() is preferable in this
00188 //               case.
00189 ////////////////////////////////////////////////////////////////////
00190 INLINE PandaNode *PandaNode::
00191 get_stashed(int n, Thread *current_thread) const {
00192   CDReader cdata(_cycler, current_thread);
00193   CPT(Down) stashed = cdata->get_stashed();
00194   nassertr(n >= 0 && n < (int)stashed->size(), NULL);
00195   return (*stashed)[n].get_child();
00196 }
00197 
00198 ////////////////////////////////////////////////////////////////////
00199 //     Function: PandaNode::get_stashed_sort
00200 //       Access: Published
00201 //  Description: Returns the sort index of the nth stashed node of this
00202 //               node (that is, the number that was passed to
00203 //               add_child()).  See get_num_stashed().
00204 ////////////////////////////////////////////////////////////////////
00205 INLINE int PandaNode::
00206 get_stashed_sort(int n, Thread *current_thread) const {
00207   CDReader cdata(_cycler, current_thread);
00208   CPT(Down) stashed = cdata->get_stashed();
00209   nassertr(n >= 0 && n < (int)stashed->size(), -1);
00210   return (*stashed)[n].get_sort();
00211 }
00212 
00213 ////////////////////////////////////////////////////////////////////
00214 //     Function: PandaNode::find_stashed
00215 //       Access: Published
00216 //  Description: Returns the index of the indicated stashed node, if
00217 //               it is a stashed child, or -1 if it is not.
00218 ////////////////////////////////////////////////////////////////////
00219 INLINE int PandaNode::
00220 find_stashed(PandaNode *node, Thread *current_thread) const {
00221   CDReader cdata(_cycler, current_thread);
00222   return do_find_child(node, cdata->get_stashed());
00223 }
00224 
00225 ////////////////////////////////////////////////////////////////////
00226 //     Function: PandaNode::get_attrib
00227 //       Access: Published
00228 //  Description: Returns the render attribute of the indicated type,
00229 //               if it is defined on the node, or NULL if it is not.
00230 //               This checks only what is set on this particular node
00231 //               level, and has nothing to do with what render
00232 //               attributes may be inherited from parent nodes.
00233 ////////////////////////////////////////////////////////////////////
00234 INLINE const RenderAttrib *PandaNode::
00235 get_attrib(TypeHandle type) const {
00236   CDReader cdata(_cycler);
00237   return cdata->_state->get_attrib(type);
00238 }
00239 
00240 ////////////////////////////////////////////////////////////////////
00241 //     Function: PandaNode::get_attrib
00242 //       Access: Published
00243 //  Description: Returns the render attribute of the indicated type,
00244 //               if it is defined on the node, or NULL if it is not.
00245 //               This checks only what is set on this particular node
00246 //               level, and has nothing to do with what render
00247 //               attributes may be inherited from parent nodes.
00248 ////////////////////////////////////////////////////////////////////
00249 INLINE const RenderAttrib *PandaNode::
00250 get_attrib(int slot) const {
00251   CDReader cdata(_cycler);
00252   return cdata->_state->get_attrib(slot);
00253 }
00254 
00255 ////////////////////////////////////////////////////////////////////
00256 //     Function: PandaNode::has_attrib
00257 //       Access: Published
00258 //  Description: Returns true if there is a render attribute of the
00259 //               indicated type defined on this node, or false if
00260 //               there is not.
00261 ////////////////////////////////////////////////////////////////////
00262 INLINE bool PandaNode::
00263 has_attrib(TypeHandle type) const {
00264   CDReader cdata(_cycler);
00265   return cdata->_state->has_attrib(type);
00266 }
00267 
00268 ////////////////////////////////////////////////////////////////////
00269 //     Function: PandaNode::has_attrib
00270 //       Access: Published
00271 //  Description: Returns true if there is a render attribute of the
00272 //               indicated type defined on this node, or false if
00273 //               there is not.
00274 ////////////////////////////////////////////////////////////////////
00275 INLINE bool PandaNode::
00276 has_attrib(int slot) const {
00277   CDReader cdata(_cycler);
00278   return cdata->_state->has_attrib(slot);
00279 }
00280 
00281 ////////////////////////////////////////////////////////////////////
00282 //     Function: PandaNode::clear_attrib
00283 //       Access: Published
00284 //  Description: Removes the render attribute of the given type from
00285 //               this node.  This node, and the subgraph below, will
00286 //               now inherit the indicated render attribute from the
00287 //               nodes above this one.
00288 ////////////////////////////////////////////////////////////////////
00289 INLINE void PandaNode::
00290 clear_attrib(TypeHandle type) {
00291   RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr();
00292   int slot = reg->get_slot(type);
00293   clear_attrib(slot);
00294 }
00295 
00296 ////////////////////////////////////////////////////////////////////
00297 //     Function: PandaNode::get_effect
00298 //       Access: Published
00299 //  Description: Returns the render effect of the indicated type,
00300 //               if it is defined on the node, or NULL if it is not.
00301 ////////////////////////////////////////////////////////////////////
00302 INLINE const RenderEffect *PandaNode::
00303 get_effect(TypeHandle type) const {
00304   CDReader cdata(_cycler);
00305   int index = cdata->_effects->find_effect(type);
00306   if (index >= 0) {
00307     return cdata->_effects->get_effect(index);
00308   }
00309   return NULL;
00310 }
00311 
00312 ////////////////////////////////////////////////////////////////////
00313 //     Function: PandaNode::has_effect
00314 //       Access: Published
00315 //  Description: Returns true if there is a render effect of the
00316 //               indicated type defined on this node, or false if
00317 //               there is not.
00318 ////////////////////////////////////////////////////////////////////
00319 INLINE bool PandaNode::
00320 has_effect(TypeHandle type) const {
00321   CDReader cdata(_cycler);
00322   int index = cdata->_effects->find_effect(type);
00323   return (index >= 0);
00324 }
00325 
00326 ////////////////////////////////////////////////////////////////////
00327 //     Function: PandaNode::get_state
00328 //       Access: Published
00329 //  Description: Returns the complete RenderState that will be applied
00330 //               to all nodes at this level and below, as set on this
00331 //               node.  This returns only the RenderState set on this
00332 //               particular node, and has nothing to do with state
00333 //               that might be inherited from above.
00334 ////////////////////////////////////////////////////////////////////
00335 INLINE const RenderState *PandaNode::
00336 get_state(Thread *current_thread) const {
00337   CDReader cdata(_cycler, current_thread);
00338   return cdata->_state;
00339 }
00340 
00341 ////////////////////////////////////////////////////////////////////
00342 //     Function: PandaNode::clear_state
00343 //       Access: Published
00344 //  Description: Resets this node to leave the render state alone.
00345 //               Nodes at this level and below will once again inherit
00346 //               their render state unchanged from the nodes above
00347 //               this level.
00348 ////////////////////////////////////////////////////////////////////
00349 INLINE void PandaNode::
00350 clear_state(Thread *current_thread) {
00351   set_state(RenderState::make_empty(), current_thread);
00352 }
00353 
00354 ////////////////////////////////////////////////////////////////////
00355 //     Function: PandaNode::get_effects
00356 //       Access: Published
00357 //  Description: Returns the complete RenderEffects that will be
00358 //               applied to this node.
00359 ////////////////////////////////////////////////////////////////////
00360 INLINE const RenderEffects *PandaNode::
00361 get_effects(Thread *current_thread) const {
00362   CDReader cdata(_cycler, current_thread);
00363   return cdata->_effects;
00364 }
00365 
00366 ////////////////////////////////////////////////////////////////////
00367 //     Function: PandaNode::clear_effects
00368 //       Access: Published
00369 //  Description: Resets this node to have no render effects.
00370 ////////////////////////////////////////////////////////////////////
00371 INLINE void PandaNode::
00372 clear_effects(Thread *current_thread) {
00373   set_effects(RenderEffects::make_empty(), current_thread);
00374 }
00375 
00376 ////////////////////////////////////////////////////////////////////
00377 //     Function: PandaNode::get_transform
00378 //       Access: Published
00379 //  Description: Returns the transform that has been set on this
00380 //               particular node.  This is not the net transform from
00381 //               the root, but simply the transform on this particular
00382 //               node.
00383 ////////////////////////////////////////////////////////////////////
00384 INLINE const TransformState *PandaNode::
00385 get_transform(Thread *current_thread) const {
00386   CDReader cdata(_cycler, current_thread);
00387   return cdata->_transform;
00388 }
00389 
00390 ////////////////////////////////////////////////////////////////////
00391 //     Function: PandaNode::clear_transform
00392 //       Access: Published
00393 //  Description: Resets the transform on this node to the identity
00394 //               transform.
00395 ////////////////////////////////////////////////////////////////////
00396 INLINE void PandaNode::
00397 clear_transform(Thread *current_thread) {
00398   set_transform(TransformState::make_identity(), current_thread);
00399 }
00400 
00401 ////////////////////////////////////////////////////////////////////
00402 //     Function: PandaNode::get_prev_transform
00403 //       Access: Published
00404 //  Description: Returns the transform that has been set as this
00405 //               node's "previous" position.  See
00406 //               set_prev_transform().
00407 ////////////////////////////////////////////////////////////////////
00408 const TransformState *PandaNode::
00409 get_prev_transform(Thread *current_thread) const {
00410   CDReader cdata(_cycler, current_thread);
00411   return cdata->_prev_transform;
00412 }
00413 
00414 ////////////////////////////////////////////////////////////////////
00415 //     Function: PandaNode::has_dirty_prev_transform
00416 //       Access: Published
00417 //  Description: Returns true if this node has the
00418 //               _dirty_prev_transform flag set, which indicates its
00419 //               _prev_transform is different from its _transform
00420 //               value (in pipeline stage 0).  In this case, the node
00421 //               will be visited by reset_prev_transform().
00422 ////////////////////////////////////////////////////////////////////
00423 INLINE bool PandaNode::
00424 has_dirty_prev_transform() const {
00425   return _dirty_prev_transform;
00426 }
00427 
00428 ////////////////////////////////////////////////////////////////////
00429 //     Function: PandaNode::get_tag
00430 //       Access: Published
00431 //  Description: Retrieves the user-defined value that was previously
00432 //               set on this node for the particular key, if any.  If
00433 //               no value has been previously set, returns the empty
00434 //               string.
00435 ////////////////////////////////////////////////////////////////////
00436 INLINE string PandaNode::
00437 get_tag(const string &key, Thread *current_thread) const {
00438   CDReader cdata(_cycler, current_thread);
00439   TagData::const_iterator ti;
00440   ti = cdata->_tag_data.find(key);
00441   if (ti != cdata->_tag_data.end()) {
00442     return (*ti).second;
00443   }
00444   return string();
00445 }
00446 
00447 ////////////////////////////////////////////////////////////////////
00448 //     Function: PandaNode::has_tag
00449 //       Access: Published
00450 //  Description: Returns true if a value has been defined on this node
00451 //               for the particular key (even if that value is the
00452 //               empty string), or false if no value has been set.
00453 ////////////////////////////////////////////////////////////////////
00454 INLINE bool PandaNode::
00455 has_tag(const string &key, Thread *current_thread) const {
00456   CDReader cdata(_cycler, current_thread);
00457   TagData::const_iterator ti;
00458   ti = cdata->_tag_data.find(key);
00459   return (ti != cdata->_tag_data.end());
00460 }
00461 
00462 ////////////////////////////////////////////////////////////////////
00463 //     Function: PandaNode::has_tags
00464 //       Access: Published
00465 //  Description: Returns true if the node has any tags (or any Python
00466 //               tags) at all, false if it has none.
00467 ////////////////////////////////////////////////////////////////////
00468 INLINE bool PandaNode::
00469 has_tags() const {
00470   CDReader cdata(_cycler);
00471   if (!cdata->_tag_data.empty()) {
00472     return true;
00473   }
00474 #ifdef HAVE_PYTHON
00475   if (!cdata->_python_tag_data.empty()) {
00476     return true;
00477   }
00478 #endif  // HAVE_PYTHON
00479   return false;
00480 }
00481 
00482 ////////////////////////////////////////////////////////////////////
00483 //     Function: PandaNode::ls
00484 //       Access: Published
00485 //  Description: Lists all the nodes at and below the current path
00486 //               hierarchically.
00487 ////////////////////////////////////////////////////////////////////
00488 INLINE void PandaNode::
00489 ls(ostream &out, int indent_level) const {
00490   r_list_descendants(out, indent_level);
00491 }
00492 
00493 ////////////////////////////////////////////////////////////////////
00494 //     Function: PandaNode::get_overall_bit
00495 //       Access: Published, Static
00496 //  Description: Returns the special bit that, when specifically
00497 //               cleared in the node's DrawMask, indicates that the
00498 //               node is hidden to all cameras, regardless of the
00499 //               remaining DrawMask bits.
00500 ////////////////////////////////////////////////////////////////////
00501 INLINE DrawMask PandaNode::
00502 get_overall_bit() {
00503   return _overall_bit;
00504 }
00505 
00506 ////////////////////////////////////////////////////////////////////
00507 //     Function: PandaNode::get_all_camera_mask
00508 //       Access: Published, Static
00509 //  Description: Returns a DrawMask that is appropriate for rendering
00510 //               to all cameras.
00511 ////////////////////////////////////////////////////////////////////
00512 INLINE DrawMask PandaNode::
00513 get_all_camera_mask() {
00514   return ~_overall_bit;
00515 }
00516 
00517 ////////////////////////////////////////////////////////////////////
00518 //     Function: PandaNode::is_overall_hidden
00519 //       Access: Published, Static
00520 //  Description: Returns true if the node has been hidden to all
00521 //               cameras by clearing its overall bit.
00522 ////////////////////////////////////////////////////////////////////
00523 INLINE bool PandaNode::
00524 is_overall_hidden() const {
00525   CDReader cdata(_cycler);
00526   return ((cdata->_draw_show_mask | ~cdata->_draw_control_mask) & _overall_bit).is_zero();
00527 }
00528 
00529 ////////////////////////////////////////////////////////////////////
00530 //     Function: PandaNode::set_overall_hidden
00531 //       Access: Published
00532 //  Description: Sets or clears the hidden flag.  When the hidden flag
00533 //               is true, the node and all of its children are
00534 //               invisible to all cameras, regardless of the setting
00535 //               of any draw masks.  Setting the hidden flag to false
00536 //               restores the previous visibility as established by
00537 //               the draw masks.
00538 //
00539 //               This actually works by twiddling the reserved
00540 //               _overall_bit in the node's draw mask, which has
00541 //               special meaning.
00542 ////////////////////////////////////////////////////////////////////
00543 INLINE void PandaNode::
00544 set_overall_hidden(bool hidden) {
00545   if (hidden) {
00546     adjust_draw_mask(DrawMask::all_off(), _overall_bit, DrawMask::all_off());
00547   } else {
00548     adjust_draw_mask(DrawMask::all_off(), DrawMask::all_off(), _overall_bit);
00549   }
00550 }
00551 
00552 ////////////////////////////////////////////////////////////////////
00553 //     Function: PandaNode::get_draw_control_mask
00554 //       Access: Published
00555 //  Description: Returns the set of bits in draw_show_mask that are
00556 //               considered meaningful.  See adjust_draw_mask().
00557 ////////////////////////////////////////////////////////////////////
00558 INLINE DrawMask PandaNode::
00559 get_draw_control_mask() const {
00560   CDReader cdata(_cycler);
00561   return cdata->_draw_control_mask;
00562 }
00563 
00564 ////////////////////////////////////////////////////////////////////
00565 //     Function: PandaNode::get_draw_show_mask
00566 //       Access: Published
00567 //  Description: Returns the hide/show bits of this particular node.
00568 //               See adjust_draw_mask().
00569 ////////////////////////////////////////////////////////////////////
00570 INLINE DrawMask PandaNode::
00571 get_draw_show_mask() const {
00572   CDReader cdata(_cycler);
00573   return cdata->_draw_show_mask;
00574 }
00575 
00576 ////////////////////////////////////////////////////////////////////
00577 //     Function: PandaNode::get_into_collide_mask
00578 //       Access: Published
00579 //  Description: Returns the "into" collide mask for this node.
00580 ////////////////////////////////////////////////////////////////////
00581 INLINE CollideMask PandaNode::
00582 get_into_collide_mask() const {
00583   CDReader cdata(_cycler);
00584   return cdata->_into_collide_mask;
00585 }
00586 
00587 ////////////////////////////////////////////////////////////////////
00588 //     Function: PandaNode::clear_bounds
00589 //       Access: Published
00590 //  Description: Reverses the effect of a previous call to
00591 //               set_bounds(), and allows the node's bounding volume
00592 //               to be automatically computed once more based on the
00593 //               contents of the node.
00594 ////////////////////////////////////////////////////////////////////
00595 INLINE void PandaNode::
00596 clear_bounds() {
00597   set_bounds((BoundingVolume *)NULL);
00598 }
00599 
00600 ////////////////////////////////////////////////////////////////////
00601 //     Function: PandaNode::get_internal_bounds
00602 //       Access: Published
00603 //  Description: Returns the node's internal bounding volume.  This is
00604 //               the bounding volume around the node alone, without
00605 //               including children.  If the user has called
00606 //               set_bounds(), it will be the specified bounding
00607 //               volume.
00608 ////////////////////////////////////////////////////////////////////
00609 INLINE CPT(BoundingVolume) PandaNode::
00610 get_internal_bounds(Thread *current_thread) const {
00611   return get_internal_bounds(current_thread->get_pipeline_stage(),
00612                              current_thread);
00613 }
00614 
00615 ////////////////////////////////////////////////////////////////////
00616 //     Function: PandaNode::get_internal_vertices
00617 //       Access: Published
00618 //  Description: Returns the total number of vertices that will be
00619 //               rendered by this particular node alone, not
00620 //               accounting for its children.
00621 //
00622 //               This may not include all vertices for certain dynamic
00623 //               effects.
00624 ////////////////////////////////////////////////////////////////////
00625 INLINE int PandaNode::
00626 get_internal_vertices(Thread *current_thread) const {
00627   return get_internal_vertices(current_thread->get_pipeline_stage(),
00628                                current_thread);
00629 }
00630 
00631 ////////////////////////////////////////////////////////////////////
00632 //     Function: PandaNode::is_bounds_stale
00633 //       Access: Published
00634 //  Description: Returns true if the bounding volume of this node is
00635 //                stale and will be implicitly recomputed at the next
00636 //                call to get_bounds(), or false if it is fresh and
00637 //                need not be recomputed.
00638 ////////////////////////////////////////////////////////////////////
00639 bool PandaNode::
00640 is_bounds_stale() const {
00641   CDReader cdata(_cycler);
00642   return (cdata->_last_update != cdata->_next_update);
00643 }
00644 
00645 ////////////////////////////////////////////////////////////////////
00646 //     Function: PandaNode::set_final
00647 //       Access: Published
00648 //  Description: Sets the "final" flag on this PandaNode.  If
00649 //               this is true, than no bounding volume need be tested
00650 //               below it; a positive intersection with this node's
00651 //               bounding volume is deemed to be a positive
00652 //               intersection with all geometry inside.
00653 //
00654 //               This is useful to quickly force a larger bounding
00655 //               volume around a node when the GeomNodes themselves
00656 //               are inaccurate for some reason, without forcing a
00657 //               recompute of every nested bounding volume.  It's also
00658 //               helpful when the bounding volume is tricked by some
00659 //               special properties, like billboards, that may move
00660 //               geometry out of its bounding volume otherwise.
00661 ////////////////////////////////////////////////////////////////////
00662 INLINE void PandaNode::
00663 set_final(bool flag) {
00664   CDWriter cdata(_cycler);
00665   cdata->_final_bounds = flag;
00666   mark_bam_modified();
00667 }
00668 
00669 ////////////////////////////////////////////////////////////////////
00670 //     Function: PandaNode::is_final
00671 //       Access: Published
00672 //  Description: Returns the current state of the "final" flag.
00673 //               Initially, this flag is off (false), but it may be
00674 //               changed by an explicit call to set_final().  See
00675 //               set_final().
00676 ////////////////////////////////////////////////////////////////////
00677 INLINE bool PandaNode::
00678 is_final(Thread *current_thread) const {
00679   CDReader cdata(_cycler, current_thread);
00680   return cdata->_final_bounds;
00681 }
00682 
00683 ////////////////////////////////////////////////////////////////////
00684 //     Function: PandaNode::get_fancy_bits
00685 //       Access: Published
00686 //  Description: Returns the union of all of the enum FancyBits values
00687 //               corresponding to the various "fancy" attributes that
00688 //               are set on the node.  If this returns 0, the node has
00689 //               nothing interesting about it.  This is intended to
00690 //               speed traversal by quickly skipping past nodes that
00691 //               don't particularly affect the render state.
00692 ////////////////////////////////////////////////////////////////////
00693 INLINE int PandaNode::
00694 get_fancy_bits(Thread *current_thread) const {
00695   CDReader cdata(_cycler, current_thread);
00696   return cdata->_fancy_bits;
00697 }
00698 
00699 ////////////////////////////////////////////////////////////////////
00700 //     Function: PandaNode::get_user_bounds
00701 //       Access: Protected
00702 //  Description: Returns the node's user bounding volume.  This is the
00703 //               bounding volume specified with get_bounds().  This
00704 //               will return NULL if the user bounding volume has
00705 //               never been set.
00706 ////////////////////////////////////////////////////////////////////
00707 INLINE CPT(BoundingVolume) PandaNode::
00708 get_user_bounds(int pipeline_stage, Thread *current_thread) const {
00709   CDStageReader cdata(_cycler, pipeline_stage, current_thread);
00710   return cdata->_user_bounds;
00711 }
00712 
00713 ////////////////////////////////////////////////////////////////////
00714 //     Function: PandaNode::mark_bounds_stale
00715 //       Access: Protected
00716 //  Description: Indicates that the bounding volume, or something that
00717 //               influences the bounding volume (or any of the other
00718 //               things stored in CData, like net_collide_mask),
00719 //               may have changed for this node, and that it must be
00720 //               recomputed.
00721 ////////////////////////////////////////////////////////////////////
00722 INLINE void PandaNode::
00723 mark_bounds_stale(int pipeline_stage, Thread *current_thread) const {
00724   // It's important that we don't hold the lock during the call to
00725   // force_bounds_stale().
00726   bool is_stale_bounds;
00727   {
00728     CDStageReader cdata(_cycler, pipeline_stage, current_thread);
00729     is_stale_bounds = (cdata->_last_update != cdata->_next_update);
00730   }
00731   if (!is_stale_bounds) {
00732     ((PandaNode *)this)->force_bounds_stale(pipeline_stage, current_thread);
00733   }
00734 }
00735 
00736 
00737 ////////////////////////////////////////////////////////////////////
00738 //     Function: PandaNode::mark_internal_bounds_stale
00739 //       Access: Protected
00740 //  Description: Should be called by a derived class to mark the
00741 //               internal bounding volume stale, so that
00742 //               recompute_internal_bounds() will be called when the
00743 //               bounding volume is next requested.
00744 ////////////////////////////////////////////////////////////////////
00745 INLINE void PandaNode::
00746 mark_internal_bounds_stale(int pipeline_stage, Thread *current_thread) {
00747   {
00748     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
00749     ++cdata->_internal_bounds_mark;
00750   }
00751   mark_bounds_stale(pipeline_stage, current_thread);
00752 }
00753 
00754 ////////////////////////////////////////////////////////////////////
00755 //     Function: PandaNode::get_children
00756 //       Access: Public
00757 //  Description: Returns an object that can be used to walk through
00758 //               the list of children of the node.  When you intend to
00759 //               visit multiple children, using this is slightly
00760 //               faster than calling get_child() directly on the
00761 //               PandaNode, since this object avoids reopening the
00762 //               PipelineCycler each time.
00763 //
00764 //               This object also protects you from self-modifying
00765 //               loops (e.g. adding or removing children during
00766 //               traversal), since a virtual copy of the children is
00767 //               made ahead of time.  The virtual copy is fast--it is
00768 //               a form of copy-on-write, so the list is not actually
00769 //               copied unless it is modified during the traversal.
00770 ////////////////////////////////////////////////////////////////////
00771 INLINE PandaNode::Children PandaNode::
00772 get_children(Thread *current_thread) const {
00773   CDReader cdata(_cycler, current_thread);
00774   return Children(cdata);
00775 }
00776 
00777 ////////////////////////////////////////////////////////////////////
00778 //     Function: PandaNode::get_stashed
00779 //       Access: Public
00780 //  Description: Returns an object that can be used to walk through
00781 //               the list of children of the node.  When you intend to
00782 //               visit multiple children, using this is slightly
00783 //               faster than calling get_stashed() directly on the
00784 //               PandaNode, since this object avoids reopening the
00785 //               PipelineCycler each time.
00786 //
00787 //               This object also protects you from self-modifying
00788 //               loops (e.g. adding or removing children during
00789 //               traversal), since a virtual copy of the children is
00790 //               made ahead of time.  The virtual copy is fast--it is
00791 //               a form of copy-on-write, so the list is not actually
00792 //               copied unless it is modified during the traversal.
00793 ////////////////////////////////////////////////////////////////////
00794 INLINE PandaNode::Stashed PandaNode::
00795 get_stashed(Thread *current_thread) const {
00796   CDReader cdata(_cycler, current_thread);
00797   return Stashed(cdata);
00798 }
00799 
00800 ////////////////////////////////////////////////////////////////////
00801 //     Function: PandaNode::get_parents
00802 //       Access: Public
00803 //  Description: Returns an object that can be used to walk through
00804 //               the list of parents of the node, similar to
00805 //               get_children() and get_stashed().
00806 ////////////////////////////////////////////////////////////////////
00807 INLINE PandaNode::Parents PandaNode::
00808 get_parents(Thread *current_thread) const {
00809   CDReader cdata(_cycler, current_thread);
00810   return Parents(cdata);
00811 }
00812 
00813 ////////////////////////////////////////////////////////////////////
00814 //     Function: PandaNode::do_find_parent
00815 //       Access: Private
00816 //  Description: The private implementation of find_parent().
00817 ////////////////////////////////////////////////////////////////////
00818 INLINE int PandaNode::
00819 do_find_parent(PandaNode *node, const CData *cdata) const {
00820   CPT(Up) up = cdata->get_up();
00821   Up::const_iterator ui = up->find(UpConnection(node));
00822   if (ui == up->end()) {
00823     return -1;
00824   }
00825   return ui - up->begin();
00826 }
00827 
00828 ////////////////////////////////////////////////////////////////////
00829 //     Function: PandaNode::verify_child_no_cycles
00830 //       Access: Private
00831 //  Description: Ensures that attaching the indicated child node to
00832 //               this node would not introduce a cycle in the graph.
00833 //               Returns true if the attachment is valid, false
00834 //               otherwise.
00835 ////////////////////////////////////////////////////////////////////
00836 INLINE bool PandaNode::
00837 verify_child_no_cycles(PandaNode *child_node) {
00838 #ifndef NDEBUG
00839   if (detect_graph_cycles) {
00840     if (!find_node_above(child_node)) {
00841       return true;
00842     }
00843     report_cycle(child_node);
00844     return false;
00845   }
00846 #endif  // NDEBUG
00847   return true;
00848 }
00849 
00850 ////////////////////////////////////////////////////////////////////
00851 //     Function: PandaNode::do_set_dirty_prev_transform
00852 //       Access: Private
00853 //  Description: Sets the dirty_prev_transform flag, and adds the node
00854 //               to the _dirty_prev_transforms chain.  Assumes
00855 //               _dirty_prev_transforms._lock is already held.
00856 ////////////////////////////////////////////////////////////////////
00857 INLINE void PandaNode::
00858 do_set_dirty_prev_transform() {
00859   nassertv(_dirty_prev_transforms._lock.debug_is_locked());
00860   if (!_dirty_prev_transform) {
00861     LinkedListNode::insert_before(&_dirty_prev_transforms);
00862     _dirty_prev_transform = true;
00863   }
00864 }
00865 
00866 ////////////////////////////////////////////////////////////////////
00867 //     Function: PandaNode::do_clear_dirty_prev_transform
00868 //       Access: Private
00869 //  Description: Clears the dirty_prev_transform flag, and removes the node
00870 //               from the _dirty_prev_transforms chain.  Assumes
00871 //               _dirty_prev_transforms._lock is already held.
00872 ////////////////////////////////////////////////////////////////////
00873 INLINE void PandaNode::
00874 do_clear_dirty_prev_transform() {
00875   nassertv(_dirty_prev_transforms._lock.debug_is_locked());
00876   if (_dirty_prev_transform) {
00877     LinkedListNode::remove_from_list();
00878     _dirty_prev_transform = false;
00879   }
00880 }
00881 
00882 ////////////////////////////////////////////////////////////////////
00883 //     Function: PandaNode::DownConnection::Constructor
00884 //       Access: Public
00885 //  Description:
00886 ////////////////////////////////////////////////////////////////////
00887 INLINE PandaNode::DownConnection::
00888 DownConnection(PandaNode *child, int sort) :
00889   _child(child),
00890   _sort(sort)
00891 {
00892 }
00893 
00894 ////////////////////////////////////////////////////////////////////
00895 //     Function: PandaNode::DownConnection::operator <
00896 //       Access: Public
00897 //  Description: Provides a partial ordering on the children of a node
00898 //               so that they are ranked first in sort order, and then
00899 //               (by virtue of the ordered_vector) in the order they
00900 //               were added.
00901 ////////////////////////////////////////////////////////////////////
00902 INLINE bool PandaNode::DownConnection::
00903 operator < (const DownConnection &other) const {
00904   return _sort < other._sort;
00905 }
00906 
00907 ////////////////////////////////////////////////////////////////////
00908 //     Function: PandaNode::DownConnection::get_child
00909 //       Access: Public
00910 //  Description: 
00911 ////////////////////////////////////////////////////////////////////
00912 INLINE PandaNode *PandaNode::DownConnection::
00913 get_child() const {
00914   return _child;
00915 }
00916 
00917 ////////////////////////////////////////////////////////////////////
00918 //     Function: PandaNode::DownConnection::set_child
00919 //       Access: Public
00920 //  Description: This is only called by PandaNode::replace_child().
00921 ////////////////////////////////////////////////////////////////////
00922 INLINE void PandaNode::DownConnection::
00923 set_child(PandaNode *child) {
00924   _child = child;
00925 }
00926 
00927 ////////////////////////////////////////////////////////////////////
00928 //     Function: PandaNode::DownConnection::get_sort
00929 //       Access: Public
00930 //  Description: 
00931 ////////////////////////////////////////////////////////////////////
00932 INLINE int PandaNode::DownConnection::
00933 get_sort() const {
00934   return _sort;
00935 }
00936 
00937 ////////////////////////////////////////////////////////////////////
00938 //     Function: PandaNode::UpConnection::Constructor
00939 //       Access: Public
00940 //  Description:
00941 ////////////////////////////////////////////////////////////////////
00942 INLINE PandaNode::UpConnection::
00943 UpConnection(PandaNode *parent) :
00944   _parent(parent)
00945 {
00946 }
00947 
00948 ////////////////////////////////////////////////////////////////////
00949 //     Function: PandaNode::UpConnection::operator <
00950 //       Access: Public
00951 //  Description: Sorts the up connections of a node by pointer.  This
00952 //               is different from the down connections of a node,
00953 //               which are sorted by the specified _sort number.  This
00954 //               makes it easy to locate a particular parent of a node
00955 //               by pointer, or to test for a parent-child
00956 //               relationship given two node pointers.
00957 ////////////////////////////////////////////////////////////////////
00958 INLINE bool PandaNode::UpConnection::
00959 operator < (const UpConnection &other) const {
00960   return _parent < other._parent;
00961 }
00962 
00963 ////////////////////////////////////////////////////////////////////
00964 //     Function: PandaNode::UpConnection::get_parent
00965 //       Access: Public
00966 //  Description: 
00967 ////////////////////////////////////////////////////////////////////
00968 INLINE PandaNode *PandaNode::UpConnection::
00969 get_parent() const {
00970   return _parent;
00971 }
00972 
00973 ////////////////////////////////////////////////////////////////////
00974 //     Function: PandaNode::BoundsData::Constructor
00975 //       Access: Protected
00976 //  Description:
00977 ////////////////////////////////////////////////////////////////////
00978 INLINE PandaNode::BoundsData::
00979 BoundsData() :
00980   _internal_bounds(NULL),
00981   _internal_vertices(0)
00982 {
00983   ++_internal_bounds_mark;
00984 }
00985 
00986 ////////////////////////////////////////////////////////////////////
00987 //     Function: PandaNode::BoundsData::Copy Constructor
00988 //       Access: Protected
00989 //  Description:
00990 ////////////////////////////////////////////////////////////////////
00991 INLINE PandaNode::BoundsData::
00992 BoundsData(const PandaNode::BoundsData &copy) :
00993   _internal_bounds(copy._internal_bounds),
00994   _internal_vertices(copy._internal_vertices),
00995   _internal_bounds_mark(copy._internal_bounds_mark),
00996   _internal_bounds_computed(copy._internal_bounds_computed)
00997 {
00998 }
00999 
01000 ////////////////////////////////////////////////////////////////////
01001 //     Function: PandaNode::BoundsData::copy_bounds
01002 //       Access: Protected
01003 //  Description: Copies just the BoundsData part of the structure.
01004 ////////////////////////////////////////////////////////////////////
01005 INLINE void PandaNode::BoundsData::
01006 copy_bounds(const PandaNode::BoundsData &copy) {
01007   _internal_bounds = copy._internal_bounds;
01008   _internal_vertices = copy._internal_vertices;
01009   _internal_bounds_mark = copy._internal_bounds_mark;
01010   _internal_bounds_computed = copy._internal_bounds_computed;
01011 }
01012 
01013 ////////////////////////////////////////////////////////////////////
01014 //     Function: PandaNode::CData::set_fancy_bit
01015 //       Access: Public
01016 //  Description: Internal function to set (if value is true) or clear
01017 //               (if value is false) the indicated bit(s) in the
01018 //               _fancy_bits member.
01019 ////////////////////////////////////////////////////////////////////
01020 INLINE void PandaNode::CData::
01021 set_fancy_bit(int bits, bool value) {
01022   if (value) {
01023     _fancy_bits |= bits;
01024   } else {
01025     _fancy_bits &= ~bits;
01026   }
01027 }
01028 
01029 ////////////////////////////////////////////////////////////////////
01030 //     Function: PandaNode::CData::get_down
01031 //       Access: Public
01032 //  Description: Returns a read-only pointer to the _down list.
01033 ////////////////////////////////////////////////////////////////////
01034 INLINE CPT(PandaNode::Down) PandaNode::CData::
01035 get_down() const {
01036   return _down.get_read_pointer();
01037 }
01038 
01039 ////////////////////////////////////////////////////////////////////
01040 //     Function: PandaNode::CData::modify_down
01041 //       Access: Public
01042 //  Description: Returns a modifiable, unique pointer to the _down
01043 //               list.
01044 ////////////////////////////////////////////////////////////////////
01045 INLINE PT(PandaNode::Down) PandaNode::CData::
01046 modify_down() {
01047   return _down.get_write_pointer();
01048 }
01049 
01050 ////////////////////////////////////////////////////////////////////
01051 //     Function: PandaNode::CData::get_stashed
01052 //       Access: Public
01053 //  Description: Returns a read-only pointer to the _stashed list.
01054 ////////////////////////////////////////////////////////////////////
01055 INLINE CPT(PandaNode::Down) PandaNode::CData::
01056 get_stashed() const {
01057   return _stashed.get_read_pointer();
01058 }
01059 
01060 ////////////////////////////////////////////////////////////////////
01061 //     Function: PandaNode::CData::modify_stashed
01062 //       Access: Public
01063 //  Description: Returns a modifiable, unique pointer to the _stashed
01064 //               list.
01065 ////////////////////////////////////////////////////////////////////
01066 INLINE PT(PandaNode::Down) PandaNode::CData::
01067 modify_stashed() {
01068   return _stashed.get_write_pointer();
01069 }
01070 
01071 ////////////////////////////////////////////////////////////////////
01072 //     Function: PandaNode::CData::get_up
01073 //       Access: Public
01074 //  Description: Returns a read-only pointer to the _up list.
01075 ////////////////////////////////////////////////////////////////////
01076 INLINE CPT(PandaNode::Up) PandaNode::CData::
01077 get_up() const {
01078   return _up.get_read_pointer();
01079 }
01080 
01081 ////////////////////////////////////////////////////////////////////
01082 //     Function: PandaNode::CData::modify_up
01083 //       Access: Public
01084 //  Description: Returns a modifiable, unique pointer to the _up
01085 //               list.
01086 ////////////////////////////////////////////////////////////////////
01087 INLINE PT(PandaNode::Up) PandaNode::CData::
01088 modify_up() {
01089   return _up.get_write_pointer();
01090 }
01091 
01092 ////////////////////////////////////////////////////////////////////
01093 //     Function: PandaNode::Children::Constructor
01094 //       Access: Public
01095 //  Description:
01096 ////////////////////////////////////////////////////////////////////
01097 INLINE PandaNode::Children::
01098 Children() {
01099 }
01100 
01101 ////////////////////////////////////////////////////////////////////
01102 //     Function: PandaNode::Children::Constructor
01103 //       Access: Public
01104 //  Description:
01105 ////////////////////////////////////////////////////////////////////
01106 INLINE PandaNode::Children::
01107 Children(const PandaNode::CData *cdata) :
01108   _down(cdata->get_down())
01109 {
01110 }
01111 
01112 ////////////////////////////////////////////////////////////////////
01113 //     Function: PandaNode::Children::Copy Constructor
01114 //       Access: Public
01115 //  Description:
01116 ////////////////////////////////////////////////////////////////////
01117 INLINE PandaNode::Children::
01118 Children(const PandaNode::Children &copy) :
01119   _down(copy._down)
01120 {
01121 }
01122 
01123 ////////////////////////////////////////////////////////////////////
01124 //     Function: PandaNode::Children::Copy Assignment Operator
01125 //       Access: Public
01126 //  Description:
01127 ////////////////////////////////////////////////////////////////////
01128 INLINE void PandaNode::Children::
01129 operator = (const PandaNode::Children &copy) {
01130   _down = copy._down;
01131 }
01132 
01133 ////////////////////////////////////////////////////////////////////
01134 //     Function: PandaNode::Children::get_num_children
01135 //       Access: Public
01136 //  Description: Returns the number of children of the node.
01137 ////////////////////////////////////////////////////////////////////
01138 INLINE int PandaNode::Children::
01139 get_num_children() const {
01140   nassertr(_down != (Down *)NULL, 0);
01141   return _down->size();
01142 }
01143 
01144 ////////////////////////////////////////////////////////////////////
01145 //     Function: PandaNode::Children::get_child
01146 //       Access: Public
01147 //  Description: Returns the nth child of the node.
01148 ////////////////////////////////////////////////////////////////////
01149 INLINE PandaNode *PandaNode::Children::
01150 get_child(int n) const {
01151   nassertr(_down != (Down *)NULL, NULL);
01152   nassertr(n >= 0 && n < (int)_down->size(), NULL);
01153   return (*_down)[n].get_child();
01154 }
01155 
01156 ////////////////////////////////////////////////////////////////////
01157 //     Function: PandaNode::Children::get_child_sort
01158 //       Access: Public
01159 //  Description: Returns the sort index of the nth child node of this
01160 //               node (that is, the number that was passed to
01161 //               add_child()).  See get_num_children().
01162 ////////////////////////////////////////////////////////////////////
01163 INLINE int PandaNode::Children::
01164 get_child_sort(int n) const {
01165   nassertr(_down != (Down *)NULL, -1);
01166   nassertr(n >= 0 && n < (int)_down->size(), -1);
01167   return (*_down)[n].get_sort();
01168 }
01169 
01170 ////////////////////////////////////////////////////////////////////
01171 //     Function: PandaNode::Stashed::Constructor
01172 //       Access: Public
01173 //  Description:
01174 ////////////////////////////////////////////////////////////////////
01175 INLINE PandaNode::Stashed::
01176 Stashed() {
01177 }
01178 
01179 ////////////////////////////////////////////////////////////////////
01180 //     Function: PandaNode::Stashed::Constructor
01181 //       Access: Public
01182 //  Description:
01183 ////////////////////////////////////////////////////////////////////
01184 INLINE PandaNode::Stashed::
01185 Stashed(const PandaNode::CData *cdata) :
01186   _stashed(cdata->get_stashed())
01187 {
01188 }
01189 
01190 ////////////////////////////////////////////////////////////////////
01191 //     Function: PandaNode::Stashed::Copy Constructor
01192 //       Access: Public
01193 //  Description:
01194 ////////////////////////////////////////////////////////////////////
01195 INLINE PandaNode::Stashed::
01196 Stashed(const PandaNode::Stashed &copy) :
01197   _stashed(copy._stashed)
01198 {
01199 }
01200 
01201 ////////////////////////////////////////////////////////////////////
01202 //     Function: PandaNode::Stashed::Copy Assignment Operator
01203 //       Access: Public
01204 //  Description:
01205 ////////////////////////////////////////////////////////////////////
01206 INLINE void PandaNode::Stashed::
01207 operator = (const PandaNode::Stashed &copy) {
01208   _stashed = copy._stashed;
01209 }
01210 
01211 ////////////////////////////////////////////////////////////////////
01212 //     Function: PandaNode::Stashed::get_num_stashed
01213 //       Access: Public
01214 //  Description: Returns the number of stashed children of the node.
01215 ////////////////////////////////////////////////////////////////////
01216 INLINE int PandaNode::Stashed::
01217 get_num_stashed() const {
01218   nassertr(_stashed != (Down *)NULL, 0);
01219   return _stashed->size();
01220 }
01221 
01222 ////////////////////////////////////////////////////////////////////
01223 //     Function: PandaNode::Stashed::get_stashed
01224 //       Access: Public
01225 //  Description: Returns the nth stashed child of the node.
01226 ////////////////////////////////////////////////////////////////////
01227 INLINE PandaNode *PandaNode::Stashed::
01228 get_stashed(int n) const {
01229   nassertr(_stashed != (Down *)NULL, NULL);
01230   nassertr(n >= 0 && n < (int)_stashed->size(), NULL);
01231   return (*_stashed)[n].get_child();
01232 }
01233 
01234 ////////////////////////////////////////////////////////////////////
01235 //     Function: PandaNode::Stashed::get_stashed_sort
01236 //       Access: Public
01237 //  Description: Returns the sort index of the nth child node of this
01238 //               node (that is, the number that was passed to
01239 //               add_child()).  See get_num_stashed().
01240 ////////////////////////////////////////////////////////////////////
01241 INLINE int PandaNode::Stashed::
01242 get_stashed_sort(int n) const {
01243   nassertr(_stashed != (Down *)NULL, -1);
01244   nassertr(n >= 0 && n < (int)_stashed->size(), -1);
01245   return (*_stashed)[n].get_sort();
01246 }
01247 
01248 ////////////////////////////////////////////////////////////////////
01249 //     Function: PandaNode::Parents::Constructor
01250 //       Access: Public
01251 //  Description:
01252 ////////////////////////////////////////////////////////////////////
01253 INLINE PandaNode::Parents::
01254 Parents() {
01255 }
01256 
01257 ////////////////////////////////////////////////////////////////////
01258 //     Function: PandaNode::Parents::Constructor
01259 //       Access: Public
01260 //  Description:
01261 ////////////////////////////////////////////////////////////////////
01262 INLINE PandaNode::Parents::
01263 Parents(const PandaNode::CData *cdata) :
01264   _up(cdata->get_up())
01265 {
01266 }
01267 
01268 ////////////////////////////////////////////////////////////////////
01269 //     Function: PandaNode::Parents::Copy Constructor
01270 //       Access: Public
01271 //  Description:
01272 ////////////////////////////////////////////////////////////////////
01273 INLINE PandaNode::Parents::
01274 Parents(const PandaNode::Parents &copy) :
01275   _up(copy._up)
01276 {
01277 }
01278 
01279 ////////////////////////////////////////////////////////////////////
01280 //     Function: PandaNode::Parents::Copy Assignment Operator
01281 //       Access: Public
01282 //  Description:
01283 ////////////////////////////////////////////////////////////////////
01284 INLINE void PandaNode::Parents::
01285 operator = (const PandaNode::Parents &copy) {
01286   _up = copy._up;
01287 }
01288 
01289 ////////////////////////////////////////////////////////////////////
01290 //     Function: PandaNode::Parents::get_num_parents
01291 //       Access: Public
01292 //  Description: Returns the number of parents of the node.
01293 ////////////////////////////////////////////////////////////////////
01294 INLINE int PandaNode::Parents::
01295 get_num_parents() const {
01296   nassertr(_up != (Up *)NULL, 0);
01297   return _up->size();
01298 }
01299 
01300 ////////////////////////////////////////////////////////////////////
01301 //     Function: PandaNode::Parents::get_parent
01302 //       Access: Public
01303 //  Description: Returns the nth parent of the node.
01304 ////////////////////////////////////////////////////////////////////
01305 INLINE PandaNode *PandaNode::Parents::
01306 get_parent(int n) const {
01307   nassertr(_up != (Up *)NULL, NULL);
01308   nassertr(n >= 0 && n < (int)_up->size(), NULL);
01309   return (*_up)[n].get_parent();
01310 }
01311 
01312 ////////////////////////////////////////////////////////////////////
01313 //     Function: PandaNodePipelineReader::Constructor
01314 //       Access: Public
01315 //  Description:
01316 ////////////////////////////////////////////////////////////////////
01317 INLINE PandaNodePipelineReader::
01318 PandaNodePipelineReader(const PandaNode *object, Thread *current_thread) :
01319   _object(object),
01320   _current_thread(current_thread),
01321   _cdata(object->_cycler.read_unlocked(current_thread))
01322 {
01323 #ifdef _DEBUG
01324   nassertv(_object->test_ref_count_nonzero());
01325 #endif // _DEBUG
01326 
01327 #ifdef DO_PIPELINING
01328   // We node_ref the CData pointer, so that if anyone makes changes to
01329   // the PandaNode while we hold this pointer, it will force a
01330   // copy--so that this object will remain unchanged (if out-of-date).
01331   _cdata->node_ref();
01332 #endif  // DO_PIPELINING
01333 }
01334 
01335 ////////////////////////////////////////////////////////////////////
01336 //     Function: PandaNodePipelineReader::Copy Constructor
01337 //       Access: Public
01338 //  Description: 
01339 ////////////////////////////////////////////////////////////////////
01340 INLINE PandaNodePipelineReader::
01341 PandaNodePipelineReader(const PandaNodePipelineReader &copy) :
01342   _object(copy._object),
01343   _current_thread(copy._current_thread),
01344   _cdata(copy._cdata)
01345 {
01346 #ifdef DO_PIPELINING
01347   _cdata->node_ref();
01348 #endif  // DO_PIPELINING
01349 
01350   /*
01351   if (_cdata != (PandaNode::CData *)NULL) {
01352     _object->_cycler.increment_read(_cdata);
01353   }
01354   */
01355 }
01356 
01357 ////////////////////////////////////////////////////////////////////
01358 //     Function: PandaNodePipelineReader::Copy Assignment Operator
01359 //       Access: Public
01360 //  Description: 
01361 ////////////////////////////////////////////////////////////////////
01362 INLINE void PandaNodePipelineReader::
01363 operator = (const PandaNodePipelineReader &copy) {
01364   nassertv(_current_thread == copy._current_thread);
01365 
01366   /*
01367   if (_cdata != (PandaNode::CData *)NULL) {
01368     _object->_cycler.release_read(_cdata);
01369   }
01370   */
01371 
01372 #ifdef DO_PIPELINING
01373   node_unref_delete((CycleData *)_cdata);
01374 #endif  // DO_PIPELINING
01375 
01376   _object = copy._object;
01377   _cdata = copy._cdata;
01378 
01379 #ifdef DO_PIPELINING
01380   _cdata->node_ref();
01381 #endif  // DO_PIPELINING
01382 
01383   /*
01384   if (_cdata != (PandaNode::CData *)NULL) {
01385     _object->_cycler.increment_read(_cdata);
01386   }
01387   */
01388 }
01389 
01390 ////////////////////////////////////////////////////////////////////
01391 //     Function: PandaNodePipelineReader::Destructor
01392 //       Access: Public
01393 //  Description:
01394 ////////////////////////////////////////////////////////////////////
01395 INLINE PandaNodePipelineReader::
01396 ~PandaNodePipelineReader() {
01397   /*
01398   if (_cdata != (PandaNode::CData *)NULL) {
01399     _object->_cycler.release_read(_cdata);
01400   }
01401   */
01402 
01403 #ifdef DO_PIPELINING
01404   node_unref_delete((CycleData *)_cdata);
01405 #endif  // DO_PIPELINING
01406 
01407 #ifdef _DEBUG
01408   _object = NULL;
01409   _cdata = NULL;
01410 #endif  // _DEBUG
01411 }
01412 
01413 ////////////////////////////////////////////////////////////////////
01414 //     Function: PandaNodePipelineReader::get_object
01415 //       Access: Public
01416 //  Description:
01417 ////////////////////////////////////////////////////////////////////
01418 INLINE const PandaNode *PandaNodePipelineReader::
01419 get_object() const {
01420   return _object;
01421 }
01422 
01423 ////////////////////////////////////////////////////////////////////
01424 //     Function: PandaNodePipelineReader::get_current_thread
01425 //       Access: Public
01426 //  Description:
01427 ////////////////////////////////////////////////////////////////////
01428 INLINE Thread *PandaNodePipelineReader::
01429 get_current_thread() const {
01430   return _current_thread;
01431 }
01432 
01433 ////////////////////////////////////////////////////////////////////
01434 //     Function: PandaNodePipelineReader::release
01435 //       Access: Public
01436 //  Description: Releases the lock on this object.  No future calls
01437 //               will be valid on this object.
01438 ////////////////////////////////////////////////////////////////////
01439 INLINE void PandaNodePipelineReader::
01440 release() {
01441   /*
01442   if (_cdata != (PandaNode::CData *)NULL) {
01443     _object->_cycler.release_read(_cdata);
01444     _cdata = NULL;
01445   }
01446   */
01447 }
01448 
01449 ////////////////////////////////////////////////////////////////////
01450 //     Function: PandaNodePipelineReader::compose_draw_mask
01451 //       Access: Public
01452 //  Description: Computes the result of applying this node's draw
01453 //               masks to a running draw mask, as during a traversal.
01454 ////////////////////////////////////////////////////////////////////
01455 INLINE void PandaNodePipelineReader::
01456 compose_draw_mask(DrawMask &running_draw_mask) const {
01457   nassertv(_cdata != (PandaNode::CData *)NULL);
01458   running_draw_mask = (running_draw_mask & ~_cdata->_draw_control_mask) |
01459     (_cdata->_draw_show_mask & _cdata->_draw_control_mask);
01460 }
01461 
01462 ////////////////////////////////////////////////////////////////////
01463 //     Function: PandaNodePipelineReader::compare_draw_mask
01464 //       Access: Public
01465 //  Description: Compares the running draw mask computed during a
01466 //               traversal with this node's net draw masks.  Returns
01467 //               true if the node should be traversed into, or false
01468 //               if there is nothing at this level or below that will
01469 //               be visible to the indicated camera_mask.
01470 ////////////////////////////////////////////////////////////////////
01471 INLINE bool PandaNodePipelineReader::
01472 compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const {
01473   nassertr(_cdata != (PandaNode::CData *)NULL, false);
01474   nassertr(_cdata->_last_update == _cdata->_next_update, false);
01475 
01476   // As a special case, if net_draw_show_mask is all 0, it means
01477   // either that all nodes under this node are hidden to all cameras,
01478   // or that none of them are renderable nodes (or some combination).
01479   // In either case, we might as well short-circuit.
01480   if (_cdata->_net_draw_show_mask.is_zero()) {
01481     return false;
01482   }
01483 
01484   DrawMask net_draw_control_mask, net_draw_show_mask;
01485   net_draw_control_mask = _cdata->_net_draw_control_mask;
01486   net_draw_show_mask = _cdata->_net_draw_show_mask;
01487 
01488   // Now the bits that are not in net_draw_control_mask--that is,
01489   // those bits that are not changed by any of the nodes at this level
01490   // and below--are taken from running_draw_mask, which is inherited
01491   // from above.  On the other hand, the bits that *are* in
01492   // net_draw_control_mask--those bits that are changed by any of the
01493   // nodes at this level and below--are taken from net_draw_show_mask,
01494   // which is propagated upwards from below.
01495 
01496   // This way, we will traverse into this node if it has any children
01497   // which want to be visited by the traversal, but we will avoid
01498   // traversing into it if all of its children are hidden to this
01499   // camera.
01500   DrawMask compare_mask = (running_draw_mask & ~net_draw_control_mask) | (net_draw_show_mask & net_draw_control_mask);
01501 
01502   return !((compare_mask & PandaNode::_overall_bit).is_zero()) && !((compare_mask & camera_mask).is_zero());
01503 }
01504 
01505 ////////////////////////////////////////////////////////////////////
01506 //     Function: PandaNodePipelineReader::get_num_parents
01507 //       Access: Public
01508 //  Description: Returns the number of parent nodes this node has.  If
01509 //               this number is greater than 1, the node has been
01510 //               multiply instanced.  The order of the parent nodes is
01511 //               not meaningful and is not related to the order in
01512 //               which the node was instanced to them.
01513 ////////////////////////////////////////////////////////////////////
01514 INLINE int PandaNodePipelineReader::
01515 get_num_parents() const {
01516   return _cdata->get_up()->size();
01517 }
01518 
01519 ////////////////////////////////////////////////////////////////////
01520 //     Function: PandaNodePipelineReader::get_parent
01521 //       Access: Public
01522 //  Description: Returns the nth parent node of this node.  See
01523 //               get_num_parents().  Also see get_parents(), if your
01524 //               intention is to iterate through the complete list of
01525 //               parents; get_parents() is preferable in this case.
01526 ////////////////////////////////////////////////////////////////////
01527 INLINE PandaNode *PandaNodePipelineReader::
01528 get_parent(int n) const {
01529   CPT(PandaNode::Up) up = _cdata->get_up();
01530   nassertr(n >= 0 && n < (int)up->size(), NULL);
01531   return (*up)[n].get_parent();
01532 }
01533 
01534 ////////////////////////////////////////////////////////////////////
01535 //     Function: PandaNodePipelineReader::find_parent
01536 //       Access: Public
01537 //  Description: Returns the index of the indicated parent node, if it
01538 //               is a parent, or -1 if it is not.
01539 ////////////////////////////////////////////////////////////////////
01540 INLINE int PandaNodePipelineReader::
01541 find_parent(PandaNode *node) const {
01542   return _object->do_find_parent(node, _cdata);
01543 }
01544 
01545 ////////////////////////////////////////////////////////////////////
01546 //     Function: PandaNodePipelineReader::get_num_children
01547 //       Access: Public
01548 //  Description: Returns the number of child nodes this node has.  The
01549 //               order of the child nodes *is* meaningful and is based
01550 //               on the sort number that was passed to add_child(),
01551 //               and also on the order in which the nodes were added.
01552 ////////////////////////////////////////////////////////////////////
01553 INLINE int PandaNodePipelineReader::
01554 get_num_children() const {
01555   return _cdata->get_down()->size();
01556 }
01557 
01558 ////////////////////////////////////////////////////////////////////
01559 //     Function: PandaNodePipelineReader::get_child
01560 //       Access: Public
01561 //  Description: Returns the nth child node of this node.  See
01562 //               get_num_children().  Also see get_children(), if your
01563 //               intention is to iterate through the complete list of
01564 //               children; get_children() is preferable in this case.
01565 ////////////////////////////////////////////////////////////////////
01566 INLINE PandaNode *PandaNodePipelineReader::
01567 get_child(int n) const {
01568   CPT(PandaNode::Down) down = _cdata->get_down();
01569   nassertr(n >= 0 && n < (int)down->size(), NULL);
01570   return (*down)[n].get_child();
01571 }
01572 
01573 ////////////////////////////////////////////////////////////////////
01574 //     Function: PandaNodePipelineReader::get_child_sort
01575 //       Access: Public
01576 //  Description: Returns the sort index of the nth child node of this
01577 //               node (that is, the number that was passed to
01578 //               add_child()).  See get_num_children().
01579 ////////////////////////////////////////////////////////////////////
01580 INLINE int PandaNodePipelineReader::
01581 get_child_sort(int n) const {
01582   CPT(PandaNode::Down) down = _cdata->get_down();
01583   nassertr(n >= 0 && n < (int)down->size(), -1);
01584   return (*down)[n].get_sort();
01585 }
01586 
01587 ////////////////////////////////////////////////////////////////////
01588 //     Function: PandaNodePipelineReader::find_child
01589 //       Access: Public
01590 //  Description: Returns the index of the indicated child node, if it
01591 //               is a child, or -1 if it is not.
01592 ////////////////////////////////////////////////////////////////////
01593 INLINE int PandaNodePipelineReader::
01594 find_child(PandaNode *node) const {
01595   return _object->do_find_child(node, _cdata->get_down());
01596 }
01597 
01598 ////////////////////////////////////////////////////////////////////
01599 //     Function: PandaNodePipelineReader::get_num_stashed
01600 //       Access: Public
01601 //  Description: Returns the number of stashed nodes this node has.
01602 //               These are former children of the node that have been
01603 //               moved to the special stashed list via stash_child().
01604 ////////////////////////////////////////////////////////////////////
01605 INLINE int PandaNodePipelineReader::
01606 get_num_stashed() const {
01607   return _cdata->get_stashed()->size();
01608 }
01609 
01610 ////////////////////////////////////////////////////////////////////
01611 //     Function: PandaNodePipelineReader::get_stashed
01612 //       Access: Public
01613 //  Description: Returns the nth stashed child of this node.  See
01614 //               get_num_stashed().  Also see get_stashed(), if your
01615 //               intention is to iterate through the complete list of
01616 //               stashed children; get_stashed() is preferable in this
01617 //               case.
01618 ////////////////////////////////////////////////////////////////////
01619 INLINE PandaNode *PandaNodePipelineReader::
01620 get_stashed(int n) const {
01621   CPT(PandaNode::Down) stashed = _cdata->get_stashed();
01622   nassertr(n >= 0 && n < (int)stashed->size(), NULL);
01623   return (*stashed)[n].get_child();
01624 }
01625 
01626 ////////////////////////////////////////////////////////////////////
01627 //     Function: PandaNodePipelineReader::get_stashed_sort
01628 //       Access: Public
01629 //  Description: Returns the sort index of the nth stashed node of this
01630 //               node (that is, the number that was passed to
01631 //               add_child()).  See get_num_stashed().
01632 ////////////////////////////////////////////////////////////////////
01633 INLINE int PandaNodePipelineReader::
01634 get_stashed_sort(int n) const {
01635   CPT(PandaNode::Down) stashed = _cdata->get_stashed();
01636   nassertr(n >= 0 && n < (int)stashed->size(), -1);
01637   return (*stashed)[n].get_sort();
01638 }
01639 
01640 ////////////////////////////////////////////////////////////////////
01641 //     Function: PandaNodePipelineReader::find_stashed
01642 //       Access: Public
01643 //  Description: Returns the index of the indicated stashed node, if
01644 //               it is a stashed child, or -1 if it is not.
01645 ////////////////////////////////////////////////////////////////////
01646 INLINE int PandaNodePipelineReader::
01647 find_stashed(PandaNode *node) const {
01648   return _object->do_find_child(node, _cdata->get_stashed());
01649 }
01650 
01651 ////////////////////////////////////////////////////////////////////
01652 //     Function: PandaNodePipelineReader::get_state
01653 //       Access: Public
01654 //  Description: Returns the complete RenderState that will be applied
01655 //               to all nodes at this level and below, as set on this
01656 //               node.  This returns only the RenderState set on this
01657 //               particular node, and has nothing to do with state
01658 //               that might be inherited from above.
01659 ////////////////////////////////////////////////////////////////////
01660 INLINE const RenderState *PandaNodePipelineReader::
01661 get_state() const {
01662   return _cdata->_state;
01663 }
01664 
01665 ////////////////////////////////////////////////////////////////////
01666 //     Function: PandaNodePipelineReader::get_effects
01667 //       Access: Public
01668 //  Description: Returns the complete RenderEffects that will be
01669 //               applied to this node.
01670 ////////////////////////////////////////////////////////////////////
01671 INLINE const RenderEffects *PandaNodePipelineReader::
01672 get_effects() const {
01673   return _cdata->_effects;
01674 }
01675 
01676 ////////////////////////////////////////////////////////////////////
01677 //     Function: PandaNodePipelineReader::get_transform
01678 //       Access: Public
01679 //  Description: Returns the transform that has been set on this
01680 //               particular node.  This is not the net transform from
01681 //               the root, but simply the transform on this particular
01682 //               node.
01683 ////////////////////////////////////////////////////////////////////
01684 INLINE const TransformState *PandaNodePipelineReader::
01685 get_transform() const {
01686   return _cdata->_transform;
01687 }
01688 
01689 ////////////////////////////////////////////////////////////////////
01690 //     Function: PandaNodePipelineReader::get_prev_transform
01691 //       Access: Public
01692 //  Description: Returns the transform that has been set as this
01693 //               node's "previous" position.  See
01694 //               set_prev_transform().
01695 ////////////////////////////////////////////////////////////////////
01696 const TransformState *PandaNodePipelineReader::
01697 get_prev_transform() const {
01698   return _cdata->_prev_transform;
01699 }
01700 
01701 ////////////////////////////////////////////////////////////////////
01702 //     Function: PandaNodePipelineReader::get_tag
01703 //       Access: Public
01704 //  Description: Retrieves the user-defined value that was previously
01705 //               set on this node for the particular key, if any.  If
01706 //               no value has been previously set, returns the empty
01707 //               string.
01708 ////////////////////////////////////////////////////////////////////
01709 INLINE string PandaNodePipelineReader::
01710 get_tag(const string &key) const {
01711   PandaNode::TagData::const_iterator ti;
01712   ti = _cdata->_tag_data.find(key);
01713   if (ti != _cdata->_tag_data.end()) {
01714     return (*ti).second;
01715   }
01716   return string();
01717 }
01718 
01719 ////////////////////////////////////////////////////////////////////
01720 //     Function: PandaNodePipelineReader::has_tag
01721 //       Access: Public
01722 //  Description: Returns true if a value has been defined on this node
01723 //               for the particular key (even if that value is the
01724 //               empty string), or false if no value has been set.
01725 ////////////////////////////////////////////////////////////////////
01726 INLINE bool PandaNodePipelineReader::
01727 has_tag(const string &key) const {
01728   PandaNode::TagData::const_iterator ti;
01729   ti = _cdata->_tag_data.find(key);
01730   return (ti != _cdata->_tag_data.end());
01731 }
01732 
01733 ////////////////////////////////////////////////////////////////////
01734 //     Function: PandaNodePipelineReader::get_net_collide_mask
01735 //       Access: Public
01736 //  Description: Returns the union of all into_collide_mask() values
01737 //               set at CollisionNodes at this level and below.
01738 ////////////////////////////////////////////////////////////////////
01739 INLINE CollideMask PandaNodePipelineReader::
01740 get_net_collide_mask() const {
01741   nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_net_collide_mask);
01742   return _cdata->_net_collide_mask;
01743 }
01744 
01745 ////////////////////////////////////////////////////////////////////
01746 //     Function: PandaNodePipelineReader::get_off_clip_planes
01747 //       Access: Public
01748 //  Description: Returns a ClipPlaneAttrib which represents the union
01749 //               of all of the clip planes that have been turned *off*
01750 //               at this level and below.
01751 ////////////////////////////////////////////////////////////////////
01752 INLINE CPT(RenderAttrib) PandaNodePipelineReader::
01753 get_off_clip_planes() const {
01754   nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_off_clip_planes);
01755   return _cdata->_off_clip_planes;
01756 }
01757 
01758 ////////////////////////////////////////////////////////////////////
01759 //     Function: PandaNodePipelineReader::get_bounds
01760 //       Access: Public
01761 //  Description: Returns the external bounding volume of this node: a
01762 //               bounding volume that contains the user bounding
01763 //               volume, the internal bounding volume, and all of the
01764 //               children's bounding volumes.
01765 ////////////////////////////////////////////////////////////////////
01766 INLINE CPT(BoundingVolume) PandaNodePipelineReader::
01767 get_bounds() const {
01768   nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_external_bounds);
01769   return _cdata->_external_bounds;
01770 }
01771 
01772 ////////////////////////////////////////////////////////////////////
01773 //     Function: PandaNodePipelineReader::get_nested_vertices
01774 //       Access: Public
01775 //  Description: Returns the total number of vertices that will be
01776 //               rendered by this node and all of its descendents.
01777 //
01778 //               This is not necessarily an accurate count of vertices
01779 //               that will actually be rendered, since this will
01780 //               include all vertices of all LOD's, and it will also
01781 //               include hidden nodes.  It may also omit or only
01782 //               approximate certain kinds of dynamic geometry.
01783 //               However, it will not include stashed nodes.
01784 ////////////////////////////////////////////////////////////////////
01785 INLINE int PandaNodePipelineReader::
01786 get_nested_vertices() const {
01787   nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_nested_vertices);
01788   return _cdata->_nested_vertices;
01789 }
01790 
01791 ////////////////////////////////////////////////////////////////////
01792 //     Function: PandaNodePipelineReader::is_final
01793 //       Access: Public
01794 //  Description: Returns the current state of the "final" flag.
01795 //               Initially, this flag is off (false), but it may be
01796 //               changed by an explicit call to set_final().  See
01797 //               set_final().
01798 ////////////////////////////////////////////////////////////////////
01799 INLINE bool PandaNodePipelineReader::
01800 is_final() const {
01801   return _cdata->_final_bounds;
01802 }
01803 
01804 
01805 ////////////////////////////////////////////////////////////////////
01806 //     Function: PandaNodePipelineReader::get_fancy_bits
01807 //       Access: Public
01808 //  Description: Returns the union of all of the enum FancyBits values
01809 //               corresponding to the various "fancy" attributes that
01810 //               are set on the node.  If this returns 0, the node has
01811 //               nothing interesting about it.  This is intended to
01812 //               speed traversal by quickly skipping past nodes that
01813 //               don't particularly affect the render state.
01814 ////////////////////////////////////////////////////////////////////
01815 INLINE int PandaNodePipelineReader::
01816 get_fancy_bits() const {
01817   return _cdata->_fancy_bits;
01818 }
01819 
01820 ////////////////////////////////////////////////////////////////////
01821 //     Function: PandaNodePipelineReader::get_children
01822 //       Access: Public
01823 //  Description: Returns an object that can be used to walk through
01824 //               the list of children of the node.  When you intend to
01825 //               visit multiple children, using this is slightly
01826 //               faster than calling get_child() directly on the
01827 //               PandaNode, since this object avoids reopening the
01828 //               PipelineCycler each time.
01829 //
01830 //               This object also protects you from self-modifying
01831 //               loops (e.g. adding or removing children during
01832 //               traversal), since a virtual copy of the children is
01833 //               made ahead of time.  The virtual copy is fast--it is
01834 //               a form of copy-on-write, so the list is not actually
01835 //               copied unless it is modified during the traversal.
01836 ////////////////////////////////////////////////////////////////////
01837 INLINE PandaNode::Children PandaNodePipelineReader::
01838 get_children() const {
01839   return PandaNode::Children(_cdata);
01840 }
01841 
01842 ////////////////////////////////////////////////////////////////////
01843 //     Function: PandaNodePipelineReader::get_stashed
01844 //       Access: Public
01845 //  Description: Returns an object that can be used to walk through
01846 //               the list of children of the node.  When you intend to
01847 //               visit multiple children, using this is slightly
01848 //               faster than calling get_stashed() directly on the
01849 //               PandaNode, since this object avoids reopening the
01850 //               PipelineCycler each time.
01851 //
01852 //               This object also protects you from self-modifying
01853 //               loops (e.g. adding or removing children during
01854 //               traversal), since a virtual copy of the children is
01855 //               made ahead of time.  The virtual copy is fast--it is
01856 //               a form of copy-on-write, so the list is not actually
01857 //               copied unless it is modified during the traversal.
01858 ////////////////////////////////////////////////////////////////////
01859 INLINE PandaNode::Stashed PandaNodePipelineReader::
01860 get_stashed() const {
01861   return PandaNode::Stashed(_cdata);
01862 }
01863 
01864 ////////////////////////////////////////////////////////////////////
01865 //     Function: PandaNodePipelineReader::get_parents
01866 //       Access: Public
01867 //  Description: Returns an object that can be used to walk through
01868 //               the list of parents of the node, similar to
01869 //               get_children() and get_stashed().
01870 ////////////////////////////////////////////////////////////////////
01871 INLINE PandaNode::Parents PandaNodePipelineReader::
01872 get_parents() const {
01873   return PandaNode::Parents(_cdata);
01874 }
01875 
01876 ////////////////////////////////////////////////////////////////////
01877 //     Function: PandaNode::BamReaderAuxDataDown::Constructor
01878 //       Access: Public
01879 //  Description: 
01880 ////////////////////////////////////////////////////////////////////
01881 INLINE PandaNode::BamReaderAuxDataDown::
01882 BamReaderAuxDataDown() :
01883   _down_list(PandaNode::get_class_type())
01884 {
01885 }
 All Classes Functions Variables Enumerations