00001 // Filename: eggNode.cxx 00002 // Created by: drose (16Jan99) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "eggNode.h" 00020 #include "eggGroupNode.h" 00021 #include "config_egg.h" 00022 #include "eggTextureCollection.h" 00023 00024 #include <algorithm> 00025 00026 extern int eggyyparse(void); 00027 #include "parserDefs.h" 00028 #include "lexerDefs.h" 00029 00030 TypeHandle EggNode::_type_handle; 00031 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Function: EggNode::apply_texmats 00035 // Access: Public 00036 // Description: Applies the texture matrices to the UV's of the 00037 // vertices that reference them, and then removes the 00038 // texture matrices from the textures themselves. 00039 //////////////////////////////////////////////////////////////////// 00040 void EggNode:: 00041 apply_texmats() { 00042 EggTextureCollection textures; 00043 textures.find_used_textures(this); 00044 r_apply_texmats(textures); 00045 } 00046 00047 //////////////////////////////////////////////////////////////////// 00048 // Function: EggNode::determine_alpha_mode 00049 // Access: Public, Virtual 00050 // Description: Walks back up the hierarchy, looking for an EggGroup 00051 // or EggPrimitive or some such object at this level or 00052 // above this node that has an alpha_mode other than 00053 // AM_unspecified. Returns a valid EggRenderMode pointer 00054 // if one is found, or NULL otherwise. 00055 //////////////////////////////////////////////////////////////////// 00056 EggRenderMode *EggNode:: 00057 determine_alpha_mode() { 00058 if (_parent == (EggGroupNode *)NULL) { 00059 // Too bad; we're done. 00060 return (EggRenderMode *)NULL; 00061 } 00062 return _parent->determine_alpha_mode(); 00063 } 00064 00065 //////////////////////////////////////////////////////////////////// 00066 // Function: EggNode::determine_depth_write_mode 00067 // Access: Public, Virtual 00068 // Description: Walks back up the hierarchy, looking for an EggGroup 00069 // or EggPrimitive or some such object at this level or 00070 // above this node that has a depth_write_mode other than 00071 // DWM_unspecified. Returns a valid EggRenderMode pointer 00072 // if one is found, or NULL otherwise. 00073 //////////////////////////////////////////////////////////////////// 00074 EggRenderMode *EggNode:: 00075 determine_depth_write_mode() { 00076 if (_parent == (EggGroupNode *)NULL) { 00077 // Too bad; we're done. 00078 return (EggRenderMode *)NULL; 00079 } 00080 return _parent->determine_depth_write_mode(); 00081 } 00082 00083 //////////////////////////////////////////////////////////////////// 00084 // Function: EggNode::determine_depth_test_mode 00085 // Access: Public, Virtual 00086 // Description: Walks back up the hierarchy, looking for an EggGroup 00087 // or EggPrimitive or some such object at this level or 00088 // above this node that has a depth_test_mode other than 00089 // DTM_unspecified. Returns a valid EggRenderMode pointer 00090 // if one is found, or NULL otherwise. 00091 //////////////////////////////////////////////////////////////////// 00092 EggRenderMode *EggNode:: 00093 determine_depth_test_mode() { 00094 if (_parent == (EggGroupNode *)NULL) { 00095 // Too bad; we're done. 00096 return (EggRenderMode *)NULL; 00097 } 00098 return _parent->determine_depth_test_mode(); 00099 } 00100 00101 //////////////////////////////////////////////////////////////////// 00102 // Function: EggNode::determine_draw_order 00103 // Access: Public, Virtual 00104 // Description: Walks back up the hierarchy, looking for an EggGroup 00105 // or EggPrimitive or some such object at this level or 00106 // above this node that has a draw_order specified. 00107 // Returns a valid EggRenderMode pointer if one is found, 00108 // or NULL otherwise. 00109 //////////////////////////////////////////////////////////////////// 00110 EggRenderMode *EggNode:: 00111 determine_draw_order() { 00112 if (_parent == (EggGroupNode *)NULL) { 00113 // Too bad; we're done. 00114 return (EggRenderMode *)NULL; 00115 } 00116 return _parent->determine_draw_order(); 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: EggNode::determine_bin 00121 // Access: Public, Virtual 00122 // Description: Walks back up the hierarchy, looking for an EggGroup 00123 // or EggPrimitive or some such object at this level or 00124 // above this node that has a bin specified. Returns a 00125 // valid EggRenderMode pointer if one is found, or NULL 00126 // otherwise. 00127 //////////////////////////////////////////////////////////////////// 00128 EggRenderMode *EggNode:: 00129 determine_bin() { 00130 if (_parent == (EggGroupNode *)NULL) { 00131 // Too bad; we're done. 00132 return (EggRenderMode *)NULL; 00133 } 00134 return _parent->determine_bin(); 00135 } 00136 00137 00138 //////////////////////////////////////////////////////////////////// 00139 // Function: EggNode::parse_egg 00140 // Access: Public 00141 // Description: Parses the egg syntax given in the indicate string as 00142 // if it had been read from the egg file within this 00143 // object's definition. Updates the object accordingly. 00144 // Returns true if successful, false if there was some 00145 // parse error or if the object does not support this 00146 // functionality. 00147 //////////////////////////////////////////////////////////////////// 00148 bool EggNode:: 00149 parse_egg(const string &egg_syntax) { 00150 EggGroupNode *group = get_parent(); 00151 if (is_of_type(EggGroupNode::get_class_type())) { 00152 DCAST_INTO_R(group, this, false); 00153 } 00154 00155 istringstream in(egg_syntax); 00156 egg_init_parser(in, "", this, group); 00157 00158 if (!egg_start_parse_body()) { 00159 egg_cleanup_parser(); 00160 return false; 00161 } 00162 00163 eggyyparse(); 00164 egg_cleanup_parser(); 00165 00166 return (egg_error_count() == 0); 00167 } 00168 00169 #ifndef NDEBUG 00170 00171 //////////////////////////////////////////////////////////////////// 00172 // Function: EggNode::test_under_integrity 00173 // Access: Public 00174 // Description: Recursively checks the integrity of the _under_flags, 00175 // _parent, and _depth members of this node and all of 00176 // its ancestors. 00177 //////////////////////////////////////////////////////////////////// 00178 void EggNode:: 00179 test_under_integrity() const { 00180 if (_parent == NULL) { 00181 // If we have no parent, everything should be zero. 00182 nassertv(_depth == 0); 00183 nassertv(_under_flags == 0); 00184 } else { 00185 // Otherwise, make sure we're consistent with our parent. 00186 _parent->test_ref_count_integrity(); 00187 00188 nassertv(_depth == _parent->_depth + 1); 00189 00190 // We can't perform too much checking on the under_flags, since we 00191 // don't know which bits should have been added for this node. 00192 // We'll verify that at least we didn't accidentally take some 00193 // bits away. 00194 nassertv((_under_flags & _parent->_under_flags) == _parent->_under_flags); 00195 00196 // Make sure we're mentioned in our parent's children list. 00197 EggGroupNode::iterator ci; 00198 ci = find(_parent->begin(), _parent->end(), this); 00199 nassertv(ci != _parent->end()); 00200 00201 // Now recurse up our parent. 00202 _parent->test_under_integrity(); 00203 } 00204 } 00205 00206 #endif // NDEBUG 00207 00208 00209 //////////////////////////////////////////////////////////////////// 00210 // Function: EggNode::egg_start_parse_body 00211 // Access: Protected, Virtual 00212 // Description: This function is called within parse_egg(). It 00213 // should call the appropriate function on the lexer to 00214 // initialize the parser into the state associated with 00215 // this object. If the object cannot be parsed into 00216 // directly, it should return false. 00217 //////////////////////////////////////////////////////////////////// 00218 bool EggNode:: 00219 egg_start_parse_body() { 00220 return false; 00221 } 00222 00223 //////////////////////////////////////////////////////////////////// 00224 // Function: EggNode::update_under 00225 // Access: Protected, Virtual 00226 // Description: This function is called from within EggGroupNode 00227 // whenever the parentage of the node has changed. It 00228 // should update the depth and under_instance flags 00229 // accordingly. 00230 // 00231 // depth_offset is the difference between the old depth 00232 // value and the new value. It should be consistent 00233 // with the supplied depth value. If it is not, we have 00234 // some error. 00235 //////////////////////////////////////////////////////////////////// 00236 void EggNode:: 00237 update_under(int depth_offset) { 00238 int depth; 00239 if (_parent == NULL) { 00240 depth = 0; 00241 _under_flags = 0; 00242 _vertex_frame = NULL; 00243 _node_frame = NULL; 00244 _vertex_frame_inv = NULL; 00245 _node_frame_inv = NULL; 00246 _vertex_to_node = NULL; 00247 _node_to_vertex = NULL; 00248 } else { 00249 depth = _parent->_depth + 1; 00250 _under_flags = _parent->_under_flags; 00251 _vertex_frame = _parent->_vertex_frame; 00252 _node_frame = _parent->_node_frame; 00253 _vertex_frame_inv = _parent->_vertex_frame_inv; 00254 _node_frame_inv = _parent->_node_frame_inv; 00255 _vertex_to_node = _parent->_vertex_to_node; 00256 _node_to_vertex = _parent->_node_to_vertex; 00257 } 00258 00259 if (depth - _depth != depth_offset) { 00260 egg_cat.error() << "Cycle in egg graph or invalid egg pointer!\n"; 00261 return; 00262 } 00263 _depth = depth; 00264 00265 adjust_under(); 00266 } 00267 00268 //////////////////////////////////////////////////////////////////// 00269 // Function: EggNode::adjust_under 00270 // Access: Protected, Virtual 00271 // Description: This is called within update_under() after all the 00272 // various under settings have been inherited directly 00273 // from the parent node. It is responsible for 00274 // adjusting these settings to reflect states local to 00275 // the current node; for instance, an <Instance> node 00276 // will force the UF_under_instance bit on. 00277 //////////////////////////////////////////////////////////////////// 00278 void EggNode:: 00279 adjust_under() { 00280 } 00281 00282 00283 //////////////////////////////////////////////////////////////////// 00284 // Function: EggNode::r_transform 00285 // Access: Protected, Virtual 00286 // Description: This is called from within the egg code by 00287 // transform(). It applies a transformation matrix 00288 // to the current node in some sensible way, then 00289 // continues down the tree. 00290 // 00291 // The first matrix is the transformation to apply; the 00292 // second is its inverse. The third parameter is the 00293 // coordinate system we are changing to, or CS_default 00294 // if we are not changing coordinate systems. 00295 //////////////////////////////////////////////////////////////////// 00296 void EggNode:: 00297 r_transform(const LMatrix4d &, const LMatrix4d &, CoordinateSystem) { 00298 } 00299 00300 //////////////////////////////////////////////////////////////////// 00301 // Function: EggNode::r_transform_vertices 00302 // Access: Protected, Virtual 00303 // Description: This is called from within the egg code by 00304 // transform_vertices_only()(). It applies a 00305 // transformation matrix to the current node in some 00306 // sensible way (if the current node is a vertex pool 00307 // with vertices), then continues down the tree. 00308 //////////////////////////////////////////////////////////////////// 00309 void EggNode:: 00310 r_transform_vertices(const LMatrix4d &) { 00311 } 00312 00313 //////////////////////////////////////////////////////////////////// 00314 // Function: EggNode::r_mark_coordsys 00315 // Access: Protected, Virtual 00316 // Description: This is only called immediately after loading an egg 00317 // file from disk, to propagate the value found in the 00318 // CoordinateSystem entry (or the default Y-up 00319 // coordinate system) to all nodes that care about what 00320 // the coordinate system is. 00321 //////////////////////////////////////////////////////////////////// 00322 void EggNode:: 00323 r_mark_coordsys(CoordinateSystem) { 00324 } 00325 00326 //////////////////////////////////////////////////////////////////// 00327 // Function: EggNode::r_flatten_transforms 00328 // Access: Protected, Virtual 00329 // Description: The recursive implementation of flatten_transforms(). 00330 //////////////////////////////////////////////////////////////////// 00331 void EggNode:: 00332 r_flatten_transforms() { 00333 } 00334 00335 //////////////////////////////////////////////////////////////////// 00336 // Function: EggNode::r_apply_texmats 00337 // Access: Protected, Virtual 00338 // Description: The recursive implementation of apply_texmats(). 00339 //////////////////////////////////////////////////////////////////// 00340 void EggNode:: 00341 r_apply_texmats(EggTextureCollection &textures) { 00342 }