diff --git a/panda/src/pnm/ppmcmap.h b/panda/src/pnm/ppmcmap.h index d52f71fe38..5f7e5e300c 100644 --- a/panda/src/pnm/ppmcmap.h +++ b/panda/src/pnm/ppmcmap.h @@ -42,4 +42,4 @@ int ppm_addtocolorhash ARGS(( colorhash_table cht, pixel* colorP, int value )); colorhash_table ppm_alloccolorhash ARGS(( void )); -void ppm_freecolorhash ARGS(( colorhash_table cht )); +void ppm_freecolorhash( colorhash_table cht ); diff --git a/pandatool/src/converter/somethingToEggConverter.I b/pandatool/src/converter/somethingToEggConverter.I index 6f962a27d2..56f56d9fdf 100644 --- a/pandatool/src/converter/somethingToEggConverter.I +++ b/pandatool/src/converter/somethingToEggConverter.I @@ -72,3 +72,54 @@ INLINE EggData &SomethingToEggConverter:: get_egg_data() { return *_egg_data; } + + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEggConverter::convert_texture_path +// Access: Public +// Description: Converts the indicated texture filename to a relative +// or absolute or whatever filename, according to _tpc +// and _tpc_directory. See convert_path(). +//////////////////////////////////////////////////////////////////// +INLINE Filename SomethingToEggConverter:: +convert_texture_path(const Filename &orig_filename) { + return convert_path(orig_filename, get_texture_path(), _tpc_directory, _tpc); +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEggConverter::convert_texture_path +// Access: Public +// Description: Converts the indicated texture filename to a relative +// or absolute or whatever filename, according to _tpc +// and _tpc_directory. See convert_path(). +//////////////////////////////////////////////////////////////////// +INLINE Filename SomethingToEggConverter:: +convert_texture_path(const Filename &orig_filename, + const DSearchPath &searchpath) { + return convert_path(orig_filename, searchpath, _tpc_directory, _tpc); +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEggConverter::convert_model_path +// Access: Public +// Description: Converts the indicated model filename to a relative +// or absolute or whatever filename, according to _mpc +// and _mpc_directory. See convert_path(). +//////////////////////////////////////////////////////////////////// +INLINE Filename SomethingToEggConverter:: +convert_model_path(const Filename &orig_filename) { + return convert_path(orig_filename, get_model_path(), _mpc_directory, _mpc); +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEggConverter::convert_model_path +// Access: Public +// Description: Converts the indicated model filename to a relative +// or absolute or whatever filename, according to _mpc +// and _mpc_directory. See convert_path(). +//////////////////////////////////////////////////////////////////// +INLINE Filename SomethingToEggConverter:: +convert_model_path(const Filename &orig_filename, + const DSearchPath &searchpath) { + return convert_path(orig_filename, searchpath, _mpc_directory, _mpc); +} diff --git a/pandatool/src/converter/somethingToEggConverter.cxx b/pandatool/src/converter/somethingToEggConverter.cxx index fe71fa7888..4dce9c265c 100644 --- a/pandatool/src/converter/somethingToEggConverter.cxx +++ b/pandatool/src/converter/somethingToEggConverter.cxx @@ -58,15 +58,25 @@ set_egg_data(EggData *egg_data, bool owns_egg_data) { // relative, or leave it alone. // // orig_filename is the filename as it actually appeared -// in the source 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. +// in the source file; searchpath is the search path to +// look for it along. rel_dir is the directory to make +// the pathname relative to in the case of PC_relative +// or PC_rel_abs. //////////////////////////////////////////////////////////////////// Filename SomethingToEggConverter:: -convert_path(const Filename &orig_filename, const Filename &as_found, +convert_path(const Filename &orig_filename, const DSearchPath &searchpath, const Filename &rel_dir, PathConvert path_convert) { + // Try to look up the filename along the search path. + Filename as_found = orig_filename; + if (!as_found.resolve_filename(searchpath)) { + // If the filename can't be found, try just the truncated + // filename. + Filename truncated = orig_filename.get_basename(); + if (truncated.resolve_filename(searchpath)) { + as_found = truncated; + } + } + Filename result; switch (path_convert) { @@ -77,8 +87,8 @@ convert_path(const Filename &orig_filename, const Filename &as_found, case PC_absolute: result = as_found; - if (as_found.is_local()) { - nout << "Warning: file " << as_found << " not found; cannot make absolute.\n"; + if (result.is_local()) { + nout << "Warning: file " << orig_filename << " not found.\n"; return result; } result.make_absolute(); diff --git a/pandatool/src/converter/somethingToEggConverter.h b/pandatool/src/converter/somethingToEggConverter.h index 950203033a..de9715a7b6 100644 --- a/pandatool/src/converter/somethingToEggConverter.h +++ b/pandatool/src/converter/somethingToEggConverter.h @@ -9,6 +9,7 @@ #include #include +#include // for get_texture_path() and get_model_path() class EggData; @@ -48,9 +49,17 @@ public: virtual bool convert_file(const Filename &filename)=0; + + INLINE Filename convert_texture_path(const Filename &orig_filename); + INLINE Filename convert_texture_path(const Filename &orig_filename, + const DSearchPath &searchpath); + INLINE Filename convert_model_path(const Filename &orig_filename); + INLINE Filename convert_model_path(const Filename &orig_filename, + const DSearchPath &searchpath); + protected: static Filename convert_path(const Filename &orig_filename, - const Filename &as_found, + const DSearchPath &searchpath, const Filename &rel_dir, PathConvert path_convert); diff --git a/pandatool/src/eggbase/somethingToEgg.cxx b/pandatool/src/eggbase/somethingToEgg.cxx index f8e49af753..ac0d4755f0 100644 --- a/pandatool/src/eggbase/somethingToEgg.cxx +++ b/pandatool/src/eggbase/somethingToEgg.cxx @@ -38,6 +38,8 @@ SomethingToEgg(const string &format_name, _input_units = DU_invalid; _output_units = DU_invalid; + _texture_path_convert = SomethingToEggConverter::PC_unchanged; + _model_path_convert = SomethingToEggConverter::PC_unchanged; } //////////////////////////////////////////////////////////////////// @@ -66,6 +68,126 @@ add_units_options() { &SomethingToEgg::dispatch_units, NULL, &_output_units); } +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::add_texture_path_options +// Access: Public +// Description: Adds -rt etc. as valid options for this program. +// These specify how the texture pathnames that appear +// in the source file should be changed for the egg +// file. +//////////////////////////////////////////////////////////////////// +void SomethingToEgg:: +add_texture_path_options() { + add_option + ("rt", "", 40, + "Convert texture filenames to relative pathnames, relative to the " + "directory specified by -rd.", + &SomethingToEgg::dispatch_path_convert_relative, NULL, &_texture_path_convert); + + add_option + ("rta", "", 40, + "Convert texture filenames to absolute pathnames.", + &SomethingToEgg::dispatch_path_convert_absolute, NULL, &_texture_path_convert); + + add_option + ("rtA", "", 40, + "Convert texture filenames to absolute pathnames that begin with the " + "prefix specified by -rd.", + &SomethingToEgg::dispatch_path_convert_rel_abs, NULL, &_texture_path_convert); + + add_option + ("rts", "", 40, + "Strip paths from texture filenames. Only the basename of the texture " + "will be preserved.", + &SomethingToEgg::dispatch_path_convert_strip, NULL, &_texture_path_convert); + + add_option + ("rtu", "", 40, + "Leave texture filenames unchanged. They will be relative if they " + "are relative in the source file, or absolute if they are absolute in " + "the source file.", + &SomethingToEgg::dispatch_path_convert_unchanged, NULL, &_texture_path_convert); +} + + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::add_model_path_options +// Access: Public +// Description: Adds -re etc. as valid options for this program. +// These specify how the model pathnames that appear +// in the source file should be changed for the egg +// file. +//////////////////////////////////////////////////////////////////// +void SomethingToEgg:: +add_model_path_options() { + add_option + ("re", "", 40, + "Convert model filenames (external references) to relative pathnames, " + "relative to the directory specified by -rd.", + &SomethingToEgg::dispatch_path_convert_relative, NULL, &_model_path_convert); + + add_option + ("rea", "", 40, + "Convert model filenames to absolute pathnames.", + &SomethingToEgg::dispatch_path_convert_absolute, NULL, &_model_path_convert); + + add_option + ("reA", "", 40, + "Convert model filenames to absolute pathnames that begin with the " + "prefix specified by -rd.", + &SomethingToEgg::dispatch_path_convert_rel_abs, NULL, &_model_path_convert); + + add_option + ("res", "", 40, + "Strip paths from model filenames. Only the basename of the model " + "will be preserved.", + &SomethingToEgg::dispatch_path_convert_strip, NULL, &_model_path_convert); + + add_option + ("reu", "", 40, + "Leave model filenames unchanged. They will be relative if they " + "are relative in the source file, or absolute if they are absolute in " + "the source file.", + &SomethingToEgg::dispatch_path_convert_unchanged, NULL, &_model_path_convert); +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::add_rel_dir_options +// Access: Public +// Description: Adds -rd. This should generally be called if +// add_texture_path_options() or +// add_model_path_options() is called. +//////////////////////////////////////////////////////////////////// +void SomethingToEgg:: +add_rel_dir_options() { + add_option + ("rd", "dir", 40, + "Specify the directory to make relative to. This is the " + "directory that all pathnames given in the source 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.", + &SomethingToEgg::dispatch_string, &_got_make_rel_dir, &_make_rel_dir); +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::add_search_path_options +// Access: Public +// Description: Adds -rs. +//////////////////////////////////////////////////////////////////// +void SomethingToEgg:: +add_search_path_options() { + 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 source file. It " + "is unrelated to -re and -rt, and is used only if the source file " + "does not store absolute pathnames. The directory containing " + "the source filename is always implicitly included.", + &SomethingToEgg::dispatch_search_path, NULL, &_search_path); +} + //////////////////////////////////////////////////////////////////// // Function: SomethingToEgg::apply_units_scale // Access: Protected @@ -133,6 +255,25 @@ handle_args(Args &args) { return true; } +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::post_command_line +// Access: Protected, Virtual +// Description: This is called after the command line has been +// completely processed, and it gives the program a +// chance to do some last-minute processing and +// validation of the options and arguments. It should +// return true if everything is fine, false if there is +// an error. +//////////////////////////////////////////////////////////////////// +bool SomethingToEgg:: +post_command_line() { + if (!_got_make_rel_dir) { + _make_rel_dir = _input_filename.get_dirname(); + } + + return EggConverter::post_command_line(); +} + //////////////////////////////////////////////////////////////////// // Function: SomethingToEgg::post_process_egg_file // Access: Protected, Virtual @@ -150,3 +291,73 @@ post_process_egg_file() { apply_units_scale(_data); EggConverter::post_process_egg_file(); } + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::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 +// SomethingToEggConverter::PathConvert variable. +//////////////////////////////////////////////////////////////////// +bool SomethingToEgg:: +dispatch_path_convert_relative(const string &opt, const string &, void *var) { + SomethingToEggConverter::PathConvert *ip = (SomethingToEggConverter::PathConvert *)var; + (*ip) = SomethingToEggConverter::PC_relative; + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::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 +// SomethingToEggConverter::PathConvert variable. +//////////////////////////////////////////////////////////////////// +bool SomethingToEgg:: +dispatch_path_convert_absolute(const string &opt, const string &, void *var) { + SomethingToEggConverter::PathConvert *ip = (SomethingToEggConverter::PathConvert *)var; + (*ip) = SomethingToEggConverter::PC_absolute; + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::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 +// SomethingToEggConverter::PathConvert variable. +//////////////////////////////////////////////////////////////////// +bool SomethingToEgg:: +dispatch_path_convert_rel_abs(const string &opt, const string &, void *var) { + SomethingToEggConverter::PathConvert *ip = (SomethingToEggConverter::PathConvert *)var; + (*ip) = SomethingToEggConverter::PC_rel_abs; + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::dispatch_path_convert_strip +// Access: Protected, Static +// Description: Dispatch function to set the given path convert mode +// to PC_strip. var is a pointer to a +// SomethingToEggConverter::PathConvert variable. +//////////////////////////////////////////////////////////////////// +bool SomethingToEgg:: +dispatch_path_convert_strip(const string &opt, const string &, void *var) { + SomethingToEggConverter::PathConvert *ip = (SomethingToEggConverter::PathConvert *)var; + (*ip) = SomethingToEggConverter::PC_strip; + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::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 +// SomethingToEggConverter::PathConvert variable. +//////////////////////////////////////////////////////////////////// +bool SomethingToEgg:: +dispatch_path_convert_unchanged(const string &opt, const string &, void *var) { + SomethingToEggConverter::PathConvert *ip = (SomethingToEggConverter::PathConvert *)var; + (*ip) = SomethingToEggConverter::PC_unchanged; + return true; +} diff --git a/pandatool/src/eggbase/somethingToEgg.h b/pandatool/src/eggbase/somethingToEgg.h index 44f9c95232..733c64e9ed 100644 --- a/pandatool/src/eggbase/somethingToEgg.h +++ b/pandatool/src/eggbase/somethingToEgg.h @@ -11,6 +11,7 @@ #include "eggConverter.h" #include +#include //////////////////////////////////////////////////////////////////// @@ -27,17 +28,37 @@ public: bool allow_stdout = true); void add_units_options(); + void add_texture_path_options(); + void add_model_path_options(); + void add_rel_dir_options(); + void add_search_path_options(); protected: void apply_units_scale(EggData &data); virtual bool handle_args(Args &args); + virtual bool post_command_line(); virtual void post_process_egg_file(); + 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_strip(const string &opt, const string &arg, void *var); + static bool dispatch_path_convert_unchanged(const string &opt, const string &arg, void *var); + + Filename _input_filename; DistanceUnit _input_units; DistanceUnit _output_units; + + SomethingToEggConverter::PathConvert _texture_path_convert; + SomethingToEggConverter::PathConvert _model_path_convert; + + Filename _make_rel_dir; + bool _got_make_rel_dir; + + DSearchPath _search_path; }; #endif diff --git a/pandatool/src/eggprogs/lwoToEgg.cxx b/pandatool/src/eggprogs/lwoToEgg.cxx index 2618ebb792..2ddba3afd9 100644 --- a/pandatool/src/eggprogs/lwoToEgg.cxx +++ b/pandatool/src/eggprogs/lwoToEgg.cxx @@ -21,6 +21,8 @@ LwoToEgg() : add_units_options(); add_normals_options(); add_transform_options(); + add_texture_path_options(); + add_rel_dir_options(); set_program_description ("This program converts Lightwave Object (.lwo) files to egg. Many " @@ -58,6 +60,8 @@ run() { LwoToEggConverter converter; converter.set_egg_data(&_data, false); + 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_file(_input_filename)) { nout << "Errors in conversion.\n"; diff --git a/pandatool/src/fltegg/fltToEggConverter.cxx b/pandatool/src/fltegg/fltToEggConverter.cxx index afcfa7de12..422fa616c0 100644 --- a/pandatool/src/fltegg/fltToEggConverter.cxx +++ b/pandatool/src/fltegg/fltToEggConverter.cxx @@ -346,10 +346,7 @@ convert_ext_ref(const FltExternalReference *flt_ext, FltToEggLevelState &state) state.get_synthetic_group("", flt_ext->get_transform()); Filename filename = - convert_path(flt_ext->_filename, - flt_ext->get_ref_filename(), - _mpc_directory, - _mpc); + convert_model_path(flt_ext->_filename, _flt_header->get_model_path()); filename.set_extension("egg"); @@ -699,10 +696,8 @@ make_egg_texture(const FltTexture *flt_texture) { // Create a new one. string tref_name = format_string(flt_texture->_pattern_index); Filename filename = - convert_path(flt_texture->_filename, - flt_texture->get_texture_filename(), - _tpc_directory, - _tpc); + convert_texture_path(flt_texture->_filename, + _flt_header->get_texture_path()); PT(EggTexture) egg_texture = new EggTexture(tref_name, filename); diff --git a/pandatool/src/fltprogs/fltToEgg.cxx b/pandatool/src/fltprogs/fltToEgg.cxx index 6a05d1baec..371f4b9be7 100644 --- a/pandatool/src/fltprogs/fltToEgg.cxx +++ b/pandatool/src/fltprogs/fltToEgg.cxx @@ -19,85 +19,20 @@ FltToEgg() : add_units_options(); add_normals_options(); add_transform_options(); + add_texture_path_options(); + add_model_path_options(); + add_rel_dir_options(); + add_search_path_options(); set_program_description ("This program converts MultiGen OpenFlight (.flt) files to egg. Most " "features of MultiGen that are also recognized by egg are supported."); - add_option - ("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."); - _texture_path_convert = FltToEggConverter::PC_unchanged; - _model_path_convert = FltToEggConverter::PC_unchanged; _coordinate_system = CS_zup_right; } @@ -108,10 +43,6 @@ 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(_search_path); header->set_model_path(_search_path); @@ -146,62 +77,6 @@ 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 e12b794f0a..0ccd16c2f9 100644 --- a/pandatool/src/fltprogs/fltToEgg.h +++ b/pandatool/src/fltprogs/fltToEgg.h @@ -23,19 +23,6 @@ public: FltToEgg(); void run(); - -protected: - 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/lwoegg/Sources.pp b/pandatool/src/lwoegg/Sources.pp index 84ae5d40f4..34c99b7f9b 100644 --- a/pandatool/src/lwoegg/Sources.pp +++ b/pandatool/src/lwoegg/Sources.pp @@ -8,6 +8,7 @@ m #define SOURCES \ + cLwoClip.I cLwoClip.cxx cLwoClip.h \ cLwoLayer.I cLwoLayer.cxx cLwoLayer.h \ cLwoPoints.I cLwoPoints.cxx cLwoPoints.h \ cLwoPolygons.I cLwoPolygons.cxx cLwoPolygons.h \ diff --git a/pandatool/src/lwoegg/cLwoClip.I b/pandatool/src/lwoegg/cLwoClip.I new file mode 100644 index 0000000000..1e7e390813 --- /dev/null +++ b/pandatool/src/lwoegg/cLwoClip.I @@ -0,0 +1,29 @@ +// Filename: cLwoClip.I +// Created by: drose (27Apr01) +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: CLwoClip::get_index +// Access: Public +// Description: Returns the index number of this clip. Each clip in +// a Lightwave object file should have a unique index +// number. +//////////////////////////////////////////////////////////////////// +int CLwoClip:: +get_index() const { + return _clip->_index; +} + +//////////////////////////////////////////////////////////////////// +// Function: CLwoClip::is_still_image +// Access: Public +// Description: Returns true if this clip represents a still image, +// as opposed to an animated image. If this is true, +// _filename will contain the image filename. +//////////////////////////////////////////////////////////////////// +bool CLwoClip:: +is_still_image() const { + return _still_image; +} diff --git a/pandatool/src/lwoegg/cLwoClip.cxx b/pandatool/src/lwoegg/cLwoClip.cxx new file mode 100644 index 0000000000..aa0648f9da --- /dev/null +++ b/pandatool/src/lwoegg/cLwoClip.cxx @@ -0,0 +1,36 @@ +// Filename: cLwoClip.cxx +// Created by: drose (27Apr01) +// +//////////////////////////////////////////////////////////////////// + +#include "cLwoClip.h" +#include "lwoToEggConverter.h" + +#include +#include + + +//////////////////////////////////////////////////////////////////// +// Function: CLwoClip::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +CLwoClip:: +CLwoClip(LwoToEggConverter *converter, const LwoClip *clip) : + _converter(converter), + _clip(clip) +{ + _still_image = false; + + // Walk through the chunk list, looking for some basic properties. + int num_chunks = _clip->get_num_chunks(); + for (int i = 0; i < num_chunks; i++) { + const IffChunk *chunk = _clip->get_chunk(i); + + if (chunk->is_of_type(LwoStillImage::get_class_type())) { + const LwoStillImage *image = DCAST(LwoStillImage, chunk); + _filename = image->_filename; + _still_image = true; + } + } +} diff --git a/pandatool/src/lwoegg/cLwoClip.h b/pandatool/src/lwoegg/cLwoClip.h index 2d5ad26319..87d5f75051 100644 --- a/pandatool/src/lwoegg/cLwoClip.h +++ b/pandatool/src/lwoegg/cLwoClip.h @@ -22,11 +22,16 @@ class LwoToEggConverter; //////////////////////////////////////////////////////////////////// class CLwoClip { public: - INLINE CLwoClip(LwoToEggConverter *converter, const LwoClip *clip); - INLINE int get_number() const; + CLwoClip(LwoToEggConverter *converter, const LwoClip *clip); + + INLINE int get_index() const; + INLINE bool is_still_image() const; LwoToEggConverter *_converter; CPT(LwoClip) _clip; + + Filename _filename; + bool _still_image; }; #include "cLwoClip.I" diff --git a/pandatool/src/lwoegg/cLwoPolygons.cxx b/pandatool/src/lwoegg/cLwoPolygons.cxx index 265e70b67b..f54831d7d2 100644 --- a/pandatool/src/lwoegg/cLwoPolygons.cxx +++ b/pandatool/src/lwoegg/cLwoPolygons.cxx @@ -141,6 +141,7 @@ make_faces() { int num_polygons = _polygons->get_num_polygons(); for (int i = 0; i < num_polygons; i++) { LwoPolygons::Polygon *poly = _polygons->get_polygon(i); + CLwoSurface *surface = get_surface(i); bool is_valid = true; @@ -162,6 +163,10 @@ make_faces() { egg_prim = new EggPolygon; } + if (surface != (CLwoSurface *)NULL) { + surface->apply_properties(egg_prim, smooth_angle); + } + for (int vi = num_vertices; vi > 0; vi--) { int vindex = poly->_vertices[vi % num_vertices]; if (vindex < 0 || vindex >= num_points) { @@ -170,18 +175,17 @@ make_faces() { } else { EggVertex egg_vert; - egg_vert.set_pos(LCAST(double, points->get_point(vindex))); + LPoint3d pos = LCAST(double, points->get_point(vindex)); + egg_vert.set_pos(pos); + if (surface != (CLwoSurface *)NULL && surface->has_uvs()) { + egg_vert.set_uv(surface->get_uv(pos)); + } EggVertex *new_vert = egg_vpool->create_unique_vertex(egg_vert); egg_prim->add_vertex(new_vert); } } if (is_valid) { - CLwoSurface *surface = get_surface(i); - if (surface != (CLwoSurface *)NULL) { - surface->apply_properties(egg_prim, smooth_angle); - } - _egg_group->add_child(egg_prim.p()); } } diff --git a/pandatool/src/lwoegg/cLwoSurface.I b/pandatool/src/lwoegg/cLwoSurface.I index 19991104e6..e3d9a3f489 100644 --- a/pandatool/src/lwoegg/cLwoSurface.I +++ b/pandatool/src/lwoegg/cLwoSurface.I @@ -14,3 +14,16 @@ INLINE const string &CLwoSurface:: get_name() const { return _surface->_name; } + +//////////////////////////////////////////////////////////////////// +// Function: CLwoSurface::has_uvs +// Access: Public +// Description: Returns true if check_texture() has been called and +// the surface is known to have UV's available, either +// computed or stored. If this is true, get_uv() may be +// called to determine each UV coordinate. +//////////////////////////////////////////////////////////////////// +INLINE bool CLwoSurface:: +has_uvs() const { + return _has_uvs; +} diff --git a/pandatool/src/lwoegg/cLwoSurface.cxx b/pandatool/src/lwoegg/cLwoSurface.cxx index d4170db266..9ed032c3b1 100644 --- a/pandatool/src/lwoegg/cLwoSurface.cxx +++ b/pandatool/src/lwoegg/cLwoSurface.cxx @@ -5,6 +5,7 @@ #include "cLwoSurface.h" #include "cLwoSurfaceBlock.h" +#include "cLwoClip.h" #include "lwoToEggConverter.h" #include @@ -13,6 +14,8 @@ #include #include #include +#include +#include //////////////////////////////////////////////////////////////////// @@ -27,6 +30,7 @@ CLwoSurface(LwoToEggConverter *converter, const LwoSurface *surface) : { _flags = 0; _checked_texture = false; + _has_uvs = false; _block = (CLwoSurfaceBlock *)NULL; // Walk through the chunk list, looking for some basic properties. @@ -157,6 +161,12 @@ apply_properties(EggPrimitive *egg_prim, float &smooth_angle) { egg_prim->set_color(color); } + if (check_texture()) { + // Texture overrides the primitive's natural color. + egg_prim->set_texture(_egg_texture); + egg_prim->clear_color(); + } + if ((_flags & F_transparency) != 0) { Colorf color(1.0, 1.0, 1.0, 1.0); if (egg_prim->has_color()) { @@ -174,8 +184,6 @@ apply_properties(EggPrimitive *egg_prim, float &smooth_angle) { if ((_flags & F_smooth_angle) != 0) { smooth_angle = max(smooth_angle, _smooth_angle); } - - check_texture(); } //////////////////////////////////////////////////////////////////// @@ -194,11 +202,63 @@ check_texture() { return (_egg_texture != (EggTexture *)NULL); } _checked_texture = true; + _egg_texture = (EggTexture *)NULL; - /* - cerr << "Got texture:\n"; - _block->_block->write(cerr, 2); - */ + if (_block == (CLwoSurfaceBlock *)NULL) { + // No texture. Not even a shader block. + return false; + } + + int clip_index = _block->_clip_index; + if (clip_index < 0) { + // No image file associated with the texture. + return false; + } + + CLwoClip *clip = _converter->get_clip(clip_index); + if (clip == (CLwoClip *)NULL) { + nout << "No clip image with index " << clip_index << "\n"; + return false; + } + + if (!clip->is_still_image()) { + // Can't do anything with an animated image right now. + return false; + } + + Filename pathname = _converter->convert_texture_path(clip->_filename); + + _egg_texture = new EggTexture("clip" + format_string(clip_index), pathname); + _has_uvs = true; return true; } + +//////////////////////////////////////////////////////////////////// +// Function: CLwoSurface::get_uv +// Access: Public +// Description: Computes or looks up the appropriate UV for the given +// vertex. +//////////////////////////////////////////////////////////////////// +LPoint2d CLwoSurface:: +get_uv(const LPoint3d &pos) const { + // For now, we always compute spherical UV's. + + // To compute the x position on the frame, we only need to consider + // the angle of the vector about the Y axis. Project the vector + // into the XZ plane to do this. + + LVector2d xz(pos[0], pos[2]); + + // The x position is longitude: the angle about the Y axis. + double x = + (atan2(xz[0], -xz[1]) / (2.0 * MathNumbers::pi) + 0.5) * _block->_w_repeat; + + // Now rotate the vector into the YZ plane, and the y position is + // latitude: the angle about the X axis. + LVector2d yz(pos[1], xz.length()); + double y = + (atan2(yz[0], yz[1]) / MathNumbers::pi + 0.5) * _block->_h_repeat; + + return LPoint2d(x, y); +} diff --git a/pandatool/src/lwoegg/cLwoSurface.h b/pandatool/src/lwoegg/cLwoSurface.h index df3592a33f..8c01044334 100644 --- a/pandatool/src/lwoegg/cLwoSurface.h +++ b/pandatool/src/lwoegg/cLwoSurface.h @@ -35,6 +35,9 @@ public: void apply_properties(EggPrimitive *egg_prim, float &smooth_angle); bool check_texture(); + INLINE bool has_uvs() const; + LPoint2d get_uv(const LPoint3d &pos) const; + enum Flags { F_color = 0x0001, F_diffuse = 0x0002, @@ -63,6 +66,7 @@ public: bool _checked_texture; PT(EggTexture) _egg_texture; + bool _has_uvs; CLwoSurfaceBlock *_block; }; diff --git a/pandatool/src/lwoegg/lwoToEggConverter.cxx b/pandatool/src/lwoegg/lwoToEggConverter.cxx index 15f541d353..6631db86fd 100644 --- a/pandatool/src/lwoegg/lwoToEggConverter.cxx +++ b/pandatool/src/lwoegg/lwoToEggConverter.cxx @@ -5,6 +5,7 @@ #include "lwoToEggConverter.h" #include "cLwoLayer.h" +#include "cLwoClip.h" #include "cLwoPoints.h" #include "cLwoPolygons.h" #include "cLwoSurface.h" @@ -50,6 +51,14 @@ LwoToEggConverter:: } } + Clips::iterator ci; + for (ci = _clips.begin(); ci != _clips.end(); ++ci) { + CLwoClip *clip = (*ci); + if (clip != (CLwoClip *)NULL) { + delete clip; + } + } + Points::iterator pi; for (pi = _points.begin(); pi != _points.end(); ++pi) { CLwoPoints *points = (*pi); @@ -179,12 +188,12 @@ get_layer(int number) const { // Description: Returns a pointer to the clip with the given index // number, or NULL if there is no such clip. //////////////////////////////////////////////////////////////////// -const LwoClip *LwoToEggConverter:: +CLwoClip *LwoToEggConverter:: get_clip(int number) const { if (number >= 0 && number < (int)_clips.size()) { return _clips[number]; } - return (const LwoClip *)NULL; + return (CLwoClip *)NULL; } //////////////////////////////////////////////////////////////////// @@ -237,13 +246,15 @@ collect_lwo() { } else if (chunk->is_of_type(LwoClip::get_class_type())) { const LwoClip *lwo_clip = DCAST(LwoClip, chunk); - int index = lwo_clip->_index; + CLwoClip *clip = new CLwoClip(this, lwo_clip); + + int index = clip->get_index(); slot_clip(index); - if (_clips[index] != (LwoClip *)NULL) { + if (_clips[index] != (CLwoClip *)NULL) { nout << "Warning: multiple clips with index " << index << "\n"; } - _clips[index] = lwo_clip; + _clips[index] = clip; } else if (chunk->is_of_type(LwoPoints::get_class_type())) { if (last_layer == (CLwoLayer *)NULL) { @@ -394,7 +405,7 @@ void LwoToEggConverter:: slot_clip(int number) { nassertv(number - (int)_clips.size() < 1000); while (number >= (int)_clips.size()) { - _clips.push_back((LwoClip *)NULL); + _clips.push_back((CLwoClip *)NULL); } nassertv(number >= 0 && number < (int)_clips.size()); } diff --git a/pandatool/src/lwoegg/lwoToEggConverter.h b/pandatool/src/lwoegg/lwoToEggConverter.h index 949a8be2cb..16db8e6d66 100644 --- a/pandatool/src/lwoegg/lwoToEggConverter.h +++ b/pandatool/src/lwoegg/lwoToEggConverter.h @@ -16,6 +16,7 @@ #include class CLwoLayer; +class CLwoClip; class CLwoPoints; class CLwoPolygons; class CLwoSurface; @@ -40,7 +41,7 @@ public: bool convert_lwo(const LwoHeader *lwo_header); CLwoLayer *get_layer(int number) const; - const LwoClip *get_clip(int number) const; + CLwoClip *get_clip(int number) const; CLwoSurface *get_surface(const string &name) const; @@ -59,7 +60,7 @@ private: typedef vector Layers; Layers _layers; - typedef vector Clips; + typedef vector Clips; Clips _clips; typedef vector Points;