nodePath.I
00001 // Filename: nodePath.I
00002 // Created by:  drose (25Feb02)
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: NodePath::Default Constructor
00018 //       Access: Published
00019 //  Description: This constructs an empty NodePath with no nodes.
00020 ////////////////////////////////////////////////////////////////////
00021 INLINE NodePath::
00022 NodePath() :
00023   _error_type(ET_ok)
00024 {
00025   _backup_key = 0;
00026 }
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: NodePath::Constructor
00030 //       Access: Published
00031 //  Description: This constructs a new NodePath with a single
00032 //               node.  An ordinary, unattached PandaNode is created
00033 //               with the indicated name.
00034 ////////////////////////////////////////////////////////////////////
00035 INLINE NodePath::
00036 NodePath(const string &top_node_name, Thread *current_thread) :
00037   _error_type(ET_ok)
00038 {
00039   PandaNode *top_node = new PandaNode(top_node_name);
00040   int pipeline_stage = current_thread->get_pipeline_stage();
00041   _head = top_node->get_generic_component(false, pipeline_stage, current_thread);
00042   _backup_key = 0;
00043 }
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //     Function: NodePath::Constructor
00047 //       Access: Published
00048 //  Description: This constructs a NodePath for the indicated node.
00049 //               If the node does not have any parents, this creates a
00050 //               singleton NodePath; otherwise, it automatically finds
00051 //               the path from the node to the root.  If the node has
00052 //               multiple paths to the root, one path is chosen
00053 //               arbitrarily and a warning message is printed (but see
00054 //               also NodePath::any_path(), below).
00055 ////////////////////////////////////////////////////////////////////
00056 INLINE NodePath::
00057 NodePath(PandaNode *node, Thread *current_thread) :
00058   _error_type(ET_ok)
00059 {
00060   if (node != (PandaNode *)NULL) {
00061     int pipeline_stage = current_thread->get_pipeline_stage();
00062     _head = node->get_generic_component(false, pipeline_stage, current_thread);
00063   }
00064   _backup_key = 0;
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: NodePath::any_path named constructor
00069 //       Access: Published, Static
00070 //  Description: Returns a new NodePath that represents any arbitrary
00071 //               path from the root to the indicated node.  This is
00072 //               the same thing that would be returned by
00073 //               NodePath(node), except that no warning is issued if
00074 //               the path is ambiguous.
00075 ////////////////////////////////////////////////////////////////////
00076 INLINE NodePath NodePath::
00077 any_path(PandaNode *node, Thread *current_thread) {
00078   NodePath result;
00079   if (node != (PandaNode *)NULL) {
00080     int pipeline_stage = current_thread->get_pipeline_stage();
00081     result._head = node->get_generic_component(true, pipeline_stage,
00082                                                current_thread);
00083   }
00084   return result;
00085 }
00086 
00087 ////////////////////////////////////////////////////////////////////
00088 //     Function: NodePath::Copy Constructor
00089 //       Access: Published
00090 //  Description:
00091 ////////////////////////////////////////////////////////////////////
00092 INLINE NodePath::
00093 NodePath(const NodePath &copy) :
00094   _head(copy._head),
00095   _backup_key(copy._backup_key),
00096   _error_type(copy._error_type)
00097 {
00098 }
00099 
00100 ////////////////////////////////////////////////////////////////////
00101 //     Function: NodePath::Copy Assignment Operator
00102 //       Access: Published
00103 //  Description:
00104 ////////////////////////////////////////////////////////////////////
00105 INLINE void NodePath::
00106 operator = (const NodePath &copy) {
00107   _head = copy._head;
00108   _backup_key = copy._backup_key;
00109   _error_type = copy._error_type;
00110 }
00111 
00112 ////////////////////////////////////////////////////////////////////
00113 //     Function: NodePath::not_found named constructor
00114 //       Access: Published, Static
00115 //  Description: Creates a NodePath with the ET_not_found error type
00116 //               set.
00117 ////////////////////////////////////////////////////////////////////
00118 INLINE NodePath NodePath::
00119 not_found() {
00120   NodePath result;
00121   result._error_type = ET_not_found;
00122   return result;
00123 }
00124 
00125 ////////////////////////////////////////////////////////////////////
00126 //     Function: NodePath::removed named constructor
00127 //       Access: Published, Static
00128 //  Description: Creates a NodePath with the ET_removed error type
00129 //               set.
00130 ////////////////////////////////////////////////////////////////////
00131 INLINE NodePath NodePath::
00132 removed() {
00133   NodePath result;
00134   result._error_type = ET_removed;
00135   return result;
00136 }
00137 
00138 ////////////////////////////////////////////////////////////////////
00139 //     Function: NodePath::fail named constructor
00140 //       Access: Published, Static
00141 //  Description: Creates a NodePath with the ET_fail error type
00142 //               set.
00143 ////////////////////////////////////////////////////////////////////
00144 INLINE NodePath NodePath::
00145 fail() {
00146   NodePath result;
00147   result._error_type = ET_fail;
00148   return result;
00149 }
00150 
00151 ////////////////////////////////////////////////////////////////////
00152 //     Function: NodePath::set_max_search_depth
00153 //       Access: Published, Static
00154 //  Description: Certain operations, such as find() or
00155 //               find_all_matches(), require a traversal of the scene
00156 //               graph to search for the target node or nodes.  This
00157 //               traversal does not attempt to detect cycles, so an
00158 //               arbitrary cap is set on the depth of the traversal as
00159 //               a poor man's cycle detection, in the event that a
00160 //               cycle has inadvertently been introduced into the
00161 //               scene graph.
00162 //
00163 //               There may be other reasons you'd want to truncate a
00164 //               search before the bottom of the scene graph has been
00165 //               reached.  In any event, this function sets the limit
00166 //               on the number of levels that a traversal will
00167 //               continue, and hence the maximum length of a path that
00168 //               may be returned by a traversal.
00169 //
00170 //               This is a static method, and so changing this
00171 //               parameter affects all of the NodePaths in the
00172 //               universe.
00173 ////////////////////////////////////////////////////////////////////
00174 INLINE void NodePath::
00175 set_max_search_depth(int max_search_depth) {
00176   _max_search_depth = max_search_depth;
00177 }
00178 
00179 ////////////////////////////////////////////////////////////////////
00180 //     Function: NodePath::get_max_search_depth
00181 //       Access: Published, Static
00182 //  Description: Returns the current setting of the search depth
00183 //               limit.  See set_max_search_depth.
00184 ////////////////////////////////////////////////////////////////////
00185 INLINE int NodePath::
00186 get_max_search_depth() {
00187   return _max_search_depth;
00188 }
00189 
00190 ////////////////////////////////////////////////////////////////////
00191 //     Function: NodePath::is_empty
00192 //       Access: Published
00193 //  Description: Returns true if the NodePath contains no nodes.
00194 ////////////////////////////////////////////////////////////////////
00195 INLINE bool NodePath::
00196 is_empty() const {
00197   return (_head == (NodePathComponent *)NULL);
00198 }
00199 
00200 ////////////////////////////////////////////////////////////////////
00201 //     Function: NodePath::is_singleton
00202 //       Access: Published
00203 //  Description: Returns true if the NodePath contains exactly one
00204 //               node.
00205 ////////////////////////////////////////////////////////////////////
00206 INLINE bool NodePath::
00207 is_singleton(Thread *current_thread) const {
00208   int pipeline_stage = current_thread->get_pipeline_stage();
00209   return (_head != (NodePathComponent *)NULL && _head->is_top_node(pipeline_stage, current_thread));
00210 }
00211 
00212 ////////////////////////////////////////////////////////////////////
00213 //     Function: NodePath::get_error_type
00214 //       Access: Published
00215 //  Description: If is_empty() is true, this returns a code that
00216 //               represents the reason why the NodePath is empty.
00217 ////////////////////////////////////////////////////////////////////
00218 INLINE NodePath::ErrorType NodePath::
00219 get_error_type() const {
00220   return _error_type;
00221 }
00222 
00223 ////////////////////////////////////////////////////////////////////
00224 //     Function: NodePath::get_top_node
00225 //       Access: Published
00226 //  Description: Returns the top node of the path, or NULL if the path
00227 //               is empty.  This requires iterating through the path.
00228 ////////////////////////////////////////////////////////////////////
00229 INLINE PandaNode *NodePath::
00230 get_top_node(Thread *current_thread) const {
00231   if (is_empty()) {
00232     return (PandaNode *)NULL;
00233   }
00234 
00235   return get_top(current_thread).node();
00236 }
00237 
00238 ////////////////////////////////////////////////////////////////////
00239 //     Function: NodePath::node
00240 //       Access: Published
00241 //  Description: Returns the referenced node of the path.
00242 ////////////////////////////////////////////////////////////////////
00243 INLINE PandaNode *NodePath::
00244 node() const {
00245   nassertr_always(!is_empty(), (PandaNode *)NULL);
00246   return _head->get_node();
00247 }
00248 
00249 ////////////////////////////////////////////////////////////////////
00250 //     Function: NodePath::get_key
00251 //       Access: Published
00252 //  Description: Returns an integer that is guaranteed to be the same
00253 //               for all NodePaths that represent the same node
00254 //               instance, and different for all NodePaths that
00255 //               represent a different node instance.  
00256 //
00257 //               The same key will be returned for a particular
00258 //               instance as long as at least one NodePath exists that
00259 //               represents that instance; if all NodePaths for a
00260 //               particular instance destruct and a new one is later
00261 //               created, it may have a different index.  However, a
00262 //               given key will never be reused for a different
00263 //               instance (unless the app has been running long enough
00264 //               that we overflow the integer key value).
00265 ////////////////////////////////////////////////////////////////////
00266 INLINE int NodePath::
00267 get_key() const {
00268   if (is_empty()) {
00269     return _backup_key;
00270   }
00271   return _head->get_key();
00272 }
00273 
00274 ////////////////////////////////////////////////////////////////////
00275 //     Function: NodePath::add_hash
00276 //       Access: Published
00277 //  Description: Adds the NodePath into the running hash.  This is
00278 //               intended to be used by lower-level code that computes
00279 //               a hash for each NodePath.  It modifies the hash value
00280 //               passed in by a unique adjustment for each NodePath,
00281 //               and returns the modified hash.
00282 //
00283 //               This is similar to the unique integer returned by
00284 //               get_key(), but it is not guaranteed to remain unique
00285 //               beyond the lifetime of this particular NodePath.
00286 //               Once this NodePath destructs, a different NodePath
00287 //               may be created which shares the same hash value.
00288 ////////////////////////////////////////////////////////////////////
00289 INLINE size_t NodePath::
00290 add_hash(size_t hash) const {
00291   return pointer_hash::add_hash(hash, _head);
00292 }
00293 
00294 ////////////////////////////////////////////////////////////////////
00295 //     Function: NodePath::is_same_graph
00296 //       Access: Published
00297 //  Description: Returns true if the node represented by this NodePath
00298 //               is parented within the same graph as that of the
00299 //               other NodePath.  This is essentially the same thing
00300 //               as asking whether get_top() of both NodePaths is the
00301 //               same (e.g., both "render").
00302 ////////////////////////////////////////////////////////////////////
00303 INLINE bool NodePath::
00304 is_same_graph(const NodePath &other, Thread *current_thread) const {
00305   // Actually, it's possible for the top nodes to be the same, but the
00306   // NodePaths still to be considered in different graphs.  But even
00307   // in this case, get_top() will be different for each one.  (They'll
00308   // be different singleton NodePaths that happen to reference the
00309   // same node).
00310 
00311   // This will happen if one of the top nodes is considered a
00312   // different instance--for instance, render.instance_to(NodePath())
00313   // returns a different instance of render that appears to have the
00314   // same top node.  But this is a very rare thing to do.
00315   int a_count, b_count;
00316   return (find_common_ancestor(*this, other, a_count, b_count, current_thread) != (NodePathComponent *)NULL);
00317 }
00318 
00319 ////////////////////////////////////////////////////////////////////
00320 //     Function: NodePath::is_ancestor_of
00321 //       Access: Published
00322 //  Description: Returns true if the node represented by this NodePath
00323 //               is a parent or other ancestor of the other NodePath,
00324 //               or false if it is not.
00325 ////////////////////////////////////////////////////////////////////
00326 INLINE bool NodePath::
00327 is_ancestor_of(const NodePath &other, Thread *current_thread) const {
00328   int a_count, b_count;
00329   if (find_common_ancestor(*this, other, a_count, b_count, current_thread) == (NodePathComponent *)NULL) {
00330     // Not related.
00331     return false;
00332   }
00333 
00334   // They are related; now b is descended from a only if a is the
00335   // common ancestor (which is to say, a_count == 0).
00336   return (a_count == 0);
00337 }
00338 
00339 ////////////////////////////////////////////////////////////////////
00340 //     Function: NodePath::get_common_ancestor
00341 //       Access: Published
00342 //  Description: Returns the lowest NodePath that both of these two
00343 //               NodePaths have in common: the first ancestor that
00344 //               both of them share.  If the two NodePaths are
00345 //               unrelated, returns NodePath::not_found().
00346 ////////////////////////////////////////////////////////////////////
00347 INLINE NodePath NodePath::
00348 get_common_ancestor(const NodePath &other, Thread *current_thread) const {
00349   int a_count, b_count;
00350   NodePathComponent *common = find_common_ancestor(*this, other, a_count, b_count, current_thread);
00351   if (common == (NodePathComponent *)NULL) {
00352     return NodePath::not_found();
00353   }
00354 
00355   NodePath result;
00356   result._head = common;
00357   return result;
00358 }
00359 
00360 ////////////////////////////////////////////////////////////////////
00361 //     Function: NodePath::get_num_children
00362 //       Access: Published
00363 //  Description: Returns the number of children of the referenced node.
00364 ////////////////////////////////////////////////////////////////////
00365 INLINE int NodePath::
00366 get_num_children(Thread *current_thread) const {
00367   nassertr_always(!is_empty(), 0);
00368   return _head->get_node()->get_num_children(current_thread);
00369 }
00370 
00371 ////////////////////////////////////////////////////////////////////
00372 //     Function: NodePath::get_child
00373 //       Access: Published
00374 //  Description: Returns a NodePath representing the nth child of the
00375 //               referenced node.
00376 ////////////////////////////////////////////////////////////////////
00377 INLINE NodePath NodePath::
00378 get_child(int n, Thread *current_thread) const {
00379   nassertr_always(n >= 0 && n < get_num_children(current_thread), NodePath());
00380   NodePath child;
00381   int pipeline_stage = current_thread->get_pipeline_stage();
00382   child._head = PandaNode::get_component(_head, _head->get_node()->get_child(n, current_thread),
00383                                          pipeline_stage, current_thread);
00384   return child;
00385 }
00386 
00387 ////////////////////////////////////////////////////////////////////
00388 //     Function: NodePath::count_num_descendants
00389 //       Access: Published
00390 //  Description: Returns the number of nodes at and below this level.
00391 ////////////////////////////////////////////////////////////////////
00392 INLINE int NodePath::
00393 count_num_descendants() const {
00394   if (is_empty()) {
00395     return 0;
00396   }
00397   return _head->get_node()->count_num_descendants();
00398 }
00399 
00400 ////////////////////////////////////////////////////////////////////
00401 //     Function: NodePath::has_parent
00402 //       Access: Published
00403 //  Description: Returns true if the referenced node has a parent;
00404 //               i.e. the NodePath chain contains at least two nodes.
00405 ////////////////////////////////////////////////////////////////////
00406 INLINE bool NodePath::
00407 has_parent(Thread *current_thread) const {
00408   return !is_empty() && !is_singleton(current_thread);
00409 }
00410 
00411 ////////////////////////////////////////////////////////////////////
00412 //     Function: NodePath::get_parent
00413 //       Access: Published
00414 //  Description: Returns the NodePath to the parent of the referenced
00415 //               node: that is, this NodePath, shortened by one node.
00416 //               The parent of a singleton NodePath is defined to be
00417 //               the empty NodePath.
00418 ////////////////////////////////////////////////////////////////////
00419 INLINE NodePath NodePath::
00420 get_parent(Thread *current_thread) const {
00421   if (!has_parent(current_thread)) {
00422     return NodePath();
00423   }
00424 
00425   int pipeline_stage = current_thread->get_pipeline_stage();
00426 
00427   NodePath parent;
00428   parent._head = _head->get_next(pipeline_stage, current_thread);
00429   return parent;
00430 }
00431 
00432 ////////////////////////////////////////////////////////////////////
00433 //     Function: NodePath::attach_new_node
00434 //       Access: Published
00435 //  Description: Creates an ordinary PandaNode and attaches it below
00436 //               the current NodePath, returning a new NodePath that
00437 //               references it.
00438 ////////////////////////////////////////////////////////////////////
00439 INLINE NodePath NodePath::
00440 attach_new_node(const string &name, int sort, Thread *current_thread) const {
00441   nassertr(verify_complete(current_thread), NodePath::fail());
00442 
00443   return attach_new_node(new PandaNode(name), sort, current_thread);
00444 }
00445 
00446 ////////////////////////////////////////////////////////////////////
00447 //     Function: NodePath::ls
00448 //       Access: Published
00449 //  Description: Lists the hierarchy at and below the referenced node.
00450 ////////////////////////////////////////////////////////////////////
00451 INLINE void NodePath::
00452 ls() const {
00453   ls(nout);
00454 }
00455 
00456 ////////////////////////////////////////////////////////////////////
00457 //     Function: NodePath::ls
00458 //       Access: Published
00459 //  Description: Lists the hierarchy at and below the referenced node.
00460 ////////////////////////////////////////////////////////////////////
00461 INLINE void NodePath::
00462 ls(ostream &out, int indent_level) const {
00463   if (is_empty()) {
00464     out << "(empty)\n";
00465   } else {
00466     node()->ls(out, indent_level);
00467   }
00468 }
00469 
00470 ////////////////////////////////////////////////////////////////////
00471 //     Function: NodePath::reverse_ls
00472 //       Access: Published
00473 //  Description: Lists the hierarchy at and above the referenced node.
00474 ////////////////////////////////////////////////////////////////////
00475 INLINE void NodePath::
00476 reverse_ls() const {
00477   reverse_ls(nout);
00478 }
00479 
00480 ////////////////////////////////////////////////////////////////////
00481 //     Function: NodePath::reverse_ls
00482 //       Access: Published
00483 //  Description: Lists the hierarchy at and above the referenced node.
00484 ////////////////////////////////////////////////////////////////////
00485 INLINE int NodePath::
00486 reverse_ls(ostream &out, int indent_level) const {
00487   if (is_empty()) {
00488     out << "(empty)\n";
00489     return 0;
00490   } else if (has_parent()) {
00491     indent_level = get_parent().reverse_ls(out, indent_level);
00492   }
00493   node()->write(out, indent_level);
00494   return indent_level + 2;
00495 }
00496 
00497 ////////////////////////////////////////////////////////////////////
00498 //     Function: NodePath::set_state
00499 //       Access: Published
00500 //  Description: Changes the complete state object on this node.
00501 ////////////////////////////////////////////////////////////////////
00502 INLINE void NodePath::
00503 set_state(const RenderState *state, Thread *current_thread) {
00504   nassertv_always(!is_empty());
00505   node()->set_state(state, current_thread);
00506 }
00507 
00508 ////////////////////////////////////////////////////////////////////
00509 //     Function: NodePath::get_net_state
00510 //       Access: Published
00511 //  Description: Returns the net state on this node from the root.
00512 ////////////////////////////////////////////////////////////////////
00513 INLINE CPT(RenderState) NodePath::
00514 get_net_state(Thread *current_thread) const {
00515   nassertr(_error_type == ET_ok, RenderState::make_empty());
00516   return r_get_net_state(_head, current_thread);
00517 }
00518 
00519 ////////////////////////////////////////////////////////////////////
00520 //     Function: NodePath::set_attrib
00521 //       Access: Published
00522 //  Description: Adds the indicated render attribute to the scene
00523 //               graph on this node.  This attribute will now apply to
00524 //               this node and everything below.  If there was already
00525 //               an attribute of the same type, it is replaced.
00526 ////////////////////////////////////////////////////////////////////
00527 INLINE void NodePath::
00528 set_attrib(const RenderAttrib *attrib, int priority) {
00529   nassertv_always(!is_empty());
00530   node()->set_attrib(attrib, priority);
00531 }
00532 
00533 ////////////////////////////////////////////////////////////////////
00534 //     Function: NodePath::get_attrib
00535 //       Access: Published
00536 //  Description: Returns the render attribute of the indicated type,
00537 //               if it is defined on the node, or NULL if it is not.
00538 //               This checks only what is set on this particular node
00539 //               level, and has nothing to do with what render
00540 //               attributes may be inherited from parent nodes.
00541 ////////////////////////////////////////////////////////////////////
00542 INLINE const RenderAttrib *NodePath::
00543 get_attrib(TypeHandle type) const {
00544   nassertr_always(!is_empty(), NULL);
00545   return node()->get_attrib(type);
00546 }
00547 
00548 ////////////////////////////////////////////////////////////////////
00549 //     Function: NodePath::has_attrib
00550 //       Access: Published
00551 //  Description: Returns true if there is a render attribute of the
00552 //               indicated type defined on this node, or false if
00553 //               there is not.
00554 ////////////////////////////////////////////////////////////////////
00555 INLINE bool NodePath::
00556 has_attrib(TypeHandle type) const {
00557   nassertr_always(!is_empty(), false);
00558   return node()->has_attrib(type);
00559 }
00560 
00561 ////////////////////////////////////////////////////////////////////
00562 //     Function: NodePath::clear_attrib
00563 //       Access: Published
00564 //  Description: Removes the render attribute of the given type from
00565 //               this node.  This node, and the subgraph below, will
00566 //               now inherit the indicated render attribute from the
00567 //               nodes above this one.
00568 ////////////////////////////////////////////////////////////////////
00569 INLINE void NodePath::
00570 clear_attrib(TypeHandle type) {
00571   nassertv_always(!is_empty());
00572   node()->clear_attrib(type);
00573 }
00574 
00575 ////////////////////////////////////////////////////////////////////
00576 //     Function: NodePath::set_effect
00577 //       Access: Published
00578 //  Description: Adds the indicated render effect to the scene
00579 //               graph on this node.  If there was already an effect
00580 //               of the same type, it is replaced.
00581 ////////////////////////////////////////////////////////////////////
00582 INLINE void NodePath::
00583 set_effect(const RenderEffect *effect) {
00584   nassertv_always(!is_empty());
00585   node()->set_effect(effect);
00586 }
00587 
00588 ////////////////////////////////////////////////////////////////////
00589 //     Function: NodePath::get_effect
00590 //       Access: Published
00591 //  Description: Returns the render effect of the indicated type,
00592 //               if it is defined on the node, or NULL if it is not.
00593 ////////////////////////////////////////////////////////////////////
00594 INLINE const RenderEffect *NodePath::
00595 get_effect(TypeHandle type) const {
00596   nassertr_always(!is_empty(), NULL);
00597   return node()->get_effect(type);
00598 }
00599 
00600 ////////////////////////////////////////////////////////////////////
00601 //     Function: NodePath::has_effect
00602 //       Access: Published
00603 //  Description: Returns true if there is a render effect of the
00604 //               indicated type defined on this node, or false if
00605 //               there is not.
00606 ////////////////////////////////////////////////////////////////////
00607 INLINE bool NodePath::
00608 has_effect(TypeHandle type) const {
00609   nassertr_always(!is_empty(), false);
00610   return node()->has_effect(type);
00611 }
00612 
00613 ////////////////////////////////////////////////////////////////////
00614 //     Function: NodePath::clear_effect
00615 //       Access: Published
00616 //  Description: Removes the render effect of the given type from
00617 //               this node.
00618 ////////////////////////////////////////////////////////////////////
00619 INLINE void NodePath::
00620 clear_effect(TypeHandle type) {
00621   nassertv_always(!is_empty());
00622   node()->clear_effect(type);
00623 }
00624 
00625 ////////////////////////////////////////////////////////////////////
00626 //     Function: NodePath::set_effects
00627 //       Access: Published
00628 //  Description: Sets the complete RenderEffects that will be applied
00629 //               this node.  This completely replaces whatever has
00630 //               been set on this node via repeated calls to
00631 //               set_attrib().
00632 ////////////////////////////////////////////////////////////////////
00633 INLINE void NodePath::
00634 set_effects(const RenderEffects *effects) {
00635   nassertv_always(!is_empty());
00636   node()->set_effects(effects);
00637 }
00638 
00639 ////////////////////////////////////////////////////////////////////
00640 //     Function: NodePath::get_effects
00641 //       Access: Published
00642 //  Description: Returns the complete RenderEffects that will be
00643 //               applied to this node.
00644 ////////////////////////////////////////////////////////////////////
00645 INLINE const RenderEffects *NodePath::
00646 get_effects() const {
00647   nassertr_always(!is_empty(), RenderEffects::make_empty());
00648   return node()->get_effects();
00649 }
00650 
00651 ////////////////////////////////////////////////////////////////////
00652 //     Function: NodePath::clear_effects
00653 //       Access: Published
00654 //  Description: Resets this node to have no render effects.
00655 ////////////////////////////////////////////////////////////////////
00656 INLINE void NodePath::
00657 clear_effects() {
00658   nassertv_always(!is_empty());
00659   node()->clear_effects();
00660 }
00661 
00662 ////////////////////////////////////////////////////////////////////
00663 //     Function: NodePath::clear_transform
00664 //       Access: Published
00665 //  Description: Sets the transform object on this node to identity.
00666 ////////////////////////////////////////////////////////////////////
00667 INLINE void NodePath::
00668 clear_transform(Thread *current_thread) {
00669   set_transform(TransformState::make_identity(), current_thread);
00670 }
00671 
00672 ////////////////////////////////////////////////////////////////////
00673 //     Function: NodePath::set_transform
00674 //       Access: Published
00675 //  Description: Changes the complete transform object on this node.
00676 ////////////////////////////////////////////////////////////////////
00677 INLINE void NodePath::
00678 set_transform(const TransformState *transform, Thread *current_thread) {
00679   nassertv_always(!is_empty());
00680   node()->set_transform(transform, current_thread);
00681 }
00682 
00683 ////////////////////////////////////////////////////////////////////
00684 //     Function: NodePath::clear_transform
00685 //       Access: Published
00686 //  Description: Sets the transform object on this node to identity,
00687 //               relative to the other node.  This effectively places
00688 //               this node at the same position as the other node.
00689 ////////////////////////////////////////////////////////////////////
00690 INLINE void NodePath::
00691 clear_transform(const NodePath &other, Thread *current_thread) {
00692   set_transform(other, TransformState::make_identity(), current_thread);
00693 }
00694 
00695 ////////////////////////////////////////////////////////////////////
00696 //     Function: NodePath::get_net_transform
00697 //       Access: Published
00698 //  Description: Returns the net transform on this node from the root.
00699 ////////////////////////////////////////////////////////////////////
00700 INLINE CPT(TransformState) NodePath::
00701 get_net_transform(Thread *current_thread) const {
00702   nassertr(_error_type == ET_ok, TransformState::make_identity());
00703   return r_get_net_transform(_head, current_thread);
00704 }
00705 
00706 ////////////////////////////////////////////////////////////////////
00707 //     Function: NodePath::set_prev_transform
00708 //       Access: Published
00709 //  Description: Sets the transform that represents this node's
00710 //               "previous" position, one frame ago, for the purposes
00711 //               of detecting motion for accurate collision
00712 //               calculations.
00713 ////////////////////////////////////////////////////////////////////
00714 INLINE void NodePath::
00715 set_prev_transform(const TransformState *transform, Thread *current_thread) {
00716   nassertv_always(!is_empty());
00717   node()->set_prev_transform(transform, current_thread);
00718 }
00719 
00720 ////////////////////////////////////////////////////////////////////
00721 //     Function: NodePath::get_net_prev_transform
00722 //       Access: Published
00723 //  Description: Returns the net "previous" transform on this node
00724 //               from the root.  See set_prev_transform().
00725 ////////////////////////////////////////////////////////////////////
00726 INLINE CPT(TransformState) NodePath::
00727 get_net_prev_transform(Thread *current_thread) const {
00728   nassertr(_error_type == ET_ok, TransformState::make_identity());
00729   return r_get_net_prev_transform(_head, current_thread);
00730 }
00731 
00732 ////////////////////////////////////////////////////////////////////
00733 //     Function: NodePath::set_pos
00734 //       Access: Published
00735 //  Description: Sets the translation component of the transform,
00736 //               leaving rotation and scale untouched.  This also
00737 //               resets the node's "previous" position, so that the
00738 //               collision system will see the node as having suddenly
00739 //               appeared in the new position, without passing any
00740 //               points in between.
00741 ////////////////////////////////////////////////////////////////////
00742 INLINE void NodePath::
00743 set_pos(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
00744   set_pos(LPoint3(x, y, z));
00745 }
00746 
00747 ////////////////////////////////////////////////////////////////////
00748 //     Function: NodePath::set_fluid_pos
00749 //       Access: Published
00750 //  Description: Sets the translation component, without changing the
00751 //               "previous" position, so that the collision system
00752 //               will see the node as moving fluidly from its previous
00753 //               position to its new position.
00754 ////////////////////////////////////////////////////////////////////
00755 INLINE void NodePath::
00756 set_fluid_pos(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
00757   set_fluid_pos(LPoint3(x, y, z));
00758 }
00759 
00760 INLINE PN_stdfloat NodePath::
00761 get_x() const {
00762   return get_pos()[0];
00763 }
00764 
00765 INLINE PN_stdfloat NodePath::
00766 get_y() const {
00767   return get_pos()[1];
00768 }
00769 
00770 INLINE PN_stdfloat NodePath::
00771 get_z() const {
00772   return get_pos()[2];
00773 }
00774 
00775 ////////////////////////////////////////////////////////////////////
00776 //     Function: NodePath::set_hpr
00777 //       Access: Published
00778 //  Description: Sets the rotation component of the transform,
00779 //               leaving translation and scale untouched.
00780 ////////////////////////////////////////////////////////////////////
00781 INLINE void NodePath::
00782 set_hpr(PN_stdfloat h, PN_stdfloat p, PN_stdfloat r) {
00783   set_hpr(LVecBase3(h, p, r));
00784 }
00785 
00786 INLINE PN_stdfloat NodePath::
00787 get_h() const {
00788   return get_hpr()[0];
00789 }
00790 
00791 INLINE PN_stdfloat NodePath::
00792 get_p() const {
00793   return get_hpr()[1];
00794 }
00795 
00796 INLINE PN_stdfloat NodePath::
00797 get_r() const {
00798   return get_hpr()[2];
00799 }
00800 
00801 ////////////////////////////////////////////////////////////////////
00802 //     Function: NodePath::set_scale
00803 //       Access: Published
00804 //  Description: Sets the scale component of the transform,
00805 //               leaving translation and rotation untouched.
00806 ////////////////////////////////////////////////////////////////////
00807 INLINE void NodePath::
00808 set_scale(PN_stdfloat scale) {
00809   set_scale(LVecBase3(scale, scale, scale));
00810 }
00811 
00812 INLINE void NodePath::
00813 set_scale(PN_stdfloat sx, PN_stdfloat sy, PN_stdfloat sz) {
00814   set_scale(LVecBase3(sx, sy, sz));
00815 }
00816 
00817 INLINE PN_stdfloat NodePath::
00818 get_sx() const {
00819   return get_scale()[0];
00820 }
00821 
00822 INLINE PN_stdfloat NodePath::
00823 get_sy() const {
00824   return get_scale()[1];
00825 }
00826 
00827 INLINE PN_stdfloat NodePath::
00828 get_sz() const {
00829   return get_scale()[2];
00830 }
00831 
00832 ////////////////////////////////////////////////////////////////////
00833 //     Function: NodePath::set_shear
00834 //       Access: Published
00835 //  Description: Sets the shear component of the transform,
00836 //               leaving translation, rotation, and scale untouched.
00837 ////////////////////////////////////////////////////////////////////
00838 INLINE void NodePath::
00839 set_shear(PN_stdfloat shxy, PN_stdfloat shxz, PN_stdfloat shyz) {
00840   set_shear(LVecBase3(shxy, shxz, shyz));
00841 }
00842 
00843 INLINE PN_stdfloat NodePath::
00844 get_shxy() const {
00845   return get_shear()[0];
00846 }
00847 
00848 INLINE PN_stdfloat NodePath::
00849 get_shxz() const {
00850   return get_shear()[1];
00851 }
00852 
00853 INLINE PN_stdfloat NodePath::
00854 get_shyz() const {
00855   return get_shear()[2];
00856 }
00857 
00858 ////////////////////////////////////////////////////////////////////
00859 //     Function: NodePath::set_pos_hpr
00860 //       Access: Published
00861 //  Description: Sets the translation and rotation component of the
00862 //               transform, leaving scale untouched.
00863 ////////////////////////////////////////////////////////////////////
00864 INLINE void NodePath::
00865 set_pos_hpr(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat h, PN_stdfloat p, PN_stdfloat r) {
00866   set_pos_hpr(LVecBase3(x, y, z), LVecBase3(h, p, r));
00867 }
00868 
00869 ////////////////////////////////////////////////////////////////////
00870 //     Function: NodePath::set_hpr_scale
00871 //       Access: Published
00872 //  Description: Sets the rotation and scale components of the
00873 //               transform, leaving translation untouched.
00874 ////////////////////////////////////////////////////////////////////
00875 INLINE void NodePath::
00876 set_hpr_scale(PN_stdfloat h, PN_stdfloat p, PN_stdfloat r, PN_stdfloat sx, PN_stdfloat sy, PN_stdfloat sz) {
00877   set_hpr_scale(LVecBase3(h, p, r), LVecBase3(sx, sy, sz));
00878 }
00879 
00880 ////////////////////////////////////////////////////////////////////
00881 //     Function: NodePath::set_pos_hpr_scale
00882 //       Access: Published
00883 //  Description: Completely replaces the transform with new
00884 //               translation, rotation, and scale components.
00885 ////////////////////////////////////////////////////////////////////
00886 INLINE void NodePath::
00887 set_pos_hpr_scale(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat h, PN_stdfloat p, PN_stdfloat r,
00888                   PN_stdfloat sx, PN_stdfloat sy, PN_stdfloat sz) {
00889   set_pos_hpr_scale(LVecBase3(x, y, z), LVecBase3(h, p, r),
00890                     LVecBase3(sx, sy, sz));
00891 }
00892 
00893 ////////////////////////////////////////////////////////////////////
00894 //     Function: NodePath::clear_mat
00895 //       Access: Published
00896 //  Description: Completely removes any transform from the referenced
00897 //               node.
00898 ////////////////////////////////////////////////////////////////////
00899 INLINE void NodePath::
00900 clear_mat() {
00901   nassertv_always(!is_empty());
00902   node()->clear_transform();
00903 }
00904 
00905 ////////////////////////////////////////////////////////////////////
00906 //     Function: NodePath::has_mat
00907 //       Access: Published
00908 //  Description: Returns true if a non-identity transform matrix has
00909 //               been applied to the referenced node, false otherwise.
00910 ////////////////////////////////////////////////////////////////////
00911 INLINE bool NodePath::
00912 has_mat() const {
00913   nassertr_always(!is_empty(), false);
00914   return !node()->get_transform()->is_identity();
00915 }
00916 
00917 ////////////////////////////////////////////////////////////////////
00918 //     Function: NodePath::get_mat
00919 //       Access: Published
00920 //  Description: Returns the transform matrix that has been applied to
00921 //               the referenced node, or the identity matrix if no
00922 //               matrix has been applied.
00923 ////////////////////////////////////////////////////////////////////
00924 INLINE const LMatrix4 &NodePath::
00925 get_mat() const {
00926   nassertr_always(!is_empty(), LMatrix4::ident_mat());
00927 
00928   return node()->get_transform()->get_mat();
00929 }
00930 
00931 
00932 ////////////////////////////////////////////////////////////////////
00933 //     Function: NodePath::look_at
00934 //       Access: Published
00935 //  Description: Sets the transform on this NodePath so that it
00936 //               rotates to face the indicated point in space.  This
00937 //               will overwrite any previously existing scale on the
00938 //               node, although it will preserve any translation.
00939 ////////////////////////////////////////////////////////////////////
00940 INLINE void NodePath::
00941 look_at(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
00942   look_at(LPoint3(x, y, z));
00943 }
00944 
00945 ////////////////////////////////////////////////////////////////////
00946 //     Function: NodePath::heads_up
00947 //       Access: Published
00948 //  Description: Behaves like look_at(), but with a strong preference
00949 //               to keeping the up vector oriented in the indicated
00950 //               "up" direction.
00951 ////////////////////////////////////////////////////////////////////
00952 INLINE void NodePath::
00953 heads_up(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
00954   heads_up(LPoint3(x, y, z));
00955 }
00956 
00957 ////////////////////////////////////////////////////////////////////
00958 //     Function: NodePath::set_pos
00959 //       Access: Published
00960 //  Description: Sets the translation component of the transform,
00961 //               relative to the other node.
00962 ////////////////////////////////////////////////////////////////////
00963 INLINE void NodePath::
00964 set_pos(const NodePath &other, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
00965   set_pos(other, LPoint3(x, y, z));
00966 }
00967 
00968 ////////////////////////////////////////////////////////////////////
00969 //     Function: NodePath::set_fluid_pos
00970 //       Access: Published
00971 //  Description: Sets the translation component, without changing the
00972 //               "previous" position, so that the collision system
00973 //               will see the node as moving fluidly from its previous
00974 //               position to its new position.
00975 ////////////////////////////////////////////////////////////////////
00976 INLINE void NodePath::
00977 set_fluid_pos(const NodePath &other, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
00978   set_fluid_pos(other, LPoint3(x, y, z));
00979 }
00980 
00981 INLINE PN_stdfloat NodePath::
00982 get_x(const NodePath &other) const {
00983   return get_pos(other)[0];
00984 }
00985 
00986 INLINE PN_stdfloat NodePath::
00987 get_y(const NodePath &other) const {
00988   return get_pos(other)[1];
00989 }
00990 
00991 INLINE PN_stdfloat NodePath::
00992 get_z(const NodePath &other) const {
00993   return get_pos(other)[2];
00994 }
00995 
00996 ////////////////////////////////////////////////////////////////////
00997 //     Function: NodePath::set_hpr
00998 //       Access: Published
00999 //  Description: Sets the rotation component of the transform,
01000 //               relative to the other node.
01001 ////////////////////////////////////////////////////////////////////
01002 INLINE void NodePath::
01003 set_hpr(const NodePath &other, PN_stdfloat h, PN_stdfloat p, PN_stdfloat r) {
01004   set_hpr(other, LPoint3(h, p, r));
01005 }
01006 
01007 INLINE PN_stdfloat NodePath::
01008 get_h(const NodePath &other) const {
01009   return get_hpr(other)[0];
01010 }
01011 
01012 INLINE PN_stdfloat NodePath::
01013 get_p(const NodePath &other) const {
01014   return get_hpr(other)[1];
01015 }
01016 
01017 INLINE PN_stdfloat NodePath::
01018 get_r(const NodePath &other) const {
01019   return get_hpr(other)[2];
01020 }
01021 
01022 ////////////////////////////////////////////////////////////////////
01023 //     Function: NodePath::set_scale
01024 //       Access: Published
01025 //  Description: Sets the scale component of the transform,
01026 //               relative to the other node.
01027 ////////////////////////////////////////////////////////////////////
01028 INLINE void NodePath::
01029 set_scale(const NodePath &other, PN_stdfloat scale) {
01030   set_scale(other, LPoint3(scale, scale, scale));
01031 }
01032 
01033 ////////////////////////////////////////////////////////////////////
01034 //     Function: NodePath::set_scale
01035 //       Access: Published
01036 //  Description: Sets the scale component of the transform,
01037 //               relative to the other node.
01038 ////////////////////////////////////////////////////////////////////
01039 INLINE void NodePath::
01040 set_scale(const NodePath &other, PN_stdfloat sx, PN_stdfloat sy, PN_stdfloat sz) {
01041   set_scale(other, LPoint3(sx, sy, sz));
01042 }
01043 
01044 ////////////////////////////////////////////////////////////////////
01045 //     Function: NodePath::get_scale
01046 //       Access: Published
01047 //  Description: Returns the relative scale of the referenced node
01048 //               as seen from the other node.
01049 ////////////////////////////////////////////////////////////////////
01050 INLINE PN_stdfloat NodePath::
01051 get_sx(const NodePath &other) const {
01052   return get_scale(other)[0];
01053 }
01054 
01055 INLINE PN_stdfloat NodePath::
01056 get_sy(const NodePath &other) const {
01057   return get_scale(other)[1];
01058 }
01059 
01060 INLINE PN_stdfloat NodePath::
01061 get_sz(const NodePath &other) const {
01062   return get_scale(other)[2];
01063 }
01064 
01065 ////////////////////////////////////////////////////////////////////
01066 //     Function: NodePath::set_shear
01067 //       Access: Published
01068 //  Description: Sets the shear component of the transform,
01069 //               relative to the other node.
01070 ////////////////////////////////////////////////////////////////////
01071 INLINE void NodePath::
01072 set_shear(const NodePath &other, PN_stdfloat shxy, PN_stdfloat shxz, PN_stdfloat shyz) {
01073   set_shear(other, LPoint3(shxy, shxz, shyz));
01074 }
01075 
01076 ////////////////////////////////////////////////////////////////////
01077 //     Function: NodePath::get_shear
01078 //       Access: Published
01079 //  Description: Returns the relative shear of the referenced node
01080 //               as seen from the other node.
01081 ////////////////////////////////////////////////////////////////////
01082 INLINE PN_stdfloat NodePath::
01083 get_shxy(const NodePath &other) const {
01084   return get_shear(other)[0];
01085 }
01086 
01087 INLINE PN_stdfloat NodePath::
01088 get_shxz(const NodePath &other) const {
01089   return get_shear(other)[1];
01090 }
01091 
01092 INLINE PN_stdfloat NodePath::
01093 get_shyz(const NodePath &other) const {
01094   return get_shear(other)[2];
01095 }
01096 
01097 ////////////////////////////////////////////////////////////////////
01098 //     Function: NodePath::set_pos_hpr
01099 //       Access: Published
01100 //  Description: Sets the translation and rotation component of the
01101 //               transform, relative to the other node.
01102 ////////////////////////////////////////////////////////////////////
01103 INLINE void NodePath::
01104 set_pos_hpr(const NodePath &other,
01105             PN_stdfloat x, PN_stdfloat y, PN_stdfloat z,
01106             PN_stdfloat h, PN_stdfloat p, PN_stdfloat r) {
01107   set_pos_hpr(other, LVecBase3(x, y, z), LVecBase3(h, p, r));
01108 }
01109 
01110 ////////////////////////////////////////////////////////////////////
01111 //     Function: NodePath::set_hpr_scale
01112 //       Access: Published
01113 //  Description: Sets the rotation and scale components of the
01114 //               transform, leaving translation untouched.  This, or
01115 //               set_pos_hpr_scale, is the preferred way to update a
01116 //               transform when both hpr and scale are to be changed.
01117 ////////////////////////////////////////////////////////////////////
01118 INLINE void NodePath::
01119 set_hpr_scale(const NodePath &other,
01120         PN_stdfloat h, PN_stdfloat p, PN_stdfloat r, PN_stdfloat sx, PN_stdfloat sy, PN_stdfloat sz) {
01121   set_hpr_scale(other, LVecBase3(h, p, r), LVecBase3(sx, sy, sz));
01122 }
01123 
01124 ////////////////////////////////////////////////////////////////////
01125 //     Function: NodePath::set_pos_hpr_scale
01126 //       Access: Published
01127 //  Description: Completely replaces the transform with new
01128 //               translation, rotation, and scale components, relative
01129 //               to the other node.
01130 ////////////////////////////////////////////////////////////////////
01131 INLINE void NodePath::
01132 set_pos_hpr_scale(const NodePath &other,
01133                   PN_stdfloat x, PN_stdfloat y, PN_stdfloat z,
01134                   PN_stdfloat h, PN_stdfloat p, PN_stdfloat r,
01135                   PN_stdfloat sx, PN_stdfloat sy, PN_stdfloat sz) {
01136   set_pos_hpr_scale(other, LVecBase3(x, y, z), LVecBase3(h, p, r),
01137                     LVecBase3(sx, sy, sz));
01138 }
01139 
01140 ////////////////////////////////////////////////////////////////////
01141 //     Function: NodePath::look_at
01142 //       Access: Published
01143 //  Description: Sets the hpr on this NodePath so that it rotates to
01144 //               face the indicated point in space, which is relative
01145 //               to the other NodePath.
01146 ////////////////////////////////////////////////////////////////////
01147 INLINE void NodePath::
01148 look_at(const NodePath &other, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
01149   look_at(other, LPoint3(x, y, z));
01150 }
01151 
01152 ////////////////////////////////////////////////////////////////////
01153 //     Function: NodePath::heads_up
01154 //       Access: Published
01155 //  Description: Behaves like look_at(), but with a strong preference
01156 //               to keeping the up vector oriented in the indicated
01157 //               "up" direction.
01158 ////////////////////////////////////////////////////////////////////
01159 INLINE void NodePath::
01160 heads_up(const NodePath &other, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
01161   heads_up(other, LPoint3(x, y, z));
01162 }
01163 
01164 ////////////////////////////////////////////////////////////////////
01165 //     Function: NodePath::get_distance
01166 //       Access: Published
01167 //  Description: Returns the straight-line distance between this
01168 //               referenced node's coordinate frame's origin, and that
01169 //               of the other node's origin.
01170 ////////////////////////////////////////////////////////////////////
01171 INLINE PN_stdfloat NodePath::
01172 get_distance(const NodePath &other) const {
01173   LPoint3 pos = get_pos(other);
01174   return length(LVector3(pos));
01175 }
01176 
01177 ////////////////////////////////////////////////////////////////////
01178 //     Function: NodePath::set_color_scale
01179 //       Access: Published
01180 //  Description: Sets the color scale component of the transform
01181 ////////////////////////////////////////////////////////////////////
01182 INLINE void NodePath::
01183 set_color_scale(PN_stdfloat sr, PN_stdfloat sg, PN_stdfloat sb, PN_stdfloat sa, int priority) {
01184   set_color_scale(LVecBase4(sr, sg, sb, sa), priority);
01185 }
01186 
01187 ////////////////////////////////////////////////////////////////////
01188 //     Function: NodePath::compose_color_scale
01189 //       Access: Published
01190 //  Description: Sets the color scale component of the transform
01191 ////////////////////////////////////////////////////////////////////
01192 INLINE void NodePath::
01193 compose_color_scale(PN_stdfloat sr, PN_stdfloat sg, PN_stdfloat sb, PN_stdfloat sa, int priority) {
01194   compose_color_scale(LVecBase4(sr, sg, sb, sa), priority);
01195 }
01196 
01197 ////////////////////////////////////////////////////////////////////
01198 //     Function: NodePath::set_sr
01199 //       Access: Published
01200 //  Description: Sets the red scale component of the transform
01201 ////////////////////////////////////////////////////////////////////
01202 INLINE void NodePath::
01203 set_sr(PN_stdfloat sr) {
01204   LVecBase4 new_scale = get_color_scale();
01205   new_scale[0] = sr;
01206 
01207   set_color_scale(new_scale);
01208 }
01209 
01210 ////////////////////////////////////////////////////////////////////
01211 //     Function: NodePath::set_sg
01212 //       Access: Published
01213 //  Description: Sets the alpha scale component of the transform
01214 ////////////////////////////////////////////////////////////////////
01215 INLINE void NodePath::
01216 set_sg(PN_stdfloat sg) {
01217   LVecBase4 new_scale = get_color_scale();
01218   new_scale[1] = sg;
01219 
01220   set_color_scale(new_scale);
01221 }
01222 
01223 ////////////////////////////////////////////////////////////////////
01224 //     Function: NodePath::set_sb
01225 //       Access: Published
01226 //  Description: Sets the blue scale component of the transform
01227 ////////////////////////////////////////////////////////////////////
01228 INLINE void NodePath::
01229 set_sb(PN_stdfloat sb) {
01230   LVecBase4 new_scale = get_color_scale();
01231   new_scale[2] = sb;
01232 
01233   set_color_scale(new_scale);
01234 }
01235 
01236 ////////////////////////////////////////////////////////////////////
01237 //     Function: NodePath::set_sa
01238 //       Access: Published
01239 //  Description: Sets the alpha scale component of the transform
01240 ////////////////////////////////////////////////////////////////////
01241 INLINE void NodePath::
01242 set_sa(PN_stdfloat sa) {
01243   LVecBase4 new_scale = get_color_scale();
01244   new_scale[3] = sa;
01245 
01246   set_color_scale(new_scale);
01247 }
01248 
01249 ////////////////////////////////////////////////////////////////////
01250 //     Function: NodePath::get_sr
01251 //       Access: Published
01252 //  Description: Gets the red scale component of the transform
01253 ////////////////////////////////////////////////////////////////////
01254 INLINE PN_stdfloat NodePath::
01255 get_sr() const {
01256   return get_color_scale()[0];
01257 }
01258 
01259 ////////////////////////////////////////////////////////////////////
01260 //     Function: NodePath::get_sg
01261 //       Access: Published
01262 //  Description: Gets the green scale component of the transform
01263 ////////////////////////////////////////////////////////////////////
01264 INLINE PN_stdfloat NodePath::
01265 get_sg() const {
01266   return get_color_scale()[1];
01267 }
01268 
01269 ////////////////////////////////////////////////////////////////////
01270 //     Function: NodePath::get_sb
01271 //       Access: Published
01272 //  Description: Gets the blue scale component of the transform
01273 ////////////////////////////////////////////////////////////////////
01274 INLINE PN_stdfloat NodePath::
01275 get_sb() const {
01276   return get_color_scale()[2];
01277 }
01278 
01279 ////////////////////////////////////////////////////////////////////
01280 //     Function: NodePath::get_sa
01281 //       Access: Published
01282 //  Description: Gets the alpha scale component of the transform
01283 ////////////////////////////////////////////////////////////////////
01284 INLINE PN_stdfloat NodePath::
01285 get_sa() const {
01286   return get_color_scale()[3];
01287 }
01288 
01289 ////////////////////////////////////////////////////////////////////
01290 //     Function: NodePath::set_tex_offset
01291 //       Access: Published
01292 //  Description: Sets a texture matrix on the current node to apply
01293 //               the indicated offset to UV's for the given stage.
01294 //
01295 //               This call is appropriate for ordinary 2-d texture
01296 //               coordinates.
01297 ////////////////////////////////////////////////////////////////////
01298 INLINE void NodePath::
01299 set_tex_offset(TextureStage *stage, PN_stdfloat u, PN_stdfloat v) {
01300   set_tex_offset(stage, LVecBase2(u, v));
01301 }
01302 
01303 ////////////////////////////////////////////////////////////////////
01304 //     Function: NodePath::set_tex_offset
01305 //       Access: Published
01306 //  Description: Sets a texture matrix on the current node to apply
01307 //               the indicated offset to UV's for the given stage.
01308 //
01309 //               This call is appropriate for ordinary 2-d texture
01310 //               coordinates.
01311 ////////////////////////////////////////////////////////////////////
01312 INLINE void NodePath::
01313 set_tex_offset(TextureStage *stage, const LVecBase2 &uv) {
01314   nassertv_always(!is_empty());
01315   set_tex_transform(stage, 
01316                     get_tex_transform(stage)->set_pos2d(uv));
01317 }
01318 
01319 ////////////////////////////////////////////////////////////////////
01320 //     Function: NodePath::set_tex_rotate
01321 //       Access: Published
01322 //  Description: Sets a texture matrix on the current node to apply
01323 //               the indicated rotation, clockwise in degrees, to UV's
01324 //               for the given stage.
01325 //
01326 //               This call is appropriate for ordinary 2-d texture
01327 //               coordinates.
01328 ////////////////////////////////////////////////////////////////////
01329 INLINE void NodePath::
01330 set_tex_rotate(TextureStage *stage, PN_stdfloat r) {
01331   nassertv_always(!is_empty());
01332   set_tex_transform(stage, 
01333                     get_tex_transform(stage)->set_rotate2d(r));
01334 }
01335 
01336 ////////////////////////////////////////////////////////////////////
01337 //     Function: NodePath::set_tex_scale
01338 //       Access: Published
01339 //  Description: Sets a texture matrix on the current node to apply
01340 //               the indicated scale to UVW's for the given stage.
01341 //
01342 //               This call is appropriate for 2-d or 3-d texture
01343 //               coordinates.
01344 ////////////////////////////////////////////////////////////////////
01345 INLINE void NodePath::
01346 set_tex_scale(TextureStage *stage, PN_stdfloat scale) {
01347   nassertv_always(!is_empty());
01348   set_tex_transform(stage, 
01349                     get_tex_transform(stage)->set_scale(scale));
01350 }
01351 
01352 ////////////////////////////////////////////////////////////////////
01353 //     Function: NodePath::set_tex_scale
01354 //       Access: Published
01355 //  Description: Sets a texture matrix on the current node to apply
01356 //               the indicated scale to UV's for the given stage.
01357 //
01358 //               This call is appropriate for ordinary 2-d texture
01359 //               coordinates.
01360 ////////////////////////////////////////////////////////////////////
01361 INLINE void NodePath::
01362 set_tex_scale(TextureStage *stage, PN_stdfloat su, PN_stdfloat sv) {
01363   set_tex_scale(stage, LVecBase2(su, sv));
01364 }
01365 
01366 ////////////////////////////////////////////////////////////////////
01367 //     Function: NodePath::set_tex_scale
01368 //       Access: Published
01369 //  Description: Sets a texture matrix on the current node to apply
01370 //               the indicated scale to UV's for the given stage.
01371 //
01372 //               This call is appropriate for ordinary 2-d texture
01373 //               coordinates.
01374 ////////////////////////////////////////////////////////////////////
01375 INLINE void NodePath::
01376 set_tex_scale(TextureStage *stage, const LVecBase2 &scale) {
01377   nassertv_always(!is_empty());
01378   set_tex_transform(stage, 
01379                     get_tex_transform(stage)->set_scale2d(scale));
01380 }
01381 
01382 ////////////////////////////////////////////////////////////////////
01383 //     Function: NodePath::get_tex_offset
01384 //       Access: Published
01385 //  Description: Returns the offset set for the UV's for the given
01386 //               stage on the current node.
01387 //
01388 //               This call is appropriate for ordinary 2-d texture
01389 //               coordinates.
01390 ////////////////////////////////////////////////////////////////////
01391 INLINE LVecBase2 NodePath::
01392 get_tex_offset(TextureStage *stage) const {
01393   nassertr_always(!is_empty(), LVecBase2::zero());
01394   return get_tex_transform(stage)->get_pos2d();
01395 }
01396 
01397 ////////////////////////////////////////////////////////////////////
01398 //     Function: NodePath::get_tex_rotate
01399 //       Access: Published
01400 //  Description: Returns the rotation set for the UV's for the given
01401 //               stage on the current node.
01402 //
01403 //               This call is appropriate for ordinary 2-d texture
01404 //               coordinates.
01405 ////////////////////////////////////////////////////////////////////
01406 INLINE PN_stdfloat NodePath::
01407 get_tex_rotate(TextureStage *stage) const {
01408   nassertr_always(!is_empty(), 0.0f);
01409   return get_tex_transform(stage)->get_rotate2d();
01410 }
01411 
01412 ////////////////////////////////////////////////////////////////////
01413 //     Function: NodePath::get_tex_scale
01414 //       Access: Published
01415 //  Description: Returns the scale set for the UV's for the given
01416 //               stage on the current node.
01417 //
01418 //               This call is appropriate for ordinary 2-d texture
01419 //               coordinates.
01420 ////////////////////////////////////////////////////////////////////
01421 INLINE LVecBase2 NodePath::
01422 get_tex_scale(TextureStage *stage) const {
01423   nassertr_always(!is_empty(), LVecBase2(1.0f, 1.0f));
01424   return get_tex_transform(stage)->get_scale2d();
01425 }
01426 
01427 ////////////////////////////////////////////////////////////////////
01428 //     Function: NodePath::set_tex_pos
01429 //       Access: Published
01430 //  Description: Sets a texture matrix on the current node to apply
01431 //               the indicated offset to UVW's for the given stage.
01432 //
01433 //               This call is appropriate for 3-d texture coordinates.
01434 ////////////////////////////////////////////////////////////////////
01435 INLINE void NodePath::
01436 set_tex_pos(TextureStage *stage, PN_stdfloat u, PN_stdfloat v, PN_stdfloat w) {
01437   set_tex_pos(stage, LVecBase3(u, v, w));
01438 }
01439 
01440 ////////////////////////////////////////////////////////////////////
01441 //     Function: NodePath::set_tex_pos
01442 //       Access: Published
01443 //  Description: Sets a texture matrix on the current node to apply
01444 //               the indicated offset to UVW's for the given stage.
01445 //
01446 //               This call is appropriate for 3-d texture coordinates.
01447 ////////////////////////////////////////////////////////////////////
01448 INLINE void NodePath::
01449 set_tex_pos(TextureStage *stage, const LVecBase3 &uvw) {
01450   nassertv_always(!is_empty());
01451   set_tex_transform(stage, 
01452                     get_tex_transform(stage)->set_pos(uvw));
01453 }
01454 
01455 ////////////////////////////////////////////////////////////////////
01456 //     Function: NodePath::set_tex_hpr
01457 //       Access: Published
01458 //  Description: Sets a texture matrix on the current node to apply
01459 //               the indicated rotation, as a 3-D HPR, to UVW's
01460 //               for the given stage.
01461 //
01462 //               This call is appropriate for 3-d texture coordinates.
01463 ////////////////////////////////////////////////////////////////////
01464 INLINE void NodePath::
01465 set_tex_hpr(TextureStage *stage, PN_stdfloat h, PN_stdfloat p, PN_stdfloat r) {
01466   set_tex_hpr(stage, LVecBase3(h, p, r));
01467 }
01468 
01469 ////////////////////////////////////////////////////////////////////
01470 //     Function: NodePath::set_tex_hpr
01471 //       Access: Published
01472 //  Description: Sets a texture matrix on the current node to apply
01473 //               the indicated rotation, as a 3-D HPR, to UVW's
01474 //               for the given stage.
01475 //
01476 //               This call is appropriate for 3-d texture coordinates.
01477 ////////////////////////////////////////////////////////////////////
01478 INLINE void NodePath::
01479 set_tex_hpr(TextureStage *stage, const LVecBase3 &hpr) {
01480   nassertv_always(!is_empty());
01481   set_tex_transform(stage, 
01482                     get_tex_transform(stage)->set_hpr(hpr));
01483 }
01484 
01485 ////////////////////////////////////////////////////////////////////
01486 //     Function: NodePath::set_tex_scale
01487 //       Access: Published
01488 //  Description: Sets a texture matrix on the current node to apply
01489 //               the indicated scale to UVW's for the given stage.
01490 //
01491 //               This call is appropriate for 3-d texture coordinates.
01492 ////////////////////////////////////////////////////////////////////
01493 INLINE void NodePath::
01494 set_tex_scale(TextureStage *stage, PN_stdfloat su, PN_stdfloat sv, PN_stdfloat sw) {
01495   set_tex_scale(stage, LVecBase3(su, sv, sw));
01496 }
01497 
01498 ////////////////////////////////////////////////////////////////////
01499 //     Function: NodePath::set_tex_scale
01500 //       Access: Published
01501 //  Description: Sets a texture matrix on the current node to apply
01502 //               the indicated scale to UVW's for the given stage.
01503 //
01504 //               This call is appropriate for 3-d texture coordinates.
01505 ////////////////////////////////////////////////////////////////////
01506 INLINE void NodePath::
01507 set_tex_scale(TextureStage *stage, const LVecBase3 &scale) {
01508   nassertv_always(!is_empty());
01509   set_tex_transform(stage, 
01510                     get_tex_transform(stage)->set_scale(scale));
01511 }
01512 
01513 ////////////////////////////////////////////////////////////////////
01514 //     Function: NodePath::get_tex_pos
01515 //       Access: Published
01516 //  Description: Returns the offset set for the UVW's for the given
01517 //               stage on the current node.
01518 //
01519 //               This call is appropriate for 3-d texture coordinates.
01520 ////////////////////////////////////////////////////////////////////
01521 INLINE LVecBase3 NodePath::
01522 get_tex_pos(TextureStage *stage) const {
01523   nassertr_always(!is_empty(), LVecBase3::zero());
01524   return get_tex_transform(stage)->get_pos();
01525 }
01526 
01527 ////////////////////////////////////////////////////////////////////
01528 //     Function: NodePath::get_tex_hpr
01529 //       Access: Published
01530 //  Description: Returns the 3-D HPR set for the UVW's for the given
01531 //               stage on the current node.
01532 //
01533 //               This call is appropriate for 3-d texture coordinates.
01534 ////////////////////////////////////////////////////////////////////
01535 INLINE LVecBase3 NodePath::
01536 get_tex_hpr(TextureStage *stage) const {
01537   nassertr_always(!is_empty(), LVecBase3::zero());
01538   return get_tex_transform(stage)->get_hpr();
01539 }
01540 
01541 ////////////////////////////////////////////////////////////////////
01542 //     Function: NodePath::get_tex_scale_3d
01543 //       Access: Published
01544 //  Description: Returns the scale set for the UVW's for the given
01545 //               stage on the current node.
01546 //
01547 //               This call is appropriate for 3-d texture coordinates.
01548 ////////////////////////////////////////////////////////////////////
01549 INLINE LVecBase3 NodePath::
01550 get_tex_scale_3d(TextureStage *stage) const {
01551   nassertr_always(!is_empty(), LVecBase3(1.0f, 1.0f, 1.0f));
01552   return get_tex_transform(stage)->get_scale();
01553 }
01554 
01555 ////////////////////////////////////////////////////////////////////
01556 //     Function: NodePath::set_tex_offset
01557 //       Access: Published
01558 //  Description: Sets a texture matrix on the current node to apply
01559 //               the indicated offset to UV's for the given stage.
01560 //
01561 //               This call is appropriate for ordinary 2-d texture
01562 //               coordinates.
01563 ////////////////////////////////////////////////////////////////////
01564 INLINE void NodePath::
01565 set_tex_offset(const NodePath &other, TextureStage *stage, PN_stdfloat u, PN_stdfloat v) {
01566   set_tex_offset(other, stage, LVecBase2(u, v));
01567 }
01568 
01569 ////////////////////////////////////////////////////////////////////
01570 //     Function: NodePath::set_tex_offset
01571 //       Access: Published
01572 //  Description: Sets a texture matrix on the current node to apply
01573 //               the indicated offset to UV's for the given stage.
01574 //
01575 //               This call is appropriate for ordinary 2-d texture
01576 //               coordinates.
01577 ////////////////////////////////////////////////////////////////////
01578 INLINE void NodePath::
01579 set_tex_offset(const NodePath &other, TextureStage *stage, const LVecBase2 &uv) {
01580   nassertv_always(!is_empty());
01581   set_tex_transform(other, stage, 
01582                     get_tex_transform(other, stage)->set_pos2d(uv));
01583 }
01584 
01585 ////////////////////////////////////////////////////////////////////
01586 //     Function: NodePath::set_tex_rotate
01587 //       Access: Published
01588 //  Description: Sets a texture matrix on the current node to apply
01589 //               the indicated rotation, clockwise in degrees, to UV's
01590 //               for the given stage.
01591 //
01592 //               This call is appropriate for ordinary 2-d texture
01593 //               coordinates.
01594 ////////////////////////////////////////////////////////////////////
01595 INLINE void NodePath::
01596 set_tex_rotate(const NodePath &other, TextureStage *stage, PN_stdfloat r) {
01597   nassertv_always(!is_empty());
01598   set_tex_transform(other, stage, 
01599                     get_tex_transform(other, stage)->set_rotate2d(r));
01600 }
01601 
01602 ////////////////////////////////////////////////////////////////////
01603 //     Function: NodePath::set_tex_scale
01604 //       Access: Published
01605 //  Description: Sets a texture matrix on the current node to apply
01606 //               the indicated scale to UV's for the given stage.
01607 //
01608 //               This call is appropriate for 2-d or 3-d texture
01609 //               coordinates.
01610 ////////////////////////////////////////////////////////////////////
01611 INLINE void NodePath::
01612 set_tex_scale(const NodePath &other, TextureStage *stage, PN_stdfloat scale) {
01613   nassertv_always(!is_empty());
01614   set_tex_transform(other, stage, 
01615                     get_tex_transform(stage)->set_scale(scale));
01616 }
01617 
01618 ////////////////////////////////////////////////////////////////////
01619 //     Function: NodePath::set_tex_scale
01620 //       Access: Published
01621 //  Description: Sets a texture matrix on the current node to apply
01622 //               the indicated scale to UV's for the given stage.
01623 //
01624 //               This call is appropriate for ordinary 2-d texture
01625 //               coordinates.
01626 ////////////////////////////////////////////////////////////////////
01627 INLINE void NodePath::
01628 set_tex_scale(const NodePath &other, TextureStage *stage, PN_stdfloat su, PN_stdfloat sv) {
01629   set_tex_scale(other, stage, LVecBase2(su, sv));
01630 }
01631 
01632 ////////////////////////////////////////////////////////////////////
01633 //     Function: NodePath::set_tex_scale
01634 //       Access: Published
01635 //  Description: Sets a texture matrix on the current node to apply
01636 //               the indicated scale to UV's for the given stage.
01637 //
01638 //               This call is appropriate for ordinary 2-d texture
01639 //               coordinates.
01640 ////////////////////////////////////////////////////////////////////
01641 INLINE void NodePath::
01642 set_tex_scale(const NodePath &other, TextureStage *stage, const LVecBase2 &scale) {
01643   nassertv_always(!is_empty());
01644   set_tex_transform(other, stage, 
01645                     get_tex_transform(stage)->set_scale2d(scale));
01646 }
01647 
01648 ////////////////////////////////////////////////////////////////////
01649 //     Function: NodePath::get_tex_offset
01650 //       Access: Published
01651 //  Description: Returns the offset set for the UV's for the given
01652 //               stage on the current node.
01653 //
01654 //               This call is appropriate for ordinary 2-d texture
01655 //               coordinates.
01656 ////////////////////////////////////////////////////////////////////
01657 INLINE LVecBase2 NodePath::
01658 get_tex_offset(const NodePath &other, TextureStage *stage) const {
01659   nassertr_always(!is_empty(), LVecBase2::zero());
01660   return get_tex_transform(other, stage)->get_pos2d();
01661 }
01662 
01663 ////////////////////////////////////////////////////////////////////
01664 //     Function: NodePath::get_tex_rotate
01665 //       Access: Published
01666 //  Description: Returns the rotation set for the UV's for the given
01667 //               stage on the current node.
01668 //
01669 //               This call is appropriate for ordinary 2-d texture
01670 //               coordinates.
01671 ////////////////////////////////////////////////////////////////////
01672 INLINE PN_stdfloat NodePath::
01673 get_tex_rotate(const NodePath &other, TextureStage *stage) const {
01674   nassertr_always(!is_empty(), 0.0f);
01675   return get_tex_transform(other, stage)->get_rotate2d();
01676 }
01677 
01678 ////////////////////////////////////////////////////////////////////
01679 //     Function: NodePath::get_tex_scale
01680 //       Access: Published
01681 //  Description: Returns the scale set for the UV's for the given
01682 //               stage on the current node.
01683 //
01684 //               This call is appropriate for ordinary 2-d texture
01685 //               coordinates.
01686 ////////////////////////////////////////////////////////////////////
01687 INLINE LVecBase2 NodePath::
01688 get_tex_scale(const NodePath &other, TextureStage *stage) const {
01689   nassertr_always(!is_empty(), LVecBase2(1.0f, 1.0f));
01690   return get_tex_transform(other, stage)->get_scale2d();
01691 }
01692 
01693 ////////////////////////////////////////////////////////////////////
01694 //     Function: NodePath::set_tex_pos
01695 //       Access: Published
01696 //  Description: Sets a texture matrix on the current node to apply
01697 //               the indicated offset to UVW's for the given stage.
01698 //
01699 //               This call is appropriate for 3-d texture coordinates.
01700 ////////////////////////////////////////////////////////////////////
01701 INLINE void NodePath::
01702 set_tex_pos(const NodePath &other, TextureStage *stage, PN_stdfloat u, PN_stdfloat v, PN_stdfloat w) {
01703   set_tex_pos(other, stage, LVecBase3(u, v, w));
01704 }
01705 
01706 ////////////////////////////////////////////////////////////////////
01707 //     Function: NodePath::set_tex_pos
01708 //       Access: Published
01709 //  Description: Sets a texture matrix on the current node to apply
01710 //               the indicated offset to UVW's for the given stage.
01711 //
01712 //               This call is appropriate for 3-d texture coordinates.
01713 ////////////////////////////////////////////////////////////////////
01714 INLINE void NodePath::
01715 set_tex_pos(const NodePath &other, TextureStage *stage, const LVecBase3 &uvw) {
01716   nassertv_always(!is_empty());
01717   set_tex_transform(other, stage, 
01718                     get_tex_transform(stage)->set_pos(uvw));
01719 }
01720 
01721 ////////////////////////////////////////////////////////////////////
01722 //     Function: NodePath::set_tex_hpr
01723 //       Access: Published
01724 //  Description: Sets a texture matrix on the current node to apply
01725 //               the indicated rotation, as a 3-D HPR, to UVW's
01726 //               for the given stage.
01727 //
01728 //               This call is appropriate for 3-d texture coordinates.
01729 ////////////////////////////////////////////////////////////////////
01730 INLINE void NodePath::
01731 set_tex_hpr(const NodePath &other, TextureStage *stage, PN_stdfloat h, PN_stdfloat p, PN_stdfloat r) {
01732   set_tex_hpr(other, stage, LVecBase3(h, p, r));
01733 }
01734 
01735 ////////////////////////////////////////////////////////////////////
01736 //     Function: NodePath::set_tex_hpr
01737 //       Access: Published
01738 //  Description: Sets a texture matrix on the current node to apply
01739 //               the indicated rotation, as a 3-D HPR, to UVW's
01740 //               for the given stage.
01741 //
01742 //               This call is appropriate for 3-d texture coordinates.
01743 ////////////////////////////////////////////////////////////////////
01744 INLINE void NodePath::
01745 set_tex_hpr(const NodePath &other, TextureStage *stage, const LVecBase3 &hpr) {
01746   nassertv_always(!is_empty());
01747   set_tex_transform(other, stage, 
01748                     get_tex_transform(stage)->set_hpr(hpr));
01749 }
01750 
01751 ////////////////////////////////////////////////////////////////////
01752 //     Function: NodePath::set_tex_scale
01753 //       Access: Published
01754 //  Description: Sets a texture matrix on the current node to apply
01755 //               the indicated scale to UVW's for the given stage.
01756 //
01757 //               This call is appropriate for 3-d texture coordinates.
01758 ////////////////////////////////////////////////////////////////////
01759 INLINE void NodePath::
01760 set_tex_scale(const NodePath &other, TextureStage *stage, PN_stdfloat su, PN_stdfloat sv, PN_stdfloat sw) {
01761   set_tex_scale(other, stage, LVecBase3(su, sv, sw));
01762 }
01763 
01764 ////////////////////////////////////////////////////////////////////
01765 //     Function: NodePath::set_tex_scale
01766 //       Access: Published
01767 //  Description: Sets a texture matrix on the current node to apply
01768 //               the indicated scale to UVW's for the given stage.
01769 //
01770 //               This call is appropriate for 3-d texture coordinates.
01771 ////////////////////////////////////////////////////////////////////
01772 INLINE void NodePath::
01773 set_tex_scale(const NodePath &other, TextureStage *stage, const LVecBase3 &scale) {
01774   nassertv_always(!is_empty());
01775   set_tex_transform(other, stage, 
01776                     get_tex_transform(stage)->set_scale(scale));
01777 }
01778 
01779 ////////////////////////////////////////////////////////////////////
01780 //     Function: NodePath::get_tex_pos
01781 //       Access: Published
01782 //  Description: Returns the offset set for the UVW's for the given
01783 //               stage on the current node.
01784 //
01785 //               This call is appropriate for 3-d texture coordinates.
01786 ////////////////////////////////////////////////////////////////////
01787 INLINE LVecBase3 NodePath::
01788 get_tex_pos(const NodePath &other, TextureStage *stage) const {
01789   nassertr_always(!is_empty(), LVecBase3::zero());
01790   return get_tex_transform(stage)->get_pos();
01791 }
01792 
01793 ////////////////////////////////////////////////////////////////////
01794 //     Function: NodePath::get_tex_hpr
01795 //       Access: Published
01796 //  Description: Returns the 3-D HPR set for the UVW's for the given
01797 //               stage on the current node.
01798 //
01799 //               This call is appropriate for 3-d texture coordinates.
01800 ////////////////////////////////////////////////////////////////////
01801 INLINE LVecBase3 NodePath::
01802 get_tex_hpr(const NodePath &other, TextureStage *stage) const {
01803   nassertr_always(!is_empty(), LVecBase3::zero());
01804   return get_tex_transform(stage)->get_hpr();
01805 }
01806 
01807 ////////////////////////////////////////////////////////////////////
01808 //     Function: NodePath::get_tex_scale_3d
01809 //       Access: Published
01810 //  Description: Returns the scale set for the UVW's for the given
01811 //               stage on the current node.
01812 //
01813 //               This call is appropriate for 3-d texture coordinates.
01814 ////////////////////////////////////////////////////////////////////
01815 INLINE LVecBase3 NodePath::
01816 get_tex_scale_3d(const NodePath &other, TextureStage *stage) const {
01817   nassertr_always(!is_empty(), LVecBase3(1.0f, 1.0f, 1.0f));
01818   return get_tex_transform(stage)->get_scale();
01819 }
01820 
01821 ////////////////////////////////////////////////////////////////////
01822 //     Function: NodePath::clear_project_texture
01823 //       Access: Published
01824 //  Description: Undoes the effect of project_texture().
01825 ////////////////////////////////////////////////////////////////////
01826 INLINE void NodePath::
01827 clear_project_texture(TextureStage *stage) {
01828   clear_texture(stage);
01829   clear_tex_gen(stage);
01830   clear_tex_projector(stage);
01831 }
01832 
01833 ////////////////////////////////////////////////////////////////////
01834 //     Function: NodePath::has_texcoord
01835 //       Access: Published
01836 //  Description: Returns true if there are at least some vertices at
01837 //               this node and below that use the named texture
01838 //               coordinate set, false otherwise.  Pass the empty
01839 //               string for the default texture coordinate set.
01840 ////////////////////////////////////////////////////////////////////
01841 INLINE bool NodePath::
01842 has_texcoord(const string &texcoord_name) const {
01843   return has_vertex_column(InternalName::get_texcoord_name(texcoord_name));
01844 }
01845 
01846 ////////////////////////////////////////////////////////////////////
01847 //     Function: NodePath::set_billboard_axis
01848 //       Access: Published
01849 //  Description: Puts a billboard transition on the node such that it
01850 //               will rotate in two dimensions around the up axis.
01851 ////////////////////////////////////////////////////////////////////
01852 INLINE void NodePath::
01853 set_billboard_axis(PN_stdfloat offset) {
01854   set_billboard_axis(NodePath(), offset);
01855 }
01856 
01857 ////////////////////////////////////////////////////////////////////
01858 //     Function: NodePath::set_billboard_point_eye
01859 //       Access: Published
01860 //  Description: Puts a billboard transition on the node such that it
01861 //               will rotate in three dimensions about the origin,
01862 //               keeping its up vector oriented to the top of the
01863 //               camera.
01864 ////////////////////////////////////////////////////////////////////
01865 INLINE void NodePath::
01866 set_billboard_point_eye(PN_stdfloat offset) {
01867   set_billboard_point_eye(NodePath(), offset);
01868 }
01869 
01870 ////////////////////////////////////////////////////////////////////
01871 //     Function: NodePath::set_billboard_point_world
01872 //       Access: Published
01873 //  Description: Puts a billboard transition on the node such that it
01874 //               will rotate in three dimensions about the origin,
01875 //               keeping its up vector oriented to the sky.
01876 ////////////////////////////////////////////////////////////////////
01877 INLINE void NodePath::
01878 set_billboard_point_world(PN_stdfloat offset) {
01879   set_billboard_point_world(NodePath(), offset);
01880 }
01881 
01882 ////////////////////////////////////////////////////////////////////
01883 //     Function: NodePath::adjust_all_priorities
01884 //       Access: Published
01885 //  Description: Adds the indicated adjustment amount (which may be
01886 //               negative) to the priority for all transitions on the
01887 //               referenced node, and for all nodes in the subgraph
01888 //               below.  This can be used to force these nodes not to
01889 //               be overridden by a high-level state change above.  If
01890 //               the priority would drop below zero, it is set to
01891 //               zero.
01892 ////////////////////////////////////////////////////////////////////
01893 INLINE void NodePath::
01894 adjust_all_priorities(int adjustment) {
01895   nassertv_always(!is_empty());
01896   r_adjust_all_priorities(node(), adjustment);
01897 }
01898 
01899 ////////////////////////////////////////////////////////////////////
01900 //     Function: NodePath::show
01901 //       Access: Published
01902 //  Description: Undoes the effect of a previous hide() on this node:
01903 //               makes the referenced node (and the entire subgraph
01904 //               below this node) visible to all cameras.
01905 //
01906 //               This will not reveal the node if a parent node has
01907 //               been hidden.
01908 ////////////////////////////////////////////////////////////////////
01909 INLINE void NodePath::
01910 show() {
01911   nassertv_always(!is_empty());
01912   node()->adjust_draw_mask(DrawMask::all_off(), DrawMask::all_off(), PandaNode::get_overall_bit());
01913 }
01914 
01915 ////////////////////////////////////////////////////////////////////
01916 //     Function: NodePath::show
01917 //       Access: Published
01918 //  Description: Makes the referenced node visible just to the
01919 //               cameras whose camera_mask shares the indicated bits.
01920 //
01921 //               This undoes the effect of a previous hide() call.  It
01922 //               will not reveal the node if a parent node has been
01923 //               hidden.  However, see show_through().
01924 ////////////////////////////////////////////////////////////////////
01925 INLINE void NodePath::
01926 show(DrawMask camera_mask) {
01927   nassertv_always(!is_empty());
01928   camera_mask &= ~PandaNode::get_overall_bit();
01929   node()->adjust_draw_mask(DrawMask::all_off(), DrawMask::all_off(), camera_mask);
01930 }
01931 
01932 ////////////////////////////////////////////////////////////////////
01933 //     Function: NodePath::show_through
01934 //       Access: Published
01935 //  Description: Makes the referenced node visible just to the
01936 //               cameras whose camera_mask shares the indicated bits.
01937 //
01938 //               Unlike show(), this will reveal the node even if a
01939 //               parent node has been hidden, thus "showing through" a
01940 //               parent's hide().
01941 ////////////////////////////////////////////////////////////////////
01942 INLINE void NodePath::
01943 show_through() {
01944   nassertv_always(!is_empty());
01945   node()->adjust_draw_mask(PandaNode::get_overall_bit(), DrawMask::all_off(), DrawMask::all_off());
01946 }
01947 
01948 ////////////////////////////////////////////////////////////////////
01949 //     Function: NodePath::show_through
01950 //       Access: Published
01951 //  Description: Makes the referenced node visible just to the
01952 //               cameras whose camera_mask shares the indicated bits.
01953 //
01954 //               Unlike show(), this will reveal the node even if a
01955 //               parent node has been hidden via the one-parameter
01956 //               hide() method, thus "showing through" a parent's
01957 //               hide().  (However, it will not show through a
01958 //               parent's hide() call if the no-parameter form of
01959 //               hide() was used.)
01960 ////////////////////////////////////////////////////////////////////
01961 INLINE void NodePath::
01962 show_through(DrawMask camera_mask) {
01963   nassertv_always(!is_empty());
01964   camera_mask &= ~PandaNode::get_overall_bit();
01965   node()->adjust_draw_mask(camera_mask, DrawMask::all_off(), DrawMask::all_off());
01966 }
01967 
01968 ////////////////////////////////////////////////////////////////////
01969 //     Function: NodePath::hide
01970 //       Access: Published
01971 //  Description: Makes the referenced node (and the entire subgraph
01972 //               below this node) invisible to all cameras.  It
01973 //               remains part of the scene graph, its bounding volume
01974 //               still contributes to its parent's bounding volume,
01975 //               and it will still be involved in collision tests.
01976 ////////////////////////////////////////////////////////////////////
01977 INLINE void NodePath::
01978 hide() {
01979   nassertv_always(!is_empty());
01980   node()->adjust_draw_mask(DrawMask::all_off(), PandaNode::get_overall_bit(), DrawMask::all_off());
01981 }
01982 
01983 ////////////////////////////////////////////////////////////////////
01984 //     Function: NodePath::hide
01985 //       Access: Published
01986 //  Description: Makes the referenced node invisible just to the
01987 //               cameras whose camera_mask shares the indicated bits.
01988 //
01989 //               This will also hide any nodes below this node in the
01990 //               scene graph, including those nodes for which show()
01991 //               has been called, but it will not hide descendent
01992 //               nodes for which show_through() has been called.
01993 ////////////////////////////////////////////////////////////////////
01994 INLINE void NodePath::
01995 hide(DrawMask camera_mask) {
01996   nassertv_always(!is_empty());
01997   camera_mask &= ~PandaNode::get_overall_bit();
01998   node()->adjust_draw_mask(DrawMask::all_off(), camera_mask, DrawMask::all_off());
01999 }
02000 
02001 ////////////////////////////////////////////////////////////////////
02002 //     Function: NodePath::is_hidden
02003 //       Access: Published
02004 //  Description: Returns true if the referenced node is hidden from
02005 //               the indicated camera(s) either directly, or because
02006 //               some ancestor is hidden.
02007 ////////////////////////////////////////////////////////////////////
02008 INLINE bool NodePath::
02009 is_hidden(DrawMask camera_mask) const {
02010   return !get_hidden_ancestor(camera_mask).is_empty();
02011 }
02012 
02013 ////////////////////////////////////////////////////////////////////
02014 //     Function: NodePath::is_stashed
02015 //       Access: Published
02016 //  Description: Returns true if the referenced node is stashed either
02017 //               directly, or because some ancestor is stashed.
02018 ////////////////////////////////////////////////////////////////////
02019 INLINE bool NodePath::
02020 is_stashed() const {
02021   return !get_stashed_ancestor().is_empty();
02022 }
02023 
02024 ////////////////////////////////////////////////////////////////////
02025 //     Function: NodePath::get_collide_mask
02026 //       Access: Published
02027 //  Description: Returns the union of all of the into_collide_masks
02028 //               for nodes at this level and below.  This is the same
02029 //               thing as node()->get_net_collide_mask().
02030 //
02031 //               If you want to return what the into_collide_mask of
02032 //               this node itself is, without regard to its children,
02033 //               use node()->get_into_collide_mask().
02034 ////////////////////////////////////////////////////////////////////
02035 INLINE CollideMask NodePath::
02036 get_collide_mask() const {
02037   nassertr_always(!is_empty(), CollideMask::all_off());
02038   return node()->get_net_collide_mask();
02039 }
02040 
02041 ////////////////////////////////////////////////////////////////////
02042 //     Function: NodePath::set_collide_mask
02043 //       Access: Published
02044 //  Description: Recursively applies the indicated CollideMask to the
02045 //               into_collide_masks for all nodes at this level and
02046 //               below.  If node_type is not TypeHandle::none(), then
02047 //               only nodes matching (or inheriting from) the
02048 //               indicated PandaNode subclass are modified.
02049 //
02050 //               The default is to change all bits, but if
02051 //               bits_to_change is not all bits on, then only the bits
02052 //               that are set in bits_to_change are modified, allowing
02053 //               this call to change only a subset of the bits in the
02054 //               subgraph.
02055 ////////////////////////////////////////////////////////////////////
02056 INLINE void NodePath::
02057 set_collide_mask(CollideMask new_mask, CollideMask bits_to_change,
02058                  TypeHandle node_type) {
02059   nassertv_always(!is_empty());
02060   if (node_type == TypeHandle::none()) {
02061     node_type = PandaNode::get_class_type();
02062   }
02063 
02064   r_set_collide_mask(node(), ~bits_to_change, new_mask & bits_to_change,
02065                      node_type);
02066 }
02067 
02068 ////////////////////////////////////////////////////////////////////
02069 //     Function: NodePath::operator ==
02070 //       Access: Published
02071 //  Description: Returns true if the two paths are equivalent; that
02072 //               is, if they contain the same list of nodes in the same
02073 //               order.
02074 ////////////////////////////////////////////////////////////////////
02075 INLINE bool NodePath::
02076 operator == (const NodePath &other) const {
02077   return _head == other._head;
02078 }
02079 
02080 ////////////////////////////////////////////////////////////////////
02081 //     Function: NodePath::operator !=
02082 //       Access: Published
02083 //  Description: Returns true if the two paths are not equivalent.
02084 ////////////////////////////////////////////////////////////////////
02085 INLINE bool NodePath::
02086 operator != (const NodePath &other) const {
02087   return _head != other._head;
02088 }
02089 
02090 ////////////////////////////////////////////////////////////////////
02091 //     Function: NodePath::operator <
02092 //       Access: Published
02093 //  Description: Returns true if this NodePath sorts before the other
02094 //               one, false otherwise.  The sorting order of two
02095 //               nonequivalent NodePaths is consistent but undefined,
02096 //               and is useful only for storing NodePaths in a sorted
02097 //               container like an STL set.
02098 ////////////////////////////////////////////////////////////////////
02099 INLINE bool NodePath::
02100 operator < (const NodePath &other) const {
02101   return _head < other._head;
02102 }
02103 
02104 ////////////////////////////////////////////////////////////////////
02105 //     Function: NodePath::compare_to
02106 //       Access: Published
02107 //  Description: Returns a number less than zero if this NodePath
02108 //               sorts before the other one, greater than zero if it
02109 //               sorts after, or zero if they are equivalent.
02110 //
02111 //               Two NodePaths are considered equivalent if they
02112 //               consist of exactly the same list of nodes in the same
02113 //               order.  Otherwise, they are different; different
02114 //               NodePaths will be ranked in a consistent but
02115 //               undefined ordering; the ordering is useful only for
02116 //               placing the NodePaths in a sorted container like an
02117 //               STL set.
02118 ////////////////////////////////////////////////////////////////////
02119 INLINE int NodePath::
02120 compare_to(const NodePath &other) const {
02121   // Nowadays, the NodePathComponents at the head are pointerwise
02122   // equivalent if and only if the NodePaths are equivalent.  So we
02123   // only have to compare pointers.
02124   if (_head != other._head) {
02125     return _head < other._head ? -1 : 1;
02126   }
02127   return 0;
02128 }
02129 
02130 ////////////////////////////////////////////////////////////////////
02131 //     Function: NodePath::clear_model_nodes
02132 //       Access: Published
02133 //  Description: Recursively walks through the scene graph at this
02134 //               level and below, looking for ModelNodes, and calls
02135 //               model_node->set_preserve_transform(PT_drop_node) on
02136 //               each one.  This allows a subsequent call to
02137 //               flatten_strong() to eliminate all of the ModelNodes.
02138 //
02139 //               Returns the number of ModelNodes found.
02140 ////////////////////////////////////////////////////////////////////
02141 INLINE int NodePath::
02142 clear_model_nodes() {
02143   nassertr_always(!is_empty(), 0);
02144   return r_clear_model_nodes(node());
02145 }
02146 
02147 ////////////////////////////////////////////////////////////////////
02148 //     Function: NodePath::set_tag
02149 //       Access: Published
02150 //  Description: Associates a user-defined value with a user-defined
02151 //               key which is stored on the node.  This value has no
02152 //               meaning to Panda; but it is stored indefinitely on
02153 //               the node until it is requested again.
02154 //
02155 //               Each unique key stores a different string value.
02156 //               There is no effective limit on the number of
02157 //               different keys that may be stored or on the length of
02158 //               any one key's value.
02159 ////////////////////////////////////////////////////////////////////
02160 INLINE void NodePath::
02161 set_tag(const string &key, const string &value) {
02162   nassertv_always(!is_empty());
02163   node()->set_tag(key, value);
02164 }
02165 
02166 ////////////////////////////////////////////////////////////////////
02167 //     Function: NodePath::get_tag
02168 //       Access: Published
02169 //  Description: Retrieves the user-defined value that was previously
02170 //               set on this node for the particular key, if any.  If
02171 //               no value has been previously set, returns the empty
02172 //               string.  See also get_net_tag().
02173 ////////////////////////////////////////////////////////////////////
02174 INLINE string NodePath::
02175 get_tag(const string &key) const {
02176   // An empty NodePath quietly returns no tags.  This makes
02177   // get_net_tag() easier to implement.
02178   if (is_empty()) {
02179     return string();
02180   }
02181   return node()->get_tag(key);
02182 }
02183 
02184 ////////////////////////////////////////////////////////////////////
02185 //     Function: NodePath::get_tag_keys
02186 //       Access: Published
02187 //  Description: Fills the given vector up with the
02188 //               list of tags on this PandaNode.
02189 //
02190 //               It is the user's responsibility to ensure that the
02191 //               keys vector is empty before making this call;
02192 //               otherwise, the new files will be appended to it.
02193 ////////////////////////////////////////////////////////////////////
02194 INLINE void NodePath::
02195 get_tag_keys(vector_string &keys) const {
02196   nassertv_always(!is_empty());
02197   node()->get_tag_keys(keys);
02198 }
02199 
02200 ////////////////////////////////////////////////////////////////////
02201 //     Function: NodePath::has_tag
02202 //       Access: Published
02203 //  Description: Returns true if a value has been defined on this node
02204 //               for the particular key (even if that value is the
02205 //               empty string), or false if no value has been set.
02206 //               See also has_net_tag().
02207 ////////////////////////////////////////////////////////////////////
02208 INLINE bool NodePath::
02209 has_tag(const string &key) const {
02210   // An empty NodePath quietly has no tags.  This makes has_net_tag()
02211   // easier to implement.
02212   if (is_empty()) {
02213     return false;
02214   }
02215   return node()->has_tag(key);
02216 }
02217 
02218 ////////////////////////////////////////////////////////////////////
02219 //     Function: NodePath::clear_tag
02220 //       Access: Published
02221 //  Description: Removes the value defined for this key on this
02222 //               particular node.  After a call to clear_tag(),
02223 //               has_tag() will return false for the indicated key.
02224 ////////////////////////////////////////////////////////////////////
02225 INLINE void NodePath::
02226 clear_tag(const string &key) {
02227   nassertv_always(!is_empty());
02228   node()->clear_tag(key);
02229 }
02230 
02231 ////////////////////////////////////////////////////////////////////
02232 //     Function: NodePath::get_net_tag
02233 //       Access: Published
02234 //  Description: Returns the tag value that has been defined on this
02235 //               node, or the nearest ancestor node, for the indicated
02236 //               key.  If no value has been defined for the indicated
02237 //               key on any ancestor node, returns the empty string.
02238 //               See also get_tag().
02239 ////////////////////////////////////////////////////////////////////
02240 INLINE string NodePath::
02241 get_net_tag(const string &key) const {
02242   return find_net_tag(key).get_tag(key);
02243 }
02244 
02245 ////////////////////////////////////////////////////////////////////
02246 //     Function: NodePath::has_net_tag
02247 //       Access: Published
02248 //  Description: Returns true if the indicated tag value has been
02249 //               defined on this node or on any ancestor node, or
02250 //               false otherwise.  See also has_tag().
02251 ////////////////////////////////////////////////////////////////////
02252 INLINE bool NodePath::
02253 has_net_tag(const string &key) const {
02254   return !find_net_tag(key).is_empty();
02255 }
02256 
02257 ////////////////////////////////////////////////////////////////////
02258 //     Function: NodePath::list_tags
02259 //       Access: Published
02260 //  Description: Lists the tags to the nout stream, one per line.  See
02261 //               PandaNode::list_tags() for a variant that allows you
02262 //               to specify the output stream.
02263 ////////////////////////////////////////////////////////////////////
02264 INLINE void NodePath::
02265 list_tags() const {
02266   nassertv_always(!is_empty());
02267   node()->list_tags(nout);
02268   nout << "\n";
02269 }
02270 
02271 ////////////////////////////////////////////////////////////////////
02272 //     Function: NodePath::set_name
02273 //       Access: Published
02274 //  Description: Changes the name of the referenced node.
02275 ////////////////////////////////////////////////////////////////////
02276 INLINE void NodePath::
02277 set_name(const string &name) {
02278   nassertv_always(!is_empty());
02279   node()->set_name(name);
02280 }
02281 
02282 ////////////////////////////////////////////////////////////////////
02283 //     Function: NodePath::get_name
02284 //       Access: Published
02285 //  Description: Returns the name of the referenced node.
02286 ////////////////////////////////////////////////////////////////////
02287 INLINE string NodePath::
02288 get_name() const {
02289   nassertr_always(!is_empty(), string());
02290   return node()->get_name();
02291 }
02292 
02293 ////////////////////////////////////////////////////////////////////
02294 //     Function: NodePath::encode_to_bam_stream
02295 //       Access: Published
02296 //  Description: Converts the NodePath object into a single
02297 //               stream of data using a BamWriter, and returns that
02298 //               data as a string string.  Returns empty string on
02299 //               failure.  This is similar to write_bam_stream().
02300 //
02301 //               This method is used by __reduce__ to handle streaming
02302 //               of NodePaths to a pickle file.
02303 ////////////////////////////////////////////////////////////////////
02304 INLINE string NodePath::
02305 encode_to_bam_stream() const {
02306   string data;
02307   if (!encode_to_bam_stream(data)) {
02308     return string();
02309   }
02310   return data;
02311 }
02312 
02313 
02314 INLINE ostream &operator << (ostream &out, const NodePath &node_path) {
02315   node_path.output(out);
02316   return out;
02317 }
02318