00001 // Filename: nodePath.I 00002 // Created by: drose (25Feb02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: NodePath::Default Constructor 00022 // Access: Published 00023 // Description: This constructs an empty NodePath with no nodes. 00024 //////////////////////////////////////////////////////////////////// 00025 INLINE NodePath:: 00026 NodePath() : 00027 _error_type(ET_ok) 00028 { 00029 } 00030 00031 //////////////////////////////////////////////////////////////////// 00032 // Function: NodePath::Constructor 00033 // Access: Published 00034 // Description: This constructs a new NodePath with a single 00035 // node. An ordinary, unattached PandaNode is created 00036 // with the indicated name. 00037 //////////////////////////////////////////////////////////////////// 00038 INLINE NodePath:: 00039 NodePath(const string &top_node_name) : 00040 _error_type(ET_ok) 00041 { 00042 PandaNode *top_node = new PandaNode(top_node_name); 00043 _head = top_node->get_generic_component(false); 00044 } 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Function: NodePath::Constructor 00048 // Access: Published 00049 // Description: This constructs a NodePath for the indicated node. 00050 // If the node does not have any parents, this creates a 00051 // singleton NodePath; otherwise, it automatically finds 00052 // the path from the node to the root. If the node has 00053 // multiple paths to the root, one path is chosen 00054 // arbitrarily and a warning message is printed (but see 00055 // also NodePath::any_path(), below). 00056 //////////////////////////////////////////////////////////////////// 00057 INLINE NodePath:: 00058 NodePath(PandaNode *node) : 00059 _error_type(ET_ok) 00060 { 00061 if (node != (PandaNode *)NULL) { 00062 _head = node->get_generic_component(false); 00063 } 00064 } 00065 00066 //////////////////////////////////////////////////////////////////// 00067 // Function: NodePath::any_path named constructor 00068 // Access: Published, Static 00069 // Description: Returns a new NodePath that represents any arbitrary 00070 // path from the root to the indicated node. This is 00071 // the same thing that would be returned by 00072 // NodePath(node), except that no warning is issued if 00073 // the path is ambiguous. 00074 //////////////////////////////////////////////////////////////////// 00075 INLINE NodePath NodePath:: 00076 any_path(PandaNode *node) { 00077 NodePath result; 00078 if (node != (PandaNode *)NULL) { 00079 result._head = node->get_generic_component(true); 00080 } 00081 return result; 00082 } 00083 00084 //////////////////////////////////////////////////////////////////// 00085 // Function: NodePath::Constructor 00086 // Access: Published 00087 // Description: Constructs a NodePath with the indicated parent 00088 // NodePath and child node; the child node must be a 00089 // stashed or unstashed child of the parent. 00090 //////////////////////////////////////////////////////////////////// 00091 INLINE NodePath:: 00092 NodePath(const NodePath &parent, PandaNode *child_node) : 00093 _error_type(ET_fail) 00094 { 00095 nassertv(!parent.is_empty()); 00096 nassertv(child_node != (PandaNode *)NULL); 00097 _head = PandaNode::get_component(parent._head, child_node); 00098 nassertv(_head != (NodePathComponent *)NULL); 00099 00100 if (_head != (NodePathComponent *)NULL) { 00101 _error_type = ET_ok; 00102 } 00103 } 00104 00105 //////////////////////////////////////////////////////////////////// 00106 // Function: NodePath::Copy Constructor 00107 // Access: Published 00108 // Description: 00109 //////////////////////////////////////////////////////////////////// 00110 INLINE NodePath:: 00111 NodePath(const NodePath ©) : 00112 _head(copy._head), 00113 _error_type(copy._error_type) 00114 { 00115 uncollapse_head(); 00116 } 00117 00118 //////////////////////////////////////////////////////////////////// 00119 // Function: NodePath::Copy Assignment Operator 00120 // Access: Published 00121 // Description: 00122 //////////////////////////////////////////////////////////////////// 00123 INLINE void NodePath:: 00124 operator = (const NodePath ©) { 00125 _head = copy._head; 00126 _error_type = copy._error_type; 00127 uncollapse_head(); 00128 } 00129 00130 //////////////////////////////////////////////////////////////////// 00131 // Function: NodePath::not_found named constructor 00132 // Access: Published, Static 00133 // Description: Creates a NodePath with the ET_not_found error type 00134 // set. 00135 //////////////////////////////////////////////////////////////////// 00136 INLINE NodePath NodePath:: 00137 not_found() { 00138 NodePath result; 00139 result._error_type = ET_not_found; 00140 return result; 00141 } 00142 00143 //////////////////////////////////////////////////////////////////// 00144 // Function: NodePath::removed named constructor 00145 // Access: Published, Static 00146 // Description: Creates a NodePath with the ET_removed error type 00147 // set. 00148 //////////////////////////////////////////////////////////////////// 00149 INLINE NodePath NodePath:: 00150 removed() { 00151 NodePath result; 00152 result._error_type = ET_removed; 00153 return result; 00154 } 00155 00156 //////////////////////////////////////////////////////////////////// 00157 // Function: NodePath::fail named constructor 00158 // Access: Published, Static 00159 // Description: Creates a NodePath with the ET_fail error type 00160 // set. 00161 //////////////////////////////////////////////////////////////////// 00162 INLINE NodePath NodePath:: 00163 fail() { 00164 NodePath result; 00165 result._error_type = ET_fail; 00166 return result; 00167 } 00168 00169 //////////////////////////////////////////////////////////////////// 00170 // Function: NodePath::set_max_search_depth 00171 // Access: Published, Static 00172 // Description: Certain operations, such as find() or 00173 // find_all_matches(), require a traversal of the scene 00174 // graph to search for the target node or nodes. This 00175 // traversal does not attempt to detect cycles, so an 00176 // arbitrary cap is set on the depth of the traversal as 00177 // a poor man's cycle detection, in the event that a 00178 // cycle has inadvertently been introduced into the 00179 // scene graph. 00180 // 00181 // There may be other reasons you'd want to truncate a 00182 // search before the bottom of the scene graph has been 00183 // reached. In any event, this function sets the limit 00184 // on the number of levels that a traversal will 00185 // continue, and hence the maximum length of a path that 00186 // may be returned by a traversal. 00187 // 00188 // This is a static method, and so changing this 00189 // parameter affects all of the NodePaths in the 00190 // universe. 00191 //////////////////////////////////////////////////////////////////// 00192 INLINE void NodePath:: 00193 set_max_search_depth(int max_search_depth) { 00194 _max_search_depth = max_search_depth; 00195 } 00196 00197 //////////////////////////////////////////////////////////////////// 00198 // Function: NodePath::get_max_search_depth 00199 // Access: Published, Static 00200 // Description: Returns the current setting of the search depth 00201 // limit. See set_max_search_depth. 00202 //////////////////////////////////////////////////////////////////// 00203 INLINE int NodePath:: 00204 get_max_search_depth() { 00205 return _max_search_depth; 00206 } 00207 00208 //////////////////////////////////////////////////////////////////// 00209 // Function: NodePath::is_empty 00210 // Access: Published 00211 // Description: Returns true if the NodePath contains no nodes. 00212 //////////////////////////////////////////////////////////////////// 00213 INLINE bool NodePath:: 00214 is_empty() const { 00215 uncollapse_head(); 00216 return (_head == (NodePathComponent *)NULL); 00217 } 00218 00219 //////////////////////////////////////////////////////////////////// 00220 // Function: NodePath::is_singleton 00221 // Access: Published 00222 // Description: Returns true if the NodePath contains exactly one 00223 // node. 00224 //////////////////////////////////////////////////////////////////// 00225 INLINE bool NodePath:: 00226 is_singleton() const { 00227 uncollapse_head(); 00228 return (_head != (NodePathComponent *)NULL && _head->is_top_node()); 00229 } 00230 00231 //////////////////////////////////////////////////////////////////// 00232 // Function: NodePath::get_error_type 00233 // Access: Published 00234 // Description: If is_empty() is true, this returns a code that 00235 // represents the reason why the NodePath is empty. 00236 //////////////////////////////////////////////////////////////////// 00237 INLINE NodePath::ErrorType NodePath:: 00238 get_error_type() const { 00239 return _error_type; 00240 } 00241 00242 //////////////////////////////////////////////////////////////////// 00243 // Function: NodePath::node 00244 // Access: Published 00245 // Description: Returns the referenced node of the path. 00246 //////////////////////////////////////////////////////////////////// 00247 INLINE PandaNode *NodePath:: 00248 node() const { 00249 nassertr_always(!is_empty(), (PandaNode *)NULL); 00250 return _head->get_node(); 00251 } 00252 00253 //////////////////////////////////////////////////////////////////// 00254 // Function: NodePath::get_key 00255 // Access: Published 00256 // Description: Returns an integer that is guaranteed to be the same 00257 // for all NodePaths that represent the same node 00258 // instance, and different for all NodePaths that 00259 // represent a different node instance. 00260 // 00261 // The same key will be returned for a particular 00262 // instance as long as at least one NodePath exists that 00263 // represents that instance; if all NodePaths for a 00264 // particular instance destruct and a new one is later 00265 // created, it may have a different index. However, a 00266 // given key will never be reused for a different 00267 // instance (unless the app has been running long enough 00268 // that we overflow the integer key value). 00269 // 00270 // There are a few special case circumstances that can 00271 // cause the key for a particular instance to be 00272 // changed. These all involve different instances being 00273 // collapsed into the same instance by some scene graph 00274 // operation (for instance, detaching a node below an 00275 // instanced node). 00276 //////////////////////////////////////////////////////////////////// 00277 INLINE int NodePath:: 00278 get_key() const { 00279 if (is_empty()) { 00280 return 0; 00281 } 00282 return _head->get_key(); 00283 } 00284 00285 //////////////////////////////////////////////////////////////////// 00286 // Function: NodePath::get_num_children 00287 // Access: Published 00288 // Description: Returns the number of children of the referenced node. 00289 //////////////////////////////////////////////////////////////////// 00290 INLINE int NodePath:: 00291 get_num_children() const { 00292 nassertr_always(!is_empty(), 0); 00293 return _head->get_node()->get_num_children(); 00294 } 00295 00296 //////////////////////////////////////////////////////////////////// 00297 // Function: NodePath::get_child 00298 // Access: Published 00299 // Description: Returns a NodePath representing the nth child of the 00300 // referenced node. 00301 //////////////////////////////////////////////////////////////////// 00302 INLINE NodePath NodePath:: 00303 get_child(int n) const { 00304 nassertr(n >= 0 && n < get_num_children(), NodePath()); 00305 NodePath child; 00306 child._head = PandaNode::get_component(_head, _head->get_node()->get_child(n)); 00307 return child; 00308 } 00309 00310 //////////////////////////////////////////////////////////////////// 00311 // Function: NodePath::has_parent 00312 // Access: Published 00313 // Description: Returns true if the referenced node has a parent; 00314 // i.e. the NodePath chain contains at least two nodes. 00315 //////////////////////////////////////////////////////////////////// 00316 INLINE bool NodePath:: 00317 has_parent() const { 00318 return !is_empty() && !is_singleton(); 00319 } 00320 00321 //////////////////////////////////////////////////////////////////// 00322 // Function: NodePath::get_parent 00323 // Access: Published 00324 // Description: Returns the NodePath to the parent of the referenced 00325 // node: that is, this NodePath, shortened by one node. 00326 //////////////////////////////////////////////////////////////////// 00327 INLINE NodePath NodePath:: 00328 get_parent() const { 00329 nassertr(has_parent(), NodePath::fail()); 00330 NodePath parent; 00331 parent._head = _head->get_next(); 00332 return parent; 00333 } 00334 00335 //////////////////////////////////////////////////////////////////// 00336 // Function: NodePath::attach_new_node 00337 // Access: Published 00338 // Description: Creates an ordinary PandaNode and attaches it below 00339 // the current NodePath, returning a new NodePath that 00340 // references it. 00341 //////////////////////////////////////////////////////////////////// 00342 INLINE NodePath NodePath:: 00343 attach_new_node(const string &name, int sort) const { 00344 nassertr(verify_complete(), NodePath::fail()); 00345 nassertr_always(!is_empty(), *this); 00346 00347 return attach_new_node(new PandaNode(name), sort); 00348 } 00349 00350 //////////////////////////////////////////////////////////////////// 00351 // Function: NodePath::ls 00352 // Access: Published 00353 // Description: Lists the hierarchy at and below the referenced node. 00354 //////////////////////////////////////////////////////////////////// 00355 INLINE void NodePath:: 00356 ls() const { 00357 ls(nout); 00358 } 00359 00360 //////////////////////////////////////////////////////////////////// 00361 // Function: NodePath::ls 00362 // Access: Published 00363 // Description: Lists the hierarchy at and below the referenced node. 00364 //////////////////////////////////////////////////////////////////// 00365 INLINE void NodePath:: 00366 ls(ostream &out, int indent_level) const { 00367 if (is_empty()) { 00368 out << "(empty)\n"; 00369 } else { 00370 node()->ls(out, indent_level); 00371 } 00372 } 00373 00374 //////////////////////////////////////////////////////////////////// 00375 // Function: NodePath::get_state 00376 // Access: Published 00377 // Description: Returns the complete state object set on this node. 00378 //////////////////////////////////////////////////////////////////// 00379 INLINE const RenderState *NodePath:: 00380 get_state() const { 00381 nassertr_always(!is_empty(), RenderState::make_empty()); 00382 return node()->get_state(); 00383 } 00384 00385 //////////////////////////////////////////////////////////////////// 00386 // Function: NodePath::set_state 00387 // Access: Published 00388 // Description: Changes the complete state object on this node. 00389 //////////////////////////////////////////////////////////////////// 00390 INLINE void NodePath:: 00391 set_state(const RenderState *state) const { 00392 nassertv_always(!is_empty()); 00393 node()->set_state(state); 00394 } 00395 00396 //////////////////////////////////////////////////////////////////// 00397 // Function: NodePath::get_net_state 00398 // Access: Published 00399 // Description: Returns the net state on this node from the root. 00400 //////////////////////////////////////////////////////////////////// 00401 INLINE CPT(RenderState) NodePath:: 00402 get_net_state() const { 00403 uncollapse_head(); 00404 return r_get_net_state(_head); 00405 } 00406 00407 //////////////////////////////////////////////////////////////////// 00408 // Function: NodePath::get_transform 00409 // Access: Published 00410 // Description: Returns the complete transform object set on this node. 00411 //////////////////////////////////////////////////////////////////// 00412 INLINE const TransformState *NodePath:: 00413 get_transform() const { 00414 nassertr_always(!is_empty(), TransformState::make_identity()); 00415 return node()->get_transform(); 00416 } 00417 00418 //////////////////////////////////////////////////////////////////// 00419 // Function: NodePath::set_transform 00420 // Access: Published 00421 // Description: Changes the complete transform object on this node. 00422 //////////////////////////////////////////////////////////////////// 00423 INLINE void NodePath:: 00424 set_transform(const TransformState *transform) const { 00425 nassertv_always(!is_empty()); 00426 node()->set_transform(transform); 00427 } 00428 00429 //////////////////////////////////////////////////////////////////// 00430 // Function: NodePath::get_net_transform 00431 // Access: Published 00432 // Description: Returns the net transform on this node from the root. 00433 //////////////////////////////////////////////////////////////////// 00434 INLINE CPT(TransformState) NodePath:: 00435 get_net_transform() const { 00436 uncollapse_head(); 00437 return r_get_net_transform(_head); 00438 } 00439 00440 //////////////////////////////////////////////////////////////////// 00441 // Function: NodePath::set_pos 00442 // Access: Published 00443 // Description: Sets the translation component of the transform, 00444 // leaving rotation and scale untouched. 00445 //////////////////////////////////////////////////////////////////// 00446 INLINE void NodePath:: 00447 set_pos(float x, float y, float z) { 00448 set_pos(LPoint3f(x, y, z)); 00449 } 00450 00451 INLINE float NodePath:: 00452 get_x() const { 00453 return get_pos()[0]; 00454 } 00455 00456 INLINE float NodePath:: 00457 get_y() const { 00458 return get_pos()[1]; 00459 } 00460 00461 INLINE float NodePath:: 00462 get_z() const { 00463 return get_pos()[2]; 00464 } 00465 00466 //////////////////////////////////////////////////////////////////// 00467 // Function: NodePath::set_hpr 00468 // Access: Published 00469 // Description: Sets the rotation component of the transform, 00470 // leaving translation and scale untouched. 00471 //////////////////////////////////////////////////////////////////// 00472 INLINE void NodePath:: 00473 set_hpr(float h, float p, float r) { 00474 set_hpr(LVecBase3f(h, p, r)); 00475 } 00476 00477 INLINE float NodePath:: 00478 get_h() const { 00479 return get_hpr()[0]; 00480 } 00481 00482 INLINE float NodePath:: 00483 get_p() const { 00484 return get_hpr()[1]; 00485 } 00486 00487 INLINE float NodePath:: 00488 get_r() const { 00489 return get_hpr()[2]; 00490 } 00491 00492 //////////////////////////////////////////////////////////////////// 00493 // Function: NodePath::set_scale 00494 // Access: Published 00495 // Description: Sets the scale component of the transform, 00496 // leaving translation and rotation untouched. 00497 //////////////////////////////////////////////////////////////////// 00498 INLINE void NodePath:: 00499 set_scale(float scale) { 00500 set_scale(LVecBase3f(scale, scale, scale)); 00501 } 00502 00503 INLINE void NodePath:: 00504 set_scale(float sx, float sy, float sz) { 00505 set_scale(LVecBase3f(sx, sy, sz)); 00506 } 00507 00508 INLINE float NodePath:: 00509 get_sx() const { 00510 return get_scale()[0]; 00511 } 00512 00513 INLINE float NodePath:: 00514 get_sy() const { 00515 return get_scale()[1]; 00516 } 00517 00518 INLINE float NodePath:: 00519 get_sz() const { 00520 return get_scale()[2]; 00521 } 00522 00523 //////////////////////////////////////////////////////////////////// 00524 // Function: NodePath::set_pos_hpr 00525 // Access: Published 00526 // Description: Sets the translation and rotation component of the 00527 // transform, leaving scale untouched. 00528 //////////////////////////////////////////////////////////////////// 00529 INLINE void NodePath:: 00530 set_pos_hpr(float x, float y, float z, float h, float p, float r) { 00531 set_pos_hpr(LVecBase3f(x, y, z), LVecBase3f(h, p, r)); 00532 } 00533 00534 //////////////////////////////////////////////////////////////////// 00535 // Function: NodePath::set_hpr_scale 00536 // Access: Published 00537 // Description: Sets the rotation and scale components of the 00538 // transform, leaving translation untouched. 00539 //////////////////////////////////////////////////////////////////// 00540 INLINE void NodePath:: 00541 set_hpr_scale(float h, float p, float r, float sx, float sy, float sz) { 00542 set_hpr_scale(LVecBase3f(h, p, r), LVecBase3f(sx, sy, sz)); 00543 } 00544 00545 //////////////////////////////////////////////////////////////////// 00546 // Function: NodePath::set_pos_hpr_scale 00547 // Access: Published 00548 // Description: Completely replaces the transform with new 00549 // translation, rotation, and scale components. 00550 //////////////////////////////////////////////////////////////////// 00551 INLINE void NodePath:: 00552 set_pos_hpr_scale(float x, float y, float z, float h, float p, float r, 00553 float sx, float sy, float sz) { 00554 set_pos_hpr_scale(LVecBase3f(x, y, z), LVecBase3f(h, p, r), 00555 LVecBase3f(sx, sy, sz)); 00556 } 00557 00558 //////////////////////////////////////////////////////////////////// 00559 // Function: NodePath::clear_mat 00560 // Access: Published 00561 // Description: Completely removes any transform from the referenced 00562 // node. 00563 //////////////////////////////////////////////////////////////////// 00564 INLINE void NodePath:: 00565 clear_mat() { 00566 nassertv_always(!is_empty()); 00567 node()->clear_transform(); 00568 } 00569 00570 //////////////////////////////////////////////////////////////////// 00571 // Function: NodePath::has_mat 00572 // Access: Published 00573 // Description: Returns true if a non-identity transform matrix has 00574 // been applied to the referenced node, false otherwise. 00575 //////////////////////////////////////////////////////////////////// 00576 INLINE bool NodePath:: 00577 has_mat() const { 00578 nassertr_always(!is_empty(), false); 00579 return !node()->get_transform()->is_identity(); 00580 } 00581 00582 //////////////////////////////////////////////////////////////////// 00583 // Function: NodePath::get_mat 00584 // Access: Published 00585 // Description: Returns the transform matrix that has been applied to 00586 // the referenced node, or the identity matrix if no 00587 // matrix has been applied. 00588 //////////////////////////////////////////////////////////////////// 00589 INLINE const LMatrix4f &NodePath:: 00590 get_mat() const { 00591 nassertr_always(!is_empty(), LMatrix4f::ident_mat()); 00592 00593 return node()->get_transform()->get_mat(); 00594 } 00595 00596 //////////////////////////////////////////////////////////////////// 00597 // Function: NodePath::set_color_scale 00598 // Access: Published 00599 // Description: Sets the color scale component of the transform 00600 //////////////////////////////////////////////////////////////////// 00601 INLINE void NodePath:: 00602 set_color_scale(float sr, float sg, float sb, float sa) { 00603 set_color_scale(LVecBase4f(sr, sg, sb, sa)); 00604 } 00605 00606 //////////////////////////////////////////////////////////////////// 00607 // Function: NodePath::set_sr 00608 // Access: Published 00609 // Description: Sets the red scale component of the transform 00610 //////////////////////////////////////////////////////////////////// 00611 INLINE void NodePath:: 00612 set_sr(float sr) { 00613 LVecBase4f new_scale = get_color_scale(); 00614 new_scale[0] = sr; 00615 00616 set_color_scale(new_scale); 00617 } 00618 00619 //////////////////////////////////////////////////////////////////// 00620 // Function: NodePath::set_sg 00621 // Access: Published 00622 // Description: Sets the alpha scale component of the transform 00623 //////////////////////////////////////////////////////////////////// 00624 INLINE void NodePath:: 00625 set_sg(float sg) { 00626 LVecBase4f new_scale = get_color_scale(); 00627 new_scale[1] = sg; 00628 00629 set_color_scale(new_scale); 00630 } 00631 00632 //////////////////////////////////////////////////////////////////// 00633 // Function: NodePath::set_sb 00634 // Access: Published 00635 // Description: Sets the blue scale component of the transform 00636 //////////////////////////////////////////////////////////////////// 00637 INLINE void NodePath:: 00638 set_sb(float sb) { 00639 LVecBase4f new_scale = get_color_scale(); 00640 new_scale[2] = sb; 00641 00642 set_color_scale(new_scale); 00643 } 00644 00645 //////////////////////////////////////////////////////////////////// 00646 // Function: NodePath::set_sa 00647 // Access: Published 00648 // Description: Sets the alpha scale component of the transform 00649 //////////////////////////////////////////////////////////////////// 00650 INLINE void NodePath:: 00651 set_sa(float sa) { 00652 LVecBase4f new_scale = get_color_scale(); 00653 new_scale[3] = sa; 00654 00655 set_color_scale(new_scale); 00656 } 00657 00658 //////////////////////////////////////////////////////////////////// 00659 // Function: NodePath::get_sr 00660 // Access: Published 00661 // Description: Gets the red scale component of the transform 00662 //////////////////////////////////////////////////////////////////// 00663 INLINE float NodePath:: 00664 get_sr() const { 00665 return get_color_scale()[0]; 00666 } 00667 00668 //////////////////////////////////////////////////////////////////// 00669 // Function: NodePath::get_sg 00670 // Access: Published 00671 // Description: Gets the green scale component of the transform 00672 //////////////////////////////////////////////////////////////////// 00673 INLINE float NodePath:: 00674 get_sg() const { 00675 return get_color_scale()[1]; 00676 } 00677 00678 //////////////////////////////////////////////////////////////////// 00679 // Function: NodePath::get_sb 00680 // Access: Published 00681 // Description: Gets the blue scale component of the transform 00682 //////////////////////////////////////////////////////////////////// 00683 INLINE float NodePath:: 00684 get_sb() const { 00685 return get_color_scale()[2]; 00686 } 00687 00688 //////////////////////////////////////////////////////////////////// 00689 // Function: NodePath::get_sa 00690 // Access: Published 00691 // Description: Gets the alpha scale component of the transform 00692 //////////////////////////////////////////////////////////////////// 00693 INLINE float NodePath:: 00694 get_sa() const { 00695 return get_color_scale()[3]; 00696 } 00697 00698 00699 //////////////////////////////////////////////////////////////////// 00700 // Function: NodePath::look_at 00701 // Access: Published 00702 // Description: Sets the transform on this NodePath so that it 00703 // rotates to face the indicated point in space. This 00704 // will overwrite any previously existing scale on the 00705 // node, although it will preserve any translation. 00706 //////////////////////////////////////////////////////////////////// 00707 INLINE void NodePath:: 00708 look_at(float x, float y, float z) { 00709 look_at(LPoint3f(x, y, z)); 00710 } 00711 00712 //////////////////////////////////////////////////////////////////// 00713 // Function: NodePath::heads_up 00714 // Access: Published 00715 // Description: Behaves like look_at(), but with a strong preference 00716 // to keeping the up vector oriented in the indicated 00717 // "up" direction. 00718 //////////////////////////////////////////////////////////////////// 00719 INLINE void NodePath:: 00720 heads_up(float x, float y, float z) { 00721 heads_up(LPoint3f(x, y, z)); 00722 } 00723 00724 //////////////////////////////////////////////////////////////////// 00725 // Function: NodePath::set_pos 00726 // Access: Published 00727 // Description: Sets the translation component of the transform, 00728 // relative to the other node. 00729 //////////////////////////////////////////////////////////////////// 00730 INLINE void NodePath:: 00731 set_pos(const NodePath &other, float x, float y, float z) { 00732 set_pos(other, LPoint3f(x, y, z)); 00733 } 00734 00735 INLINE float NodePath:: 00736 get_x(const NodePath &other) const { 00737 return get_pos(other)[0]; 00738 } 00739 00740 INLINE float NodePath:: 00741 get_y(const NodePath &other) const { 00742 return get_pos(other)[1]; 00743 } 00744 00745 INLINE float NodePath:: 00746 get_z(const NodePath &other) const { 00747 return get_pos(other)[2]; 00748 } 00749 00750 //////////////////////////////////////////////////////////////////// 00751 // Function: NodePath::set_hpr 00752 // Access: Published 00753 // Description: Sets the rotation component of the transform, 00754 // relative to the other node. 00755 //////////////////////////////////////////////////////////////////// 00756 INLINE void NodePath:: 00757 set_hpr(const NodePath &other, float h, float p, float r) { 00758 set_hpr(other, LPoint3f(h, p, r)); 00759 } 00760 00761 INLINE float NodePath:: 00762 get_h(const NodePath &other) const { 00763 return get_hpr(other)[0]; 00764 } 00765 00766 INLINE float NodePath:: 00767 get_p(const NodePath &other) const { 00768 return get_hpr(other)[1]; 00769 } 00770 00771 INLINE float NodePath:: 00772 get_r(const NodePath &other) const { 00773 return get_hpr(other)[2]; 00774 } 00775 00776 //////////////////////////////////////////////////////////////////// 00777 // Function: NodePath::set_scale 00778 // Access: Published 00779 // Description: Sets the scale component of the transform, 00780 // relative to the other node. 00781 //////////////////////////////////////////////////////////////////// 00782 INLINE void NodePath:: 00783 set_scale(const NodePath &other, float sx, float sy, float sz) { 00784 set_scale(other, LPoint3f(sx, sy, sz)); 00785 } 00786 00787 //////////////////////////////////////////////////////////////////// 00788 // Function: NodePath::get_scale 00789 // Access: Published 00790 // Description: Returns the relative scale of the referenced node 00791 // as seen from the other node. 00792 //////////////////////////////////////////////////////////////////// 00793 INLINE float NodePath:: 00794 get_sx(const NodePath &other) const { 00795 return get_scale(other)[0]; 00796 } 00797 00798 INLINE float NodePath:: 00799 get_sy(const NodePath &other) const { 00800 return get_scale(other)[1]; 00801 } 00802 00803 INLINE float NodePath:: 00804 get_sz(const NodePath &other) const { 00805 return get_scale(other)[2]; 00806 } 00807 00808 //////////////////////////////////////////////////////////////////// 00809 // Function: NodePath::set_pos_hpr 00810 // Access: Published 00811 // Description: Sets the translation and rotation component of the 00812 // transform, relative to the other node. 00813 //////////////////////////////////////////////////////////////////// 00814 INLINE void NodePath:: 00815 set_pos_hpr(const NodePath &other, 00816 float x, float y, float z, 00817 float h, float p, float r) { 00818 set_pos_hpr(other, LVecBase3f(x, y, z), LVecBase3f(h, p, r)); 00819 } 00820 00821 //////////////////////////////////////////////////////////////////// 00822 // Function: NodePath::set_hpr_scale 00823 // Access: Published 00824 // Description: Sets the rotation and scale components of the 00825 // transform, leaving translation untouched. This, or 00826 // set_pos_hpr_scale, is the preferred way to update a 00827 // transform when both hpr and scale are to be changed. 00828 //////////////////////////////////////////////////////////////////// 00829 INLINE void NodePath:: 00830 set_hpr_scale(const NodePath &other, 00831 float h, float p, float r, float sx, float sy, float sz) { 00832 set_hpr_scale(other, LVecBase3f(h, p, r), LVecBase3f(sx, sy, sz)); 00833 } 00834 00835 //////////////////////////////////////////////////////////////////// 00836 // Function: NodePath::set_pos_hpr_scale 00837 // Access: Published 00838 // Description: Completely replaces the transform with new 00839 // translation, rotation, and scale components, relative 00840 // to the other node. 00841 //////////////////////////////////////////////////////////////////// 00842 INLINE void NodePath:: 00843 set_pos_hpr_scale(const NodePath &other, 00844 float x, float y, float z, 00845 float h, float p, float r, 00846 float sx, float sy, float sz) { 00847 set_pos_hpr_scale(other, LVecBase3f(x, y, z), LVecBase3f(h, p, r), 00848 LVecBase3f(sx, sy, sz)); 00849 } 00850 00851 //////////////////////////////////////////////////////////////////// 00852 // Function: NodePath::look_at 00853 // Access: Published 00854 // Description: Sets the hpr on this NodePath so that it rotates to 00855 // face the indicated point in space, which is relative 00856 // to the other NodePath. 00857 //////////////////////////////////////////////////////////////////// 00858 INLINE void NodePath:: 00859 look_at(const NodePath &other, float x, float y, float z) { 00860 look_at(other, LPoint3f(x, y, z)); 00861 } 00862 00863 //////////////////////////////////////////////////////////////////// 00864 // Function: NodePath::heads_up 00865 // Access: Published 00866 // Description: Behaves like look_at(), but with a strong preference 00867 // to keeping the up vector oriented in the indicated 00868 // "up" direction. 00869 //////////////////////////////////////////////////////////////////// 00870 INLINE void NodePath:: 00871 heads_up(const NodePath &other, float x, float y, float z) { 00872 heads_up(other, LPoint3f(x, y, z)); 00873 } 00874 00875 //////////////////////////////////////////////////////////////////// 00876 // Function: NodePath::get_distance 00877 // Access: Published 00878 // Description: Returns the straight-line distance between this 00879 // referenced node's coordinate frame's origin, and that 00880 // of the other node's origin. 00881 //////////////////////////////////////////////////////////////////// 00882 INLINE float NodePath:: 00883 get_distance(const NodePath &other) const { 00884 LPoint3f pos = get_pos(other); 00885 return length(LVector3f(pos)); 00886 } 00887 00888 //////////////////////////////////////////////////////////////////// 00889 // Function: NodePath::set_billboard_axis 00890 // Access: Published 00891 // Description: Puts a billboard transition on the node such that it 00892 // will rotate in two dimensions around the up axis. 00893 //////////////////////////////////////////////////////////////////// 00894 INLINE void NodePath:: 00895 set_billboard_axis(float offset) { 00896 set_billboard_axis(NodePath(), offset); 00897 } 00898 00899 //////////////////////////////////////////////////////////////////// 00900 // Function: NodePath::set_billboard_point_eye 00901 // Access: Published 00902 // Description: Puts a billboard transition on the node such that it 00903 // will rotate in three dimensions about the origin, 00904 // keeping its up vector oriented to the top of the 00905 // camera. 00906 //////////////////////////////////////////////////////////////////// 00907 INLINE void NodePath:: 00908 set_billboard_point_eye(float offset) { 00909 set_billboard_point_eye(NodePath(), offset); 00910 } 00911 00912 //////////////////////////////////////////////////////////////////// 00913 // Function: NodePath::set_billboard_point_world 00914 // Access: Published 00915 // Description: Puts a billboard transition on the node such that it 00916 // will rotate in three dimensions about the origin, 00917 // keeping its up vector oriented to the sky. 00918 //////////////////////////////////////////////////////////////////// 00919 INLINE void NodePath:: 00920 set_billboard_point_world(float offset) { 00921 set_billboard_point_world(NodePath(), offset); 00922 } 00923 00924 //////////////////////////////////////////////////////////////////// 00925 // Function: NodePath::adjust_all_priorities 00926 // Access: Published 00927 // Description: Adds the indicated adjustment amount (which may be 00928 // negative) to the priority for all transitions on the 00929 // referenced node, and for all nodes in the subgraph 00930 // below. This can be used to force these nodes not to 00931 // be overridden by a high-level state change above. If 00932 // the priority would drop below zero, it is set to 00933 // zero. 00934 //////////////////////////////////////////////////////////////////// 00935 INLINE void NodePath:: 00936 adjust_all_priorities(int adjustment) { 00937 nassertv_always(!is_empty()); 00938 r_adjust_all_priorities(node(), adjustment); 00939 } 00940 00941 //////////////////////////////////////////////////////////////////// 00942 // Function: NodePath::show 00943 // Access: Published 00944 // Description: Undoes the effect of a previous hide() on this node: 00945 // makes the referenced node (and the entire subgraph 00946 // below this node) visible to all cameras. 00947 //////////////////////////////////////////////////////////////////// 00948 INLINE void NodePath:: 00949 show() { 00950 nassertv_always(!is_empty()); 00951 node()->set_draw_mask(DrawMask::all_on()); 00952 } 00953 00954 //////////////////////////////////////////////////////////////////// 00955 // Function: NodePath::show 00956 // Access: Published 00957 // Description: Makes the referenced node visible just to the 00958 // cameras whose camera_mask shares the indicated bits. 00959 // That is, this sets the indicated bits in the 00960 // node's draw mask. 00961 //////////////////////////////////////////////////////////////////// 00962 INLINE void NodePath:: 00963 show(DrawMask camera_mask) { 00964 nassertv_always(!is_empty()); 00965 node()->set_draw_mask(node()->get_draw_mask() | camera_mask); 00966 } 00967 00968 //////////////////////////////////////////////////////////////////// 00969 // Function: NodePath::hide 00970 // Access: Published 00971 // Description: Makes the referenced node (and the entire subgraph 00972 // below this node) invisible to all cameras. It 00973 // remains part of the scene graph, its bounding volume 00974 // still contributes to its parent's bounding volume, 00975 // and it will still be involved in collision tests. 00976 //////////////////////////////////////////////////////////////////// 00977 INLINE void NodePath:: 00978 hide() { 00979 nassertv_always(!is_empty()); 00980 node()->set_draw_mask(DrawMask::all_off()); 00981 } 00982 00983 //////////////////////////////////////////////////////////////////// 00984 // Function: NodePath::hide 00985 // Access: Published 00986 // Description: Makes the referenced node invisible just to the 00987 // cameras whose camera_mask shares the indicated bits. 00988 // That is, this clears the indicated bits from the 00989 // node's draw mask. 00990 //////////////////////////////////////////////////////////////////// 00991 INLINE void NodePath:: 00992 hide(DrawMask camera_mask) { 00993 nassertv_always(!is_empty()); 00994 node()->set_draw_mask(node()->get_draw_mask() & ~camera_mask); 00995 } 00996 00997 //////////////////////////////////////////////////////////////////// 00998 // Function: NodePath::is_hidden 00999 // Access: Published 01000 // Description: Returns true if the referenced node is hidden from 01001 // the indicated camera(s) either directly, or because 01002 // some ancestor is hidden. 01003 //////////////////////////////////////////////////////////////////// 01004 INLINE bool NodePath:: 01005 is_hidden(DrawMask camera_mask) const { 01006 return !get_hidden_ancestor(camera_mask).is_empty(); 01007 } 01008 01009 //////////////////////////////////////////////////////////////////// 01010 // Function: NodePath::unstash 01011 // Access: Published 01012 // Description: Undoes the effect of a previous stash() on this 01013 // node: makes the referenced node (and the entire 01014 // subgraph below this node) once again part of the 01015 // scene graph. Returns true if the node is unstashed, 01016 // or false if it wasn't stashed to begin with. 01017 //////////////////////////////////////////////////////////////////// 01018 INLINE bool NodePath:: 01019 unstash() { 01020 nassertr(!is_singleton(), false); 01021 PandaNode *parent_node = get_parent().node(); 01022 PandaNode *this_node = node(); 01023 nassertr(parent_node != (PandaNode *)NULL && this_node != (PandaNode *)NULL, false); 01024 return parent_node->unstash_child(this_node); 01025 } 01026 01027 //////////////////////////////////////////////////////////////////// 01028 // Function: NodePath::stash 01029 // Access: Published 01030 // Description: Removes the referenced node (and the entire subgraph 01031 // below this node) from the scene graph in any normal 01032 // sense. The node will no longer be visible and is not 01033 // tested for collisions; furthermore, no normal scene 01034 // graph traversal will visit the node. The node's 01035 // bounding volume no longer contributes to its parent's 01036 // bounding volume. 01037 // 01038 // A stashed node cannot be located by a normal find() 01039 // operation (although a special find string can still 01040 // retrieve it). 01041 // 01042 // Returns true if the node is successfully stashed, or 01043 // false if it was already stashed. 01044 //////////////////////////////////////////////////////////////////// 01045 INLINE bool NodePath:: 01046 stash() { 01047 nassertr(!is_singleton(), false); 01048 PandaNode *parent_node = get_parent().node(); 01049 PandaNode *this_node = node(); 01050 nassertr(parent_node != (PandaNode *)NULL && this_node != (PandaNode *)NULL, false); 01051 return parent_node->stash_child(this_node); 01052 } 01053 01054 //////////////////////////////////////////////////////////////////// 01055 // Function: NodePath::is_stashed 01056 // Access: Published 01057 // Description: Returns true if the referenced node is stashed either 01058 // directly, or because some ancestor is stashed. 01059 //////////////////////////////////////////////////////////////////// 01060 INLINE bool NodePath:: 01061 is_stashed() const { 01062 return !get_stashed_ancestor().is_empty(); 01063 } 01064 01065 //////////////////////////////////////////////////////////////////// 01066 // Function: NodePath::operator == 01067 // Access: Published 01068 // Description: Returns true if the two paths are equivalent; that 01069 // is, if they contain the same list of nodes in the same 01070 // order. 01071 //////////////////////////////////////////////////////////////////// 01072 INLINE bool NodePath:: 01073 operator == (const NodePath &other) const { 01074 return (compare_to(other) == 0); 01075 } 01076 01077 //////////////////////////////////////////////////////////////////// 01078 // Function: NodePath::operator != 01079 // Access: Published 01080 // Description: Returns true if the two paths are not equivalent. 01081 //////////////////////////////////////////////////////////////////// 01082 INLINE bool NodePath:: 01083 operator != (const NodePath &other) const { 01084 return (compare_to(other) != 0); 01085 } 01086 01087 //////////////////////////////////////////////////////////////////// 01088 // Function: NodePath::operator < 01089 // Access: Published 01090 // Description: Returns true if this NodePath sorts before the other 01091 // one, false otherwise. The sorting order of two 01092 // nonequivalent NodePaths is consistent but undefined, 01093 // and is useful only for storing NodePaths in a sorted 01094 // container like an STL set. 01095 //////////////////////////////////////////////////////////////////// 01096 INLINE bool NodePath:: 01097 operator < (const NodePath &other) const { 01098 return (compare_to(other) < 0); 01099 } 01100 01101 //////////////////////////////////////////////////////////////////// 01102 // Function: NodePath::compare_to 01103 // Access: Published 01104 // Description: Returns a number less than zero if this NodePath 01105 // sorts before the other one, greater than zero if it 01106 // sorts after, or zero if they are equivalent. 01107 // 01108 // Two NodePaths are considered equivalent if they 01109 // consist of exactly the same list of nodes in the same 01110 // order. Otherwise, they are different; different 01111 // NodePaths will be ranked in a consistent but 01112 // undefined ordering; the ordering is useful only for 01113 // placing the NodePaths in a sorted container like an 01114 // STL set. 01115 //////////////////////////////////////////////////////////////////// 01116 INLINE int NodePath:: 01117 compare_to(const NodePath &other) const { 01118 uncollapse_head(); 01119 other.uncollapse_head(); 01120 01121 // Nowadays, the NodePathComponents at the head are pointerwise 01122 // equivalent if and only if the NodePaths are equivalent. So we 01123 // only have to compare pointers. 01124 return _head - other._head; 01125 } 01126 01127 01128 INLINE ostream &operator << (ostream &out, const NodePath &node_path) { 01129 node_path.output(out); 01130 return out; 01131 } 01132