00001 // Filename: eggNode.I 00002 // Created by: drose (10Feb99) 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 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: EggNode::Constructor 00022 // Access: Public 00023 // Description: 00024 //////////////////////////////////////////////////////////////////// 00025 INLINE EggNode:: 00026 EggNode(const string &name) : EggNamedObject(name) { 00027 _parent = NULL; 00028 _depth = 0; 00029 _under_flags = 0; 00030 } 00031 00032 //////////////////////////////////////////////////////////////////// 00033 // Function: EggNode::Copy constructor 00034 // Access: Public 00035 // Description: 00036 //////////////////////////////////////////////////////////////////// 00037 INLINE EggNode:: 00038 EggNode(const EggNode ©) : EggNamedObject(copy) { 00039 _parent = NULL; 00040 _depth = 0; 00041 _under_flags = 0; 00042 } 00043 00044 00045 //////////////////////////////////////////////////////////////////// 00046 // Function: EggNode::Copy assignment operator 00047 // Access: Public 00048 // Description: 00049 //////////////////////////////////////////////////////////////////// 00050 INLINE EggNode &EggNode:: 00051 operator = (const EggNode ©) { 00052 EggNamedObject::operator = (copy); 00053 update_under(0); 00054 return *this; 00055 } 00056 00057 00058 //////////////////////////////////////////////////////////////////// 00059 // Function: EggNode::get_parent 00060 // Access: Public 00061 // Description: 00062 //////////////////////////////////////////////////////////////////// 00063 INLINE EggGroupNode *EggNode:: 00064 get_parent() const { 00065 return _parent; 00066 } 00067 00068 //////////////////////////////////////////////////////////////////// 00069 // Function: EggNode::get_depth 00070 // Access: Public 00071 // Description: Returns the number of nodes above this node in the 00072 // egg hierarchy. 00073 //////////////////////////////////////////////////////////////////// 00074 INLINE int EggNode:: 00075 get_depth() const { 00076 return _depth; 00077 } 00078 00079 00080 //////////////////////////////////////////////////////////////////// 00081 // Function: EggNode::is_under_instance 00082 // Access: Public 00083 // Description: Returns true if there is an <Instance> node somewhere 00084 // in the egg tree at or above this node, false 00085 // otherwise. 00086 //////////////////////////////////////////////////////////////////// 00087 INLINE bool EggNode:: 00088 is_under_instance() const { 00089 return (_under_flags & UF_under_instance) != 0; 00090 } 00091 00092 //////////////////////////////////////////////////////////////////// 00093 // Function: EggNode::is_under_transform 00094 // Access: Public 00095 // Description: Returns true if there is a <Transform> entry somewhere 00096 // in the egg tree at or above this node, false 00097 // otherwise. 00098 //////////////////////////////////////////////////////////////////// 00099 INLINE bool EggNode:: 00100 is_under_transform() const { 00101 return (_under_flags & UF_under_transform) != 0; 00102 } 00103 00104 //////////////////////////////////////////////////////////////////// 00105 // Function: EggNode::is_local_coord 00106 // Access: Public 00107 // Description: Returns true if this node's vertices are not in the 00108 // global coordinate space. This will be the case if 00109 // there was an <Instance> node under a transform at or 00110 // above this node. 00111 //////////////////////////////////////////////////////////////////// 00112 INLINE bool EggNode:: 00113 is_local_coord() const { 00114 return (_under_flags & UF_local_coord) != 0; 00115 } 00116 00117 00118 //////////////////////////////////////////////////////////////////// 00119 // Function: EggNode::get_vertex_frame 00120 // Access: Public 00121 // Description: Returns the coordinate frame of the vertices 00122 // referenced by primitives at or under this node. This 00123 // is not the same as get_node_frame(). 00124 // 00125 // Generally, vertices in an egg file are stored in the 00126 // global coordinate space, regardless of the transforms 00127 // defined at each node. Thus, get_vertex_frame() will 00128 // usually return the identity transform (global 00129 // coordinate space). However, primitives under an 00130 // <Instance> entry reference their vertices in the 00131 // coordinate system under effect at the time of the 00132 // <Instance>. Thus, nodes under an <Instance> entry 00133 // may return this non-identity matrix. 00134 // 00135 // Specifically, this may return a non-identity matrix 00136 // only if is_local_coord() is true. 00137 //////////////////////////////////////////////////////////////////// 00138 INLINE const LMatrix4d &EggNode:: 00139 get_vertex_frame() const { 00140 if (_vertex_frame == (LMatrix4d *)NULL) { 00141 return LMatrix4d::ident_mat(); 00142 } else { 00143 return *_vertex_frame; 00144 } 00145 } 00146 00147 00148 //////////////////////////////////////////////////////////////////// 00149 // Function: EggNode::get_node_frame 00150 // Access: Public 00151 // Description: Returns the coordinate frame of the node itself. 00152 // This is simply the net product of all transformations 00153 // up to the root. 00154 //////////////////////////////////////////////////////////////////// 00155 INLINE const LMatrix4d &EggNode:: 00156 get_node_frame() const { 00157 if (_node_frame == (LMatrix4d *)NULL) { 00158 return LMatrix4d::ident_mat(); 00159 } else { 00160 return *_node_frame; 00161 } 00162 } 00163 00164 //////////////////////////////////////////////////////////////////// 00165 // Function: EggNode::get_vertex_frame_inv 00166 // Access: Public 00167 // Description: Returns the inverse of the matrix returned by 00168 // get_vertex_frame(). See get_vertex_frame(). 00169 //////////////////////////////////////////////////////////////////// 00170 INLINE const LMatrix4d &EggNode:: 00171 get_vertex_frame_inv() const { 00172 if (_vertex_frame_inv == (LMatrix4d *)NULL) { 00173 return LMatrix4d::ident_mat(); 00174 } else { 00175 return *_vertex_frame_inv; 00176 } 00177 } 00178 00179 00180 //////////////////////////////////////////////////////////////////// 00181 // Function: EggNode::get_node_frame_inv 00182 // Access: Public 00183 // Description: Returns the inverse of the matrix returned by 00184 // get_node_frame(). See get_node_frame(). 00185 //////////////////////////////////////////////////////////////////// 00186 INLINE const LMatrix4d &EggNode:: 00187 get_node_frame_inv() const { 00188 if (_node_frame_inv == (LMatrix4d *)NULL) { 00189 return LMatrix4d::ident_mat(); 00190 } else { 00191 return *_node_frame_inv; 00192 } 00193 } 00194 00195 //////////////////////////////////////////////////////////////////// 00196 // Function: EggNode::get_vertex_to_node 00197 // Access: Public 00198 // Description: Returns the transformation matrix suitable for 00199 // converting the vertices as read from the egg file 00200 // into the coordinate space of the node. This is the 00201 // same thing as: 00202 // 00203 // get_vertex_frame() * get_node_frame_inv() 00204 // 00205 //////////////////////////////////////////////////////////////////// 00206 INLINE const LMatrix4d &EggNode:: 00207 get_vertex_to_node() const { 00208 if (_vertex_to_node == (LMatrix4d *)NULL) { 00209 return LMatrix4d::ident_mat(); 00210 } else { 00211 return *_vertex_to_node; 00212 } 00213 } 00214 00215 //////////////////////////////////////////////////////////////////// 00216 // Function: EggNode::get_node_to_vertex 00217 // Access: Public 00218 // Description: Returns the transformation matrix suitable for 00219 // converting vertices in the coordinate space of the 00220 // node to the appropriate coordinate space for storing 00221 // in the egg file. This is the same thing as: 00222 // 00223 // get_node_frame() * get_vertex_frame_inv() 00224 // 00225 //////////////////////////////////////////////////////////////////// 00226 INLINE const LMatrix4d &EggNode:: 00227 get_node_to_vertex() const { 00228 if (_node_to_vertex == (LMatrix4d *)NULL) { 00229 return LMatrix4d::ident_mat(); 00230 } else { 00231 return *_node_to_vertex; 00232 } 00233 } 00234 00235 00236 //////////////////////////////////////////////////////////////////// 00237 // Function: EggNode::transform 00238 // Access: Public 00239 // Description: Applies the indicated transformation to the node and 00240 // all of its descendants. 00241 //////////////////////////////////////////////////////////////////// 00242 INLINE void EggNode:: 00243 transform(const LMatrix4d &mat) { 00244 LMatrix4d inv = invert(mat); 00245 00246 r_transform(mat, inv, CS_default); 00247 00248 // Now we have to recompute the under_flags to ensure that all the 00249 // cached relative matrices are correct. 00250 update_under(0); 00251 } 00252 00253 //////////////////////////////////////////////////////////////////// 00254 // Function: EggNode::transform_vertices_only 00255 // Access: Public 00256 // Description: Applies the indicated transformation only to vertices 00257 // that appear in global space within vertex pools at 00258 // this node and below. Joints and other transforms are 00259 // not affected, nor are local vertices. 00260 //////////////////////////////////////////////////////////////////// 00261 INLINE void EggNode:: 00262 transform_vertices_only(const LMatrix4d &mat) { 00263 r_transform_vertices(mat); 00264 } 00265 00266 //////////////////////////////////////////////////////////////////// 00267 // Function: EggNode::flatten_transforms 00268 // Access: Public 00269 // Description: Removes any transform and instance records from this 00270 // node in the scene graph and below. If an instance 00271 // node is encountered, removes the instance and applies 00272 // the transform to its vertices, duplicating vertices 00273 // if necessary. 00274 // 00275 // Since this function may result in duplicated 00276 // vertices, it may be a good idea to call 00277 // remove_unused_vertices() after calling this. 00278 //////////////////////////////////////////////////////////////////// 00279 INLINE void EggNode:: 00280 flatten_transforms() { 00281 r_flatten_transforms(); 00282 update_under(0); 00283 }