Panda3D
 All Classes Functions Variables Enumerations
eggNode.cxx
00001 // Filename: eggNode.cxx
00002 // Created by:  drose (16Jan99)
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 "eggNode.h"
00016 #include "eggGroupNode.h"
00017 #include "config_egg.h"
00018 #include "eggTextureCollection.h"
00019 #include "dcast.h"
00020 
00021 #include <algorithm>
00022 
00023 extern int eggyyparse();
00024 #include "parserDefs.h"
00025 #include "lexerDefs.h"
00026 
00027 TypeHandle EggNode::_type_handle;
00028 
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //     Function: EggNode::rename_node
00032 //       Access: Published
00033 //  Description: Rename by stripping out the prefix
00034 ////////////////////////////////////////////////////////////////////
00035 int EggNode::
00036 rename_node(vector_string strip_prefix) {
00037   int num_renamed = 0;
00038   for (unsigned int ni = 0; ni < strip_prefix.size(); ++ni) {
00039     string axe_name = strip_prefix[ni];
00040     if (this->get_name().substr(0, axe_name.size()) == axe_name) {
00041       string new_name = this->get_name().substr(axe_name.size());
00042       //cout << "renaming " << this->get_name() << "->" << new_name << endl;
00043       this->set_name(new_name);
00044       num_renamed += 1;
00045     }
00046   }
00047   return num_renamed;
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: EggNode::apply_texmats
00052 //       Access: Public
00053 //  Description: Applies the texture matrices to the UV's of the
00054 //               vertices that reference them, and then removes the
00055 //               texture matrices from the textures themselves.
00056 ////////////////////////////////////////////////////////////////////
00057 void EggNode::
00058 apply_texmats() {
00059   EggTextureCollection textures;
00060   textures.find_used_textures(this);
00061   r_apply_texmats(textures);
00062 }
00063 
00064 ////////////////////////////////////////////////////////////////////
00065 //     Function: EggNode::is_joint
00066 //       Access: Public, Virtual
00067 //  Description: Returns true if this particular node represents a
00068 //               <Joint> entry or not.  This is a handy thing to know
00069 //               since Joints are sorted to the end of their sibling
00070 //               list when writing an egg file.  See
00071 //               EggGroupNode::write().
00072 ////////////////////////////////////////////////////////////////////
00073 bool EggNode::
00074 is_joint() const {
00075   return false;
00076 }
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: EggNode::is_anim_matrix
00080 //       Access: Public, Virtual
00081 //  Description: Returns true if this node represents a table of
00082 //               animation transformation data, false otherwise.
00083 ////////////////////////////////////////////////////////////////////
00084 bool EggNode::
00085 is_anim_matrix() const {
00086   return false;
00087 }
00088 
00089 ////////////////////////////////////////////////////////////////////
00090 //     Function: EggNode::determine_alpha_mode
00091 //       Access: Public, Virtual
00092 //  Description: Walks back up the hierarchy, looking for an EggGroup
00093 //               or EggPrimitive or some such object at this level or
00094 //               above this node that has an alpha_mode other than
00095 //               AM_unspecified.  Returns a valid EggRenderMode pointer
00096 //               if one is found, or NULL otherwise.
00097 ////////////////////////////////////////////////////////////////////
00098 EggRenderMode *EggNode::
00099 determine_alpha_mode() {
00100   if (_parent == (EggGroupNode *)NULL) {
00101     // Too bad; we're done.
00102     return (EggRenderMode *)NULL;
00103   }
00104   return _parent->determine_alpha_mode();
00105 }
00106 
00107 ////////////////////////////////////////////////////////////////////
00108 //     Function: EggNode::determine_depth_write_mode
00109 //       Access: Public, Virtual
00110 //  Description: Walks back up the hierarchy, looking for an EggGroup
00111 //               or EggPrimitive or some such object at this level or
00112 //               above this node that has a depth_write_mode other than
00113 //               DWM_unspecified.  Returns a valid EggRenderMode pointer
00114 //               if one is found, or NULL otherwise.
00115 ////////////////////////////////////////////////////////////////////
00116 EggRenderMode *EggNode::
00117 determine_depth_write_mode() {
00118   if (_parent == (EggGroupNode *)NULL) {
00119     // Too bad; we're done.
00120     return (EggRenderMode *)NULL;
00121   }
00122   return _parent->determine_depth_write_mode();
00123 }
00124 
00125 ////////////////////////////////////////////////////////////////////
00126 //     Function: EggNode::determine_depth_test_mode
00127 //       Access: Public, Virtual
00128 //  Description: Walks back up the hierarchy, looking for an EggGroup
00129 //               or EggPrimitive or some such object at this level or
00130 //               above this node that has a depth_test_mode other than
00131 //               DTM_unspecified.  Returns a valid EggRenderMode pointer
00132 //               if one is found, or NULL otherwise.
00133 ////////////////////////////////////////////////////////////////////
00134 EggRenderMode *EggNode::
00135 determine_depth_test_mode() {
00136   if (_parent == (EggGroupNode *)NULL) {
00137     // Too bad; we're done.
00138     return (EggRenderMode *)NULL;
00139   }
00140   return _parent->determine_depth_test_mode();
00141 }
00142 
00143 ////////////////////////////////////////////////////////////////////
00144 //     Function: EggNode::determine_visibility_mode
00145 //       Access: Public, Virtual
00146 //  Description: Walks back up the hierarchy, looking for an EggGroup
00147 //               or EggPrimitive or some such object at this level or
00148 //               above this node that has a visibility_mode other than
00149 //               VM_unspecified.  Returns a valid EggRenderMode pointer
00150 //               if one is found, or NULL otherwise.
00151 ////////////////////////////////////////////////////////////////////
00152 EggRenderMode *EggNode::
00153 determine_visibility_mode() {
00154   if (_parent == (EggGroupNode *)NULL) {
00155     // Too bad; we're done.
00156     return (EggRenderMode *)NULL;
00157   }
00158   return _parent->determine_visibility_mode();
00159 }
00160 
00161 ////////////////////////////////////////////////////////////////////
00162 //     Function: EggNode::determine_depth_offset
00163 //       Access: Public, Virtual
00164 //  Description: Walks back up the hierarchy, looking for an EggGroup
00165 //               or EggPrimitive or some such object at this level or
00166 //               above this node that has a depth_offset specified.
00167 //               Returns a valid EggRenderMode pointer if one is found,
00168 //               or NULL otherwise.
00169 ////////////////////////////////////////////////////////////////////
00170 EggRenderMode *EggNode::
00171 determine_depth_offset() {
00172   if (_parent == (EggGroupNode *)NULL) {
00173     // Too bad; we're done.
00174     return (EggRenderMode *)NULL;
00175   }
00176   return _parent->determine_depth_offset();
00177 }
00178 
00179 ////////////////////////////////////////////////////////////////////
00180 //     Function: EggNode::determine_draw_order
00181 //       Access: Public, Virtual
00182 //  Description: Walks back up the hierarchy, looking for an EggGroup
00183 //               or EggPrimitive or some such object at this level or
00184 //               above this node that has a draw_order specified.
00185 //               Returns a valid EggRenderMode pointer if one is found,
00186 //               or NULL otherwise.
00187 ////////////////////////////////////////////////////////////////////
00188 EggRenderMode *EggNode::
00189 determine_draw_order() {
00190   if (_parent == (EggGroupNode *)NULL) {
00191     // Too bad; we're done.
00192     return (EggRenderMode *)NULL;
00193   }
00194   return _parent->determine_draw_order();
00195 }
00196 
00197 ////////////////////////////////////////////////////////////////////
00198 //     Function: EggNode::determine_bin
00199 //       Access: Public, Virtual
00200 //  Description: Walks back up the hierarchy, looking for an EggGroup
00201 //               or EggPrimitive or some such object at this level or
00202 //               above this node that has a bin specified.  Returns a
00203 //               valid EggRenderMode pointer if one is found, or NULL
00204 //               otherwise.
00205 ////////////////////////////////////////////////////////////////////
00206 EggRenderMode *EggNode::
00207 determine_bin() {
00208   if (_parent == (EggGroupNode *)NULL) {
00209     // Too bad; we're done.
00210     return (EggRenderMode *)NULL;
00211   }
00212   return _parent->determine_bin();
00213 }
00214 
00215 ////////////////////////////////////////////////////////////////////
00216 //     Function: EggNode::determine_indexed
00217 //       Access: Public, Virtual
00218 //  Description: Walks back up the hierarchy, looking for an EggGroup
00219 //               at this level or above that has the "indexed" scalar
00220 //               set.  Returns the value of the indexed scalar if it
00221 //               is found, or false if it is not.
00222 //
00223 //               In other words, returns true if the "indexed" flag is
00224 //               in effect for the indicated node, false otherwise.
00225 ////////////////////////////////////////////////////////////////////
00226 bool EggNode::
00227 determine_indexed() {
00228   if (_parent == (EggGroupNode *)NULL) {
00229     // Too bad; we're done.
00230     return false;
00231   }
00232   return _parent->determine_indexed();
00233 }
00234 
00235 ////////////////////////////////////////////////////////////////////
00236 //     Function: EggNode::determine_decal
00237 //       Access: Public, Virtual
00238 //  Description: Walks back up the hierarchy, looking for an EggGroup
00239 //               at this level or above that has the "decal" flag
00240 //               set.  Returns the value of the decal flag if it
00241 //               is found, or false if it is not.
00242 //
00243 //               In other words, returns true if the "decal" flag is
00244 //               in effect for the indicated node, false otherwise.
00245 ////////////////////////////////////////////////////////////////////
00246 bool EggNode::
00247 determine_decal() {
00248   if (_parent == (EggGroupNode *)NULL) {
00249     // Too bad; we're done.
00250     return false;
00251   }
00252   return _parent->determine_decal();
00253 }
00254 
00255 
00256 ////////////////////////////////////////////////////////////////////
00257 //     Function: EggNode::parse_egg
00258 //       Access: Public
00259 //  Description: Parses the egg syntax given in the indicate string as
00260 //               if it had been read from the egg file within this
00261 //               object's definition.  Updates the object accordingly.
00262 //               Returns true if successful, false if there was some
00263 //               parse error or if the object does not support this
00264 //               functionality.
00265 ////////////////////////////////////////////////////////////////////
00266 bool EggNode::
00267 parse_egg(const string &egg_syntax) {
00268   EggGroupNode *group = get_parent();
00269   if (is_of_type(EggGroupNode::get_class_type())) {
00270     DCAST_INTO_R(group, this, false);
00271   }
00272 
00273   istringstream in(egg_syntax);
00274 
00275   LightMutexHolder holder(egg_lock);
00276 
00277   egg_init_parser(in, "", this, group);
00278 
00279   if (!egg_start_parse_body()) {
00280     egg_cleanup_parser();
00281     return false;
00282   }
00283 
00284   eggyyparse();
00285   egg_cleanup_parser();
00286 
00287   return (egg_error_count() == 0);
00288 }
00289 
00290 #ifdef _DEBUG
00291 
00292 ////////////////////////////////////////////////////////////////////
00293 //     Function: EggNode::test_under_integrity
00294 //       Access: Public
00295 //  Description: Recursively checks the integrity of the _under_flags,
00296 //               _parent, and _depth members of this node and all of
00297 //               its ancestors.
00298 ////////////////////////////////////////////////////////////////////
00299 void EggNode::
00300 test_under_integrity() const {
00301   if (_parent == NULL) {
00302     // If we have no parent, everything should be zero.
00303     nassertv(_depth == 0);
00304     nassertv(_under_flags == 0);
00305   } else {
00306     // Otherwise, make sure we're consistent with our parent.
00307     _parent->test_ref_count_integrity();
00308 
00309     nassertv(_depth == _parent->_depth + 1);
00310 
00311     // We can't perform too much checking on the under_flags, since we
00312     // don't know which bits should have been added for this node.
00313     // We'll verify that at least we didn't accidentally take some
00314     // bits away.
00315     nassertv((_under_flags & _parent->_under_flags) == _parent->_under_flags);
00316 
00317     // Make sure we're mentioned in our parent's children list.
00318     EggGroupNode::iterator ci;
00319     ci = find(_parent->begin(), _parent->end(), this);
00320     nassertv(ci != _parent->end());
00321 
00322     // Now recurse up our parent.
00323     _parent->test_under_integrity();
00324   }
00325 }
00326 
00327 #endif  // _DEBUG
00328 
00329 
00330 ////////////////////////////////////////////////////////////////////
00331 //     Function: EggNode::egg_start_parse_body
00332 //       Access: Protected, Virtual
00333 //  Description: This function is called within parse_egg().  It
00334 //               should call the appropriate function on the lexer to
00335 //               initialize the parser into the state associated with
00336 //               this object.  If the object cannot be parsed into
00337 //               directly, it should return false.
00338 ////////////////////////////////////////////////////////////////////
00339 bool EggNode::
00340 egg_start_parse_body() {
00341   return false;
00342 }
00343 
00344 ////////////////////////////////////////////////////////////////////
00345 //     Function: EggNode::update_under
00346 //       Access: Protected, Virtual
00347 //  Description: This function is called from within EggGroupNode
00348 //               whenever the parentage of the node has changed.  It
00349 //               should update the depth and under_instance flags
00350 //               accordingly.
00351 //
00352 //               depth_offset is the difference between the old depth
00353 //               value and the new value.  It should be consistent
00354 //               with the supplied depth value.  If it is not, we have
00355 //               some error.
00356 ////////////////////////////////////////////////////////////////////
00357 void EggNode::
00358 update_under(int depth_offset) {
00359   int depth;
00360   if (_parent == NULL) {
00361     depth = 0;
00362     _under_flags = 0;
00363     _vertex_frame = NULL;
00364     _node_frame = NULL;
00365     _vertex_frame_inv = NULL;
00366     _node_frame_inv = NULL;
00367     _vertex_to_node = NULL;
00368     _node_to_vertex = NULL;
00369   } else {
00370     _parent->test_ref_count_integrity();
00371     depth = _parent->_depth + 1;
00372     _under_flags = _parent->_under_flags;
00373     _vertex_frame = _parent->_vertex_frame;
00374     _node_frame = _parent->_node_frame;
00375     _vertex_frame_inv = _parent->_vertex_frame_inv;
00376     _node_frame_inv = _parent->_node_frame_inv;
00377     _vertex_to_node = _parent->_vertex_to_node;
00378     _node_to_vertex = _parent->_node_to_vertex;
00379   }
00380 
00381   if (depth - _depth != depth_offset) {
00382     egg_cat.error() << "Cycle in egg graph or invalid egg pointer!\n";
00383     return;
00384   }
00385   _depth = depth;
00386 
00387   adjust_under();
00388 }
00389 
00390 ////////////////////////////////////////////////////////////////////
00391 //     Function: EggNode::adjust_under
00392 //       Access: Protected, Virtual
00393 //  Description: This is called within update_under() after all the
00394 //               various under settings have been inherited directly
00395 //               from the parent node.  It is responsible for
00396 //               adjusting these settings to reflect states local to
00397 //               the current node; for instance, an <Instance> node
00398 //               will force the UF_under_instance bit on.
00399 ////////////////////////////////////////////////////////////////////
00400 void EggNode::
00401 adjust_under() {
00402 }
00403 
00404 ////////////////////////////////////////////////////////////////////
00405 //     Function: EggNode::has_primitives
00406 //       Access: Protected, Virtual
00407 //  Description: Returns true if there are any primitives
00408 //               (e.g. polygons) defined within this group or below,
00409 //               false otherwise.
00410 ////////////////////////////////////////////////////////////////////
00411 bool EggNode::
00412 has_primitives() const {
00413   return false;
00414 }
00415 
00416 ////////////////////////////////////////////////////////////////////
00417 //     Function: EggNode::joint_has_primitives
00418 //       Access: Protected, Virtual
00419 //  Description: Returns true if there are any primitives
00420 //               (e.g. polygons) defined within this group or below,
00421 //               but the search does not include nested joints.
00422 ////////////////////////////////////////////////////////////////////
00423 bool EggNode::
00424 joint_has_primitives() const {
00425   return false;
00426 }
00427 
00428 ////////////////////////////////////////////////////////////////////
00429 //     Function: EggNode::has_normals
00430 //       Access: Published, Virtual
00431 //  Description: Returns true if any of the primitives (e.g. polygons)
00432 //               defined within this group or below have either face
00433 //               or vertex normals defined, false otherwise.
00434 ////////////////////////////////////////////////////////////////////
00435 bool EggNode::
00436 has_normals() const {
00437   return false;
00438 }
00439 
00440 
00441 ////////////////////////////////////////////////////////////////////
00442 //     Function: EggNode::r_transform
00443 //       Access: Protected, Virtual
00444 //  Description: This is called from within the egg code by
00445 //               transform().  It applies a transformation matrix
00446 //               to the current node in some sensible way, then
00447 //               continues down the tree.
00448 //
00449 //               The first matrix is the transformation to apply; the
00450 //               second is its inverse.  The third parameter is the
00451 //               coordinate system we are changing to, or CS_default
00452 //               if we are not changing coordinate systems.
00453 ////////////////////////////////////////////////////////////////////
00454 void EggNode::
00455 r_transform(const LMatrix4d &, const LMatrix4d &, CoordinateSystem) {
00456 }
00457 
00458 ////////////////////////////////////////////////////////////////////
00459 //     Function: EggNode::r_transform_vertices
00460 //       Access: Protected, Virtual
00461 //  Description: This is called from within the egg code by
00462 //               transform_vertices_only()().  It applies a
00463 //               transformation matrix to the current node in some
00464 //               sensible way (if the current node is a vertex pool
00465 //               with vertices), then continues down the tree.
00466 ////////////////////////////////////////////////////////////////////
00467 void EggNode::
00468 r_transform_vertices(const LMatrix4d &) {
00469 }
00470 
00471 ////////////////////////////////////////////////////////////////////
00472 //     Function: EggNode::r_mark_coordsys
00473 //       Access: Protected, Virtual
00474 //  Description: This is only called immediately after loading an egg
00475 //               file from disk, to propagate the value found in the
00476 //               CoordinateSystem entry (or the default Y-up
00477 //               coordinate system) to all nodes that care about what
00478 //               the coordinate system is.
00479 ////////////////////////////////////////////////////////////////////
00480 void EggNode::
00481 r_mark_coordsys(CoordinateSystem) {
00482 }
00483 
00484 ////////////////////////////////////////////////////////////////////
00485 //     Function: EggNode::r_flatten_transforms
00486 //       Access: Protected, Virtual
00487 //  Description: The recursive implementation of flatten_transforms().
00488 ////////////////////////////////////////////////////////////////////
00489 void EggNode::
00490 r_flatten_transforms() {
00491 }
00492 
00493 ////////////////////////////////////////////////////////////////////
00494 //     Function: EggNode::r_apply_texmats
00495 //       Access: Protected, Virtual
00496 //  Description: The recursive implementation of apply_texmats().
00497 ////////////////////////////////////////////////////////////////////
00498 void EggNode::
00499 r_apply_texmats(EggTextureCollection &textures) {
00500 }
 All Classes Functions Variables Enumerations