mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
*** empty log message ***
This commit is contained in:
parent
7a110a31cd
commit
faa13d10e5
@ -66,6 +66,7 @@ public:
|
||||
_data_root(data_root),
|
||||
_initial_state(initial_state),
|
||||
_app_traverser(RenderRelation::get_class_type()) { }
|
||||
virtual ~WindowCallback() { }
|
||||
|
||||
virtual void draw(bool) {
|
||||
_app_traverser.traverse(_render);
|
||||
@ -156,7 +157,7 @@ PT(GraphicsWindow) make_graphics_window(GraphicsPipe *pipe,
|
||||
// can contain 2-d geometry and will be rendered on top of the
|
||||
// existing 3-d window. Returns the top node of the scene graph.
|
||||
NodePath
|
||||
setup_panda_2d(PT(GraphicsWindow) win) {
|
||||
setup_panda_2d(GraphicsWindow *win) {
|
||||
PT(Node) render2d_top;
|
||||
|
||||
render2d_top = new NamedNode("render2d_top");
|
||||
@ -165,6 +166,12 @@ setup_panda_2d(PT(GraphicsWindow) win) {
|
||||
|
||||
// Set up some overrides to turn off certain properties which we
|
||||
// probably won't need for 2-d objects.
|
||||
|
||||
// It's particularly important to turn off the depth test, since
|
||||
// we'll be keeping the same depth buffer already filled by the
|
||||
// previously-drawn 3-d scene--we don't want to pay for a clear
|
||||
// operation, but we also don't want to collide with that depth
|
||||
// buffer.
|
||||
render2d_arc->set_transition(new DepthTestTransition(DepthTestProperty::M_none), 1);
|
||||
render2d_arc->set_transition(new DepthWriteTransition(DepthWriteTransition::off()), 1);
|
||||
render2d_arc->set_transition(new LightTransition(LightTransition::all_off()), 1);
|
||||
@ -174,26 +181,32 @@ setup_panda_2d(PT(GraphicsWindow) win) {
|
||||
// Create a 2-d camera.
|
||||
Camera *cam2d = new Camera("cam2d");
|
||||
new RenderRelation(render2d, cam2d);
|
||||
cam2d->set_scene(render2d_top);
|
||||
|
||||
Frustumf frustum2d;
|
||||
frustum2d.make_ortho(-1000,1000);
|
||||
cam2d->set_projection(OrthoProjection(frustum2d));
|
||||
|
||||
// Now create a new layer.
|
||||
GraphicsChannel *chan = win->get_channel(0);
|
||||
nassertr(chan != (GraphicsChannel *)NULL, NodePath());
|
||||
|
||||
GraphicsLayer *layer = chan->make_layer();
|
||||
nassertr(layer != (GraphicsLayer *)NULL, NodePath());
|
||||
|
||||
DisplayRegion *dr = layer->make_display_region();
|
||||
nassertr(dr != (DisplayRegion *)NULL, NodePath());
|
||||
dr->set_camera(cam2d);
|
||||
add_render_layer(win, render2d_top, cam2d);
|
||||
|
||||
return NodePath(render2d_arc);
|
||||
}
|
||||
|
||||
// Create an auxiliary scene graph starting at the indicated node,
|
||||
// layered on top of the previously-created layers.
|
||||
void
|
||||
add_render_layer(GraphicsWindow *win, Node *render_top, Camera *camera) {
|
||||
GraphicsChannel *chan = win->get_channel(0);
|
||||
nassertv(chan != (GraphicsChannel *)NULL);
|
||||
|
||||
GraphicsLayer *layer = chan->make_layer();
|
||||
nassertv(layer != (GraphicsLayer *)NULL);
|
||||
|
||||
DisplayRegion *dr = layer->make_display_region();
|
||||
nassertv(dr != (DisplayRegion *)NULL);
|
||||
camera->set_scene(render_top);
|
||||
dr->set_camera(camera);
|
||||
}
|
||||
|
||||
// Enable the collision traversal using a particular traverser.
|
||||
void set_collision_traverser(CollisionTraverser *traverser) {
|
||||
collision_traverser = traverser;
|
||||
|
@ -17,16 +17,11 @@
|
||||
#include <nodePath.h>
|
||||
#include <dconfig.h>
|
||||
|
||||
#define testint 1
|
||||
#define testfloat 1.2345
|
||||
#define testcstring "testcstring"
|
||||
#include <string>
|
||||
#define teststring string("teststring")
|
||||
|
||||
ConfigureDecl(config_showbase, EXPCL_DIRECT, EXPTP_DIRECT);
|
||||
typedef Config::Config<ConfigureGetConfig_config_showbase> ConfigShowbase;
|
||||
|
||||
class CollisionTraverser;
|
||||
class Camera;
|
||||
|
||||
BEGIN_PUBLISH
|
||||
|
||||
@ -39,7 +34,9 @@ EXPCL_DIRECT PT(GraphicsWindow)
|
||||
NodeAttributes &initial_state
|
||||
);
|
||||
|
||||
EXPCL_DIRECT NodePath setup_panda_2d(PT(GraphicsWindow) win);
|
||||
EXPCL_DIRECT NodePath setup_panda_2d(GraphicsWindow *win);
|
||||
EXPCL_DIRECT void add_render_layer(GraphicsWindow *win, Node *render_top,
|
||||
Camera *camera);
|
||||
|
||||
EXPCL_DIRECT void set_collision_traverser(CollisionTraverser *traverser);
|
||||
EXPCL_DIRECT CollisionTraverser *get_collision_traverser();
|
||||
|
@ -128,6 +128,6 @@ get_direction() const {
|
||||
// the screen given a camera and a mouse location.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CollisionRay::
|
||||
set_projection(const ProjectionNode *camera, float px, float py) {
|
||||
set_projection(ProjectionNode *camera, float px, float py) {
|
||||
return set_projection(camera, LPoint2f(px, py));
|
||||
}
|
||||
|
@ -75,8 +75,8 @@ output(ostream &out) const {
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CollisionRay::
|
||||
set_projection(const ProjectionNode *camera, const LPoint2f &point) {
|
||||
const Projection *proj = camera->get_projection();
|
||||
set_projection(ProjectionNode *camera, const LPoint2f &point) {
|
||||
Projection *proj = camera->get_projection();
|
||||
|
||||
bool success = true;
|
||||
if (!proj->extrude(point, _origin, _direction)) {
|
||||
|
@ -49,8 +49,8 @@ PUBLISHED:
|
||||
INLINE void set_direction(float x, float y, float z);
|
||||
INLINE const LVector3f &get_direction() const;
|
||||
|
||||
bool set_projection(const ProjectionNode *camera, const LPoint2f &point);
|
||||
INLINE bool set_projection(const ProjectionNode *camera, float px, float py);
|
||||
bool set_projection(ProjectionNode *camera, const LPoint2f &point);
|
||||
INLINE bool set_projection(ProjectionNode *camera, float px, float py);
|
||||
|
||||
protected:
|
||||
virtual void recompute_bound();
|
||||
|
@ -33,3 +33,7 @@ ConfigureFn(config_cull) {
|
||||
DirectRenderTransition::init_type();
|
||||
}
|
||||
|
||||
// Set this true to force all of the caching to blow itself away every
|
||||
// frame. Normally you would only do this during testing.
|
||||
const bool cull_force_update = config_cull.GetBool("cull-force-update", false);
|
||||
|
||||
|
@ -11,4 +11,6 @@
|
||||
|
||||
NotifyCategoryDecl(cull, EXPCL_PANDA, EXPTP_PANDA);
|
||||
|
||||
extern const bool cull_force_update;
|
||||
|
||||
#endif
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "cullStateLookup.h"
|
||||
|
||||
#include <updateSeq.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CullLevelState
|
||||
// Description : This is the state information the
|
||||
@ -19,6 +21,7 @@
|
||||
class EXPCL_PANDA CullLevelState {
|
||||
public:
|
||||
CullStateLookup *_lookup;
|
||||
UpdateSeq _now;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -79,8 +79,13 @@ clear_current_nodes() {
|
||||
// be visible this frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CullState::
|
||||
record_current_geom_node(const PT(GeomNode) &node) {
|
||||
_current_geom_nodes.push_back(node);
|
||||
record_current_geom_node(const ArcChain &arc_chain) {
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "Recording geom node " << arc_chain << " with state " << (void *)this
|
||||
<< "\n";
|
||||
}
|
||||
_current_geom_nodes.push_back(arc_chain);
|
||||
_empty_frames_count = 0;
|
||||
}
|
||||
|
||||
@ -92,8 +97,8 @@ record_current_geom_node(const PT(GeomNode) &node) {
|
||||
// visible this frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CullState::
|
||||
record_current_direct_node(const PT_Node &node) {
|
||||
_current_direct_nodes.push_back(node);
|
||||
record_current_direct_node(const ArcChain &arc_chain) {
|
||||
_current_direct_nodes.push_back(arc_chain);
|
||||
_empty_frames_count = 0;
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cullState.h"
|
||||
#include "config_cull.h"
|
||||
|
||||
#include <indent.h>
|
||||
#include <graphicsStateGuardian.h>
|
||||
@ -26,7 +27,14 @@ check_currency(Node *node, const AllTransitionsWrapper &,
|
||||
nassertr(vi != _verified.end(), false);
|
||||
|
||||
UpdateSeq verified_stamp = (*vi).second;
|
||||
if (verified_stamp == now) {
|
||||
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "Checking currency for " << *node << ", verified_stamp = "
|
||||
<< verified_stamp << " now = " << now << "\n";
|
||||
}
|
||||
|
||||
if (verified_stamp == now && !verified_stamp.is_fresh()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -63,10 +71,10 @@ write(ostream &out, int indent_level) const {
|
||||
if (!_current_geom_nodes.empty()) {
|
||||
CurrentGeomNodes::const_iterator ci;
|
||||
ci = _current_geom_nodes.begin();
|
||||
out << " (" << *(*ci);
|
||||
out << " (" << (*ci);
|
||||
++ci;
|
||||
while (ci != _current_geom_nodes.end()) {
|
||||
out << ", " << *(*ci);
|
||||
out << ", " << (*ci);
|
||||
++ci;
|
||||
}
|
||||
out << ")";
|
||||
@ -77,10 +85,10 @@ write(ostream &out, int indent_level) const {
|
||||
if (!_current_direct_nodes.empty()) {
|
||||
CurrentDirectNodes::const_iterator ci;
|
||||
ci = _current_direct_nodes.begin();
|
||||
out << " (" << *(*ci);
|
||||
out << " (" << (*ci);
|
||||
++ci;
|
||||
while (ci != _current_direct_nodes.end()) {
|
||||
out << ", " << *(*ci);
|
||||
out << ", " << (*ci);
|
||||
++ci;
|
||||
}
|
||||
out << ")";
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include <pandabase.h>
|
||||
|
||||
#include "config_cull.h"
|
||||
|
||||
#include <geomNode.h>
|
||||
#include <allTransitionsWrapper.h>
|
||||
#include <allAttributesWrapper.h>
|
||||
@ -15,10 +17,10 @@
|
||||
#include <pointerToArray.h>
|
||||
#include <updateSeq.h>
|
||||
#include <referenceCount.h>
|
||||
#include <pt_Node.h>
|
||||
#include <vector_PT_Node.h>
|
||||
#include <arcChain.h>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class GraphicsStateGuardian;
|
||||
class GeomBin;
|
||||
@ -34,8 +36,8 @@ class GeomBin;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA CullState : public ReferenceCount {
|
||||
public:
|
||||
typedef vector<PT(GeomNode)> CurrentGeomNodes;
|
||||
typedef vector_PT_Node CurrentDirectNodes;
|
||||
typedef vector<ArcChain> CurrentGeomNodes;
|
||||
typedef vector<ArcChain> CurrentDirectNodes;
|
||||
|
||||
public:
|
||||
INLINE CullState(const AllTransitionsWrapper &trans);
|
||||
@ -50,8 +52,8 @@ public:
|
||||
INLINE void mark_verified(Node *node, UpdateSeq now);
|
||||
|
||||
INLINE void clear_current_nodes();
|
||||
INLINE void record_current_geom_node(const PT(GeomNode) &node);
|
||||
INLINE void record_current_direct_node(const PT_Node &node);
|
||||
INLINE void record_current_geom_node(const ArcChain &arc_chain);
|
||||
INLINE void record_current_direct_node(const ArcChain &arc_chain);
|
||||
INLINE bool is_empty() const;
|
||||
INLINE int count_current_nodes() const;
|
||||
INLINE int get_empty_frames_count() const;
|
||||
|
@ -50,20 +50,36 @@ CullState *CullStateLookup::
|
||||
find_node(Node *node,
|
||||
const AllTransitionsWrapper &trans,
|
||||
UpdateSeq now) {
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "Looking up " << *node << " in lookup " << (void *)this << "\n";
|
||||
}
|
||||
CullStates::iterator csi;
|
||||
csi = _cull_states.find(node);
|
||||
if (csi == _cull_states.end()) {
|
||||
// No entry for the node.
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "No entry for the node.\n";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CullState *cs = (*csi).second;
|
||||
if (cs->check_currency(node, trans, now)) {
|
||||
// The entry is current enough to use.
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "The entry is found and current.\n";
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
// The entry is stale; remove it and return NULL.
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "The entry is stale.\n";
|
||||
}
|
||||
_cull_states.erase(csi);
|
||||
return NULL;
|
||||
}
|
||||
@ -94,10 +110,19 @@ get_subtree(const PT(NodeRelation) &arc,
|
||||
const AllTransitionsWrapper &trans,
|
||||
Node *top_subtree,
|
||||
UpdateSeq now) {
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "Getting subtree for " << *arc << " in lookup "
|
||||
<< (void *)this << "\n";
|
||||
}
|
||||
Subtrees::iterator si;
|
||||
si = _subtrees.find(arc);
|
||||
if (si == _subtrees.end()) {
|
||||
// No entry for the arc.
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "No entry for the arc; creating new one.\n";
|
||||
}
|
||||
CullStateSubtree *subtree =
|
||||
new CullStateSubtree(this, trans, top_subtree, now);
|
||||
_subtrees.insert(Subtrees::value_type(arc, subtree));
|
||||
@ -107,10 +132,18 @@ get_subtree(const PT(NodeRelation) &arc,
|
||||
CullStateSubtree *subtree = (*si).second;
|
||||
if (subtree->check_currency(trans, top_subtree, now)) {
|
||||
// The entry is current enough to use.
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "The entry is found and current.\n";
|
||||
}
|
||||
return subtree;
|
||||
}
|
||||
|
||||
// The entry is stale; update it.
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "The entry is stale.\n";
|
||||
}
|
||||
subtree->update(trans, top_subtree, now);
|
||||
return subtree;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cullStateSubtree.h"
|
||||
#include "config_cull.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -25,13 +26,19 @@ CullStateSubtree::
|
||||
bool CullStateSubtree::
|
||||
check_currency(const AllTransitionsWrapper &, Node *top_subtree,
|
||||
UpdateSeq now) {
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "Checking currency for subtree " << (void *)this
|
||||
<< ", _verified = " << _verified << " now = " << now << "\n";
|
||||
}
|
||||
|
||||
// Make sure we've still got the same top_subtree node.
|
||||
if (_top_subtree != top_subtree) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// First, check the verified time stamp.
|
||||
if (_verified == now) {
|
||||
if (_verified == now && !_verified.is_fresh()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,22 @@ draw_geom(GeomNode *geom_node, const AllAttributesWrapper &initial_state) {
|
||||
geom_node->draw(_gsg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverser::draw_geom
|
||||
// Access: Public
|
||||
// Description: Sets up the GSG to draw the indicated GeomNode in the
|
||||
// indicated state. If the state so demands it and the
|
||||
// GeomNode has children, draws the rest of the
|
||||
// hierarchy below it immediately.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CullTraverser::
|
||||
draw_geom(const ArcChain &arc_chain, const AllAttributesWrapper &initial_state) {
|
||||
nassertv(!arc_chain.empty());
|
||||
GeomNode *geom_node;
|
||||
DCAST_INTO_V(geom_node, arc_chain.back()->get_child());
|
||||
draw_geom(geom_node, initial_state);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverser::draw_direct
|
||||
// Access: Public
|
||||
@ -63,13 +79,16 @@ draw_geom(GeomNode *geom_node, const AllAttributesWrapper &initial_state) {
|
||||
// indicated node, and including all nested nodes below.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CullTraverser::
|
||||
draw_direct(Node *node, const AllAttributesWrapper &initial_state) {
|
||||
draw_direct(const ArcChain &arc_chain,
|
||||
const AllAttributesWrapper &initial_state) {
|
||||
nassertv(!arc_chain.empty());
|
||||
Node *node = arc_chain.back()->get_child();
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "Drawing " << *node << " in direct mode.\n";
|
||||
}
|
||||
nassertv(node != (Node *)NULL);
|
||||
DirectRenderTraverser drt(_gsg, _graph_type);
|
||||
DirectRenderTraverser drt(_gsg, _graph_type, arc_chain);
|
||||
drt.traverse(node, initial_state, AllTransitionsWrapper());
|
||||
}
|
||||
|
||||
@ -87,14 +106,15 @@ draw_direct(Node *node, const AllAttributesWrapper &initial_state) {
|
||||
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, _now);
|
||||
return level_state._lookup->get_subtree
|
||||
(arc, trans, top_subtree, level_state._now);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverser::find_bin_state
|
||||
// Access: Private
|
||||
// Description: Looks for a CullState in the set that corresponds to
|
||||
// the indicates set of transitions; if one is found,
|
||||
// the indicated set of transitions; if one is found,
|
||||
// returns its pointer; otherwise, creates a new one and
|
||||
// returns it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -108,14 +128,32 @@ find_bin_state(const AllTransitionsWrapper &trans) {
|
||||
// corresponding CullState that is (now) stored in the set.
|
||||
pair<States::iterator, bool> result = _states.insert(cs);
|
||||
|
||||
/*
|
||||
if (result.second) {
|
||||
// The insert succeeded, so the CullState was not there
|
||||
// previously.
|
||||
cerr << "Created CullState for:\n";
|
||||
trans.write(cerr, 2);
|
||||
if (cull_cat.is_spam()) {
|
||||
if (result.second) {
|
||||
// The insert succeeded, so the CullState was not there
|
||||
// previously.
|
||||
cull_cat.spam()
|
||||
<< "Created CullState " << (void *)cs << " for:\n";
|
||||
trans.write(cull_cat.spam(false), 2);
|
||||
} else {
|
||||
cull_cat.spam()
|
||||
<< "Found existing CullState " << (void *)(*result.first)
|
||||
<< " for:\n";
|
||||
trans.write(cull_cat.spam(false), 2);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return *result.first;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverser::backward_arc
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CullTraverser::
|
||||
backward_arc(NodeRelation *arc, NullTransitionWrapper &,
|
||||
NullAttributeWrapper &, NullAttributeWrapper &,
|
||||
const CullLevelState &) {
|
||||
mark_backward_arc(arc);
|
||||
}
|
||||
|
@ -14,9 +14,10 @@
|
||||
#include <wrt.h>
|
||||
#include <frustumCullTraverser.h>
|
||||
#include <graphicsStateGuardian.h>
|
||||
#include <billboardTransition.h>
|
||||
#include <decalTransition.h>
|
||||
#include <pruneTransition.h>
|
||||
#include <transformTransition.h>
|
||||
#include <nodeTransitionWrapper.h>
|
||||
#include <indent.h>
|
||||
#include <config_sgraphutil.h> // for implicit_app_traversal
|
||||
#include <pStatTimer.h>
|
||||
@ -36,8 +37,9 @@ PStatCollector CullTraverser::_draw_pcollector =
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CullTraverser::
|
||||
CullTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type) :
|
||||
RenderTraverser(gsg, graph_type)
|
||||
CullTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type,
|
||||
const ArcChain &arc_chain) :
|
||||
RenderTraverser(gsg, graph_type, arc_chain)
|
||||
{
|
||||
_default_bin = new GeomBinNormal("default", this);
|
||||
_nested_count = 0;
|
||||
@ -85,9 +87,14 @@ traverse(Node *root,
|
||||
|
||||
nassertv(!_bins.empty());
|
||||
|
||||
_now = last_graph_update[_graph_type];
|
||||
|
||||
bool is_initial = (_nested_count == 0);
|
||||
if (is_initial) {
|
||||
if (cull_force_update) {
|
||||
_now = UpdateSeq::fresh();
|
||||
} else {
|
||||
_now = UpdateSeq::initial();
|
||||
}
|
||||
}
|
||||
_nested_count++;
|
||||
|
||||
if (is_initial) {
|
||||
@ -101,8 +108,25 @@ traverse(Node *root,
|
||||
|
||||
CullLevelState level_state;
|
||||
level_state._lookup = &_lookup;
|
||||
fc_traverse(root, *this, NullAttributeWrapper(), level_state,
|
||||
_gsg, _graph_type);
|
||||
level_state._now = _now;
|
||||
|
||||
// Determine the relative transform matrix from the camera to our
|
||||
// starting node. This is important for proper view-frustum
|
||||
// culling.
|
||||
LMatrix4f rel_from_camera;
|
||||
NodeTransitionWrapper ntw(TransformTransition::get_class_type());
|
||||
wrt(_gsg->get_current_projection_node(), root, begin(), end(),
|
||||
ntw, get_graph_type());
|
||||
const TransformTransition *tt;
|
||||
if (get_transition_into(tt, ntw)) {
|
||||
rel_from_camera = tt->get_matrix();
|
||||
} else {
|
||||
// No relative transform.
|
||||
rel_from_camera = LMatrix4f::ident_mat();
|
||||
}
|
||||
|
||||
fc_traverse(root, rel_from_camera, *this, NullAttributeWrapper(),
|
||||
level_state, _gsg, _graph_type);
|
||||
|
||||
if (is_initial) {
|
||||
draw();
|
||||
@ -262,9 +286,12 @@ clean_out_old_states() {
|
||||
// appropriate bin.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CullTraverser::
|
||||
add_geom_node(const PT(GeomNode) &node, const AllTransitionsWrapper &trans,
|
||||
add_geom_node(GeomNode *node, const AllTransitionsWrapper &trans,
|
||||
const CullLevelState &level_state) {
|
||||
nassertv(node != (GeomNode *)NULL);
|
||||
const ArcChain &arc_chain = get_arc_chain();
|
||||
nassertv(!arc_chain.empty());
|
||||
nassertv(arc_chain.back()->get_child() == node);
|
||||
|
||||
AllTransitionsWrapper complete_trans;
|
||||
level_state._lookup->compose_trans(trans, complete_trans);
|
||||
@ -275,17 +302,23 @@ add_geom_node(const PT(GeomNode) &node, const AllTransitionsWrapper &trans,
|
||||
// remove it here just to be paranoid.
|
||||
complete_trans.clear_transition(DirectRenderTransition::get_class_type());
|
||||
|
||||
CullState *cs = level_state._lookup->find_node(node, complete_trans, _now);
|
||||
CullState *cs = level_state._lookup->find_node
|
||||
(node, complete_trans, level_state._now);
|
||||
if (cs == (CullState *)NULL) {
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "Finding a new bin state\n";
|
||||
}
|
||||
|
||||
// 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, _now);
|
||||
level_state._lookup->record_node(node, cs, level_state._now);
|
||||
}
|
||||
|
||||
cs->record_current_geom_node(node);
|
||||
cs->record_current_geom_node(arc_chain);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -294,13 +327,16 @@ add_geom_node(const PT(GeomNode) &node, const AllTransitionsWrapper &trans,
|
||||
// Description: Records the indicated Node as one that is immediately
|
||||
// under a DirectRenderTransition, and thus it and its
|
||||
// subtree should be rendered directly, in a depth-first
|
||||
// traversal. This is usuall done when the render order
|
||||
// traversal. This is usually done when the render order
|
||||
// is very important within a small subtree of nodes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CullTraverser::
|
||||
add_direct_node(const PT_Node &node, const AllTransitionsWrapper &trans,
|
||||
add_direct_node(Node *node, const AllTransitionsWrapper &trans,
|
||||
const CullLevelState &level_state) {
|
||||
nassertv(node != (Node *)NULL);
|
||||
const ArcChain &arc_chain = get_arc_chain();
|
||||
nassertv(!arc_chain.empty());
|
||||
nassertv(arc_chain.back()->get_child() == node);
|
||||
|
||||
AllTransitionsWrapper complete_trans;
|
||||
level_state._lookup->compose_trans(trans, complete_trans);
|
||||
@ -309,17 +345,18 @@ add_direct_node(const PT_Node &node, const AllTransitionsWrapper &trans,
|
||||
// and interfere with state-sorting.
|
||||
complete_trans.clear_transition(DirectRenderTransition::get_class_type());
|
||||
|
||||
CullState *cs = level_state._lookup->find_node(node, complete_trans, _now);
|
||||
CullState *cs = level_state._lookup->find_node
|
||||
(node, complete_trans, level_state._now);
|
||||
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, _now);
|
||||
level_state._lookup->record_node(node, cs, level_state._now);
|
||||
}
|
||||
|
||||
cs->record_current_direct_node(node);
|
||||
cs->record_current_direct_node(arc_chain);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -346,6 +383,11 @@ 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;
|
||||
}
|
||||
|
||||
bool is_instanced = (node->get_num_parents(_graph_type) > 1);
|
||||
bool is_geom = node->is_of_type(GeomNode::get_class_type());
|
||||
bool node_has_sub_render = node->has_sub_render();
|
||||
@ -354,10 +396,18 @@ forward_arc(NodeRelation *arc, NullTransitionWrapper &,
|
||||
arc->has_transition(DirectRenderTransition::get_class_type()) ||
|
||||
arc->has_transition(DecalTransition::get_class_type());
|
||||
|
||||
if (arc_has_sub_render) {
|
||||
level_state._now = UpdateSeq::fresh();
|
||||
}
|
||||
_now = level_state._now;
|
||||
|
||||
mark_forward_arc(arc);
|
||||
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "Reached " << *node << ":\n"
|
||||
<< "is_instanced = " << is_instanced
|
||||
<< " now = " << level_state._now
|
||||
<< " is_instanced = " << is_instanced
|
||||
<< " is_geom = " << is_geom
|
||||
<< " node_has_sub_render = " << node_has_sub_render
|
||||
<< " arc_has_sub_render = " << arc_has_sub_render
|
||||
@ -382,10 +432,9 @@ forward_arc(NodeRelation *arc, NullTransitionWrapper &,
|
||||
|
||||
AllTransitionsWrapper new_trans;
|
||||
|
||||
if (!arc->sub_render_trans(attrib, new_trans, _gsg)) {
|
||||
return false;
|
||||
}
|
||||
if (!node->sub_render(attrib, new_trans, _gsg)) {
|
||||
if (!arc->sub_render_trans(attrib, new_trans, this) ||
|
||||
!node->sub_render(attrib, new_trans, this)) {
|
||||
mark_backward_arc(arc);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -399,6 +448,7 @@ forward_arc(NodeRelation *arc, NullTransitionWrapper &,
|
||||
// traverse any further beyond it--the rest of the subgraph
|
||||
// beginning at this node will be traversed when the node is
|
||||
// rendered.
|
||||
mark_backward_arc(arc);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,8 @@ class EXPCL_PANDA CullTraverser :
|
||||
public RenderTraverser,
|
||||
public TraverserVisitor<NullTransitionWrapper, CullLevelState> {
|
||||
public:
|
||||
CullTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type);
|
||||
CullTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type,
|
||||
const ArcChain &arc_chain = ArcChain());
|
||||
virtual ~CullTraverser();
|
||||
|
||||
INLINE void set_default_bin(GeomBin *bin);
|
||||
@ -49,7 +50,9 @@ public:
|
||||
|
||||
INLINE void draw_geom(GeomNode *geom_node,
|
||||
const AllAttributesWrapper &initial_state);
|
||||
INLINE void draw_direct(Node *node,
|
||||
INLINE void draw_geom(const ArcChain &arc_chain,
|
||||
const AllAttributesWrapper &initial_state);
|
||||
INLINE void draw_direct(const ArcChain &arc_chain,
|
||||
const AllAttributesWrapper &initial_state);
|
||||
|
||||
PUBLISHED:
|
||||
@ -60,10 +63,10 @@ private:
|
||||
void draw();
|
||||
void clean_out_old_states();
|
||||
|
||||
void add_geom_node(const PT(GeomNode) &node,
|
||||
void add_geom_node(GeomNode *node,
|
||||
const AllTransitionsWrapper &trans,
|
||||
const CullLevelState &level_state);
|
||||
void add_direct_node(const PT_Node &node,
|
||||
void add_direct_node(Node *node,
|
||||
const AllTransitionsWrapper &trans,
|
||||
const CullLevelState &level_state);
|
||||
|
||||
@ -83,8 +86,12 @@ public:
|
||||
NullAttributeWrapper &pre, NullAttributeWrapper &post,
|
||||
CullLevelState &level_state);
|
||||
|
||||
INLINE void
|
||||
backward_arc(NodeRelation *arc, NullTransitionWrapper &trans,
|
||||
NullAttributeWrapper &pre, NullAttributeWrapper &post,
|
||||
const CullLevelState &level_state);
|
||||
|
||||
private:
|
||||
UpdateSeq _now;
|
||||
AllAttributesWrapper _initial_state;
|
||||
|
||||
typedef set<PT(GeomBin)> Bins;
|
||||
@ -96,6 +103,7 @@ private:
|
||||
|
||||
CullStateLookup _lookup;
|
||||
int _nested_count;
|
||||
UpdateSeq _now;
|
||||
|
||||
public:
|
||||
// Statistics
|
||||
|
@ -12,10 +12,10 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomBinBackToFront::NodeEntry::
|
||||
NodeEntry(float distance, const PT(CullState) &state,
|
||||
Node *node, bool is_direct) :
|
||||
const ArcChain &arc_chain, bool is_direct) :
|
||||
_distance(distance),
|
||||
_state(state),
|
||||
_node(node),
|
||||
_arc_chain(arc_chain),
|
||||
_is_direct(is_direct)
|
||||
{
|
||||
}
|
||||
@ -29,7 +29,7 @@ INLINE GeomBinBackToFront::NodeEntry::
|
||||
NodeEntry(const GeomBinBackToFront::NodeEntry ©) :
|
||||
_distance(copy._distance),
|
||||
_state(copy._state),
|
||||
_node(copy._node),
|
||||
_arc_chain(copy._arc_chain),
|
||||
_is_direct(copy._is_direct)
|
||||
{
|
||||
}
|
||||
@ -43,7 +43,7 @@ INLINE void GeomBinBackToFront::NodeEntry::
|
||||
operator = (const NodeEntry ©) {
|
||||
_distance = copy._distance;
|
||||
_state = copy._state;
|
||||
_node = copy._node;
|
||||
_arc_chain = copy._arc_chain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -63,12 +63,11 @@ operator < (const NodeEntry &other) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomBinBackToFront::NodeEntry::
|
||||
draw(CullTraverser *trav) const {
|
||||
nassertv(_node != (GeomNode *)NULL);
|
||||
nassertv(!_arc_chain.empty());
|
||||
if (_is_direct) {
|
||||
trav->draw_direct(_node, AllAttributesWrapper(_state->get_attributes()));
|
||||
trav->draw_direct(_arc_chain, AllAttributesWrapper(_state->get_attributes()));
|
||||
} else {
|
||||
trav->draw_geom(DCAST(GeomNode, _node),
|
||||
AllAttributesWrapper(_state->get_attributes()));
|
||||
trav->draw_geom(_arc_chain, AllAttributesWrapper(_state->get_attributes()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ clear_current_states() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomBinBackToFront::record_current_state
|
||||
// Access: Public, Virtual
|
||||
// Description: Called each frame by the CullTraverser to indicated
|
||||
// Description: Called each frame by the CullTraverser to indicate
|
||||
// that the given CullState (and all of its current
|
||||
// GeomNodes) is visible this frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -45,7 +45,10 @@ record_current_state(GraphicsStateGuardian *gsg, CullState *cs, int,
|
||||
|
||||
CullState::geom_const_iterator gi;
|
||||
for (gi = cs->geom_begin(); gi != cs->geom_end(); ++gi) {
|
||||
GeomNode *node = (*gi);
|
||||
const ArcChain &arc_chain = (*gi);
|
||||
nassertv(!arc_chain.empty());
|
||||
GeomNode *node;
|
||||
DCAST_INTO_V(node, arc_chain.back()->get_child());
|
||||
nassertv(node != (GeomNode *)NULL);
|
||||
const BoundingVolume &volume = node->get_bound();
|
||||
|
||||
@ -60,13 +63,15 @@ record_current_state(GraphicsStateGuardian *gsg, CullState *cs, int,
|
||||
}
|
||||
|
||||
float distance = gsg->compute_distance_to(center);
|
||||
_node_entries.insert(NodeEntry(distance, cs, node, false));
|
||||
_node_entries.insert(NodeEntry(distance, cs, arc_chain, false));
|
||||
}
|
||||
}
|
||||
|
||||
CullState::direct_const_iterator di;
|
||||
for (di = cs->direct_begin(); di != cs->direct_end(); ++di) {
|
||||
Node *node = (*di);
|
||||
const ArcChain &arc_chain = (*di);
|
||||
nassertv(!arc_chain.empty());
|
||||
Node *node = arc_chain.back()->get_child();
|
||||
nassertv(node != (Node *)NULL);
|
||||
|
||||
const BoundingVolume &volume = node->get_bound();
|
||||
@ -119,7 +124,7 @@ record_current_state(GraphicsStateGuardian *gsg, CullState *cs, int,
|
||||
}
|
||||
}
|
||||
|
||||
_node_entries.insert(NodeEntry(distance, cs, node, true));
|
||||
_node_entries.insert(NodeEntry(distance, cs, arc_chain, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ private:
|
||||
class NodeEntry {
|
||||
public:
|
||||
INLINE NodeEntry(float distance, const PT(CullState) &state,
|
||||
Node *node, bool is_direct);
|
||||
const ArcChain &arc_chain, bool is_direct);
|
||||
INLINE NodeEntry(const NodeEntry ©);
|
||||
INLINE void operator = (const NodeEntry ©);
|
||||
|
||||
@ -51,7 +51,7 @@ private:
|
||||
private:
|
||||
float _distance;
|
||||
PT(CullState) _state;
|
||||
Node *_node;
|
||||
ArcChain _arc_chain;
|
||||
bool _is_direct;
|
||||
};
|
||||
|
||||
|
@ -12,10 +12,10 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomBinFixed::NodeEntry::
|
||||
NodeEntry(int draw_order, const PT(CullState) &state,
|
||||
Node *node, bool is_direct) :
|
||||
const ArcChain &arc_chain, bool is_direct) :
|
||||
_draw_order(draw_order),
|
||||
_state(state),
|
||||
_node(node),
|
||||
_arc_chain(arc_chain),
|
||||
_is_direct(is_direct)
|
||||
{
|
||||
}
|
||||
@ -29,7 +29,7 @@ INLINE GeomBinFixed::NodeEntry::
|
||||
NodeEntry(const GeomBinFixed::NodeEntry ©) :
|
||||
_draw_order(copy._draw_order),
|
||||
_state(copy._state),
|
||||
_node(copy._node),
|
||||
_arc_chain(copy._arc_chain),
|
||||
_is_direct(copy._is_direct)
|
||||
{
|
||||
}
|
||||
@ -43,7 +43,7 @@ INLINE void GeomBinFixed::NodeEntry::
|
||||
operator = (const NodeEntry ©) {
|
||||
_draw_order = copy._draw_order;
|
||||
_state = copy._state;
|
||||
_node = copy._node;
|
||||
_arc_chain = copy._arc_chain;
|
||||
_is_direct = copy._is_direct;
|
||||
}
|
||||
|
||||
@ -64,12 +64,11 @@ operator < (const NodeEntry &other) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomBinFixed::NodeEntry::
|
||||
draw(CullTraverser *trav) const {
|
||||
nassertv(_node != (GeomNode *)NULL);
|
||||
nassertv(!_arc_chain.empty());
|
||||
if (_is_direct) {
|
||||
trav->draw_direct(_node, AllAttributesWrapper(_state->get_attributes()));
|
||||
trav->draw_direct(_arc_chain, AllAttributesWrapper(_state->get_attributes()));
|
||||
} else {
|
||||
trav->draw_geom(DCAST(GeomNode, _node),
|
||||
AllAttributesWrapper(_state->get_attributes()));
|
||||
trav->draw_geom(_arc_chain, AllAttributesWrapper(_state->get_attributes()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ clear_current_states() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomBinFixed::record_current_state
|
||||
// Access: Public, Virtual
|
||||
// Description: Called each frame by the CullTraverser to indicated
|
||||
// Description: Called each frame by the CullTraverser to indicate
|
||||
// that the given CullState (and all of its current
|
||||
// GeomNodes) is visible this frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -46,16 +46,14 @@ record_current_state(GraphicsStateGuardian *, CullState *cs,
|
||||
|
||||
CullState::geom_const_iterator gi;
|
||||
for (gi = cs->geom_begin(); gi != cs->geom_end(); ++gi) {
|
||||
GeomNode *node = (*gi);
|
||||
nassertv(node != (GeomNode *)NULL);
|
||||
_node_entries.insert(NodeEntry(draw_order, cs, node, false));
|
||||
const ArcChain &arc_chain = (*gi);
|
||||
_node_entries.insert(NodeEntry(draw_order, cs, arc_chain, false));
|
||||
}
|
||||
|
||||
CullState::direct_const_iterator di;
|
||||
for (di = cs->direct_begin(); di != cs->direct_end(); ++di) {
|
||||
Node *node = (*di);
|
||||
nassertv(node != (Node *)NULL);
|
||||
_node_entries.insert(NodeEntry(draw_order, cs, node, true));
|
||||
const ArcChain &arc_chain = (*di);
|
||||
_node_entries.insert(NodeEntry(draw_order, cs, arc_chain, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ private:
|
||||
class NodeEntry {
|
||||
public:
|
||||
INLINE NodeEntry(int draw_order, const PT(CullState) &state,
|
||||
Node *node, bool is_direct);
|
||||
const ArcChain &arc_chain, bool is_direct);
|
||||
INLINE NodeEntry(const NodeEntry ©);
|
||||
INLINE void operator = (const NodeEntry ©);
|
||||
|
||||
@ -48,7 +48,7 @@ private:
|
||||
private:
|
||||
int _draw_order;
|
||||
PT(CullState) _state;
|
||||
Node *_node;
|
||||
ArcChain _arc_chain;
|
||||
bool _is_direct;
|
||||
};
|
||||
|
||||
|
@ -90,26 +90,24 @@ draw(CullTraverser *trav) {
|
||||
|
||||
CullState::geom_iterator gi;
|
||||
for (gi = cs->geom_begin(); gi != cs->geom_end(); ++gi) {
|
||||
GeomNode *geom = (*gi);
|
||||
nassertv(geom != (GeomNode *)NULL);
|
||||
const ArcChain &arc_chain = (*gi);
|
||||
nassertv(!arc_chain.empty());
|
||||
GeomNode *geom_node;
|
||||
DCAST_INTO_V(geom_node, arc_chain.back()->get_child());
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "Drawing " << *geom << "\n";
|
||||
<< "Drawing " << *geom_node << "\n";
|
||||
}
|
||||
geom->draw(gsg);
|
||||
geom_node->draw(gsg);
|
||||
}
|
||||
}
|
||||
|
||||
CullState::direct_iterator di;
|
||||
for (di = cs->direct_begin(); di != cs->direct_end(); ++di) {
|
||||
Node *node = (*di);
|
||||
nassertv(node != (Node *)NULL);
|
||||
const ArcChain &arc_chain = (*di);
|
||||
nassertv(!arc_chain.empty());
|
||||
|
||||
if (cull_cat.is_spam()) {
|
||||
cull_cat.spam()
|
||||
<< "Drawing direct: " << *node << "\n";
|
||||
}
|
||||
trav->draw_direct(node, cs->get_attributes());
|
||||
trav->draw_direct(arc_chain, cs->get_attributes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ get_state() const {
|
||||
// projection node (i.e. the camera) for this scene, as
|
||||
// set by the last call to render_subgraph().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const ProjectionNode *GraphicsStateGuardian::
|
||||
INLINE ProjectionNode *GraphicsStateGuardian::
|
||||
get_current_projection_node(void) const {
|
||||
return _current_projection_node;
|
||||
}
|
||||
|
@ -68,10 +68,10 @@ public:
|
||||
virtual void prepare_display_region()=0;
|
||||
|
||||
virtual void render_frame(const AllAttributesWrapper &initial_state)=0;
|
||||
virtual void render_scene(Node *root, const ProjectionNode *projnode,
|
||||
virtual void render_scene(Node *root, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state)=0;
|
||||
virtual void render_subgraph(RenderTraverser *traverser,
|
||||
Node *subgraph, const ProjectionNode *projnode,
|
||||
Node *subgraph, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state,
|
||||
const AllTransitionsWrapper &net_trans)=0;
|
||||
virtual void render_subgraph(RenderTraverser *traverser,
|
||||
@ -99,7 +99,7 @@ public:
|
||||
|
||||
RenderBuffer get_render_buffer(int buffer_type);
|
||||
|
||||
INLINE const ProjectionNode* get_current_projection_node(void) const ;
|
||||
INLINE ProjectionNode *get_current_projection_node(void) const ;
|
||||
INLINE const Node* get_current_root_node(void) const;
|
||||
|
||||
INLINE CPT(DisplayRegion) get_current_display_region(void) const;
|
||||
@ -144,7 +144,7 @@ protected:
|
||||
|
||||
// These must be set by render_scene().
|
||||
Node *_current_root_node;
|
||||
const ProjectionNode *_current_projection_node;
|
||||
ProjectionNode *_current_projection_node;
|
||||
CPT(DisplayRegion) _current_display_region;
|
||||
|
||||
// This is used by wants_normals()
|
||||
|
@ -875,7 +875,7 @@ render_frame(const AllAttributesWrapper &initial_state) {
|
||||
// may be modified during rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian::
|
||||
render_scene(Node *root, const ProjectionNode *projnode,
|
||||
render_scene(Node *root, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state) {
|
||||
#ifdef GSG_VERBOSE
|
||||
_pass_number = 0;
|
||||
@ -905,11 +905,11 @@ render_scene(Node *root, const ProjectionNode *projnode,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian::
|
||||
render_subgraph(RenderTraverser *traverser,
|
||||
Node *subgraph, const ProjectionNode *projnode,
|
||||
Node *subgraph, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state,
|
||||
const AllTransitionsWrapper &net_trans) {
|
||||
activate();
|
||||
const ProjectionNode *old_projection_node = _current_projection_node;
|
||||
ProjectionNode *old_projection_node = _current_projection_node;
|
||||
_current_projection_node = projnode;
|
||||
LMatrix4f old_projection_mat = _current_projection_mat;
|
||||
|
||||
|
@ -85,10 +85,10 @@ public:
|
||||
virtual void prepare_display_region();
|
||||
|
||||
virtual void render_frame(const AllAttributesWrapper &initial_state);
|
||||
virtual void render_scene(Node *root, const ProjectionNode *projnode,
|
||||
virtual void render_scene(Node *root, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state);
|
||||
virtual void render_subgraph(RenderTraverser *traverser,
|
||||
Node *subgraph, const ProjectionNode *projnode,
|
||||
Node *subgraph, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state,
|
||||
const AllTransitionsWrapper &net_trans);
|
||||
virtual void render_subgraph(RenderTraverser *traverser,
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <billboardTransition.h>
|
||||
#include <transformAttribute.h>
|
||||
#include <transparencyTransition.h>
|
||||
#include <renderTraverser.h>
|
||||
|
||||
#include <orthoProjection.h>
|
||||
#include <perspectiveProjection.h>
|
||||
@ -295,15 +296,14 @@ render_children(const vector_relation &arcs, const AllAttributesWrapper &attrib,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool LensFlareNode::
|
||||
sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase)
|
||||
{
|
||||
GraphicsStateGuardian *gsg = DCAST(GraphicsStateGuardian, gsgbase);
|
||||
RenderTraverser *trav) {
|
||||
GraphicsStateGuardian *gsg = trav->get_gsg();
|
||||
|
||||
nassertr(_light_node != (Node*) NULL, false);
|
||||
|
||||
//First we need the light position
|
||||
const ProjectionNode *camera_node = gsg->get_current_projection_node();
|
||||
const PerspectiveProjection *pp = DCAST(PerspectiveProjection, camera_node->get_projection());
|
||||
ProjectionNode *camera_node = gsg->get_current_projection_node();
|
||||
PerspectiveProjection *pp = DCAST(PerspectiveProjection, camera_node->get_projection());
|
||||
|
||||
LPoint3f light_pos = get_rel_pos(_light_node, camera_node);
|
||||
|
||||
|
@ -38,8 +38,9 @@ PUBLISHED:
|
||||
INLINE void set_light_source(PT_Node source);
|
||||
|
||||
public:
|
||||
virtual bool sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase);
|
||||
virtual bool sub_render(const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
RenderTraverser *trav);
|
||||
virtual bool has_sub_render() const;
|
||||
|
||||
private:
|
||||
|
@ -50,9 +50,12 @@ template<class T>
|
||||
void PointerToBase<T>::
|
||||
reassign(To *ptr) {
|
||||
if (ptr != _ptr) {
|
||||
if (_ptr != (To *)NULL) {
|
||||
unref_delete(_ptr);
|
||||
}
|
||||
// First save the old pointer; we won't delete it until we have
|
||||
// assigned the new one. We do this just in case there are
|
||||
// cascading effects from deleting this pointer that might
|
||||
// inadvertently delete the new one. (Don't laugh--it's
|
||||
// happened!)
|
||||
To *old_ptr = _ptr;
|
||||
|
||||
_ptr = ptr;
|
||||
if (_ptr != (To *)NULL) {
|
||||
@ -72,6 +75,11 @@ reassign(To *ptr) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Now delete the old pointer.
|
||||
if (old_ptr != (To *)NULL) {
|
||||
unref_delete(old_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,6 @@ prepare_delete() {
|
||||
_ref_count = -100;
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCount::unref_consider_delete
|
||||
// Access: Public
|
||||
@ -143,7 +142,6 @@ unref_consider_delete() {
|
||||
unref();
|
||||
return (get_ref_count() == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCount::get_ref_count
|
||||
@ -291,6 +289,16 @@ template<class RefCountType>
|
||||
INLINE void
|
||||
unref_delete(RefCountType *ptr) {
|
||||
if (((ReferenceCount *)ptr)->unref_consider_delete()) {
|
||||
#ifndef NDEBUG
|
||||
if (get_leak_memory()) {
|
||||
// In leak-memory mode, we don't actually delete the pointer,
|
||||
// although we do call the destructor explicitly. This has
|
||||
// exactly the same effect as deleting it, without actually
|
||||
// freeing up the memory it uses.
|
||||
ptr->~RefCountType();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
delete ptr;
|
||||
}
|
||||
}
|
||||
|
@ -6,35 +6,3 @@
|
||||
#include "referenceCount.h"
|
||||
|
||||
TypeHandle ReferenceCount::_type_handle;
|
||||
|
||||
#ifndef NDEBUG
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCount::unref_consider_delete
|
||||
// Access: Public
|
||||
// Description: This function is called by the global unref_delete()
|
||||
// function. This function unrefs the pointer and
|
||||
// returns true if it should be deleted (i.e. the count
|
||||
// has gone to zero), or false otherwise. It doesn't
|
||||
// delete itself because (a) a method cannot safely
|
||||
// delete this, and (b) we don't have a virtual
|
||||
// destructor anyway. The decision of whether to delete
|
||||
// is left up to unref_delete().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ReferenceCount::
|
||||
unref_consider_delete() {
|
||||
unref();
|
||||
|
||||
if (get_leak_memory()) {
|
||||
// In leak-memory mode, we don't actually delete anything.
|
||||
// However, we do want to call prepare_delete() when the count
|
||||
// reaches zero, to reset the refcount to -100 as a deleted flag.
|
||||
if (get_ref_count() == 0) {
|
||||
prepare_delete();
|
||||
MemoryUsage::remove_pointer(this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return (get_ref_count() == 0);
|
||||
}
|
||||
#endif
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "typeHandle.h"
|
||||
#include "memoryUsage.h"
|
||||
#include "config_express.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -44,13 +45,7 @@ public:
|
||||
// These functions are not part of the normal API, but they have to
|
||||
// be public. You shouldn't generally call these directly.
|
||||
INLINE void prepare_delete();
|
||||
#ifdef NDEBUG
|
||||
// unref_consider_delete() is inline only if we are compiling
|
||||
// NDEBUG.
|
||||
INLINE bool unref_consider_delete();
|
||||
#else
|
||||
bool unref_consider_delete();
|
||||
#endif
|
||||
|
||||
PUBLISHED:
|
||||
INLINE int get_ref_count() const;
|
||||
|
@ -554,7 +554,7 @@ render_frame(const AllAttributesWrapper &initial_state) {
|
||||
// may be modified during rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GLGraphicsStateGuardian::
|
||||
render_scene(Node *root, const ProjectionNode *projnode,
|
||||
render_scene(Node *root, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state) {
|
||||
#ifdef GSG_VERBOSE
|
||||
_pass_number = 0;
|
||||
@ -584,7 +584,7 @@ render_scene(Node *root, const ProjectionNode *projnode,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GLGraphicsStateGuardian::
|
||||
render_subgraph(RenderTraverser *traverser,
|
||||
Node *subgraph, const ProjectionNode *projnode,
|
||||
Node *subgraph, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state,
|
||||
const AllTransitionsWrapper &net_trans) {
|
||||
// Calling activate() frequently seems to be intolerably expensive
|
||||
@ -593,7 +593,7 @@ render_subgraph(RenderTraverser *traverser,
|
||||
|
||||
// activate();
|
||||
|
||||
const ProjectionNode *old_projection_node = _current_projection_node;
|
||||
ProjectionNode *old_projection_node = _current_projection_node;
|
||||
_current_projection_node = projnode;
|
||||
LMatrix4f old_projection_mat = _current_projection_mat;
|
||||
|
||||
|
@ -62,10 +62,10 @@ public:
|
||||
virtual void prepare_display_region();
|
||||
|
||||
virtual void render_frame(const AllAttributesWrapper &initial_state);
|
||||
virtual void render_scene(Node *root, const ProjectionNode *projnode,
|
||||
virtual void render_scene(Node *root, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state);
|
||||
virtual void render_subgraph(RenderTraverser *traverser,
|
||||
Node *subgraph, const ProjectionNode *projnode,
|
||||
Node *subgraph, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state,
|
||||
const AllTransitionsWrapper &net_trans);
|
||||
virtual void render_subgraph(RenderTraverser *traverser,
|
||||
|
@ -9,12 +9,19 @@
|
||||
allAttributesWrapper.I allAttributesWrapper.cxx \
|
||||
allAttributesWrapper.h allTransitionsWrapper.I \
|
||||
allTransitionsWrapper.cxx allTransitionsWrapper.h \
|
||||
bitMask32Transition.cxx bitMask32Transition.h boundedObject.I \
|
||||
arcChain.I arcChain.cxx arcChain.h \
|
||||
bitMask32Transition.cxx bitMask32Transition.h \
|
||||
bitMaskAttribute.I bitMaskAttribute.h \
|
||||
bitMaskTransition.I bitMaskTransition.h \
|
||||
boundedObject.I \
|
||||
boundedObject.N boundedObject.cxx boundedObject.h config_graph.cxx \
|
||||
config_graph.h graphReducer.cxx graphReducer.h immediateAttribute.I \
|
||||
immediateAttribute.cxx immediateAttribute.h immediateTransition.I \
|
||||
immediateTransition.cxx immediateTransition.h \
|
||||
lmatrix4fTransition.cxx lmatrix4fTransition.h multiNodeAttribute.I \
|
||||
lmatrix4fTransition.cxx lmatrix4fTransition.h \
|
||||
matrixAttribute.I matrixAttribute.h matrixTransition.I \
|
||||
matrixTransition.h \
|
||||
multiNodeAttribute.I \
|
||||
multiNodeAttribute.cxx multiNodeAttribute.h multiNodeTransition.I \
|
||||
multiNodeTransition.cxx multiNodeTransition.h namedNode.I \
|
||||
namedNode.cxx namedNode.h node.I node.cxx node.h nodeAttribute.I \
|
||||
@ -36,11 +43,14 @@
|
||||
onOffTransition.I onOffTransition.cxx onOffTransition.h \
|
||||
onTransition.I onTransition.cxx onTransition.h pt_NamedNode.N \
|
||||
pt_NamedNode.cxx pt_NamedNode.h pt_Node.N pt_Node.cxx pt_Node.h \
|
||||
vector_PT_Node.cxx vector_PT_Node.h
|
||||
setTransitionHelpers.I setTransitionHelpers.h \
|
||||
traverserVisitor.I traverserVisitor.h \
|
||||
vector_PT_Node.cxx vector_PT_Node.h wrt.I wrt.h
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
allAttributesWrapper.I allAttributesWrapper.h \
|
||||
allTransitionsWrapper.I allTransitionsWrapper.h \
|
||||
arcChain.I arcChain.h \
|
||||
bitMask32Transition.h bitMaskAttribute.I bitMaskAttribute.h \
|
||||
bitMaskTransition.I bitMaskTransition.h boundedObject.I \
|
||||
boundedObject.h config_graph.h dftraverser.I dftraverser.h \
|
||||
|
219
panda/src/graph/arcChain.I
Normal file
219
panda/src/graph/arcChain.I
Normal file
@ -0,0 +1,219 @@
|
||||
// Filename: arcChain.I
|
||||
// Created by: drose (05Jan01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::ArcComponent::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ArcChain::ArcComponent::
|
||||
ArcComponent(NodeRelation *arc, ArcComponent *next) :
|
||||
_arc(arc),
|
||||
_next(next)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::ForwardIterator::Constructor
|
||||
// Access: Public
|
||||
// Description: This is an STL-style iterator that can be used to
|
||||
// traverse the full list of arcs traversed so far by
|
||||
// the ArcChain. Its primary purpose is as a
|
||||
// parameter to wrt() so we can compute a correct
|
||||
// relative wrt to the particular instance we've reached
|
||||
// so far.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ArcChain::ForwardIterator::
|
||||
ForwardIterator(ArcChain::ArcComponent *comp) : _comp(comp) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::ForwardIterator::Dereference Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeRelation *ArcChain::ForwardIterator::
|
||||
operator * () const {
|
||||
nassertr(_comp != (ArcComponent *)NULL, NULL);
|
||||
return _comp->_arc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::ForwardIterator::Increment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ArcChain::ForwardIterator::
|
||||
operator ++() {
|
||||
nassertv(_comp != (ArcComponent *)NULL);
|
||||
_comp = _comp->_next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::ForwardIterator::Equality Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ArcChain::ForwardIterator::
|
||||
operator == (const ArcChain::ForwardIterator &other) const {
|
||||
return _comp == other._comp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::ForwardIterator::Inequality Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ArcChain::ForwardIterator::
|
||||
operator != (const ArcChain::ForwardIterator &other) const {
|
||||
return _comp != other._comp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::Default Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ArcChain::
|
||||
ArcChain() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ArcChain::
|
||||
ArcChain(const ArcChain ©) :
|
||||
_head(copy._head)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ArcChain::
|
||||
operator = (const ArcChain ©) {
|
||||
_head = copy._head;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::begin
|
||||
// Access: Public
|
||||
// Description: Returns an iterator that can be used to traverse the
|
||||
// list of arcs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ArcChain::const_iterator ArcChain::
|
||||
begin() const {
|
||||
return ForwardIterator(_head);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::end
|
||||
// Access: Public
|
||||
// Description: Returns an iterator that can be used to traverse the
|
||||
// list of arcs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ArcChain::const_iterator ArcChain::
|
||||
end() const {
|
||||
return ForwardIterator();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::empty
|
||||
// Access: Public
|
||||
// Description: Returns true if the list of arcs returned by begin()
|
||||
// .. end() is empty (i.e. begin() == end()), false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ArcChain::
|
||||
empty() const {
|
||||
return (_head == (ArcComponent *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::push_back
|
||||
// Access: Public
|
||||
// Description: Appends the indicated arc onto the end of the chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ArcChain::
|
||||
push_back(NodeRelation *arc) {
|
||||
_head = new ArcComponent(arc, _head);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::pop_back
|
||||
// Access: Public
|
||||
// Description: Removes the last arc from the end of the chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ArcChain::
|
||||
pop_back() {
|
||||
nassertv(_head != (ArcComponent *)NULL);
|
||||
_head = _head->_next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::back
|
||||
// Access: Public
|
||||
// Description: Returns the last arc in the chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeRelation *ArcChain::
|
||||
back() const {
|
||||
nassertr(_head != (ArcComponent *)NULL, (NodeRelation *)NULL);
|
||||
return _head->_arc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::operator ==
|
||||
// Access: Public
|
||||
// Description: Returns true if the two chains are equivalent; that
|
||||
// is, if they contain the same list of arcs in the same
|
||||
// order.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ArcChain::
|
||||
operator == (const ArcChain &other) const {
|
||||
return (compare_to(other) == 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::operator !=
|
||||
// Access: Public
|
||||
// Description: Returns true if the two chains are not equivalent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ArcChain::
|
||||
operator != (const ArcChain &other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::operator <
|
||||
// Access: Public
|
||||
// Description: Returns true if this ArcChain sorts before the other
|
||||
// one, false otherwise. The sorting order of two
|
||||
// nonequivalent ArcChains is consistent but undefined,
|
||||
// and is useful only for storing ArcChains in a sorted
|
||||
// container like an STL set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ArcChain::
|
||||
operator < (const ArcChain &other) const {
|
||||
return (compare_to(other) < 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::output
|
||||
// Access: Public
|
||||
// Description: Writes a sensible description of the ArcChain to the
|
||||
// indicated output stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ArcChain::
|
||||
output(ostream &out) const {
|
||||
if (empty()) {
|
||||
out << "(empty)";
|
||||
} else {
|
||||
r_output(out, _head);
|
||||
}
|
||||
}
|
79
panda/src/graph/arcChain.cxx
Normal file
79
panda/src/graph/arcChain.cxx
Normal file
@ -0,0 +1,79 @@
|
||||
// Filename: arcChain.cxx
|
||||
// Created by: drose (05Jan01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "arcChain.h"
|
||||
#include "node.h"
|
||||
#include "namedNode.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::compare_to
|
||||
// Access: Public
|
||||
// Description: Returns a number less than zero if this ArcChain
|
||||
// sorts before the other one, greater than zero if it
|
||||
// sorts after, or zero if they are equivalent.
|
||||
//
|
||||
// Two ArcChains are considered equivalent if they
|
||||
// consist of exactly the same list of arcs in the same
|
||||
// order. Otherwise, they are different; different
|
||||
// ArcChains will be ranked in a consistent but
|
||||
// undefined ordering; the ordering is useful only for
|
||||
// placing the ArcChains in a sorted container like an
|
||||
// STL set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ArcChain::
|
||||
compare_to(const ArcChain &other) const {
|
||||
ArcComponent *a = _head;
|
||||
ArcComponent *b = other._head;
|
||||
|
||||
while (a != (ArcComponent *)NULL && b != (ArcComponent *)NULL) {
|
||||
if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
a = a->_next;
|
||||
b = b->_next;
|
||||
}
|
||||
|
||||
if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::r_output
|
||||
// Access: Private
|
||||
// Description: The recursive implementation of output(), this writes
|
||||
// the names of each arc component in order from
|
||||
// beginning to end, by first walking to the end of the
|
||||
// linked list and then outputting from there.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ArcChain::
|
||||
r_output(ostream &out, ArcComponent *comp) const {
|
||||
ArcComponent *next = comp->_next;
|
||||
if (next != (ArcComponent *)NULL) {
|
||||
// This is not the head of the list; keep going up.
|
||||
r_output(out, next);
|
||||
out << "/";
|
||||
}
|
||||
|
||||
// Now output this component.
|
||||
Node *node = comp->_arc->get_child();
|
||||
if (node->is_of_type(NamedNode::get_class_type())) {
|
||||
NamedNode *named_node = DCAST(NamedNode, node);
|
||||
if (named_node->has_name()) {
|
||||
out << named_node->get_name();
|
||||
} else {
|
||||
out << node->get_type();
|
||||
}
|
||||
} else {
|
||||
out << node->get_type();
|
||||
}
|
||||
}
|
105
panda/src/graph/arcChain.h
Normal file
105
panda/src/graph/arcChain.h
Normal file
@ -0,0 +1,105 @@
|
||||
// Filename: arcChain.h
|
||||
// Created by: drose (05Jan01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARCCHAIN_H
|
||||
#define ARCCHAIN_H
|
||||
|
||||
#include <pandabase.h>
|
||||
|
||||
#include "nodeRelation.h"
|
||||
|
||||
#include <pointerTo.h>
|
||||
#include <referenceCount.h>
|
||||
#include <notify.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ArcChain
|
||||
// Description : This defines a singly-linked chain of arcs from one
|
||||
// point (e.g. the root of the scene graph) to another
|
||||
// point (e.g. a leaf), although no assumption is made
|
||||
// about the relationship between the arcs. It is
|
||||
// simply a list of arcs that may only be lengthened or
|
||||
// shortened, or copied.
|
||||
//
|
||||
// This list may be copied by reference using the copy
|
||||
// constructor; the new copy may be appended to without
|
||||
// modifying the source (but individual nodes may not be
|
||||
// modified).
|
||||
//
|
||||
// This serves as the fundamental implementation of
|
||||
// NodePaths, for instance, and also is used during
|
||||
// render traversals to manage the list of arcs
|
||||
// traversed so far (and thus compute unambiguous
|
||||
// wrt's).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA ArcChain {
|
||||
private:
|
||||
// We maintain our own linked list structure here instead of using
|
||||
// some STL structure, so we can efficiently copy-construct these
|
||||
// things by sharing the initial part of the list.
|
||||
|
||||
// We have a singly-linked list whose head is the bottom arc of the
|
||||
// path, and whose tail is the top arc of the path. Thus, we can
|
||||
// copy the entire path by simply copying the head pointer, and we
|
||||
// can then append to or shorten our own path without affecting the
|
||||
// paths we're sharing ArcComponents with. Very LISPy.
|
||||
class ArcComponent : public ReferenceCount {
|
||||
public:
|
||||
INLINE ArcComponent(NodeRelation *arc, ArcComponent *next);
|
||||
PT(NodeRelation) _arc;
|
||||
PT(ArcComponent) _next;
|
||||
};
|
||||
|
||||
PT(ArcComponent) _head;
|
||||
|
||||
// This is a supporting class for iterating through all the arcs via
|
||||
// begin() .. end().
|
||||
class ForwardIterator {
|
||||
public:
|
||||
INLINE ForwardIterator(ArcComponent *comp = NULL);
|
||||
INLINE NodeRelation *operator * () const;
|
||||
INLINE void operator ++();
|
||||
INLINE bool operator == (const ForwardIterator &other) const;
|
||||
INLINE bool operator != (const ForwardIterator &other) const;
|
||||
|
||||
private:
|
||||
ArcComponent *_comp;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef ForwardIterator iterator;
|
||||
typedef ForwardIterator const_iterator;
|
||||
|
||||
INLINE ArcChain();
|
||||
INLINE ArcChain(const ArcChain ©);
|
||||
INLINE void operator = (const ArcChain ©);
|
||||
|
||||
INLINE const_iterator begin() const;
|
||||
INLINE const_iterator end() const;
|
||||
INLINE bool empty() const;
|
||||
|
||||
INLINE void push_back(NodeRelation *arc);
|
||||
INLINE void pop_back();
|
||||
INLINE NodeRelation *back() const;
|
||||
|
||||
INLINE bool operator == (const ArcChain &other) const;
|
||||
INLINE bool operator != (const ArcChain &other) const;
|
||||
INLINE bool operator < (const ArcChain &other) const;
|
||||
int compare_to(const ArcChain &other) const;
|
||||
|
||||
INLINE void output(ostream &out) const;
|
||||
|
||||
private:
|
||||
void r_output(ostream &out, ArcComponent *comp) const;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const ArcChain &arc_chain) {
|
||||
arc_chain.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "arcChain.I"
|
||||
|
||||
#endif
|
@ -49,9 +49,16 @@ ConfigureFn(config_graph) {
|
||||
// wrt(), so that the second time wrt() is called on a particular
|
||||
// node-node pair it will be much cheaper than the first time. This
|
||||
// is the default behavior; you'd only want to turn it off if for some
|
||||
// reason it was broken.
|
||||
// reason it was broken. This is true by default and cannot be turned
|
||||
// off in optimized (NDEBUG) mode.
|
||||
const bool cache_wrt = config_graph.GetBool("cache-wrt", true);
|
||||
|
||||
// Set this true to force abort() to be called if an ambiguous wrt()
|
||||
// call is made. This will hopefully allow the programmer to get a
|
||||
// stack dump and determine who is issuing the ambiguous wrt(). This
|
||||
// cannot be turned on in optimized (NDEBUG) mode.
|
||||
const bool ambiguous_wrt_abort = config_graph.GetBool("ambiguous-wrt-abort", false);
|
||||
|
||||
// Set this true to double-check the cached value of wrt(), above, by
|
||||
// performing an explicit uncached wrt() and comparing the results.
|
||||
// Obviously very slow. This cannot be turned on in optimized
|
||||
|
@ -14,6 +14,7 @@ NotifyCategoryDecl(wrt, EXPCL_PANDA, EXPTP_PANDA);
|
||||
|
||||
// Configure variables for graph package.
|
||||
extern const bool EXPCL_PANDA cache_wrt;
|
||||
extern const bool EXPCL_PANDA ambiguous_wrt_abort;
|
||||
extern const bool EXPCL_PANDA paranoid_wrt;
|
||||
extern const bool EXPCL_PANDA paranoid_graph;
|
||||
|
||||
|
@ -176,8 +176,17 @@ internal_compare_to(const NodeTransition *other) const {
|
||||
const MatrixTransition<Matrix> *ot;
|
||||
DCAST_INTO_R(ot, other, false);
|
||||
|
||||
// return _matrix.compare_to(ot->_matrix);
|
||||
return this - other;
|
||||
// Should we bother comparing matrices componentwise, or should we
|
||||
// just assume that any two different Matrix pointers are probably
|
||||
// different matrices?
|
||||
|
||||
// For now, we compare componentwise. It makes paranoid_wrt more
|
||||
// sensible, and it doesn't seem to make a big different to
|
||||
// performance.
|
||||
return _matrix.compare_to(ot->_matrix, 0.001);
|
||||
|
||||
// Uncomment this line instead to compare matrices pointerwise.
|
||||
// return this - other;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -232,7 +232,7 @@ get_child(TypeHandle type, int index) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Node::
|
||||
sub_render(const AllAttributesWrapper &, AllTransitionsWrapper &,
|
||||
GraphicsStateGuardianBase *) {
|
||||
RenderTraverser *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <luse.h>
|
||||
|
||||
class NodeAttributes;
|
||||
class GraphicsStateGuardianBase;
|
||||
class RenderTraverser;
|
||||
class AllAttributesWrapper;
|
||||
class AllTransitionsWrapper;
|
||||
class BamWriter;
|
||||
@ -70,7 +70,7 @@ public:
|
||||
// It may or may not intercept the render traversal.
|
||||
virtual bool sub_render(const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase);
|
||||
RenderTraverser *trav);
|
||||
virtual bool has_sub_render() const;
|
||||
|
||||
PUBLISHED:
|
||||
|
@ -315,6 +315,20 @@ compare_transitions_to(const NodeRelation *arc) const {
|
||||
return _transitions.compare_to(arc->_transitions);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeRelation::get_last_update
|
||||
// Access: Public
|
||||
// Description: Returns the sequence number associated with the last
|
||||
// time this arc was changed, for instance to change its
|
||||
// state or to reparent it. The only sensible thing you
|
||||
// can do with this is store it and note whether it
|
||||
// increases.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq NodeRelation::
|
||||
get_last_update() const {
|
||||
return _last_update;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeRelation::create_typed_arc
|
||||
// Access: Public, Static
|
||||
|
@ -382,11 +382,11 @@ compose_transitions_from(const NodeTransitions &trans) {
|
||||
bool NodeRelation::
|
||||
sub_render_trans(const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase) {
|
||||
RenderTraverser *trav) {
|
||||
bool all_true = true;
|
||||
NodeTransitions::const_iterator ti;
|
||||
for (ti = _transitions.begin(); ti != _transitions.end(); ++ti) {
|
||||
if (!(*ti).second->sub_render(this, attrib, trans, gsgbase)) {
|
||||
if (!(*ti).second->sub_render(this, attrib, trans, trav)) {
|
||||
all_true = false;
|
||||
}
|
||||
}
|
||||
@ -449,7 +449,7 @@ attach() {
|
||||
|
||||
// Blow out the cache and increment the current update sequence.
|
||||
_net_transitions.clear();
|
||||
++last_graph_update[_type];
|
||||
_last_update = ++last_graph_update[_type];
|
||||
|
||||
_parent->force_bound_stale();
|
||||
mark_bound_stale();
|
||||
@ -491,7 +491,7 @@ detach() {
|
||||
|
||||
// Blow out the cache and increment the current update sequence.
|
||||
_net_transitions.clear();
|
||||
++last_graph_update[_type];
|
||||
_last_update = ++last_graph_update[_type];
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -522,7 +522,7 @@ detach_below() {
|
||||
|
||||
// Blow out the cache and increment the current update sequence.
|
||||
_net_transitions.clear();
|
||||
++last_graph_update[_type];
|
||||
_last_update = ++last_graph_update[_type];
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -544,7 +544,7 @@ changed_transition(TypeHandle trans_type) {
|
||||
if (_net_transitions != (NodeTransitionCache *)NULL) {
|
||||
_net_transitions->clear_transition(trans_type);
|
||||
}
|
||||
last_graph_update[get_type()]++;
|
||||
_last_update = ++last_graph_update[get_type()];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -102,10 +102,12 @@ PUBLISHED:
|
||||
|
||||
INLINE int compare_transitions_to(const NodeRelation *arc) const;
|
||||
|
||||
INLINE UpdateSeq get_last_update() const;
|
||||
|
||||
public:
|
||||
bool sub_render_trans(const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase);
|
||||
RenderTraverser *trav);
|
||||
bool has_sub_render_trans() const;
|
||||
|
||||
public:
|
||||
@ -154,6 +156,12 @@ private:
|
||||
PT(NodeTransitionCache) _net_transitions;
|
||||
Node *_top_subtree;
|
||||
|
||||
// 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
|
||||
// traversal.
|
||||
UpdateSeq _last_update;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory(void);
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
|
@ -36,7 +36,7 @@ get_handle() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodeTransition::
|
||||
sub_render(NodeRelation *, const AllAttributesWrapper &,
|
||||
AllTransitionsWrapper &, GraphicsStateGuardianBase *) {
|
||||
AllTransitionsWrapper &, RenderTraverser *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ class NodeAttribute;
|
||||
class NodeAttributes;
|
||||
class NodeTransitions;
|
||||
class NodeRelation;
|
||||
class GraphicsStateGuardianBase;
|
||||
class RenderTraverser;
|
||||
class AllAttributesWrapper;
|
||||
class AllTransitionsWrapper;
|
||||
class BamWriter;
|
||||
@ -67,7 +67,7 @@ public:
|
||||
virtual bool sub_render(NodeRelation *arc,
|
||||
const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase);
|
||||
RenderTraverser *trav);
|
||||
virtual bool has_sub_render() const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
|
@ -1,13 +1,8 @@
|
||||
// Filename: wrt.cxx
|
||||
// Filename: wrt.I
|
||||
// Created by: drose (26Oct98)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "wrt.h"
|
||||
#include "nodeRelation.h"
|
||||
#include "node.h"
|
||||
#include "config_graph.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_cached_net_transition
|
||||
// Description: Returns the net transition from the root of the
|
||||
@ -148,10 +143,27 @@ get_cached_net_transition(const Node *node,
|
||||
}
|
||||
|
||||
if (parent_arc == (NodeRelation *)NULL) {
|
||||
#ifndef NDEBUG
|
||||
// No, it wasn't mentioned. Issue a warning and use the first
|
||||
// one.
|
||||
graph_cat.warning()
|
||||
<< *node << " has multiple parents; wrt() ambiguous.\n";
|
||||
if (graph_cat.is_warning()) {
|
||||
graph_cat.warning()
|
||||
<< *node << " has " << urp.size() << " parents; wrt() ambiguous.\n"
|
||||
<< " parents are: ";
|
||||
UpRelationPointers::const_iterator urpi;
|
||||
urpi = urp.begin();
|
||||
graph_cat.warning(false) << *(*urpi)->get_parent();
|
||||
urpi++;
|
||||
while (urpi != urp.end()) {
|
||||
graph_cat.warning(false) << ", " << *(*urpi)->get_parent();
|
||||
urpi++;
|
||||
}
|
||||
graph_cat.warning(false) << "\n";
|
||||
}
|
||||
if (ambiguous_wrt_abort) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
parent_arc = *(urp.begin());
|
||||
}
|
||||
}
|
||||
@ -172,6 +184,7 @@ get_cached_net_transition(const Node *node,
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_uncached_net_transition
|
||||
// Description: Returns the net transition from the root of the graph
|
||||
@ -238,10 +251,27 @@ get_uncached_net_transition(const Node *node,
|
||||
}
|
||||
|
||||
if (parent_arc == (NodeRelation *)NULL) {
|
||||
#ifndef NDEBUG
|
||||
// No, it wasn't mentioned. Issue a warning and use the first
|
||||
// one.
|
||||
graph_cat.warning()
|
||||
<< *node << " has multiple parents; wrt() ambiguous.\n";
|
||||
// one.
|
||||
if (graph_cat.is_warning()) {
|
||||
graph_cat.warning()
|
||||
<< *node << " has " << urp.size() << " parents; wrt() ambiguous.\n"
|
||||
<< " parents are:";
|
||||
UpRelationPointers::const_iterator urpi;
|
||||
urpi = urp.begin();
|
||||
graph_cat.warning(false) << *(*urpi)->get_parent();
|
||||
urpi++;
|
||||
while (urpi != urp.end()) {
|
||||
graph_cat.warning(false) << ", " << *(*urpi)->get_parent();
|
||||
urpi++;
|
||||
}
|
||||
graph_cat.warning(false) << "\n";
|
||||
}
|
||||
if (ambiguous_wrt_abort) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
parent_arc = *(urp.begin());
|
||||
}
|
||||
}
|
||||
@ -256,7 +286,7 @@ get_uncached_net_transition(const Node *node,
|
||||
|
||||
result.compose_in_place(next);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -295,8 +325,11 @@ cached_wrt_base(const Node *from,
|
||||
if (check_from_trans.compare_to(net_from_trans) != 0) {
|
||||
graph_cat.warning()
|
||||
<< "WRT cache from " << *from << " is invalid!\n"
|
||||
<< " cached value is " << net_from_trans << "\n"
|
||||
<< " should be " << check_from_trans << "\n";
|
||||
<< " cached value is:\n";
|
||||
net_from_trans.write(graph_cat.warning(false), 4);
|
||||
graph_cat.warning(false)
|
||||
<< " should be:\n";
|
||||
check_from_trans.write(graph_cat.warning(false), 4);
|
||||
net_from_trans = check_from_trans;
|
||||
}
|
||||
|
||||
@ -305,8 +338,11 @@ cached_wrt_base(const Node *from,
|
||||
if (check_to_trans.compare_to(result) != 0) {
|
||||
graph_cat.warning()
|
||||
<< "WRT cache to " << *to << " is invalid!\n"
|
||||
<< " cached value is " << result << "\n"
|
||||
<< " should be " << check_to_trans << "\n";
|
||||
<< " cached value is:\n";
|
||||
result.write(graph_cat.warning(false), 4);
|
||||
graph_cat.warning(false)
|
||||
<< " should be:\n";
|
||||
check_to_trans.write(graph_cat.warning(false), 4);
|
||||
result = check_to_trans;
|
||||
}
|
||||
}
|
||||
@ -315,6 +351,7 @@ cached_wrt_base(const Node *from,
|
||||
result.invert_compose_in_place(net_from_trans);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: uncached_wrt_base
|
||||
// Description: The implementation of wrt_base, below, but never
|
||||
@ -328,8 +365,6 @@ uncached_wrt_base(const Node *from,
|
||||
InputIterator2 to_arcs_begin, InputIterator2 to_arcs_end,
|
||||
TransitionWrapper &result,
|
||||
TypeHandle graph_type) {
|
||||
// UpdateSeq now = last_graph_update[graph_type];
|
||||
|
||||
TransitionWrapper net_from_trans = TransitionWrapper::init_from(result);
|
||||
get_uncached_net_transition(from, from_arcs_begin, from_arcs_end,
|
||||
net_from_trans, graph_type);
|
||||
@ -337,6 +372,7 @@ uncached_wrt_base(const Node *from,
|
||||
result, graph_type);
|
||||
result.invert_compose_in_place(net_from_trans);
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wrt_base
|
||||
@ -362,15 +398,17 @@ wrt_base(const Node *from,
|
||||
InputIterator2 to_arcs_begin, InputIterator2 to_arcs_end,
|
||||
TransitionWrapper &result,
|
||||
TypeHandle graph_type) {
|
||||
if (cache_wrt) {
|
||||
cached_wrt_base(from, from_arcs_begin, from_arcs_end,
|
||||
to, to_arcs_begin, to_arcs_end,
|
||||
result, graph_type);
|
||||
} else {
|
||||
#ifndef NDEBUG
|
||||
if (!cache_wrt) {
|
||||
uncached_wrt_base(from, from_arcs_begin, from_arcs_end,
|
||||
to, to_arcs_begin, to_arcs_end,
|
||||
result, graph_type);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
cached_wrt_base(from, from_arcs_begin, from_arcs_end,
|
||||
to, to_arcs_begin, to_arcs_end,
|
||||
result, graph_type);
|
||||
}
|
||||
|
||||
template<class TransitionWrapper>
|
||||
@ -417,6 +455,7 @@ wrt(const Node *from,
|
||||
result, graph_type);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<class TransitionWrapper>
|
||||
INLINE void
|
||||
uncached_wrt(const Node *from, const Node *to,
|
||||
@ -458,17 +497,78 @@ uncached_wrt(const Node *from,
|
||||
to, to_arcs_begin, to_arcs_end,
|
||||
result, graph_type);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<class TransitionWrapper>
|
||||
Node *
|
||||
wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
|
||||
TypeHandle graph_type) {
|
||||
if (!cache_wrt) {
|
||||
// If we aren't caching wrt, do this the hard way.
|
||||
uncached_wrt(arc->get_child(), &arc, &arc + 1, to, result, graph_type);
|
||||
get_uncached_wrt_subtree(Node *node, Node *to, TransitionWrapper &result,
|
||||
TypeHandle graph_type) {
|
||||
nassertr(node != (Node *)NULL, to);
|
||||
UpRelations::const_iterator uri;
|
||||
uri = node->_parents.find(graph_type);
|
||||
|
||||
if (uri == node->_parents.end()) {
|
||||
// This node has no parents. Stop here.
|
||||
result.make_identity();
|
||||
return to;
|
||||
}
|
||||
|
||||
const UpRelationPointers &urp = (*uri).second;
|
||||
if (urp.empty()) {
|
||||
// Again, no parents. Stop here.
|
||||
result.make_identity();
|
||||
return to;
|
||||
}
|
||||
|
||||
if (node == to) {
|
||||
// We've reached our stopping point. Stop here.
|
||||
result.make_identity();
|
||||
return node;
|
||||
}
|
||||
|
||||
if (urp.size() != 1) {
|
||||
// There are multiple parents, so stop here.
|
||||
result.make_identity();
|
||||
return node;
|
||||
}
|
||||
|
||||
const NodeRelation *parent_arc = *(urp.begin());
|
||||
|
||||
Node *stop =
|
||||
get_uncached_wrt_subtree(parent_arc->get_parent(), to,
|
||||
result, graph_type);
|
||||
|
||||
TransitionWrapper next = TransitionWrapper::init_from(result);
|
||||
next.extract_from(parent_arc);
|
||||
|
||||
result.compose_in_place(next);
|
||||
|
||||
return stop;
|
||||
}
|
||||
|
||||
template<class TransitionWrapper>
|
||||
INLINE Node *
|
||||
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);
|
||||
|
||||
TransitionWrapper next = TransitionWrapper::init_from(result);
|
||||
next.extract_from(arc);
|
||||
|
||||
result.compose_in_place(next);
|
||||
|
||||
return stop;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class TransitionWrapper>
|
||||
Node *
|
||||
cached_wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
|
||||
TypeHandle graph_type) {
|
||||
UpdateSeq now = last_graph_update[graph_type];
|
||||
|
||||
// First, determine the net transition up to the top of the current
|
||||
@ -507,8 +607,34 @@ wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
|
||||
// Now check the results.
|
||||
TransitionWrapper check_trans =
|
||||
TransitionWrapper::init_from(result);
|
||||
uncached_wrt(arc->get_child(), &arc, &arc + 1, to, check_trans,
|
||||
graph_type);
|
||||
Node *top_subtree_3 =
|
||||
uncached_wrt_subtree(arc, to, check_trans, graph_type);
|
||||
|
||||
if (top_subtree_3 != top_subtree) {
|
||||
graph_cat.warning()
|
||||
<< "WRT subtree cache from " << *arc->get_child() << " to ";
|
||||
if (to == (Node *)NULL) {
|
||||
graph_cat.warning(false) << "(top)";
|
||||
} else {
|
||||
graph_cat.warning(false) << *to;
|
||||
}
|
||||
graph_cat.warning(false)
|
||||
<< " computes incorrect top_subtree!\n"
|
||||
<< " computed ";
|
||||
if (top_subtree == (Node *)NULL) {
|
||||
graph_cat.warning(false) << "(top)\n";
|
||||
} else {
|
||||
graph_cat.warning(false) << *top_subtree << "\n";
|
||||
}
|
||||
graph_cat.warning(false)
|
||||
<< " should be ";
|
||||
if (top_subtree_3 == (Node *)NULL) {
|
||||
graph_cat.warning(false) << "(top)\n";
|
||||
} else {
|
||||
graph_cat.warning(false) << *top_subtree_3 << "\n";
|
||||
}
|
||||
top_subtree = top_subtree_3;
|
||||
}
|
||||
|
||||
if (check_trans.compare_to(result) != 0) {
|
||||
graph_cat.warning()
|
||||
@ -520,8 +646,11 @@ wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
|
||||
}
|
||||
graph_cat.warning(false)
|
||||
<< " is invalid!\n"
|
||||
<< " cached value is " << result << "\n"
|
||||
<< " should be " << check_trans << "\n";
|
||||
<< " cached value is:\n";
|
||||
result.write(graph_cat.warning(false), 4);
|
||||
graph_cat.warning(false)
|
||||
<< " should be:\n";
|
||||
check_trans.write(graph_cat.warning(false), 4);
|
||||
result = check_trans;
|
||||
}
|
||||
}
|
||||
@ -529,3 +658,18 @@ wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
|
||||
|
||||
return top_subtree;
|
||||
}
|
||||
|
||||
template<class TransitionWrapper>
|
||||
INLINE Node *
|
||||
wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
|
||||
TypeHandle graph_type) {
|
||||
#ifndef NDEBUG
|
||||
if (!cache_wrt) {
|
||||
// If we aren't caching wrt, do this the hard way.
|
||||
return uncached_wrt_subtree(arc, to, result, graph_type);
|
||||
}
|
||||
#endif
|
||||
return cached_wrt_subtree(arc, to, result, graph_type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,6 +8,10 @@
|
||||
|
||||
#include <pandabase.h>
|
||||
|
||||
#include "nodeRelation.h"
|
||||
#include "node.h"
|
||||
#include "config_graph.h"
|
||||
|
||||
#include <typeHandle.h>
|
||||
|
||||
class Node;
|
||||
@ -57,6 +61,7 @@ wrt(const Node *from,
|
||||
InputIterator2 to_arcs_begin, InputIterator2 to_arcs_end,
|
||||
TransitionWrapper &result, TypeHandle graph_type);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Similar to the above, but always uncached. Useful mainly for
|
||||
// debugging, or when you suspect the cache is invalid. Also note
|
||||
// that you can configure 'cache-wrt' or 'paranoid-wrt' to disable or
|
||||
@ -87,17 +92,18 @@ uncached_wrt(const Node *from,
|
||||
const Node *to,
|
||||
InputIterator2 to_arcs_begin, InputIterator2 to_arcs_end,
|
||||
TransitionWrapper &result, TypeHandle graph_type);
|
||||
#endif
|
||||
|
||||
|
||||
// The following function is a bit different. Rather than computing
|
||||
// the relative transform between two nodes, it computes the net
|
||||
// transform along the shortest unambigous path from the indicated arc
|
||||
// towards the root. That is, this is the wrt between the child of
|
||||
// the indicated arc and the closest ancestor node that has multiple
|
||||
// parents, or the root of the scene graph if the arc only appears
|
||||
// once in the scene graph. The return value is the particular node
|
||||
// with multiple parents at which the wrt stopped, or NULL if it went
|
||||
// all the way to the root.
|
||||
// transform along the shortest unambiguous path from the indicated
|
||||
// arc towards the root. That is, this is the wrt between the child
|
||||
// of the indicated arc and the closest ancestor node that has
|
||||
// multiple parents, or the root of the scene graph if the arc only
|
||||
// appears once in the scene graph. The return value is the
|
||||
// particular node with multiple parents at which the wrt stopped, or
|
||||
// NULL if it went all the way to the root.
|
||||
|
||||
// This is extended just a bit further by allowing the user to specify
|
||||
// a "to" node. This must be either NULL, or the expected top node,
|
||||
@ -113,7 +119,7 @@ uncached_wrt(const Node *from,
|
||||
// CullTraverser) that needs to cache a wrt-type value for many nodes
|
||||
// across the entire tree.
|
||||
template<class TransitionWrapper>
|
||||
Node *
|
||||
INLINE Node *
|
||||
wrt_subtree(NodeRelation *arc, Node *to, TransitionWrapper &result,
|
||||
TypeHandle graph_type);
|
||||
|
||||
|
@ -18,7 +18,8 @@
|
||||
|
||||
GuiManager::GuiMap* GuiManager::_map = (GuiManager::GuiMap*)0L;
|
||||
|
||||
GuiManager* GuiManager::get_ptr(GraphicsWindow* w, MouseAndKeyboard* mak) {
|
||||
GuiManager* GuiManager::get_ptr(GraphicsWindow* w, MouseAndKeyboard* mak,
|
||||
Node *root2d) {
|
||||
GuiManager* ret;
|
||||
if (_map == (GuiMap*)0L) {
|
||||
if (gui_cat->is_debug())
|
||||
@ -83,30 +84,36 @@ GuiManager* GuiManager::get_ptr(GraphicsWindow* w, MouseAndKeyboard* mak) {
|
||||
<< watcher->get_leave_pattern()
|
||||
<< "' with 'gui-out-%r'" << endl;
|
||||
watcher->set_leave_pattern("gui-out-%r");
|
||||
// next, create a 2d layer for the GUI stuff to live in.
|
||||
Node* root2d_top = new NamedNode("GUI_top");
|
||||
Node* root2d = new NamedNode("GUI");
|
||||
NodeRelation* root2d_arc = new RenderRelation(root2d_top, root2d);
|
||||
root2d_arc->set_transition(new DepthTestTransition(DepthTestProperty::M_none), 1);
|
||||
root2d_arc->set_transition(new DepthWriteTransition(DepthWriteTransition::off()), 1);
|
||||
root2d_arc->set_transition(new LightTransition(LightTransition::all_off()), 1);
|
||||
root2d_arc->set_transition(new MaterialTransition(MaterialTransition::off()), 1);
|
||||
root2d_arc->set_transition(new CullFaceTransition(CullFaceProperty::M_cull_none), 1);
|
||||
PT(Camera) cam = new Camera("GUI_cam");
|
||||
new RenderRelation(root2d, cam);
|
||||
cam->set_scene(root2d_top);
|
||||
Frustumf frust2d;
|
||||
frust2d.make_ortho_2D();
|
||||
cam->set_projection(OrthoProjection(frust2d));
|
||||
GraphicsChannel *chan = w->get_channel(0); // root/full-window channel
|
||||
nassertr(chan != (GraphicsChannel*)0L, NULL);
|
||||
GraphicsLayer *layer = chan->make_layer();
|
||||
nassertr(layer != (GraphicsLayer*)0L, NULL);
|
||||
DisplayRegion *dr = layer->make_display_region();
|
||||
nassertr(dr != (DisplayRegion*)0L, NULL);
|
||||
dr->set_camera(cam);
|
||||
if (gui_cat->is_debug())
|
||||
gui_cat->debug() << "2D layer created" << endl;
|
||||
|
||||
if (root2d == (Node *)NULL) {
|
||||
// If we weren't given a 2-d scene graph, then create one now.
|
||||
// It lives in its own layer.
|
||||
|
||||
Node* root2d_top = new NamedNode("GUI_top");
|
||||
root2d = new NamedNode("GUI");
|
||||
NodeRelation* root2d_arc = new RenderRelation(root2d_top, root2d);
|
||||
root2d_arc->set_transition(new DepthTestTransition(DepthTestProperty::M_none), 1);
|
||||
root2d_arc->set_transition(new DepthWriteTransition(DepthWriteTransition::off()), 1);
|
||||
root2d_arc->set_transition(new LightTransition(LightTransition::all_off()), 1);
|
||||
root2d_arc->set_transition(new MaterialTransition(MaterialTransition::off()), 1);
|
||||
root2d_arc->set_transition(new CullFaceTransition(CullFaceProperty::M_cull_none), 1);
|
||||
PT(Camera) cam = new Camera("GUI_cam");
|
||||
new RenderRelation(root2d, cam);
|
||||
cam->set_scene(root2d_top);
|
||||
Frustumf frust2d;
|
||||
frust2d.make_ortho_2D();
|
||||
cam->set_projection(OrthoProjection(frust2d));
|
||||
GraphicsChannel *chan = w->get_channel(0); // root/full-window channel
|
||||
nassertr(chan != (GraphicsChannel*)0L, NULL);
|
||||
GraphicsLayer *layer = chan->make_layer();
|
||||
nassertr(layer != (GraphicsLayer*)0L, NULL);
|
||||
DisplayRegion *dr = layer->make_display_region();
|
||||
nassertr(dr != (DisplayRegion*)0L, NULL);
|
||||
dr->set_camera(cam);
|
||||
if (gui_cat->is_debug())
|
||||
gui_cat->debug() << "2D layer created" << endl;
|
||||
}
|
||||
|
||||
// now make the manager for this window
|
||||
ret = new GuiManager(watcher, root2d);
|
||||
if (gui_cat->is_debug())
|
||||
|
@ -32,7 +32,8 @@ private:
|
||||
INLINE GuiManager(MouseWatcher*, Node*);
|
||||
|
||||
PUBLISHED:
|
||||
static GuiManager* get_ptr(GraphicsWindow*, MouseAndKeyboard*);
|
||||
static GuiManager* get_ptr(GraphicsWindow*, MouseAndKeyboard*,
|
||||
Node *root2d = (Node *)NULL);
|
||||
|
||||
void add_region(GuiRegion*);
|
||||
void add_label(GuiLabel*);
|
||||
|
@ -76,7 +76,7 @@ write(ostream &out, int indent_level) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
float Spotlight::get_cutoff_angle(void) const
|
||||
{
|
||||
const Projection* proj = get_projection();
|
||||
Projection* proj = ((ProjectionNode *)this)->get_projection();
|
||||
Frustumf frustum;
|
||||
float cutoff = 0;
|
||||
if (proj->get_type() == PerspectiveProjection::get_class_type()) {
|
||||
|
@ -11,7 +11,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq::
|
||||
UpdateSeq() {
|
||||
_seq = (unsigned)SC_initial;
|
||||
_seq = (unsigned int)SC_initial;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -32,7 +32,19 @@ initial() {
|
||||
INLINE UpdateSeq UpdateSeq::
|
||||
old() {
|
||||
UpdateSeq result;
|
||||
result._seq = (unsigned)SC_old;
|
||||
result._seq = (unsigned int)SC_old;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: UpdateSeq::fresh (named constructor)
|
||||
// Access: Public, Static
|
||||
// Description: Returns an UpdateSeq in the 'fresh' state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq UpdateSeq::
|
||||
fresh() {
|
||||
UpdateSeq result;
|
||||
result._seq = (unsigned int)SC_fresh;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -64,7 +76,7 @@ operator = (const UpdateSeq ©) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void UpdateSeq::
|
||||
clear() {
|
||||
_seq = (unsigned)SC_initial;
|
||||
_seq = (unsigned int)SC_initial;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -75,7 +87,7 @@ clear() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool UpdateSeq::
|
||||
is_initial() const {
|
||||
return _seq == SC_initial;
|
||||
return _seq == (unsigned int)SC_initial;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -85,18 +97,37 @@ is_initial() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool UpdateSeq::
|
||||
is_old() const {
|
||||
return _seq == SC_old;
|
||||
return _seq == (unsigned int)SC_old;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: UpdateSeq::is_fresh
|
||||
// Access: Public
|
||||
// Description: Returns true if the UpdateSeq is in the 'fresh'
|
||||
// state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool UpdateSeq::
|
||||
is_fresh() const {
|
||||
return _seq == (unsigned int)SC_fresh;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: UpdateSeq::is_special
|
||||
// Access: Public
|
||||
// Description: Returns true if the UpdateSeq is in any special
|
||||
// states, i.e. 'initial' or 'old'.
|
||||
// states, i.e. 'initial', 'old', or 'fresh'.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool UpdateSeq::
|
||||
is_special() const {
|
||||
return _seq <= (unsigned)SC_old;
|
||||
switch (_seq) {
|
||||
case (unsigned int)SC_initial:
|
||||
case (unsigned int)SC_old:
|
||||
case (unsigned int)SC_fresh:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -127,10 +158,12 @@ operator != (const UpdateSeq &other) const {
|
||||
INLINE bool UpdateSeq::
|
||||
operator < (const UpdateSeq &other) const {
|
||||
// The special cases of SC_initial or SC_old are less than all other
|
||||
// non-special numbers, and SC_initial is less than SC_old. For all
|
||||
// other cases, we use a circular comparision such that n < m iff
|
||||
// (signed)(n - m) < 0.
|
||||
return (is_special() || other.is_special()) ? (_seq < other._seq) :
|
||||
// non-special numbers, and SC_initial is less than SC_old. The
|
||||
// special case of SC_fresh is greater than all other non-special
|
||||
// numbers. For all other cases, we use a circular comparision such
|
||||
// that n < m iff (signed)(n - m) < 0.
|
||||
return
|
||||
(is_special() || other.is_special()) ? (_seq < other._seq) :
|
||||
((signed int)(_seq - other._seq) < 0);
|
||||
}
|
||||
|
||||
@ -155,7 +188,7 @@ operator ++ () {
|
||||
if (is_special()) {
|
||||
// Oops, wraparound. We don't want to confuse the new value
|
||||
// with our special cases.
|
||||
_seq = (unsigned)SC_old + 1;
|
||||
_seq = (unsigned int)SC_old + 1;
|
||||
}
|
||||
|
||||
return *this;
|
||||
@ -189,6 +222,10 @@ output(ostream &out) const {
|
||||
out << "old";
|
||||
break;
|
||||
|
||||
case SC_fresh:
|
||||
out << "fresh";
|
||||
break;
|
||||
|
||||
default:
|
||||
out << _seq;
|
||||
}
|
||||
|
@ -22,15 +22,17 @@
|
||||
// first created. This sequence is older than any other
|
||||
// sequence number. Secondly, a sequence number may be
|
||||
// explicitly set to 'old'. This is older than any
|
||||
// other sequence number except 'initial'. All other
|
||||
// sequences are numeric and are monotonically
|
||||
// increasing.
|
||||
// other sequence number except 'initial'. Finally, we
|
||||
// have the explicit number 'fresh', which is newer
|
||||
// than any other sequence number. All other sequences
|
||||
// are numeric and are monotonically increasing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA UpdateSeq {
|
||||
public:
|
||||
INLINE UpdateSeq();
|
||||
INLINE static UpdateSeq initial();
|
||||
INLINE static UpdateSeq old();
|
||||
INLINE static UpdateSeq fresh();
|
||||
|
||||
INLINE UpdateSeq(const UpdateSeq ©);
|
||||
INLINE UpdateSeq &operator = (const UpdateSeq ©);
|
||||
@ -39,6 +41,7 @@ public:
|
||||
|
||||
INLINE bool is_initial() const;
|
||||
INLINE bool is_old() const;
|
||||
INLINE bool is_fresh() const;
|
||||
INLINE bool is_special() const;
|
||||
|
||||
INLINE bool operator == (const UpdateSeq &other) const;
|
||||
@ -55,9 +58,10 @@ private:
|
||||
enum SpecialCases {
|
||||
SC_initial = 0,
|
||||
SC_old = 1,
|
||||
SC_fresh = ~0,
|
||||
};
|
||||
|
||||
unsigned _seq;
|
||||
unsigned int _seq;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const UpdateSeq &value);
|
||||
|
@ -243,7 +243,7 @@ render_frame(const AllAttributesWrapper &initial_state) {
|
||||
// may be modified during rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RIBGraphicsStateGuardian::
|
||||
render_scene(Node *root, const ProjectionNode *projnode,
|
||||
render_scene(Node *root, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state) {
|
||||
_current_root_node = root;
|
||||
|
||||
@ -262,10 +262,10 @@ render_scene(Node *root, const ProjectionNode *projnode,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RIBGraphicsStateGuardian::
|
||||
render_subgraph(RenderTraverser *traverser,
|
||||
Node *subgraph, const ProjectionNode *projnode,
|
||||
Node *subgraph, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state,
|
||||
const AllTransitionsWrapper &net_trans) {
|
||||
const ProjectionNode *old_projection_node = _current_projection_node;
|
||||
ProjectionNode *old_projection_node = _current_projection_node;
|
||||
_current_projection_node = projnode;
|
||||
|
||||
(*_output) << "\n";
|
||||
|
@ -40,10 +40,10 @@ public:
|
||||
virtual void prepare_display_region();
|
||||
|
||||
virtual void render_frame(const AllAttributesWrapper &initial_state);
|
||||
virtual void render_scene(Node *root, const ProjectionNode *projnode,
|
||||
virtual void render_scene(Node *root, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state);
|
||||
virtual void render_subgraph(RenderTraverser *traverser,
|
||||
Node *subgraph, const ProjectionNode *projnode,
|
||||
Node *subgraph, ProjectionNode *projnode,
|
||||
const AllAttributesWrapper &initial_state,
|
||||
const AllTransitionsWrapper &net_trans);
|
||||
virtual void render_subgraph(RenderTraverser *traverser,
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "renderRelation.h"
|
||||
|
||||
#include <graphicsStateGuardian.h>
|
||||
#include <renderTraverser.h>
|
||||
#include <projectionNode.h>
|
||||
#include <look_at.h>
|
||||
#include <nodeTransitionWrapper.h>
|
||||
@ -39,9 +40,9 @@ make_copy() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool BillboardTransition::
|
||||
sub_render(NodeRelation *arc, const AllAttributesWrapper &,
|
||||
AllTransitionsWrapper &trans, GraphicsStateGuardianBase *gsgbase) {
|
||||
AllTransitionsWrapper &trans, RenderTraverser *trav) {
|
||||
Node *node = arc->get_child();
|
||||
GraphicsStateGuardian *gsg = DCAST(GraphicsStateGuardian, gsgbase);
|
||||
GraphicsStateGuardian *gsg = trav->get_gsg();
|
||||
|
||||
// Get the current camera from the gsg
|
||||
const ProjectionNode *camera = gsg->get_current_projection_node();
|
||||
@ -50,7 +51,8 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &,
|
||||
// And the relative coordinate space.
|
||||
LMatrix4f rel_mat;
|
||||
NodeTransitionWrapper ntw(TransformTransition::get_class_type());
|
||||
wrt(camera, node, (&arc), (&arc) + 1, ntw, RenderRelation::get_class_type());
|
||||
wrt(camera, node, trav->begin(), trav->end(),
|
||||
ntw, RenderRelation::get_class_type());
|
||||
TransformTransition *tt;
|
||||
if (!get_transition_into(tt, ntw)) {
|
||||
// No relative transform.
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
virtual bool sub_render(NodeRelation *arc,
|
||||
const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase);
|
||||
RenderTraverser *trav);
|
||||
virtual bool has_sub_render() const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <allTransitionsWrapper.h>
|
||||
#include <allAttributesWrapper.h>
|
||||
#include <graphicsStateGuardian.h>
|
||||
#include <renderTraverser.h>
|
||||
#include <geomSphere.h>
|
||||
|
||||
TypeHandle DrawBoundsTransition::_type_handle;
|
||||
@ -70,8 +71,8 @@ make_copy() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DrawBoundsTransition::
|
||||
sub_render(NodeRelation *arc, const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &, GraphicsStateGuardianBase *gsgbase) {
|
||||
GraphicsStateGuardian *gsg = DCAST(GraphicsStateGuardian, gsgbase);
|
||||
AllTransitionsWrapper &, RenderTraverser *trav) {
|
||||
GraphicsStateGuardian *gsg = trav->get_gsg();
|
||||
|
||||
const BoundingVolume &vol = arc->get_bound();
|
||||
if (!vol.is_empty() && !vol.is_infinite()) {
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
virtual bool sub_render(NodeRelation *arc,
|
||||
const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase);
|
||||
RenderTraverser *trav);
|
||||
virtual bool has_sub_render() const;
|
||||
|
||||
NodeAttributes _outside_attrib;
|
||||
|
@ -29,7 +29,7 @@ make_copy() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PruneTransition::
|
||||
sub_render(NodeRelation *, const AllAttributesWrapper &,
|
||||
AllTransitionsWrapper &, GraphicsStateGuardianBase *) {
|
||||
AllTransitionsWrapper &, RenderTraverser *) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
virtual bool sub_render(NodeRelation *arc,
|
||||
const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase);
|
||||
RenderTraverser *trav);
|
||||
virtual bool has_sub_render() const;
|
||||
|
||||
public:
|
||||
|
@ -30,26 +30,43 @@ make_copy() const {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: set_projection
|
||||
// Access:
|
||||
// Description:
|
||||
// Access: Public
|
||||
// Description: Sets up the ProjectionNode using a copy of the
|
||||
// indicated Projection. If the original Projection is
|
||||
// changed or destroyed, this ProjectionNode is not
|
||||
// affected.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ProjectionNode::set_projection( const Projection& projection )
|
||||
{
|
||||
_projection = projection.make_copy();
|
||||
void ProjectionNode::
|
||||
set_projection(const Projection &projection) {
|
||||
_projection = projection.make_copy();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: share_projection
|
||||
// Access: Public
|
||||
// Description: This is similar to set_projection(), but the
|
||||
// Projection is assigned by pointer. If the original
|
||||
// Projection is changed, this ProjectionNode is
|
||||
// immediately affected.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ProjectionNode::
|
||||
share_projection(Projection *projection) {
|
||||
_projection = projection;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_projection
|
||||
// Access:
|
||||
// Description:
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to particular Projection associated
|
||||
// with this ProjectionNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const Projection* ProjectionNode::get_projection( void ) const
|
||||
{
|
||||
if (_projection == NULL) {
|
||||
// If we have no projection yet, just return a default projection.
|
||||
Projection *ProjectionNode::
|
||||
get_projection() {
|
||||
if (_projection == (Projection *)NULL) {
|
||||
// If we have no projection yet, give us a default Projection.
|
||||
Frustumf f;
|
||||
static PerspectiveProjection default_projection(f);
|
||||
return &default_projection;
|
||||
_projection = new PerspectiveProjection(f);
|
||||
}
|
||||
|
||||
return _projection;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA ProjectionNode : public NamedNode {
|
||||
PUBLISHED:
|
||||
INLINE ProjectionNode(const string& name = "");
|
||||
INLINE ProjectionNode(const string &name = "");
|
||||
|
||||
public:
|
||||
INLINE ProjectionNode(const ProjectionNode ©);
|
||||
@ -33,12 +33,12 @@ public:
|
||||
virtual Node *make_copy() const;
|
||||
|
||||
PUBLISHED:
|
||||
void set_projection( const Projection& projection );
|
||||
const Projection* get_projection( void ) const;
|
||||
void set_projection(const Projection &projection);
|
||||
void share_projection(Projection *projection);
|
||||
Projection *get_projection();
|
||||
|
||||
protected:
|
||||
|
||||
PT(Projection) _projection;
|
||||
PT(Projection) _projection;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -7,13 +7,76 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderTraverser::Constructor
|
||||
// Access: Public
|
||||
// Description: Creates a new RenderTraverser ready to traverse a
|
||||
// scene graph beginning at the end of the arc chain
|
||||
// indicated in arc_chain (either an empty ArcChain, or
|
||||
// the result of get_arc_chain() from some other
|
||||
// traverser), with the indicated graph_type (usually
|
||||
// RenderRelation) and for the indicated gsg.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE RenderTraverser::
|
||||
RenderTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type,
|
||||
const ArcChain &arc_chain) :
|
||||
_gsg(gsg),
|
||||
_graph_type(graph_type),
|
||||
_arc_chain(arc_chain)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderTraverser::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE RenderTraverser::
|
||||
RenderTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type) :
|
||||
_gsg(gsg),
|
||||
_graph_type(graph_type)
|
||||
{
|
||||
~RenderTraverser() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderTraverser::get_arc_chain
|
||||
// Access: Public
|
||||
// Description: Returns the complete chain of arcs from the root to
|
||||
// the current node in the traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const ArcChain &RenderTraverser::
|
||||
get_arc_chain() const {
|
||||
return _arc_chain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderTraverser::begin
|
||||
// Access: Public
|
||||
// Description: Returns an iterator that can be used to traverse the
|
||||
// list of arcs from the root to the current node in the
|
||||
// traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE RenderTraverser::const_iterator RenderTraverser::
|
||||
begin() const {
|
||||
return _arc_chain.begin();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderTraverser::end
|
||||
// Access: Public
|
||||
// Description: Returns an iterator that can be used to traverse the
|
||||
// list of arcs from the root to the current node in the
|
||||
// traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE RenderTraverser::const_iterator RenderTraverser::
|
||||
end() const {
|
||||
return _arc_chain.end();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderTraverser::empty
|
||||
// Access: Public
|
||||
// Description: Returns true if the list of arcs returned by begin()
|
||||
// .. end() is empty (i.e. begin() == end()), false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool RenderTraverser::
|
||||
empty() const {
|
||||
return _arc_chain.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -35,3 +98,29 @@ INLINE TypeHandle RenderTraverser::
|
||||
get_graph_type() const {
|
||||
return _graph_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderTraverser::mark_forward_arc
|
||||
// Access: Public
|
||||
// Description: To be called by the derived class's forward_arc()
|
||||
// method, this updates the list of arcs traversed to
|
||||
// include the current arc.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void RenderTraverser::
|
||||
mark_forward_arc(NodeRelation *arc) {
|
||||
_arc_chain.push_back(arc);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderTraverser::mark_backward_arc
|
||||
// Access: Public
|
||||
// Description: To be called by the derived class's forward_arc()
|
||||
// method, this updates the list of arcs traversed to
|
||||
// remove the current arc.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void RenderTraverser::
|
||||
mark_backward_arc(NodeRelation *arc) {
|
||||
nassertv(!_arc_chain.empty());
|
||||
nassertv(_arc_chain.back() == arc);
|
||||
_arc_chain.pop_back();
|
||||
}
|
||||
|
@ -8,11 +8,14 @@
|
||||
|
||||
#include <pandabase.h>
|
||||
|
||||
#include <arcChain.h>
|
||||
#include <typeHandle.h>
|
||||
#include <typedReferenceCount.h>
|
||||
#include <notify.h>
|
||||
|
||||
class GraphicsStateGuardian;
|
||||
class Node;
|
||||
class NodeRelation;
|
||||
class AllAttributesWrapper;
|
||||
class AllTransitionsWrapper;
|
||||
|
||||
@ -26,7 +29,18 @@ class AllTransitionsWrapper;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA RenderTraverser : public TypedReferenceCount {
|
||||
public:
|
||||
INLINE RenderTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type);
|
||||
INLINE RenderTraverser(GraphicsStateGuardian *gsg,
|
||||
TypeHandle graph_type,
|
||||
const ArcChain &arc_chain);
|
||||
INLINE ~RenderTraverser();
|
||||
|
||||
typedef ArcChain::iterator iterator;
|
||||
typedef ArcChain::const_iterator const_iterator;
|
||||
|
||||
INLINE const ArcChain &get_arc_chain() const;
|
||||
INLINE const_iterator begin() const;
|
||||
INLINE const_iterator end() const;
|
||||
INLINE bool empty() const;
|
||||
|
||||
PUBLISHED:
|
||||
INLINE GraphicsStateGuardian *get_gsg() const;
|
||||
@ -41,9 +55,16 @@ PUBLISHED:
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
protected:
|
||||
// These methods are to be called by derived classes as we traverse
|
||||
// each arc. They update the arc list returned by begin()/end().
|
||||
INLINE void mark_forward_arc(NodeRelation *arc);
|
||||
INLINE void mark_backward_arc(NodeRelation *arc);
|
||||
|
||||
protected:
|
||||
GraphicsStateGuardian *_gsg;
|
||||
TypeHandle _graph_type;
|
||||
ArcChain _arc_chain;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "config_sgraphutil.h"
|
||||
#include "frustumCullTraverser.h"
|
||||
|
||||
#include <wrt.h>
|
||||
#include <geomNode.h>
|
||||
#include <graphicsStateGuardian.h>
|
||||
#include <geometricBoundingVolume.h>
|
||||
@ -18,6 +19,8 @@
|
||||
#include <transformTransition.h>
|
||||
#include <allAttributesWrapper.h>
|
||||
#include <allTransitionsWrapper.h>
|
||||
#include <transformTransition.h>
|
||||
#include <nodeTransitionWrapper.h>
|
||||
#include <decalTransition.h>
|
||||
#include <decalAttribute.h>
|
||||
#include <pStatTimer.h>
|
||||
@ -32,8 +35,9 @@ PStatCollector DirectRenderTraverser::_draw_pcollector =
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DirectRenderTraverser::
|
||||
DirectRenderTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type) :
|
||||
RenderTraverser(gsg, graph_type)
|
||||
DirectRenderTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type,
|
||||
const ArcChain &arc_chain) :
|
||||
RenderTraverser(gsg, graph_type, arc_chain)
|
||||
{
|
||||
}
|
||||
|
||||
@ -72,7 +76,22 @@ traverse(Node *root,
|
||||
level_state._decal_mode = decal_attrib->is_on();
|
||||
}
|
||||
|
||||
fc_traverse(root, *this, render_state, level_state,
|
||||
// Determine the relative transform matrix from the camera to our
|
||||
// starting node. This is important for proper view-frustum
|
||||
// culling.
|
||||
LMatrix4f rel_from_camera;
|
||||
NodeTransitionWrapper ntw(TransformTransition::get_class_type());
|
||||
wrt(_gsg->get_current_projection_node(), root, begin(), end(),
|
||||
ntw, get_graph_type());
|
||||
const TransformTransition *tt;
|
||||
if (get_transition_into(tt, ntw)) {
|
||||
rel_from_camera = tt->get_matrix();
|
||||
} else {
|
||||
// No relative transform.
|
||||
rel_from_camera = LMatrix4f::ident_mat();
|
||||
}
|
||||
|
||||
fc_traverse(root, rel_from_camera, *this, render_state, level_state,
|
||||
_gsg, _graph_type);
|
||||
|
||||
if (level_state._decal_mode &&
|
||||
@ -100,7 +119,7 @@ reached_node(Node *node, AllAttributesWrapper &render_state,
|
||||
|
||||
AllTransitionsWrapper new_trans;
|
||||
|
||||
if (!node->sub_render(render_state, new_trans, _gsg)) {
|
||||
if (!node->sub_render(render_state, new_trans, this)) {
|
||||
return false;
|
||||
}
|
||||
render_state.apply_in_place(new_trans);
|
||||
@ -146,16 +165,22 @@ forward_arc(NodeRelation *arc, AllTransitionsWrapper &trans,
|
||||
// return true. For Shader types, this will fire off another render
|
||||
// and return false.
|
||||
|
||||
mark_forward_arc(arc);
|
||||
|
||||
AllTransitionsWrapper::const_iterator nti;
|
||||
for (nti = trans.begin(); nti != trans.end(); ++nti) {
|
||||
NodeTransition *t = (*nti).second.get_trans();
|
||||
AllTransitionsWrapper new_trans;
|
||||
if (!t->sub_render(arc, post, new_trans, _gsg)) {
|
||||
if (!t->sub_render(arc, post, new_trans, this)) {
|
||||
carry_on = false;
|
||||
}
|
||||
post.apply_in_place(new_trans);
|
||||
}
|
||||
|
||||
if (!carry_on) {
|
||||
mark_backward_arc(arc);
|
||||
}
|
||||
|
||||
return carry_on;
|
||||
}
|
||||
|
||||
@ -169,6 +194,7 @@ void DirectRenderTraverser::
|
||||
backward_arc(NodeRelation *arc, AllTransitionsWrapper &,
|
||||
AllAttributesWrapper &, AllAttributesWrapper &post,
|
||||
const DirectRenderLevelState &level_state) {
|
||||
mark_backward_arc(arc);
|
||||
if (level_state._decal_mode) {
|
||||
// Reset the state to redraw the base geometry.
|
||||
_gsg->set_state(post.get_attributes(), true);
|
||||
|
@ -36,7 +36,8 @@ class EXPCL_PANDA DirectRenderTraverser :
|
||||
public RenderTraverser,
|
||||
public TraverserVisitor<AllTransitionsWrapper, DirectRenderLevelState> {
|
||||
public:
|
||||
DirectRenderTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type);
|
||||
DirectRenderTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type,
|
||||
const ArcChain &arc_chain = ArcChain());
|
||||
virtual ~DirectRenderTraverser();
|
||||
|
||||
virtual void traverse(Node *root,
|
||||
|
@ -4,11 +4,11 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "frustumCullTraverser.h"
|
||||
#include "get_rel_pos.h"
|
||||
#include "config_sgraphutil.h"
|
||||
|
||||
#include <notify.h>
|
||||
#include <nodeTransitionWrapper.h>
|
||||
#include <transformTransition.h>
|
||||
#include <wrt.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -18,7 +18,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Visitor, class LevelState>
|
||||
FrustumCullTraverser<Visitor, LevelState>::
|
||||
FrustumCullTraverser(Node *root,
|
||||
FrustumCullTraverser(Node *root, const LMatrix4f &rel_from_camera,
|
||||
Visitor &visitor,
|
||||
const AttributeWrapper &initial_render_state,
|
||||
const LevelState &initial_level_state,
|
||||
@ -36,7 +36,7 @@ FrustumCullTraverser(Node *root,
|
||||
// If we're to be performing view-frustum culling, determine the
|
||||
// bounding volume associated with the current viewing frustum.
|
||||
|
||||
const ProjectionNode *camera = _gsg->get_current_projection_node();
|
||||
ProjectionNode *camera = _gsg->get_current_projection_node();
|
||||
if (camera != (const ProjectionNode *)NULL) {
|
||||
const Projection *proj = camera->get_projection();
|
||||
nassertv(proj != (const Projection *)NULL);
|
||||
@ -49,17 +49,14 @@ FrustumCullTraverser(Node *root,
|
||||
}
|
||||
}
|
||||
|
||||
LMatrix4f mat;
|
||||
get_rel_mat(_gsg->get_current_projection_node(), root, mat);
|
||||
|
||||
local_frustum = DCAST(GeometricBoundingVolume, _view_frustum->make_copy());
|
||||
local_frustum->xform(mat);
|
||||
local_frustum->xform(rel_from_camera);
|
||||
|
||||
if (sgraphutil_cat.is_spam()) {
|
||||
sgraphutil_cat.spam()
|
||||
<< "Beginning frustum cull, frustum is: " << *local_frustum << "\n"
|
||||
<< "Transform is:\n";
|
||||
mat.write(sgraphutil_cat.spam(false), 2);
|
||||
rel_from_camera.write(sgraphutil_cat.spam(false), 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
typedef TYPENAME Visitor::TransitionWrapper TransitionWrapper;
|
||||
typedef TYPENAME Visitor::AttributeWrapper AttributeWrapper;
|
||||
|
||||
FrustumCullTraverser(Node *root,
|
||||
FrustumCullTraverser(Node *root, const LMatrix4f &rel_from_camera,
|
||||
Visitor &visitor,
|
||||
const AttributeWrapper &initial_render_state,
|
||||
const LevelState &initial_level_state,
|
||||
@ -67,12 +67,12 @@ protected:
|
||||
// Convenience function.
|
||||
template<class Visitor, class AttributeWrapper, class LevelState>
|
||||
INLINE void
|
||||
fc_traverse(Node *root, Visitor &visitor,
|
||||
fc_traverse(Node *root, const LMatrix4f &rel_from_camera, Visitor &visitor,
|
||||
const AttributeWrapper &initial_render_state,
|
||||
const LevelState &initial_level_state,
|
||||
GraphicsStateGuardian *gsg, TypeHandle graph_type) {
|
||||
FrustumCullTraverser<Visitor, LevelState>
|
||||
fct(root, visitor, initial_render_state,
|
||||
fct(root, rel_from_camera, visitor, initial_render_state,
|
||||
initial_level_state, gsg, graph_type);
|
||||
}
|
||||
|
||||
|
@ -245,9 +245,9 @@ must_blend()
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ShaderTransition::
|
||||
sub_render(NodeRelation *arc, const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans, GraphicsStateGuardianBase *gsgbase) {
|
||||
AllTransitionsWrapper &trans, RenderTraverser *trav) {
|
||||
Node *node = arc->get_child();
|
||||
GraphicsStateGuardian *gsg = DCAST(GraphicsStateGuardian, gsgbase);
|
||||
GraphicsStateGuardian *gsg = trav->get_gsg();
|
||||
bool multipass_on = false;
|
||||
|
||||
// No shaders; never mind.
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
virtual bool sub_render(NodeRelation *arc,
|
||||
const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase);
|
||||
RenderTraverser *trav);
|
||||
virtual bool has_sub_render() const;
|
||||
|
||||
private:
|
||||
|
@ -12,12 +12,12 @@
|
||||
|
||||
#include <graphicsStateGuardian.h>
|
||||
#include <get_rel_pos.h>
|
||||
#include <dftraverser.h>
|
||||
#include <luse.h>
|
||||
#include <renderRelation.h>
|
||||
#include <transformTransition.h>
|
||||
#include <allAttributesWrapper.h>
|
||||
#include <allTransitionsWrapper.h>
|
||||
#include <renderTraverser.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Static variables
|
||||
@ -69,9 +69,9 @@ output(ostream &out) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool LODNode::
|
||||
sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase) {
|
||||
RenderTraverser *trav) {
|
||||
|
||||
GraphicsStateGuardian *gsg = DCAST(GraphicsStateGuardian, gsgbase);
|
||||
GraphicsStateGuardian *gsg = trav->get_gsg();
|
||||
|
||||
// Get the current camera position from the gsg
|
||||
const ProjectionNode* camera = gsg->get_current_projection_node();
|
||||
@ -81,7 +81,8 @@ sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &trans,
|
||||
LPoint3f LOD_pos;
|
||||
|
||||
NodeTransitionWrapper ntw(TransformTransition::get_class_type());
|
||||
wrt(this, camera, ntw, RenderRelation::get_class_type());
|
||||
wrt(this, camera, trav->begin(), trav->end(),
|
||||
ntw, RenderRelation::get_class_type());
|
||||
const TransformTransition *tt;
|
||||
if (get_transition_into(tt, ntw)) {
|
||||
LOD_pos = _lod._center * tt->get_matrix();
|
||||
@ -110,8 +111,7 @@ sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &trans,
|
||||
new_trans.compose_in_place(arc_trans);
|
||||
|
||||
// Now render everything from this node and below.
|
||||
gsg->render_subgraph(gsg->get_render_traverser(),
|
||||
arc->get_child(), attrib, new_trans);
|
||||
gsg->render_subgraph(trav, arc->get_child(), attrib, new_trans);
|
||||
|
||||
} else {
|
||||
if (switchnode_cat.is_debug()) {
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
|
||||
virtual bool sub_render(const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase);
|
||||
RenderTraverser *trav);
|
||||
virtual bool has_sub_render() const;
|
||||
|
||||
public:
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <allAttributesWrapper.h>
|
||||
#include <allTransitionsWrapper.h>
|
||||
#include <renderRelation.h>
|
||||
#include <renderTraverser.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Static variables
|
||||
@ -62,9 +63,8 @@ set_switch_time(float switch_time)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool SequenceNode::
|
||||
sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase)
|
||||
{
|
||||
GraphicsStateGuardian *gsg = DCAST(GraphicsStateGuardian, gsgbase);
|
||||
RenderTraverser *trav) {
|
||||
GraphicsStateGuardian *gsg = trav->get_gsg();
|
||||
|
||||
// Determine which child to traverse
|
||||
int num_children = get_num_children(RenderRelation::get_class_type());
|
||||
@ -88,8 +88,7 @@ sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &trans,
|
||||
new_trans.compose_in_place(arc_trans);
|
||||
|
||||
// Now render everything from this node and below.
|
||||
gsg->render_subgraph(gsg->get_render_traverser(),
|
||||
arc->get_child(), attrib, new_trans);
|
||||
gsg->render_subgraph(trav, arc->get_child(), attrib, new_trans);
|
||||
|
||||
} else {
|
||||
if (switchnode_cat.is_debug()) {
|
||||
|
@ -32,7 +32,7 @@ PUBLISHED:
|
||||
public:
|
||||
virtual bool sub_render(const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
GraphicsStateGuardianBase *gsgbase);
|
||||
RenderTraverser *trav);
|
||||
virtual bool has_sub_render() const;
|
||||
|
||||
public:
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#begin test_bin_target
|
||||
#define TARGET chat
|
||||
#define LOCAL_LIBS $[LOCAL_LIBS] chat
|
||||
|
||||
#define SOURCES \
|
||||
chat_test.cxx
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <eventHandler.h>
|
||||
#include <chancfg.h>
|
||||
#include <textNode.h>
|
||||
#include <eggLoader.h>
|
||||
#include <mouse.h>
|
||||
#include <graphicsWindow.h>
|
||||
#include <chatInput.h>
|
||||
@ -50,22 +49,23 @@ void chat_keys(EventHandler& eh) {
|
||||
eh.add_hook("chat_exit", event_chat_exit);
|
||||
eh.add_hook("chat_overflow", event_chat_overflow);
|
||||
|
||||
PT_NamedNode font = loader.load_sync("ttf-comic");
|
||||
PT_Node font = loader.load_sync("ttf-comic");
|
||||
|
||||
// Create the input text node
|
||||
input_text_node = new TextNode("input_text_node");
|
||||
input_text_node->set_billboard(false);
|
||||
input_text_node->set_font(font.p());
|
||||
input_text_node->set_text("Press Enter to begin chat mode.");
|
||||
input_text_node->set_wordwrap(12.0);
|
||||
RenderRelation *text_arc = new RenderRelation(cameras, input_text_node);
|
||||
LMatrix4f mat = LMatrix4f::scale_mat(0.25);
|
||||
mat.set_row(3, LVector3f(-3, 8, -2.4));
|
||||
mat.set_row(3, LVector3f(-3, 8, -1.4));
|
||||
text_arc->set_transition(new TransformTransition(mat));
|
||||
LightTransition *no_light = new LightTransition(LightTransition::all_off());
|
||||
text_arc->set_transition(no_light);
|
||||
|
||||
chat_input = new ChatInput(input_text_node, "chat input");
|
||||
chat_input->set_max_chars(20);
|
||||
chat_input->set_max_lines(2);
|
||||
|
||||
// Create the output text node
|
||||
output_text_node = new TextNode("output_text_node");
|
||||
|
@ -78,6 +78,7 @@ RenderRelation *flare_arc = (RenderRelation *)NULL;
|
||||
DownRelationPointers *current_siblings;
|
||||
DownRelationPointers::iterator current_sib;
|
||||
|
||||
/*
|
||||
void
|
||||
setup_panda2d() {
|
||||
static bool already_setup = false;
|
||||
@ -173,7 +174,6 @@ setup_panda2d() {
|
||||
} else {
|
||||
nout << "Couldn't find lilsmiley.egg\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -191,6 +191,7 @@ event_out_label2d(CPT_Event) {
|
||||
|
||||
label2d->set_card_color(0.5, 0.5, 0.5, 0.5);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
@ -220,6 +221,9 @@ set_highlight(Node *node) {
|
||||
const BoundingVolume &vol = arc->get_bound();
|
||||
nout << "Bounding volume of arc is " << vol << "\n";
|
||||
|
||||
nout << "Transitions on arc:\n";
|
||||
arc->write_transitions(nout, 2);
|
||||
|
||||
arc->set_transition(new DrawBoundsTransition);
|
||||
bounds_arc = arc;
|
||||
}
|
||||
@ -408,15 +412,6 @@ event_h(CPT_Event) {
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
event_2(CPT_Event) {
|
||||
static bool is_setup = false;
|
||||
if (!is_setup) {
|
||||
setup_panda2d();
|
||||
is_setup = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void attach_sky() {
|
||||
// Load the sun and sky
|
||||
sky = DCAST(NamedNode, loader.load_sync("sky"));
|
||||
@ -556,8 +551,10 @@ void demo_keys(EventHandler&) {
|
||||
new RenderRelation( lights, dlight );
|
||||
have_dlight = true;
|
||||
|
||||
/*
|
||||
event_handler.add_hook("mw-in-label2d", event_in_label2d);
|
||||
event_handler.add_hook("mw-out-label2d", event_out_label2d);
|
||||
*/
|
||||
|
||||
event_handler.add_hook("h", event_h);
|
||||
event_handler.add_hook("up", event_up);
|
||||
@ -574,8 +571,6 @@ void demo_keys(EventHandler&) {
|
||||
event_handler.add_hook("f8", event_fkey);
|
||||
event_handler.add_hook("f9", event_fkey);
|
||||
|
||||
event_handler.add_hook("2", event_2);
|
||||
|
||||
event_handler.add_hook("L", event_L);
|
||||
event_handler.add_hook("k", event_k);
|
||||
event_handler.add_hook("a", event_a);
|
||||
|
Loading…
x
Reference in New Issue
Block a user