Panda3D
somethingToEgg.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file somethingToEgg.cxx
10  * @author drose
11  * @date 2000-02-15
12  */
13 
14 #include "somethingToEgg.h"
16 
17 #include "config_putil.h"
18 
19 /**
20  * The first parameter to the constructor should be the one-word name of the
21  * file format that is to be read, for instance "OpenFlight" or "Alias". It's
22  * just used in printing error messages and such.
23  */
25 SomethingToEgg(const std::string &format_name,
26  const std::string &preferred_extension,
27  bool allow_last_param, bool allow_stdout) :
28  EggConverter(format_name, preferred_extension, allow_last_param, allow_stdout)
29 {
30  clear_runlines();
31  if (_allow_last_param) {
32  add_runline("[opts] input" + _preferred_extension + " output.egg");
33  }
34  add_runline("[opts] -o output.egg input" + _preferred_extension);
35  if (_allow_stdout) {
36  add_runline("[opts] input" + _preferred_extension + " >output.egg");
37  }
38 
39  // -f doesn't make sense if we aren't reading egg files.
40  remove_option("f");
41 
42  redescribe_option
43  ("cs",
44  "Specify the coordinate system of the input " + _format_name +
45  " file. Normally, this can inferred from the file itself.");
46 
47  add_option
48  ("noabs", "", 0,
49  "Don't allow the input " + _format_name + " file to have absolute pathnames. "
50  "If it does, abort with an error. This option is designed to help "
51  "detect errors when populating or building a standalone model tree, "
52  "which should be self-contained and include only relative pathnames.",
53  &SomethingToEgg::dispatch_none, &_noabs);
54 
55  add_option
56  ("noexist", "", 0,
57  "Don't treat it as an error if the input file references pathnames "
58  "(e.g. textures) that don't exist. Normally, this will be flagged as "
59  "an error and the command aborted; with this option, an egg file will "
60  "be generated anyway, referencing pathnames that do not exist.",
61  &SomethingToEgg::dispatch_none, &_noexist);
62 
63  add_option
64  ("ignore", "", 0,
65  "Ignore non-fatal errors and generate an egg file anyway.",
66  &SomethingToEgg::dispatch_none, &_allow_errors);
67 
68  _input_units = DU_invalid;
69  _output_units = DU_invalid;
70  _animation_convert = AC_none;
71  _got_start_frame = false;
72  _got_end_frame = false;
73  _got_frame_inc = false;
74  _got_neutral_frame = false;
75  _got_input_frame_rate = false;
76  _got_output_frame_rate = false;
77  _merge_externals = false;
78 }
79 
80 /**
81  * Adds -ui and -uo as valid options for this program. If the user specifies
82  * -uo and -ui, or just -uo and the program specifies -ui by setting
83  * _input_units, the indicated units conversion will be automatically applied
84  * before writing out the egg file.
85  */
88  add_option
89  ("ui", "units", 40,
90  "Specify the units of the input " + _format_name +
91  " file. Normally, this can be inferred from the file itself.",
92  &SomethingToEgg::dispatch_units, nullptr, &_input_units);
93 
94  add_option
95  ("uo", "units", 40,
96  "Specify the units of the resulting egg file. If this is "
97  "specified, the vertices in the egg file will be scaled as "
98  "necessary to make the appropriate units conversion; otherwise, "
99  "the vertices will be left as they are.",
100  &SomethingToEgg::dispatch_units, nullptr, &_output_units);
101 }
102 
103 /**
104  * Adds options appropriate to animation packages.
105  */
108  add_option
109  ("a", "animation-mode", 40,
110  "Specifies how animation from the " + _format_name + " file is "
111  "converted to egg, if at all. At present, the following keywords "
112  "are supported: none, pose, flip, strobe, model, chan, or both. "
113  "The default is none, which means not to convert animation.",
114  &SomethingToEgg::dispatch_animation_convert, nullptr, &_animation_convert);
115 
116  add_option
117  ("cn", "name", 40,
118  "Specifies the name of the animation character. This should match "
119  "between all of the model files and all of the channel files for a "
120  "particular model and its associated channels.",
121  &SomethingToEgg::dispatch_string, nullptr, &_character_name);
122 
123  add_option
124  ("sf", "start-frame", 40,
125  "Specifies the starting frame of animation to extract. If omitted, "
126  "the first frame of the time slider will be used. For -a pose, this "
127  "is the one frame of animation to extract.",
128  &SomethingToEgg::dispatch_double, &_got_start_frame, &_start_frame);
129 
130  add_option
131  ("ef", "end-frame", 40,
132  "Specifies the ending frame of animation to extract. If omitted, "
133  "the last frame of the time slider will be used.",
134  &SomethingToEgg::dispatch_double, &_got_end_frame, &_end_frame);
135 
136  add_option
137  ("if", "frame-inc", 40,
138  "Specifies the increment between successive frames. If omitted, "
139  "this is taken from the time slider settings, or 1.0 if the time "
140  "slider does not specify.",
141  &SomethingToEgg::dispatch_double, &_got_frame_inc, &_frame_inc);
142 
143  add_option
144  ("nf", "neutral-frame", 40,
145  "Specifies the frame number to use for the neutral pose. The model "
146  "will be set to this frame before extracting out the neutral character. "
147  "If omitted, the current frame of the model is used. This is only "
148  "relevant for -a model or -a both.",
149  &SomethingToEgg::dispatch_double, &_got_neutral_frame, &_neutral_frame);
150 
151  add_option
152  ("fri", "fps", 40,
153  "Specify the frame rate (frames per second) of the input " + _format_name +
154  " file. Normally, this can be inferred from the file itself.",
155  &SomethingToEgg::dispatch_double, &_got_input_frame_rate, &_input_frame_rate);
156 
157  add_option
158  ("fro", "fps", 40,
159  "Specify the frame rate (frames per second) of the generated animation. "
160  "If this is specified, the animation speed is scaled by the appropriate "
161  "factor based on the frame rate of the input file (see -fri).",
162  &SomethingToEgg::dispatch_double, &_got_output_frame_rate, &_output_frame_rate);
163 }
164 
165 /**
166  * Adds -f.
167  */
170  add_option
171  ("f", "", 40,
172  "Follow and convert all external references in the source file.",
173  &SomethingToEgg::dispatch_none, &_merge_externals);
174 }
175 
176 /**
177  * Applies the scale indicated by the input and output units to the indicated
178  * egg file. This is normally done automatically when the file is written
179  * out.
180  */
181 void SomethingToEgg::
182 apply_units_scale(EggData *data) {
183  if (_output_units != DU_invalid && _input_units != DU_invalid &&
184  _input_units != _output_units) {
185  nout << "Converting from " << format_long_unit(_input_units)
186  << " to " << format_long_unit(_output_units) << "\n";
187  double scale = convert_units(_input_units, _output_units);
188  data->transform(LMatrix4d::scale_mat(scale));
189  }
190 }
191 
192 /**
193  * Copies the relevant parameters specified by the user on the command line
194  * (if add_path_replace_options(), add_path_store_options(), or
195  * add_animation_options() was used) to the converter.
196  */
197 void SomethingToEgg::
198 apply_parameters(SomethingToEggConverter &converter) {
199  _path_replace->_noabs = _noabs;
200  _path_replace->_exists = !_noexist;
201  converter.set_path_replace(_path_replace);
202 
203  converter.set_animation_convert(_animation_convert);
204  converter.set_character_name(_character_name);
205  if (_got_start_frame) {
206  converter.set_start_frame(_start_frame);
207  }
208  if (_got_end_frame) {
209  converter.set_end_frame(_end_frame);
210  }
211  if (_got_frame_inc) {
212  converter.set_frame_inc(_frame_inc);
213  }
214  if (_got_neutral_frame) {
215  converter.set_neutral_frame(_neutral_frame);
216  }
217  if (_got_input_frame_rate) {
218  converter.set_input_frame_rate(_input_frame_rate);
219  }
220  if (_got_output_frame_rate) {
221  converter.set_output_frame_rate(_output_frame_rate);
222  }
223 }
224 
225 /**
226  *
227  */
228 bool SomethingToEgg::
229 handle_args(Args &args) {
230  if (_allow_last_param && !_got_output_filename && args.size() > 1) {
231  _got_output_filename = true;
232  _output_filename = Filename::from_os_specific(args.back());
233  args.pop_back();
234 
235  if (!(_output_filename.get_extension() == "egg")) {
236  nout << "Output filename " << _output_filename
237  << " does not end in .egg. If this is really what you intended, "
238  "use the -o output_file syntax.\n";
239  return false;
240  }
241 
242  if (!verify_output_file_safe()) {
243  return false;
244  }
245  }
246 
247  if (args.empty()) {
248  nout << "You must specify the " << _format_name
249  << " file to read on the command line.\n";
250  return false;
251  }
252 
253  if (args.size() != 1) {
254  nout << "You may only specify one " << _format_name
255  << " file to read on the command line. "
256  << "You specified: ";
257  Args::const_iterator ai;
258  for (ai = args.begin(); ai != args.end(); ++ai) {
259  nout << (*ai) << " ";
260  }
261  nout << "\n";
262  return false;
263  }
264 
265  _input_filename = Filename::from_os_specific(args[0]);
266 
267  if (!_input_filename.exists()) {
268  nout << "Cannot find input file " << _input_filename << "\n";
269  return false;
270  }
271 
272  if (!_got_path_directory && _got_output_filename) {
273  // Put in the name of the output directory.
274  _path_replace->_path_directory = _output_filename.get_dirname();
275  }
276 
277  return true;
278 }
279 
280 /**
281  * This is called after the command line has been completely processed, and it
282  * gives the program a chance to do some last-minute processing and validation
283  * of the options and arguments. It should return true if everything is fine,
284  * false if there is an error.
285  */
286 bool SomethingToEgg::
287 post_command_line() {
288  // Prepend the source filename to the model path.
289  ConfigVariableSearchPath &model_path = get_model_path();
290  Filename directory = _input_filename.get_dirname();
291  if (directory.empty()) {
292  directory = ".";
293  }
294  model_path.prepend_directory(directory);
295 
296  return EggConverter::post_command_line();
297 }
298 
299 /**
300  * Performs any processing of the egg file that is appropriate before writing
301  * it out. This includes any normal adjustments the user requested via -np,
302  * etc.
303  *
304  * Normally, you should not need to call this function directly;
305  * write_egg_file() calls it for you. You should call this only if you do not
306  * use write_egg_file() to write out the resulting egg file.
307  */
308 void SomethingToEgg::
309 post_process_egg_file() {
310  apply_units_scale(_data);
312 }
313 
314 /**
315  * Dispatch function to set the given animation convert mode according to the
316  * specified parameter. var is a pointer to an AnimationConvert variable.
317  */
318 bool SomethingToEgg::
319 dispatch_animation_convert(const std::string &opt, const std::string &arg, void *var) {
320  AnimationConvert *ip = (AnimationConvert *)var;
321  (*ip) = string_animation_convert(arg);
322  if ((*ip) == AC_invalid) {
323  nout << "Invalid keyword for -" << opt << ": " << arg << "\n";
324  return false;
325  }
326 
327  return true;
328 }
SomethingToEgg::add_merge_externals_options
void add_merge_externals_options()
Adds -f.
Definition: somethingToEgg.cxx:169
SomethingToEggConverter::set_frame_inc
void set_frame_inc(double frame_inc)
Specifies the increment between frames to extract.
Definition: somethingToEggConverter.I:187
config_putil.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
SomethingToEgg::add_animation_options
void add_animation_options()
Adds options appropriate to animation packages.
Definition: somethingToEgg.cxx:107
Filename::get_dirname
std::string get_dirname() const
Returns the directory part of the filename.
Definition: filename.I:358
Filename::from_os_specific
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes,...
Definition: filename.cxx:328
AnimationConvert
AnimationConvert
This enumerated type lists the methods by which animation from an animation package might be represen...
Definition: animationConvert.h:23
string_animation_convert
AnimationConvert string_animation_convert(const std::string &str)
Converts from a string, as might be input by the user, to one of the known AnimationConvert types.
Definition: animationConvert.cxx:66
SomethingToEggConverter::set_character_name
void set_character_name(const std::string &character_name)
Specifies the name of the character generated.
Definition: somethingToEggConverter.I:85
Filename::exists
bool exists() const
Returns true if the filename exists on the disk, false otherwise.
Definition: filename.cxx:1267
SomethingToEggConverter::set_neutral_frame
void set_neutral_frame(double neutral_frame)
Specifies the frame of animation to represent the neutral pose of the model.
Definition: somethingToEggConverter.I:226
SomethingToEggConverter::set_start_frame
void set_start_frame(double start_frame)
Specifies the starting frame of the animation to convert, in the units specified by set_input_frame_r...
Definition: somethingToEggConverter.I:104
SomethingToEggConverter::set_end_frame
void set_end_frame(double end_frame)
Specifies the ending frame of the animation to convert, in the units specified by set_input_frame_rat...
Definition: somethingToEggConverter.I:145
EggWriter::post_process_egg_file
virtual void post_process_egg_file()
Performs any processing of the egg file that is appropriate before writing it out.
Definition: eggWriter.cxx:112
EggConverter
This is a general base class for programs that convert between egg files and some other format.
Definition: eggConverter.h:25
SomethingToEgg::SomethingToEgg
SomethingToEgg(const std::string &format_name, const std::string &preferred_extension=std::string(), bool allow_last_param=true, bool allow_stdout=true)
The first parameter to the constructor should be the one-word name of the file format that is to be r...
Definition: somethingToEgg.cxx:25
somethingToEggConverter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggData
This is the primary interface into all the egg data, and the root of the egg file structure.
Definition: eggData.h:37
SomethingToEggConverter::set_path_replace
void set_path_replace(PathReplace *path_replace)
Replaces the PathReplace object (which specifies how to mangle paths from the source to the destinati...
Definition: somethingToEggConverter.I:37
ConfigVariableSearchPath::prepend_directory
void prepend_directory(const Filename &directory)
Adds a new directory to the front of the search list.
Definition: configVariableSearchPath.I:170
SomethingToEggConverter
This is a base class for a family of converter classes that manage a conversion from some file type t...
Definition: somethingToEggConverter.h:38
somethingToEgg.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
SomethingToEgg::add_units_options
void add_units_options()
Adds -ui and -uo as valid options for this program.
Definition: somethingToEgg.cxx:87
convert_units
double convert_units(DistanceUnit from, DistanceUnit to)
Returns the scaling factor that must be applied to convert from units of "from" to "to".
Definition: distanceUnit.cxx:213
format_long_unit
string format_long_unit(DistanceUnit unit)
Returns the string representing the full name (plural) for the given unit.
Definition: distanceUnit.cxx:67
SomethingToEggConverter::set_animation_convert
void set_animation_convert(AnimationConvert animation_convert)
Specifies how source animation will be converted into egg structures.
Definition: somethingToEggConverter.I:67
SomethingToEggConverter::set_output_frame_rate
void set_output_frame_rate(double output_frame_rate)
Specifies the number of frames per second that the resulting animation should be played at.
Definition: somethingToEggConverter.I:306
ConfigVariableSearchPath
This is similar to a ConfigVariableList, but it returns its list as a DSearchPath,...
Definition: configVariableSearchPath.h:36
SomethingToEggConverter::set_input_frame_rate
void set_input_frame_rate(double input_frame_rate)
Specifies the number of frames per second that is represented by the "frame" unit in the animation pa...
Definition: somethingToEggConverter.I:267
Filename
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39