00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "somethingToEgg.h"
00016 #include "somethingToEggConverter.h"
00017
00018 #include "config_util.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 SomethingToEgg::
00029 SomethingToEgg(const string &format_name,
00030 const string &preferred_extension,
00031 bool allow_last_param, bool allow_stdout) :
00032 EggConverter(format_name, preferred_extension, allow_last_param, allow_stdout)
00033 {
00034 clear_runlines();
00035 if (_allow_last_param) {
00036 add_runline("[opts] input" + _preferred_extension + " output.egg");
00037 }
00038 add_runline("[opts] -o output.egg input" + _preferred_extension);
00039 if (_allow_stdout) {
00040 add_runline("[opts] input" + _preferred_extension + " >output.egg");
00041 }
00042
00043
00044 remove_option("f");
00045
00046 redescribe_option
00047 ("cs",
00048 "Specify the coordinate system of the input " + _format_name +
00049 " file. Normally, this can inferred from the file itself.");
00050
00051 add_option
00052 ("noabs", "", 0,
00053 "Don't allow the input " + _format_name + " file to have absolute pathnames. "
00054 "If it does, abort with an error. This option is designed to help "
00055 "detect errors when populating or building a standalone model tree, "
00056 "which should be self-contained and include only relative pathnames.",
00057 &SomethingToEgg::dispatch_none, &_noabs);
00058
00059 add_option
00060 ("noexist", "", 0,
00061 "Don't treat it as an error if the input file references pathnames "
00062 "(e.g. textures) that don't exist. Normally, this will be flagged as "
00063 "an error and the command aborted; with this option, an egg file will "
00064 "be generated anyway, referencing pathnames that do not exist.",
00065 &SomethingToEgg::dispatch_none, &_noexist);
00066
00067 add_option
00068 ("ignore", "", 0,
00069 "Ignore non-fatal errors and generate an egg file anyway.",
00070 &SomethingToEgg::dispatch_none, &_allow_errors);
00071
00072 _input_units = DU_invalid;
00073 _output_units = DU_invalid;
00074 _animation_convert = AC_none;
00075 _got_start_frame = false;
00076 _got_end_frame = false;
00077 _got_frame_inc = false;
00078 _got_neutral_frame = false;
00079 _got_input_frame_rate = false;
00080 _got_output_frame_rate = false;
00081 _merge_externals = false;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 void SomethingToEgg::
00094 add_units_options() {
00095 add_option
00096 ("ui", "units", 40,
00097 "Specify the units of the input " + _format_name +
00098 " file. Normally, this can be inferred from the file itself.",
00099 &SomethingToEgg::dispatch_units, NULL, &_input_units);
00100
00101 add_option
00102 ("uo", "units", 40,
00103 "Specify the units of the resulting egg file. If this is "
00104 "specified, the vertices in the egg file will be scaled as "
00105 "necessary to make the appropriate units conversion; otherwise, "
00106 "the vertices will be left as they are.",
00107 &SomethingToEgg::dispatch_units, NULL, &_output_units);
00108 }
00109
00110
00111
00112
00113
00114
00115 void SomethingToEgg::
00116 add_animation_options() {
00117 add_option
00118 ("a", "animation-mode", 40,
00119 "Specifies how animation from the " + _format_name + " file is "
00120 "converted to egg, if at all. At present, the following keywords "
00121 "are supported: none, pose, flip, strobe, model, chan, or both. "
00122 "The default is none, which means not to convert animation.",
00123 &SomethingToEgg::dispatch_animation_convert, NULL, &_animation_convert);
00124
00125 add_option
00126 ("cn", "name", 40,
00127 "Specifies the name of the animation character. This should match "
00128 "between all of the model files and all of the channel files for a "
00129 "particular model and its associated channels.",
00130 &SomethingToEgg::dispatch_string, NULL, &_character_name);
00131
00132 add_option
00133 ("sf", "start-frame", 40,
00134 "Specifies the starting frame of animation to extract. If omitted, "
00135 "the first frame of the time slider will be used. For -a pose, this "
00136 "is the one frame of animation to extract.",
00137 &SomethingToEgg::dispatch_double, &_got_start_frame, &_start_frame);
00138
00139 add_option
00140 ("ef", "end-frame", 40,
00141 "Specifies the ending frame of animation to extract. If omitted, "
00142 "the last frame of the time slider will be used.",
00143 &SomethingToEgg::dispatch_double, &_got_end_frame, &_end_frame);
00144
00145 add_option
00146 ("if", "frame-inc", 40,
00147 "Specifies the increment between successive frames. If omitted, "
00148 "this is taken from the time slider settings, or 1.0 if the time "
00149 "slider does not specify.",
00150 &SomethingToEgg::dispatch_double, &_got_frame_inc, &_frame_inc);
00151
00152 add_option
00153 ("nf", "neutral-frame", 40,
00154 "Specifies the frame number to use for the neutral pose. The model "
00155 "will be set to this frame before extracting out the neutral character. "
00156 "If omitted, the current frame of the model is used. This is only "
00157 "relevant for -a model or -a both.",
00158 &SomethingToEgg::dispatch_double, &_got_neutral_frame, &_neutral_frame);
00159
00160 add_option
00161 ("fri", "fps", 40,
00162 "Specify the frame rate (frames per second) of the input " + _format_name +
00163 " file. Normally, this can be inferred from the file itself.",
00164 &SomethingToEgg::dispatch_double, &_got_input_frame_rate, &_input_frame_rate);
00165
00166 add_option
00167 ("fro", "fps", 40,
00168 "Specify the frame rate (frames per second) of the generated animation. "
00169 "If this is specified, the animation speed is scaled by the appropriate "
00170 "factor based on the frame rate of the input file (see -fri).",
00171 &SomethingToEgg::dispatch_double, &_got_output_frame_rate, &_output_frame_rate);
00172 }
00173
00174
00175
00176
00177
00178
00179 void SomethingToEgg::
00180 add_merge_externals_options() {
00181 add_option
00182 ("f", "", 40,
00183 "Follow and convert all external references in the source file.",
00184 &SomethingToEgg::dispatch_none, &_merge_externals);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194 void SomethingToEgg::
00195 apply_units_scale(EggData *data) {
00196 if (_output_units != DU_invalid && _input_units != DU_invalid &&
00197 _input_units != _output_units) {
00198 nout << "Converting from " << format_long_unit(_input_units)
00199 << " to " << format_long_unit(_output_units) << "\n";
00200 double scale = convert_units(_input_units, _output_units);
00201 data->transform(LMatrix4d::scale_mat(scale));
00202 }
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 void SomethingToEgg::
00214 apply_parameters(SomethingToEggConverter &converter) {
00215 _path_replace->_noabs = _noabs;
00216 _path_replace->_exists = !_noexist;
00217 converter.set_path_replace(_path_replace);
00218
00219 converter.set_animation_convert(_animation_convert);
00220 converter.set_character_name(_character_name);
00221 if (_got_start_frame) {
00222 converter.set_start_frame(_start_frame);
00223 }
00224 if (_got_end_frame) {
00225 converter.set_end_frame(_end_frame);
00226 }
00227 if (_got_frame_inc) {
00228 converter.set_frame_inc(_frame_inc);
00229 }
00230 if (_got_neutral_frame) {
00231 converter.set_neutral_frame(_neutral_frame);
00232 }
00233 if (_got_input_frame_rate) {
00234 converter.set_input_frame_rate(_input_frame_rate);
00235 }
00236 if (_got_output_frame_rate) {
00237 converter.set_output_frame_rate(_output_frame_rate);
00238 }
00239 }
00240
00241
00242
00243
00244
00245
00246 bool SomethingToEgg::
00247 handle_args(Args &args) {
00248 if (_allow_last_param && !_got_output_filename && args.size() > 1) {
00249 _got_output_filename = true;
00250 _output_filename = Filename::from_os_specific(args.back());
00251 args.pop_back();
00252
00253 if (!(_output_filename.get_extension() == "egg")) {
00254 nout << "Output filename " << _output_filename
00255 << " does not end in .egg. If this is really what you intended, "
00256 "use the -o output_file syntax.\n";
00257 return false;
00258 }
00259
00260 if (!verify_output_file_safe()) {
00261 return false;
00262 }
00263 }
00264
00265 if (args.empty()) {
00266 nout << "You must specify the " << _format_name
00267 << " file to read on the command line.\n";
00268 return false;
00269 }
00270
00271 if (args.size() != 1) {
00272 nout << "You may only specify one " << _format_name
00273 << " file to read on the command line. "
00274 << "You specified: ";
00275 Args::const_iterator ai;
00276 for (ai = args.begin(); ai != args.end(); ++ai) {
00277 nout << (*ai) << " ";
00278 }
00279 nout << "\n";
00280 return false;
00281 }
00282
00283 _input_filename = Filename::from_os_specific(args[0]);
00284
00285 if (!_input_filename.exists()) {
00286 nout << "Cannot find input file " << _input_filename << "\n";
00287 return false;
00288 }
00289
00290 if (!_got_path_directory && _got_output_filename) {
00291
00292 _path_replace->_path_directory = _output_filename.get_dirname();
00293 }
00294
00295 return true;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 bool SomethingToEgg::
00309 post_command_line() {
00310
00311 ConfigVariableSearchPath &model_path = get_model_path();
00312 Filename directory = _input_filename.get_dirname();
00313 if (directory.empty()) {
00314 directory = ".";
00315 }
00316 model_path.prepend_directory(directory);
00317
00318 return EggConverter::post_command_line();
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 void SomethingToEgg::
00334 post_process_egg_file() {
00335 apply_units_scale(_data);
00336 EggConverter::post_process_egg_file();
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346 bool SomethingToEgg::
00347 dispatch_animation_convert(const string &opt, const string &arg, void *var) {
00348 AnimationConvert *ip = (AnimationConvert *)var;
00349 (*ip) = string_animation_convert(arg);
00350 if ((*ip) == AC_invalid) {
00351 nout << "Invalid keyword for -" << opt << ": " << arg << "\n";
00352 return false;
00353 }
00354
00355 return true;
00356 }