00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "eggReader.h"
00020
00021 #include "pnmImage.h"
00022 #include "config_util.h"
00023 #include "eggTextureCollection.h"
00024 #include "eggGroup.h"
00025 #include "eggGroupNode.h"
00026 #include "eggSwitchCondition.h"
00027 #include "string_utils.h"
00028 #include "dcast.h"
00029
00030
00031
00032
00033
00034
00035 EggReader::
00036 EggReader() {
00037 clear_runlines();
00038 add_runline("[opts] input.egg");
00039
00040 redescribe_option
00041 ("cs",
00042 "Specify the coordinate system to operate in. This may be "
00043 " one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default "
00044 "is the coordinate system of the input egg file.");
00045
00046 add_option
00047 ("f", "", 80,
00048 "Force complete loading: load up the egg file along with all of its "
00049 "external references.",
00050 &EggReader::dispatch_none, &_force_complete);
00051
00052 _tex_type = (PNMFileType *)NULL;
00053 _delod = -1.0;
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 void EggReader::
00070 add_texture_options() {
00071 add_option
00072 ("td", "dirname", 40,
00073 "Copy textures to the indicated directory. The copy is performed "
00074 "only if the destination file does not exist or is older than the "
00075 "source file.",
00076 &EggReader::dispatch_filename, &_got_tex_dirname, &_tex_dirname);
00077
00078 add_option
00079 ("te", "ext", 40,
00080 "Rename textures to have the indicated extension. This also "
00081 "automatically copies them to the new filename (possibly in a "
00082 "different directory if -td is also specified), and may implicitly "
00083 "convert to a different image format according to the extension.",
00084 &EggReader::dispatch_string, &_got_tex_extension, &_tex_extension);
00085
00086 add_option
00087 ("tt", "type", 40,
00088 "Explicitly specifies the image format to convert textures to "
00089 "when copying them via -td or -te. Normally, this is unnecessary as "
00090 "the image format can be determined by the extension, but sometimes "
00091 "the extension is insufficient to unambiguously specify an image "
00092 "type.",
00093 &EggReader::dispatch_image_type, NULL, &_tex_type);
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 void EggReader::
00107 add_delod_options(double default_delod) {
00108 _delod = default_delod;
00109
00110 if (default_delod < 0) {
00111 add_option
00112 ("delod", "dist", 40,
00113 "Eliminate LOD's by choosing the level that would be appropriate for "
00114 "a camera at the indicated fixed distance from each LOD. "
00115 "Use -delod -1 to keep all the LOD's as they are, which is "
00116 "the default.\n",
00117 &EggReader::dispatch_double, NULL, &_delod);
00118
00119 } else {
00120 add_option
00121 ("delod", "dist", 40,
00122 "Eliminate LOD's by choosing the level that would be appropriate for "
00123 "a camera at the indicated fixed distance from each LOD. "
00124 "Use -delod -1 to keep all the LOD's as they are. The default value "
00125 "is " + format_string(default_delod) + ".",
00126 &EggReader::dispatch_double, NULL, &_delod);
00127 }
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 EggReader *EggReader::
00143 as_reader() {
00144 return this;
00145 }
00146
00147
00148
00149
00150
00151
00152 bool EggReader::
00153 handle_args(ProgramBase::Args &args) {
00154 if (args.empty()) {
00155 nout << "You must specify the egg file(s) to read on the command line.\n";
00156 return false;
00157 }
00158
00159
00160
00161
00162 if (!args.empty()) {
00163 _data.set_egg_filename(Filename::from_os_specific(args[0]));
00164 }
00165 Args::const_iterator ai;
00166 for (ai = args.begin(); ai != args.end(); ++ai) {
00167 Filename filename = Filename::from_os_specific(*ai);
00168
00169 EggData file_data;
00170 if (!file_data.read(filename)) {
00171
00172
00173
00174 exit(1);
00175 }
00176
00177 DSearchPath file_path;
00178 file_path.append_directory(filename.get_dirname());
00179
00180
00181
00182
00183
00184 file_data.resolve_filenames(file_path);
00185
00186 if (_force_complete) {
00187 if (!file_data.load_externals()) {
00188 exit(1);
00189 }
00190 }
00191
00192
00193
00194 convert_paths(&file_data, _path_replace, file_path);
00195
00196 _data.merge(file_data);
00197 }
00198
00199 return true;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 bool EggReader::
00213 post_command_line() {
00214 return EggBase::post_command_line();
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 bool EggReader::
00226 do_reader_options() {
00227 bool okflag = true;
00228
00229 if (_got_tex_dirname || _got_tex_extension) {
00230 if (!copy_textures()) {
00231 okflag = false;
00232 }
00233 }
00234
00235 if (_delod >= 0.0) {
00236 do_delod(&_data);
00237 }
00238
00239 return okflag;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 bool EggReader::
00251 copy_textures() {
00252 bool success = true;
00253 EggTextureCollection textures;
00254 textures.find_used_textures(&_data);
00255
00256 EggTextureCollection::const_iterator ti;
00257 for (ti = textures.begin(); ti != textures.end(); ++ti) {
00258 EggTexture *tex = (*ti);
00259 Filename orig_filename = tex->get_filename();
00260 if (!orig_filename.exists()) {
00261 bool found =
00262 orig_filename.resolve_filename(get_texture_path()) ||
00263 orig_filename.resolve_filename(get_model_path());
00264 if (!found) {
00265 nout << "Cannot find " << orig_filename << "\n";
00266 success = false;
00267 continue;
00268 }
00269 }
00270
00271 Filename new_filename = orig_filename;
00272 if (_got_tex_dirname) {
00273 new_filename.set_dirname(_tex_dirname);
00274 }
00275 if (_got_tex_extension) {
00276 new_filename.set_extension(_tex_extension);
00277 }
00278
00279 if (orig_filename != new_filename) {
00280 tex->set_filename(new_filename);
00281
00282
00283 int compare =
00284 orig_filename.compare_timestamps(new_filename, true, true);
00285 if (compare > 0) {
00286
00287 nout << "Reading " << orig_filename << "\n";
00288 PNMImage image;
00289 if (!image.read(orig_filename)) {
00290 nout << " unable to read!\n";
00291 success = false;
00292 } else {
00293 nout << "Writing " << new_filename << "\n";
00294 if (!image.write(new_filename, _tex_type)) {
00295 nout << " unable to write!\n";
00296 success = false;
00297 }
00298 }
00299 }
00300 }
00301 }
00302
00303 return success;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 bool EggReader::
00315 do_delod(EggNode *node) {
00316 if (node->is_of_type(EggGroup::get_class_type())) {
00317 EggGroup *group = DCAST(EggGroup, node);
00318 if (group->has_lod()) {
00319 const EggSwitchCondition &cond = group->get_lod();
00320 if (cond.is_of_type(EggSwitchConditionDistance::get_class_type())) {
00321 const EggSwitchConditionDistance *dist =
00322 DCAST(EggSwitchConditionDistance, &cond);
00323 if (_delod >= dist->_switch_out && _delod < dist->_switch_in) {
00324
00325
00326 nout << "Preserving LOD " << node->get_name()
00327 << " (" << dist->_switch_out << " to " << dist->_switch_in
00328 << ")\n";
00329 group->clear_lod();
00330 } else {
00331
00332 nout << "Eliminating LOD " << node->get_name()
00333 << " (" << dist->_switch_out << " to " << dist->_switch_in
00334 << ")\n";
00335 return false;
00336 }
00337 }
00338 }
00339 }
00340
00341
00342 if (node->is_of_type(EggGroupNode::get_class_type())) {
00343 EggGroupNode *group = DCAST(EggGroupNode, node);
00344 EggGroupNode::iterator ci;
00345 ci = group->begin();
00346 while (ci != group->end()) {
00347 EggNode *child = *ci;
00348 ++ci;
00349
00350 if (!do_delod(child)) {
00351 group->remove_child(child);
00352 }
00353 }
00354 }
00355
00356 return true;
00357 }