Panda3D
|
00001 // Filename: sceneGraphReducer.I 00002 // Created by: drose (14Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: SceneGraphReducer::Constructor 00018 // Access: Published 00019 // Description: 00020 //////////////////////////////////////////////////////////////////// 00021 INLINE SceneGraphReducer:: 00022 SceneGraphReducer(GraphicsStateGuardianBase *gsg) : 00023 _combine_radius(0.0f) 00024 { 00025 set_gsg(gsg); 00026 } 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: SceneGraphReducer::Destructor 00030 // Access: Published 00031 // Description: 00032 //////////////////////////////////////////////////////////////////// 00033 INLINE SceneGraphReducer:: 00034 ~SceneGraphReducer() { 00035 } 00036 00037 //////////////////////////////////////////////////////////////////// 00038 // Function: SceneGraphReducer::get_gsg 00039 // Access: Published 00040 // Description: Returns the particular GraphicsStateGuardian that 00041 // this object will attempt to optimize to. 00042 // See set_gsg(). 00043 //////////////////////////////////////////////////////////////////// 00044 INLINE GraphicsStateGuardianBase *SceneGraphReducer:: 00045 get_gsg() const { 00046 return _gsg; 00047 } 00048 00049 00050 //////////////////////////////////////////////////////////////////// 00051 // Function: SceneGraphReducer::set_combine_radius 00052 // Access: Published 00053 // Description: Specifies the radius that is used in conjunction with 00054 // CS_within_radius to decide whether a subgraph's 00055 // siblings should be combined into a single node or 00056 // not. 00057 // 00058 // If the CS_within_radius bit is included in the 00059 // combine_siblings_bits parameter passed to flatten, 00060 // than any nodes whose bounding volume is smaller than 00061 // the indicated radius will be combined together (as if 00062 // CS_other were set). 00063 //////////////////////////////////////////////////////////////////// 00064 INLINE void SceneGraphReducer:: 00065 set_combine_radius(PN_stdfloat combine_radius) { 00066 _combine_radius = combine_radius; 00067 } 00068 00069 //////////////////////////////////////////////////////////////////// 00070 // Function: SceneGraphReducer::get_combine_radius 00071 // Access: Published 00072 // Description: Returns the radius that is used in conjunction with 00073 // CS_within_radius. See set_combine_radius(). 00074 //////////////////////////////////////////////////////////////////// 00075 INLINE PN_stdfloat SceneGraphReducer:: 00076 get_combine_radius() const { 00077 return _combine_radius; 00078 } 00079 00080 00081 //////////////////////////////////////////////////////////////////// 00082 // Function: SceneGraphReducer::apply_attribs 00083 // Access: Published 00084 // Description: Walks the scene graph, accumulating attribs of 00085 // the indicated types, applying them to the vertices, 00086 // and removing them from the scene graph. This has a 00087 // performance optimization benefit in itself, but is 00088 // especially useful to pave the way for a call to 00089 // flatten() and greatly improve the effectiveness of 00090 // the flattening operation. 00091 // 00092 // Multiply instanced geometry is duplicated before the 00093 // attribs are applied. 00094 // 00095 // Of course, this operation does make certain dynamic 00096 // operations impossible. 00097 //////////////////////////////////////////////////////////////////// 00098 INLINE void SceneGraphReducer:: 00099 apply_attribs(PandaNode *node, int attrib_types) { 00100 nassertv(check_live_flatten(node)); 00101 nassertv(node != (PandaNode *)NULL); 00102 PStatTimer timer(_apply_collector); 00103 AccumulatedAttribs attribs; 00104 r_apply_attribs(node, attribs, attrib_types, _transformer); 00105 _transformer.finish_apply(); 00106 } 00107 00108 //////////////////////////////////////////////////////////////////// 00109 // Function: SceneGraphReducer::apply_attribs 00110 // Access: Published 00111 // Description: This flavor of apply_attribs() can be called 00112 // recursively from within another flatten process 00113 // (e.g. from PandaNode::apply_attribs_to_vertices()). 00114 // The parameters were presumably received from a parent 00115 // SceneGraphReducer object. 00116 //////////////////////////////////////////////////////////////////// 00117 INLINE void SceneGraphReducer:: 00118 apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs, 00119 int attrib_types, GeomTransformer &transformer) { 00120 nassertv(node != (PandaNode *)NULL); 00121 r_apply_attribs(node, attribs, attrib_types, transformer); 00122 } 00123 00124 //////////////////////////////////////////////////////////////////// 00125 // Function: SceneGraphReducer::make_compatible_format 00126 // Access: Published 00127 // Description: Walks through the tree at this node and below and 00128 // unifies the GeomVertexFormat for any GeomVertexData 00129 // objects that are found, so that all eligible vdatas 00130 // (according to collect_bits; see collect_vertex_data) 00131 // will share the same vertex format. 00132 // 00133 // This will add unused columns where necessary to match 00134 // formats. It can result in suboptimal performance if 00135 // used needlessly. 00136 // 00137 // There is usually no reason to call this explicitly, 00138 // since collect_vertex_data() will do this anyway if it 00139 // has not been done already. However, calling it ahead 00140 // of time can make that future call to 00141 // collect_vertex_data() run a little bit faster. 00142 // 00143 // The return value is the number of vertex datas 00144 // modified. 00145 //////////////////////////////////////////////////////////////////// 00146 INLINE int SceneGraphReducer:: 00147 make_compatible_format(PandaNode *root, int collect_bits) { 00148 nassertr(root != (PandaNode *)NULL, 0); 00149 nassertr(check_live_flatten(root), 0); 00150 PStatTimer timer(_collect_collector); 00151 int count = 0; 00152 count += r_collect_vertex_data(root, collect_bits, _transformer, true); 00153 count += _transformer.finish_collect(true); 00154 return count; 00155 } 00156 00157 //////////////////////////////////////////////////////////////////// 00158 // Function: SceneGraphReducer::collect_vertex_data 00159 // Access: Published 00160 // Description: Collects all different GeomVertexData blocks that 00161 // have compatible formats at this node and below into a 00162 // single, unified block (or at least multiple larger 00163 // blocks). This is intended to reduce rendering 00164 // overhead incurred by switching vertex buffers. It 00165 // can also make a subsequent call to unify() much more 00166 // effective than it would have been otherwise. 00167 // 00168 // The set of bits passed in collect_bits indicates 00169 // which properties are used to differentiate 00170 // GeomVertexData blocks. If it is 0, then more blocks 00171 // will be combined together than if it is nonzero. 00172 //////////////////////////////////////////////////////////////////// 00173 INLINE int SceneGraphReducer:: 00174 collect_vertex_data(PandaNode *root, int collect_bits) { 00175 nassertr(root != (PandaNode *)NULL, 0); 00176 nassertr(check_live_flatten(root), 0); 00177 PStatTimer timer(_collect_collector); 00178 int count = 0; 00179 count += r_collect_vertex_data(root, collect_bits, _transformer, false); 00180 count += _transformer.finish_collect(false); 00181 return count; 00182 } 00183 00184 //////////////////////////////////////////////////////////////////// 00185 // Function: SceneGraphReducer::make_nonindexed 00186 // Access: Published 00187 // Description: Converts indexed geometry to nonindexed geometry at 00188 // the indicated node and below, by duplicating vertices 00189 // where necessary. The parameter nonindexed_bits is a 00190 // union of bits defined in 00191 // SceneGraphReducer::MakeNonindexed, which specifes 00192 // which types of geometry to avoid making nonindexed. 00193 //////////////////////////////////////////////////////////////////// 00194 INLINE int SceneGraphReducer:: 00195 make_nonindexed(PandaNode *root, int nonindexed_bits) { 00196 nassertr(root != (PandaNode *)NULL, 0); 00197 nassertr(check_live_flatten(root), 0); 00198 PStatTimer timer(_make_nonindexed_collector); 00199 return r_make_nonindexed(root, nonindexed_bits); 00200 } 00201 00202 //////////////////////////////////////////////////////////////////// 00203 // Function: SceneGraphReducer::premunge 00204 // Access: Published 00205 // Description: Walks the scene graph rooted at this node and below, 00206 // and uses the indicated GSG to premunge every Geom 00207 // found to optimize it for eventual rendering on the 00208 // indicated GSG. If there is no GSG indicated for the 00209 // SceneGraphReducer, this is a no-op. 00210 // 00211 // This operation will also apply to stashed children. 00212 //////////////////////////////////////////////////////////////////// 00213 INLINE void SceneGraphReducer:: 00214 premunge(PandaNode *root, const RenderState *initial_state) { 00215 nassertv(root != (PandaNode *)NULL); 00216 nassertv(check_live_flatten(root)); 00217 if (_gsg != (GraphicsStateGuardianBase *)NULL) { 00218 PStatTimer timer(_premunge_collector); 00219 r_premunge(root, initial_state); 00220 } 00221 } 00222