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