Panda3D
|
00001 // Filename: accumulatedAttribs.cxx 00002 // Created by: drose (30Jan03) 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 #include "accumulatedAttribs.h" 00016 #include "sceneGraphReducer.h" 00017 #include "pandaNode.h" 00018 #include "colorAttrib.h" 00019 #include "colorScaleAttrib.h" 00020 #include "texMatrixAttrib.h" 00021 #include "textureAttrib.h" 00022 #include "clipPlaneAttrib.h" 00023 #include "cullFaceAttrib.h" 00024 #include "config_pgraph.h" 00025 00026 00027 //////////////////////////////////////////////////////////////////// 00028 // Function: AccumulatedAttribs::Constructor 00029 // Access: Public 00030 // Description: 00031 //////////////////////////////////////////////////////////////////// 00032 AccumulatedAttribs:: 00033 AccumulatedAttribs() { 00034 _transform = TransformState::make_identity(); 00035 _color_override = 0; 00036 _color_scale_override = 0; 00037 _tex_matrix_override = 0; 00038 _texture_override = 0; 00039 _clip_plane_override = 0; 00040 _cull_face_override = 0; 00041 _other = RenderState::make_empty(); 00042 } 00043 00044 //////////////////////////////////////////////////////////////////// 00045 // Function: AccumulatedAttribs::Copy Constructor 00046 // Access: Public 00047 // Description: 00048 //////////////////////////////////////////////////////////////////// 00049 AccumulatedAttribs:: 00050 AccumulatedAttribs(const AccumulatedAttribs ©) : 00051 _transform(copy._transform), 00052 _color(copy._color), 00053 _color_override(copy._color_override), 00054 _color_scale(copy._color_scale), 00055 _color_scale_override(copy._color_scale_override), 00056 _tex_matrix(copy._tex_matrix), 00057 _tex_matrix_override(copy._tex_matrix_override), 00058 _texture(copy._texture), 00059 _texture_override(copy._texture_override), 00060 _clip_plane(copy._clip_plane), 00061 _clip_plane_override(copy._clip_plane_override), 00062 _cull_face(copy._cull_face), 00063 _cull_face_override(copy._cull_face_override), 00064 _other(copy._other) 00065 { 00066 } 00067 00068 //////////////////////////////////////////////////////////////////// 00069 // Function: AccumulatedAttribs::Copy Assignment 00070 // Access: Public 00071 // Description: 00072 //////////////////////////////////////////////////////////////////// 00073 void AccumulatedAttribs:: 00074 operator = (const AccumulatedAttribs ©) { 00075 _transform = copy._transform; 00076 _color = copy._color; 00077 _color_override = copy._color_override; 00078 _color_scale = copy._color_scale; 00079 _color_scale_override = copy._color_scale_override; 00080 _tex_matrix = copy._tex_matrix; 00081 _tex_matrix_override = copy._tex_matrix_override; 00082 _texture = copy._texture; 00083 _texture_override = copy._texture_override; 00084 _clip_plane = copy._clip_plane; 00085 _clip_plane_override = copy._clip_plane_override; 00086 _cull_face = copy._cull_face; 00087 _cull_face_override = copy._cull_face_override; 00088 _other = copy._other; 00089 } 00090 00091 //////////////////////////////////////////////////////////////////// 00092 // Function: AccumulatedAttribs::write 00093 // Access: Public 00094 // Description: 00095 //////////////////////////////////////////////////////////////////// 00096 void AccumulatedAttribs:: 00097 write(ostream &out, int attrib_types, int indent_level) const { 00098 if ((attrib_types & SceneGraphReducer::TT_transform) != 0) { 00099 _transform->write(out, indent_level); 00100 } 00101 if ((attrib_types & SceneGraphReducer::TT_color) != 0) { 00102 if (_color == (const RenderAttrib *)NULL) { 00103 indent(out, indent_level) << "no color\n"; 00104 } else { 00105 _color->write(out, indent_level); 00106 } 00107 } 00108 if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) { 00109 if (_color_scale == (const RenderAttrib *)NULL) { 00110 indent(out, indent_level) << "no color scale\n"; 00111 } else { 00112 _color_scale->write(out, indent_level); 00113 } 00114 } 00115 if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) { 00116 if (_tex_matrix == (const RenderAttrib *)NULL) { 00117 indent(out, indent_level) << "no tex matrix\n"; 00118 } else { 00119 _tex_matrix->write(out, indent_level); 00120 } 00121 } 00122 if ((attrib_types & SceneGraphReducer::TT_clip_plane) != 0) { 00123 if (_clip_plane == (const RenderAttrib *)NULL) { 00124 indent(out, indent_level) << "no clip plane\n"; 00125 } else { 00126 _clip_plane->write(out, indent_level); 00127 } 00128 } 00129 if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) { 00130 if (_cull_face == (const RenderAttrib *)NULL) { 00131 indent(out, indent_level) << "no cull face\n"; 00132 } else { 00133 _cull_face->write(out, indent_level); 00134 } 00135 } 00136 if ((attrib_types & SceneGraphReducer::TT_other) != 0) { 00137 _other->write(out, indent_level); 00138 } 00139 } 00140 00141 //////////////////////////////////////////////////////////////////// 00142 // Function: AccumulatedAttribs::collect 00143 // Access: Public 00144 // Description: Collects the state and transform from the indicated 00145 // node and adds it to the accumulator, removing it from 00146 // the node. 00147 //////////////////////////////////////////////////////////////////// 00148 void AccumulatedAttribs:: 00149 collect(PandaNode *node, int attrib_types) { 00150 if ((attrib_types & SceneGraphReducer::TT_transform) != 0) { 00151 // Collect the node's transform. 00152 nassertv(_transform != (TransformState *)NULL); 00153 _transform = _transform->compose(node->get_transform()); 00154 node->set_transform(TransformState::make_identity()); 00155 node->set_prev_transform(TransformState::make_identity()); 00156 } 00157 00158 CPT(RenderState) new_state = collect(node->get_state(), attrib_types); 00159 node->set_state(new_state); 00160 } 00161 00162 //////////////////////////////////////////////////////////////////// 00163 // Function: AccumulatedAttribs::collect 00164 // Access: Public 00165 // Description: Collects the state and transform from the indicated 00166 // node and adds it to the accumulator, removing it from 00167 // the state (and returning a new state). 00168 //////////////////////////////////////////////////////////////////// 00169 CPT(RenderState) AccumulatedAttribs:: 00170 collect(const RenderState *state, int attrib_types) { 00171 CPT(RenderState) new_state = state; 00172 00173 if ((attrib_types & SceneGraphReducer::TT_color) != 0) { 00174 const RenderAttrib *node_attrib = 00175 new_state->get_attrib(ColorAttrib::get_class_slot()); 00176 if (node_attrib != (const RenderAttrib *)NULL) { 00177 int color_override = new_state->get_override(ColorAttrib::get_class_slot()); 00178 if (color_override >= _color_override || 00179 _color == (const RenderAttrib *)NULL) { 00180 // The node has a color attribute; apply it. 00181 if (_color == (const RenderAttrib *)NULL) { 00182 _color = node_attrib; 00183 } else { 00184 _color = _color->compose(node_attrib); 00185 } 00186 _color_override = color_override; 00187 } 00188 new_state = new_state->remove_attrib(ColorAttrib::get_class_slot()); 00189 } 00190 } 00191 00192 if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) { 00193 const RenderAttrib *node_attrib = 00194 new_state->get_attrib(ColorScaleAttrib::get_class_slot()); 00195 if (node_attrib != (const RenderAttrib *)NULL) { 00196 int color_scale_override = new_state->get_override(ColorScaleAttrib::get_class_slot()); 00197 if (color_scale_override >= _color_scale_override || 00198 _color_scale == (const RenderAttrib *)NULL) { 00199 if (_color_scale == (const RenderAttrib *)NULL) { 00200 _color_scale = node_attrib; 00201 } else { 00202 _color_scale = _color_scale->compose(node_attrib); 00203 } 00204 _color_scale_override = color_scale_override; 00205 } 00206 new_state = new_state->remove_attrib(ColorScaleAttrib::get_class_slot()); 00207 } 00208 } 00209 00210 if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) { 00211 const RenderAttrib *node_attrib = 00212 new_state->get_attrib(TexMatrixAttrib::get_class_slot()); 00213 if (node_attrib != (const RenderAttrib *)NULL) { 00214 int tex_matrix_override = new_state->get_override(TexMatrixAttrib::get_class_slot()); 00215 if (tex_matrix_override >= _tex_matrix_override || 00216 _tex_matrix == (const RenderAttrib *)NULL) { 00217 if (_tex_matrix == (const RenderAttrib *)NULL) { 00218 _tex_matrix = node_attrib; 00219 } else { 00220 _tex_matrix = _tex_matrix->compose(node_attrib); 00221 } 00222 _tex_matrix_override = tex_matrix_override; 00223 } 00224 new_state = new_state->remove_attrib(TexMatrixAttrib::get_class_slot()); 00225 } 00226 00227 // We also need to accumulate the texture state if we are 00228 // accumulating texture matrix. 00229 const RenderAttrib *tex_attrib = 00230 new_state->get_attrib(TextureAttrib::get_class_slot()); 00231 if (tex_attrib != (const RenderAttrib *)NULL) { 00232 int texture_override = new_state->get_override(TextureAttrib::get_class_slot()); 00233 if (texture_override >= _texture_override || 00234 _texture == (const RenderAttrib *)NULL) { 00235 if (_texture == (const RenderAttrib *)NULL) { 00236 _texture = tex_attrib; 00237 } else { 00238 _texture = _texture->compose(tex_attrib); 00239 } 00240 _texture_override = texture_override; 00241 } 00242 00243 // However, we don't remove the texture state from the node. 00244 // We're just accumulating it so we can tell which texture 00245 // coordinates are safe to flatten. 00246 } 00247 } 00248 00249 if ((attrib_types & SceneGraphReducer::TT_clip_plane) != 0) { 00250 const RenderAttrib *node_attrib = 00251 new_state->get_attrib(ClipPlaneAttrib::get_class_slot()); 00252 if (node_attrib != (const RenderAttrib *)NULL) { 00253 int clip_plane_override = new_state->get_override(ClipPlaneAttrib::get_class_slot()); 00254 if (clip_plane_override >= _clip_plane_override || 00255 _clip_plane == (const RenderAttrib *)NULL) { 00256 if (_clip_plane == (const RenderAttrib *)NULL) { 00257 _clip_plane = node_attrib; 00258 } else { 00259 _clip_plane = _clip_plane->compose(node_attrib); 00260 } 00261 _clip_plane_override = clip_plane_override; 00262 } 00263 new_state = new_state->remove_attrib(ClipPlaneAttrib::get_class_slot()); 00264 } 00265 } 00266 00267 if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) { 00268 const RenderAttrib *node_attrib = 00269 new_state->get_attrib(CullFaceAttrib::get_class_slot()); 00270 if (node_attrib != (const RenderAttrib *)NULL) { 00271 int cull_face_override = new_state->get_override(CullFaceAttrib::get_class_slot()); 00272 if (cull_face_override >= _cull_face_override || 00273 _cull_face == (const RenderAttrib *)NULL) { 00274 if (_cull_face == (const RenderAttrib *)NULL) { 00275 _cull_face = node_attrib; 00276 } else { 00277 _cull_face = _cull_face->compose(node_attrib); 00278 } 00279 _cull_face_override = cull_face_override; 00280 } 00281 new_state = new_state->remove_attrib(CullFaceAttrib::get_class_slot()); 00282 } 00283 } 00284 00285 if ((attrib_types & SceneGraphReducer::TT_other) != 0) { 00286 // Collect everything else. 00287 nassertr(_other != (RenderState *)NULL, new_state); 00288 _other = _other->compose(new_state); 00289 new_state = RenderState::make_empty(); 00290 } 00291 00292 return new_state; 00293 } 00294 00295 //////////////////////////////////////////////////////////////////// 00296 // Function: AccumulatedAttribs::apply_to_node 00297 // Access: Public 00298 // Description: Stores the indicated attributes in the node's 00299 // transform and state information; does not attempt to 00300 // apply the properties to the vertices. Clears the 00301 // attributes from the accumulator for future 00302 // traversals. 00303 //////////////////////////////////////////////////////////////////// 00304 void AccumulatedAttribs:: 00305 apply_to_node(PandaNode *node, int attrib_types) { 00306 if ((attrib_types & SceneGraphReducer::TT_transform) != 0) { 00307 node->set_transform(_transform->compose(node->get_transform())->get_unique()); 00308 node->reset_prev_transform(); 00309 _transform = TransformState::make_identity(); 00310 } 00311 00312 if ((attrib_types & SceneGraphReducer::TT_color) != 0) { 00313 if (_color != (RenderAttrib *)NULL) { 00314 const RenderAttrib *node_attrib = 00315 node->get_attrib(ColorAttrib::get_class_slot()); 00316 if (node_attrib != (RenderAttrib *)NULL) { 00317 node->set_attrib(_color->compose(node_attrib)->get_unique()); 00318 } else { 00319 node->set_attrib(_color->get_unique()); 00320 } 00321 _color = (RenderAttrib *)NULL; 00322 } 00323 } 00324 00325 if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) { 00326 if (_color_scale != (RenderAttrib *)NULL) { 00327 const RenderAttrib *node_attrib = 00328 node->get_attrib(ColorScaleAttrib::get_class_slot()); 00329 if (node_attrib != (RenderAttrib *)NULL) { 00330 node->set_attrib(_color_scale->compose(node_attrib)->get_unique()); 00331 } else { 00332 node->set_attrib(_color_scale->get_unique()); 00333 } 00334 _color_scale = (RenderAttrib *)NULL; 00335 } 00336 } 00337 00338 if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) { 00339 if (_tex_matrix != (RenderAttrib *)NULL) { 00340 const RenderAttrib *node_attrib = 00341 node->get_attrib(TexMatrixAttrib::get_class_slot()); 00342 if (node_attrib != (RenderAttrib *)NULL) { 00343 node->set_attrib(_tex_matrix->compose(node_attrib)->get_unique()); 00344 } else { 00345 node->set_attrib(_tex_matrix->get_unique()); 00346 } 00347 _tex_matrix = (RenderAttrib *)NULL; 00348 } 00349 } 00350 00351 if ((attrib_types & SceneGraphReducer::TT_clip_plane) != 0) { 00352 if (_clip_plane != (RenderAttrib *)NULL) { 00353 const RenderAttrib *node_attrib = 00354 node->get_attrib(ClipPlaneAttrib::get_class_slot()); 00355 if (node_attrib != (RenderAttrib *)NULL) { 00356 node->set_attrib(_clip_plane->compose(node_attrib)->get_unique()); 00357 } else { 00358 node->set_attrib(_clip_plane->get_unique()); 00359 } 00360 _clip_plane = (RenderAttrib *)NULL; 00361 } 00362 } 00363 00364 if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) { 00365 if (_cull_face != (RenderAttrib *)NULL) { 00366 const RenderAttrib *node_attrib = 00367 node->get_attrib(CullFaceAttrib::get_class_slot()); 00368 if (node_attrib != (RenderAttrib *)NULL) { 00369 node->set_attrib(_cull_face->compose(node_attrib)->get_unique()); 00370 } else { 00371 node->set_attrib(_cull_face->get_unique()); 00372 } 00373 _cull_face = (RenderAttrib *)NULL; 00374 } 00375 } 00376 00377 if ((attrib_types & SceneGraphReducer::TT_other) != 0) { 00378 node->set_state(_other->compose(node->get_state())->get_unique()); 00379 _other = RenderState::make_empty(); 00380 } 00381 }