// Filename: nodeRelation.I // Created by: drose (30Sep99) // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved // // All use of this software is subject to the terms of the Panda 3d // Software license. You should have received a copy of this license // along with this source code; you will also find a current copy of // the license at http://www.panda3d.org/license.txt . // // To contact the maintainers of this program write to // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// // Function: remove_arc // Description: Removes the arc from the graph, which incidentally // will also delete the arc unless there are some // additional outstanding pointers to it. //////////////////////////////////////////////////////////////////// EXPCL_PANDA INLINE_GRAPH void remove_arc(NodeRelation *arc) { PT(TypedWritableReferenceCount) hold_ptr = arc->detach(); arc->_parent = NULL; arc->_child = NULL; } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::output_transitions // Access: Public // Description: //////////////////////////////////////////////////////////////////// INLINE_GRAPH void NodeRelation:: output_transitions(ostream &out) const { out << _transitions; } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::write_transitions // Access: Public // Description: //////////////////////////////////////////////////////////////////// INLINE_GRAPH void NodeRelation:: write_transitions(ostream &out, int indent_level) const { _transitions.write(out, indent_level); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::get_parent // Access: Public // Description: Returns the node above the arc in the scene graph. //////////////////////////////////////////////////////////////////// INLINE_GRAPH Node *NodeRelation:: get_parent() const { return _parent; } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::get_child // Access: Public // Description: Returns the node below the arc in the scene graph. //////////////////////////////////////////////////////////////////// INLINE_GRAPH Node *NodeRelation:: get_child() const { return _child; } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::get_sort // Access: Public // Description: Returns the sorting index of the arc. This affects // its apparent position among its list of siblings. //////////////////////////////////////////////////////////////////// INLINE_GRAPH int NodeRelation:: get_sort() const { return _sort; } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::get_graph_type // Access: Public // Description: Returns the type of graph this arc represents. This // is normally the same value as get_type(), i.e. the // class type of the arc, but it may be set to any type. // A node may simultaneously have many arcs of different // types. //////////////////////////////////////////////////////////////////// INLINE_GRAPH TypeHandle NodeRelation:: get_graph_type() const { return _graph_type; } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::is_attached // Access: Public // Description: Returns true if this arc is attached to the scene // graph, false otherwise. Normally, an arc should // always be attached; generally you will only see an // unattached arc if the arc (or some parent of the arc) // has been disconnected from all nodes via // remove_arc(). //////////////////////////////////////////////////////////////////// INLINE_GRAPH bool NodeRelation:: is_attached() const { return _attached; } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::change_parent // Access: Public // Description: Changes the parent of the arc to a different node. //////////////////////////////////////////////////////////////////// INLINE_GRAPH void NodeRelation:: change_parent(Node *parent) { PT(TypedWritableReferenceCount) hold_ptr = detach(); _parent = parent; attach(); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::change_parent // Access: Public // Description: Changes the parent of the arc to a different node, // simultaneously changing the sort index. //////////////////////////////////////////////////////////////////// INLINE_GRAPH void NodeRelation:: change_parent(Node *parent, int sort) { PT(TypedWritableReferenceCount) hold_ptr = detach(); _parent = parent; _sort = sort; attach(); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::change_child // Access: Public // Description: Changes the child of the arc to a different node. //////////////////////////////////////////////////////////////////// INLINE_GRAPH void NodeRelation:: change_child(Node *child) { PT(TypedWritableReferenceCount) hold_ptr = detach(); _child = child; attach(); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::change_parent_and_child // Access: Public // Description: Simultaneously moves both the parent and child of the // arc to different nodes. //////////////////////////////////////////////////////////////////// INLINE_GRAPH void NodeRelation:: change_parent_and_child(Node *parent, Node *child) { PT(TypedWritableReferenceCount) hold_ptr = detach(); _parent = parent; _child = child; attach(); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::set_sort // Access: Public // Description: Changes the sorting index of the arc. This affects // its apparent position among its list of siblings. //////////////////////////////////////////////////////////////////// INLINE_GRAPH void NodeRelation:: set_sort(int sort) { PT(TypedWritableReferenceCount) hold_ptr = detach(); _sort = sort; attach(); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::set_graph_type // Access: Public // Description: Changes the graph type of the arc. This moves the // arc into a totally different graph; it may now be // detected only by a special traversal. //////////////////////////////////////////////////////////////////// INLINE_GRAPH void NodeRelation:: set_graph_type(TypeHandle graph_type) { PT(TypedWritableReferenceCount) hold_ptr = detach(); _graph_type = graph_type; attach(); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::set_transition // Access: Public // Description: This flavor of set_transition() accepts a pointer to // a NodeTransition only. It infers the type of the // NodeTransition from the pointer. However, it is not // valid to pass a NULL pointer to this flavor of // set_transition; if the pointer might be NULL, use the // above flavor instead (or just call clear_transition). // // The return value is a pointer to the *previous* // transition in the set, if any, or NULL if there was // none. //////////////////////////////////////////////////////////////////// INLINE_GRAPH PT(NodeTransition) NodeRelation:: set_transition(NodeTransition *trans) { nassertr(trans != (NodeTransition *)NULL, NULL); nassertr(trans->get_handle() != TypeHandle::none(), NULL); return set_transition(trans->get_handle(), trans); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::set_transition // Access: Public // Description: This is a convenience flavor. It automatically // applies the indicated priority to the given // transition before setting the transition. Generally, // this will be used for creating override transitions // on-the-fly. //////////////////////////////////////////////////////////////////// INLINE_GRAPH PT(NodeTransition) NodeRelation:: set_transition(NodeTransition *trans, int priority) { nassertr(trans != (NodeTransition *)NULL, NULL); nassertr(trans->get_handle() != TypeHandle::none(), NULL); trans->set_priority(priority); return set_transition(trans->get_handle(), trans); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::has_transition // Access: Public // Description: Returns true if a transition associated with the // indicated handle has been stored on the arc (even if // it is the identity transition), or false otherwise. //////////////////////////////////////////////////////////////////// INLINE_GRAPH bool NodeRelation:: has_transition(TypeHandle handle) const { return _transitions.has_transition(handle); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::has_any_transition // Access: Public // Description: Returns true if a any transition has been stored on // the arc (even if it is the identity transition), or // false otherwise. //////////////////////////////////////////////////////////////////// INLINE_GRAPH bool NodeRelation:: has_any_transition() const { return !_transitions.is_empty(); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::get_transition // Access: Public // Description: Returns the transition associated with the indicated // handle, or NULL if no such transition has been stored // on the arc. //////////////////////////////////////////////////////////////////// INLINE_GRAPH NodeTransition *NodeRelation:: get_transition(TypeHandle handle) const { return _transitions.get_transition(handle); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::compare_transitions_to // Access: Public // Description: Returns a negative number if the transitions on the // other arc sort before those on this arc, positive if // they sort after, or zero if the sets of transitions // are equivalent. //////////////////////////////////////////////////////////////////// INLINE_GRAPH int NodeRelation:: compare_transitions_to(const NodeRelation *arc) const { return _transitions.compare_to(arc->_transitions); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::get_last_update // Access: Public // Description: Returns the sequence number associated with the last // time this arc was changed, for instance to change its // state or to reparent it. The only sensible thing you // can do with this is store it and note whether it // increases. //////////////////////////////////////////////////////////////////// INLINE_GRAPH UpdateSeq NodeRelation:: get_last_update() const { return _last_update; } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::clear_wrt_cache // Access: Public // Description: Blows away the wrt cache information on this arc. // This forces the wrt to be recomputed next time it is // asked for. //////////////////////////////////////////////////////////////////// INLINE_GRAPH void NodeRelation:: clear_wrt_cache() { _net_transitions.clear(); _top_subtree = (Node *)NULL; _all_verified = UpdateSeq::initial(); _last_update = ++last_graph_update(_graph_type); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::create_typed_arc // Access: Public, Static // Description: Creates a new arc of the scene graph of the indicated // type, and immediately attaches it. Returns NULL if // the type is unknown. //////////////////////////////////////////////////////////////////// INLINE_GRAPH NodeRelation *NodeRelation:: create_typed_arc(TypeHandle type, Node *parent, Node *child, int sort) { NodeRelation *arc = get_factory().make_instance(type); if (arc != (NodeRelation *)NULL) { arc->_parent = parent; arc->_child = child; arc->_sort = sort; arc->attach(); } return arc; } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::register_with_factory // Access: Public, Static // Description: Registers the type NodeRelation with the factory. // This is only intended to be called at initialization // time; don't call it directly. //////////////////////////////////////////////////////////////////// INLINE_GRAPH void NodeRelation:: register_with_factory() { get_factory().register_factory(get_class_type(), make_arc); } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::get_factory // Access: Protected, Static // Description: Returns a reference to the NodeRelation factory. // Creates one if this is the first time this function // has been called. This is necessary to guarantee // ordering at static init time. //////////////////////////////////////////////////////////////////// INLINE_GRAPH Factory &NodeRelation:: get_factory() { if (_factory == (Factory *)NULL) { _factory = new Factory; } return *_factory; } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::get_class_type // Access: Public, Static // Description: Returns the TypeHandle associated with this type. //////////////////////////////////////////////////////////////////// INLINE_GRAPH TypeHandle NodeRelation:: get_class_type() { return _type_handle; } //////////////////////////////////////////////////////////////////// // Function: NodeRelation::get_stashed_type // Access: Public, Static // Description: Returns a special TypeHandle that, by convention, // arcs that wish to remove themselves from normal // consideration during any traversal (including // rendering and collision traversals), as well as // removing themselves from the bounding volumes of // their parents, should set their graph_type to. //////////////////////////////////////////////////////////////////// INLINE_GRAPH TypeHandle NodeRelation:: get_stashed_type() { return _stashed_type_handle; } EXPCL_PANDA INLINE_GRAPH ostream & operator << (ostream &out, const NodeRelation &arc) { arc.output(out); return out; }