Panda3D
loaderFileTypePandatool.cxx
1 // Filename: loaderFileTypePandatool.cxx
2 // Created by: drose (26Apr01)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "loaderFileTypePandatool.h"
16 #include "config_ptloader.h"
17 #include "somethingToEggConverter.h"
18 #include "eggToSomethingConverter.h"
19 #include "config_util.h"
20 #include "load_egg_file.h"
21 #include "save_egg_file.h"
22 #include "eggData.h"
23 #include "loaderOptions.h"
24 #include "bamCacheRecord.h"
25 
26 TypeHandle LoaderFileTypePandatool::_type_handle;
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: LoaderFileTypePandatool::Constructor
30 // Access: Public
31 // Description:
32 ////////////////////////////////////////////////////////////////////
33 LoaderFileTypePandatool::
34 LoaderFileTypePandatool(SomethingToEggConverter *loader,
35  EggToSomethingConverter *saver) :
36  _loader(loader), _saver(saver)
37 {
38  if (_loader != (SomethingToEggConverter *)NULL) {
39  _loader->set_merge_externals(true);
40  }
41 }
42 
43 ////////////////////////////////////////////////////////////////////
44 // Function: LoaderFileTypePandatool::Destructor
45 // Access: Public, Virtual
46 // Description:
47 ////////////////////////////////////////////////////////////////////
48 LoaderFileTypePandatool::
49 ~LoaderFileTypePandatool() {
50 }
51 
52 ////////////////////////////////////////////////////////////////////
53 // Function: LoaderFileTypePandatool::get_name
54 // Access: Public, Virtual
55 // Description:
56 ////////////////////////////////////////////////////////////////////
57 string LoaderFileTypePandatool::
58 get_name() const {
59  if (_loader != (SomethingToEggConverter *)NULL) {
60  return _loader->get_name();
61  }
62  return _saver->get_name();
63 }
64 
65 ////////////////////////////////////////////////////////////////////
66 // Function: LoaderFileTypePandatool::get_extension
67 // Access: Public, Virtual
68 // Description:
69 ////////////////////////////////////////////////////////////////////
70 string LoaderFileTypePandatool::
71 get_extension() const {
72  if (_loader != (SomethingToEggConverter *)NULL) {
73  return _loader->get_extension();
74  }
75  return _saver->get_extension();
76 }
77 
78 ////////////////////////////////////////////////////////////////////
79 // Function: LoaderFileTypePandatool::get_additional_extensions
80 // Access: Public, Virtual
81 // Description: Returns a space-separated list of extension, in
82 // addition to the one returned by get_extension(), that
83 // are recognized by this converter.
84 ////////////////////////////////////////////////////////////////////
87  if (_loader != (SomethingToEggConverter *)NULL) {
88  return _loader->get_additional_extensions();
89  }
90  return _saver->get_additional_extensions();
91 }
92 
93 ////////////////////////////////////////////////////////////////////
94 // Function: LoaderFileTypePandatool::supports_compressed
95 // Access: Published, Virtual
96 // Description: Returns true if this file type can transparently load
97 // compressed files (with a .pz extension), false
98 // otherwise.
99 ////////////////////////////////////////////////////////////////////
102  if (_loader != (SomethingToEggConverter *)NULL) {
103  return _loader->supports_compressed();
104  }
105  return _saver->supports_compressed();
106 }
107 
108 ////////////////////////////////////////////////////////////////////
109 // Function: LoaderFileTypePandatool::supports_load
110 // Access: Published, Virtual
111 // Description: Returns true if the file type can be used to load
112 // files, and load_file() is supported. Returns false
113 // if load_file() is unimplemented and will always fail.
114 ////////////////////////////////////////////////////////////////////
116 supports_load() const {
117  return (_loader != NULL);
118 }
119 
120 ////////////////////////////////////////////////////////////////////
121 // Function: LoaderFileTypePandatool::supports_save
122 // Access: Published, Virtual
123 // Description: Returns true if the file type can be used to save
124 // files, and save_file() is supported. Returns false
125 // if save_file() is unimplemented and will always fail.
126 ////////////////////////////////////////////////////////////////////
128 supports_save() const {
129  return (_saver != NULL);
130 }
131 
132 ////////////////////////////////////////////////////////////////////
133 // Function: LoaderFileTypePandatool::resolve_filename
134 // Access: Public, Virtual
135 // Description: Searches for the indicated filename on whatever paths
136 // are appropriate to this file type, and updates it if
137 // it is found.
138 ////////////////////////////////////////////////////////////////////
141  path.resolve_filename(get_model_path(), get_extension());
142 }
143 
144 ////////////////////////////////////////////////////////////////////
145 // Function: LoaderFileTypePandatool::load_file
146 // Access: Public, Virtual
147 // Description:
148 ////////////////////////////////////////////////////////////////////
149 PT(PandaNode) LoaderFileTypePandatool::
150 load_file(const Filename &path, const LoaderOptions &options,
151  BamCacheRecord *record) const {
152  if (_loader == NULL) {
153  return NULL;
154  }
155 
156  if (record != (BamCacheRecord *)NULL) {
157  record->add_dependent_file(path);
158  }
159 
160  PT(PandaNode) result;
161 
162  SomethingToEggConverter *loader = _loader->make_copy();
163 
164  DSearchPath file_path;
165  file_path.append_directory(path.get_dirname());
166  loader->get_path_replace()->_path = file_path;
167 
168  // Convert animation, if the converter supports it.
169  switch (options.get_flags() & LoaderOptions::LF_convert_anim) {
170  case LoaderOptions::LF_convert_anim:
171  loader->set_animation_convert(AC_both);
172  break;
173 
174  case LoaderOptions::LF_convert_skeleton:
175  loader->set_animation_convert(AC_model);
176  break;
177 
178  case LoaderOptions::LF_convert_channels:
179  loader->set_animation_convert(AC_chan);
180  break;
181 
182  default:
183  break;
184  }
185 
186  // Try to convert directly to PandaNode first, if the converter type
187  // supports it.
188  if (ptloader_load_node && loader->supports_convert_to_node(options)) {
189  result = loader->convert_to_node(options, path);
190  if (!result.is_null()) {
191  return result;
192  }
193  }
194 
195  // If the converter type doesn't support the direct PandaNode
196  // conversion, take the slower route through egg instead.
197  PT(EggData) egg_data = new EggData;
198  loader->set_egg_data(egg_data);
199 
200  if (loader->convert_file(path)) {
201  DistanceUnit input_units = loader->get_input_units();
202  if (input_units != DU_invalid && ptloader_units != DU_invalid &&
203  input_units != ptloader_units) {
204  // Convert the file to the units specified by the ptloader-units
205  // Configrc variable.
206  ptloader_cat.info()
207  << "Converting from " << format_long_unit(input_units)
208  << " to " << format_long_unit(ptloader_units) << "\n";
209  double scale = convert_units(input_units, ptloader_units);
210  egg_data->transform(LMatrix4d::scale_mat(scale));
211  }
212 
213  if (!egg_data->has_primitives()) {
214  egg_data->make_point_primitives();
215  } else if (!egg_data->has_normals()) {
216  egg_data->recompute_polygon_normals();
217  }
218 
219  result = load_egg_data(egg_data);
220  }
221  delete loader;
222 
223  return result.p();
224 }
225 
226 ////////////////////////////////////////////////////////////////////
227 // Function: LoaderFileTypePandatool::save_file
228 // Access: Public, Virtual
229 // Description:
230 ////////////////////////////////////////////////////////////////////
231 bool LoaderFileTypePandatool::
232 save_file(const Filename &path, const LoaderOptions &options,
233  PandaNode *node) const {
234  if (_saver == NULL) {
235  return false;
236  }
237 
238  PT(EggData) egg_data = new EggData;
239  if (!save_egg_data(egg_data, node)) {
240  return false;
241  }
242 
243  EggToSomethingConverter *saver = _saver->make_copy();
244  saver->set_egg_data(egg_data);
245 
246  bool result = saver->write_file(path);
247  delete saver;
248  return result;
249 }
string get_dirname() const
Returns the directory part of the filename.
Definition: filename.I:424
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
virtual bool supports_convert_to_node(const LoaderOptions &options) const
Returns true if this converter can directly convert the model type to internal Panda memory structure...
virtual string get_additional_extensions() const
Returns a space-separated list of extension, in addition to the one returned by get_extension(), that are recognized by this converter.
Specifies parameters that may be passed to the loader.
Definition: loaderOptions.h:26
static LMatrix4d scale_mat(const LVecBase3d &scale)
Returns a matrix that applies the indicated scale in each of the three axes.
Definition: lmatrix.h:6721
void append_directory(const Filename &directory)
Adds a new directory to the end of the search list.
This is the primary interface into all the egg data, and the root of the egg file structure...
Definition: eggData.h:41
This is a base class for a family of converter classes that manage a conversion from egg format to so...
bool resolve_filename(const DSearchPath &searchpath, const string &default_extension=string())
Searches the given search path for the filename.
Definition: filename.cxx:1699
void set_egg_data(EggData *egg_data)
Sets the egg data that will be filled in when convert_file() is called.
virtual bool supports_load() const
Returns true if the file type can be used to load files, and load_file() is supported.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
virtual bool supports_compressed() const
Returns true if this file type can transparently load compressed files (with a .pz extension)...
An instance of this class is written to the front of a Bam or Txo file to make the file a cached inst...
virtual bool supports_save() const
Returns true if the file type can be used to save files, and save_file() is supported.
virtual bool supports_compressed() const
Returns true if this file type can transparently save compressed files (with a .pz extension)...
void set_animation_convert(AnimationConvert animation_convert)
Specifies how source animation will be converted into egg structures.
void set_egg_data(EggData *egg_data)
Sets the egg data that will be filled in when convert_file() is called.
virtual string get_additional_extensions() const
Returns a space-separated list of extension, in addition to the one returned by get_extension(), that are recognized by this converter.
virtual string get_additional_extensions() const
Returns a space-separated list of extension, in addition to the one returned by get_extension(), that are recognized by this converter.
PathReplace * get_path_replace()
Returns a pointer to the PathReplace object associated with this converter.
void set_merge_externals(bool merge_externals)
Sets the merge_externals flag.
This class stores a list of directories that can be searched, in order, to locate a particular file...
Definition: dSearchPath.h:32
void add_dependent_file(const Filename &pathname)
Adds the indicated file to the list of files that will be loaded to generate the data in this record...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
virtual void resolve_filename(Filename &path) const
Searches for the indicated filename on whatever paths are appropriate to this file type...
virtual DistanceUnit get_input_units()
This may be called after convert_file() has been called and returned true, indicating a successful co...
This is a base class for a family of converter classes that manage a conversion from some file type t...
virtual bool supports_compressed() const
Returns true if this file type can transparently load compressed files (with a .pz extension)...