*** empty log message ***

This commit is contained in:
David Rose 2001-01-13 03:03:33 +00:00
parent e695049e0e
commit 79377c587e
20 changed files with 232 additions and 80 deletions

View File

@ -21,7 +21,7 @@
class EXPCL_PANDA CullLevelState {
public:
CullStateLookup *_lookup;
UpdateSeq _now;
UpdateSeq _as_of;
};
#endif

View File

@ -20,21 +20,24 @@
////////////////////////////////////////////////////////////////////
bool CullState::
check_currency(Node *node, const AllTransitionsWrapper &,
UpdateSeq now) {
UpdateSeq as_of) {
// First, check the verified time stamp.
Verified::iterator vi;
vi = _verified.find(node);
nassertr(vi != _verified.end(), false);
if (vi == _verified.end()) {
// We have never seen this node before.
return false;
}
UpdateSeq verified_stamp = (*vi).second;
if (cull_cat.is_spam()) {
cull_cat.spam()
<< "Checking currency for " << *node << ", verified_stamp = "
<< verified_stamp << " now = " << now << "\n";
<< verified_stamp << " as_of = " << as_of << "\n";
}
if (verified_stamp == now && !verified_stamp.is_fresh()) {
if (as_of <= verified_stamp && !verified_stamp.is_fresh()) {
return true;
}

View File

@ -47,7 +47,7 @@ public:
bool check_currency(Node *node,
const AllTransitionsWrapper &trans,
UpdateSeq now);
UpdateSeq as_of);
INLINE void mark_verified(Node *node, UpdateSeq now);

View File

@ -35,7 +35,7 @@ update(const AllTransitionsWrapper &trans, Node *top_subtree, UpdateSeq now) {
// blow out the cache for all of our children. We do it for now
// just to cut down on things that can go wrong, but this should
// come out of here before long.
clear();
// clear();
_trans = trans;
_parent->compose_trans(_trans, _trans_from_root);

View File

@ -25,11 +25,11 @@ CullStateSubtree::
////////////////////////////////////////////////////////////////////
bool CullStateSubtree::
check_currency(const AllTransitionsWrapper &, Node *top_subtree,
UpdateSeq now) {
UpdateSeq as_of) {
if (cull_cat.is_spam()) {
cull_cat.spam()
<< "Checking currency for subtree " << (void *)this
<< ", _verified = " << _verified << " now = " << now << "\n";
<< ", _verified = " << _verified << " as_of = " << as_of << "\n";
}
// Make sure we've still got the same top_subtree node.
@ -38,7 +38,7 @@ check_currency(const AllTransitionsWrapper &, Node *top_subtree,
}
// First, check the verified time stamp.
if (_verified == now && !_verified.is_fresh()) {
if (as_of <= _verified && !_verified.is_fresh()) {
return true;
}

View File

@ -32,7 +32,7 @@ public:
bool check_currency(const AllTransitionsWrapper &trans,
Node *top_subtree,
UpdateSeq now);
UpdateSeq as_of);
INLINE void update(const AllTransitionsWrapper &trans,
Node *top_subtree,
UpdateSeq now);

View File

@ -107,7 +107,7 @@ INLINE CullStateLookup *CullTraverser::
add_instance(NodeRelation *arc, const AllTransitionsWrapper &trans,
Node *top_subtree, const CullLevelState &level_state) {
return level_state._lookup->get_subtree
(arc, trans, top_subtree, level_state._now);
(arc, trans, top_subtree, level_state._as_of);
}
////////////////////////////////////////////////////////////////////

View File

@ -91,11 +91,12 @@ traverse(Node *root,
bool is_initial = (_nested_count == 0);
if (is_initial) {
if (cull_force_update) {
_now = UpdateSeq::fresh();
_as_of = UpdateSeq::fresh();
} else {
_now = UpdateSeq::initial();
_as_of = UpdateSeq::initial();
}
}
_now = last_graph_update[_graph_type];
_nested_count++;
if (is_initial) {
@ -109,7 +110,7 @@ traverse(Node *root,
CullLevelState level_state;
level_state._lookup = &_lookup;
level_state._now = _now;
level_state._as_of = _as_of;
// Determine the relative transform matrix from the camera to our
// starting node. This is important for proper view-frustum
@ -304,7 +305,7 @@ add_geom_node(GeomNode *node, const AllTransitionsWrapper &trans,
complete_trans.clear_transition(DirectRenderTransition::get_class_type());
CullState *cs = level_state._lookup->find_node
(node, complete_trans, level_state._now);
(node, complete_trans, level_state._as_of);
if (cs == (CullState *)NULL) {
if (cull_cat.is_spam()) {
cull_cat.spam()
@ -316,7 +317,7 @@ add_geom_node(GeomNode *node, const AllTransitionsWrapper &trans,
cs = find_bin_state(complete_trans);
nassertv(cs != (CullState *)NULL);
level_state._lookup->record_node(node, cs, level_state._now);
level_state._lookup->record_node(node, cs, level_state._as_of);
}
cs->record_current_geom_node(arc_chain);
@ -347,14 +348,14 @@ add_direct_node(Node *node, const AllTransitionsWrapper &trans,
complete_trans.clear_transition(DirectRenderTransition::get_class_type());
CullState *cs = level_state._lookup->find_node
(node, complete_trans, level_state._now);
(node, complete_trans, level_state._as_of);
if (cs == (CullState *)NULL) {
// The node didn't have a previously-associated CullState that we
// could use, so determine a new one for it.
cs = find_bin_state(complete_trans);
nassertv(cs != (CullState *)NULL);
level_state._lookup->record_node(node, cs, level_state._now);
level_state._lookup->record_node(node, cs, level_state._as_of);
}
cs->record_current_direct_node(arc_chain);
@ -385,8 +386,8 @@ forward_arc(NodeRelation *arc, NullTransitionWrapper &,
AllTransitionsWrapper trans;
UpdateSeq last_update = arc->get_last_update();
if (level_state._now < last_update) {
level_state._now = last_update;
if (level_state._as_of < last_update) {
level_state._as_of = last_update;
}
bool is_instanced = (node->get_num_parents(_graph_type) > 1);
@ -435,16 +436,17 @@ forward_arc(NodeRelation *arc, NullTransitionWrapper &,
#endif
if (arc_has_sub_render) {
level_state._now = UpdateSeq::fresh();
level_state._as_of = UpdateSeq::fresh();
}
_now = level_state._now;
_as_of = level_state._as_of;
mark_forward_arc(arc);
if (cull_cat.is_spam()) {
cull_cat.spam()
<< "Reached " << *node << ":\n"
<< " now = " << level_state._now
<< " as_of = " << level_state._as_of
<< " now = " << _now
<< " is_instanced = " << is_instanced
<< " is_geom = " << is_geom
<< " node_has_sub_render = " << node_has_sub_render
@ -458,6 +460,7 @@ forward_arc(NodeRelation *arc, NullTransitionWrapper &,
// In any of these cases, we'll need to determine the net
// transition to this node.
wrt_subtree(arc, level_state._lookup->get_top_subtree(),
level_state._as_of, _now,
trans, _graph_type);
}

View File

@ -103,6 +103,7 @@ private:
CullStateLookup _lookup;
int _nested_count;
UpdateSeq _as_of;
UpdateSeq _now;
public:

View File

@ -21,7 +21,8 @@ AllTransitionsWrapper() {
////////////////////////////////////////////////////////////////////
INLINE AllTransitionsWrapper::
AllTransitionsWrapper(const AllTransitionsWrapper &copy) :
_cache(copy._cache)
_cache(copy._cache),
_all_verified(copy._all_verified)
{
}
@ -33,6 +34,7 @@ AllTransitionsWrapper(const AllTransitionsWrapper &copy) :
INLINE void AllTransitionsWrapper::
operator = (const AllTransitionsWrapper &copy) {
_cache = copy._cache;
_all_verified = copy._all_verified;
}
////////////////////////////////////////////////////////////////////
@ -102,11 +104,12 @@ set_transition(TypeHandle handle, NodeTransition *trans) {
if (_cache == (NodeTransitionCache *)NULL) {
_cache = new NodeTransitionCache;
}
_all_verified.clear();
return _cache->set_transition(handle, trans);
}
////////////////////////////////////////////////////////////////////
// Function: AllTransitionsWrapperset_transition
// Function: AllTransitionsWrapper::set_transition
// Access: Public
// Description: This flavor of set_transition() accepts a pointer to
// a NodeTransition only. It infers the type of the
@ -137,6 +140,7 @@ clear_transition(TypeHandle handle) {
if (_cache == (NodeTransitionCache *)NULL) {
return NULL;
}
_all_verified.clear();
return _cache->clear_transition(handle);
}
@ -245,6 +249,7 @@ extract_from(const NodeRelation *arc) {
} else {
_cache = new NodeTransitionCache(arc->_transitions);
}
_all_verified.clear();
}
////////////////////////////////////////////////////////////////////
@ -267,6 +272,7 @@ store_to(NodeRelation *arc) const {
INLINE void AllTransitionsWrapper::
compose_in_place(const AllTransitionsWrapper &other) {
_cache = NodeTransitionCache::compose(_cache, other._cache);
_all_verified.clear();
}
////////////////////////////////////////////////////////////////////
@ -277,6 +283,7 @@ compose_in_place(const AllTransitionsWrapper &other) {
INLINE void AllTransitionsWrapper::
invert_in_place() {
_cache = NodeTransitionCache::invert(_cache);
_all_verified.clear();
}
////////////////////////////////////////////////////////////////////
@ -288,6 +295,7 @@ invert_in_place() {
INLINE void AllTransitionsWrapper::
invert_compose_in_place(const AllTransitionsWrapper &other) {
_cache = NodeTransitionCache::invert_compose(_cache, other._cache);
_all_verified.clear();
}
////////////////////////////////////////////////////////////////////
@ -300,19 +308,63 @@ invert_compose_in_place(const AllTransitionsWrapper &other) {
INLINE Node *AllTransitionsWrapper::
extract_from_cache(const NodeRelation *arc) {
_cache = arc->_net_transitions;
_all_verified = arc->_all_verified;
#ifndef NDEBUG
if (wrt_cat.is_spam()) {
wrt_cat.spam()
<< "AllTransitionsWrapper::extract_from_cache(" << *arc
<< "), _all_verified = " << _all_verified << "\n";
}
#endif
return arc->_top_subtree;
}
////////////////////////////////////////////////////////////////////
// Function: AllTransitionsWrapper::store_to_cache
// Access: Public
// Description:
// Description: Completely replaces the cached state on the arc with
// what is represented here. This makes sense if we
// have computed the complete set of net transitions to
// the arc.
////////////////////////////////////////////////////////////////////
INLINE void AllTransitionsWrapper::
store_to_cache(NodeRelation *arc, Node *top_subtree) {
arc->_top_subtree = top_subtree;
arc->_net_transitions = _cache;
arc->_all_verified = _all_verified;
#ifndef NDEBUG
if (wrt_cat.is_spam()) {
wrt_cat.spam()
<< "AllTransitionsWrapper::store_to_cache(" << *arc
<< "), _all_verified = " << _all_verified << "\n";
}
#endif
}
////////////////////////////////////////////////////////////////////
// Function: AllTransitionsWrapper::store_to_cache_partial
// Access: Public
// Description: Updates the cached state on the arc with what is
// represented here, but does not remove transitions on
// the arc's cache that are not mentioned here. This
// makes sense if this cache represents only some of the
// net transitions to the arc, but not necessarily all
// of them.
////////////////////////////////////////////////////////////////////
INLINE void AllTransitionsWrapper::
store_to_cache_partial(NodeRelation *arc, Node *top_subtree) {
arc->_top_subtree = top_subtree;
arc->_net_transitions =
NodeTransitionCache::c_union(arc->_net_transitions, _cache);
#ifndef NDEBUG
if (wrt_cat.is_spam()) {
wrt_cat.spam()
<< "AllTransitionsWrapper::store_to_cache_partial(" << *arc
<< "), _all_verified = " << _all_verified << "\n";
}
#endif
}
////////////////////////////////////////////////////////////////////
@ -321,10 +373,16 @@ store_to_cache(NodeRelation *arc, Node *top_subtree) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool AllTransitionsWrapper::
is_cache_verified(UpdateSeq) const {
// We can't ever know if all elements in the set are verified,
// because the set might not be complete.
return false;
is_cache_verified(UpdateSeq as_of) const {
#ifndef NDEBUG
if (wrt_cat.is_spam()) {
wrt_cat.spam()
<< "AllTransitionsWrapper::is_cache_verified(" << as_of
<< "), _all_verified = " << _all_verified << ", result = "
<< (as_of <= _all_verified) << "\n";
}
#endif
return as_of <= _all_verified;
}
////////////////////////////////////////////////////////////////////
@ -335,6 +393,14 @@ is_cache_verified(UpdateSeq) const {
INLINE void AllTransitionsWrapper::
set_computed_verified(UpdateSeq now) {
_cache = NodeTransitionCache::set_computed_verified(_cache, now);
_all_verified = now;
#ifndef NDEBUG
if (wrt_cat.is_spam()) {
wrt_cat.spam()
<< "AllTransitionsWrapper::set_computed_verified(" << now << ")\n";
}
#endif
}
////////////////////////////////////////////////////////////////////
@ -350,6 +416,7 @@ cached_compose(const AllTransitionsWrapper &cache,
UpdateSeq now) {
_cache = NodeTransitionCache::cached_compose(_cache, cache._cache,
value._cache, now);
_all_verified = now;
}
////////////////////////////////////////////////////////////////////

View File

@ -23,6 +23,7 @@
#include "nodeTransition.h"
#include "nodeTransitionCache.h"
#include "config_graph.h"
#include <pointerTo.h>
@ -76,7 +77,8 @@ public:
INLINE Node *extract_from_cache(const NodeRelation *arc);
INLINE void store_to_cache(NodeRelation *arc, Node *top_subtree);
INLINE bool is_cache_verified(UpdateSeq now) const;
INLINE void store_to_cache_partial(NodeRelation *arc, Node *top_subtree);
INLINE bool is_cache_verified(UpdateSeq as_of) const;
INLINE void set_computed_verified(UpdateSeq now);
INLINE void cached_compose(const AllTransitionsWrapper &cache,
@ -104,6 +106,7 @@ public:
private:
PT(NodeTransitionCache) _cache;
UpdateSeq _all_verified;
// This is a special cache object which is always around and always
// empty. It's used just so we can have a sensible return value

View File

@ -442,15 +442,33 @@ attach() {
nassertv(!_attached);
_attached = true;
DownRelationPointers &parent_list = _parent->_children[_type];
UpRelationPointers &child_list = _child->_parents[_type];
bool inserted_one = internal_insert_arc(_parent->_children[_type], this);
bool inserted_two = internal_insert_arc(_child->_parents[_type], this);
bool inserted_one = internal_insert_arc(parent_list, this);
bool inserted_two = internal_insert_arc(child_list, this);
nassertv(inserted_one && inserted_two);
// Blow out the cache and increment the current update sequence.
_net_transitions.clear();
_last_update = ++last_graph_update[_type];
/*
// If we have just added a new parent arc to a node that previously
// had exactly one parent, we also need to increment the update
// counter for all the children of that node.
if (child_list.size() == 2) {
cerr << "Attaching " << *this << " at " << _last_update << "\n";
DownRelationPointers &child_children = _child->_children[_type];
DownRelationPointers::iterator drpi;
for (drpi = child_children.begin(); drpi != child_children.end(); ++drpi) {
cerr << "Forcing update for " << *(*drpi) << "\n";
(*drpi)->_last_update = _last_update;
}
}
*/
_parent->force_bound_stale();
mark_bound_stale();
}
@ -481,8 +499,11 @@ detach() {
force_bound_stale();
bool removed_one = internal_remove_arc(_parent->_children[_type], this);
bool removed_two = internal_remove_arc(_child->_parents[_type], this);
DownRelationPointers &parent_list = _parent->_children[_type];
UpRelationPointers &child_list = _child->_parents[_type];
bool removed_one = internal_remove_arc(parent_list, this);
bool removed_two = internal_remove_arc(child_list, this);
nassertr(removed_one, result);
nassertr(removed_two, result);
@ -493,6 +514,19 @@ detach() {
_net_transitions.clear();
_last_update = ++last_graph_update[_type];
/*
// If we have just removed a parent arc from a node, leaving exactly
// one parent, we also need to increment the update counter for all
// the children of that node.
if (child_list.size() == 1) {
DownRelationPointers &child_children = _child->_children[_type];
DownRelationPointers::iterator drpi;
for (drpi = child_children.begin(); drpi != child_children.end(); ++drpi) {
(*drpi)->_last_update = _last_update;
}
}
*/
return result;
}

View File

@ -156,6 +156,11 @@ private:
PT(NodeTransitionCache) _net_transitions;
Node *_top_subtree;
// This is updated with the current update sequence whenever we
// verify that *all* the transitions to this arc are accurately
// reflected in the above set.
UpdateSeq _all_verified;
// This is updated with the current update sequence each time the
// arc is changed (for instance, to change its state or to reparent
// it or something). It exists to support caching in the cull

View File

@ -390,7 +390,11 @@ invert_compose(const NodeTransitionCache *a, const NodeTransitionCache *b) {
////////////////////////////////////////////////////////////////////
// Function: NodeTransitionCache::cached_compose
// Access: Public, Static
// Description:
// Description: Returns a cache pointer (which might be a pointer to
// the same cache object, or to a newly allocated
// object) that represents the result of compose(a, b),
// as computed using the cache value as a hint. Mark
// the result as computed at time 'now'.
////////////////////////////////////////////////////////////////////
NodeTransitionCache *NodeTransitionCache::
cached_compose(const NodeTransitionCache *a,
@ -440,7 +444,8 @@ cached_compose(const NodeTransitionCache *a,
// Description: Returns a new pointer that represents the adjustment
// of the given cache to set each computed and verified
// value to the current now value. This may modify the
// source cache only if there is only one pointer to it.
// source cache only if there are no other pointers to
// it.
////////////////////////////////////////////////////////////////////
NodeTransitionCache *NodeTransitionCache::
set_computed_verified(const NodeTransitionCache *a, UpdateSeq now) {

View File

@ -142,8 +142,16 @@ get_trans() const {
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool NodeTransitionCacheEntry::
is_cache_verified(UpdateSeq now) const {
return _verified == now;
is_cache_verified(UpdateSeq as_of) const {
#ifndef NDEBUG
if (wrt_cat.is_spam()) {
wrt_cat.spam()
<< "NodeTransitionCacheEntry::is_cache_verified(" << as_of
<< "), _verified = " << _verified << ", result = "
<< (as_of <= _verified) << "\n";
}
#endif
return as_of <= _verified;
}
////////////////////////////////////////////////////////////////////
@ -275,7 +283,8 @@ invert_compose(const NodeTransitionCacheEntry &a,
// Function: NodeTransitionCacheEntry::cached_compose
// Access: Public, Static
// Description: Sets this cache entry to the result of compose(a, b),
// as computed using the cache value as a hint.
// as computed using the cache value as a hint. Mark
// the result as computed at time 'now'.
////////////////////////////////////////////////////////////////////
INLINE NodeTransitionCacheEntry NodeTransitionCacheEntry::
cached_compose(const NodeTransitionCacheEntry &a,

View File

@ -9,6 +9,7 @@
#include <pandabase.h>
#include "nodeTransition.h"
#include "config_graph.h"
#include <updateSeq.h>
#include <pointerTo.h>
@ -35,7 +36,7 @@ public:
INLINE bool has_trans() const;
INLINE NodeTransition *get_trans() const;
INLINE bool is_cache_verified(UpdateSeq now) const;
INLINE bool is_cache_verified(UpdateSeq as_of) const;
INLINE bool is_freshly_computed(UpdateSeq changed) const;
INLINE void set_computed_verified(UpdateSeq now);

View File

@ -214,8 +214,8 @@ store_to_cache(NodeRelation *arc, Node *top_subtree) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool NodeTransitionWrapper::
is_cache_verified(UpdateSeq now) const {
return _entry.is_cache_verified(now);
is_cache_verified(UpdateSeq as_of) const {
return _entry.is_cache_verified(as_of);
}
////////////////////////////////////////////////////////////////////

View File

@ -66,7 +66,7 @@ public:
INLINE Node *extract_from_cache(const NodeRelation *arc);
INLINE void store_to_cache(NodeRelation *arc, Node *top_subtree);
INLINE bool is_cache_verified(UpdateSeq now) const;
INLINE bool is_cache_verified(UpdateSeq as_of) const;
INLINE void set_computed_verified(UpdateSeq now);
INLINE void cached_compose(const NodeTransitionWrapper &cache,

View File

@ -21,15 +21,20 @@
// transitions returned by this function, the result is
// always unambiguous; any wrt() ambiguity is resolved
// later.
//
// as_of is the most recent update so far on this branch
// of the scene graph; now is the stamp to use to mark
// any computed cache values.
////////////////////////////////////////////////////////////////////
template<class TransitionWrapper>
void
get_cached_net_transition(NodeRelation *arc, Node *&root, UpdateSeq now,
get_cached_net_transition(NodeRelation *arc, Node *&root,
UpdateSeq as_of, UpdateSeq now,
TransitionWrapper &net, TypeHandle graph_type) {
TransitionWrapper cur_cache = TransitionWrapper::init_from(net);
Node *top_subtree = cur_cache.extract_from_cache(arc);
if (cur_cache.is_cache_verified(now)) {
if (cur_cache.is_cache_verified(as_of)) {
// This arc's cached value has recently been verified, so we don't
// even need to go anywhere--we trust it's still good.
root = top_subtree;
@ -45,7 +50,11 @@ get_cached_net_transition(NodeRelation *arc, Node *&root, UpdateSeq now,
wrt_cat.debug(false) << *root;
}
wrt_cat.debug(false)
<< ") is current as of " << now << "\n";
<< ") is current as of " << as_of << " (now is "
<< now << ")\n";
if (wrt_cat.is_spam()) {
wrt_cat.spam() << "result of " << *arc << " is " << net << "\n";
}
}
#endif
@ -83,7 +92,7 @@ get_cached_net_transition(NodeRelation *arc, Node *&root, UpdateSeq now,
// The node has exactly one parent. Carry on.
NodeRelation *parent = *(*uri).second.begin();
get_cached_net_transition(parent, root, now, net, graph_type);
get_cached_net_transition(parent, root, as_of, now, net, graph_type);
// Now recompute our own cache.
TransitionWrapper cur_value = TransitionWrapper::init_from(net);
@ -103,7 +112,11 @@ get_cached_net_transition(NodeRelation *arc, Node *&root, UpdateSeq now,
wrt_cat.debug(false) << *root;
}
wrt_cat.debug(false)
<< ") is recomputed as of " << now << "\n";
<< ") is recomputed as of " << as_of << " (now is "
<< now << ")\n";
if (wrt_cat.is_spam()) {
wrt_cat.spam() << "result of " << *arc << " is " << net << "\n";
}
}
#endif
}
@ -120,13 +133,17 @@ get_cached_net_transition(NodeRelation *arc, Node *&root, UpdateSeq now,
// contains a list of NodeRelation pointers to resolve
// ambiguities when a node with multiple parents is
// encountered.
//
// as_of is the most recent update so far on this branch
// of the scene graph; now is the stamp to use to mark
// any computed cache values.
////////////////////////////////////////////////////////////////////
template<class InputIterator, class TransitionWrapper>
void
get_cached_net_transition(const Node *node,
InputIterator arc_list_begin,
InputIterator arc_list_end,
UpdateSeq now,
UpdateSeq as_of, UpdateSeq now,
TransitionWrapper &result,
TypeHandle graph_type) {
if (node == NULL) {
@ -219,15 +236,15 @@ get_cached_net_transition(const Node *node,
// Get the net transition leading into this node.
Node *root;
get_cached_net_transition((NodeRelation *)parent_arc, root, now, result,
graph_type);
get_cached_net_transition((NodeRelation *)parent_arc, root,
as_of, now, result, graph_type);
if (root != NULL) {
// There's more to get. The above function call was forced to
// stop at a node with multiple parents.
TransitionWrapper more = TransitionWrapper::init_from(result);
get_cached_net_transition(root, arc_list_begin, arc_list_end,
now, more, graph_type);
as_of, now, more, graph_type);
more.compose_in_place(result);
result = more;
}
@ -396,14 +413,15 @@ cached_wrt_base(const Node *from,
wrt_cat.debug(false) << *to;
}
wrt_cat.debug(false)
<< "), as of " << now << "\n";
<< "), as of " << now << " (now is "
<< now << ")\n";
}
#endif
get_cached_net_transition(from, from_arcs_begin, from_arcs_end, now,
net_from_trans, graph_type);
get_cached_net_transition(to, to_arcs_begin, to_arcs_end, now,
result, graph_type);
get_cached_net_transition(from, from_arcs_begin, from_arcs_end,
now, now, net_from_trans, graph_type);
get_cached_net_transition(to, to_arcs_begin, to_arcs_end,
now, now, result, graph_type);
#ifndef NDEBUG
if (paranoid_wrt) {
@ -686,8 +704,8 @@ get_uncached_wrt_subtree(Node *node, Node *to, TransitionWrapper &result,
template<class TransitionWrapper>
INLINE Node *
uncached_wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
TypeHandle graph_type) {
uncached_wrt_subtree(NodeRelation *arc, Node *to,
TransitionWrapper &result, TypeHandle graph_type) {
Node *stop =
get_uncached_wrt_subtree(arc->get_parent(), to,
result, graph_type);
@ -717,14 +735,12 @@ uncached_wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
template<class TransitionWrapper>
Node *
cached_wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
TypeHandle graph_type) {
UpdateSeq now = last_graph_update[graph_type];
cached_wrt_subtree(NodeRelation *arc, Node *to, UpdateSeq as_of, UpdateSeq now,
TransitionWrapper &result, TypeHandle graph_type) {
// First, determine the net transition up to the top of the current
// subtree.
Node *top_subtree;
get_cached_net_transition(arc, top_subtree, now, result, graph_type);
get_cached_net_transition(arc, top_subtree, as_of, now, result, graph_type);
if (top_subtree == to || to == (Node *)NULL) {
// If the top of the subtree is the node we asked to wrt to,
@ -749,12 +765,6 @@ cached_wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
// Otherwise, it must be the case that the node we want to wrt to is
// some descendent of the top_subtree node. It also therefore
// follows that this node has exactly one parent.
nassertr(to->get_num_parents(graph_type) == 1, NULL);
NodeRelation *to_arc = to->get_parent(graph_type, 0);
// Save the result from the first pass.
TransitionWrapper net_from_trans = result;
#ifndef NDEBUG
if (wrt_cat.is_spam()) {
@ -765,15 +775,22 @@ cached_wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
} else {
wrt_cat.spam(false) << *top_subtree;
}
wrt_cat.spam() << ", first result is:\n";
wrt_cat.spam(false) << ", first result is:\n";
result.write(wrt_cat.spam(false), 2);
}
#endif
nassertr(to->get_num_parents(graph_type) == 1, NULL);
NodeRelation *to_arc = to->get_parent(graph_type, 0);
// Save the result from the first pass.
TransitionWrapper net_from_trans = result;
// Now determine the net transition to the top of the subtree from
// this arc. It had better be the same subtree!
Node *top_subtree_2;
get_cached_net_transition(to_arc, top_subtree_2, now, result, graph_type);
get_cached_net_transition(to_arc, top_subtree_2, as_of, now,
result, graph_type);
nassertr(top_subtree == top_subtree_2, NULL);
// And now compute the actual wrt.
@ -855,15 +872,15 @@ cached_wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
template<class TransitionWrapper>
INLINE Node *
wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
TypeHandle graph_type) {
wrt_subtree(NodeRelation *arc, Node *to, UpdateSeq as_of, UpdateSeq now,
TransitionWrapper &result, TypeHandle graph_type) {
#ifndef NDEBUG
if (!cache_wrt) {
// If we aren't caching wrt, do this the hard way.
// If we aren't caching wrt, compute it explicitly.
return uncached_wrt_subtree(arc, to, result, graph_type);
}
#endif
return cached_wrt_subtree(arc, to, result, graph_type);
return cached_wrt_subtree(arc, to, as_of, now, result, graph_type);
}

View File

@ -118,10 +118,14 @@ uncached_wrt(const Node *from,
// general utility; it is of primary interest to code (like the
// CullTraverser) that needs to cache a wrt-type value for many nodes
// across the entire tree.
// as_of is the most recent update between 'arc' and 'to'; now is the
// current most recent update sequence anywhere, used to use to mark
// any computed cache values.
template<class TransitionWrapper>
INLINE Node *
wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
TypeHandle graph_type);
wrt_subtree(NodeRelation *arc, Node *to, UpdateSeq as_of, UpdateSeq now,
TransitionWrapper &result, TypeHandle graph_type);
#include "wrt.I"