Panda3D
|
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::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. 00855 //////////////////////////////////////////////////////////////////// 00856 INLINE void PandaNode:: 00857 set_dirty_prev_transform() { 00858 if (!_dirty_prev_transform) { 00859 LightMutexHolder holder(_dirty_prev_transforms._lock); 00860 if (!_dirty_prev_transform) { 00861 LinkedListNode::insert_before(&_dirty_prev_transforms); 00862 _dirty_prev_transform = true; 00863 } 00864 } 00865 } 00866 00867 //////////////////////////////////////////////////////////////////// 00868 // Function: PandaNode::clear_dirty_prev_transform 00869 // Access: Private 00870 // Description: Clears the dirty_prev_transform flag, and removes the node 00871 // from the _dirty_prev_transforms chain. 00872 //////////////////////////////////////////////////////////////////// 00873 INLINE void PandaNode:: 00874 clear_dirty_prev_transform() { 00875 if (_dirty_prev_transform) { 00876 LightMutexHolder holder(_dirty_prev_transforms._lock); 00877 if (_dirty_prev_transform) { 00878 LinkedListNode::remove_from_list(); 00879 _dirty_prev_transform = false; 00880 } 00881 } 00882 } 00883 00884 //////////////////////////////////////////////////////////////////// 00885 // Function: PandaNode::DownConnection::Constructor 00886 // Access: Public 00887 // Description: 00888 //////////////////////////////////////////////////////////////////// 00889 INLINE PandaNode::DownConnection:: 00890 DownConnection(PandaNode *child, int sort) : 00891 _child(child), 00892 _sort(sort) 00893 { 00894 } 00895 00896 //////////////////////////////////////////////////////////////////// 00897 // Function: PandaNode::DownConnection::operator < 00898 // Access: Public 00899 // Description: Provides a partial ordering on the children of a node 00900 // so that they are ranked first in sort order, and then 00901 // (by virtue of the ordered_vector) in the order they 00902 // were added. 00903 //////////////////////////////////////////////////////////////////// 00904 INLINE bool PandaNode::DownConnection:: 00905 operator < (const DownConnection &other) const { 00906 return _sort < other._sort; 00907 } 00908 00909 //////////////////////////////////////////////////////////////////// 00910 // Function: PandaNode::DownConnection::get_child 00911 // Access: Public 00912 // Description: 00913 //////////////////////////////////////////////////////////////////// 00914 INLINE PandaNode *PandaNode::DownConnection:: 00915 get_child() const { 00916 return _child; 00917 } 00918 00919 //////////////////////////////////////////////////////////////////// 00920 // Function: PandaNode::DownConnection::set_child 00921 // Access: Public 00922 // Description: This is only called by PandaNode::replace_child(). 00923 //////////////////////////////////////////////////////////////////// 00924 INLINE void PandaNode::DownConnection:: 00925 set_child(PandaNode *child) { 00926 _child = child; 00927 } 00928 00929 //////////////////////////////////////////////////////////////////// 00930 // Function: PandaNode::DownConnection::get_sort 00931 // Access: Public 00932 // Description: 00933 //////////////////////////////////////////////////////////////////// 00934 INLINE int PandaNode::DownConnection:: 00935 get_sort() const { 00936 return _sort; 00937 } 00938 00939 //////////////////////////////////////////////////////////////////// 00940 // Function: PandaNode::UpConnection::Constructor 00941 // Access: Public 00942 // Description: 00943 //////////////////////////////////////////////////////////////////// 00944 INLINE PandaNode::UpConnection:: 00945 UpConnection(PandaNode *parent) : 00946 _parent(parent) 00947 { 00948 } 00949 00950 //////////////////////////////////////////////////////////////////// 00951 // Function: PandaNode::UpConnection::operator < 00952 // Access: Public 00953 // Description: Sorts the up connections of a node by pointer. This 00954 // is different from the down connections of a node, 00955 // which are sorted by the specified _sort number. This 00956 // makes it easy to locate a particular parent of a node 00957 // by pointer, or to test for a parent-child 00958 // relationship given two node pointers. 00959 //////////////////////////////////////////////////////////////////// 00960 INLINE bool PandaNode::UpConnection:: 00961 operator < (const UpConnection &other) const { 00962 return _parent < other._parent; 00963 } 00964 00965 //////////////////////////////////////////////////////////////////// 00966 // Function: PandaNode::UpConnection::get_parent 00967 // Access: Public 00968 // Description: 00969 //////////////////////////////////////////////////////////////////// 00970 INLINE PandaNode *PandaNode::UpConnection:: 00971 get_parent() const { 00972 return _parent; 00973 } 00974 00975 //////////////////////////////////////////////////////////////////// 00976 // Function: PandaNode::BoundsData::Constructor 00977 // Access: Protected 00978 // Description: 00979 //////////////////////////////////////////////////////////////////// 00980 INLINE PandaNode::BoundsData:: 00981 BoundsData() : 00982 _internal_bounds(NULL), 00983 _internal_vertices(0) 00984 { 00985 ++_internal_bounds_mark; 00986 } 00987 00988 //////////////////////////////////////////////////////////////////// 00989 // Function: PandaNode::BoundsData::Copy Constructor 00990 // Access: Protected 00991 // Description: 00992 //////////////////////////////////////////////////////////////////// 00993 INLINE PandaNode::BoundsData:: 00994 BoundsData(const PandaNode::BoundsData ©) : 00995 _internal_bounds(copy._internal_bounds), 00996 _internal_vertices(copy._internal_vertices), 00997 _internal_bounds_mark(copy._internal_bounds_mark), 00998 _internal_bounds_computed(copy._internal_bounds_computed) 00999 { 01000 } 01001 01002 //////////////////////////////////////////////////////////////////// 01003 // Function: PandaNode::BoundsData::copy_bounds 01004 // Access: Protected 01005 // Description: Copies just the BoundsData part of the structure. 01006 //////////////////////////////////////////////////////////////////// 01007 INLINE void PandaNode::BoundsData:: 01008 copy_bounds(const PandaNode::BoundsData ©) { 01009 _internal_bounds = copy._internal_bounds; 01010 _internal_vertices = copy._internal_vertices; 01011 _internal_bounds_mark = copy._internal_bounds_mark; 01012 _internal_bounds_computed = copy._internal_bounds_computed; 01013 } 01014 01015 //////////////////////////////////////////////////////////////////// 01016 // Function: PandaNode::CData::set_fancy_bit 01017 // Access: Public 01018 // Description: Internal function to set (if value is true) or clear 01019 // (if value is false) the indicated bit(s) in the 01020 // _fancy_bits member. 01021 //////////////////////////////////////////////////////////////////// 01022 INLINE void PandaNode::CData:: 01023 set_fancy_bit(int bits, bool value) { 01024 if (value) { 01025 _fancy_bits |= bits; 01026 } else { 01027 _fancy_bits &= ~bits; 01028 } 01029 } 01030 01031 //////////////////////////////////////////////////////////////////// 01032 // Function: PandaNode::CData::get_down 01033 // Access: Public 01034 // Description: Returns a read-only pointer to the _down list. 01035 //////////////////////////////////////////////////////////////////// 01036 INLINE CPT(PandaNode::Down) PandaNode::CData:: 01037 get_down() const { 01038 return _down.get_read_pointer(); 01039 } 01040 01041 //////////////////////////////////////////////////////////////////// 01042 // Function: PandaNode::CData::modify_down 01043 // Access: Public 01044 // Description: Returns a modifiable, unique pointer to the _down 01045 // list. 01046 //////////////////////////////////////////////////////////////////// 01047 INLINE PT(PandaNode::Down) PandaNode::CData:: 01048 modify_down() { 01049 return _down.get_write_pointer(); 01050 } 01051 01052 //////////////////////////////////////////////////////////////////// 01053 // Function: PandaNode::CData::get_stashed 01054 // Access: Public 01055 // Description: Returns a read-only pointer to the _stashed list. 01056 //////////////////////////////////////////////////////////////////// 01057 INLINE CPT(PandaNode::Down) PandaNode::CData:: 01058 get_stashed() const { 01059 return _stashed.get_read_pointer(); 01060 } 01061 01062 //////////////////////////////////////////////////////////////////// 01063 // Function: PandaNode::CData::modify_stashed 01064 // Access: Public 01065 // Description: Returns a modifiable, unique pointer to the _stashed 01066 // list. 01067 //////////////////////////////////////////////////////////////////// 01068 INLINE PT(PandaNode::Down) PandaNode::CData:: 01069 modify_stashed() { 01070 return _stashed.get_write_pointer(); 01071 } 01072 01073 //////////////////////////////////////////////////////////////////// 01074 // Function: PandaNode::CData::get_up 01075 // Access: Public 01076 // Description: Returns a read-only pointer to the _up list. 01077 //////////////////////////////////////////////////////////////////// 01078 INLINE CPT(PandaNode::Up) PandaNode::CData:: 01079 get_up() const { 01080 return _up.get_read_pointer(); 01081 } 01082 01083 //////////////////////////////////////////////////////////////////// 01084 // Function: PandaNode::CData::modify_up 01085 // Access: Public 01086 // Description: Returns a modifiable, unique pointer to the _up 01087 // list. 01088 //////////////////////////////////////////////////////////////////// 01089 INLINE PT(PandaNode::Up) PandaNode::CData:: 01090 modify_up() { 01091 return _up.get_write_pointer(); 01092 } 01093 01094 //////////////////////////////////////////////////////////////////// 01095 // Function: PandaNode::Children::Constructor 01096 // Access: Public 01097 // Description: 01098 //////////////////////////////////////////////////////////////////// 01099 INLINE PandaNode::Children:: 01100 Children() { 01101 } 01102 01103 //////////////////////////////////////////////////////////////////// 01104 // Function: PandaNode::Children::Constructor 01105 // Access: Public 01106 // Description: 01107 //////////////////////////////////////////////////////////////////// 01108 INLINE PandaNode::Children:: 01109 Children(const PandaNode::CData *cdata) : 01110 _down(cdata->get_down()) 01111 { 01112 } 01113 01114 //////////////////////////////////////////////////////////////////// 01115 // Function: PandaNode::Children::Copy Constructor 01116 // Access: Public 01117 // Description: 01118 //////////////////////////////////////////////////////////////////// 01119 INLINE PandaNode::Children:: 01120 Children(const PandaNode::Children ©) : 01121 _down(copy._down) 01122 { 01123 } 01124 01125 //////////////////////////////////////////////////////////////////// 01126 // Function: PandaNode::Children::Copy Assignment Operator 01127 // Access: Public 01128 // Description: 01129 //////////////////////////////////////////////////////////////////// 01130 INLINE void PandaNode::Children:: 01131 operator = (const PandaNode::Children ©) { 01132 _down = copy._down; 01133 } 01134 01135 //////////////////////////////////////////////////////////////////// 01136 // Function: PandaNode::Children::get_num_children 01137 // Access: Public 01138 // Description: Returns the number of children of the node. 01139 //////////////////////////////////////////////////////////////////// 01140 INLINE int PandaNode::Children:: 01141 get_num_children() const { 01142 nassertr(_down != (Down *)NULL, 0); 01143 return _down->size(); 01144 } 01145 01146 //////////////////////////////////////////////////////////////////// 01147 // Function: PandaNode::Children::get_child 01148 // Access: Public 01149 // Description: Returns the nth child of the node. 01150 //////////////////////////////////////////////////////////////////// 01151 INLINE PandaNode *PandaNode::Children:: 01152 get_child(int n) const { 01153 nassertr(_down != (Down *)NULL, NULL); 01154 nassertr(n >= 0 && n < (int)_down->size(), NULL); 01155 return (*_down)[n].get_child(); 01156 } 01157 01158 //////////////////////////////////////////////////////////////////// 01159 // Function: PandaNode::Children::get_child_sort 01160 // Access: Public 01161 // Description: Returns the sort index of the nth child node of this 01162 // node (that is, the number that was passed to 01163 // add_child()). See get_num_children(). 01164 //////////////////////////////////////////////////////////////////// 01165 INLINE int PandaNode::Children:: 01166 get_child_sort(int n) const { 01167 nassertr(_down != (Down *)NULL, -1); 01168 nassertr(n >= 0 && n < (int)_down->size(), -1); 01169 return (*_down)[n].get_sort(); 01170 } 01171 01172 //////////////////////////////////////////////////////////////////// 01173 // Function: PandaNode::Stashed::Constructor 01174 // Access: Public 01175 // Description: 01176 //////////////////////////////////////////////////////////////////// 01177 INLINE PandaNode::Stashed:: 01178 Stashed() { 01179 } 01180 01181 //////////////////////////////////////////////////////////////////// 01182 // Function: PandaNode::Stashed::Constructor 01183 // Access: Public 01184 // Description: 01185 //////////////////////////////////////////////////////////////////// 01186 INLINE PandaNode::Stashed:: 01187 Stashed(const PandaNode::CData *cdata) : 01188 _stashed(cdata->get_stashed()) 01189 { 01190 } 01191 01192 //////////////////////////////////////////////////////////////////// 01193 // Function: PandaNode::Stashed::Copy Constructor 01194 // Access: Public 01195 // Description: 01196 //////////////////////////////////////////////////////////////////// 01197 INLINE PandaNode::Stashed:: 01198 Stashed(const PandaNode::Stashed ©) : 01199 _stashed(copy._stashed) 01200 { 01201 } 01202 01203 //////////////////////////////////////////////////////////////////// 01204 // Function: PandaNode::Stashed::Copy Assignment Operator 01205 // Access: Public 01206 // Description: 01207 //////////////////////////////////////////////////////////////////// 01208 INLINE void PandaNode::Stashed:: 01209 operator = (const PandaNode::Stashed ©) { 01210 _stashed = copy._stashed; 01211 } 01212 01213 //////////////////////////////////////////////////////////////////// 01214 // Function: PandaNode::Stashed::get_num_stashed 01215 // Access: Public 01216 // Description: Returns the number of stashed children of the node. 01217 //////////////////////////////////////////////////////////////////// 01218 INLINE int PandaNode::Stashed:: 01219 get_num_stashed() const { 01220 nassertr(_stashed != (Down *)NULL, 0); 01221 return _stashed->size(); 01222 } 01223 01224 //////////////////////////////////////////////////////////////////// 01225 // Function: PandaNode::Stashed::get_stashed 01226 // Access: Public 01227 // Description: Returns the nth stashed child of the node. 01228 //////////////////////////////////////////////////////////////////// 01229 INLINE PandaNode *PandaNode::Stashed:: 01230 get_stashed(int n) const { 01231 nassertr(_stashed != (Down *)NULL, NULL); 01232 nassertr(n >= 0 && n < (int)_stashed->size(), NULL); 01233 return (*_stashed)[n].get_child(); 01234 } 01235 01236 //////////////////////////////////////////////////////////////////// 01237 // Function: PandaNode::Stashed::get_stashed_sort 01238 // Access: Public 01239 // Description: Returns the sort index of the nth child node of this 01240 // node (that is, the number that was passed to 01241 // add_child()). See get_num_stashed(). 01242 //////////////////////////////////////////////////////////////////// 01243 INLINE int PandaNode::Stashed:: 01244 get_stashed_sort(int n) const { 01245 nassertr(_stashed != (Down *)NULL, -1); 01246 nassertr(n >= 0 && n < (int)_stashed->size(), -1); 01247 return (*_stashed)[n].get_sort(); 01248 } 01249 01250 //////////////////////////////////////////////////////////////////// 01251 // Function: PandaNode::Parents::Constructor 01252 // Access: Public 01253 // Description: 01254 //////////////////////////////////////////////////////////////////// 01255 INLINE PandaNode::Parents:: 01256 Parents() { 01257 } 01258 01259 //////////////////////////////////////////////////////////////////// 01260 // Function: PandaNode::Parents::Constructor 01261 // Access: Public 01262 // Description: 01263 //////////////////////////////////////////////////////////////////// 01264 INLINE PandaNode::Parents:: 01265 Parents(const PandaNode::CData *cdata) : 01266 _up(cdata->get_up()) 01267 { 01268 } 01269 01270 //////////////////////////////////////////////////////////////////// 01271 // Function: PandaNode::Parents::Copy Constructor 01272 // Access: Public 01273 // Description: 01274 //////////////////////////////////////////////////////////////////// 01275 INLINE PandaNode::Parents:: 01276 Parents(const PandaNode::Parents ©) : 01277 _up(copy._up) 01278 { 01279 } 01280 01281 //////////////////////////////////////////////////////////////////// 01282 // Function: PandaNode::Parents::Copy Assignment Operator 01283 // Access: Public 01284 // Description: 01285 //////////////////////////////////////////////////////////////////// 01286 INLINE void PandaNode::Parents:: 01287 operator = (const PandaNode::Parents ©) { 01288 _up = copy._up; 01289 } 01290 01291 //////////////////////////////////////////////////////////////////// 01292 // Function: PandaNode::Parents::get_num_parents 01293 // Access: Public 01294 // Description: Returns the number of parents of the node. 01295 //////////////////////////////////////////////////////////////////// 01296 INLINE int PandaNode::Parents:: 01297 get_num_parents() const { 01298 nassertr(_up != (Up *)NULL, 0); 01299 return _up->size(); 01300 } 01301 01302 //////////////////////////////////////////////////////////////////// 01303 // Function: PandaNode::Parents::get_parent 01304 // Access: Public 01305 // Description: Returns the nth parent of the node. 01306 //////////////////////////////////////////////////////////////////// 01307 INLINE PandaNode *PandaNode::Parents:: 01308 get_parent(int n) const { 01309 nassertr(_up != (Up *)NULL, NULL); 01310 nassertr(n >= 0 && n < (int)_up->size(), NULL); 01311 return (*_up)[n].get_parent(); 01312 } 01313 01314 //////////////////////////////////////////////////////////////////// 01315 // Function: PandaNodePipelineReader::Constructor 01316 // Access: Public 01317 // Description: 01318 //////////////////////////////////////////////////////////////////// 01319 INLINE PandaNodePipelineReader:: 01320 PandaNodePipelineReader(const PandaNode *object, Thread *current_thread) : 01321 _object(object), 01322 _current_thread(current_thread), 01323 _cdata(object->_cycler.read_unlocked(current_thread)) 01324 { 01325 #ifdef _DEBUG 01326 nassertv(_object->test_ref_count_nonzero()); 01327 #endif // _DEBUG 01328 01329 #ifdef DO_PIPELINING 01330 // We node_ref the CData pointer, so that if anyone makes changes to 01331 // the PandaNode while we hold this pointer, it will force a 01332 // copy--so that this object will remain unchanged (if out-of-date). 01333 _cdata->node_ref(); 01334 #endif // DO_PIPELINING 01335 } 01336 01337 //////////////////////////////////////////////////////////////////// 01338 // Function: PandaNodePipelineReader::Copy Constructor 01339 // Access: Public 01340 // Description: 01341 //////////////////////////////////////////////////////////////////// 01342 INLINE PandaNodePipelineReader:: 01343 PandaNodePipelineReader(const PandaNodePipelineReader ©) : 01344 _object(copy._object), 01345 _current_thread(copy._current_thread), 01346 _cdata(copy._cdata) 01347 { 01348 #ifdef DO_PIPELINING 01349 _cdata->node_ref(); 01350 #endif // DO_PIPELINING 01351 01352 /* 01353 if (_cdata != (PandaNode::CData *)NULL) { 01354 _object->_cycler.increment_read(_cdata); 01355 } 01356 */ 01357 } 01358 01359 //////////////////////////////////////////////////////////////////// 01360 // Function: PandaNodePipelineReader::Copy Assignment Operator 01361 // Access: Public 01362 // Description: 01363 //////////////////////////////////////////////////////////////////// 01364 INLINE void PandaNodePipelineReader:: 01365 operator = (const PandaNodePipelineReader ©) { 01366 nassertv(_current_thread == copy._current_thread); 01367 01368 /* 01369 if (_cdata != (PandaNode::CData *)NULL) { 01370 _object->_cycler.release_read(_cdata); 01371 } 01372 */ 01373 01374 #ifdef DO_PIPELINING 01375 node_unref_delete((CycleData *)_cdata); 01376 #endif // DO_PIPELINING 01377 01378 _object = copy._object; 01379 _cdata = copy._cdata; 01380 01381 #ifdef DO_PIPELINING 01382 _cdata->node_ref(); 01383 #endif // DO_PIPELINING 01384 01385 /* 01386 if (_cdata != (PandaNode::CData *)NULL) { 01387 _object->_cycler.increment_read(_cdata); 01388 } 01389 */ 01390 } 01391 01392 //////////////////////////////////////////////////////////////////// 01393 // Function: PandaNodePipelineReader::Destructor 01394 // Access: Public 01395 // Description: 01396 //////////////////////////////////////////////////////////////////// 01397 INLINE PandaNodePipelineReader:: 01398 ~PandaNodePipelineReader() { 01399 /* 01400 if (_cdata != (PandaNode::CData *)NULL) { 01401 _object->_cycler.release_read(_cdata); 01402 } 01403 */ 01404 01405 #ifdef DO_PIPELINING 01406 node_unref_delete((CycleData *)_cdata); 01407 #endif // DO_PIPELINING 01408 01409 #ifdef _DEBUG 01410 _object = NULL; 01411 _cdata = NULL; 01412 #endif // _DEBUG 01413 } 01414 01415 //////////////////////////////////////////////////////////////////// 01416 // Function: PandaNodePipelineReader::get_object 01417 // Access: Public 01418 // Description: 01419 //////////////////////////////////////////////////////////////////// 01420 INLINE const PandaNode *PandaNodePipelineReader:: 01421 get_object() const { 01422 return _object; 01423 } 01424 01425 //////////////////////////////////////////////////////////////////// 01426 // Function: PandaNodePipelineReader::get_current_thread 01427 // Access: Public 01428 // Description: 01429 //////////////////////////////////////////////////////////////////// 01430 INLINE Thread *PandaNodePipelineReader:: 01431 get_current_thread() const { 01432 return _current_thread; 01433 } 01434 01435 //////////////////////////////////////////////////////////////////// 01436 // Function: PandaNodePipelineReader::release 01437 // Access: Public 01438 // Description: Releases the lock on this object. No future calls 01439 // will be valid on this object. 01440 //////////////////////////////////////////////////////////////////// 01441 INLINE void PandaNodePipelineReader:: 01442 release() { 01443 /* 01444 if (_cdata != (PandaNode::CData *)NULL) { 01445 _object->_cycler.release_read(_cdata); 01446 _cdata = NULL; 01447 } 01448 */ 01449 } 01450 01451 //////////////////////////////////////////////////////////////////// 01452 // Function: PandaNodePipelineReader::compose_draw_mask 01453 // Access: Public 01454 // Description: Computes the result of applying this node's draw 01455 // masks to a running draw mask, as during a traversal. 01456 //////////////////////////////////////////////////////////////////// 01457 INLINE void PandaNodePipelineReader:: 01458 compose_draw_mask(DrawMask &running_draw_mask) const { 01459 nassertv(_cdata != (PandaNode::CData *)NULL); 01460 running_draw_mask = (running_draw_mask & ~_cdata->_draw_control_mask) | 01461 (_cdata->_draw_show_mask & _cdata->_draw_control_mask); 01462 } 01463 01464 //////////////////////////////////////////////////////////////////// 01465 // Function: PandaNodePipelineReader::compare_draw_mask 01466 // Access: Public 01467 // Description: Compares the running draw mask computed during a 01468 // traversal with this node's net draw masks. Returns 01469 // true if the node should be traversed into, or false 01470 // if there is nothing at this level or below that will 01471 // be visible to the indicated camera_mask. 01472 //////////////////////////////////////////////////////////////////// 01473 INLINE bool PandaNodePipelineReader:: 01474 compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const { 01475 nassertr(_cdata != (PandaNode::CData *)NULL, false); 01476 nassertr(_cdata->_last_update == _cdata->_next_update, false); 01477 01478 // As a special case, if net_draw_show_mask is all 0, it means 01479 // either that all nodes under this node are hidden to all cameras, 01480 // or that none of them are renderable nodes (or some combination). 01481 // In either case, we might as well short-circuit. 01482 if (_cdata->_net_draw_show_mask.is_zero()) { 01483 return false; 01484 } 01485 01486 DrawMask net_draw_control_mask, net_draw_show_mask; 01487 net_draw_control_mask = _cdata->_net_draw_control_mask; 01488 net_draw_show_mask = _cdata->_net_draw_show_mask; 01489 01490 // Now the bits that are not in net_draw_control_mask--that is, 01491 // those bits that are not changed by any of the nodes at this level 01492 // and below--are taken from running_draw_mask, which is inherited 01493 // from above. On the other hand, the bits that *are* in 01494 // net_draw_control_mask--those bits that are changed by any of the 01495 // nodes at this level and below--are taken from net_draw_show_mask, 01496 // which is propagated upwards from below. 01497 01498 // This way, we will traverse into this node if it has any children 01499 // which want to be visited by the traversal, but we will avoid 01500 // traversing into it if all of its children are hidden to this 01501 // camera. 01502 DrawMask compare_mask = (running_draw_mask & ~net_draw_control_mask) | (net_draw_show_mask & net_draw_control_mask); 01503 01504 return !((compare_mask & PandaNode::_overall_bit).is_zero()) && !((compare_mask & camera_mask).is_zero()); 01505 } 01506 01507 //////////////////////////////////////////////////////////////////// 01508 // Function: PandaNodePipelineReader::get_num_parents 01509 // Access: Public 01510 // Description: Returns the number of parent nodes this node has. If 01511 // this number is greater than 1, the node has been 01512 // multiply instanced. The order of the parent nodes is 01513 // not meaningful and is not related to the order in 01514 // which the node was instanced to them. 01515 //////////////////////////////////////////////////////////////////// 01516 INLINE int PandaNodePipelineReader:: 01517 get_num_parents() const { 01518 return _cdata->get_up()->size(); 01519 } 01520 01521 //////////////////////////////////////////////////////////////////// 01522 // Function: PandaNodePipelineReader::get_parent 01523 // Access: Public 01524 // Description: Returns the nth parent node of this node. See 01525 // get_num_parents(). Also see get_parents(), if your 01526 // intention is to iterate through the complete list of 01527 // parents; get_parents() is preferable in this case. 01528 //////////////////////////////////////////////////////////////////// 01529 INLINE PandaNode *PandaNodePipelineReader:: 01530 get_parent(int n) const { 01531 CPT(PandaNode::Up) up = _cdata->get_up(); 01532 nassertr(n >= 0 && n < (int)up->size(), NULL); 01533 return (*up)[n].get_parent(); 01534 } 01535 01536 //////////////////////////////////////////////////////////////////// 01537 // Function: PandaNodePipelineReader::find_parent 01538 // Access: Public 01539 // Description: Returns the index of the indicated parent node, if it 01540 // is a parent, or -1 if it is not. 01541 //////////////////////////////////////////////////////////////////// 01542 INLINE int PandaNodePipelineReader:: 01543 find_parent(PandaNode *node) const { 01544 return _object->do_find_parent(node, _cdata); 01545 } 01546 01547 //////////////////////////////////////////////////////////////////// 01548 // Function: PandaNodePipelineReader::get_num_children 01549 // Access: Public 01550 // Description: Returns the number of child nodes this node has. The 01551 // order of the child nodes *is* meaningful and is based 01552 // on the sort number that was passed to add_child(), 01553 // and also on the order in which the nodes were added. 01554 //////////////////////////////////////////////////////////////////// 01555 INLINE int PandaNodePipelineReader:: 01556 get_num_children() const { 01557 return _cdata->get_down()->size(); 01558 } 01559 01560 //////////////////////////////////////////////////////////////////// 01561 // Function: PandaNodePipelineReader::get_child 01562 // Access: Public 01563 // Description: Returns the nth child node of this node. See 01564 // get_num_children(). Also see get_children(), if your 01565 // intention is to iterate through the complete list of 01566 // children; get_children() is preferable in this case. 01567 //////////////////////////////////////////////////////////////////// 01568 INLINE PandaNode *PandaNodePipelineReader:: 01569 get_child(int n) const { 01570 CPT(PandaNode::Down) down = _cdata->get_down(); 01571 nassertr(n >= 0 && n < (int)down->size(), NULL); 01572 return (*down)[n].get_child(); 01573 } 01574 01575 //////////////////////////////////////////////////////////////////// 01576 // Function: PandaNodePipelineReader::get_child_sort 01577 // Access: Public 01578 // Description: Returns the sort index of the nth child node of this 01579 // node (that is, the number that was passed to 01580 // add_child()). See get_num_children(). 01581 //////////////////////////////////////////////////////////////////// 01582 INLINE int PandaNodePipelineReader:: 01583 get_child_sort(int n) const { 01584 CPT(PandaNode::Down) down = _cdata->get_down(); 01585 nassertr(n >= 0 && n < (int)down->size(), -1); 01586 return (*down)[n].get_sort(); 01587 } 01588 01589 //////////////////////////////////////////////////////////////////// 01590 // Function: PandaNodePipelineReader::find_child 01591 // Access: Public 01592 // Description: Returns the index of the indicated child node, if it 01593 // is a child, or -1 if it is not. 01594 //////////////////////////////////////////////////////////////////// 01595 INLINE int PandaNodePipelineReader:: 01596 find_child(PandaNode *node) const { 01597 return _object->do_find_child(node, _cdata->get_down()); 01598 } 01599 01600 //////////////////////////////////////////////////////////////////// 01601 // Function: PandaNodePipelineReader::get_num_stashed 01602 // Access: Public 01603 // Description: Returns the number of stashed nodes this node has. 01604 // These are former children of the node that have been 01605 // moved to the special stashed list via stash_child(). 01606 //////////////////////////////////////////////////////////////////// 01607 INLINE int PandaNodePipelineReader:: 01608 get_num_stashed() const { 01609 return _cdata->get_stashed()->size(); 01610 } 01611 01612 //////////////////////////////////////////////////////////////////// 01613 // Function: PandaNodePipelineReader::get_stashed 01614 // Access: Public 01615 // Description: Returns the nth stashed child of this node. See 01616 // get_num_stashed(). Also see get_stashed(), if your 01617 // intention is to iterate through the complete list of 01618 // stashed children; get_stashed() is preferable in this 01619 // case. 01620 //////////////////////////////////////////////////////////////////// 01621 INLINE PandaNode *PandaNodePipelineReader:: 01622 get_stashed(int n) const { 01623 CPT(PandaNode::Down) stashed = _cdata->get_stashed(); 01624 nassertr(n >= 0 && n < (int)stashed->size(), NULL); 01625 return (*stashed)[n].get_child(); 01626 } 01627 01628 //////////////////////////////////////////////////////////////////// 01629 // Function: PandaNodePipelineReader::get_stashed_sort 01630 // Access: Public 01631 // Description: Returns the sort index of the nth stashed node of this 01632 // node (that is, the number that was passed to 01633 // add_child()). See get_num_stashed(). 01634 //////////////////////////////////////////////////////////////////// 01635 INLINE int PandaNodePipelineReader:: 01636 get_stashed_sort(int n) const { 01637 CPT(PandaNode::Down) stashed = _cdata->get_stashed(); 01638 nassertr(n >= 0 && n < (int)stashed->size(), -1); 01639 return (*stashed)[n].get_sort(); 01640 } 01641 01642 //////////////////////////////////////////////////////////////////// 01643 // Function: PandaNodePipelineReader::find_stashed 01644 // Access: Public 01645 // Description: Returns the index of the indicated stashed node, if 01646 // it is a stashed child, or -1 if it is not. 01647 //////////////////////////////////////////////////////////////////// 01648 INLINE int PandaNodePipelineReader:: 01649 find_stashed(PandaNode *node) const { 01650 return _object->do_find_child(node, _cdata->get_stashed()); 01651 } 01652 01653 //////////////////////////////////////////////////////////////////// 01654 // Function: PandaNodePipelineReader::get_state 01655 // Access: Public 01656 // Description: Returns the complete RenderState that will be applied 01657 // to all nodes at this level and below, as set on this 01658 // node. This returns only the RenderState set on this 01659 // particular node, and has nothing to do with state 01660 // that might be inherited from above. 01661 //////////////////////////////////////////////////////////////////// 01662 INLINE const RenderState *PandaNodePipelineReader:: 01663 get_state() const { 01664 return _cdata->_state; 01665 } 01666 01667 //////////////////////////////////////////////////////////////////// 01668 // Function: PandaNodePipelineReader::get_effects 01669 // Access: Public 01670 // Description: Returns the complete RenderEffects that will be 01671 // applied to this node. 01672 //////////////////////////////////////////////////////////////////// 01673 INLINE const RenderEffects *PandaNodePipelineReader:: 01674 get_effects() const { 01675 return _cdata->_effects; 01676 } 01677 01678 //////////////////////////////////////////////////////////////////// 01679 // Function: PandaNodePipelineReader::get_transform 01680 // Access: Public 01681 // Description: Returns the transform that has been set on this 01682 // particular node. This is not the net transform from 01683 // the root, but simply the transform on this particular 01684 // node. 01685 //////////////////////////////////////////////////////////////////// 01686 INLINE const TransformState *PandaNodePipelineReader:: 01687 get_transform() const { 01688 return _cdata->_transform; 01689 } 01690 01691 //////////////////////////////////////////////////////////////////// 01692 // Function: PandaNodePipelineReader::get_prev_transform 01693 // Access: Public 01694 // Description: Returns the transform that has been set as this 01695 // node's "previous" position. See 01696 // set_prev_transform(). 01697 //////////////////////////////////////////////////////////////////// 01698 const TransformState *PandaNodePipelineReader:: 01699 get_prev_transform() const { 01700 return _cdata->_prev_transform; 01701 } 01702 01703 //////////////////////////////////////////////////////////////////// 01704 // Function: PandaNodePipelineReader::get_tag 01705 // Access: Public 01706 // Description: Retrieves the user-defined value that was previously 01707 // set on this node for the particular key, if any. If 01708 // no value has been previously set, returns the empty 01709 // string. 01710 //////////////////////////////////////////////////////////////////// 01711 INLINE string PandaNodePipelineReader:: 01712 get_tag(const string &key) const { 01713 PandaNode::TagData::const_iterator ti; 01714 ti = _cdata->_tag_data.find(key); 01715 if (ti != _cdata->_tag_data.end()) { 01716 return (*ti).second; 01717 } 01718 return string(); 01719 } 01720 01721 //////////////////////////////////////////////////////////////////// 01722 // Function: PandaNodePipelineReader::has_tag 01723 // Access: Public 01724 // Description: Returns true if a value has been defined on this node 01725 // for the particular key (even if that value is the 01726 // empty string), or false if no value has been set. 01727 //////////////////////////////////////////////////////////////////// 01728 INLINE bool PandaNodePipelineReader:: 01729 has_tag(const string &key) const { 01730 PandaNode::TagData::const_iterator ti; 01731 ti = _cdata->_tag_data.find(key); 01732 return (ti != _cdata->_tag_data.end()); 01733 } 01734 01735 //////////////////////////////////////////////////////////////////// 01736 // Function: PandaNodePipelineReader::get_net_collide_mask 01737 // Access: Public 01738 // Description: Returns the union of all into_collide_mask() values 01739 // set at CollisionNodes at this level and below. 01740 //////////////////////////////////////////////////////////////////// 01741 INLINE CollideMask PandaNodePipelineReader:: 01742 get_net_collide_mask() const { 01743 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_net_collide_mask); 01744 return _cdata->_net_collide_mask; 01745 } 01746 01747 //////////////////////////////////////////////////////////////////// 01748 // Function: PandaNodePipelineReader::get_off_clip_planes 01749 // Access: Public 01750 // Description: Returns a ClipPlaneAttrib which represents the union 01751 // of all of the clip planes that have been turned *off* 01752 // at this level and below. 01753 //////////////////////////////////////////////////////////////////// 01754 INLINE CPT(RenderAttrib) PandaNodePipelineReader:: 01755 get_off_clip_planes() const { 01756 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_off_clip_planes); 01757 return _cdata->_off_clip_planes; 01758 } 01759 01760 //////////////////////////////////////////////////////////////////// 01761 // Function: PandaNodePipelineReader::get_bounds 01762 // Access: Public 01763 // Description: Returns the external bounding volume of this node: a 01764 // bounding volume that contains the user bounding 01765 // volume, the internal bounding volume, and all of the 01766 // children's bounding volumes. 01767 //////////////////////////////////////////////////////////////////// 01768 INLINE CPT(BoundingVolume) PandaNodePipelineReader:: 01769 get_bounds() const { 01770 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_external_bounds); 01771 return _cdata->_external_bounds; 01772 } 01773 01774 //////////////////////////////////////////////////////////////////// 01775 // Function: PandaNodePipelineReader::get_nested_vertices 01776 // Access: Public 01777 // Description: Returns the total number of vertices that will be 01778 // rendered by this node and all of its descendents. 01779 // 01780 // This is not necessarily an accurate count of vertices 01781 // that will actually be rendered, since this will 01782 // include all vertices of all LOD's, and it will also 01783 // include hidden nodes. It may also omit or only 01784 // approximate certain kinds of dynamic geometry. 01785 // However, it will not include stashed nodes. 01786 //////////////////////////////////////////////////////////////////// 01787 INLINE int PandaNodePipelineReader:: 01788 get_nested_vertices() const { 01789 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_nested_vertices); 01790 return _cdata->_nested_vertices; 01791 } 01792 01793 //////////////////////////////////////////////////////////////////// 01794 // Function: PandaNodePipelineReader::is_final 01795 // Access: Public 01796 // Description: Returns the current state of the "final" flag. 01797 // Initially, this flag is off (false), but it may be 01798 // changed by an explicit call to set_final(). See 01799 // set_final(). 01800 //////////////////////////////////////////////////////////////////// 01801 INLINE bool PandaNodePipelineReader:: 01802 is_final() const { 01803 return _cdata->_final_bounds; 01804 } 01805 01806 01807 //////////////////////////////////////////////////////////////////// 01808 // Function: PandaNodePipelineReader::get_fancy_bits 01809 // Access: Public 01810 // Description: Returns the union of all of the enum FancyBits values 01811 // corresponding to the various "fancy" attributes that 01812 // are set on the node. If this returns 0, the node has 01813 // nothing interesting about it. This is intended to 01814 // speed traversal by quickly skipping past nodes that 01815 // don't particularly affect the render state. 01816 //////////////////////////////////////////////////////////////////// 01817 INLINE int PandaNodePipelineReader:: 01818 get_fancy_bits() const { 01819 return _cdata->_fancy_bits; 01820 } 01821 01822 //////////////////////////////////////////////////////////////////// 01823 // Function: PandaNodePipelineReader::get_children 01824 // Access: Public 01825 // Description: Returns an object that can be used to walk through 01826 // the list of children of the node. When you intend to 01827 // visit multiple children, using this is slightly 01828 // faster than calling get_child() directly on the 01829 // PandaNode, since this object avoids reopening the 01830 // PipelineCycler each time. 01831 // 01832 // This object also protects you from self-modifying 01833 // loops (e.g. adding or removing children during 01834 // traversal), since a virtual copy of the children is 01835 // made ahead of time. The virtual copy is fast--it is 01836 // a form of copy-on-write, so the list is not actually 01837 // copied unless it is modified during the traversal. 01838 //////////////////////////////////////////////////////////////////// 01839 INLINE PandaNode::Children PandaNodePipelineReader:: 01840 get_children() const { 01841 return PandaNode::Children(_cdata); 01842 } 01843 01844 //////////////////////////////////////////////////////////////////// 01845 // Function: PandaNodePipelineReader::get_stashed 01846 // Access: Public 01847 // Description: Returns an object that can be used to walk through 01848 // the list of children of the node. When you intend to 01849 // visit multiple children, using this is slightly 01850 // faster than calling get_stashed() directly on the 01851 // PandaNode, since this object avoids reopening the 01852 // PipelineCycler each time. 01853 // 01854 // This object also protects you from self-modifying 01855 // loops (e.g. adding or removing children during 01856 // traversal), since a virtual copy of the children is 01857 // made ahead of time. The virtual copy is fast--it is 01858 // a form of copy-on-write, so the list is not actually 01859 // copied unless it is modified during the traversal. 01860 //////////////////////////////////////////////////////////////////// 01861 INLINE PandaNode::Stashed PandaNodePipelineReader:: 01862 get_stashed() const { 01863 return PandaNode::Stashed(_cdata); 01864 } 01865 01866 //////////////////////////////////////////////////////////////////// 01867 // Function: PandaNodePipelineReader::get_parents 01868 // Access: Public 01869 // Description: Returns an object that can be used to walk through 01870 // the list of parents of the node, similar to 01871 // get_children() and get_stashed(). 01872 //////////////////////////////////////////////////////////////////// 01873 INLINE PandaNode::Parents PandaNodePipelineReader:: 01874 get_parents() const { 01875 return PandaNode::Parents(_cdata); 01876 } 01877 01878 //////////////////////////////////////////////////////////////////// 01879 // Function: PandaNode::BamReaderAuxDataDown::Constructor 01880 // Access: Public 01881 // Description: 01882 //////////////////////////////////////////////////////////////////// 01883 INLINE PandaNode::BamReaderAuxDataDown:: 01884 BamReaderAuxDataDown() : 01885 _down_list(PandaNode::get_class_type()) 01886 { 01887 }