Panda3D
Loading...
Searching...
No Matches
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"
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"
36#include "string_utils.h"
37
38using std::string;
39
40
41/**
42 *
43 */
44FltToEggConverter::
45FltToEggConverter() {
46 _compose_transforms = false;
47 _flt_units = DU_invalid;
48}
49
50/**
51 *
52 */
53FltToEggConverter::
54FltToEggConverter(const FltToEggConverter &copy) :
56 _compose_transforms(copy._compose_transforms)
57{
58}
59
60/**
61 *
62 */
63FltToEggConverter::
64~FltToEggConverter() {
65 cleanup();
66}
67
68/**
69 * Allocates and returns a new copy of the converter.
70 */
75
76
77/**
78 * Returns the English name of the file type this converter supports.
79 */
81get_name() const {
82 return "MultiGen";
83}
84
85/**
86 * Returns the common extension of the file type this converter supports.
87 */
89get_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 */
98supports_compressed() const {
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 */
111convert_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 */
143convert_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 */
179void FltToEggConverter::
180cleanup() {
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 */
189void FltToEggConverter::
190convert_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 */
203void FltToEggConverter::
204dispatch_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 */
235void FltToEggConverter::
236convert_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 */
257void FltToEggConverter::
258convert_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 */
281void FltToEggConverter::
282convert_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 */
298void FltToEggConverter::
299convert_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 */
316void FltToEggConverter::
317convert_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 */
334void FltToEggConverter::
335convert_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.
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 */
381void FltToEggConverter::
382convert_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 */
396void FltToEggConverter::
397setup_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 */
522void FltToEggConverter::
523convert_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 */
556bool FltToEggConverter::
557parse_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 */
566bool FltToEggConverter::
567parse_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 */
576bool FltToEggConverter::
577parse_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 */
587bool FltToEggConverter::
588parse_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 */
653PT_EggVertex FltToEggConverter::
654make_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 */
677PT_EggTexture FltToEggConverter::
678make_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}
LColor get_color() const
Returns the color set on this particular attribute.
A base class for nodes in the hierarchy that are not leaf nodes.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition eggGroup.h:34
A base class for things that may be directly added into the egg hierarchy.
Definition eggNode.h:36
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
A single point, or a collection of points as defined by a single <PointLight> entry.
Definition eggPoint.h:25
A single polygon.
Definition eggPolygon.h:24
A base class for any of a number of kinds of geometry primitives: polygons, point lights,...
set_bface_flag
Sets the backfacing flag of the polygon.
void set_texture(EggTexture *texture)
Replaces the current list of textures with the indicated texture.
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.
Defines a texture map that may be applied to geometry.
Definition eggTexture.h:30
A collection of vertices.
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.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
Definition eggVertex.h:39
void set_pos(double pos)
Sets the vertex position.
Definition eggVertex.I:42
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
A base class for any of a broad family of flt beads that include an ID.
Definition fltBeadID.h:24
const std::string & get_id() const
Returns the id (name) of this particular bead.
Definition fltBeadID.cxx:32
A base class for any of a broad family of flt records that represent particular beads in the hierarch...
Definition fltBead.h:29
An external reference to another flt file (possibly to a specific bead within the flt file).
Filename get_ref_filename() const
Returns the name of the referenced file.
A single face bead, e.g.
Definition fltFace.h:24
This is a base class for both FltFace and FltMesh, which are two different kinds of geometric primiti...
Definition fltGeometry.h:33
bool has_texture() const
Returns true if the face has a texture applied, false otherwise.
Definition fltGeometry.I:18
LColor get_color() const
Returns the primary color of the face, as a four-component value (including alpha as the transparency...
FltTexture * get_texture() const
Returns the texture applied to this face, or NULL if no texture was applied.
Definition fltGeometry.I:27
bool has_color() const
Returns true if the face has a primary color indicated, false otherwise.
Definition fltGeometry.I:80
The main grouping bead of the flt file.
Definition fltGroup.h:24
This is the first bead in the file, the top of the bead hierarchy, and the primary interface to readi...
Definition fltHeader.h:44
A Level-of-Detail record.
Definition fltLOD.h:24
The main objecting bead of the flt file.
Definition fltObject.h:24
The base class for all kinds of records in a MultiGen OpenFlight file.
Definition fltRecord.h:36
FltRecord * get_subface(int n) const
Returns the nth subface of this record.
const std::string & get_comment() const
Retrieves the comment for this record, or empty string if the record has no comment.
FltRecord * get_child(int n) const
Returns the nth child of this record.
Definition fltRecord.cxx:71
int get_num_subfaces() const
Returns the number of subface records of this record.
Definition fltRecord.cxx:98
int get_num_children() const
Returns the number of child records of this record.
Definition fltRecord.cxx:63
Represents a single texture in the texture palette.
Definition fltTexture.h:27
Filename get_texture_filename() const
Returns the name of the texture image file.
This class supervises the construction of an EggData structure from the data represented by the FltHe...
virtual std::string get_name() const
Returns the English name of the file type this converter supports.
virtual DistanceUnit get_input_units()
This may be called after convert_file() has been called and returned true, indicating a successful co...
virtual SomethingToEggConverter * make_copy()
Allocates and returns a new copy of the converter.
virtual bool convert_file(const Filename &filename)
Handles the reading of the input file and converting it to egg.
bool convert_flt(const FltHeader *flt_header)
Fills up the egg_data structure according to the indicated lwo structure.
virtual std::string get_extension() const
Returns the common extension of the file type this converter supports.
virtual bool supports_compressed() const
Returns true if this file type can transparently load compressed files (with a .pz extension),...
This keeps track of relevant things about the traversal as we walk through the flt hierarchy.
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 ...
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.
A list of vertices, typically added as a child of a face bead.
Represents a single vertex in the vertex palette.
Definition fltVertex.h:32
LColor get_color() const
If has_color() indicates true, returns the color of the vertex, as a four- component value.
bool has_color() const
Returns true if the vertex has a primary color indicated, false otherwise.
Definition fltVertex.I:18
This is a base class for a family of converter classes that manage a conversion from some file type t...
bool had_error() const
Returns true if an error was detected during the conversion process (unless _allow_errors is true),...
bool handle_external_reference(EggGroupNode *egg_parent, const Filename &ref_filename)
Handles an external reference in the source file.
void clear_error()
Resets the error flag to the no-error state.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition typedObject.I:28
This is our own Panda specialization on the default STL vector.
Definition pvector.h:42
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
DistanceUnit
This enumerated type lists all the kinds of units we're likely to come across in model conversion pro...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.