From 0b8e32771ee5595df29ade36a77b95cfb37872dc Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 24 Apr 2001 00:19:17 +0000 Subject: [PATCH] *** empty log message *** --- pandatool/src/eggbase/eggWriter.cxx | 8 +- pandatool/src/eggbase/somethingToEgg.cxx | 59 +++- pandatool/src/eggbase/somethingToEgg.h | 9 + pandatool/src/flt/Sources.pp | 2 +- pandatool/src/flt/fltHeader.cxx | 30 ++ pandatool/src/flt/fltHeader.h | 2 + pandatool/src/flt/fltRecord.cxx | 3 +- pandatool/src/fltegg/fltToEggConverter.I | 35 ++- pandatool/src/fltegg/fltToEggConverter.cxx | 322 ++++++++++++++++++--- pandatool/src/fltegg/fltToEggConverter.h | 27 +- pandatool/src/fltprogs/fltToEgg.cxx | 148 +++++++++- pandatool/src/fltprogs/fltToEgg.h | 13 +- pandatool/src/progbase/distanceUnit.cxx | 118 ++++++-- pandatool/src/progbase/distanceUnit.h | 3 + 14 files changed, 678 insertions(+), 101 deletions(-) diff --git a/pandatool/src/eggbase/eggWriter.cxx b/pandatool/src/eggbase/eggWriter.cxx index 284babbd65..1580e2f78a 100644 --- a/pandatool/src/eggbase/eggWriter.cxx +++ b/pandatool/src/eggbase/eggWriter.cxx @@ -104,24 +104,24 @@ add_normals_options() { static NormalsMode preserve = NM_preserve; add_option - ("no", "", 49, + ("no", "", 48, "Strip all normals.", &EggWriter::dispatch_normals, NULL, &strip); add_option - ("np", "", 49, + ("np", "", 48, "Strip existing normals and redefine polygon normals.", &EggWriter::dispatch_normals, NULL, &polygon); add_option - ("nv", "threshold", 49, + ("nv", "threshold", 48, "Strip existing normals and redefine vertex normals. Consider an edge " "between adjacent polygons to be smooth if the angle between them " "is less than threshold degrees.", &EggWriter::dispatch_normals, NULL, &vertex); add_option - ("nn", "", 49, + ("nn", "", 48, "Preserve normals exactly as they are. This is the default.", &EggWriter::dispatch_normals, NULL, &preserve); } diff --git a/pandatool/src/eggbase/somethingToEgg.cxx b/pandatool/src/eggbase/somethingToEgg.cxx index b3ffb223df..d54b8874a9 100644 --- a/pandatool/src/eggbase/somethingToEgg.cxx +++ b/pandatool/src/eggbase/somethingToEgg.cxx @@ -34,12 +34,49 @@ SomethingToEgg(const string &format_name, redescribe_option ("cs", "Specify the coordinate system of the input " + _format_name + - "file. Normally, this can inferred from the file itself."); + " file. Normally, this can inferred from the file itself."); + + add_option + ("ui", "units", 40, + "Specify the units of the input " + _format_name + + " file. Normally, this can be inferred from the file itself.", + &SomethingToEgg::dispatch_units, NULL, &_input_units); + + add_option + ("uo", "units", 40, + "Specify the units of the resulting egg file. If this is " + "specified, the vertices in the egg file will be scaled as " + "necessary to make the appropriate units conversion; otherwise, " + "the vertices in the input file will be converted exactly as they are.", + &SomethingToEgg::dispatch_units, NULL, &_output_units); + + _input_units = DU_invalid; + _output_units = DU_invalid; + + add_transform_options(); +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::apply_units_scale +// Access: Protected +// Description: Applies the scale indicated by the input and output +// units to the indicated egg file. This is normally +// done automatically when the file is written out. +//////////////////////////////////////////////////////////////////// +void SomethingToEgg:: +apply_units_scale(EggData &data) { + if (_output_units != DU_invalid && _input_units != DU_invalid && + _input_units != _output_units) { + nout << "Converting from " << format_long_unit(_input_units) + << " to " << format_long_unit(_output_units) << "\n"; + double scale = convert_units(_input_units, _output_units); + data.transform(LMatrix4d::scale_mat(scale)); + } } //////////////////////////////////////////////////////////////////// // Function: SomethingToEgg::handle_args -// Access: Public +// Access: Protected // Description: //////////////////////////////////////////////////////////////////// bool SomethingToEgg:: @@ -85,3 +122,21 @@ handle_args(Args &args) { return true; } + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::post_process_egg_file +// Access: Protected, Virtual +// Description: Performs any processing of the egg file that is +// appropriate before writing it out. This includes any +// normal adjustments the user requested via -np, etc. +// +// Normally, you should not need to call this function +// directly; write_egg_file() calls it for you. You +// should call this only if you do not use +// write_egg_file() to write out the resulting egg file. +//////////////////////////////////////////////////////////////////// +void SomethingToEgg:: +post_process_egg_file() { + apply_units_scale(_data); + EggConverter::post_process_egg_file(); +} diff --git a/pandatool/src/eggbase/somethingToEgg.h b/pandatool/src/eggbase/somethingToEgg.h index b15ae826bc..715d0d8792 100644 --- a/pandatool/src/eggbase/somethingToEgg.h +++ b/pandatool/src/eggbase/somethingToEgg.h @@ -10,6 +10,9 @@ #include "eggConverter.h" +#include + + //////////////////////////////////////////////////////////////////// // Class : SomethingToEgg // Description : This is the general base class for a file-converter @@ -24,9 +27,15 @@ public: bool allow_stdout = true); protected: + void apply_units_scale(EggData &data); + virtual bool handle_args(Args &args); + virtual void post_process_egg_file(); Filename _input_filename; + + DistanceUnit _input_units; + DistanceUnit _output_units; }; #endif diff --git a/pandatool/src/flt/Sources.pp b/pandatool/src/flt/Sources.pp index 9d90886a66..7b9bb7903f 100644 --- a/pandatool/src/flt/Sources.pp +++ b/pandatool/src/flt/Sources.pp @@ -1,6 +1,6 @@ #begin ss_lib_target #define TARGET flt - #define LOCAL_LIBS pandatoolbase + #define LOCAL_LIBS progbase pandatoolbase #define OTHER_LIBS \ mathutil:c linmath:c putil:c express:c panda:m dtoolconfig dtool #define UNIX_SYS_LIBS \ diff --git a/pandatool/src/flt/fltHeader.cxx b/pandatool/src/flt/fltHeader.cxx index 22cebe2729..5e7d56ff38 100644 --- a/pandatool/src/flt/fltHeader.cxx +++ b/pandatool/src/flt/fltHeader.cxx @@ -306,6 +306,36 @@ check_version() const { return true; } +//////////////////////////////////////////////////////////////////// +// Function: FltHeader::get_units +// Access: Public +// Description: Returns the units indicated by the flt header, or +// DU_invalid if the units in the header are not +// understood. +//////////////////////////////////////////////////////////////////// +DistanceUnit FltHeader:: +get_units() const { + switch (_vertex_units) { + case FltHeader::U_meters: + return DU_meters; + + case FltHeader::U_kilometers: + return DU_kilometers; + + case FltHeader::U_feet: + return DU_feet; + + case FltHeader::U_inches: + return DU_inches; + + case FltHeader::U_nautical_miles: + return DU_nautical_miles; + } + + // Unknown units. + return DU_invalid; +} + //////////////////////////////////////////////////////////////////// // Function: FltHeader::has_instance // Access: Public diff --git a/pandatool/src/flt/fltHeader.h b/pandatool/src/flt/fltHeader.h index 8d2ab15062..6925d844a6 100644 --- a/pandatool/src/flt/fltHeader.h +++ b/pandatool/src/flt/fltHeader.h @@ -19,6 +19,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////// // Class : FltHeader @@ -133,6 +134,7 @@ public: static double max_flt_version(); bool check_version() const; + DistanceUnit get_units() const; // Accessors into the instance pool. bool has_instance(int instance_index) const; diff --git a/pandatool/src/flt/fltRecord.cxx b/pandatool/src/flt/fltRecord.cxx index 3f90f15850..3b9e0d82a5 100644 --- a/pandatool/src/flt/fltRecord.cxx +++ b/pandatool/src/flt/fltRecord.cxx @@ -257,7 +257,8 @@ has_comment() const { //////////////////////////////////////////////////////////////////// // Function: FltRecord::get_comment // Access: Public -// Description: Retrieves the comment for this record. +// Description: Retrieves the comment for this record, or empty +// string if the record has no comment. //////////////////////////////////////////////////////////////////// const string &FltRecord:: get_comment() const { diff --git a/pandatool/src/fltegg/fltToEggConverter.I b/pandatool/src/fltegg/fltToEggConverter.I index 11644f3c18..0612945144 100644 --- a/pandatool/src/fltegg/fltToEggConverter.I +++ b/pandatool/src/fltegg/fltToEggConverter.I @@ -14,24 +14,37 @@ INLINE FltToEggConverter:: } //////////////////////////////////////////////////////////////////// -// Function: FltToEggConverter::set_input_units +// Function: FltToEggConverter::set_texture_path_convert // 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. +// Description: Sets the mode for converting texture paths extracted +// from the flt file. If this is PC_relative, the +// texture paths are made relative to the indicated +// directory; if it is PC_absolute, they are made +// absolute to the indicated directory. PC_unchanged +// leaves them alone (and the directory, if specified, +// is ignored). //////////////////////////////////////////////////////////////////// INLINE void FltToEggConverter:: -set_input_units(DistanceUnit input_units) { - _input_units = input_units; +set_texture_path_convert(PathConvert tpc, + const Filename &tpc_directory) { + _tpc = tpc; + _tpc_directory = tpc_directory; } //////////////////////////////////////////////////////////////////// -// Function: FltToEggConverter::set_output_units +// Function: FltToEggConverter::set_model_path_convert // Access: Public -// Description: Sets the units to generate in the resulting egg file. -// If this is unset, no units conversion is performed. +// Description: Sets the mode for converting model paths extracted +// from the flt file. If this is PC_relative, the +// model paths are made relative to the indicated +// directory; if it is PC_absolute, they are made +// absolute to the indicated directory. PC_unchanged +// leaves them alone (and the directory, if specified, +// is ignored). //////////////////////////////////////////////////////////////////// INLINE void FltToEggConverter:: -set_output_units(DistanceUnit output_units) { - _output_units = output_units; +set_model_path_convert(PathConvert mpc, + const Filename &mpc_directory) { + _mpc = mpc; + _mpc_directory = mpc_directory; } diff --git a/pandatool/src/fltegg/fltToEggConverter.cxx b/pandatool/src/fltegg/fltToEggConverter.cxx index 54e7ac787e..ba27bfcc9e 100644 --- a/pandatool/src/fltegg/fltToEggConverter.cxx +++ b/pandatool/src/fltegg/fltToEggConverter.cxx @@ -33,8 +33,8 @@ //////////////////////////////////////////////////////////////////// FltToEggConverter:: FltToEggConverter(EggData &egg_data) : _egg_data(egg_data) { - _input_units = DU_invalid; - _output_units = DU_invalid; + _tpc = PC_unchanged; + _mpc = PC_unchanged; } //////////////////////////////////////////////////////////////////// @@ -47,30 +47,6 @@ bool FltToEggConverter:: convert_flt(const FltHeader *flt_header) { _error = false; _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"); @@ -245,7 +221,7 @@ convert_bead(const FltBead *flt_bead, FltToEggLevelState &state) { state._egg_parent->add_child(egg_group); set_transform(flt_bead, egg_group); - parse_comment(flt_bead, "anonymous", egg_group); + parse_comment(flt_bead, egg_group); FltToEggLevelState next_state(state); next_state._egg_parent = egg_group; @@ -312,7 +288,12 @@ convert_ext_ref(const FltExternalReference *flt_ext, FltToEggLevelState &state) EggGroupNode *egg_parent = state.get_synthetic_group("", flt_ext->get_transform()); - Filename filename = flt_ext->get_ref_filename(); + Filename filename = + convert_path(flt_ext->_filename, + flt_ext->get_ref_filename(), + _mpc_directory, + _mpc); + filename.set_extension("egg"); EggExternalReference *egg_ref = new EggExternalReference("", filename); @@ -335,7 +316,8 @@ setup_geometry(const FltGeometry *flt_geom, FltToEggLevelState &state, // Determine what the appropriate parent will be. EggGroupNode *egg_parent = - state.get_synthetic_group(flt_geom->get_id(), flt_geom->get_transform()); + state.get_synthetic_group(flt_geom->get_id(), flt_geom->get_transform(), + flt_geom->_billboard_type); // Create a new state to reflect the new parent. FltToEggLevelState next_state(state); @@ -499,7 +481,7 @@ set_transform(const FltBead *flt_bead, EggGroup *egg_group) { //////////////////////////////////////////////////////////////////// bool FltToEggConverter:: parse_comment(const FltBeadID *flt_bead, EggNode *egg_node) { - return parse_comment(flt_bead, flt_bead->get_id(), egg_node); + return parse_comment(flt_bead->get_comment(), flt_bead->get_id(), egg_node); } //////////////////////////////////////////////////////////////////// @@ -512,13 +494,40 @@ parse_comment(const FltBeadID *flt_bead, EggNode *egg_node) { // true). //////////////////////////////////////////////////////////////////// bool FltToEggConverter:: -parse_comment(const FltRecord *flt_record, const string &name, +parse_comment(const FltBead *flt_bead, EggNode *egg_node) { + return parse_comment(flt_bead->get_comment(), "anonymous", egg_node); +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::parse_comment +// Access: Private +// Description: Scans the comment on this record for " { ... }" +// and parses the enclosed string as if it appeared in +// the egg file. Returns true on success, false on +// syntax error (in which case _error is also set to +// true). +//////////////////////////////////////////////////////////////////// +bool FltToEggConverter:: +parse_comment(const FltTexture *flt_texture, EggNode *egg_node) { + return parse_comment(flt_texture->_comment, flt_texture->_filename, egg_node); +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::parse_comment +// Access: Private +// Description: Scans the comment on this record for " { ... }" +// and parses the enclosed string as if it appeared in +// the egg file. Returns true on success, false on +// syntax error (in which case _error is also set to +// true). +//////////////////////////////////////////////////////////////////// +bool FltToEggConverter:: +parse_comment(const string &comment, const string &name, EggNode *egg_node) { - if (!flt_record->has_comment()) { + if (comment.empty()) { // No comment. return true; } - string comment = flt_record->get_comment(); // Scan for . static const string egg_str = ""; @@ -574,6 +583,59 @@ parse_comment(const FltRecord *flt_record, const string &name, return true; } +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::convert_path +// Access: Private, Static +// Description: Converts the pathname reference by the flt file as +// requested. This may either make it absolute, +// relative, or leave it alone. +// +// orig_filename is the filename as it actually appeared +// in the flt file; as_found is the full pathname to the +// file as it actually exists on disk, assuming it was +// found on the search path. rel_dir is the directory +// to make the pathname relative to in the case of +// PC_relative or PC_rel_abs. +//////////////////////////////////////////////////////////////////// +Filename FltToEggConverter:: +convert_path(const Filename &orig_filename, const Filename &as_found, + const Filename &rel_dir, PathConvert path_convert) { + Filename result; + + switch (path_convert) { + case PC_relative: + result = as_found; + if (!result.make_relative_to(rel_dir)) { + nout << "Cannot make " << result << " relative to " << rel_dir << "\n"; + } + return result; + + case PC_absolute: + result = as_found; + if (as_found.is_local()) { + nout << "Warning: file " << as_found << " not found; cannot make absolute.\n"; + return result; + } + result.make_absolute(); + return result; + + case PC_rel_abs: + result = as_found; + if (!result.make_relative_to(rel_dir)) { + nout << "Cannot make " << result << " relative to " << rel_dir << "\n"; + } + result = Filename(rel_dir, result); + return result; + + case PC_unchanged: + return orig_filename; + } + + // Error case. + nout << "Invalid PathConvert type: " << (int)path_convert << "\n"; + return orig_filename; +} + //////////////////////////////////////////////////////////////////// // Function: FltToEggConverter::make_egg_vertex // Access: Private @@ -619,12 +681,202 @@ make_egg_texture(const FltTexture *flt_texture) { // Create a new one. string tref_name = format_string(flt_texture->_pattern_index); - Filename filename = flt_texture->get_texture_filename(); + Filename filename = + convert_path(flt_texture->_filename, + flt_texture->get_texture_filename(), + _tpc_directory, + _tpc); + PT(EggTexture) egg_texture = new EggTexture(tref_name, filename); _textures.insert(Textures::value_type(flt_texture, egg_texture)); - ////*** Texture properties. + // Set up the texture properties. + switch (flt_texture->_min_filter) { + case FltTexture::MN_point: + egg_texture->set_minfilter(EggTexture::FT_nearest); + break; + + case FltTexture::MN_bilinear: + egg_texture->set_minfilter(EggTexture::FT_linear); + break; + + case FltTexture::MN_mipmap_point: + egg_texture->set_minfilter(EggTexture::FT_nearest_mipmap_nearest); + break; + + case FltTexture::MN_mipmap_linear: + egg_texture->set_minfilter(EggTexture::FT_nearest_mipmap_linear); + break; + + case FltTexture::MN_mipmap_bilinear: + egg_texture->set_minfilter(EggTexture::FT_linear_mipmap_nearest); + break; + + case FltTexture::MN_mipmap_trilinear: + case FltTexture::MN_OB_mipmap: + egg_texture->set_minfilter(EggTexture::FT_linear_mipmap_linear); + break; + + case FltTexture::MN_bicubic: + case FltTexture::MN_bilinear_gequal: + case FltTexture::MN_bilinear_lequal: + case FltTexture::MN_bicubic_gequal: + case FltTexture::MN_bicubic_lequal: + // Not supported. + break; + } + + switch (flt_texture->_mag_filter) { + case FltTexture::MG_point: + egg_texture->set_magfilter(EggTexture::FT_nearest); + break; + + case FltTexture::MG_bilinear: + egg_texture->set_magfilter(EggTexture::FT_linear); + break; + + case FltTexture::MG_bicubic: + case FltTexture::MG_sharpen: + case FltTexture::MG_add_detail: + case FltTexture::MG_modulate_detail: + case FltTexture::MG_bilinear_gequal: + case FltTexture::MG_bilinear_lequal: + case FltTexture::MG_bicubic_gequal: + case FltTexture::MG_bicubic_lequal: + // Not supported. + break; + } + + switch (flt_texture->_repeat) { + case FltTexture::RT_repeat: + egg_texture->set_wrap_mode(EggTexture::WM_repeat); + break; + + case FltTexture::RT_clamp: + egg_texture->set_wrap_mode(EggTexture::WM_clamp); + break; + } + + switch (flt_texture->_repeat_u) { + case FltTexture::RT_repeat: + egg_texture->set_wrap_u(EggTexture::WM_repeat); + break; + + case FltTexture::RT_clamp: + egg_texture->set_wrap_u(EggTexture::WM_clamp); + break; + } + + switch (flt_texture->_repeat_v) { + case FltTexture::RT_repeat: + egg_texture->set_wrap_v(EggTexture::WM_repeat); + break; + + case FltTexture::RT_clamp: + egg_texture->set_wrap_v(EggTexture::WM_clamp); + break; + } + + switch (flt_texture->_env_type) { + case FltTexture::ET_modulate: + egg_texture->set_env_type(EggTexture::ET_modulate); + break; + + case FltTexture::ET_decal: + egg_texture->set_env_type(EggTexture::ET_decal); + break; + + case FltTexture::ET_blend: + case FltTexture::ET_color: + // Not supported. + break; + } + + switch (flt_texture->_internal_format) { + case FltTexture::IF_default: + break; + + case FltTexture::IF_i_12a_4: + case FltTexture::IF_ia_12: + case FltTexture::IF_ia_8: + egg_texture->set_format(EggTexture::F_luminance_alpha); + break; + + case FltTexture::IF_rgb_5: + egg_texture->set_format(EggTexture::F_rgb5); + break; + + case FltTexture::IF_rgba_4: + egg_texture->set_format(EggTexture::F_rgba4); + break; + + + case FltTexture::IF_rgba_8: + egg_texture->set_format(EggTexture::F_rgba8); + break; + + case FltTexture::IF_rgba_12: + egg_texture->set_format(EggTexture::F_rgba12); + break; + + case FltTexture::IF_i_16: + if (flt_texture->_intensity_is_alpha) { + egg_texture->set_format(EggTexture::F_alpha); + } else { + egg_texture->set_format(EggTexture::F_luminance); + } + break; + + case FltTexture::IF_rgb_12: + egg_texture->set_format(EggTexture::F_rgb12); + break; + } + + switch (flt_texture->_mag_filter_alpha) { + case FltTexture::MG_point: + egg_texture->set_magfilteralpha(EggTexture::FT_nearest); + break; + + case FltTexture::MG_bilinear: + egg_texture->set_magfilteralpha(EggTexture::FT_linear); + break; + + case FltTexture::MG_bicubic: + case FltTexture::MG_sharpen: + case FltTexture::MG_add_detail: + case FltTexture::MG_modulate_detail: + case FltTexture::MG_bilinear_gequal: + case FltTexture::MG_bilinear_lequal: + case FltTexture::MG_bicubic_gequal: + case FltTexture::MG_bicubic_lequal: + // Not supported. + break; + } + + switch (flt_texture->_mag_filter_color) { + case FltTexture::MG_point: + egg_texture->set_magfiltercolor(EggTexture::FT_nearest); + break; + + case FltTexture::MG_bilinear: + egg_texture->set_magfiltercolor(EggTexture::FT_linear); + break; + + case FltTexture::MG_bicubic: + case FltTexture::MG_sharpen: + case FltTexture::MG_add_detail: + case FltTexture::MG_modulate_detail: + case FltTexture::MG_bilinear_gequal: + case FltTexture::MG_bilinear_lequal: + case FltTexture::MG_bicubic_gequal: + case FltTexture::MG_bicubic_lequal: + // Not supported. + break; + } + + + parse_comment(flt_texture, egg_texture); return egg_texture; } diff --git a/pandatool/src/fltegg/fltToEggConverter.h b/pandatool/src/fltegg/fltToEggConverter.h index ef018b80d8..05611bfefe 100644 --- a/pandatool/src/fltegg/fltToEggConverter.h +++ b/pandatool/src/fltegg/fltToEggConverter.h @@ -45,8 +45,16 @@ public: FltToEggConverter(EggData &egg_data); INLINE ~FltToEggConverter(); - INLINE void set_input_units(DistanceUnit input_units); - INLINE void set_output_units(DistanceUnit output_units); + enum PathConvert { + PC_relative, + PC_absolute, + PC_rel_abs, + PC_unchanged + }; + INLINE void set_texture_path_convert(PathConvert tpc, + const Filename &tpc_directory = Filename()); + INLINE void set_model_path_convert(PathConvert mpc, + const Filename &mpc_directory = Filename()); bool convert_flt(const FltHeader *flt_header); @@ -71,14 +79,23 @@ private: void set_transform(const FltBead *flt_bead, EggGroup *egg_group); bool parse_comment(const FltBeadID *flt_bead, EggNode *egg_node); - bool parse_comment(const FltRecord *flt_record, const string &name, + bool parse_comment(const FltBead *flt_bead, EggNode *egg_node); + bool parse_comment(const FltTexture *flt_texture, EggNode *egg_node); + bool parse_comment(const string &comment, const string &name, EggNode *egg_node); + static Filename convert_path(const Filename &orig_filename, + const Filename &as_found, + const Filename &rel_dir, + PathConvert path_convert); + PT(EggVertex) make_egg_vertex(const FltVertex *flt_vertex); PT(EggTexture) make_egg_texture(const FltTexture *flt_texture); - DistanceUnit _input_units; - DistanceUnit _output_units; + PathConvert _tpc; + Filename _tpc_directory; + PathConvert _mpc; + Filename _mpc_directory; EggData &_egg_data; CPT(FltHeader) _flt_header; diff --git a/pandatool/src/fltprogs/fltToEgg.cxx b/pandatool/src/fltprogs/fltToEgg.cxx index be4bbc62a6..33373cba28 100644 --- a/pandatool/src/fltprogs/fltToEgg.cxx +++ b/pandatool/src/fltprogs/fltToEgg.cxx @@ -19,21 +19,83 @@ FltToEgg() : add_normals_options(); set_program_description - ("This program converts MultiGen OpenFlight (.flt) files to egg. " - "Nothing fancy yet."); + ("This program converts MultiGen OpenFlight (.flt) files to egg. Most " + "features of MultiGen that are also recognized by egg are supported."); add_option - ("tp", "path", 0, - "Add the indicated colon-delimited paths to the path that is searched " - "for textures referenced by the flt file. This " - "option may also be repeated to add multiple paths.", - &FltToEgg::dispatch_search_path, NULL, &_texture_path); + ("rt", "", 0, + "Convert texture filenames to relative pathnames, relative to the " + "directory specified by -rd.", + &FltToEgg::dispatch_path_convert_relative, NULL, &_texture_path_convert); + + add_option + ("rta", "", 0, + "Convert texture filenames to absolute pathnames.", + &FltToEgg::dispatch_path_convert_absolute, NULL, &_texture_path_convert); + + add_option + ("rtA", "", 0, + "Convert texture filenames to absolute pathnames that begin with the " + "prefix specified by -rd.", + &FltToEgg::dispatch_path_convert_rel_abs, NULL, &_texture_path_convert); + + add_option + ("rtu", "", 0, + "Leave texture filenames unchanged. They will be relative if they " + "are relative in the flt file, or absolute if they are absolute in " + "the flt file.", + &FltToEgg::dispatch_path_convert_unchanged, NULL, &_texture_path_convert); + + add_option + ("re", "", 0, + "Convert model filenames (external references) to relative pathnames, " + "relative to the directory specified by -rd.", + &FltToEgg::dispatch_path_convert_relative, NULL, &_model_path_convert); + + add_option + ("rea", "", 0, + "Convert model filenames to absolute pathnames.", + &FltToEgg::dispatch_path_convert_absolute, NULL, &_model_path_convert); + + add_option + ("reA", "", 0, + "Convert model filenames to absolute pathnames that begin with the " + "prefix specified by -rd.", + &FltToEgg::dispatch_path_convert_rel_abs, NULL, &_model_path_convert); + + add_option + ("reu", "", 0, + "Leave model filenames unchanged. They will be relative if they " + "are relative in the flt file, or absolute if they are absolute in " + "the flt file.", + &FltToEgg::dispatch_path_convert_unchanged, NULL, &_model_path_convert); + + add_option + ("rd", "dir", 0, + "Specify the directory to make relative to. This is the " + "directory that all pathnames given in the flt file will be " + "rewritten to be relative to, if -re or -rt is given. It is " + "ignored if one of these options is not given. If omitted, it " + "is taken from the source filename.", + &FltToEgg::dispatch_string, &_got_make_rel_dir, &_make_rel_dir); + + add_option + ("rs", "path", 0, + "A search path for textures and external file references. This " + "is a colon-separated set of directories that will be searched " + "for filenames that are not fully specified in the flt file. It " + "is unrelated to -re and -rt, and is used only if the flt file " + "does not store absolute pathnames. The directory containing " + "the source filename is always implicitly included.", + &FltToEgg::dispatch_search_path, NULL, &_search_path); redescribe_option ("cs", "Specify the coordinate system of the input " + _format_name + - "file. Normally, this is z-up."); + " file. Normally, this is z-up."); + _texture_path_convert = FltToEggConverter::PC_unchanged; + _model_path_convert = FltToEggConverter::PC_unchanged; _coordinate_system = CS_zup_right; } @@ -44,8 +106,13 @@ FltToEgg() : //////////////////////////////////////////////////////////////////// void FltToEgg:: run() { + if (!_got_make_rel_dir) { + _make_rel_dir = _input_filename.get_dirname(); + } + PT(FltHeader) header = new FltHeader; - header->set_texture_path(_texture_path); + header->set_texture_path(_search_path); + header->set_model_path(_search_path); nout << "Reading " << _input_filename << "\n"; FltError result = header->read_flt(_input_filename); @@ -58,7 +125,14 @@ run() { _data.set_coordinate_system(_coordinate_system); + if (_input_units == DU_invalid) { + _input_units = header->get_units(); + } + FltToEggConverter converter(_data); + converter.set_texture_path_convert(_texture_path_convert, _make_rel_dir); + converter.set_model_path_convert(_model_path_convert, _make_rel_dir); + if (!converter.convert_flt(header)) { nout << "Errors in conversion.\n"; exit(1); @@ -68,6 +142,62 @@ run() { } +//////////////////////////////////////////////////////////////////// +// Function: FltToEgg::dispatch_path_convert_relative +// Access: Protected, Static +// Description: Dispatch function to set the given path convert mode +// to PC_relative. var is a pointer to a +// FltToEggConverter::PathConvert variable. +//////////////////////////////////////////////////////////////////// +bool FltToEgg:: +dispatch_path_convert_relative(const string &opt, const string &, void *var) { + FltToEggConverter::PathConvert *ip = (FltToEggConverter::PathConvert *)var; + (*ip) = FltToEggConverter::PC_relative; + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEgg::dispatch_path_convert_absolute +// Access: Protected, Static +// Description: Dispatch function to set the given path convert mode +// to PC_absolute. var is a pointer to a +// FltToEggConverter::PathConvert variable. +//////////////////////////////////////////////////////////////////// +bool FltToEgg:: +dispatch_path_convert_absolute(const string &opt, const string &, void *var) { + FltToEggConverter::PathConvert *ip = (FltToEggConverter::PathConvert *)var; + (*ip) = FltToEggConverter::PC_absolute; + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEgg::dispatch_path_convert_rel_abs +// Access: Protected, Static +// Description: Dispatch function to set the given path convert mode +// to PC_rel_abs. var is a pointer to a +// FltToEggConverter::PathConvert variable. +//////////////////////////////////////////////////////////////////// +bool FltToEgg:: +dispatch_path_convert_rel_abs(const string &opt, const string &, void *var) { + FltToEggConverter::PathConvert *ip = (FltToEggConverter::PathConvert *)var; + (*ip) = FltToEggConverter::PC_rel_abs; + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: FltToEgg::dispatch_path_convert_unchanged +// Access: Protected, Static +// Description: Dispatch function to set the given path convert mode +// to PC_unchanged. var is a pointer to a +// FltToEggConverter::PathConvert variable. +//////////////////////////////////////////////////////////////////// +bool FltToEgg:: +dispatch_path_convert_unchanged(const string &opt, const string &, void *var) { + FltToEggConverter::PathConvert *ip = (FltToEggConverter::PathConvert *)var; + (*ip) = FltToEggConverter::PC_unchanged; + return true; +} + int main(int argc, char *argv[]) { FltToEgg prog; prog.parse_command_line(argc, argv); diff --git a/pandatool/src/fltprogs/fltToEgg.h b/pandatool/src/fltprogs/fltToEgg.h index ff58ea2e60..e12b794f0a 100644 --- a/pandatool/src/fltprogs/fltToEgg.h +++ b/pandatool/src/fltprogs/fltToEgg.h @@ -9,6 +9,7 @@ #include #include +#include #include @@ -24,7 +25,17 @@ public: void run(); protected: - DSearchPath _texture_path; + static bool dispatch_path_convert_relative(const string &opt, const string &arg, void *var); + static bool dispatch_path_convert_absolute(const string &opt, const string &arg, void *var); + static bool dispatch_path_convert_rel_abs(const string &opt, const string &arg, void *var); + static bool dispatch_path_convert_unchanged(const string &opt, const string &arg, void *var); + + + DSearchPath _search_path; + FltToEggConverter::PathConvert _texture_path_convert; + FltToEggConverter::PathConvert _model_path_convert; + Filename _make_rel_dir; + bool _got_make_rel_dir; }; #endif diff --git a/pandatool/src/progbase/distanceUnit.cxx b/pandatool/src/progbase/distanceUnit.cxx index 06aa2c0f84..b84da70ad5 100644 --- a/pandatool/src/progbase/distanceUnit.cxx +++ b/pandatool/src/progbase/distanceUnit.cxx @@ -6,6 +6,91 @@ #include "distanceUnit.h" #include +#include + +//////////////////////////////////////////////////////////////////// +// Function: format_abbrev_unit +// Description: Returns the string representing the common +// abbreviation for the given unit. +//////////////////////////////////////////////////////////////////// +string +format_abbrev_unit(DistanceUnit unit) { + switch (unit) { + case DU_millimeters: + return "mm"; + + case DU_centimeters: + return "cm"; + + case DU_meters: + return "m"; + + case DU_kilometers: + return "km"; + + case DU_yards: + return "yd"; + + case DU_feet: + return "ft"; + + case DU_inches: + return "in"; + + case DU_nautical_miles: + return "nmi"; + + case DU_statute_miles: + return "mi"; + + case DU_invalid: + return "invalid"; + } + nout << "**unexpected DistanceUnit value: (" << (int)unit << ")**"; + return "**"; +} + +//////////////////////////////////////////////////////////////////// +// Function: format_long_unit +// Description: Returns the string representing the full name (plural) +// for the given unit. +//////////////////////////////////////////////////////////////////// +string +format_long_unit(DistanceUnit unit) { + switch (unit) { + case DU_millimeters: + return "millimeters"; + + case DU_centimeters: + return "centimeters"; + + case DU_meters: + return "meters"; + + case DU_kilometers: + return "kilometers"; + + case DU_yards: + return "yards"; + + case DU_feet: + return "feet"; + + case DU_inches: + return "inches"; + + case DU_nautical_miles: + return "nautical miles"; + + case DU_statute_miles: + return "miles"; + + case DU_invalid: + return "invalid"; + } + nout << "**unexpected DistanceUnit value: (" << (int)unit << ")**"; + return "**"; +} //////////////////////////////////////////////////////////////////// // Function: DistanceUnit output operator @@ -13,38 +98,7 @@ //////////////////////////////////////////////////////////////////// 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 << ")**"; + return out << format_abbrev_unit(unit); } //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/progbase/distanceUnit.h b/pandatool/src/progbase/distanceUnit.h index 3d5cfb10a8..fd7aea4551 100644 --- a/pandatool/src/progbase/distanceUnit.h +++ b/pandatool/src/progbase/distanceUnit.h @@ -27,6 +27,9 @@ enum DistanceUnit { DU_invalid }; +string format_abbrev_unit(DistanceUnit unit); +string format_long_unit(DistanceUnit unit); + ostream &operator << (ostream &out, DistanceUnit unit); DistanceUnit string_distance_unit(const string &str);