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::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 ©) : 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 ©) { 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 ©) : 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 ©) { 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 ©) : 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 ©) { 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 ©) : 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 ©) { 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 ©) : 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 ©) { 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 }