diff --git a/pandatool/src/converter/somethingToEggConverter.I b/pandatool/src/converter/somethingToEggConverter.I index 56f56d9fdf..2c5d63e71a 100644 --- a/pandatool/src/converter/somethingToEggConverter.I +++ b/pandatool/src/converter/somethingToEggConverter.I @@ -52,6 +52,30 @@ set_model_path_convert(PathConvert mpc, _mpc_directory = mpc_directory; } +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEggConverter::set_merge_externals +// Access: Public +// Description: Sets the merge_externals flag. When this is true, +// external references within the source file are read +// in and merged directly; otherwise, only a reference +// to a similarly-named egg file is inserted. +//////////////////////////////////////////////////////////////////// +INLINE void SomethingToEggConverter:: +set_merge_externals(bool merge_externals) { + _merge_externals = merge_externals; +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEggConverter::get_merge_externals +// Access: Public +// Description: Returns the current state of the merge_externals +// flag. See set_merge_externals(). +//////////////////////////////////////////////////////////////////// +INLINE bool SomethingToEggConverter:: +get_merge_externals() const { + return _merge_externals; +} + //////////////////////////////////////////////////////////////////// // Function: SomethingToEggConverter::clear_egg_data // Access: Public @@ -73,6 +97,28 @@ get_egg_data() { return *_egg_data; } +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEggConverter::handle_external_reference +// Access: Public +// Description: Handles an external reference in the source file. If +// the merge_externals flag is true (see +// set_merge_externals()), this causes the named file to +// be read in and converted, and the converted egg +// geometry is parented to egg_parent. Otherwise, only +// a reference to a similarly named egg file is parented +// to egg_parent. +// +// The parameters orig_filename and searchpath are as +// those passed to convert_model_path(). +// +// Returns true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool SomethingToEggConverter:: +handle_external_reference(EggGroupNode *egg_parent, + const Filename &orig_filename) { + return handle_external_reference(egg_parent, orig_filename, get_model_path()); +} + //////////////////////////////////////////////////////////////////// // Function: SomethingToEggConverter::convert_texture_path diff --git a/pandatool/src/converter/somethingToEggConverter.cxx b/pandatool/src/converter/somethingToEggConverter.cxx index 2faeccedda..7e2a9859fc 100644 --- a/pandatool/src/converter/somethingToEggConverter.cxx +++ b/pandatool/src/converter/somethingToEggConverter.cxx @@ -6,6 +6,7 @@ #include "somethingToEggConverter.h" #include +#include //////////////////////////////////////////////////////////////////// // Function: SomethingToEggConverter::Constructor @@ -14,10 +15,29 @@ //////////////////////////////////////////////////////////////////// SomethingToEggConverter:: SomethingToEggConverter() { - _egg_data = (EggData *)NULL; - _owns_egg_data = false; _tpc = PC_absolute; _mpc = PC_absolute; + _merge_externals = false; + _egg_data = (EggData *)NULL; + _owns_egg_data = false; + _error = false; +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEggConverter::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +SomethingToEggConverter:: +SomethingToEggConverter(const SomethingToEggConverter ©) : + _tpc(copy._tpc), + _tpc_directory(copy._tpc_directory), + _mpc(copy._mpc), + _mpc_directory(copy._mpc_directory), + _merge_externals(copy._merge_externals) +{ + _egg_data = (EggData *)NULL; + _owns_egg_data = false; _error = false; } @@ -50,6 +70,69 @@ set_egg_data(EggData *egg_data, bool owns_egg_data) { _owns_egg_data = owns_egg_data; } +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEggConverter::handle_external_reference +// Access: Public +// Description: Handles an external reference in the source file. If +// the merge_externals flag is true (see +// set_merge_externals()), this causes the named file to +// be read in and converted, and the converted egg +// geometry is parented to egg_parent. Otherwise, only +// a reference to a similarly named egg file is parented +// to egg_parent. +// +// The parameters orig_filename and searchpath are as +// those passed to convert_model_path(). +// +// Returns true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool SomethingToEggConverter:: +handle_external_reference(EggGroupNode *egg_parent, + const Filename &orig_filename, + const DSearchPath &searchpath) { + if (_merge_externals) { + SomethingToEggConverter *ext = make_copy(); + EggData egg_data; + egg_data.set_coordinate_system(get_egg_data().get_coordinate_system()); + ext->set_egg_data(&egg_data, false); + + // If we're reading references directly, don't mamby around with + // the path conversion stuff, just look for the file and read it. + 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; + } + } + + if (!ext->convert_file(as_found)) { + delete ext; + nout << "Unable to read external reference: " << orig_filename << "\n"; + _error = true; + return false; + } + + egg_parent->steal_children(egg_data); + delete ext; + return true; + + } else { + // If we're installing external references instead of reading + // them, we should massage the filename as specified. + Filename filename = convert_model_path(orig_filename, searchpath); + + filename.set_extension("egg"); + + EggExternalReference *egg_ref = new EggExternalReference("", filename); + egg_parent->add_child(egg_ref); + } + + return true; +} + //////////////////////////////////////////////////////////////////// // Function: SomethingToEggConverter::convert_path // Access: Protected, Static diff --git a/pandatool/src/converter/somethingToEggConverter.h b/pandatool/src/converter/somethingToEggConverter.h index de9715a7b6..c8467c3513 100644 --- a/pandatool/src/converter/somethingToEggConverter.h +++ b/pandatool/src/converter/somethingToEggConverter.h @@ -12,6 +12,7 @@ #include // for get_texture_path() and get_model_path() class EggData; +class EggGroupNode; //////////////////////////////////////////////////////////////////// // Class : SomethingToEggConverter @@ -26,8 +27,11 @@ class EggData; class SomethingToEggConverter { public: SomethingToEggConverter(); + SomethingToEggConverter(const SomethingToEggConverter ©); virtual ~SomethingToEggConverter(); + virtual SomethingToEggConverter *make_copy()=0; + enum PathConvert { PC_relative, PC_absolute, @@ -40,6 +44,9 @@ public: INLINE void set_model_path_convert(PathConvert mpc, const Filename &mpc_directory = Filename()); + INLINE void set_merge_externals(bool merge_externals); + INLINE bool get_merge_externals() const; + void set_egg_data(EggData *egg_data, bool owns_egg_data); INLINE void clear_egg_data(); INLINE EggData &get_egg_data(); @@ -49,6 +56,12 @@ public: virtual bool convert_file(const Filename &filename)=0; + bool handle_external_reference(EggGroupNode *egg_parent, + const Filename &orig_filename, + const DSearchPath &searchpath); + INLINE bool handle_external_reference(EggGroupNode *egg_parent, + const Filename &orig_filename); + INLINE Filename convert_texture_path(const Filename &orig_filename); INLINE Filename convert_texture_path(const Filename &orig_filename, @@ -70,6 +83,8 @@ protected: PathConvert _mpc; Filename _mpc_directory; + bool _merge_externals; + EggData *_egg_data; bool _owns_egg_data; diff --git a/pandatool/src/eggbase/somethingToEgg.cxx b/pandatool/src/eggbase/somethingToEgg.cxx index 8983ca9b2d..e7b303580b 100644 --- a/pandatool/src/eggbase/somethingToEgg.cxx +++ b/pandatool/src/eggbase/somethingToEgg.cxx @@ -43,6 +43,7 @@ SomethingToEgg(const string &format_name, _texture_path_convert = SomethingToEggConverter::PC_unchanged; _model_path_convert = SomethingToEggConverter::PC_unchanged; _append_to_sys_paths = false; + _merge_externals = false; } //////////////////////////////////////////////////////////////////// @@ -196,6 +197,19 @@ add_search_path_options(bool append_to_sys_paths) { &SomethingToEgg::dispatch_search_path, &_got_search_path, &_search_path); } +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEgg::add_merge_externals_options +// Access: Public +// Description: Adds -f. +//////////////////////////////////////////////////////////////////// +void SomethingToEgg:: +add_merge_externals_options() { + add_option + ("f", "", 40, + "Follow and convert all external references in the source file.", + &SomethingToEgg::dispatch_none, &_merge_externals); +} + //////////////////////////////////////////////////////////////////// // Function: SomethingToEgg::apply_units_scale // Access: Protected diff --git a/pandatool/src/eggbase/somethingToEgg.h b/pandatool/src/eggbase/somethingToEgg.h index 0b927a25eb..a67bedd101 100644 --- a/pandatool/src/eggbase/somethingToEgg.h +++ b/pandatool/src/eggbase/somethingToEgg.h @@ -32,6 +32,7 @@ public: void add_model_path_options(); void add_rel_dir_options(); void add_search_path_options(bool append_to_sys_paths); + void add_merge_externals_options(); protected: void apply_units_scale(EggData &data); @@ -61,6 +62,8 @@ protected: DSearchPath _search_path; bool _got_search_path; bool _append_to_sys_paths; + + bool _merge_externals; }; #endif diff --git a/pandatool/src/fltegg/fltToEggConverter.cxx b/pandatool/src/fltegg/fltToEggConverter.cxx index 20116369ce..e2462746ba 100644 --- a/pandatool/src/fltegg/fltToEggConverter.cxx +++ b/pandatool/src/fltegg/fltToEggConverter.cxx @@ -36,6 +36,17 @@ FltToEggConverter:: FltToEggConverter() { } +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +FltToEggConverter:: +FltToEggConverter(const FltToEggConverter ©) : + SomethingToEggConverter(copy) +{ +} + //////////////////////////////////////////////////////////////////// // Function: FltToEggConverter::Destructor // Access: Public @@ -46,6 +57,16 @@ FltToEggConverter:: cleanup(); } +//////////////////////////////////////////////////////////////////// +// Function: FltToEggConverter::make_copy +// Access: Public, Virtual +// Description: Allocates and returns a new copy of the converter. +//////////////////////////////////////////////////////////////////// +SomethingToEggConverter *FltToEggConverter:: +make_copy() { + return new FltToEggConverter(*this); +} + //////////////////////////////////////////////////////////////////// // Function: FltToEggConverter::get_name @@ -371,13 +392,8 @@ convert_ext_ref(const FltExternalReference *flt_ext, FltToEggLevelState &state) EggGroupNode *egg_parent = state.get_synthetic_group("", flt_ext->get_transform()); - Filename filename = - convert_model_path(flt_ext->_filename, _flt_header->get_model_path()); - - filename.set_extension("egg"); - - EggExternalReference *egg_ref = new EggExternalReference("", filename); - egg_parent->add_child(egg_ref); + handle_external_reference(egg_parent, + flt_ext->_filename, _flt_header->get_model_path()); } //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/fltegg/fltToEggConverter.h b/pandatool/src/fltegg/fltToEggConverter.h index 72b23a5d25..20b0185037 100644 --- a/pandatool/src/fltegg/fltToEggConverter.h +++ b/pandatool/src/fltegg/fltToEggConverter.h @@ -41,8 +41,11 @@ class EggPrimitive; class FltToEggConverter : public SomethingToEggConverter { public: FltToEggConverter(); + FltToEggConverter(const FltToEggConverter ©); ~FltToEggConverter(); + virtual SomethingToEggConverter *make_copy(); + virtual string get_name() const; virtual string get_extension() const; diff --git a/pandatool/src/fltprogs/fltToEgg.cxx b/pandatool/src/fltprogs/fltToEgg.cxx index 6fdd2c2729..66851689bd 100644 --- a/pandatool/src/fltprogs/fltToEgg.cxx +++ b/pandatool/src/fltprogs/fltToEgg.cxx @@ -24,6 +24,7 @@ FltToEgg() : add_model_path_options(); add_rel_dir_options(); add_search_path_options(false); + add_merge_externals_options(); set_program_description ("This program converts MultiGen OpenFlight (.flt) files to egg. Most " @@ -64,6 +65,7 @@ run() { } FltToEggConverter converter; + converter.set_merge_externals(_merge_externals); 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); diff --git a/pandatool/src/lwoegg/lwoToEggConverter.cxx b/pandatool/src/lwoegg/lwoToEggConverter.cxx index cbd0784e99..483c4a1762 100644 --- a/pandatool/src/lwoegg/lwoToEggConverter.cxx +++ b/pandatool/src/lwoegg/lwoToEggConverter.cxx @@ -34,6 +34,17 @@ LwoToEggConverter() { _make_materials = true; } +//////////////////////////////////////////////////////////////////// +// Function: LwoToEggConverter::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +LwoToEggConverter:: +LwoToEggConverter(const LwoToEggConverter ©) : + SomethingToEggConverter(copy) +{ +} + //////////////////////////////////////////////////////////////////// // Function: LwoToEggConverter::Destructor // Access: Public, Virtual @@ -44,6 +55,16 @@ LwoToEggConverter:: cleanup(); } +//////////////////////////////////////////////////////////////////// +// Function: LwoToEggConverter::make_copy +// Access: Public, Virtual +// Description: Allocates and returns a new copy of the converter. +//////////////////////////////////////////////////////////////////// +SomethingToEggConverter *LwoToEggConverter:: +make_copy() { + return new LwoToEggConverter(*this); +} + //////////////////////////////////////////////////////////////////// // Function: LwoToEggConverter::get_name // Access: Public, Virtual diff --git a/pandatool/src/lwoegg/lwoToEggConverter.h b/pandatool/src/lwoegg/lwoToEggConverter.h index 86e8252f94..4dbc0aed9a 100644 --- a/pandatool/src/lwoegg/lwoToEggConverter.h +++ b/pandatool/src/lwoegg/lwoToEggConverter.h @@ -32,8 +32,11 @@ class LwoClip; class LwoToEggConverter : public SomethingToEggConverter { public: LwoToEggConverter(); + LwoToEggConverter(const LwoToEggConverter ©); virtual ~LwoToEggConverter(); + virtual SomethingToEggConverter *make_copy(); + virtual string get_name() const; virtual string get_extension() const; diff --git a/pandatool/src/ptloader/loaderFileTypePandatool.cxx b/pandatool/src/ptloader/loaderFileTypePandatool.cxx index 861eae0dd9..49e24b5a0d 100644 --- a/pandatool/src/ptloader/loaderFileTypePandatool.cxx +++ b/pandatool/src/ptloader/loaderFileTypePandatool.cxx @@ -21,6 +21,7 @@ LoaderFileTypePandatool:: LoaderFileTypePandatool(SomethingToEggConverter *converter) : _converter(converter) { + converter->set_merge_externals(true); } ////////////////////////////////////////////////////////////////////