mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
*** empty log message ***
This commit is contained in:
parent
b1f323a992
commit
259683160c
@ -738,7 +738,7 @@ void event_C(CPT_Event) {
|
||||
void event_N(CPT_Event) {
|
||||
nout << "Reducing scene graph.\n";
|
||||
SceneGraphReducer gr(RenderRelation::get_class_type());
|
||||
gr.apply_transitions(root);
|
||||
gr.apply_transitions(first_arc);
|
||||
int num_reduced = gr.flatten(root, true);
|
||||
nout << "Removed " << num_reduced << " arcs.\n";
|
||||
}
|
||||
@ -1120,8 +1120,8 @@ int framework_main(int argc, char *argv[]) {
|
||||
first_arc = new RenderRelation(render, root, 100);
|
||||
|
||||
if (files.empty() && framework.GetBool("have-omnitriangle", true)) {
|
||||
// The user did not specify an file. Create some default
|
||||
// geometry.
|
||||
// The user did not specify a model file to load. Create some
|
||||
// default geometry.
|
||||
|
||||
PTA_Vertexf coords;
|
||||
PTA_TexCoordf uvs;
|
||||
|
@ -10,9 +10,9 @@
|
||||
// attaches it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeRelation::
|
||||
NodeRelation(Node *parent, Node *to, int sort, TypeHandle type) :
|
||||
NodeRelation(Node *parent, Node *to, int sort, TypeHandle graph_type) :
|
||||
_parent(parent), _child(to), _sort(sort),
|
||||
_type(type), _num_transitions(0)
|
||||
_graph_type(graph_type), _num_transitions(0)
|
||||
{
|
||||
_top_subtree = NULL;
|
||||
_attached = false;
|
||||
@ -29,8 +29,8 @@ NodeRelation(Node *parent, Node *to, int sort, TypeHandle type) :
|
||||
// general, attempt to create an unattached arc.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeRelation::
|
||||
NodeRelation(TypeHandle type) :
|
||||
_type(type)
|
||||
NodeRelation(TypeHandle graph_type) :
|
||||
_graph_type(graph_type)
|
||||
{
|
||||
_parent = NULL;
|
||||
_child = NULL;
|
||||
@ -49,14 +49,13 @@ NodeRelation(TypeHandle type) :
|
||||
// unattached arc.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeRelation::
|
||||
NodeRelation(void)
|
||||
{
|
||||
NodeRelation(void) {
|
||||
_parent = NULL;
|
||||
_child = NULL;
|
||||
_sort = 0;
|
||||
_top_subtree = NULL;
|
||||
_attached = false;
|
||||
_type = get_class_type();
|
||||
_graph_type = get_class_type();
|
||||
_num_transitions = 0;
|
||||
}
|
||||
|
||||
@ -124,6 +123,20 @@ 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 TypeHandle NodeRelation::
|
||||
get_graph_type() const {
|
||||
return _graph_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeRelation::change_parent
|
||||
// Access: Public
|
||||
@ -189,6 +202,20 @@ set_sort(int 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 void NodeRelation::
|
||||
set_graph_type(TypeHandle graph_type) {
|
||||
PT(NodeRelation) hold_arc = detach();
|
||||
_graph_type = graph_type;
|
||||
attach();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeRelation::set_transition
|
||||
// Access: Public
|
||||
@ -390,6 +417,31 @@ get_factory() {
|
||||
return *_factory;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeRelation::get_class_type
|
||||
// Access: Public, Static
|
||||
// Description: Returns the TypeHandle associated with this type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE 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 TypeHandle NodeRelation::
|
||||
get_stashed_type() {
|
||||
return _stashed_type_handle;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_transition_into
|
||||
// Description: This external template function is handy for
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
TypeHandle NodeRelation::_type_handle;
|
||||
TypeHandle NodeRelation::_stashed_type_handle;
|
||||
|
||||
Factory<NodeRelation> *NodeRelation::_factory = NULL;
|
||||
|
||||
@ -507,8 +508,8 @@ attach() {
|
||||
|
||||
_attached = true;
|
||||
|
||||
DownRelationPointers &parent_list = _parent->_children[_type];
|
||||
UpRelationPointers &child_list = _child->_parents[_type];
|
||||
DownRelationPointers &parent_list = _parent->_children[_graph_type];
|
||||
UpRelationPointers &child_list = _child->_parents[_graph_type];
|
||||
|
||||
bool inserted_one = internal_insert_arc(parent_list, this);
|
||||
bool inserted_two = internal_insert_arc(child_list, this);
|
||||
@ -516,7 +517,7 @@ attach() {
|
||||
|
||||
// Blow out the cache and increment the current update sequence.
|
||||
_net_transitions.clear();
|
||||
_last_update = ++last_graph_update(_type);
|
||||
_last_update = ++last_graph_update(_graph_type);
|
||||
|
||||
// If we have just added a new parent arc to a node that previously
|
||||
// had exactly one parent, we also need to set the update sequence
|
||||
@ -557,8 +558,8 @@ detach() {
|
||||
|
||||
force_bound_stale();
|
||||
|
||||
DownRelationPointers &parent_list = _parent->_children[_type];
|
||||
UpRelationPointers &child_list = _child->_parents[_type];
|
||||
DownRelationPointers &parent_list = _parent->_children[_graph_type];
|
||||
UpRelationPointers &child_list = _child->_parents[_graph_type];
|
||||
|
||||
bool removed_one = internal_remove_arc(parent_list, this);
|
||||
bool removed_two = internal_remove_arc(child_list, this);
|
||||
@ -570,7 +571,7 @@ detach() {
|
||||
|
||||
// Blow out the cache and increment the current update sequence.
|
||||
_net_transitions.clear();
|
||||
_last_update = ++last_graph_update(_type);
|
||||
_last_update = ++last_graph_update(_graph_type);
|
||||
|
||||
// If we have just removed a parent arc from a node, leaving exactly
|
||||
// one parent, we also need to set the update sequence
|
||||
@ -580,6 +581,16 @@ detach() {
|
||||
child_list[0]->_last_update = _last_update;
|
||||
}
|
||||
|
||||
// If we have completely emptied the parent or child lists, remove
|
||||
// the entry for this graph type from the node, as a small render
|
||||
// optimization.
|
||||
if (parent_list.empty()) {
|
||||
_parent->_children.erase(_graph_type);
|
||||
}
|
||||
if (child_list.empty()) {
|
||||
_child->_parents.erase(_graph_type);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -601,7 +612,7 @@ detach_below() {
|
||||
|
||||
force_bound_stale();
|
||||
|
||||
bool removed = internal_remove_arc(_child->_parents[_type], this);
|
||||
bool removed = internal_remove_arc(_child->_parents[_graph_type], this);
|
||||
|
||||
nassertr(removed, result);
|
||||
|
||||
@ -609,7 +620,7 @@ detach_below() {
|
||||
|
||||
// Blow out the cache and increment the current update sequence.
|
||||
_net_transitions.clear();
|
||||
_last_update = ++last_graph_update(_type);
|
||||
_last_update = ++last_graph_update(_graph_type);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -631,7 +642,7 @@ changed_transition(TypeHandle trans_type) {
|
||||
if (_net_transitions != (NodeTransitionCache *)NULL) {
|
||||
_net_transitions->clear_transition(trans_type);
|
||||
}
|
||||
_last_update = ++last_graph_update(get_type());
|
||||
_last_update = ++last_graph_update(_graph_type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -648,7 +659,7 @@ propagate_stale_bound() {
|
||||
nassertv(node != (Node*)NULL);
|
||||
|
||||
UpRelations::const_iterator uri;
|
||||
uri = node->_parents.find(get_type());
|
||||
uri = node->_parents.find(_graph_type);
|
||||
if (uri != node->_parents.end()) {
|
||||
const UpRelationPointers &urp = (*uri).second;
|
||||
|
||||
@ -681,7 +692,7 @@ recompute_bound() {
|
||||
child_volumes.push_back(&node->get_bound());
|
||||
|
||||
DownRelations::const_iterator dri;
|
||||
dri = node->_children.find(get_type());
|
||||
dri = node->_children.find(_graph_type);
|
||||
if (dri != node->_children.end()) {
|
||||
const DownRelationPointers &drp = (*dri).second;
|
||||
|
||||
@ -717,7 +728,7 @@ void NodeRelation::
|
||||
write_datagram(BamWriter *manager, Datagram &me)
|
||||
{
|
||||
//Write out the "dynamic" type
|
||||
manager->write_handle(me, _type);
|
||||
manager->write_handle(me, _graph_type);
|
||||
|
||||
//We should always be attached if we are trying to write out
|
||||
nassertv(_attached);
|
||||
@ -769,7 +780,7 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager)
|
||||
|
||||
// We must explicitly add the arc to its child node, but not to
|
||||
// its parent node.
|
||||
UpRelationPointers &child_list = _child->_parents[_type];
|
||||
UpRelationPointers &child_list = _child->_parents[_graph_type];
|
||||
bool inserted = internal_insert_arc(child_list, this);
|
||||
nassertr(inserted, _num_transitions + 2);
|
||||
_attached = true;
|
||||
@ -785,8 +796,9 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager)
|
||||
//at old code
|
||||
if (plist[i] == TypedWriteable::Null)
|
||||
{
|
||||
graph_cat->warning() << get_type().get_name()
|
||||
<< "Ignoring null Transition" << endl;
|
||||
graph_cat->warning()
|
||||
<< get_type().get_name()
|
||||
<< ": Ignoring null Transition" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -829,7 +841,7 @@ make_NodeRelation(const FactoryParams ¶ms)
|
||||
void NodeRelation::
|
||||
fillin(DatagramIterator& scan, BamReader* manager)
|
||||
{
|
||||
_type = manager->read_handle(scan);
|
||||
_graph_type = manager->read_handle(scan);
|
||||
//Read in my parent
|
||||
manager->read_pointer(scan, this);
|
||||
//Read in my child
|
||||
@ -855,3 +867,46 @@ register_with_read_factory(void)
|
||||
{
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_NodeRelation);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeRelation::init_type
|
||||
// Access: Public, Static
|
||||
// Description: Initializes the TypeHandles associated with this
|
||||
// class.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodeRelation::
|
||||
init_type() {
|
||||
TypedWriteableReferenceCount::init_type();
|
||||
BoundedObject::init_type();
|
||||
register_type(_type_handle, "NodeRelation",
|
||||
TypedWriteableReferenceCount::get_class_type(),
|
||||
BoundedObject::get_class_type());
|
||||
register_type(_stashed_type_handle, "StashedNodeRelation",
|
||||
get_class_type());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeRelation::get_type
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the particular type represented by this
|
||||
// instance of the class.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypeHandle NodeRelation::
|
||||
get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeRelation::force_init_type
|
||||
// Access: Public, Virtual
|
||||
// Description: Called by the TypeHandle system when it is detected
|
||||
// that init_type() was not called for some reason.
|
||||
// This is only called in an error situation, and it
|
||||
// attempts to remedy the problem so we can recover and
|
||||
// continue.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypeHandle NodeRelation::
|
||||
force_init_type() {
|
||||
init_type();
|
||||
return get_class_type();
|
||||
}
|
||||
|
@ -47,13 +47,13 @@ extern EXPCL_PANDA UpdateSeq &last_graph_update(TypeHandle graph_type);
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA NodeRelation : public TypedWriteableReferenceCount, public BoundedObject {
|
||||
public:
|
||||
INLINE NodeRelation(Node *from, Node *to, int sort, TypeHandle type);
|
||||
INLINE NodeRelation(Node *from, Node *to, int sort, TypeHandle graph_type);
|
||||
|
||||
protected:
|
||||
// Normally, this should only be used from derived classes for
|
||||
// passing to the factory. Don't attempt to create an unattached
|
||||
// arc directly.
|
||||
INLINE NodeRelation(TypeHandle type);
|
||||
INLINE NodeRelation(TypeHandle graph_type);
|
||||
|
||||
//make_NodeRelation needs to have a construct that takes nothing
|
||||
//since it creates the object before it has any information
|
||||
@ -80,12 +80,14 @@ PUBLISHED:
|
||||
INLINE Node *get_parent() const;
|
||||
INLINE Node *get_child() const;
|
||||
INLINE int get_sort() const;
|
||||
INLINE TypeHandle get_graph_type() const;
|
||||
|
||||
INLINE void change_parent(Node *parent);
|
||||
INLINE void change_parent(Node *parent, int sort);
|
||||
INLINE void change_child(Node *child);
|
||||
INLINE void change_parent_and_child(Node *parent, Node *child);
|
||||
INLINE void set_sort(int sort);
|
||||
INLINE void set_graph_type(TypeHandle graph_type);
|
||||
|
||||
INLINE PT(NodeTransition) set_transition(TypeHandle handle,
|
||||
NodeTransition *trans);
|
||||
@ -141,7 +143,7 @@ private:
|
||||
Node *_parent;
|
||||
PT_Node _child;
|
||||
int _sort;
|
||||
TypeHandle _type;
|
||||
TypeHandle _graph_type;
|
||||
bool _attached;
|
||||
|
||||
private:
|
||||
@ -193,24 +195,18 @@ protected:
|
||||
virtual void propagate_stale_bound();
|
||||
virtual void recompute_bound();
|
||||
|
||||
PUBLISHED:
|
||||
INLINE static TypeHandle get_class_type();
|
||||
INLINE static TypeHandle get_stashed_type();
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedWriteableReferenceCount::init_type();
|
||||
BoundedObject::init_type();
|
||||
register_type(_type_handle, "NodeRelation",
|
||||
TypedWriteableReferenceCount::get_class_type(),
|
||||
BoundedObject::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
static void init_type();
|
||||
virtual TypeHandle get_type() const;
|
||||
virtual TypeHandle force_init_type();
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
static TypeHandle _stashed_type_handle;
|
||||
|
||||
friend INLINE void remove_arc(NodeRelation *arc);
|
||||
friend class Node;
|
||||
|
@ -39,3 +39,13 @@ INLINE void RenderRelation::
|
||||
register_with_factory() {
|
||||
get_factory().register_factory(get_class_type(), make_arc);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderRelation::get_class_type
|
||||
// Access: Public, Static
|
||||
// Description: Returns the TypeHandle associated with this type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TypeHandle RenderRelation::
|
||||
get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
|
@ -98,3 +98,43 @@ register_with_read_factory(void)
|
||||
{
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_RenderRelation);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderRelation::init_type
|
||||
// Access: Public, Static
|
||||
// Description: Initializes the TypeHandles associated with this
|
||||
// class.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RenderRelation::
|
||||
init_type() {
|
||||
NodeRelation::init_type();
|
||||
register_type(_type_handle, "RenderRelation",
|
||||
NodeRelation::get_class_type());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderRelation::get_type
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the particular type represented by this
|
||||
// instance of the class.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypeHandle RenderRelation::
|
||||
get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderRelation::force_init_type
|
||||
// Access: Public, Virtual
|
||||
// Description: Called by the TypeHandle system when it is detected
|
||||
// that init_type() was not called for some reason.
|
||||
// This is only called in an error situation, and it
|
||||
// attempts to remedy the problem so we can recover and
|
||||
// continue.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypeHandle RenderRelation::
|
||||
force_init_type() {
|
||||
init_type();
|
||||
return get_class_type();
|
||||
}
|
||||
|
@ -43,20 +43,12 @@ public:
|
||||
static TypedWriteable *make_RenderRelation(const FactoryParams ¶ms);
|
||||
|
||||
PUBLISHED:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
INLINE static TypeHandle get_class_type();
|
||||
|
||||
public:
|
||||
static void init_type() {
|
||||
NodeRelation::init_type();
|
||||
register_type(_type_handle, "RenderRelation",
|
||||
NodeRelation::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
static void init_type();
|
||||
virtual TypeHandle get_type() const;
|
||||
virtual TypeHandle force_init_type();
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
@ -44,6 +44,17 @@ operator = (const FindApproxLevelEntry ©) {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FindApproxLevelEntry::next_is_stashed
|
||||
// Access: Public
|
||||
// Description: Returns true if the next node matched by this entry
|
||||
// must be a stashed node, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool FindApproxLevelEntry::
|
||||
next_is_stashed() const {
|
||||
return _approx_path.matches_stashed(_i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FindApproxLevelEntry::is_solution
|
||||
// Access: Public
|
||||
|
@ -30,6 +30,61 @@ output(ostream &out) const {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FindApproxLevelEntry::consider_node
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FindApproxLevelEntry::
|
||||
consider_node(NodePathCollection &result, FindApproxLevel &next_level,
|
||||
int max_matches, TypeHandle graph_type) const {
|
||||
nassertv(_i < _approx_path.get_num_components());
|
||||
|
||||
if (_approx_path.is_component_match_many(_i)) {
|
||||
// Match any number, zero or more, levels of nodes. This is the
|
||||
// tricky case that requires this whole nutty breadth-first thing.
|
||||
|
||||
// This means we must reconsider our own entry with the next path
|
||||
// entry, before we consider the next entry--this supports
|
||||
// matching zero levels of nodes.
|
||||
FindApproxLevelEntry reconsider(*this);
|
||||
++reconsider._i;
|
||||
|
||||
if (reconsider.is_solution()) {
|
||||
// Does this now represent a solution?
|
||||
result.add_path(reconsider._node_path);
|
||||
if (max_matches > 0 && result.get_num_paths() >= max_matches) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
reconsider.consider_node(result, next_level, max_matches, graph_type);
|
||||
}
|
||||
}
|
||||
|
||||
Node *bottom_node = _node_path.node();
|
||||
nassertv(bottom_node != (Node *)NULL);
|
||||
|
||||
TypeHandle next_graph_type = graph_type;
|
||||
if (next_is_stashed()) {
|
||||
next_graph_type = NodeRelation::get_stashed_type();
|
||||
}
|
||||
|
||||
DownRelations::const_iterator dri;
|
||||
dri = bottom_node->_children.find(next_graph_type);
|
||||
if (dri != bottom_node->_children.end()) {
|
||||
const DownRelationPointers &drp = (*dri).second;
|
||||
|
||||
DownRelationPointers::const_iterator drpi;
|
||||
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
|
||||
NodeRelation *arc = (*drpi);
|
||||
consider_next_step(result, arc, next_level, max_matches, graph_type);
|
||||
if (max_matches > 0 && result.get_num_paths() >= max_matches) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FindApproxLevelEntry::consider_next_step
|
||||
// Access: Public
|
||||
@ -40,47 +95,28 @@ output(ostream &out) const {
|
||||
// whatever additional entries are appropriate and
|
||||
// stores them in next_level.
|
||||
//
|
||||
// If a complete solution is found, returns the solution
|
||||
// node; otherwise, returns NULL.
|
||||
// If a complete solution is found, stores it in result.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FindApproxLevelEntry::
|
||||
consider_next_step(NodePathCollection &result,
|
||||
NodeRelation *arc, FindApproxLevel &next_level,
|
||||
int max_matches) const {
|
||||
int max_matches, TypeHandle graph_type) const {
|
||||
nassertv(_i < _approx_path.get_num_components());
|
||||
|
||||
FindApproxLevelEntry next(*this);
|
||||
bool eb = next._node_path.extend_by(arc);
|
||||
nassertv(eb);
|
||||
|
||||
Node *child = arc->get_child();
|
||||
if (_approx_path.is_component_match_many(_i)) {
|
||||
// Match any number, zero or more, levels of nodes. This is the
|
||||
// tricky case that requires this whole nutty breadth-first thing.
|
||||
|
||||
// This means we must reconsider our own entry with the next
|
||||
// path entry, before we consider the next entry.
|
||||
FindApproxLevelEntry reconsider(*this);
|
||||
++reconsider._i;
|
||||
if (reconsider.is_solution()) {
|
||||
// Does this now represent a solution?
|
||||
bool eb = reconsider._node_path.extend_by(arc);
|
||||
nassertv(eb);
|
||||
result.add_path(reconsider._node_path);
|
||||
} else {
|
||||
reconsider.consider_next_step(result, arc, next_level, max_matches);
|
||||
}
|
||||
|
||||
if (max_matches > 0 && result.get_num_paths() >= max_matches) {
|
||||
return;
|
||||
}
|
||||
|
||||
// And now we just add the next entry without incrementing its
|
||||
// path entry.
|
||||
next_level.add_entry(next);
|
||||
|
||||
} else {
|
||||
if (_approx_path.matches_component(_i, child)) {
|
||||
if (_approx_path.matches_component(_i, arc)) {
|
||||
// That matched, and it consumes one path entry.
|
||||
++next._i;
|
||||
next_level.add_entry(next);
|
||||
|
@ -32,9 +32,13 @@ public:
|
||||
INLINE FindApproxLevelEntry(const FindApproxLevelEntry ©);
|
||||
INLINE void operator = (const FindApproxLevelEntry ©);
|
||||
|
||||
INLINE bool next_is_stashed() const;
|
||||
|
||||
void consider_node(NodePathCollection &result, FindApproxLevel &next_level,
|
||||
int max_matches, TypeHandle graph_type) const;
|
||||
void consider_next_step(NodePathCollection &result,
|
||||
NodeRelation *arc, FindApproxLevel &next_level,
|
||||
int max_matches) const;
|
||||
int max_matches, TypeHandle graph_type) const;
|
||||
INLINE bool is_solution() const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
@ -20,10 +20,11 @@ FindApproxPath() {
|
||||
// exactly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void FindApproxPath::
|
||||
add_match_name(const string &name) {
|
||||
add_match_name(const string &name, int flags) {
|
||||
Component comp;
|
||||
comp._type = CT_match_name;
|
||||
comp._name = name;
|
||||
comp._flags = flags;
|
||||
_path.push_back(comp);
|
||||
}
|
||||
|
||||
@ -35,10 +36,11 @@ add_match_name(const string &name) {
|
||||
// characters accepted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void FindApproxPath::
|
||||
add_match_name_glob(const string &name) {
|
||||
add_match_name_glob(const string &name, int flags) {
|
||||
Component comp;
|
||||
comp._type = CT_match_name_glob;
|
||||
comp._name = name;
|
||||
comp._flags = flags;
|
||||
_path.push_back(comp);
|
||||
}
|
||||
|
||||
@ -49,10 +51,11 @@ add_match_name_glob(const string &name) {
|
||||
// exactly, with no derived types matching.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void FindApproxPath::
|
||||
add_match_exact_type(TypeHandle type) {
|
||||
add_match_exact_type(TypeHandle type, int flags) {
|
||||
Component comp;
|
||||
comp._type = CT_match_exact_type;
|
||||
comp._type_handle = type;
|
||||
comp._flags = flags;
|
||||
_path.push_back(comp);
|
||||
}
|
||||
|
||||
@ -63,10 +66,11 @@ add_match_exact_type(TypeHandle type) {
|
||||
// or be a base class of the node's type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void FindApproxPath::
|
||||
add_match_inexact_type(TypeHandle type) {
|
||||
add_match_inexact_type(TypeHandle type, int flags) {
|
||||
Component comp;
|
||||
comp._type = CT_match_inexact_type;
|
||||
comp._type_handle = type;
|
||||
comp._flags = flags;
|
||||
_path.push_back(comp);
|
||||
}
|
||||
|
||||
@ -77,9 +81,10 @@ add_match_inexact_type(TypeHandle type) {
|
||||
// chain of many nodes).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void FindApproxPath::
|
||||
add_match_one() {
|
||||
add_match_one(int flags) {
|
||||
Component comp;
|
||||
comp._type = CT_match_one;
|
||||
comp._flags = flags;
|
||||
_path.push_back(comp);
|
||||
}
|
||||
|
||||
@ -90,9 +95,10 @@ add_match_one() {
|
||||
// more consecutive nodes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void FindApproxPath::
|
||||
add_match_many() {
|
||||
add_match_many(int flags) {
|
||||
Component comp;
|
||||
comp._type = CT_match_many;
|
||||
comp._flags = flags;
|
||||
_path.push_back(comp);
|
||||
}
|
||||
|
||||
@ -103,10 +109,11 @@ add_match_many() {
|
||||
// exactly, by pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void FindApproxPath::
|
||||
add_match_pointer(Node *pointer) {
|
||||
add_match_pointer(Node *pointer, int flags) {
|
||||
Component comp;
|
||||
comp._type = CT_match_pointer;
|
||||
comp._pointer = pointer;
|
||||
comp._flags = flags;
|
||||
_path.push_back(comp);
|
||||
}
|
||||
|
||||
@ -139,9 +146,24 @@ is_component_match_many(int index) const {
|
||||
// the indicated node, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool FindApproxPath::
|
||||
matches_component(int index, Node *node) const {
|
||||
matches_component(int index, NodeRelation *arc) const {
|
||||
nassertr(index >= 0 && index < (int)_path.size(), false);
|
||||
return (_path[index].matches(node));
|
||||
return (_path[index].matches(arc));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FindApproxPath::matches_stashed
|
||||
// Access: Public
|
||||
// Description: Returns true if the nth component of the path matches
|
||||
// a stashed node only, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool FindApproxPath::
|
||||
matches_stashed(int index) const {
|
||||
if (index >= 0 && index < (int)_path.size()) {
|
||||
return ((_path[index]._flags & CF_stashed) != 0);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <globPattern.h>
|
||||
#include <node.h>
|
||||
#include <namedNode.h>
|
||||
#include <nodeRelation.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -18,7 +19,8 @@
|
||||
// component, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool FindApproxPath::Component::
|
||||
matches(Node *node) const {
|
||||
matches(NodeRelation *arc) const {
|
||||
Node *node = arc->get_child();
|
||||
string node_name;
|
||||
|
||||
switch (_type) {
|
||||
@ -113,12 +115,22 @@ add_string(const string &str_path) {
|
||||
// the string component was in some way invalid.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool FindApproxPath::
|
||||
add_component(const string &str_component) {
|
||||
add_component(string str_component) {
|
||||
int flags = 0;
|
||||
if (str_component.size() >= 2 && str_component.substr(0, 2) == "@@") {
|
||||
flags |= CF_stashed;
|
||||
str_component = str_component.substr(2);
|
||||
}
|
||||
|
||||
if (str_component == "*") {
|
||||
add_match_one();
|
||||
add_match_one(flags);
|
||||
|
||||
} else if (str_component == "**") {
|
||||
add_match_many();
|
||||
if ((flags & CF_stashed) != 0) {
|
||||
sgmanip_cat.warning()
|
||||
<< "@@** is ambiguous; use @@*/** or **/@@* instead.\n";
|
||||
}
|
||||
add_match_many(flags);
|
||||
|
||||
} else if (!str_component.empty() && str_component[0] == '-') {
|
||||
string type_name = str_component.substr(1);
|
||||
@ -130,7 +142,7 @@ add_component(const string &str_component) {
|
||||
return false;
|
||||
|
||||
} else {
|
||||
add_match_exact_type(handle);
|
||||
add_match_exact_type(handle, flags);
|
||||
}
|
||||
|
||||
} else if (!str_component.empty() && str_component[0] == '+') {
|
||||
@ -143,11 +155,11 @@ add_component(const string &str_component) {
|
||||
return false;
|
||||
|
||||
} else {
|
||||
add_match_inexact_type(handle);
|
||||
add_match_inexact_type(handle, flags);
|
||||
}
|
||||
|
||||
} else {
|
||||
add_match_name_glob(str_component);
|
||||
add_match_name_glob(str_component, flags);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <vector>
|
||||
|
||||
class Node;
|
||||
class NodeRelation;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : FindApproxPath
|
||||
@ -27,19 +28,20 @@ public:
|
||||
INLINE FindApproxPath();
|
||||
|
||||
bool add_string(const string &str_path);
|
||||
bool add_component(const string &str_component);
|
||||
bool add_component(string str_component);
|
||||
|
||||
INLINE void add_match_name(const string &name);
|
||||
INLINE void add_match_name_glob(const string &glob);
|
||||
INLINE void add_match_exact_type(TypeHandle type);
|
||||
INLINE void add_match_inexact_type(TypeHandle type);
|
||||
INLINE void add_match_one();
|
||||
INLINE void add_match_many();
|
||||
INLINE void add_match_pointer(Node *pointer);
|
||||
INLINE void add_match_name(const string &name, int flags);
|
||||
INLINE void add_match_name_glob(const string &glob, int flags);
|
||||
INLINE void add_match_exact_type(TypeHandle type, int flags);
|
||||
INLINE void add_match_inexact_type(TypeHandle type, int flags);
|
||||
INLINE void add_match_one(int flags);
|
||||
INLINE void add_match_many(int flags);
|
||||
INLINE void add_match_pointer(Node *pointer, int flags);
|
||||
|
||||
INLINE int get_num_components() const;
|
||||
INLINE bool is_component_match_many(int index) const;
|
||||
INLINE bool matches_component(int index, Node *node) const;
|
||||
INLINE bool matches_component(int index, NodeRelation *arc) const;
|
||||
INLINE bool matches_stashed(int index) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
INLINE void output_component(ostream &out, int index) const;
|
||||
@ -58,16 +60,20 @@ private:
|
||||
CT_match_many,
|
||||
CT_match_pointer
|
||||
};
|
||||
enum ComponentFlags {
|
||||
CF_stashed = 0x001,
|
||||
};
|
||||
|
||||
class Component {
|
||||
public:
|
||||
bool matches(Node *node) const;
|
||||
bool matches(NodeRelation *arc) const;
|
||||
void output(ostream &out) const;
|
||||
|
||||
ComponentType _type;
|
||||
string _name;
|
||||
TypeHandle _type_handle;
|
||||
Node *_pointer;
|
||||
int _flags;
|
||||
};
|
||||
|
||||
typedef vector<Component> Path;
|
||||
|
@ -98,6 +98,7 @@ INLINE NodePath::
|
||||
NodePath(const ArcChain &chain, TypeHandle graph_type) :
|
||||
NodePathBase(chain, graph_type)
|
||||
{
|
||||
reset_top_node();
|
||||
nassertv(verify_connectivity());
|
||||
}
|
||||
|
||||
@ -262,6 +263,18 @@ get_num_nodes() const {
|
||||
return get_num_arcs() + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_top_node
|
||||
// Access: Public
|
||||
// Description: Returns the top node of the path, or NULL if the path
|
||||
// is empty.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Node *NodePath::
|
||||
get_top_node() {
|
||||
reset_top_node();
|
||||
return _top_node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::node
|
||||
// Access: Public
|
||||
@ -1409,6 +1422,13 @@ show() {
|
||||
// Access: Public
|
||||
// Description: Puts a PruneTransition on this bottom arc so that the
|
||||
// geometry at this level and below will be invisible.
|
||||
//
|
||||
// However, it will remain part of the scene graph, and
|
||||
// will still be counted in its parent's bounding
|
||||
// volume; furthermore, traversals like the collision
|
||||
// traversal will still visit the node.
|
||||
//
|
||||
// See stash() for a more thorough way to hide the node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
hide() {
|
||||
@ -1439,3 +1459,61 @@ INLINE void NodePath::
|
||||
hide_collision_solids() {
|
||||
find_all_matches("**/+CollisionNode").hide();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::is_hidden
|
||||
// Access: Public
|
||||
// Description: Returns true if some arc above this bottom node has
|
||||
// been set to 'hide', false if it should be visible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodePath::
|
||||
is_hidden() const {
|
||||
return !get_hidden_ancestor().is_empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::stash
|
||||
// Access: Public
|
||||
// Description: A more thorough version of hide(), this effectively
|
||||
// removes the bottom node from the scene graph--it does
|
||||
// not appear in any traversals, rendering or otherwise,
|
||||
// and cannot be located again via NodePath::find().
|
||||
// The node is also removed from its parents' bounding
|
||||
// volume.
|
||||
//
|
||||
// However, the node is still associated with its
|
||||
// parent, and will be removed if the parent is removed,
|
||||
// and it can be revealed again by a future call to
|
||||
// unstash().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
stash() {
|
||||
nassertv(has_arcs());
|
||||
nassertv(_head != (ArcComponent *)NULL);
|
||||
|
||||
_head->_arc->set_graph_type(NodeRelation::get_stashed_type());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::unstash
|
||||
// Access: Public
|
||||
// Description: Reveals a node that was previously hidden via stash().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
unstash() {
|
||||
nassertv(has_arcs());
|
||||
nassertv(_head != (ArcComponent *)NULL);
|
||||
|
||||
_head->_arc->set_graph_type(_head->_arc->get_type());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::is_stashed
|
||||
// Access: Public
|
||||
// Description: Returns true if some arc above this bottom node has
|
||||
// been set to 'stash', false if it should be visible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodePath::
|
||||
is_stashed() const {
|
||||
return !get_stashed_ancestor().is_empty();
|
||||
}
|
||||
|
@ -122,8 +122,6 @@ bool NodePath::
|
||||
extend_by(NodeRelation *arc) {
|
||||
nassertr(verify_connectivity(), false);
|
||||
nassertr(arc != (NodeRelation *)NULL, false);
|
||||
// Make sure the graph types are consistent.
|
||||
nassertr(arc->get_type() == _graph_type, false);
|
||||
|
||||
if (is_empty()) {
|
||||
nassertr(_head == (ArcComponent *)NULL, false);
|
||||
@ -212,8 +210,8 @@ extend_down_to(Node *dnode) {
|
||||
nassertr(verify_connectivity(), false);
|
||||
NodePathCollection col;
|
||||
FindApproxPath approx_path;
|
||||
approx_path.add_match_many();
|
||||
approx_path.add_match_pointer(dnode);
|
||||
approx_path.add_match_many(0);
|
||||
approx_path.add_match_pointer(dnode, 0);
|
||||
find_matches(col, approx_path, -1);
|
||||
|
||||
if (col.is_empty()) {
|
||||
@ -352,8 +350,8 @@ find_all_paths_down_to(Node *dnode) const {
|
||||
nassertr(verify_connectivity(), col);
|
||||
nassertr(dnode != (Node *)NULL, col);
|
||||
FindApproxPath approx_path;
|
||||
approx_path.add_match_many();
|
||||
approx_path.add_match_pointer(dnode);
|
||||
approx_path.add_match_many(0);
|
||||
approx_path.add_match_pointer(dnode, 0);
|
||||
find_matches(col, approx_path, -1);
|
||||
return col;
|
||||
}
|
||||
@ -485,30 +483,6 @@ get_arc(int index) const {
|
||||
return comp->_arc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_top_node
|
||||
// Access: Public
|
||||
// Description: Returns the top node of the path, or NULL if the path
|
||||
// is empty. This requires iterating through the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *NodePath::
|
||||
get_top_node() const {
|
||||
if (_head == (ArcComponent *)NULL) {
|
||||
// A singleton or empty list.
|
||||
return _top_node;
|
||||
}
|
||||
|
||||
ArcComponent *comp = _head;
|
||||
while (comp->_next != (ArcComponent *)NULL) {
|
||||
comp = comp->_next;
|
||||
}
|
||||
|
||||
// This assertion should not fail unless there is a logic error in
|
||||
// the above.
|
||||
nassertr(comp != (ArcComponent *)NULL, NULL);
|
||||
return comp->_arc->get_parent();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::share_with
|
||||
// Access: Public
|
||||
@ -604,12 +578,6 @@ verify_connectivity() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We also want to verify that all of the arcs are of the proper
|
||||
// type.
|
||||
if (comp->_arc->get_type() != _graph_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
comp = comp->_next;
|
||||
while (comp != (const ArcComponent *)NULL) {
|
||||
Node *next_parent = comp->_arc->get_parent();
|
||||
@ -620,15 +588,21 @@ verify_connectivity() const {
|
||||
if (next_child != parent) {
|
||||
return false;
|
||||
}
|
||||
if (comp->_arc->get_type() != _graph_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parent = next_parent;
|
||||
child = next_child;
|
||||
comp = comp->_next;
|
||||
}
|
||||
|
||||
// We cannot insist that _top_node be correct, since it might have
|
||||
// wandered, particularly if our parent path has changed without our
|
||||
// knowledge.
|
||||
/*
|
||||
if (parent != _top_node) {
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -666,15 +640,6 @@ amputate_badness() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We also want to verify that all of the arcs are of the proper
|
||||
// type.
|
||||
if (comp->_arc->get_type() != _graph_type) {
|
||||
// Eek! The bottom arc is broken!
|
||||
_top_node = child;
|
||||
_head = (ArcComponent *)NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
ArcComponent *prev = comp;
|
||||
comp = comp->_next;
|
||||
while (comp != (const ArcComponent *)NULL) {
|
||||
@ -682,14 +647,12 @@ amputate_badness() {
|
||||
Node *next_child = comp->_arc->get_child();
|
||||
if (next_parent == (Node *)NULL || next_child == (Node *)NULL) {
|
||||
prev->_next = (ArcComponent *)NULL;
|
||||
_top_node = parent;
|
||||
return false;
|
||||
}
|
||||
if (next_child != parent) {
|
||||
prev->_next = (ArcComponent *)NULL;
|
||||
return false;
|
||||
}
|
||||
if (comp->_arc->get_type() != _graph_type) {
|
||||
prev->_next = (ArcComponent *)NULL;
|
||||
_top_node = parent;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -714,6 +677,14 @@ amputate_badness() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodePath::
|
||||
repair_connectivity(const NodePath &top) {
|
||||
// If the only problem is the top node, we can fix that first.
|
||||
reset_top_node();
|
||||
if (verify_connectivity()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nassertr(top.verify_connectivity(), false);
|
||||
|
||||
NodePath new_path(*this);
|
||||
new_path.amputate_badness();
|
||||
if (new_path.is_empty()) {
|
||||
@ -731,6 +702,7 @@ repair_connectivity(const NodePath &top) {
|
||||
}
|
||||
|
||||
(*this) = full_path;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -767,6 +739,7 @@ reparent_to(const NodePath &other, int sort) {
|
||||
// update our own path, as well as all paths that share the same
|
||||
// head pointer (i.e. all paths derived from this one).
|
||||
_head->_next = other._head;
|
||||
_top_node = other._top_node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -832,6 +805,7 @@ instance_to(const NodePath &other, int sort) const {
|
||||
|
||||
NodePath instance(*this);
|
||||
instance._head = new ArcComponent(darc, other._head);
|
||||
instance._top_node = other._top_node;
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ -874,6 +848,7 @@ copy_to(const NodePath &other, int sort) const {
|
||||
|
||||
NodePath instance(*this);
|
||||
instance._head = new ArcComponent(darc, other._head);
|
||||
instance._top_node = other._top_node;
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ -1080,7 +1055,7 @@ int NodePath::
|
||||
flatten_medium() {
|
||||
nassertr(!is_empty(), 0);
|
||||
SceneGraphReducer gr(_graph_type);
|
||||
gr.apply_transitions(node());
|
||||
gr.apply_transitions(arc());
|
||||
int num_removed = gr.flatten(node(), false);
|
||||
|
||||
if (sgmanip_cat.is_debug()) {
|
||||
@ -1112,7 +1087,7 @@ int NodePath::
|
||||
flatten_strong() {
|
||||
nassertr(!is_empty(), 0);
|
||||
SceneGraphReducer gr(_graph_type);
|
||||
gr.apply_transitions(node());
|
||||
gr.apply_transitions(arc());
|
||||
int num_removed = gr.flatten(node(), true);
|
||||
|
||||
if (sgmanip_cat.is_debug()) {
|
||||
@ -2312,17 +2287,6 @@ get_transparency() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::is_hidden
|
||||
// Access: Public
|
||||
// Description: Returns true if some arc above this bottom node has
|
||||
// been set to 'hide', false if it should be visible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodePath::
|
||||
is_hidden() const {
|
||||
return !get_hidden_ancestor().is_empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_hidden_ancestor
|
||||
// Access: Public
|
||||
@ -2351,6 +2315,33 @@ get_hidden_ancestor() const {
|
||||
return next.get_hidden_ancestor();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_stashed_ancestor
|
||||
// Access: Public
|
||||
// Description: Returns a NodePath indicating the lowest arc above
|
||||
// this node which has been set to 'stash'. Calling
|
||||
// unstash() on the NodePath returned by this function
|
||||
// should make the node visible again (unless there is
|
||||
// another arc further up that also has been 'stashed'.
|
||||
//
|
||||
// This function returns an empty NodePath if no
|
||||
// ancestors have been 'stashed'.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NodePath NodePath::
|
||||
get_stashed_ancestor() const {
|
||||
if (!has_arcs()) {
|
||||
return NodePath();
|
||||
}
|
||||
nassertr(_head != (ArcComponent *)NULL, NodePath());
|
||||
if (_head->_arc->get_graph_type() != _graph_type) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
NodePath next(*this);
|
||||
next.shorten();
|
||||
return next.get_stashed_ancestor();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::prepare_scene
|
||||
// Access: Public
|
||||
@ -2450,6 +2441,27 @@ write_bounds(ostream &out) const {
|
||||
get_bounds()->write(out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::reset_top_node
|
||||
// Access: Private
|
||||
// Description: Recomputes the _top_node member to accurately reflect
|
||||
// the top node of the chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
reset_top_node() {
|
||||
if (_head != (ArcComponent *)NULL) {
|
||||
ArcComponent *comp = _head;
|
||||
while (comp->_next != (ArcComponent *)NULL) {
|
||||
comp = comp->_next;
|
||||
}
|
||||
|
||||
// This assertion should not fail unless there is a logic error in
|
||||
// the above.
|
||||
nassertv(comp != (ArcComponent *)NULL);
|
||||
_top_node = comp->_arc->get_parent();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::r_compare_to
|
||||
// Access: Private, Static
|
||||
@ -2513,8 +2525,9 @@ r_as_string(const ArcComponent *comp, string &result, int skip_nodes) const {
|
||||
// Here's the end of the chain.
|
||||
if (skip_nodes == 0) {
|
||||
// Skip no nodes; return the full name.
|
||||
result = format_node_name(comp->_arc->get_parent()) + "/" +
|
||||
format_node_name(comp->_arc->get_child());
|
||||
result = format_node_name(comp->_arc->get_parent());
|
||||
result += format_arc_name(comp->_arc);
|
||||
result += format_node_name(comp->_arc->get_child());
|
||||
|
||||
} else if (skip_nodes == 1) {
|
||||
// Skip the first node.
|
||||
@ -2530,14 +2543,13 @@ r_as_string(const ArcComponent *comp, string &result, int skip_nodes) const {
|
||||
// This is not the first node, so format a slash between the
|
||||
// previous node and this node.
|
||||
|
||||
if (comp->_arc->get_child() == (Node *)NULL ||
|
||||
comp->_arc->get_parent() == comp->_next->_arc->get_child()) {
|
||||
result += "/";
|
||||
} else {
|
||||
if (!(comp->_arc->get_child() == (Node *)NULL ||
|
||||
comp->_arc->get_parent() == comp->_next->_arc->get_child())) {
|
||||
// Unless the path is broken here. In this case, insert a
|
||||
// visual indication of the break.
|
||||
result += "/.../" + format_node_name(comp->_arc->get_parent()) + "/";
|
||||
result += "/.../" + format_node_name(comp->_arc->get_parent());
|
||||
}
|
||||
result += format_arc_name(comp->_arc);
|
||||
result += format_node_name(comp->_arc->get_child());
|
||||
}
|
||||
}
|
||||
@ -2615,6 +2627,28 @@ format_node_name(Node *dnode) const {
|
||||
return name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::format_arc_name
|
||||
// Access: Private
|
||||
// Description: Formats the "name" for the arc in as_string().
|
||||
// Normally, this is simply "/", but for certain arcs
|
||||
// (as for stashed nodes, for instance), it might
|
||||
// contain other characters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string NodePath::
|
||||
format_arc_name(NodeRelation *arc) const {
|
||||
string result = "/";
|
||||
|
||||
if (arc->get_graph_type() == NodeRelation::get_stashed_type()) {
|
||||
result += "@@";
|
||||
|
||||
} else if (arc->get_graph_type() != _graph_type) {
|
||||
result += "@@(" + arc->get_graph_type().get_name() + ")";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::find_matches
|
||||
// Access: Private
|
||||
@ -2685,31 +2719,16 @@ r_find_matches(NodePathCollection &result,
|
||||
FindApproxLevel::Vec::const_iterator li;
|
||||
for (li = level._v.begin(); li != level._v.end(); ++li) {
|
||||
const FindApproxLevelEntry &entry = (*li);
|
||||
|
||||
if (entry.is_solution()) {
|
||||
// Does this entry already represent a solution?
|
||||
result.add_path(entry._node_path);
|
||||
if (max_matches > 0 && result.get_num_paths() >= max_matches) {
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
Node *bottom_node = entry._node_path.node();
|
||||
nassertv(bottom_node != (Node *)NULL);
|
||||
entry.consider_node(result, next_level, max_matches, _graph_type);
|
||||
}
|
||||
|
||||
DownRelations::const_iterator dri;
|
||||
dri = bottom_node->_children.find(_graph_type);
|
||||
if (dri != bottom_node->_children.end()) {
|
||||
const DownRelationPointers &drp = (*dri).second;
|
||||
|
||||
DownRelationPointers::const_iterator drpi;
|
||||
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
|
||||
NodeRelation *arc = (*drpi);
|
||||
entry.consider_next_step(result, arc, next_level, max_matches);
|
||||
if (max_matches > 0 && result.get_num_paths() >= max_matches) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (max_matches > 0 && result.get_num_paths() >= max_matches) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ PUBLISHED:
|
||||
int get_num_arcs() const;
|
||||
NodeRelation *get_arc(int index) const;
|
||||
|
||||
Node *get_top_node() const;
|
||||
INLINE Node *get_top_node();
|
||||
INLINE Node *node() const;
|
||||
INLINE NodeRelation *arc() const;
|
||||
|
||||
@ -442,9 +442,14 @@ PUBLISHED:
|
||||
INLINE void hide();
|
||||
INLINE void show_collision_solids();
|
||||
INLINE void hide_collision_solids();
|
||||
bool is_hidden() const;
|
||||
INLINE bool is_hidden() const;
|
||||
NodePath get_hidden_ancestor() const;
|
||||
|
||||
INLINE void stash();
|
||||
INLINE void unstash();
|
||||
INLINE bool is_stashed() const;
|
||||
NodePath get_stashed_ancestor() const;
|
||||
|
||||
void prepare_scene(GraphicsStateGuardianBase *gsg);
|
||||
|
||||
void show_bounds();
|
||||
@ -466,6 +471,7 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
void reset_top_node();
|
||||
static int r_compare_to(const ArcComponent *a, const ArcComponent *v);
|
||||
bool r_extend_by(const ArcComponent *other);
|
||||
int r_as_string(const ArcComponent *comp, string &result,
|
||||
@ -475,6 +481,7 @@ private:
|
||||
void r_get_net_transitions(const ArcComponent *comp,
|
||||
AllTransitionsWrapper &trans) const;
|
||||
string format_node_name(Node *dnode) const;
|
||||
string format_arc_name(NodeRelation *arc) const;
|
||||
|
||||
void find_matches(NodePathCollection &result,
|
||||
const string &approx_path_str,
|
||||
|
@ -32,8 +32,14 @@ protected:
|
||||
// Most of the interesting part of NodePathBase is inherited from
|
||||
// ArcChain. This gives us a sharable linked list of arcs.
|
||||
|
||||
// The _top_node pointer is only used when the NodePath is a
|
||||
// singleton. If there is at least one arc, this is ignored.
|
||||
// We also add an explicit pointer to the top node in the chain,
|
||||
// mainly to allow us to define a NodePath containing a single node,
|
||||
// even if the chain of arcs is empty.
|
||||
|
||||
// If the chain is nonempty, this might still be useful (int that it
|
||||
// keeps a reference count to the top node), but this is problematic
|
||||
// since it will not automatically update if our parent is changed
|
||||
// without our knowledge.
|
||||
PT_Node _top_node;
|
||||
|
||||
TypeHandle _graph_type;
|
||||
|
@ -348,6 +348,30 @@ hide() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePathCollection::stash
|
||||
// Access: Published
|
||||
// Description: Stashes all NodePaths in the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePathCollection::
|
||||
stash() {
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
get_path(i).stash();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePathCollection::unstash
|
||||
// Access: Published
|
||||
// Description: Unstashes all NodePaths in the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePathCollection::
|
||||
unstash() {
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
get_path(i).unstash();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePathCollection::output
|
||||
// Access: Published
|
||||
|
@ -54,6 +54,8 @@ PUBLISHED:
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
void stash();
|
||||
void unstash();
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
@ -89,7 +89,7 @@ SceneGraphReducer(TypeHandle graph_type) :
|
||||
// operations impossible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void SceneGraphReducer::
|
||||
apply_transitions(Node *root, int transition_types) {
|
||||
apply_transitions(NodeRelation *arc, int transition_types) {
|
||||
AccumulatedTransitions trans;
|
||||
if ((transition_types & TT_transform) != 0) {
|
||||
trans._transform = new TransformTransition;
|
||||
@ -101,20 +101,7 @@ apply_transitions(Node *root, int transition_types) {
|
||||
trans._texture_matrix = new TexMatrixTransition;
|
||||
}
|
||||
|
||||
DownRelations::const_iterator dri;
|
||||
dri = root->_children.find(_graph_type);
|
||||
if (dri != root->_children.end()) {
|
||||
// We must make a temporary copy of the DownRelationPointers,
|
||||
// because we'll be modifying this list as we go.
|
||||
DownRelationPointers drp = (*dri).second;
|
||||
|
||||
DownRelationPointers::const_iterator drpi;
|
||||
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
|
||||
NodeRelation *child_arc = (*drpi);
|
||||
|
||||
r_apply_transitions(child_arc, transition_types, trans, false);
|
||||
}
|
||||
}
|
||||
r_apply_transitions(arc, transition_types, trans, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
TT_texture_matrix = 0x004,
|
||||
};
|
||||
|
||||
void apply_transitions(Node *root, int transition_types = ~0);
|
||||
void apply_transitions(NodeRelation *arc, int transition_types = ~0);
|
||||
|
||||
protected:
|
||||
class AccumulatedTransitions {
|
||||
|
@ -510,7 +510,7 @@ do_rebuild() {
|
||||
|
||||
if (flatten_text) {
|
||||
SceneGraphReducer gr(RenderRelation::get_class_type());
|
||||
gr.apply_transitions(_root);
|
||||
gr.apply_transitions(_root_arc);
|
||||
gr.flatten(_root, true);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user