mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
nodePath refinements
This commit is contained in:
parent
03ae7a34a7
commit
5954465fbc
@ -20,11 +20,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpNodePath::Default Constructor
|
// Function: qpNodePath::Default Constructor
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: This constructs an empty qpNodePath with no nodes. It
|
// Description: This constructs an empty qpNodePath with no nodes.
|
||||||
// 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.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE qpNodePath::
|
INLINE qpNodePath::
|
||||||
qpNodePath() :
|
qpNodePath() :
|
||||||
@ -35,9 +31,9 @@ qpNodePath() :
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpNodePath::Constructor
|
// Function: qpNodePath::Constructor
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: This constructs an empty qpNodePath with a single
|
// Description: This constructs a new qpNodePath with a single
|
||||||
// node. An ordinary PandaNode is created with the
|
// node. An ordinary, unattached PandaNode is created
|
||||||
// indicated name.
|
// with the indicated name.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE qpNodePath::
|
INLINE qpNodePath::
|
||||||
qpNodePath(const string &top_node_name) :
|
qpNodePath(const string &top_node_name) :
|
||||||
@ -52,35 +48,53 @@ qpNodePath(const string &top_node_name) :
|
|||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: This constructs a NodePath for the indicated node.
|
// Description: This constructs a NodePath for the indicated node.
|
||||||
// If the node does not have any parents, this creates a
|
// 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
|
// the path from the node to the root. If the node has
|
||||||
// multiple paths to the root, one path is chosen
|
// 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::
|
INLINE qpNodePath::
|
||||||
qpNodePath(PandaNode *top_node) :
|
qpNodePath(PandaNode *node) :
|
||||||
_error_type(ET_ok)
|
_error_type(ET_ok)
|
||||||
{
|
{
|
||||||
if (top_node != (PandaNode *)NULL) {
|
if (node != (PandaNode *)NULL) {
|
||||||
_head = top_node->get_generic_component(false);
|
_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
|
// Function: qpNodePath::Constructor
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Constructs a NodePath with the indicated parent
|
// Description: Constructs a NodePath with the indicated parent
|
||||||
// NodePath and child node; the child node must be a
|
// NodePath and child node; the child node must be a
|
||||||
|
|
||||||
// stashed or unstashed child of the parent.
|
// stashed or unstashed child of the parent.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE qpNodePath::
|
INLINE qpNodePath::
|
||||||
qpNodePath(const qpNodePath &parent, PandaNode *child) :
|
qpNodePath(const qpNodePath &parent, PandaNode *child_node) :
|
||||||
_error_type(ET_fail)
|
_error_type(ET_fail)
|
||||||
{
|
{
|
||||||
nassertv(!parent.is_empty());
|
nassertv(!parent.is_empty());
|
||||||
nassertv(child != (PandaNode *)NULL);
|
nassertv(child_node != (PandaNode *)NULL);
|
||||||
_head = PandaNode::get_component(parent._head, child);
|
_head = PandaNode::get_component(parent._head, child_node);
|
||||||
nassertv(_head != (qpNodePathComponent *)NULL);
|
nassertv(_head != (qpNodePathComponent *)NULL);
|
||||||
|
|
||||||
if (_head != (qpNodePathComponent *)NULL) {
|
if (_head != (qpNodePathComponent *)NULL) {
|
||||||
@ -155,7 +169,7 @@ fail() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpNodePath::set_max_search_depth
|
// Function: qpNodePath::set_max_search_depth
|
||||||
// Access: Published, Static
|
// 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
|
// find_all_matches(), require a traversal of the scene
|
||||||
// graph to search for the target node or nodes. This
|
// graph to search for the target node or nodes. This
|
||||||
// traversal does not attempt to detect cycles, so an
|
// traversal does not attempt to detect cycles, so an
|
||||||
@ -252,6 +266,13 @@ node() const {
|
|||||||
// given key will never be reused for a different
|
// given key will never be reused for a different
|
||||||
// instance (unless the app has been running long enough
|
// instance (unless the app has been running long enough
|
||||||
// that we overflow the integer key value).
|
// 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::
|
INLINE int qpNodePath::
|
||||||
get_key() const {
|
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
|
// Function: qpNodePath::get_state
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -1078,7 +1077,7 @@ compare_to(const qpNodePath &other) const {
|
|||||||
other.uncollapse_head();
|
other.uncollapse_head();
|
||||||
|
|
||||||
// Nowadays, the NodePathComponents at the head are pointerwise
|
// 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.
|
// only have to compare pointers.
|
||||||
return _head - other._head;
|
return _head - other._head;
|
||||||
}
|
}
|
||||||
|
@ -357,21 +357,42 @@ attach_new_node(PandaNode *node, int sort) const {
|
|||||||
void qpNodePath::
|
void qpNodePath::
|
||||||
remove_node() {
|
remove_node() {
|
||||||
nassertv(_error_type != ET_not_found);
|
nassertv(_error_type != ET_not_found);
|
||||||
if (is_empty() || is_singleton()) {
|
|
||||||
// If we have no parents, remove_node() is just a do-nothing
|
// If we have no parents, remove_node() is just a do-nothing
|
||||||
// operation; if we have no nodes, maybe we were already removed.
|
// operation; if we have no nodes, maybe we were already removed.
|
||||||
// In either case, quietly do nothing except to ensure the
|
// In either case, quietly do nothing except to ensure the
|
||||||
// qpNodePath is clear.
|
// qpNodePath is clear.
|
||||||
(*this) = qpNodePath::removed();
|
if (!is_empty() && !is_singleton()) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uncollapse_head();
|
uncollapse_head();
|
||||||
PandaNode::detach(_head);
|
PandaNode::detach(_head);
|
||||||
|
}
|
||||||
|
|
||||||
(*this) = qpNodePath::removed();
|
(*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
|
// Function: qpNodePath::output
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -149,9 +149,11 @@ PUBLISHED:
|
|||||||
|
|
||||||
INLINE qpNodePath();
|
INLINE qpNodePath();
|
||||||
INLINE qpNodePath(const string &top_node_name);
|
INLINE qpNodePath(const string &top_node_name);
|
||||||
INLINE qpNodePath(PandaNode *top_node);
|
INLINE qpNodePath(PandaNode *node);
|
||||||
INLINE qpNodePath(const qpNodePath ©);
|
INLINE static qpNodePath any_path(PandaNode *node);
|
||||||
INLINE qpNodePath(const qpNodePath &parent, PandaNode *child_node);
|
INLINE qpNodePath(const qpNodePath &parent, PandaNode *child_node);
|
||||||
|
|
||||||
|
INLINE qpNodePath(const qpNodePath ©);
|
||||||
INLINE void operator = (const qpNodePath ©);
|
INLINE void operator = (const qpNodePath ©);
|
||||||
|
|
||||||
INLINE static qpNodePath not_found();
|
INLINE static qpNodePath not_found();
|
||||||
@ -202,6 +204,7 @@ PUBLISHED:
|
|||||||
qpNodePath attach_new_node(PandaNode *node, int sort = 0) const;
|
qpNodePath attach_new_node(PandaNode *node, int sort = 0) const;
|
||||||
INLINE qpNodePath attach_new_node(const string &name, int sort = 0) const;
|
INLINE qpNodePath attach_new_node(const string &name, int sort = 0) const;
|
||||||
void remove_node();
|
void remove_node();
|
||||||
|
void detach_node();
|
||||||
|
|
||||||
// Handy ways to look at what's there, and other miscellaneous
|
// Handy ways to look at what's there, and other miscellaneous
|
||||||
// operations.
|
// operations.
|
||||||
@ -210,8 +213,6 @@ PUBLISHED:
|
|||||||
|
|
||||||
INLINE void ls() const;
|
INLINE void ls() const;
|
||||||
INLINE void ls(ostream &out, int indent_level = 0) 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.
|
// Aggregate transform and state information.
|
||||||
|
@ -135,24 +135,3 @@ get_collapsed() const {
|
|||||||
CDReader cdata(_cycler);
|
CDReader cdata(_cycler);
|
||||||
return cdata->_next;
|
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;
|
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:
|
private:
|
||||||
void set_next(qpNodePathComponent *next);
|
void set_next(qpNodePathComponent *next);
|
||||||
void set_top_node();
|
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
|
// We don't have to cycle the _node and _key elements, since these
|
||||||
// are permanent properties of this object. (Well, the _key is
|
// are permanent properties of this object. (Well, the _key is
|
||||||
|
Loading…
x
Reference in New Issue
Block a user