Panda3D
Loading...
Searching...
No Matches
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 */
25SomethingToEgg(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 */
181void SomethingToEgg::
182apply_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 */
197void SomethingToEgg::
198apply_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 */
228bool SomethingToEgg::
229handle_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 */
286bool SomethingToEgg::
287post_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 */
308void SomethingToEgg::
309post_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 */
318bool SomethingToEgg::
319dispatch_animation_convert(const std::string &opt, const std::string &arg, void *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}
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.
AnimationConvert
This enumerated type lists the methods by which animation from an animation package might be represen...
This is similar to a ConfigVariableList, but it returns its list as a DSearchPath,...
void prepend_directory(const Filename &directory)
Adds a new directory to the front of the search list.
This is a general base class for programs that convert between egg files and some other format.
This is the primary interface into all the egg data, and the root of the egg file structure.
Definition eggData.h:37
virtual void post_process_egg_file()
Performs any processing of the egg file that is appropriate before writing it out.
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
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
std::string get_dirname() const
Returns the directory part of the filename.
Definition filename.I:358
bool exists() const
Returns true if the filename exists on the physical disk, false otherwise.
This is a base class for a family of converter classes that manage a conversion from some file type t...
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...
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...
void set_animation_convert(AnimationConvert animation_convert)
Specifies how source animation will be converted into egg structures.
void set_character_name(const std::string &character_name)
Specifies the name of the character generated.
void set_path_replace(PathReplace *path_replace)
Replaces the PathReplace object (which specifies how to mangle paths from the source to the destinati...
void set_neutral_frame(double neutral_frame)
Specifies the frame of animation to represent the neutral pose of the model.
void set_output_frame_rate(double output_frame_rate)
Specifies the number of frames per second that the resulting animation should be played at.
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...
void set_frame_inc(double frame_inc)
Specifies the increment between frames to extract.
void add_merge_externals_options()
Adds -f.
void add_units_options()
Adds -ui and -uo as valid options for this program.
void add_animation_options()
Adds options appropriate to animation packages.
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
string format_long_unit(DistanceUnit unit)
Returns the string representing the full name (plural) for the given unit.
double convert_units(DistanceUnit from, DistanceUnit to)
Returns the scaling factor that must be applied to convert from units of "from" to "to".
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.