Panda3D
 All Classes Functions Variables Enumerations
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.
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
LTexCoordd get_uv() const
Returns the unnamed UV coordinate pair on the vertex.
Definition: eggVertex.I:222
const LMatrix4d & get_transform3d() const
Returns the overall transform as a 4x4 matrix.
Definition: eggTransform.I:251
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:4716
LColor get_color() const
Returns the color set on this particular attribute.
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
bool get_bface_flag() const
Retrieves the backfacing flag of the polygon.
Definition: eggPrimitive.I:301
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_...
This is a two-component vector offset.
Definition: lvector2.h:416
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
bool has_uv() const
Returns true if the vertex has an unnamed UV coordinate pair, false otherwise.
Definition: eggVertex.I:194
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
const LMatrix3d & get_component_mat3(int n) const
Returns the 3x3 matrix associated with the nth component.
Definition: eggTransform.I:344
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.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:63
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
Definition: eggVertex.I:160
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.
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
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 add_child(FltRecord *child)
Adds a new child to the end of the list of children for this record.
Definition: fltRecord.cxx:102
void write_tags(ostream &out, int indent_level) const
Writes just the &lt;Tag&gt; entries, if any, to the indicated ostream.
Definition: eggGroup.cxx:470
void set_id(const string &id)
Changes the id (name) of this particular bead.
Definition: fltBeadID.cxx:48
Filename get_output_filename() const
If has_output_filename() returns true, this is the filename that the user specified.
This is the first bead in the file, the top of the bead hierarchy, and the primary interface to readi...
Definition: fltHeader.h:48
void add_vertex(FltVertex *vertex)
Adds a new vertex to the end of the vertex list.
void write_collide_flags(ostream &out, int indent_level) const
Writes just the &lt;Collide&gt; entry and related fields to the indicated ostream.
Definition: eggGroup.cxx:352
The main glue of the egg hierarchy, this corresponds to the &lt;Group&gt;, &lt;Instance&gt;, and &lt;Joint&gt; type nod...
Definition: eggGroup.h:36
void write_model_flags(ostream &out, int indent_level) const
Writes the &lt;Model&gt; flag and related flags to the indicated ostream.
Definition: eggGroup.cxx:394
WrapMode get_wrap_v() const
Returns the amount specified for V wrap.
Definition: eggTexture.I:153
This is a 3-by-3 transform matrix.
Definition: lmatrix.h:4375
WrapMode get_wrap_u() const
Returns the amount specified for U wrap.
Definition: eggTexture.I:119
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
const LMatrix4d & get_component_mat4(int n) const
Returns the 4x4 matrix associated with the nth component.
Definition: eggTransform.I:358
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
The base class for all kinds of records in a MultiGen OpenFlight file.
Definition: fltRecord.h:40
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
Represents a single vertex in the vertex palette.
Definition: fltVertex.h:35
static const LPoint3d & zero()
Returns a zero-length point.
Definition: lpoint3.h:690
const Filename & get_filename() const
Returns a nonmodifiable reference to the filename.
int get_num_components() const
Returns the number of components that make up the transform.
Definition: eggTransform.I:274
void clear_transform()
Removes any transform matrix and all transform steps on this bead.
Definition: fltBead.cxx:93
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
void write_switch_flags(ostream &out, int indent_level) const
Writes the &lt;Switch&gt; flag and related flags to the indicated ostream.
Definition: eggGroup.cxx:425
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
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:746
ostream & get_output()
Returns an output stream that corresponds to the user&#39;s intended egg file output–either stdout...
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:531
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
void write_object_types(ostream &out, int indent_level) const
Writes just the &lt;ObjectTypes&gt; entries, if any, to the indicated ostream.
Definition: eggGroup.cxx:442
ComponentType get_component_type(int n) const
Returns the type of the nth component.
Definition: eggTransform.I:284
A transformation that rotates about a particular axis in space, defined by two endpoints.
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
void write_decal_flags(ostream &out, int indent_level) const
Writes the flags related to decaling, if any.
Definition: eggGroup.cxx:457
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 LVecBase2d & get_component_vec2(int n) const
Returns the 2-component vector associated with the nth component.
Definition: eggTransform.I:314
bool has_texture() const
Returns true if the primitive has any textures specified, false otherwise.
Definition: eggPrimitive.I:155
This represents the &lt;Transform&gt; entry of a group or texture node: a list of component transform opera...
Definition: eggTransform.h:33