Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/egg/eggNode.cxx

Go to the documentation of this file.
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 }

Generated on Fri May 2 00:37:44 2003 for Panda by doxygen1.3