Panda3D
Loading...
Searching...
No Matches
eggNode.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file eggNode.cxx
10 * @author drose
11 * @date 1999-01-16
12 */
13
14#include "eggNode.h"
15#include "eggGroupNode.h"
16#include "lightMutexHolder.h"
17#include "config_egg.h"
19#include "dcast.h"
20
21#include <algorithm>
22
23extern int eggyyparse();
24#include "parserDefs.h"
25#include "lexerDefs.h"
26
27TypeHandle EggNode::_type_handle;
28
29
30/**
31 * Rename by stripping out the prefix
32 */
34rename_node(vector_string strip_prefix) {
35 int num_renamed = 0;
36 for (unsigned int ni = 0; ni < strip_prefix.size(); ++ni) {
37 std::string axe_name = strip_prefix[ni];
38 if (this->get_name().substr(0, axe_name.size()) == axe_name) {
39 std::string new_name = this->get_name().substr(axe_name.size());
40 // cout << "renaming " << this->get_name() << "->" << new_name << endl;
41 this->set_name(new_name);
42 num_renamed += 1;
43 }
44 }
45 return num_renamed;
46}
47
48/**
49 * Applies the texture matrices to the UV's of the vertices that reference
50 * them, and then removes the texture matrices from the textures themselves.
51 */
54 EggTextureCollection textures;
55 textures.find_used_textures(this);
56 r_apply_texmats(textures);
57}
58
59/**
60 * Returns true if this particular node represents a <Joint> entry or not.
61 * This is a handy thing to know since Joints are sorted to the end of their
62 * sibling list when writing an egg file. See EggGroupNode::write().
63 */
65is_joint() const {
66 return false;
67}
68
69/**
70 * Returns true if this node represents a table of animation transformation
71 * data, false otherwise.
72 */
74is_anim_matrix() const {
75 return false;
76}
77
78/**
79 * Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or
80 * some such object at this level or above this node that has an alpha_mode
81 * other than AM_unspecified. Returns a valid EggRenderMode pointer if one is
82 * found, or NULL otherwise.
83 */
86 if (_parent == nullptr) {
87 // Too bad; we're done.
88 return nullptr;
89 }
90 return _parent->determine_alpha_mode();
91}
92
93/**
94 * Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or
95 * some such object at this level or above this node that has a
96 * depth_write_mode other than DWM_unspecified. Returns a valid EggRenderMode
97 * pointer if one is found, or NULL otherwise.
98 */
101 if (_parent == nullptr) {
102 // Too bad; we're done.
103 return nullptr;
104 }
105 return _parent->determine_depth_write_mode();
106}
107
108/**
109 * Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or
110 * some such object at this level or above this node that has a
111 * depth_test_mode other than DTM_unspecified. Returns a valid EggRenderMode
112 * pointer if one is found, or NULL otherwise.
113 */
116 if (_parent == nullptr) {
117 // Too bad; we're done.
118 return nullptr;
119 }
120 return _parent->determine_depth_test_mode();
121}
122
123/**
124 * Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or
125 * some such object at this level or above this node that has a
126 * visibility_mode other than VM_unspecified. Returns a valid EggRenderMode
127 * pointer if one is found, or NULL otherwise.
128 */
131 if (_parent == nullptr) {
132 // Too bad; we're done.
133 return nullptr;
134 }
135 return _parent->determine_visibility_mode();
136}
137
138/**
139 * Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or
140 * some such object at this level or above this node that has a depth_offset
141 * specified. Returns a valid EggRenderMode pointer if one is found, or NULL
142 * otherwise.
143 */
146 if (_parent == nullptr) {
147 // Too bad; we're done.
148 return nullptr;
149 }
150 return _parent->determine_depth_offset();
151}
152
153/**
154 * Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or
155 * some such object at this level or above this node that has a draw_order
156 * specified. Returns a valid EggRenderMode pointer if one is found, or NULL
157 * otherwise.
158 */
161 if (_parent == nullptr) {
162 // Too bad; we're done.
163 return nullptr;
164 }
165 return _parent->determine_draw_order();
166}
167
168/**
169 * Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or
170 * some such object at this level or above this node that has a bin specified.
171 * Returns a valid EggRenderMode pointer if one is found, or NULL otherwise.
172 */
175 if (_parent == nullptr) {
176 // Too bad; we're done.
177 return nullptr;
178 }
179 return _parent->determine_bin();
180}
181
182/**
183 * Walks back up the hierarchy, looking for an EggGroup at this level or above
184 * that has the "indexed" scalar set. Returns the value of the indexed scalar
185 * if it is found, or false if it is not.
186 *
187 * In other words, returns true if the "indexed" flag is in effect for the
188 * indicated node, false otherwise.
189 */
192 if (_parent == nullptr) {
193 // Too bad; we're done.
194 return false;
195 }
196 return _parent->determine_indexed();
197}
198
199/**
200 * Walks back up the hierarchy, looking for an EggGroup at this level or above
201 * that has the "decal" flag set. Returns the value of the decal flag if it
202 * is found, or false if it is not.
203 *
204 * In other words, returns true if the "decal" flag is in effect for the
205 * indicated node, false otherwise.
206 */
209 if (_parent == nullptr) {
210 // Too bad; we're done.
211 return false;
212 }
213 return _parent->determine_decal();
214}
215
216
217/**
218 * Parses the egg syntax given in the indicate string as if it had been read
219 * from the egg file within this object's definition. Updates the object
220 * accordingly. Returns true if successful, false if there was some parse
221 * error or if the object does not support this functionality.
222 */
224parse_egg(const std::string &egg_syntax) {
225 EggGroupNode *group = get_parent();
226 if (is_of_type(EggGroupNode::get_class_type())) {
227 DCAST_INTO_R(group, this, false);
228 }
229
230 std::istringstream in(egg_syntax);
231
232 LightMutexHolder holder(egg_lock);
233
234 egg_init_parser(in, "", this, group);
235
236 if (!egg_start_parse_body()) {
237 egg_cleanup_parser();
238 return false;
239 }
240
241 eggyyparse();
242 egg_cleanup_parser();
243
244 return (egg_error_count() == 0);
245}
246
247#ifdef _DEBUG
248
249/**
250 * Recursively checks the integrity of the _under_flags, _parent, and _depth
251 * members of this node and all of its ancestors.
252 */
253void EggNode::
254test_under_integrity() const {
255 if (_parent == nullptr) {
256 // If we have no parent, everything should be zero.
257 nassertv(_depth == 0);
258 nassertv(_under_flags == 0);
259 } else {
260 // Otherwise, make sure we're consistent with our parent.
261 _parent->test_ref_count_integrity();
262
263 nassertv(_depth == _parent->_depth + 1);
264
265 // We can't perform too much checking on the under_flags, since we don't
266 // know which bits should have been added for this node. We'll verify
267 // that at least we didn't accidentally take some bits away.
268 nassertv((_under_flags & _parent->_under_flags) == _parent->_under_flags);
269
270 // Make sure we're mentioned in our parent's children list.
271 EggGroupNode::iterator ci;
272 ci = find(_parent->begin(), _parent->end(), this);
273 nassertv(ci != _parent->end());
274
275 // Now recurse up our parent.
276 _parent->test_under_integrity();
277 }
278}
279
280#endif // _DEBUG
281
282
283/**
284 * This function is called within parse_egg(). It should call the appropriate
285 * function on the lexer to initialize the parser into the state associated
286 * with this object. If the object cannot be parsed into directly, it should
287 * return false.
288 */
289bool EggNode::
290egg_start_parse_body() {
291 return false;
292}
293
294/**
295 * This function is called from within EggGroupNode whenever the parentage of
296 * the node has changed. It should update the depth and under_instance flags
297 * accordingly.
298 *
299 * depth_offset is the difference between the old depth value and the new
300 * value. It should be consistent with the supplied depth value. If it is
301 * not, we have some error.
302 */
303void EggNode::
304update_under(int depth_offset) {
305 int depth;
306 if (_parent == nullptr) {
307 depth = 0;
308 _under_flags = 0;
309 _vertex_frame = nullptr;
310 _node_frame = nullptr;
311 _vertex_frame_inv = nullptr;
312 _node_frame_inv = nullptr;
313 _vertex_to_node = nullptr;
314 _node_to_vertex = nullptr;
315 } else {
316 _parent->test_ref_count_integrity();
317 depth = _parent->_depth + 1;
318 _under_flags = _parent->_under_flags;
319 _vertex_frame = _parent->_vertex_frame;
320 _node_frame = _parent->_node_frame;
321 _vertex_frame_inv = _parent->_vertex_frame_inv;
322 _node_frame_inv = _parent->_node_frame_inv;
323 _vertex_to_node = _parent->_vertex_to_node;
324 _node_to_vertex = _parent->_node_to_vertex;
325 }
326
327 if (depth - _depth != depth_offset) {
328 egg_cat.error() << "Cycle in egg graph or invalid egg pointer!\n";
329 return;
330 }
331 _depth = depth;
332
333 adjust_under();
334}
335
336/**
337 * This is called within update_under() after all the various under settings
338 * have been inherited directly from the parent node. It is responsible for
339 * adjusting these settings to reflect states local to the current node; for
340 * instance, an <Instance> node will force the UF_under_instance bit on.
341 */
342void EggNode::
343adjust_under() {
344}
345
346/**
347 * Returns true if there are any primitives (e.g. polygons) defined within
348 * this group or below, false otherwise.
349 */
350bool EggNode::
351has_primitives() const {
352 return false;
353}
354
355/**
356 * Returns true if there are any primitives (e.g. polygons) defined within
357 * this group or below, but the search does not include nested joints.
358 */
359bool EggNode::
360joint_has_primitives() const {
361 return false;
362}
363
364/**
365 * Returns true if any of the primitives (e.g. polygons) defined within this
366 * group or below have either face or vertex normals defined, false otherwise.
367 */
368bool EggNode::
369has_normals() const {
370 return false;
371}
372
373
374/**
375 * This is called from within the egg code by transform(). It applies a
376 * transformation matrix to the current node in some sensible way, then
377 * continues down the tree.
378 *
379 * The first matrix is the transformation to apply; the second is its inverse.
380 * The third parameter is the coordinate system we are changing to, or
381 * CS_default if we are not changing coordinate systems.
382 */
383void EggNode::
384r_transform(const LMatrix4d &, const LMatrix4d &, CoordinateSystem) {
385}
386
387/**
388 * This is called from within the egg code by transform_vertices_only()(). It
389 * applies a transformation matrix to the current node in some sensible way
390 * (if the current node is a vertex pool with vertices), then continues down
391 * the tree.
392 */
393void EggNode::
394r_transform_vertices(const LMatrix4d &) {
395}
396
397/**
398 * This is only called immediately after loading an egg file from disk, to
399 * propagate the value found in the CoordinateSystem entry (or the default
400 * Y-up coordinate system) to all nodes that care about what the coordinate
401 * system is.
402 */
403void EggNode::
404r_mark_coordsys(CoordinateSystem) {
405}
406
407/**
408 * The recursive implementation of flatten_transforms().
409 */
410void EggNode::
411r_flatten_transforms() {
412}
413
414/**
415 * The recursive implementation of apply_texmats().
416 */
417void EggNode::
418r_apply_texmats(EggTextureCollection &textures) {
419}
A base class for nodes in the hierarchy that are not leaf nodes.
virtual EggRenderMode * determine_bin()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition eggNode.cxx:174
virtual bool is_joint() const
Returns true if this particular node represents a <Joint> entry or not.
Definition eggNode.cxx:65
virtual EggRenderMode * determine_alpha_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition eggNode.cxx:85
int rename_node(vector_string strip_prefix)
Rename by stripping out the prefix.
Definition eggNode.cxx:34
virtual EggRenderMode * determine_depth_test_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition eggNode.cxx:115
void apply_texmats()
Applies the texture matrices to the UV's of the vertices that reference them, and then removes the te...
Definition eggNode.cxx:53
virtual EggRenderMode * determine_depth_offset()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition eggNode.cxx:145
virtual bool is_anim_matrix() const
Returns true if this node represents a table of animation transformation data, false otherwise.
Definition eggNode.cxx:74
virtual bool determine_indexed()
Walks back up the hierarchy, looking for an EggGroup at this level or above that has the "indexed" sc...
Definition eggNode.cxx:191
bool parse_egg(const std::string &egg_syntax)
Parses the egg syntax given in the indicate string as if it had been read from the egg file within th...
Definition eggNode.cxx:224
virtual EggRenderMode * determine_depth_write_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition eggNode.cxx:100
virtual EggRenderMode * determine_visibility_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition eggNode.cxx:130
virtual EggRenderMode * determine_draw_order()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition eggNode.cxx:160
virtual bool determine_decal()
Walks back up the hierarchy, looking for an EggGroup at this level or above that has the "decal" flag...
Definition eggNode.cxx:208
This class stores miscellaneous rendering properties that is associated with geometry,...
This is a collection of textures by TRef name.
int find_used_textures(EggNode *node)
Walks the egg hierarchy beginning at the indicated node, looking for textures that are referenced by ...
Similar to MutexHolder, but for a light mutex.
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn't completely bogus.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition typedObject.I:28
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.