Panda3D
eggToFlt.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 eggToFlt.cxx
10  * @author drose
11  * @date 2003-10-01
12  */
13 
14 #include "eggToFlt.h"
15 #include "fltHeader.h"
16 #include "fltBead.h"
17 #include "fltGroup.h"
18 #include "fltFace.h"
19 #include "fltVertexList.h"
20 #include "fltVertex.h"
21 #include "fltTexture.h"
22 #include "fltTransformTranslate.h"
24 #include "fltTransformScale.h"
26 #include "eggPolygon.h"
27 #include "eggPoint.h"
28 #include "eggPrimitive.h"
29 #include "eggExternalReference.h"
30 #include "eggGroup.h"
31 #include "eggGroupNode.h"
32 #include "eggTexture.h"
33 #include "eggTransform.h"
34 #include "dcast.h"
35 #include "string_utils.h"
36 #include "vector_string.h"
37 
38 /**
39  *
40  */
41 EggToFlt::
42 EggToFlt() :
43  EggToSomething("MultiGen", ".flt", true, false)
44 {
45  set_binary_output(true);
46  set_program_brief("convert files from .egg format to MultiGen .flt");
47  set_program_description
48  ("egg2lt converts files from egg format to MultiGen .flt "
49  "format. It attempts to be as robust as possible, and matches "
50  "the capabilities of flt2egg. Generally, converting a model "
51  "from egg2lt and then back via flt2egg will result in essentially "
52  "the same egg file, within the limitations of what can be "
53  "represented in flt.");
54 
55  add_option
56  ("attr", "none/new/all", 0,
57  "Specifies whether to write (or rewrite) .attr files for each "
58  "texture image. MultiGen stores texture properties like mipmapping "
59  "in a separate .attr file for each different texture image. "
60  "If this parameter is \"none\", these files will not be generated; "
61  "if this is \"new\", these files will only be generated if they "
62  "do not already exist (even if the properties have changed). "
63  "Specifying \"all\" causes these to be rewritten every time.",
64  &EggToFlt::dispatch_attr, nullptr, &_auto_attr_update);
65 
66  // Flt files are always in the z-up coordinate system. Don't confuse the
67  // user with this meaningless option.
68  remove_option("cs");
69  _coordinate_system = CS_zup_right;
70  _got_coordinate_system = true;
71  _auto_attr_update = FltHeader::AU_if_missing;
72 }
73 
74 /**
75  *
76  */
77 void EggToFlt::
78 run() {
79  _flt_header = new FltHeader(_path_replace);
80  _flt_header->set_auto_attr_update(_auto_attr_update);
81 
82  traverse(_data, _flt_header, FltGeometry::BT_none);
83 
84  // Finally, write the resulting file out.
85  FltError result = _flt_header->write_flt(get_output());
86  if (result != FE_ok) {
87  nout << "Cannot write " << get_output_filename() << "\n";
88  exit(1);
89  }
90 }
91 
92 /**
93  * Dispatch function for the -attr parameter.
94  */
95 bool EggToFlt::
96 dispatch_attr(const std::string &opt, const std::string &arg, void *var) {
97  FltHeader::AttrUpdate *ip = (FltHeader::AttrUpdate *)var;
98 
99  if (cmp_nocase(arg, "none") == 0) {
100  *ip = FltHeader::AU_none;
101 
102  } else if (cmp_nocase(arg, "new") == 0) {
103  *ip = FltHeader::AU_if_missing;
104 
105  } else if (cmp_nocase(arg, "all") == 0) {
106  *ip = FltHeader::AU_always;
107 
108  } else {
109  nout << "-" << opt
110  << " requires either \"none\", \"new\", or \"all\".\n";
111  return false;
112  }
113 
114  return true;
115 }
116 
117 /**
118  *
119  */
120 void EggToFlt::
121 traverse(EggNode *egg_node, FltBead *flt_node,
122  FltGeometry::BillboardType billboard) {
123  if (egg_node->is_of_type(EggPolygon::get_class_type()) ||
124  egg_node->is_of_type(EggPoint::get_class_type())) {
125  // It's a polygon or point light.
126  EggPrimitive *egg_primitive = DCAST(EggPrimitive, egg_node);
127  convert_primitive(egg_primitive, flt_node, billboard);
128 
129  } else if (egg_node->is_of_type(EggExternalReference::get_class_type())) {
130  // Convert external references.
131 
132  } else if (egg_node->is_of_type(EggGroup::get_class_type())) {
133  // An EggGroup creates a fltBead, and recurses.
134  EggGroup *egg_group = DCAST(EggGroup, egg_node);
135 
136  if (egg_group->get_group_type() == EggGroup::GT_joint) {
137  // Ignore joints and their children.
138  return;
139  }
140 
141  convert_group(egg_group, flt_node, billboard);
142 
143  } else if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
144  // Some kind of grouping node other than an EggGroup. Just recurse.
145  EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
146  EggGroupNode::iterator ci;
147  for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
148  traverse(*ci, flt_node, billboard);
149  }
150  }
151 }
152 
153 /**
154  * Converts an egg polygon or series of light points to the corresponding Flt
155  * geometry, and adds it to the indicated flt_node.
156  */
157 void EggToFlt::
158 convert_primitive(EggPrimitive *egg_primitive, FltBead *flt_node,
159  FltGeometry::BillboardType billboard) {
160  FltFace *flt_face = new FltFace(_flt_header);
161  flt_node->add_child(flt_face);
162 
163  flt_face->_billboard_type = billboard;
164 
165  if (egg_primitive->has_color()) {
166  flt_face->set_color(egg_primitive->get_color());
167  }
168 
169  if (egg_primitive->is_of_type(EggPoint::get_class_type())) {
170  // A series of points, instead of a polygon.
171  flt_face->_draw_type = FltFace::DT_omni_light;
172 
173  } else if (egg_primitive->get_bface_flag()) {
174  // A polygon whose backface is visible.
175  flt_face->_draw_type = FltFace::DT_solid_no_cull;
176 
177  } else {
178  // A normal polygon.
179  flt_face->_draw_type = FltFace::DT_solid_cull_backface;
180  }
181 
182  if (egg_primitive->has_texture()) {
183  EggTexture *egg_texture = egg_primitive->get_texture();
184  FltTexture *flt_texture = get_flt_texture(egg_texture);
185  flt_face->set_texture(flt_texture);
186  }
187 
188  // Create a vertex list representing the vertices in the primitive, and add
189  // it as a child of the face bead. This is how Flt files associate vertices
190  // with faces.
191  FltVertexList *flt_vertices = new FltVertexList(_flt_header);
192  flt_face->add_child(flt_vertices);
193 
194  EggPrimitive::iterator vi;
195  bool all_verts_have_color = true;
196  bool all_verts_have_normal = true;
197  for (vi = egg_primitive->begin(); vi != egg_primitive->end(); ++vi) {
198  EggVertex *egg_vertex = (*vi);
199  FltVertex *flt_vertex = get_flt_vertex(egg_vertex, egg_primitive);
200  flt_vertices->add_vertex(flt_vertex);
201 
202  if (!egg_vertex->has_color()) {
203  all_verts_have_color = false;
204  }
205  if (!egg_vertex->has_normal()) {
206  all_verts_have_normal = false;
207  }
208  }
209  if (all_verts_have_color) {
210  // If all the vertices of the face have a color specification, then we
211  // specify per-vertex color on the face.
212  if (all_verts_have_normal) {
213  // And similarly with the normals.
214  flt_face->_light_mode = FltFace::LM_vertex_with_normal;
215  } else {
216  flt_face->_light_mode = FltFace::LM_vertex_no_normal;
217  }
218  } else {
219  if (all_verts_have_normal) {
220  flt_face->_light_mode = FltFace::LM_face_with_normal;
221  } else {
222  flt_face->_light_mode = FltFace::LM_face_no_normal;
223  }
224  }
225 }
226 
227 /**
228  * Converts an egg group to the corresponding flt group, and adds it to the
229  * indicated parent node. Also recurses on the children of the egg group.
230  */
231 void EggToFlt::
232 convert_group(EggGroup *egg_group, FltBead *flt_node,
233  FltGeometry::BillboardType billboard) {
234  std::ostringstream egg_syntax;
235 
236  FltGroup *flt_group = new FltGroup(_flt_header);
237  flt_node->add_child(flt_group);
238 
239  flt_group->set_id(egg_group->get_name());
240 
241  switch (egg_group->get_billboard_type()) {
242  // MultiGen represents billboarding at the polygon level, so we have to
243  // remember this flag for later.
244  case EggGroup::BT_axis:
245  billboard = FltGeometry::BT_axial;
246  break;
247 
248  case EggGroup::BT_point_world_relative:
249  billboard = FltGeometry::BT_point;
250  break;
251 
252  case EggGroup::BT_point_camera_relative:
253  // Not sure if this is the right flag for MultiGen.
254  billboard = FltGeometry::BT_fixed;
255  break;
256 
257  default:
258  break;
259  }
260 
261  if (egg_group->has_transform()) {
262  apply_transform(egg_group, flt_group);
263  }
264 
265  if (egg_group->get_switch_flag()) {
266  if (egg_group->get_switch_fps() != 0.0) {
267  // A sequence animation.
268  flt_group->_flags |= FltGroup::F_forward_animation;
269  egg_syntax
270  << " <Scalar> fps { " << egg_group->get_switch_fps() << " }\n";
271  } else {
272  // Just a switch node.
273  egg_group->write_switch_flags(egg_syntax, 2);
274  }
275  }
276 
277  // Pick up any additional egg attributes that MultiGen doesn't support;
278  // these will get written to the comment field where flt2egg will find it.
279  egg_group->write_collide_flags(egg_syntax, 2);
280  egg_group->write_model_flags(egg_syntax, 2);
281  egg_group->write_object_types(egg_syntax, 2);
282  egg_group->write_decal_flags(egg_syntax, 2);
283  egg_group->write_tags(egg_syntax, 2);
284  egg_group->write_render_mode(egg_syntax, 2);
285 
286  apply_egg_syntax(egg_syntax.str(), flt_group);
287 
288  EggGroup::iterator ci;
289  for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
290  traverse(*ci, flt_group, billboard);
291  }
292 }
293 
294 /**
295  * Applies the indicated egg transform to the indicated flt bead.
296  */
297 void EggToFlt::
298 apply_transform(EggTransform *egg_transform, FltBead *flt_node) {
299  flt_node->clear_transform();
300 
301  bool components_ok = true;
302  int num_components = egg_transform->get_num_components();
303  for (int i = num_components - 1; i >= 0 && components_ok; i--) {
304  switch (egg_transform->get_component_type(i)) {
305  case EggTransform::CT_translate2d:
306  {
307  FltTransformTranslate *translate =
308  new FltTransformTranslate(_flt_header);
309  LVector2d v2 = egg_transform->get_component_vec2(i);
310  translate->set(LPoint3d::zero(), LVector3d(v2[0], v2[1], 0.0));
311  flt_node->add_transform_step(translate);
312  }
313  break;
314 
315  case EggTransform::CT_translate3d:
316  {
317  FltTransformTranslate *translate =
318  new FltTransformTranslate(_flt_header);
319  translate->set(LPoint3d::zero(), egg_transform->get_component_vec3(i));
320  flt_node->add_transform_step(translate);
321  }
322  break;
323 
324  case EggTransform::CT_rotate2d:
325  {
327  new FltTransformRotateAboutEdge(_flt_header);
328  rotate->set(LPoint3d::zero(), LPoint3d(0.0, 0.0, 1.0),
329  egg_transform->get_component_number(i));
330  flt_node->add_transform_step(rotate);
331  }
332  break;
333 
334  case EggTransform::CT_rotx:
335  {
337  new FltTransformRotateAboutEdge(_flt_header);
338  rotate->set(LPoint3d::zero(), LPoint3d(1.0, 0.0, 0.0),
339  egg_transform->get_component_number(i));
340  flt_node->add_transform_step(rotate);
341  }
342  break;
343 
344  case EggTransform::CT_roty:
345  {
347  new FltTransformRotateAboutEdge(_flt_header);
348  rotate->set(LPoint3d::zero(), LPoint3d(0.0, 1.0, 0.0),
349  egg_transform->get_component_number(i));
350  flt_node->add_transform_step(rotate);
351  }
352  break;
353 
354  case EggTransform::CT_rotz:
355  {
357  new FltTransformRotateAboutEdge(_flt_header);
358  rotate->set(LPoint3d::zero(), LPoint3d(0.0, 0.0, 1.0),
359  egg_transform->get_component_number(i));
360  flt_node->add_transform_step(rotate);
361  }
362  break;
363 
364  case EggTransform::CT_rotate3d:
365  {
367  new FltTransformRotateAboutEdge(_flt_header);
368  rotate->set(LPoint3d::zero(), egg_transform->get_component_vec3(i),
369  egg_transform->get_component_number(i));
370  flt_node->add_transform_step(rotate);
371  }
372  break;
373 
374  case EggTransform::CT_scale2d:
375  {
376  FltTransformScale *scale = new FltTransformScale(_flt_header);
377  LVector2d v2 = egg_transform->get_component_vec2(i);
378  scale->set(LPoint3d::zero(), LVector3(v2[0], v2[1], 1.0f));
379  flt_node->add_transform_step(scale);
380  }
381  break;
382 
383  case EggTransform::CT_scale3d:
384  {
385  FltTransformScale *scale = new FltTransformScale(_flt_header);
386  scale->set(LPoint3d::zero(), LCAST(PN_stdfloat, egg_transform->get_component_vec3(i)));
387  flt_node->add_transform_step(scale);
388  }
389  break;
390 
391  case EggTransform::CT_uniform_scale:
392  {
393  FltTransformScale *scale = new FltTransformScale(_flt_header);
394  PN_stdfloat factor = (PN_stdfloat)egg_transform->get_component_number(i);
395  scale->set(LPoint3d::zero(), LVecBase3(factor, factor, factor));
396  flt_node->add_transform_step(scale);
397  }
398  break;
399 
400  case EggTransform::CT_matrix3:
401  {
402  FltTransformGeneralMatrix *matrix =
403  new FltTransformGeneralMatrix(_flt_header);
404  const LMatrix3d &m = egg_transform->get_component_mat3(i);
405  LMatrix4d mat4(m(0, 0), m(0, 1), 0.0, m(0, 2),
406  m(1, 0), m(1, 1), 0.0, m(1, 2),
407  0.0, 0.0, 1.0, 0.0,
408  m(2, 0), m(2, 1), 0.0, m(2, 2));
409  matrix->set_matrix(mat4);
410  flt_node->add_transform_step(matrix);
411  }
412  break;
413 
414  case EggTransform::CT_matrix4:
415  {
416  FltTransformGeneralMatrix *matrix =
417  new FltTransformGeneralMatrix(_flt_header);
418  matrix->set_matrix(egg_transform->get_component_mat4(i));
419  flt_node->add_transform_step(matrix);
420  }
421  break;
422 
423  default:
424  // Don't know how to convert this component.
425  components_ok = false;
426  }
427  }
428 
429  if (components_ok) {
430  // Verify that the transform was computed correctly.
431  if (!flt_node->get_transform().almost_equal(egg_transform->get_transform3d())) {
432  nout << "Incorrect transform! Expected:\n";
433  egg_transform->get_transform3d().write(nout, 2);
434  nout << "Computed:\n";
435  flt_node->get_transform().write(nout, 2);
436  nout << "\n";
437  components_ok = false;
438  }
439  }
440 
441  if (!components_ok) {
442  // Just store the overall transform.
443  flt_node->set_transform(egg_transform->get_transform3d());
444  }
445 }
446 
447 /**
448  * Adds the indicated sequence of egg syntax lines (presumably representing
449  * egg features not directly supported by MultiGen) to the flt record as a
450  * comment, so that flt2egg will reapply it to the egg groups.
451  */
452 void EggToFlt::
453 apply_egg_syntax(const std::string &egg_syntax, FltRecord *flt_record) {
454  if (!egg_syntax.empty()) {
455  std::ostringstream out;
456  out << "<egg> {\n"
457  << egg_syntax
458  << "}";
459  flt_record->set_comment(out.str());
460  }
461 }
462 
463 /**
464  * Returns a FltVertex corresponding to the indicated EggVertex. If the
465  * vertex has not been seen before (in this particular vertex frame), creates
466  * a new one.
467  */
468 FltVertex *EggToFlt::
469 get_flt_vertex(EggVertex *egg_vertex, EggNode *context) {
470  const LMatrix4d *frame = context->get_vertex_to_node_ptr();
471  VertexMap &vertex_map = _vertex_map_per_frame[frame];
472 
473  VertexMap::iterator vi = vertex_map.find(egg_vertex);
474  if (vi != vertex_map.end()) {
475  return (*vi).second;
476  }
477  FltVertex *flt_vertex = new FltVertex(_flt_header);
478  flt_vertex->_pos = egg_vertex->get_pos3();
479 
480  if (egg_vertex->has_color()) {
481  flt_vertex->set_color(egg_vertex->get_color());
482  }
483  if (egg_vertex->has_normal()) {
484  flt_vertex->_normal = LCAST(PN_stdfloat, egg_vertex->get_normal());
485  flt_vertex->_has_normal = true;
486  }
487  if (egg_vertex->has_uv()) {
488  flt_vertex->_uv = LCAST(PN_stdfloat, egg_vertex->get_uv());
489  flt_vertex->_has_uv = true;
490  }
491 
492  if (frame != nullptr) {
493  flt_vertex->_pos = flt_vertex->_pos * (*frame);
494  flt_vertex->_normal = flt_vertex->_normal * LCAST(PN_stdfloat, (*frame));
495  }
496 
497  _flt_header->add_vertex(flt_vertex);
498  vertex_map[egg_vertex] = flt_vertex;
499 
500  return flt_vertex;
501 }
502 
503 /**
504  * Returns a FltTexture corresponding to the indicated EggTexture. If the
505  * texture has not been seen before, creates a new one.
506  */
507 FltTexture *EggToFlt::
508 get_flt_texture(EggTexture *egg_texture) {
509  // We have to maintain this map based on the filename, not the egg pointer,
510  // because there may be multiple EggTextures with the same filename, and we
511  // have to collapse them together.
512  Filename filename = egg_texture->get_filename();
513  TextureMap::iterator vi = _texture_map.find(filename);
514  if (vi != _texture_map.end()) {
515  return (*vi).second;
516  }
517  FltTexture *flt_texture = new FltTexture(_flt_header);
518  flt_texture->set_texture_filename(filename);
519 
520  switch (egg_texture->get_minfilter()) {
521  case EggTexture::FT_nearest:
522  flt_texture->_min_filter = FltTexture::MN_point;
523  break;
524 
525  case EggTexture::FT_linear:
526  flt_texture->_min_filter = FltTexture::MN_bilinear;
527  break;
528 
529  case EggTexture::FT_nearest_mipmap_nearest:
530  flt_texture->_min_filter = FltTexture::MN_mipmap_point;
531  break;
532 
533  case EggTexture::FT_nearest_mipmap_linear:
534  flt_texture->_min_filter = FltTexture::MN_mipmap_linear;
535  break;
536 
537  case EggTexture::FT_linear_mipmap_nearest:
538  flt_texture->_min_filter = FltTexture::MN_mipmap_bilinear;
539  break;
540 
541  case EggTexture::FT_linear_mipmap_linear:
542  flt_texture->_min_filter = FltTexture::MN_mipmap_trilinear;
543  break;
544 
545  default:
546  break;
547  }
548 
549  switch (egg_texture->get_magfilter()) {
550  case EggTexture::FT_nearest:
551  flt_texture->_mag_filter = FltTexture::MG_point;
552  break;
553 
554  case EggTexture::FT_linear:
555  flt_texture->_mag_filter = FltTexture::MG_bilinear;
556  break;
557 
558  default:
559  break;
560  }
561 
562  switch (egg_texture->get_wrap_mode()) {
563  case EggTexture::WM_repeat:
564  flt_texture->_repeat = FltTexture::RT_repeat;
565  break;
566 
567  case EggTexture::WM_clamp:
568  flt_texture->_repeat = FltTexture::RT_clamp;
569  break;
570 
571  default:
572  break;
573  }
574 
575  switch (egg_texture->get_wrap_u()) {
576  case EggTexture::WM_repeat:
577  flt_texture->_repeat_u = FltTexture::RT_repeat;
578  break;
579 
580  case EggTexture::WM_clamp:
581  flt_texture->_repeat_u = FltTexture::RT_clamp;
582  break;
583 
584  default:
585  break;
586  }
587 
588  switch (egg_texture->get_wrap_v()) {
589  case EggTexture::WM_repeat:
590  flt_texture->_repeat_v = FltTexture::RT_repeat;
591  break;
592 
593  case EggTexture::WM_clamp:
594  flt_texture->_repeat_v = FltTexture::RT_clamp;
595  break;
596 
597  default:
598  break;
599  }
600 
601  switch (egg_texture->get_env_type()) {
602  case EggTexture::ET_modulate:
603  flt_texture->_env_type = FltTexture::ET_modulate;
604  break;
605 
606  case EggTexture::ET_decal:
607  flt_texture->_env_type = FltTexture::ET_decal;
608  break;
609 
610  default:
611  break;
612  }
613 
614  switch (egg_texture->get_format()) {
615  case EggTexture::F_luminance_alpha:
616  case EggTexture::F_luminance_alphamask:
617  flt_texture->_internal_format = FltTexture::IF_ia_8;
618  break;
619 
620  case EggTexture::F_rgb5:
621  case EggTexture::F_rgb332:
622  flt_texture->_internal_format = FltTexture::IF_rgb_5;
623  break;
624 
625  case EggTexture::F_rgba4:
626  case EggTexture::F_rgba5:
627  flt_texture->_internal_format = FltTexture::IF_rgba_4;
628  break;
629 
630  case EggTexture::F_rgba8:
631  case EggTexture::F_rgba:
632  case EggTexture::F_rgbm:
633  case EggTexture::F_rgb:
634  case EggTexture::F_rgb8:
635  flt_texture->_internal_format = FltTexture::IF_rgba_8;
636  break;
637 
638  case EggTexture::F_rgba12:
639  flt_texture->_internal_format = FltTexture::IF_rgba_12;
640  break;
641 
642  case EggTexture::F_alpha:
643  flt_texture->_internal_format = FltTexture::IF_i_16;
644  flt_texture->_intensity_is_alpha = true;
645  break;
646 
647  case EggTexture::F_luminance:
648  flt_texture->_internal_format = FltTexture::IF_i_16;
649  break;
650 
651  case EggTexture::F_rgb12:
652  flt_texture->_internal_format = FltTexture::IF_rgb_12;
653  break;
654 
655  default:
656  break;
657  }
658 
659  _flt_header->add_texture(flt_texture);
660  _texture_map[filename] = flt_texture;
661 
662  return flt_texture;
663 }
664 
665 
666 
667 int main(int argc, char *argv[]) {
668  EggToFlt prog;
669  prog.parse_command_line(argc, argv);
670  prog.run();
671  return 0;
672 }
LColor get_color() const
Returns the color set on this particular attribute.
Definition: eggAttributes.I:91
const Filename & get_filename() const
Returns a nonmodifiable reference to the filename.
A base class for nodes in the hierarchy that are not leaf nodes.
Definition: eggGroupNode.h:46
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition: eggGroup.h:34
void write_switch_flags(std::ostream &out, int indent_level) const
Writes the <Switch> flag and related flags to the indicated ostream.
Definition: eggGroup.cxx:399
void write_object_types(std::ostream &out, int indent_level) const
Writes just the <ObjectTypes> entries, if any, to the indicated ostream.
Definition: eggGroup.cxx:413
void write_tags(std::ostream &out, int indent_level) const
Writes just the <Tag> entries, if any, to the indicated ostream.
Definition: eggGroup.cxx:436
void write_render_mode(std::ostream &out, int indent_level) const
Writes the flags inherited from EggRenderMode and similar flags that control obscure render effects.
Definition: eggGroup.cxx:454
void write_model_flags(std::ostream &out, int indent_level) const
Writes the <Model> flag and related flags to the indicated ostream.
Definition: eggGroup.cxx:371
void write_collide_flags(std::ostream &out, int indent_level) const
Writes just the <Collide> entry and related fields to the indicated ostream.
Definition: eggGroup.cxx:332
void write_decal_flags(std::ostream &out, int indent_level) const
Writes the flags related to decaling, if any.
Definition: eggGroup.cxx:426
A base class for things that may be directly added into the egg hierarchy.
Definition: eggNode.h:36
const LMatrix4d * get_vertex_to_node_ptr() const
Returns either a NULL pointer or a unique pointer shared by nodes with the same get_vertex_to_node() ...
Definition: eggNode.I:234
A base class for any of a number of kinds of geometry primitives: polygons, point lights,...
Definition: eggPrimitive.h:49
bool has_texture() const
Returns true if the primitive has any textures specified, false otherwise.
Definition: eggPrimitive.I:128
get_bface_flag
Retrieves the backfacing flag of the polygon.
Definition: eggPrimitive.h:116
get_texture
Returns the first texture on the primitive, if any, or NULL if there are no textures on the primitive...
Definition: eggPrimitive.h:100
Defines a texture map that may be applied to geometry.
Definition: eggTexture.h:30
get_wrap_u
Returns the amount specified for U wrap.
Definition: eggTexture.h:321
get_wrap_v
Returns the amount specified for V wrap.
Definition: eggTexture.h:322
A program to read an egg file and write a flt file.
Definition: eggToFlt.h:38
This is the general base class for a file-converter program that reads some model file format and gen...
This represents the <Transform> entry of a group or texture node: a list of component transform opera...
Definition: eggTransform.h:29
const LMatrix4d & get_transform3d() const
Returns the overall transform as a 4x4 matrix.
Definition: eggTransform.I:212
bool has_transform() const
Returns true if the transform is nonempty, false if it is empty (no transform components have been ad...
Definition: eggTransform.I:143
const LVecBase3d & get_component_vec3(int n) const
Returns the 3-component vector associated with the nth component.
Definition: eggTransform.I:272
ComponentType get_component_type(int n) const
Returns the type of the nth component.
Definition: eggTransform.I:237
const LVecBase2d & get_component_vec2(int n) const
Returns the 2-component vector associated with the nth component.
Definition: eggTransform.I:260
int get_num_components() const
Returns the number of components that make up the transform.
Definition: eggTransform.I:229
const LMatrix3d & get_component_mat3(int n) const
Returns the 3x3 matrix associated with the nth component.
Definition: eggTransform.I:283
const LMatrix4d & get_component_mat4(int n) const
Returns the 4x4 matrix associated with the nth component.
Definition: eggTransform.I:294
double get_component_number(int n) const
Returns the solitary number associated with the nth component.
Definition: eggTransform.I:249
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
Definition: eggVertex.h:39
bool has_uv() const
Returns true if the vertex has an unnamed UV coordinate pair, false otherwise.
Definition: eggVertex.I:158
LTexCoordd get_uv() const
Returns the unnamed UV coordinate pair on the vertex.
Definition: eggVertex.I:179
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
Definition: eggVertex.I:131
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
void set_id(const std::string &id)
Changes the id (name) of this particular bead.
Definition: fltBeadID.cxx:41
A base class for any of a broad family of flt records that represent particular beads in the hierarch...
Definition: fltBead.h:29
void clear_transform()
Removes any transform matrix and all transform steps on this bead.
Definition: fltBead.cxx:79
void add_transform_step(FltTransformRecord *record)
Applies the indicated transform step to the net transformation applied to the bead.
Definition: fltBead.cxx:123
const LMatrix4d & get_transform() const
Returns the single-precision 4x4 matrix that represents the transform applied to this bead,...
Definition: fltBead.cxx:58
void set_transform(const LMatrix4d &mat)
Replaces the transform matrix on this bead.
Definition: fltBead.cxx:68
A single face bead, e.g.
Definition: fltFace.h:24
void set_color(const LColor &color)
Sets the primary color of the face, using the packed color convention.
Definition: fltGeometry.cxx:91
void set_texture(FltTexture *texture)
Applies the indicated texture to this face, or if the texture is NULL, clears it.
Definition: fltGeometry.I:36
The main grouping bead of the flt file.
Definition: fltGroup.h:24
This is the first bead in the file, the top of the bead hierarchy, and the primary interface to readi...
Definition: fltHeader.h:44
The base class for all kinds of records in a MultiGen OpenFlight file.
Definition: fltRecord.h:36
void add_child(FltRecord *child)
Adds a new child to the end of the list of children for this record.
Definition: fltRecord.cxx:88
void set_comment(const std::string &comment)
Changes the comment for this record.
Definition: fltRecord.cxx:240
Represents a single texture in the texture palette.
Definition: fltTexture.h:27
void set_texture_filename(const Filename &filename)
Changes the name of the texture image file.
Definition: fltTexture.cxx:109
void set_matrix(const LMatrix4d &matrix)
Directly sets the general matrix.
A transformation that rotates about a particular axis in space, defined by two endpoints.
void set(const LPoint3d &point_a, const LPoint3d &point_b, PN_stdfloat angle)
Defines the rotation.
A transformation that applies a (possibly nonuniform) scale.
A transformation that applies a translation.
void set(const LPoint3d &from, const LVector3d &delta)
Defines the translation.
A list of vertices, typically added as a child of a face bead.
Definition: fltVertexList.h:28
void add_vertex(FltVertex *vertex)
Adds a new vertex to the end of the vertex list.
Represents a single vertex in the vertex palette.
Definition: fltVertex.h:32
void set_color(const LColor &color)
Sets the color of the vertex, using the packed color convention.
Definition: fltVertex.I:30
virtual void parse_command_line(int argc, char **argv)
Dispatches on each of the options on the command line, and passes the remaining parameters to handle_...
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
Filename get_output_filename() const
If has_output_filename() returns true, this is the filename that the user specified.
std::ostream & get_output()
Returns an output stream that corresponds to the user's intended egg file output–either stdout,...
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.
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.
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.