Panda3D
fltToEggConverter.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 fltToEggConverter.cxx
10  * @author drose
11  * @date 2001-04-17
12  */
13 
14 #include "fltToEggConverter.h"
15 
16 #include "fltRecord.h"
17 #include "fltLOD.h"
18 #include "fltGroup.h"
19 #include "fltObject.h"
20 #include "fltBeadID.h"
21 #include "fltBead.h"
22 #include "fltFace.h"
23 #include "fltVertex.h"
24 #include "fltVertexList.h"
25 #include "fltExternalReference.h"
26 #include "dcast.h"
27 #include "eggData.h"
28 #include "eggGroup.h"
29 #include "eggSwitchCondition.h"
30 #include "eggPrimitive.h"
31 #include "eggPolygon.h"
32 #include "eggPoint.h"
33 #include "eggVertex.h"
34 #include "eggVertexPool.h"
35 #include "eggExternalReference.h"
36 #include "string_utils.h"
37 
38 using std::string;
39 
40 
41 /**
42  *
43  */
44 FltToEggConverter::
45 FltToEggConverter() {
46  _compose_transforms = false;
47  _flt_units = DU_invalid;
48 }
49 
50 /**
51  *
52  */
53 FltToEggConverter::
54 FltToEggConverter(const FltToEggConverter &copy) :
56  _compose_transforms(copy._compose_transforms)
57 {
58 }
59 
60 /**
61  *
62  */
63 FltToEggConverter::
64 ~FltToEggConverter() {
65  cleanup();
66 }
67 
68 /**
69  * Allocates and returns a new copy of the converter.
70  */
73  return new FltToEggConverter(*this);
74 }
75 
76 
77 /**
78  * Returns the English name of the file type this converter supports.
79  */
81 get_name() const {
82  return "MultiGen";
83 }
84 
85 /**
86  * Returns the common extension of the file type this converter supports.
87  */
89 get_extension() const {
90  return "flt";
91 }
92 
93 /**
94  * Returns true if this file type can transparently load compressed files
95  * (with a .pz extension), false otherwise.
96  */
99  return true;
100 }
101 
102 /**
103  * Handles the reading of the input file and converting it to egg. Returns
104  * true if successful, false otherwise.
105  *
106  * This is designed to be as generic as possible, generally in support of run-
107  * time loading. Command-line converters may choose to use convert_flt()
108  * instead, as it provides more control.
109  */
111 convert_file(const Filename &filename) {
112  PT(FltHeader) header = new FltHeader(_path_replace);
113 
114  nout << "Reading " << filename << "\n";
115  FltError result = header->read_flt(filename);
116  if (result != FE_ok) {
117  nout << "Unable to read: " << result << "\n";
118  return false;
119  }
120 
121  header->check_version();
122 
123  _flt_units = header->get_units();
124 
125  return convert_flt(header);
126 }
127 
128 /**
129  * This may be called after convert_file() has been called and returned true,
130  * indicating a successful conversion. It will return the distance units
131  * represented by the converted egg file, if known, or DU_invalid if not
132  * known.
133  */
136  return _flt_units;
137 }
138 
139 /**
140  * Fills up the egg_data structure according to the indicated lwo structure.
141  */
143 convert_flt(const FltHeader *flt_header) {
144  if (_egg_data->get_coordinate_system() == CS_default) {
145  _egg_data->set_coordinate_system(CS_zup_right);
146  }
147 
148  clear_error();
149  _flt_header = flt_header;
150 
151  // Generate a default vertex pool.
152  _main_egg_vpool = new EggVertexPool("vpool");
153  _egg_data->add_child(_main_egg_vpool.p());
154 
155  // We could populate the vertex pool right away, but it's better to defer
156  // each vertex until we encounter it, since some of the vertices may need to
157  // be adjusted to match the particular polygon they're assigned to (for
158  // instance, to apply a transparency or something).
159 
160  FltToEggLevelState state(this);
161  state._egg_parent = _egg_data;
162  convert_record(_flt_header, state);
163 
164  if (_main_egg_vpool->empty()) {
165  // If we didn't get any global vertices, remove the vertex pool just for
166  // cleanliness.
167  _egg_data->remove_child(_main_egg_vpool.p());
168  }
169 
170  cleanup();
171 
172  return !had_error();
173 }
174 
175 /**
176  * Frees all the internal data structures after we're done converting, and
177  * resets the converter to its initial state.
178  */
179 void FltToEggConverter::
180 cleanup() {
181  _flt_header.clear();
182  _main_egg_vpool.clear();
183  _textures.clear();
184 }
185 
186 /**
187  * Converts the record and all of its children.
188  */
189 void FltToEggConverter::
190 convert_record(const FltRecord *flt_record, FltToEggLevelState &state) {
191  int num_children = flt_record->get_num_children();
192 
193  for (int i = 0; i < num_children; i++) {
194  const FltRecord *child = flt_record->get_child(i);
195  dispatch_record(child, state);
196  }
197 }
198 
199 /**
200  * Determines what kind of record this is and calls the appropriate convert
201  * function.
202  */
203 void FltToEggConverter::
204 dispatch_record(const FltRecord *flt_record, FltToEggLevelState &state) {
205  if (flt_record->is_of_type(FltLOD::get_class_type())) {
206  convert_lod(DCAST(FltLOD, flt_record), state);
207 
208  } else if (flt_record->is_of_type(FltGroup::get_class_type())) {
209  convert_group(DCAST(FltGroup, flt_record), state);
210 
211  } else if (flt_record->is_of_type(FltObject::get_class_type())) {
212  convert_object(DCAST(FltObject, flt_record), state);
213 
214  } else if (flt_record->is_of_type(FltFace::get_class_type())) {
215  convert_face(DCAST(FltFace, flt_record), state);
216 
217  } else if (flt_record->is_of_type(FltExternalReference::get_class_type())) {
218  convert_ext_ref(DCAST(FltExternalReference, flt_record), state);
219 
220  // Fallbacks.
221  } else if (flt_record->is_of_type(FltBeadID::get_class_type())) {
222  convert_bead_id(DCAST(FltBeadID, flt_record), state);
223 
224  } else if (flt_record->is_of_type(FltBead::get_class_type())) {
225  convert_bead(DCAST(FltBead, flt_record), state);
226 
227  } else {
228  convert_record(flt_record, state);
229  }
230 }
231 
232 /**
233  * Converts the LOD bead and all of its children.
234  */
235 void FltToEggConverter::
236 convert_lod(const FltLOD *flt_lod, FltToEggLevelState &state) {
237  EggGroup *egg_group = new EggGroup(flt_lod->get_id());
238  state._egg_parent->add_child(egg_group);
239 
241  (flt_lod->_switch_in, flt_lod->_switch_out,
242  LPoint3d(flt_lod->_center_x, flt_lod->_center_y, flt_lod->_center_z),
243  flt_lod->_transition_range);
244  egg_group->set_lod(lod);
245 
246  state.set_transform(flt_lod, egg_group);
247  parse_comment(flt_lod, egg_group);
248 
249  FltToEggLevelState next_state(state);
250  next_state._egg_parent = egg_group;
251  convert_record(flt_lod, next_state);
252 }
253 
254 /**
255  * Converts the group and all of its children.
256  */
257 void FltToEggConverter::
258 convert_group(const FltGroup *flt_group, FltToEggLevelState &state) {
259  EggGroup *egg_group = new EggGroup(flt_group->get_id());
260  state._egg_parent->add_child(egg_group);
261 
262  if ((flt_group->_flags & FltGroup::F_forward_animation) != 0) {
263  // It's a sequence animation.
264  egg_group->set_switch_flag(true);
265  egg_group->set_switch_fps(24.0);
266  }
267 
268  state.set_transform(flt_group, egg_group);
269  parse_comment(flt_group, egg_group);
270 
271  // *** replicate count.
272 
273  FltToEggLevelState next_state(state);
274  next_state._egg_parent = egg_group;
275  convert_record(flt_group, next_state);
276 }
277 
278 /**
279  * Converts the object and all of its children.
280  */
281 void FltToEggConverter::
282 convert_object(const FltObject *flt_object, FltToEggLevelState &state) {
283  EggGroup *egg_group = new EggGroup(flt_object->get_id());
284  state._egg_parent->add_child(egg_group);
285 
286  state.set_transform(flt_object, egg_group);
287  parse_comment(flt_object, egg_group);
288 
289  FltToEggLevelState next_state(state);
290  next_state._flt_object = flt_object;
291  next_state._egg_parent = egg_group;
292  convert_record(flt_object, next_state);
293 }
294 
295 /**
296  * Converts the generic bead (with ID) and all of its children.
297  */
298 void FltToEggConverter::
299 convert_bead_id(const FltBeadID *flt_bead, FltToEggLevelState &state) {
300  nout << "Don't know how to convert beads of type " << flt_bead->get_type()
301  << "\n";
302  EggGroup *egg_group = new EggGroup(flt_bead->get_id());
303  state._egg_parent->add_child(egg_group);
304 
305  state.set_transform(flt_bead, egg_group);
306  parse_comment(flt_bead, egg_group);
307 
308  FltToEggLevelState next_state(state);
309  next_state._egg_parent = egg_group;
310  convert_record(flt_bead, next_state);
311 }
312 
313 /**
314  * Converts the generic bead (without ID) and all of its children.
315  */
316 void FltToEggConverter::
317 convert_bead(const FltBead *flt_bead, FltToEggLevelState &state) {
318  nout << "Don't know how to convert beads of type " << flt_bead->get_type()
319  << "\n";
320  EggGroup *egg_group = new EggGroup;
321  state._egg_parent->add_child(egg_group);
322 
323  state.set_transform(flt_bead, egg_group);
324  parse_comment(flt_bead, egg_group);
325 
326  FltToEggLevelState next_state(state);
327  next_state._egg_parent = egg_group;
328  convert_record(flt_bead, next_state);
329 }
330 
331 /**
332  * Converts the face and all of its children.
333  */
334 void FltToEggConverter::
335 convert_face(const FltFace *flt_face, FltToEggLevelState &state) {
336  bool is_light;
337  switch (flt_face->_draw_type) {
338  case FltGeometry::DT_omni_light:
339  case FltGeometry::DT_uni_light:
340  case FltGeometry::DT_bi_light:
341  is_light = true;
342  break;
343 
344  default:
345  is_light = false;
346  }
347 
348  PT(EggPrimitive) egg_prim;
349  if (is_light) {
350  egg_prim = new EggPoint;
351  } else {
352  egg_prim = new EggPolygon;
353  }
354 
355  // Collect the vertices for this primitive.
356  pvector< PT_EggVertex > vertices;
357 
358  const FltVertexList *vlist = nullptr;
359  int num_children = flt_face->get_num_children();
360  for (int i = 0; i < num_children && vlist == nullptr; i++) {
361  const FltRecord *child = flt_face->get_child(i);
362  if (child->is_of_type(FltVertexList::get_class_type())) {
363  vlist = DCAST(FltVertexList, child);
364  }
365  }
366 
367  if (vlist != nullptr) {
368  int num_vertices = vlist->get_num_vertices();
369  for (int i = 0; i < num_vertices; i++) {
370  FltVertex *flt_vertex = vlist->get_vertex(i);
371  vertices.push_back(make_egg_vertex(flt_vertex));
372  }
373  }
374 
375  setup_geometry(flt_face, state, egg_prim, _main_egg_vpool, vertices);
376 }
377 
378 /**
379  * Converts the external reference node.
380  */
381 void FltToEggConverter::
382 convert_ext_ref(const FltExternalReference *flt_ext, FltToEggLevelState &state) {
383  // Get a group node to put the reference into.
384  EggGroupNode *egg_parent =
385  state.get_synthetic_group("", flt_ext);
386 
387  handle_external_reference(egg_parent, flt_ext->get_ref_filename());
388 }
389 
390 /**
391  * Applies the state indicated in the FltGeometry record to the indicated
392  * EggPrimitive and all of its indicated vertices, and then officially adds
393  * the vertices to the vertex pool and to the primitive, and adds the
394  * primitive to its appropriate parent.
395  */
396 void FltToEggConverter::
397 setup_geometry(const FltGeometry *flt_geom, FltToEggLevelState &state,
398  EggPrimitive *egg_prim, EggVertexPool *egg_vpool,
399  const FltToEggConverter::EggVertices &vertices) {
400 
401  // Determine what the appropriate parent will be.
402  EggGroupNode *egg_parent =
403  state.get_synthetic_group(flt_geom->get_id(), flt_geom,
404  flt_geom->_billboard_type);
405 
406  // Create a new state to reflect the new parent.
407  FltToEggLevelState next_state(state);
408  next_state._egg_parent = egg_parent;
409 
410  // Check for decals onto the primitive.
411  convert_subfaces(flt_geom, next_state);
412 
413  // Add the primitive to its new home.
414  next_state._egg_parent->add_child(egg_prim);
415 
416  // Now examine the vertices.
417  EggVertices::const_iterator vi;
418 
419  bool use_vertex_color = true;
420  bool keep_normals = true;
421  switch (flt_geom->_light_mode) {
422  case FltGeometry::LM_face_no_normal:
423  use_vertex_color = false;
424  keep_normals = false;
425  break;
426 
427  case FltGeometry::LM_vertex_no_normal:
428  use_vertex_color = true;
429  keep_normals = false;
430  break;
431 
432  case FltGeometry::LM_face_with_normal:
433  use_vertex_color = false;
434  keep_normals = true;
435  break;
436 
437  case FltGeometry::LM_vertex_with_normal:
438  use_vertex_color = true;
439  keep_normals = true;
440  break;
441  }
442 
443  LColor face_color = flt_geom->get_color();
444 
445  if (state._flt_object != nullptr) {
446  // If we have a FltObject above us, it might also specify a transparency.
447  // This combines with our existing transparency.
448  PN_stdfloat alpha = 1.0 - (state._flt_object->_transparency / 65535.0);
449  face_color[3] *= alpha;
450  }
451 
452  egg_prim->set_color(face_color);
453 
454  if (flt_geom->has_texture()) {
455  // If the geometry has a texture, apply it.
456  egg_prim->set_texture(make_egg_texture(flt_geom->get_texture()));
457 
458  if (flt_geom->_texwhite) {
459  // If the geometry should be colored white under the texture, then
460  // eliminate vertex colors.
461  use_vertex_color = false;
462  }
463  }
464 
465  if (use_vertex_color) {
466  // If we're to use vertex color instead of the face color, remove the face
467  // color to eliminate any ambiguity.
468  egg_prim->clear_color();
469 
470  // Also, make sure the transparency is set correctly across all vertices.
471  for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
472  EggVertex *vertex = (*vi);
473  if (vertex->has_color()) {
474  LColor vertex_color = vertex->get_color();
475  vertex_color[3] = face_color[3];
476  vertex->set_color(vertex_color);
477  } else {
478  if (flt_geom->has_color()) {
479  // If a vertex doesn't have a color but the face does, set the
480  // vertex to use the face color.
481  vertex->set_color(face_color);
482  }
483  }
484  }
485 
486  } else {
487  // If we're to use face color instead of vertex color, remove the vertex
488  // color to eliminate any ambiguity.
489  for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
490  (*vi)->clear_color();
491  }
492  }
493 
494  if (!keep_normals) {
495  // If we're not to use the normals, then eliminate them.
496  for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
497  (*vi)->clear_normal();
498  }
499  }
500 
501  if (flt_geom->_draw_type == FltGeometry::DT_solid_no_cull) {
502  // A double-sided polygon.
503  egg_prim->set_bface_flag(true);
504  }
505 
506  for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
507  EggVertex *egg_vertex = egg_vpool->create_unique_vertex(*(*vi));
508  egg_prim->add_vertex(egg_vertex);
509  }
510 
511  parse_comment(flt_geom, egg_prim);
512 }
513 
514 /**
515  * Records all of the subfaces of the indicated group as coplanar polygons
516  * (i.e. decals) of the group.
517  *
518  * If coplanar polygons exist, the state is modified so that _egg_parent is
519  * the new group to which the base polygons should be added. Therefore,
520  * subfaces should be defined before the ordinary children are processed.
521  */
522 void FltToEggConverter::
523 convert_subfaces(const FltRecord *flt_record, FltToEggLevelState &state) {
524  int num_subfaces = flt_record->get_num_subfaces();
525  if (num_subfaces == 0) {
526  // No subfaces.
527  return;
528  }
529 
530  // Create a new group to contain the base polygons.
531  EggGroup *egg_group = new EggGroup("decal_base");
532  state._egg_parent->add_child(egg_group);
533  state._egg_parent = egg_group;
534 
535  egg_group->set_decal_flag(true);
536 
537  // Now create a nested group to hold the decals.
538  EggGroup *decal_group = new EggGroup("decals");
539  egg_group->add_child(decal_group);
540  egg_group = decal_group;
541 
542  FltToEggLevelState next_state(state);
543  next_state._egg_parent = decal_group;
544 
545  for (int i = 0; i < num_subfaces; i++) {
546  const FltRecord *subface = flt_record->get_subface(i);
547  dispatch_record(subface, next_state);
548  }
549 }
550 
551 /**
552  * Scans the comment on this record for "<egg> { ... }" and parses the
553  * enclosed string as if it appeared in the egg file. Returns true on
554  * success, false on syntax error (in which case _error is also set to true).
555  */
556 bool FltToEggConverter::
557 parse_comment(const FltBeadID *flt_bead, EggNode *egg_node) {
558  return parse_comment(flt_bead->get_comment(), flt_bead->get_id(), egg_node);
559 }
560 
561 /**
562  * Scans the comment on this record for "<egg> { ... }" and parses the
563  * enclosed string as if it appeared in the egg file. Returns true on
564  * success, false on syntax error (in which case _error is also set to true).
565  */
566 bool FltToEggConverter::
567 parse_comment(const FltBead *flt_bead, EggNode *egg_node) {
568  return parse_comment(flt_bead->get_comment(), "anonymous", egg_node);
569 }
570 
571 /**
572  * Scans the comment on this record for "<egg> { ... }" and parses the
573  * enclosed string as if it appeared in the egg file. Returns true on
574  * success, false on syntax error (in which case _error is also set to true).
575  */
576 bool FltToEggConverter::
577 parse_comment(const FltTexture *flt_texture, EggNode *egg_node) {
578  return parse_comment(flt_texture->get_comment(),
579  flt_texture->get_texture_filename(), egg_node);
580 }
581 
582 /**
583  * Scans the comment on this record for "<egg> { ... }" and parses the
584  * enclosed string as if it appeared in the egg file. Returns true on
585  * success, false on syntax error (in which case _error is also set to true).
586  */
587 bool FltToEggConverter::
588 parse_comment(const string &comment, const string &name,
589  EggNode *egg_node) {
590  if (comment.empty()) {
591  // No comment.
592  return true;
593  }
594 
595  // Scan for <egg>.
596  static const string egg_str = "<egg>";
597 
598  size_t p;
599  p = 0;
600  while (p < comment.length() &&
601  cmp_nocase(comment.substr(p, 5), egg_str) != 0) {
602  p++;
603  }
604 
605  if (p >= comment.length()) {
606  // No "<egg>" in the comment.
607  return true;
608  }
609 
610  p += 5;
611  // Now scan past whitespace for the open curly brace.
612  while (p < comment.length() && isspace(comment[p])) {
613  ++p;
614  }
615  if (p >= comment.length() || comment[p] != '{') {
616  nout << "No opening brace in comment for "
617  << name << "\n\n";
618  _error = true;
619  return false;
620  }
621 
622  // Here's the beginning of the string after "<egg> {". Now lop off the
623  // closing brace at the end.
624  ++p;
625  size_t q = comment.length() - 1;
626  while (q > p && comment[q] != '}') {
627  --q;
628  }
629  if (q == p) {
630  nout << "No closing brace in comment for "
631  << name << "\n\n";
632  _error = true;
633  return false;
634  }
635 
636  string egg_syntax = comment.substr(p, q - p);
637 
638  if (!egg_node->parse_egg(egg_syntax)) {
639  nout << "Syntax error in comment for "
640  << name << "\n\n";
641  _error = true;
642  return false;
643  }
644 
645  // Correctly parsed!
646  return true;
647 }
648 
649 /**
650  * Makes a new EggVertex for the indicated FltVertex. The vertex is not
651  * automatically added to the vertex pool.
652  */
653 PT_EggVertex FltToEggConverter::
654 make_egg_vertex(const FltVertex *flt_vertex) {
655  PT_EggVertex egg_vertex = new EggVertex;
656  egg_vertex->set_pos(flt_vertex->_pos);
657 
658  if (flt_vertex->_has_normal) {
659  egg_vertex->set_normal(LCAST(double, flt_vertex->_normal));
660  }
661 
662  if (flt_vertex->_has_uv) {
663  egg_vertex->set_uv(LCAST(double, flt_vertex->_uv));
664  }
665 
666  if (flt_vertex->has_color()) {
667  egg_vertex->set_color(flt_vertex->get_color());
668  }
669 
670  return egg_vertex;
671 }
672 
673 /**
674  * Makes a new EggTexture for the indicated FltTexture, or returns a pointer
675  * to one previously made for the same FltTexture.
676  */
677 PT_EggTexture FltToEggConverter::
678 make_egg_texture(const FltTexture *flt_texture) {
679  Textures::const_iterator ti;
680  ti = _textures.find(flt_texture);
681  if (ti != _textures.end()) {
682  // There's one previously created.
683  return (*ti).second;
684  }
685 
686  // Create a new one.
687  string tref_name = format_string(flt_texture->_pattern_index);
688  Filename filename = flt_texture->get_texture_filename();
689 
690  PT_EggTexture egg_texture = new EggTexture(tref_name, filename);
691 
692  _textures.insert(Textures::value_type(flt_texture, egg_texture));
693 
694  // Set up the texture properties.
695 
696  switch (flt_texture->_min_filter) {
697  case FltTexture::MN_point:
698  egg_texture->set_minfilter(EggTexture::FT_nearest);
699  break;
700 
701  case FltTexture::MN_bilinear:
702  egg_texture->set_minfilter(EggTexture::FT_linear);
703  break;
704 
705  case FltTexture::MN_mipmap_point:
706  egg_texture->set_minfilter(EggTexture::FT_nearest_mipmap_nearest);
707  break;
708 
709  case FltTexture::MN_mipmap_linear:
710  egg_texture->set_minfilter(EggTexture::FT_nearest_mipmap_linear);
711  break;
712 
713  case FltTexture::MN_mipmap_bilinear:
714  egg_texture->set_minfilter(EggTexture::FT_linear_mipmap_nearest);
715  break;
716 
717  case FltTexture::MN_mipmap_trilinear:
718  case FltTexture::MN_OB_mipmap:
719  egg_texture->set_minfilter(EggTexture::FT_linear_mipmap_linear);
720  break;
721 
722  case FltTexture::MN_bicubic:
723  case FltTexture::MN_bilinear_gequal:
724  case FltTexture::MN_bilinear_lequal:
725  case FltTexture::MN_bicubic_gequal:
726  case FltTexture::MN_bicubic_lequal:
727  // Not supported.
728  break;
729  }
730 
731  switch (flt_texture->_mag_filter) {
732  case FltTexture::MG_point:
733  egg_texture->set_magfilter(EggTexture::FT_nearest);
734  break;
735 
736  case FltTexture::MG_bilinear:
737  egg_texture->set_magfilter(EggTexture::FT_linear);
738  break;
739 
740  case FltTexture::MG_bicubic:
741  case FltTexture::MG_sharpen:
742  case FltTexture::MG_add_detail:
743  case FltTexture::MG_modulate_detail:
744  case FltTexture::MG_bilinear_gequal:
745  case FltTexture::MG_bilinear_lequal:
746  case FltTexture::MG_bicubic_gequal:
747  case FltTexture::MG_bicubic_lequal:
748  // Not supported.
749  break;
750  }
751 
752  switch (flt_texture->_repeat) {
753  case FltTexture::RT_repeat:
754  egg_texture->set_wrap_mode(EggTexture::WM_repeat);
755  break;
756 
757  case FltTexture::RT_clamp:
758  egg_texture->set_wrap_mode(EggTexture::WM_clamp);
759  break;
760  }
761 
762  switch (flt_texture->_repeat_u) {
763  case FltTexture::RT_repeat:
764  egg_texture->set_wrap_u(EggTexture::WM_repeat);
765  break;
766 
767  case FltTexture::RT_clamp:
768  egg_texture->set_wrap_u(EggTexture::WM_clamp);
769  break;
770  }
771 
772  switch (flt_texture->_repeat_v) {
773  case FltTexture::RT_repeat:
774  egg_texture->set_wrap_v(EggTexture::WM_repeat);
775  break;
776 
777  case FltTexture::RT_clamp:
778  egg_texture->set_wrap_v(EggTexture::WM_clamp);
779  break;
780  }
781 
782  switch (flt_texture->_env_type) {
783  case FltTexture::ET_modulate:
784  egg_texture->set_env_type(EggTexture::ET_modulate);
785  break;
786 
787  case FltTexture::ET_decal:
788  egg_texture->set_env_type(EggTexture::ET_decal);
789  break;
790 
791  case FltTexture::ET_blend:
792  case FltTexture::ET_color:
793  // Not supported.
794  break;
795  }
796 
797  switch (flt_texture->_internal_format) {
798  case FltTexture::IF_default:
799  break;
800 
801  case FltTexture::IF_i_12a_4:
802  case FltTexture::IF_ia_12:
803  case FltTexture::IF_ia_8:
804  egg_texture->set_format(EggTexture::F_luminance_alpha);
805  break;
806 
807  case FltTexture::IF_rgb_5:
808  egg_texture->set_format(EggTexture::F_rgb5);
809  break;
810 
811  case FltTexture::IF_rgba_4:
812  egg_texture->set_format(EggTexture::F_rgba4);
813  break;
814 
815 
816  case FltTexture::IF_rgba_8:
817  egg_texture->set_format(EggTexture::F_rgba8);
818  break;
819 
820  case FltTexture::IF_rgba_12:
821  egg_texture->set_format(EggTexture::F_rgba12);
822  break;
823 
824  case FltTexture::IF_i_16:
825  if (flt_texture->_intensity_is_alpha) {
826  egg_texture->set_format(EggTexture::F_alpha);
827  } else {
828  egg_texture->set_format(EggTexture::F_luminance);
829  }
830  break;
831 
832  case FltTexture::IF_rgb_12:
833  egg_texture->set_format(EggTexture::F_rgb12);
834  break;
835  }
836 
837  parse_comment(flt_texture, egg_texture);
838  return egg_texture;
839 }
A base class for any of a number of kinds of geometry primitives: polygons, point lights,...
Definition: eggPrimitive.h:47
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.
virtual bool supports_compressed() const
Returns true if this file type can transparently load compressed files (with a .pz extension),...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A base class for any of a broad family of flt beads that include an ID.
Definition: fltBeadID.h:24
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Filename get_texture_filename() const
Returns the name of the texture image file.
Definition: fltTexture.cxx:101
bool had_error() const
Returns true if an error was detected during the conversion process (unless _allow_errors is true),...
void set_pos(double pos)
Sets the vertex position.
Definition: eggVertex.I:42
A base class for nodes in the hierarchy that are not leaf nodes.
Definition: eggGroupNode.h:46
int get_num_children() const
Returns the number of child records of this record.
Definition: fltRecord.cxx:63
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Defines a texture map that may be applied to geometry.
Definition: eggTexture.h:30
The main grouping bead of the flt file.
Definition: fltGroup.h:24
bool handle_external_reference(EggGroupNode *egg_parent, const Filename &ref_filename)
Handles an external reference in the source file.
void set_texture(EggTexture *texture)
Replaces the current list of textures with the indicated texture.
Definition: eggPrimitive.I:116
set_bface_flag
Sets the backfacing flag of the polygon.
Definition: eggPrimitive.h:116
A base class for any of a broad family of flt records that represent particular beads in the hierarch...
Definition: fltBead.h:29
A single face bead, e.g.
Definition: fltFace.h:24
This class supervises the construction of an EggData structure from the data represented by the FltHe...
LColor get_color() const
Returns the color set on this particular attribute.
Definition: eggAttributes.I:91
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool has_color() const
Returns true if the vertex has a primary color indicated, false otherwise.
Definition: fltVertex.I:18
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a base class for both FltFace and FltMesh, which are two different kinds of geometric primiti...
Definition: fltGeometry.h:33
A single point, or a collection of points as defined by a single <PointLight> entry.
Definition: eggPoint.h:25
bool has_color() const
Returns true if the face has a primary color indicated, false otherwise.
Definition: fltGeometry.I:80
bool parse_egg(const std::string &egg_syntax)
Parses the egg syntax given in the indicate string as if it had been read from the egg file within th...
Definition: eggNode.cxx:224
This is the first bead in the file, the top of the bead hierarchy, and the primary interface to readi...
Definition: fltHeader.h:44
virtual std::string get_name() const
Returns the English name of the file type this converter supports.
This keeps track of relevant things about the traversal as we walk through the flt hierarchy.
DistanceUnit
This enumerated type lists all the kinds of units we're likely to come across in model conversion pro...
Definition: distanceUnit.h:23
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition: eggGroup.h:34
const std::string & get_comment() const
Retrieves the comment for this record, or empty string if the record has no comment.
Definition: fltRecord.cxx:224
virtual DistanceUnit get_input_units()
This may be called after convert_file() has been called and returned true, indicating a successful co...
FltRecord * get_subface(int n) const
Returns the nth subface of this record.
Definition: fltRecord.cxx:106
void clear_error()
Resets the error flag to the no-error state.
A list of vertices, typically added as a child of a face bead.
Definition: fltVertexList.h:28
Represents a single texture in the texture palette.
Definition: fltTexture.h:27
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
Definition: eggVertex.h:39
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The base class for all kinds of records in a MultiGen OpenFlight file.
Definition: fltRecord.h:36
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggGroupNode * get_synthetic_group(const std::string &name, const FltBead *transform_bead, FltGeometry::BillboardType type=FltGeometry::BT_none)
Sometimes it is necessary to synthesize a group within a particular EggGroup, for instance to insert ...
Represents a single vertex in the vertex palette.
Definition: fltVertex.h:32
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An external reference to another flt file (possibly to a specific bead within the flt file).
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A single polygon.
Definition: eggPolygon.h:24
virtual std::string get_extension() const
Returns the common extension of the file type this converter supports.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The main objecting bead of the flt file.
Definition: fltObject.h:24
bool convert_flt(const FltHeader *flt_header)
Fills up the egg_data structure according to the indicated lwo structure.
FltRecord * get_child(int n) const
Returns the nth child of this record.
Definition: fltRecord.cxx:71
Filename get_ref_filename() const
Returns the name of the referenced file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
LColor get_color() const
Returns the primary color of the face, as a four-component value (including alpha as the transparency...
Definition: fltGeometry.cxx:59
A base class for things that may be directly added into the egg hierarchy.
Definition: eggNode.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual SomethingToEggConverter * make_copy()
Allocates and returns a new copy of the converter.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool convert_file(const Filename &filename)
Handles the reading of the input file and converting it to egg.
LColor get_color() const
If has_color() indicates true, returns the color of the vertex, as a four- component value.
Definition: fltVertex.cxx:111
bool has_texture() const
Returns true if the face has a texture applied, false otherwise.
Definition: fltGeometry.I:18
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A Level-of-Detail record.
Definition: fltLOD.h:24
This is a base class for a family of converter classes that manage a conversion from some file type t...
FltTexture * get_texture() const
Returns the texture applied to this face, or NULL if no texture was applied.
Definition: fltGeometry.I:27
const std::string & get_id() const
Returns the id (name) of this particular bead.
Definition: fltBeadID.cxx:32
EggVertex * create_unique_vertex(const EggVertex &copy)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
A collection of vertices.
Definition: eggVertexPool.h:41
EggVertex * add_vertex(EggVertex *vertex)
Adds the indicated vertex to the end of the primitive's list of vertices, and returns it.
A SwitchCondition that switches the levels-of-detail based on distance from the camera's eyepoint.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_transform(const FltBead *flt_bead, EggGroup *egg_group)
Sets up the group to reflect the transform indicated by the given record, if any.
int get_num_subfaces() const
Returns the number of subface records of this record.
Definition: fltRecord.cxx:98
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.