mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
nodePath refinements
This commit is contained in:
parent
03ae7a34a7
commit
5954465fbc
@ -20,11 +20,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::Default Constructor
|
||||
// Access: Published
|
||||
// Description: This constructs an empty qpNodePath with no nodes. It
|
||||
// cannot be extended, since you cannot add nodes without
|
||||
// first specifying the top node. Use the constructor
|
||||
// that receives a node if you ever want to do anything
|
||||
// with this path.
|
||||
// Description: This constructs an empty qpNodePath with no nodes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpNodePath::
|
||||
qpNodePath() :
|
||||
@ -35,9 +31,9 @@ qpNodePath() :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::Constructor
|
||||
// Access: Published
|
||||
// Description: This constructs an empty qpNodePath with a single
|
||||
// node. An ordinary PandaNode is created with the
|
||||
// indicated name.
|
||||
// Description: This constructs a new qpNodePath with a single
|
||||
// node. An ordinary, unattached PandaNode is created
|
||||
// with the indicated name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpNodePath::
|
||||
qpNodePath(const string &top_node_name) :
|
||||
@ -52,35 +48,53 @@ qpNodePath(const string &top_node_name) :
|
||||
// Access: Published
|
||||
// Description: This constructs a NodePath for the indicated node.
|
||||
// If the node does not have any parents, this creates a
|
||||
// single NodePath; otherwise, it automatically finds
|
||||
// singleton NodePath; otherwise, it automatically finds
|
||||
// the path from the node to the root. If the node has
|
||||
// multiple paths to the root, one path is chosen
|
||||
// arbitrarily and a warning message is printed.
|
||||
// arbitrarily and a warning message is printed (but see
|
||||
// also NodePath::any_path(), below).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpNodePath::
|
||||
qpNodePath(PandaNode *top_node) :
|
||||
qpNodePath(PandaNode *node) :
|
||||
_error_type(ET_ok)
|
||||
{
|
||||
if (top_node != (PandaNode *)NULL) {
|
||||
_head = top_node->get_generic_component(false);
|
||||
if (node != (PandaNode *)NULL) {
|
||||
_head = node->get_generic_component(false);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::any_path named constructor
|
||||
// Access: Published, Static
|
||||
// Description: Returns a new NodePath that represents any arbitrary
|
||||
// path from the root to the indicated node. This is
|
||||
// the same thing that would be returned by
|
||||
// NodePath(node), except that no warning is issued if
|
||||
// the path is ambiguous.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpNodePath qpNodePath::
|
||||
any_path(PandaNode *node) {
|
||||
qpNodePath result;
|
||||
if (node != (PandaNode *)NULL) {
|
||||
result._head = node->get_generic_component(true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::Constructor
|
||||
// Access: Published
|
||||
// Description: Constructs a NodePath with the indicated parent
|
||||
// NodePath and child node; the child node must be a
|
||||
|
||||
// stashed or unstashed child of the parent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpNodePath::
|
||||
qpNodePath(const qpNodePath &parent, PandaNode *child) :
|
||||
qpNodePath(const qpNodePath &parent, PandaNode *child_node) :
|
||||
_error_type(ET_fail)
|
||||
{
|
||||
nassertv(!parent.is_empty());
|
||||
nassertv(child != (PandaNode *)NULL);
|
||||
_head = PandaNode::get_component(parent._head, child);
|
||||
nassertv(child_node != (PandaNode *)NULL);
|
||||
_head = PandaNode::get_component(parent._head, child_node);
|
||||
nassertv(_head != (qpNodePathComponent *)NULL);
|
||||
|
||||
if (_head != (qpNodePathComponent *)NULL) {
|
||||
@ -155,7 +169,7 @@ fail() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::set_max_search_depth
|
||||
// Access: Published, Static
|
||||
// Description: Certain operations, such as extend_down_to() or
|
||||
// Description: Certain operations, such as find() or
|
||||
// find_all_matches(), require a traversal of the scene
|
||||
// graph to search for the target node or nodes. This
|
||||
// traversal does not attempt to detect cycles, so an
|
||||
@ -252,6 +266,13 @@ node() const {
|
||||
// given key will never be reused for a different
|
||||
// instance (unless the app has been running long enough
|
||||
// that we overflow the integer key value).
|
||||
//
|
||||
// There are a few special case circumstances that can
|
||||
// cause the key for a particular instance to be
|
||||
// changed. These all involve different instances being
|
||||
// collapsed into the same instance by some scene graph
|
||||
// operation (for instance, detaching a node below an
|
||||
// instanced node).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpNodePath::
|
||||
get_key() const {
|
||||
@ -350,28 +371,6 @@ ls(ostream &out, int indent_level) const {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::ls_transitions
|
||||
// Access: Published
|
||||
// Description: Lists the hierarchy at and below the referenced node,
|
||||
// along with the state transitions at each level.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpNodePath::
|
||||
ls_transitions() const {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::ls_transforms
|
||||
// Access: Published
|
||||
// Description: Lists the hierarchy at and below the referenced node,
|
||||
// along with the transforms at each level.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpNodePath::
|
||||
ls_transforms() const {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::get_state
|
||||
// Access: Published
|
||||
@ -1078,7 +1077,7 @@ compare_to(const qpNodePath &other) const {
|
||||
other.uncollapse_head();
|
||||
|
||||
// Nowadays, the NodePathComponents at the head are pointerwise
|
||||
// equivalent if and only iff the NodePaths are equivalent. So we
|
||||
// equivalent if and only if the NodePaths are equivalent. So we
|
||||
// only have to compare pointers.
|
||||
return _head - other._head;
|
||||
}
|
||||
|
@ -357,21 +357,42 @@ attach_new_node(PandaNode *node, int sort) const {
|
||||
void qpNodePath::
|
||||
remove_node() {
|
||||
nassertv(_error_type != ET_not_found);
|
||||
if (is_empty() || is_singleton()) {
|
||||
// If we have no parents, remove_node() is just a do-nothing
|
||||
// operation; if we have no nodes, maybe we were already removed.
|
||||
// In either case, quietly do nothing except to ensure the
|
||||
// qpNodePath is clear.
|
||||
(*this) = qpNodePath::removed();
|
||||
return;
|
||||
|
||||
// If we have no parents, remove_node() is just a do-nothing
|
||||
// operation; if we have no nodes, maybe we were already removed.
|
||||
// In either case, quietly do nothing except to ensure the
|
||||
// qpNodePath is clear.
|
||||
if (!is_empty() && !is_singleton()) {
|
||||
uncollapse_head();
|
||||
PandaNode::detach(_head);
|
||||
}
|
||||
|
||||
uncollapse_head();
|
||||
PandaNode::detach(_head);
|
||||
|
||||
(*this) = qpNodePath::removed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::detach_node
|
||||
// Access: Published
|
||||
// Description: Disconnects the referenced node from its parent, but
|
||||
// does not immediately delete it. The NodePath retains
|
||||
// a pointer to the node. If there are no other
|
||||
// instances to the node, this becomes a singleton
|
||||
// NodePath; otherwise, this NodePath becomes the same
|
||||
// as another arbitrary instance.
|
||||
//
|
||||
// If the NodePath later goes out of scope or is
|
||||
// reassigned to something else, this will have the same
|
||||
// effect as remove_node().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePath::
|
||||
detach_node() {
|
||||
nassertv(_error_type != ET_not_found);
|
||||
if (!is_empty() && !is_singleton()) {
|
||||
uncollapse_head();
|
||||
PandaNode::detach(_head);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePath::output
|
||||
// Access: Published
|
||||
|
@ -149,9 +149,11 @@ PUBLISHED:
|
||||
|
||||
INLINE qpNodePath();
|
||||
INLINE qpNodePath(const string &top_node_name);
|
||||
INLINE qpNodePath(PandaNode *top_node);
|
||||
INLINE qpNodePath(const qpNodePath ©);
|
||||
INLINE qpNodePath(PandaNode *node);
|
||||
INLINE static qpNodePath any_path(PandaNode *node);
|
||||
INLINE qpNodePath(const qpNodePath &parent, PandaNode *child_node);
|
||||
|
||||
INLINE qpNodePath(const qpNodePath ©);
|
||||
INLINE void operator = (const qpNodePath ©);
|
||||
|
||||
INLINE static qpNodePath not_found();
|
||||
@ -202,6 +204,7 @@ PUBLISHED:
|
||||
qpNodePath attach_new_node(PandaNode *node, int sort = 0) const;
|
||||
INLINE qpNodePath attach_new_node(const string &name, int sort = 0) const;
|
||||
void remove_node();
|
||||
void detach_node();
|
||||
|
||||
// Handy ways to look at what's there, and other miscellaneous
|
||||
// operations.
|
||||
@ -210,8 +213,6 @@ PUBLISHED:
|
||||
|
||||
INLINE void ls() const;
|
||||
INLINE void ls(ostream &out, int indent_level = 0) const;
|
||||
INLINE void ls_transitions() const;
|
||||
INLINE void ls_transforms() const;
|
||||
|
||||
|
||||
// Aggregate transform and state information.
|
||||
|
@ -135,24 +135,3 @@ get_collapsed() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathComponent::collapse_with
|
||||
// Access: Private
|
||||
// Description: Indicates that this component pointer is no longer
|
||||
// valid, and that the indicated component should be
|
||||
// used instead. This is done whenever two
|
||||
// qpNodePathComponents have been collapsed together due
|
||||
// to an instance being removed higher up in the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpNodePathComponent::
|
||||
collapse_with(qpNodePathComponent *next) {
|
||||
nassertv(!is_collapsed());
|
||||
nassertv(next != (qpNodePathComponent *)NULL);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_next = next;
|
||||
cdata->_length = 0;
|
||||
|
||||
// We indicate a component has been collapsed by setting its length
|
||||
// to zero.
|
||||
}
|
||||
|
@ -193,3 +193,30 @@ set_top_node() {
|
||||
cdata->_next = (qpNodePathComponent *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathComponent::collapse_with
|
||||
// Access: Private
|
||||
// Description: Indicates that this component pointer is no longer
|
||||
// valid, and that the indicated component should be
|
||||
// used instead. This is done whenever two
|
||||
// qpNodePathComponents have been collapsed together due
|
||||
// to an instance being removed higher up in the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathComponent::
|
||||
collapse_with(qpNodePathComponent *next) {
|
||||
nassertv(!is_collapsed());
|
||||
nassertv(next != (qpNodePathComponent *)NULL);
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
// We indicate a component has been collapsed by setting its length
|
||||
// to zero.
|
||||
cdata->_next = next;
|
||||
cdata->_length = 0;
|
||||
|
||||
if (_key != 0 && next->_key == 0) {
|
||||
// If we had a key set and the other one didn't, it inherits our
|
||||
// key. Otherwise, we inherit the other's key.
|
||||
next->_key = _key;
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
private:
|
||||
void set_next(qpNodePathComponent *next);
|
||||
void set_top_node();
|
||||
INLINE void collapse_with(qpNodePathComponent *next);
|
||||
void collapse_with(qpNodePathComponent *next);
|
||||
|
||||
// We don't have to cycle the _node and _key elements, since these
|
||||
// are permanent properties of this object. (Well, the _key is
|
||||
|
Loading…
x
Reference in New Issue
Block a user