Panda3D

eggMultiBase.cxx

00001 // Filename: eggMultiBase.cxx
00002 // Created by:  drose (02Nov00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "eggMultiBase.h"
00016 #include "eggBase.h"
00017 #include "eggData.h"
00018 #include "eggComment.h"
00019 #include "filename.h"
00020 #include "dSearchPath.h"
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function: EggMultiBase::Constructor
00024 //       Access: Public
00025 //  Description:
00026 ////////////////////////////////////////////////////////////////////
00027 EggMultiBase::
00028 EggMultiBase() {
00029   add_option
00030     ("f", "", 80,
00031      "Force complete loading: load up the egg file along with all of its "
00032      "external references.",
00033      &EggMultiBase::dispatch_none, &_force_complete);
00034 
00035   add_option
00036     ("noabs", "", 0,
00037      "Don't allow any of the named egg files to have absolute pathnames.  "
00038      "If any do, abort with an error.  This option is designed to help "
00039      "detect errors when populating or building a standalone model tree, "
00040      "which should be self-contained and include only relative pathnames.",
00041      &EggMultiBase::dispatch_none, &_noabs);
00042 }
00043 
00044 ////////////////////////////////////////////////////////////////////
00045 //     Function: EggMultiBase::post_process_egg_files
00046 //       Access: Public
00047 //  Description: Performs any processing of the egg file(s) that is
00048 //               appropriate before writing them out.  This includes any
00049 //               normal adjustments the user requested via -np, etc.
00050 //
00051 //               Normally, you should not need to call this function
00052 //               directly; write_egg_files() calls it for you.  You
00053 //               should call this only if you do not use
00054 //               write_egg_files() to write out the resulting egg
00055 //               files.
00056 ////////////////////////////////////////////////////////////////////
00057 void EggMultiBase::
00058 post_process_egg_files() {
00059   if (_eggs.empty()) {
00060     return;
00061   }
00062 
00063   Eggs::iterator ei;
00064   if (_got_transform) {
00065     nout << "Applying transform matrix:\n";
00066     _transform.write(nout, 2);
00067     LVecBase3d scale, hpr, translate;
00068     if (decompose_matrix(_transform, scale, hpr, translate,
00069                          _eggs[0]->get_coordinate_system())) {
00070       nout << "(scale " << scale << ", hpr " << hpr << ", translate "
00071            << translate << ")\n";
00072     }
00073     for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
00074       (*ei)->transform(_transform);
00075     }
00076   }
00077 
00078   if (_make_points) {
00079     nout << "Making points\n";
00080     for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
00081       (*ei)->make_point_primitives();
00082     }
00083   }
00084 
00085   switch (_normals_mode) {
00086   case NM_strip:
00087     nout << "Stripping normals.\n";
00088     for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
00089       (*ei)->strip_normals();
00090       (*ei)->remove_unused_vertices(true);
00091     }
00092     break;
00093 
00094   case NM_polygon:
00095     nout << "Recomputing polygon normals.\n";
00096     for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
00097       (*ei)->recompute_polygon_normals();
00098       (*ei)->remove_unused_vertices(true);
00099     }
00100     break;
00101 
00102   case NM_vertex:
00103     nout << "Recomputing vertex normals.\n";
00104     for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
00105       (*ei)->recompute_vertex_normals(_normals_threshold);
00106       (*ei)->remove_unused_vertices(true);
00107     }
00108     break;
00109 
00110   case NM_preserve:
00111     // Do nothing.
00112     break;
00113   }
00114 }
00115 
00116 
00117 ////////////////////////////////////////////////////////////////////
00118 //     Function: EggMultiBase::read_egg
00119 //       Access: Protected, Virtual
00120 //  Description: Allocates and returns a new EggData structure that
00121 //               represents the indicated egg file.  If the egg file
00122 //               cannot be read for some reason, returns NULL.
00123 //
00124 //               This can be overridden by derived classes to control
00125 //               how the egg files are read, or to extend the
00126 //               information stored with each egg structure, by
00127 //               deriving from EggData.
00128 ////////////////////////////////////////////////////////////////////
00129 PT(EggData) EggMultiBase::
00130 read_egg(const Filename &filename) {
00131   PT(EggData) data = new EggData;
00132 
00133   if (!data->read(filename)) {
00134     // Failure reading.
00135     return (EggData *)NULL;
00136   }
00137 
00138   if (_noabs && data->original_had_absolute_pathnames()) {
00139     nout << filename.get_basename()
00140          << " includes absolute pathnames!\n";
00141     return (EggData *)NULL;
00142   }
00143 
00144   DSearchPath file_path;
00145   file_path.append_directory(filename.get_dirname());
00146 
00147   // We always resolve filenames first based on the source egg
00148   // filename, since egg files almost always store relative paths.
00149   // This is a temporary kludge around integrating the path_replace
00150   // system with the EggData better.
00151   //
00152   // Update: I believe this kludge is obsolete. Commenting out. - Josh.
00153   // data->resolve_filenames(file_path);
00154 
00155   if (_force_complete) {
00156     if (!data->load_externals()) {
00157       return (EggData *)NULL;
00158     }
00159   }
00160 
00161   // Now resolve the filenames again according to the user's
00162   // specified _path_replace.
00163   EggBase::convert_paths(data, _path_replace, file_path);
00164 
00165   if (_got_coordinate_system) {
00166     data->set_coordinate_system(_coordinate_system);
00167   } else {
00168     _coordinate_system = data->get_coordinate_system();
00169     _got_coordinate_system = true;
00170   }
00171 
00172   return data;
00173 }
 All Classes Functions Variables Enumerations