Panda3D
sceneGraphReducer.I
1 // Filename: sceneGraphReducer.I
2 // Created by: drose (14Mar02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: SceneGraphReducer::Constructor
18 // Access: Published
19 // Description:
20 ////////////////////////////////////////////////////////////////////
21 INLINE SceneGraphReducer::
22 SceneGraphReducer(GraphicsStateGuardianBase *gsg) :
23  _combine_radius(0.0f)
24 {
25  set_gsg(gsg);
26 }
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: SceneGraphReducer::Destructor
30 // Access: Published
31 // Description:
32 ////////////////////////////////////////////////////////////////////
33 INLINE SceneGraphReducer::
34 ~SceneGraphReducer() {
35 }
36 
37 ////////////////////////////////////////////////////////////////////
38 // Function: SceneGraphReducer::get_gsg
39 // Access: Published
40 // Description: Returns the particular GraphicsStateGuardian that
41 // this object will attempt to optimize to.
42 // See set_gsg().
43 ////////////////////////////////////////////////////////////////////
45 get_gsg() const {
46  return _gsg;
47 }
48 
49 
50 ////////////////////////////////////////////////////////////////////
51 // Function: SceneGraphReducer::set_combine_radius
52 // Access: Published
53 // Description: Specifies the radius that is used in conjunction with
54 // CS_within_radius to decide whether a subgraph's
55 // siblings should be combined into a single node or
56 // not.
57 //
58 // If the CS_within_radius bit is included in the
59 // combine_siblings_bits parameter passed to flatten,
60 // than any nodes whose bounding volume is smaller than
61 // the indicated radius will be combined together (as if
62 // CS_other were set).
63 ////////////////////////////////////////////////////////////////////
64 INLINE void SceneGraphReducer::
65 set_combine_radius(PN_stdfloat combine_radius) {
66  _combine_radius = combine_radius;
67 }
68 
69 ////////////////////////////////////////////////////////////////////
70 // Function: SceneGraphReducer::get_combine_radius
71 // Access: Published
72 // Description: Returns the radius that is used in conjunction with
73 // CS_within_radius. See set_combine_radius().
74 ////////////////////////////////////////////////////////////////////
75 INLINE PN_stdfloat SceneGraphReducer::
77  return _combine_radius;
78 }
79 
80 
81 ////////////////////////////////////////////////////////////////////
82 // Function: SceneGraphReducer::apply_attribs
83 // Access: Published
84 // Description: Walks the scene graph, accumulating attribs of
85 // the indicated types, applying them to the vertices,
86 // and removing them from the scene graph. This has a
87 // performance optimization benefit in itself, but is
88 // especially useful to pave the way for a call to
89 // flatten() and greatly improve the effectiveness of
90 // the flattening operation.
91 //
92 // Multiply instanced geometry is duplicated before the
93 // attribs are applied.
94 //
95 // Of course, this operation does make certain dynamic
96 // operations impossible.
97 ////////////////////////////////////////////////////////////////////
98 INLINE void SceneGraphReducer::
99 apply_attribs(PandaNode *node, int attrib_types) {
100  nassertv(check_live_flatten(node));
101  nassertv(node != (PandaNode *)NULL);
102  PStatTimer timer(_apply_collector);
103  AccumulatedAttribs attribs;
104  r_apply_attribs(node, attribs, attrib_types, _transformer);
105  _transformer.finish_apply();
106 }
107 
108 ////////////////////////////////////////////////////////////////////
109 // Function: SceneGraphReducer::apply_attribs
110 // Access: Published
111 // Description: This flavor of apply_attribs() can be called
112 // recursively from within another flatten process
113 // (e.g. from PandaNode::apply_attribs_to_vertices()).
114 // The parameters were presumably received from a parent
115 // SceneGraphReducer object.
116 ////////////////////////////////////////////////////////////////////
117 INLINE void SceneGraphReducer::
119  int attrib_types, GeomTransformer &transformer) {
120  nassertv(node != (PandaNode *)NULL);
121  r_apply_attribs(node, attribs, attrib_types, transformer);
122 }
123 
124 ////////////////////////////////////////////////////////////////////
125 // Function: SceneGraphReducer::make_compatible_format
126 // Access: Published
127 // Description: Walks through the tree at this node and below and
128 // unifies the GeomVertexFormat for any GeomVertexData
129 // objects that are found, so that all eligible vdatas
130 // (according to collect_bits; see collect_vertex_data)
131 // will share the same vertex format.
132 //
133 // This will add unused columns where necessary to match
134 // formats. It can result in suboptimal performance if
135 // used needlessly.
136 //
137 // There is usually no reason to call this explicitly,
138 // since collect_vertex_data() will do this anyway if it
139 // has not been done already. However, calling it ahead
140 // of time can make that future call to
141 // collect_vertex_data() run a little bit faster.
142 //
143 // The return value is the number of vertex datas
144 // modified.
145 ////////////////////////////////////////////////////////////////////
146 INLINE int SceneGraphReducer::
147 make_compatible_format(PandaNode *root, int collect_bits) {
148  nassertr(root != (PandaNode *)NULL, 0);
149  nassertr(check_live_flatten(root), 0);
150  PStatTimer timer(_collect_collector);
151  int count = 0;
152  count += r_collect_vertex_data(root, collect_bits, _transformer, true);
153  count += _transformer.finish_collect(true);
154  return count;
155 }
156 
157 ////////////////////////////////////////////////////////////////////
158 // Function: SceneGraphReducer::collect_vertex_data
159 // Access: Published
160 // Description: Collects all different GeomVertexData blocks that
161 // have compatible formats at this node and below into a
162 // single, unified block (or at least multiple larger
163 // blocks). This is intended to reduce rendering
164 // overhead incurred by switching vertex buffers. It
165 // can also make a subsequent call to unify() much more
166 // effective than it would have been otherwise.
167 //
168 // The set of bits passed in collect_bits indicates
169 // which properties are used to differentiate
170 // GeomVertexData blocks. If it is 0, then more blocks
171 // will be combined together than if it is nonzero.
172 ////////////////////////////////////////////////////////////////////
173 INLINE int SceneGraphReducer::
174 collect_vertex_data(PandaNode *root, int collect_bits) {
175  nassertr(root != (PandaNode *)NULL, 0);
176  nassertr(check_live_flatten(root), 0);
177  PStatTimer timer(_collect_collector);
178  int count = 0;
179  count += r_collect_vertex_data(root, collect_bits, _transformer, false);
180  count += _transformer.finish_collect(false);
181  return count;
182 }
183 
184 ////////////////////////////////////////////////////////////////////
185 // Function: SceneGraphReducer::make_nonindexed
186 // Access: Published
187 // Description: Converts indexed geometry to nonindexed geometry at
188 // the indicated node and below, by duplicating vertices
189 // where necessary. The parameter nonindexed_bits is a
190 // union of bits defined in
191 // SceneGraphReducer::MakeNonindexed, which specifes
192 // which types of geometry to avoid making nonindexed.
193 ////////////////////////////////////////////////////////////////////
194 INLINE int SceneGraphReducer::
195 make_nonindexed(PandaNode *root, int nonindexed_bits) {
196  nassertr(root != (PandaNode *)NULL, 0);
197  nassertr(check_live_flatten(root), 0);
198  PStatTimer timer(_make_nonindexed_collector);
199  return r_make_nonindexed(root, nonindexed_bits);
200 }
201 
202 ////////////////////////////////////////////////////////////////////
203 // Function: SceneGraphReducer::premunge
204 // Access: Published
205 // Description: Walks the scene graph rooted at this node and below,
206 // and uses the indicated GSG to premunge every Geom
207 // found to optimize it for eventual rendering on the
208 // indicated GSG. If there is no GSG indicated for the
209 // SceneGraphReducer, this is a no-op.
210 //
211 // This operation will also apply to stashed children.
212 ////////////////////////////////////////////////////////////////////
213 INLINE void SceneGraphReducer::
214 premunge(PandaNode *root, const RenderState *initial_state) {
215  nassertv(root != (PandaNode *)NULL);
216  nassertv(check_live_flatten(root));
217  if (_gsg != (GraphicsStateGuardianBase *)NULL) {
218  PStatTimer timer(_premunge_collector);
219  r_premunge(root, initial_state);
220  }
221 }
222 
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
int collect_vertex_data(PandaNode *root, int collect_bits=~0)
Collects all different GeomVertexData blocks that have compatible formats at this node and below into...
int make_compatible_format(PandaNode *root, int collect_bits=~0)
Walks through the tree at this node and below and unifies the GeomVertexFormat for any GeomVertexData...
void set_combine_radius(PN_stdfloat combine_radius)
Specifies the radius that is used in conjunction with CS_within_radius to decide whether a subgraph's...
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:34
GraphicsStateGuardianBase * get_gsg() const
Returns the particular GraphicsStateGuardian that this object will attempt to optimize to...
void set_gsg(GraphicsStateGuardianBase *gsg)
Specifies the particular GraphicsStateGuardian that this object will attempt to optimize to...
int finish_collect(bool format_only)
This should be called after a call to collect_vertex_data() to finalize the changes and apply them to...
This class is used by the SceneGraphReducer to maintain and accumulate the set of attributes we have ...
int make_nonindexed(PandaNode *root, int nonindexed_bits=~0)
Converts indexed geometry to nonindexed geometry at the indicated node and below, by duplicating vert...
PN_stdfloat get_combine_radius() const
Returns the radius that is used in conjunction with CS_within_radius.
void premunge(PandaNode *root, const RenderState *initial_state)
Walks the scene graph rooted at this node and below, and uses the indicated GSG to premunge every Geo...
bool check_live_flatten(PandaNode *node)
In a non-release build, returns false if the node is correctly not in a live scene graph...
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:53
void apply_attribs(PandaNode *node, int attrib_types=~(TT_clip_plane|TT_cull_face|TT_apply_texture_color))
Walks the scene graph, accumulating attribs of the indicated types, applying them to the vertices...
void finish_apply()
Should be called after performing any operations–particularly PandaNode::apply_attribs_to_vertices()...
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
An object specifically designed to transform the vertices of a Geom without disturbing indexing or af...