From 557ced9f666b79f1ade09ced1cee5d7e74f3bd37 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 18 Apr 2001 01:52:55 +0000 Subject: [PATCH] *** empty log message *** --- pandatool/src/eggbase/somethingToEgg.cxx | 6 +- pandatool/src/flt/fltBeadID.cxx | 26 +- pandatool/src/flt/fltVertex.I | 2 +- pandatool/src/fltegg/Sources.pp | 16 + pandatool/src/fltegg/fltToEggConverter.I | 37 ++ pandatool/src/fltegg/fltToEggConverter.cxx | 423 +++++++++++++++++++++ pandatool/src/fltegg/fltToEggConverter.h | 92 +++++ pandatool/src/fltprogs/Sources.pp | 15 + pandatool/src/fltprogs/fltTrans.cxx | 31 +- pandatool/src/maya/mayaToEgg.cxx | 20 +- pandatool/src/progbase/Sources.pp | 2 + pandatool/src/progbase/distanceUnit.cxx | 144 +++++++ pandatool/src/progbase/distanceUnit.h | 35 ++ pandatool/src/progbase/programBase.cxx | 22 ++ pandatool/src/progbase/programBase.h | 3 + 15 files changed, 841 insertions(+), 33 deletions(-) create mode 100644 pandatool/src/fltegg/Sources.pp create mode 100644 pandatool/src/fltegg/fltToEggConverter.I create mode 100644 pandatool/src/fltegg/fltToEggConverter.cxx create mode 100644 pandatool/src/fltegg/fltToEggConverter.h create mode 100644 pandatool/src/progbase/distanceUnit.cxx create mode 100644 pandatool/src/progbase/distanceUnit.h diff --git a/pandatool/src/eggbase/somethingToEgg.cxx b/pandatool/src/eggbase/somethingToEgg.cxx index 0972a0aadf..b3ffb223df 100644 --- a/pandatool/src/eggbase/somethingToEgg.cxx +++ b/pandatool/src/eggbase/somethingToEgg.cxx @@ -33,10 +33,8 @@ SomethingToEgg(const string &format_name, redescribe_option ("cs", - "Specify the coordinate system of the resulting egg file. This may be " - "one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default " - "is the same coordinate system as the input " + _format_name + - " file, if this can be determined."); + "Specify the coordinate system of the input " + _format_name + + "file. Normally, this can inferred from the file itself."); } //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/flt/fltBeadID.cxx b/pandatool/src/flt/fltBeadID.cxx index 09e052a157..f3d39c21aa 100644 --- a/pandatool/src/flt/fltBeadID.cxx +++ b/pandatool/src/flt/fltBeadID.cxx @@ -18,6 +18,28 @@ FltBeadID:: FltBeadID(FltHeader *header) : FltBead(header) { } +//////////////////////////////////////////////////////////////////// +// Function: FltBeadID::get_id +// Access: Public +// Description: Returns the id (name) of this particular bead. Each +// MultiGen bead will have a unique name. +//////////////////////////////////////////////////////////////////// +const string &FltBeadID:: +get_id() const { + return _id; +} + +//////////////////////////////////////////////////////////////////// +// Function: FltBeadID::set_id +// Access: Public +// Description: Changes the id (name) of this particular bead. This +// should be a name that is unique to this bead. +//////////////////////////////////////////////////////////////////// +void FltBeadID:: +set_id(const string &id) { + _id = id; +} + //////////////////////////////////////////////////////////////////// // Function: FltBeadID::output // Access: Public @@ -64,7 +86,9 @@ extract_record(FltRecordReader &reader) { bool FltBeadID:: extract_ancillary(FltRecordReader &reader) { if (reader.get_opcode() == FO_long_id) { - _id = reader.get_iterator().get_remaining_bytes(); + string s = reader.get_iterator().get_remaining_bytes(); + size_t zero_byte = s.find('\0'); + _id = s.substr(0, zero_byte); return true; } diff --git a/pandatool/src/flt/fltVertex.I b/pandatool/src/flt/fltVertex.I index c0ce7b9cca..805f0fb931 100644 --- a/pandatool/src/flt/fltVertex.I +++ b/pandatool/src/flt/fltVertex.I @@ -12,5 +12,5 @@ //////////////////////////////////////////////////////////////////// INLINE bool FltVertex:: has_color() const { - return (_flags & F_no_color) == 0; + return (_flags & F_no_color) != 0; } diff --git a/pandatool/src/fltegg/Sources.pp b/pandatool/src/fltegg/Sources.pp new file mode 100644 index 0000000000..94115b348a --- /dev/null +++ b/pandatool/src/fltegg/Sources.pp @@ -0,0 +1,16 @@ +#begin ss_lib_target + #define TARGET fltegg + #define LOCAL_LIBS pandatoolbase progbase flt + #define OTHER_LIBS \ + egg:c pandaegg:m \ + mathutil:c linmath:c putil:c express:c panda:m dtoolconfig dtool + #define UNIX_SYS_LIBS \ + m + + #define SOURCES \ + fltToEggConverter.I fltToEggConverter.cxx fltToEggConverter.h + + #define INSTALL_HEADERS \ + fltToEggConverter.I fltToEggConverter.h + +#end ss_lib_target diff --git a/pandatool/src/fltegg/fltToEggConverter.I b/pandatool/src/fltegg/fltToEggConverter.I new file mode 100644 index 0000000000..11644f3c18 --- /dev/null +++ b/pandatool/src/fltegg/fltToEggConverter.I @@ -0,0 +1,37 @@ +// Filename: fltToEggConverter.I +// Created by: drose (17Apr01) +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE FltToEggConverter:: +~FltToEggConverter() { +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::set_input_units +// Access: Public +// Description: Sets the units the input flt file is considered to +// represent. If this is unset or DU_invalid, the units +// are taken from the flt header. +//////////////////////////////////////////////////////////////////// +INLINE void FltToEggConverter:: +set_input_units(DistanceUnit input_units) { + _input_units = input_units; +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::set_output_units +// Access: Public +// Description: Sets the units to generate in the resulting egg file. +// If this is unset, no units conversion is performed. +//////////////////////////////////////////////////////////////////// +INLINE void FltToEggConverter:: +set_output_units(DistanceUnit output_units) { + _output_units = output_units; +} diff --git a/pandatool/src/fltegg/fltToEggConverter.cxx b/pandatool/src/fltegg/fltToEggConverter.cxx new file mode 100644 index 0000000000..f9266664aa --- /dev/null +++ b/pandatool/src/fltegg/fltToEggConverter.cxx @@ -0,0 +1,423 @@ +// Filename: fltToEggConverter.cxx +// Created by: drose (17Apr01) +// +//////////////////////////////////////////////////////////////////// + +#include "fltToEggConverter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +FltToEggConverter:: +FltToEggConverter(EggData &egg_data) : _egg_data(egg_data) { + _input_units = DU_invalid; + _output_units = DU_invalid; +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::convert_flt +// Access: Public +// Description: Returns a newly-allocated EggData structure +// corresponding to the indicated flt structure. +//////////////////////////////////////////////////////////////////// +void FltToEggConverter:: +convert_flt(const FltHeader *flt_header) { + _flt_header = flt_header; + + if (_input_units == DU_invalid) { + switch (_flt_header->_vertex_units) { + case FltHeader::U_meters: + _input_units = DU_meters; + break; + + case FltHeader::U_kilometers: + _input_units = DU_kilometers; + break; + + case FltHeader::U_feet: + _input_units = DU_feet; + break; + + case FltHeader::U_inches: + _input_units = DU_inches; + break; + + case FltHeader::U_nautical_miles: + _input_units = DU_nautical_miles; + break; + } + } + + // Generate a default vertex pool. + _main_egg_vpool = new EggVertexPool("vpool"); + _egg_data.add_child(_main_egg_vpool); + + // We could populate the vertex pool right away, but it's better to + // defer each vertex until we encounter it, since some of the + // vertices may need to be adjusted to match the particular polygon + // they're assigned to (for instance, to apply a transparency or + // something). + + convert_record(_flt_header, (FltObject *)NULL, &_egg_data); + + if (_main_egg_vpool->empty()) { + // If we didn't get any global vertices, remove the vertex pool + // just for cleanliness. + _egg_data.remove_child(_main_egg_vpool); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::convert_record +// Access: Private +// Description: Converts the record and all of its children. +//////////////////////////////////////////////////////////////////// +void FltToEggConverter:: +convert_record(const FltRecord *flt_record, const FltObject *flt_object, + EggGroupNode *egg_group) { + int num_children = flt_record->get_num_children(); + + for (int i = 0; i < num_children; i++) { + const FltRecord *child = flt_record->get_child(i); + + if (child->is_of_type(FltLOD::get_class_type())) { + convert_lod(DCAST(FltLOD, child), flt_object, egg_group); + + } else if (child->is_of_type(FltGroup::get_class_type())) { + convert_group(DCAST(FltGroup, child), flt_object, egg_group); + + } else if (child->is_of_type(FltObject::get_class_type())) { + convert_object(DCAST(FltObject, child), flt_object, egg_group); + + } else if (child->is_of_type(FltFace::get_class_type())) { + convert_face(DCAST(FltFace, child), flt_object, egg_group); + + // Fallbacks. + } else if (child->is_of_type(FltBeadID::get_class_type())) { + convert_bead_id(DCAST(FltBeadID, child), flt_object, egg_group); + + } else if (child->is_of_type(FltBead::get_class_type())) { + convert_bead(DCAST(FltBead, child), flt_object, egg_group); + + } else { + convert_record(child, flt_object, egg_group); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::convert_lod +// Access: Private +// Description: Converts the LOD bead and all of its children. +//////////////////////////////////////////////////////////////////// +void FltToEggConverter:: +convert_lod(const FltLOD *flt_lod, const FltObject *flt_object, + EggGroupNode *egg_parent) { + EggGroup *egg_group = new EggGroup(flt_lod->get_id()); + egg_parent->add_child(egg_group); + + EggSwitchConditionDistance lod + (flt_lod->_switch_in, flt_lod->_switch_out, + LPoint3d(flt_lod->_center_x, flt_lod->_center_y, flt_lod->_center_z), + flt_lod->_transition_range); + egg_group->set_lod(lod); + + convert_record(flt_lod, flt_object, egg_group); +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::convert_group +// Access: Private +// Description: Converts the group and all of its children. +//////////////////////////////////////////////////////////////////// +void FltToEggConverter:: +convert_group(const FltGroup *flt_group, const FltObject *flt_object, + EggGroupNode *egg_parent) { + EggGroup *egg_group = new EggGroup(flt_group->get_id()); + egg_parent->add_child(egg_group); + + if ((flt_group->_flags & FltGroup::F_forward_animation) != 0) { + // It's a sequence animation. + egg_group->set_switch_flag(true); + egg_group->set_switch_fps(24.0); + } + + if (flt_group->has_transform()) { + egg_group->set_transform(flt_group->get_transform()); + } + + ///*** replicate count. + + convert_record(flt_group, flt_object, egg_group); +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::convert_object +// Access: Private +// Description: Converts the object and all of its children. +//////////////////////////////////////////////////////////////////// +void FltToEggConverter:: +convert_object(const FltObject *flt_object, const FltObject *, + EggGroupNode *egg_parent) { + EggGroup *egg_group = new EggGroup(flt_object->get_id()); + egg_parent->add_child(egg_group); + + if (flt_object->has_transform()) { + egg_group->set_transform(flt_object->get_transform()); + } + + convert_record(flt_object, flt_object, egg_group); +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::convert_bead_id +// Access: Private +// Description: Converts the generic bead (with ID) and all of its +// children. +//////////////////////////////////////////////////////////////////// +void FltToEggConverter:: +convert_bead_id(const FltBeadID *flt_bead, const FltObject *flt_object, + EggGroupNode *egg_parent) { + EggGroup *egg_group = new EggGroup(flt_bead->get_id()); + egg_parent->add_child(egg_group); + + if (flt_bead->has_transform()) { + egg_group->set_transform(flt_bead->get_transform()); + } + + convert_record(flt_bead, flt_object, egg_group); +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::convert_bead +// Access: Private +// Description: Converts the generic bead (without ID) and all of its +// children. +//////////////////////////////////////////////////////////////////// +void FltToEggConverter:: +convert_bead(const FltBead *flt_bead, const FltObject *flt_object, + EggGroupNode *egg_parent) { + EggGroup *egg_group = new EggGroup; + egg_parent->add_child(egg_group); + + if (flt_bead->has_transform()) { + egg_group->set_transform(flt_bead->get_transform()); + } + + convert_record(flt_bead, flt_object, egg_group); +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::convert_face +// Access: Private +// Description: Converts the face and all of its children. +//////////////////////////////////////////////////////////////////// +void FltToEggConverter:: +convert_face(const FltFace *flt_face, const FltObject *flt_object, + EggGroupNode *egg_parent) { + bool is_light; + switch (flt_face->_draw_type) { + case FltGeometry::DT_omni_light: + case FltGeometry::DT_uni_light: + case FltGeometry::DT_bi_light: + is_light = true; + break; + + default: + is_light = false; + } + + EggPrimitive *egg_prim; + if (is_light) { + egg_prim = new EggPoint; + } else { + egg_prim = new EggPolygon; + } + + egg_parent->add_child(egg_prim); + + // Collect the vertices for this primitive. + vector< PT(EggVertex) > vertices; + + const FltVertexList *vlist = (FltVertexList *)NULL; + int num_children = flt_face->get_num_children(); + for (int i = 0; i < num_children && vlist == (FltVertexList *)NULL; i++) { + const FltRecord *child = flt_face->get_child(i); + if (child->is_of_type(FltVertexList::get_class_type())) { + vlist = DCAST(FltVertexList, child); + } + } + + if (vlist != (FltVertexList *)NULL) { + int num_vertices = vlist->get_num_vertices(); + for (int i = 0; i < num_vertices; i++) { + FltVertex *flt_vertex = vlist->get_vertex(i); + vertices.push_back(make_egg_vertex(flt_vertex)); + } + } + + setup_geometry(flt_face, flt_object, egg_prim, _main_egg_vpool, vertices); +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::setup_geometry +// Access: Private +// Description: Applies the state indicated in the FltGeometry record +// to the indicated EggPrimitive and all of its +// indicated vertices, and then officially adds the +// vertices to the vertex pool and to the primitive. +//////////////////////////////////////////////////////////////////// +void FltToEggConverter:: +setup_geometry(const FltGeometry *flt_geom, const FltObject *, + EggPrimitive *egg_prim, EggVertexPool *egg_vpool, + const FltToEggConverter::EggVertices &vertices) { + EggVertices::const_iterator vi; + + if (flt_geom->has_color()) { + egg_prim->set_color(flt_geom->get_color()); + } + + bool use_vertex_color = true; + bool keep_normals = true; + switch (flt_geom->_light_mode) { + case FltGeometry::LM_face_no_normal: + use_vertex_color = false; + keep_normals = false; + break; + + case FltGeometry::LM_vertex_no_normal: + use_vertex_color = true; + keep_normals = false; + break; + + case FltGeometry::LM_face_with_normal: + use_vertex_color = false; + keep_normals = true; + break; + + case FltGeometry::LM_vertex_with_normal: + use_vertex_color = true; + keep_normals = true; + break; + } + + if (flt_geom->has_texture()) { + // If the geometry has a texture, apply it. + egg_prim->set_texture(make_egg_texture(flt_geom->get_texture())); + + if (flt_geom->_texwhite) { + // If the geometry should be colored white under the texture, + // then eliminate any explicit color; the egg loader will + // implicitly color it white. + egg_prim->clear_color(); + use_vertex_color = false; + } + } + + if (use_vertex_color) { + // If we're to use vertex color instead of the face color, remove + // the face color to eliminate any ambiguity. + if (flt_geom->has_color()) { + // Also, if some of our vertices don't have a color, set them to + // use the face color. + for (vi = vertices.begin(); vi != vertices.end(); ++vi) { + if (!(*vi)->has_color()) { + (*vi)->set_color(flt_geom->get_color()); + } + } + egg_prim->clear_color(); + } + + } else { + // If we're to use face color instead of vertex color, remove the + // vertex color to eliminate any ambiguity. + for (vi = vertices.begin(); vi != vertices.end(); ++vi) { + (*vi)->clear_color(); + } + } + + if (!keep_normals) { + // If we're not to use the normals, then eliminate them. + for (vi = vertices.begin(); vi != vertices.end(); ++vi) { + (*vi)->clear_normal(); + } + } + + for (vi = vertices.begin(); vi != vertices.end(); ++vi) { + EggVertex *egg_vertex = egg_vpool->create_unique_vertex(*(*vi)); + egg_prim->add_vertex(egg_vertex); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::make_egg_vertex +// Access: Private +// Description: Makes a new EggVertex for the indicated FltVertex. +// The vertex is not automatically added to the vertex +// pool. +//////////////////////////////////////////////////////////////////// +PT(EggVertex) FltToEggConverter:: +make_egg_vertex(const FltVertex *flt_vertex) { + PT(EggVertex) egg_vertex = new EggVertex; + egg_vertex->set_pos(flt_vertex->_pos); + + if (flt_vertex->_has_normal) { + egg_vertex->set_normal(LCAST(double, flt_vertex->_normal)); + } + + if (flt_vertex->_has_uv) { + egg_vertex->set_uv(LCAST(double, flt_vertex->_uv)); + } + + if (flt_vertex->has_color()) { + egg_vertex->set_color(flt_vertex->get_color()); + } + + return egg_vertex; +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::make_egg_texture +// Access: Private +// Description: Makes a new EggTexture for the indicated FltTexture, +// or returns a pointer to one previously made for the +// same FltTexture. +//////////////////////////////////////////////////////////////////// +PT(EggTexture) FltToEggConverter:: +make_egg_texture(const FltTexture *flt_texture) { + Textures::const_iterator ti; + ti = _textures.find(flt_texture); + if (ti != _textures.end()) { + // There's one previously created. + return (*ti).second; + } + + // Create a new one. + string tref_name = format_string(flt_texture->_pattern_index); + Filename filename = flt_texture->get_texture_filename(); + PT(EggTexture) egg_texture = new EggTexture(tref_name, filename); + + _textures.insert(Textures::value_type(flt_texture, egg_texture)); + return egg_texture; +} diff --git a/pandatool/src/fltegg/fltToEggConverter.h b/pandatool/src/fltegg/fltToEggConverter.h new file mode 100644 index 0000000000..91203913fd --- /dev/null +++ b/pandatool/src/fltegg/fltToEggConverter.h @@ -0,0 +1,92 @@ +// Filename: fltToEggConverter.h +// Created by: drose (17Apr01) +// +//////////////////////////////////////////////////////////////////// + +#ifndef FLTTOEGGCONVERTER_H +#define FLTTOEGGCONVERTER_H + +#include + +#include + +#include +#include +#include +#include +#include + +class FltRecord; +class FltLOD; +class FltGroup; +class FltObject; +class FltBeadID; +class FltBead; +class FltVertex; +class FltGeometry; +class FltFace; +class FltTexture; +class EggGroupNode; +class EggPrimitive; +class EggVertexPool; + +//////////////////////////////////////////////////////////////////// +// Class : FltToEggConverter +// Description : This class supervises the construction of an EggData +// structure from the data represented by the FltHeader. +// Reading and writing the egg and flt structures is +// left to the user. +//////////////////////////////////////////////////////////////////// +class FltToEggConverter { +public: + FltToEggConverter(EggData &egg_data); + INLINE ~FltToEggConverter(); + + INLINE void set_input_units(DistanceUnit input_units); + INLINE void set_output_units(DistanceUnit output_units); + + void convert_flt(const FltHeader *flt_header); + +private: + typedef vector< PT(EggVertex) > EggVertices; + + void convert_record(const FltRecord *flt_record, const FltObject *flt_object, + EggGroupNode *egg_group); + void convert_lod(const FltLOD *flt_lod, const FltObject *flt_object, + EggGroupNode *egg_parent); + void convert_group(const FltGroup *flt_group, const FltObject *flt_object, + EggGroupNode *egg_parent); + void convert_object(const FltObject *flt_object, const FltObject *flt_object, + EggGroupNode *egg_parent); + void convert_bead_id(const FltBeadID *flt_bead, const FltObject *flt_object, + EggGroupNode *egg_parent); + void convert_bead(const FltBead *flt_bead, const FltObject *flt_object, + EggGroupNode *egg_parent); + void convert_face(const FltFace *flt_face, const FltObject *flt_object, + EggGroupNode *egg_parent); + + + void setup_geometry(const FltGeometry *flt_geom, const FltObject *flt_object, + EggPrimitive *egg_prim, EggVertexPool *egg_vpool, + const EggVertices &vertices); + + PT(EggVertex) make_egg_vertex(const FltVertex *flt_vertex); + PT(EggTexture) make_egg_texture(const FltTexture *flt_texture); + + DistanceUnit _input_units; + DistanceUnit _output_units; + + EggData &_egg_data; + CPT(FltHeader) _flt_header; + + EggVertexPool *_main_egg_vpool; + + typedef map Textures; + Textures _textures; +}; + +#include "fltToEggConverter.I" + +#endif + + diff --git a/pandatool/src/fltprogs/Sources.pp b/pandatool/src/fltprogs/Sources.pp index 5af8c41b18..d17f0280d0 100644 --- a/pandatool/src/fltprogs/Sources.pp +++ b/pandatool/src/fltprogs/Sources.pp @@ -25,3 +25,18 @@ fltTrans.cxx fltTrans.h #end bin_target + +#begin noinst_bin_target + #define TARGET flt2egg + #define LOCAL_LIBS flt fltegg eggbase progbase + + #define OTHER_LIBS \ + egg:c pandaegg:m \ + linmath:c panda:m \ + express:c pandaexpress:m \ + dtoolutil:c dconfig:c dtoolconfig:m dtool:m pystub + + #define SOURCES \ + fltToEgg.cxx fltToEgg.h + +#end noinst_bin_target diff --git a/pandatool/src/fltprogs/fltTrans.cxx b/pandatool/src/fltprogs/fltTrans.cxx index 8b7bf69a86..f1688332c8 100644 --- a/pandatool/src/fltprogs/fltTrans.cxx +++ b/pandatool/src/fltprogs/fltTrans.cxx @@ -77,22 +77,23 @@ run() { if (result != FE_ok) { nout << "Unable to read: " << result << "\n"; exit(1); - } else { - if (header->check_version()) { - nout << "Version is " << header->get_flt_version() << "\n"; - } - - if (_got_new_version) { - header->set_flt_version(_new_version); - } - - result = header->write_flt(get_output()); - if (result != FE_ok) { - nout << "Unable to write: " << result << "\n"; - } else { - nout << "Successfully written.\n"; - } } + + if (header->check_version()) { + nout << "Version is " << header->get_flt_version() << "\n"; + } + + if (_got_new_version) { + header->set_flt_version(_new_version); + } + + result = header->write_flt(get_output()); + if (result != FE_ok) { + nout << "Unable to write: " << result << "\n"; + exit(1); + } + + nout << "Successfully written.\n"; } diff --git a/pandatool/src/maya/mayaToEgg.cxx b/pandatool/src/maya/mayaToEgg.cxx index c2da7ecfd9..2e1de2b64e 100644 --- a/pandatool/src/maya/mayaToEgg.cxx +++ b/pandatool/src/maya/mayaToEgg.cxx @@ -70,22 +70,18 @@ run() { exit(1); } - // First, we build the egg file in the same coordinate system as - // Maya. - if (MGlobal::isYAxisUp()) { - _data.set_coordinate_system(CS_yup_right); - } else { - _data.set_coordinate_system(CS_zup_right); + if (!_got_coordinate_system) { + // Choose a suitable coordinate system matching Maya. + if (MGlobal::isYAxisUp()) { + _coordinate_system = CS_yup_right; + } else { + _coordinate_system = CS_zup_right; + } } + _data.set_coordinate_system(_coordinate_system); _maya.make_egg(_data); - // Then, if the user so requested, we convert the egg file to the - // desired output coordinate system. - if (_got_coordinate_system) { - _data.set_coordinate_system(_coordinate_system); - } - write_egg_file(); } diff --git a/pandatool/src/progbase/Sources.pp b/pandatool/src/progbase/Sources.pp index 40327689bd..4333d8e4ec 100644 --- a/pandatool/src/progbase/Sources.pp +++ b/pandatool/src/progbase/Sources.pp @@ -6,6 +6,7 @@ linmath:c putil:c express:c panda:m pystub dtool #define SOURCES \ + distanceUnit.cxx distanceUnit.h \ programBase.I programBase.cxx programBase.h \ withOutputFile.cxx withOutputFile.h \ wordWrapStream.cxx \ @@ -13,6 +14,7 @@ wordWrapStreamBuf.h #define INSTALL_HEADERS \ + distanceUnit.h \ programBase.I programBase.h \ withOutputFile.h \ wordWrapStream.h wordWrapStreamBuf.I \ diff --git a/pandatool/src/progbase/distanceUnit.cxx b/pandatool/src/progbase/distanceUnit.cxx new file mode 100644 index 0000000000..06aa2c0f84 --- /dev/null +++ b/pandatool/src/progbase/distanceUnit.cxx @@ -0,0 +1,144 @@ +// Filename: distanceUnit.cxx +// Created by: drose (17Apr01) +// +//////////////////////////////////////////////////////////////////// + +#include "distanceUnit.h" + +#include + +//////////////////////////////////////////////////////////////////// +// Function: DistanceUnit output operator +// Description: +//////////////////////////////////////////////////////////////////// +ostream & +operator << (ostream &out, DistanceUnit unit) { + switch (unit) { + case DU_millimeters: + return out << "mm"; + + case DU_centimeters: + return out << "cm"; + + case DU_meters: + return out << "m"; + + case DU_kilometers: + return out << "km"; + + case DU_yards: + return out << "yd"; + + case DU_feet: + return out << "ft"; + + case DU_inches: + return out << "in"; + + case DU_nautical_miles: + return out << "nmi"; + + case DU_statute_miles: + return out << "mi"; + + case DU_invalid: + return out << "invalid"; + } + return out << "**unexpected DistanceUnit value: (" << (int)unit << ")**"; +} + +//////////////////////////////////////////////////////////////////// +// Function: string_distance_unit +// Description: Converts from a string, as might be input by the +// user, to one of the known DistanceUnit types. +// Returns DU_invalid if the string is unknown. +//////////////////////////////////////////////////////////////////// +DistanceUnit +string_distance_unit(const string &str) { + if (cmp_nocase(str, "mm") == 0 || cmp_nocase(str, "millimeters") == 0) { + return DU_millimeters; + + } else if (cmp_nocase(str, "cm") == 0 || cmp_nocase(str, "centimeters") == 0) { + return DU_centimeters; + + } else if (cmp_nocase(str, "m") == 0 || cmp_nocase(str, "meters") == 0) { + return DU_meters; + + } else if (cmp_nocase(str, "km") == 0 || cmp_nocase(str, "kilometers") == 0) { + return DU_kilometers; + + } else if (cmp_nocase(str, "yd") == 0 || cmp_nocase(str, "yards") == 0) { + return DU_yards; + + } else if (cmp_nocase(str, "ft") == 0 || cmp_nocase(str, "feet") == 0) { + return DU_feet; + + } else if (cmp_nocase(str, "in") == 0 || cmp_nocase(str, "inches") == 0) { + return DU_inches; + + } else if (cmp_nocase(str, "nmi") == 0 || + cmp_nocase(str, "nm") == 0 || + cmp_nocase_uh(str, "nautical_miles") == 0) { + return DU_nautical_miles; + + } else if (cmp_nocase(str, "mi") == 0 || + cmp_nocase(str, "miles") == 0 || + cmp_nocase_uh(str, "statute_miles") == 0) { + return DU_statute_miles; + + } else { + return DU_invalid; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: unit_scale +// Description: Returns the number of the indicated unit per each +// centimeter. This internal function is used to +// implement convert_units(), below. +//////////////////////////////////////////////////////////////////// +static double unit_scale(DistanceUnit unit) { + switch (unit) { + case DU_millimeters: + return 0.1; + + case DU_centimeters: + return 1.0; + + case DU_meters: + return 100.0; + + case DU_kilometers: + return 100000.0; + + case DU_yards: + return 3.0 * 12.0 * 2.54; + + case DU_feet: + return 12.0 * 2.54; + + case DU_inches: + return 2.54; + + case DU_nautical_miles: + // This is the U.S. definition. + return 185200.0; + + case DU_statute_miles: + return 5280.0 * 12.0 * 2.54; + + case DU_invalid: + return 1.0; + } + + return 1.0; +} + +//////////////////////////////////////////////////////////////////// +// Function: convert_units +// Description: Returns the scaling factor that must be applied to +// convert from units of "from" to "to". +//////////////////////////////////////////////////////////////////// +double convert_units(DistanceUnit from, DistanceUnit to) { + return unit_scale(to) / unit_scale(from); +} diff --git a/pandatool/src/progbase/distanceUnit.h b/pandatool/src/progbase/distanceUnit.h new file mode 100644 index 0000000000..3d5cfb10a8 --- /dev/null +++ b/pandatool/src/progbase/distanceUnit.h @@ -0,0 +1,35 @@ +// Filename: distanceUnit.h +// Created by: drose (17Apr01) +// +//////////////////////////////////////////////////////////////////// + +#ifndef DISTANCEUNIT_H +#define DISTANCEUNIT_H + +#include + +//////////////////////////////////////////////////////////////////// +// Enum : DistanceUnit +// Description : This enumerated type lists all the kinds of units +// we're likely to come across in model conversion +// programs. +//////////////////////////////////////////////////////////////////// +enum DistanceUnit { + DU_millimeters, + DU_centimeters, + DU_meters, + DU_kilometers, + DU_yards, + DU_feet, + DU_inches, + DU_nautical_miles, + DU_statute_miles, + DU_invalid +}; + +ostream &operator << (ostream &out, DistanceUnit unit); +DistanceUnit string_distance_unit(const string &str); + +double convert_units(DistanceUnit from, DistanceUnit to); + +#endif diff --git a/pandatool/src/progbase/programBase.cxx b/pandatool/src/progbase/programBase.cxx index b1378b4e46..db95f5f0ad 100644 --- a/pandatool/src/progbase/programBase.cxx +++ b/pandatool/src/progbase/programBase.cxx @@ -904,6 +904,28 @@ dispatch_coordinate_system(const string &opt, const string &arg, void *var) { return true; } +//////////////////////////////////////////////////////////////////// +// Function: ProgramBase::dispatch_units +// Access: Protected, Static +// Description: Standard dispatch function for an option that takes +// one parameter, which is to be interpreted as a +// unit of distance measurement. The data pointer is to +// a DistanceUnit variable. +//////////////////////////////////////////////////////////////////// +bool ProgramBase:: +dispatch_units(const string &opt, const string &arg, void *var) { + DistanceUnit *ip = (DistanceUnit *)var; + (*ip) = string_distance_unit(arg); + + if ((*ip) == DU_invalid) { + nout << "Invalid units for -" << opt << ": " << arg << "\n" + << "Valid units are mm, cm, m, km, yd, ft, in, nmi, and mi.\n"; + return false; + } + + return true; +} + //////////////////////////////////////////////////////////////////// // Function: ProgramBase::handle_help_option // Access: Protected, Static diff --git a/pandatool/src/progbase/programBase.h b/pandatool/src/progbase/programBase.h index 5d9968f45f..41fc3450d4 100644 --- a/pandatool/src/progbase/programBase.h +++ b/pandatool/src/progbase/programBase.h @@ -8,6 +8,8 @@ #include +#include "distanceUnit.h" + #include #include @@ -80,6 +82,7 @@ protected: static bool dispatch_filename(const string &opt, const string &arg, void *var); static bool dispatch_search_path(const string &opt, const string &arg, void *var); static bool dispatch_coordinate_system(const string &opt, const string &arg, void *var); + static bool dispatch_units(const string &opt, const string &arg, void *var); static bool handle_help_option(const string &opt, const string &arg, void *);