Panda3D
eggMultiBase.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 eggMultiBase.cxx
10  * @author drose
11  * @date 2000-11-02
12  */
13 
14 #include "eggMultiBase.h"
15 #include "eggBase.h"
16 #include "eggData.h"
17 #include "eggComment.h"
18 #include "filename.h"
19 #include "dSearchPath.h"
20 
21 /**
22  *
23  */
24 EggMultiBase::
25 EggMultiBase() {
26  add_option
27  ("f", "", 80,
28  "Force complete loading: load up the egg file along with all of its "
29  "external references.",
30  &EggMultiBase::dispatch_none, &_force_complete);
31 
32  add_option
33  ("noabs", "", 0,
34  "Don't allow any of the named egg files to have absolute pathnames. "
35  "If any do, abort with an error. This option is designed to help "
36  "detect errors when populating or building a standalone model tree, "
37  "which should be self-contained and include only relative pathnames.",
38  &EggMultiBase::dispatch_none, &_noabs);
39 }
40 
41 /**
42  * Performs any processing of the egg file(s) that is appropriate before
43  * writing them out. This includes any normal adjustments the user requested
44  * via -np, etc.
45  *
46  * Normally, you should not need to call this function directly;
47  * write_egg_files() calls it for you. You should call this only if you do
48  * not use write_egg_files() to write out the resulting egg files.
49  */
52  if (_eggs.empty()) {
53  return;
54  }
55 
56  Eggs::iterator ei;
57  if (_got_transform) {
58  nout << "Applying transform matrix:\n";
59  _transform.write(nout, 2);
60  LVecBase3d scale, hpr, translate;
61  if (decompose_matrix(_transform, scale, hpr, translate,
62  _eggs[0]->get_coordinate_system())) {
63  nout << "(scale " << scale << ", hpr " << hpr << ", translate "
64  << translate << ")\n";
65  }
66  for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
67  (*ei)->transform(_transform);
68  }
69  }
70 
71  if (_make_points) {
72  nout << "Making points\n";
73  for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
74  (*ei)->make_point_primitives();
75  }
76  }
77 
78  switch (_normals_mode) {
79  case NM_strip:
80  nout << "Stripping normals.\n";
81  for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
82  (*ei)->strip_normals();
83  (*ei)->remove_unused_vertices(true);
84  }
85  break;
86 
87  case NM_polygon:
88  nout << "Recomputing polygon normals.\n";
89  for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
90  (*ei)->recompute_polygon_normals();
91  (*ei)->remove_unused_vertices(true);
92  }
93  break;
94 
95  case NM_vertex:
96  nout << "Recomputing vertex normals.\n";
97  for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
98  (*ei)->recompute_vertex_normals(_normals_threshold);
99  (*ei)->remove_unused_vertices(true);
100  }
101  break;
102 
103  case NM_preserve:
104  // Do nothing.
105  break;
106  }
107 
108  if (_got_tbnall) {
109  for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
110  if ((*ei)->recompute_tangent_binormal(GlobPattern("*"))) {
111  (*ei)->remove_unused_vertices(true);
112  }
113  }
114  } else {
115  if (_got_tbnauto) {
116  for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
117  if ((*ei)->recompute_tangent_binormal_auto()) {
118  (*ei)->remove_unused_vertices(true);
119  }
120  }
121  }
122 
123  for (vector_string::const_iterator si = _tbn_names.begin();
124  si != _tbn_names.end();
125  ++si) {
126  GlobPattern uv_name(*si);
127  nout << "Computing tangent and binormal for \"" << uv_name << "\"\n";
128  for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
129  (*ei)->recompute_tangent_binormal(uv_name);
130  (*ei)->remove_unused_vertices(true);
131  }
132  }
133  }
134 }
135 
136 
137 /**
138  * Allocates and returns a new EggData structure that represents the indicated
139  * egg file. If the egg file cannot be read for some reason, returns NULL.
140  *
141  * This can be overridden by derived classes to control how the egg files are
142  * read, or to extend the information stored with each egg structure, by
143  * deriving from EggData.
144  */
145 PT(EggData) EggMultiBase::
146 read_egg(const Filename &filename) {
147  PT(EggData) data = new EggData;
148 
149  if (!data->read(filename)) {
150  // Failure reading.
151  return nullptr;
152  }
153 
154  if (_noabs && data->original_had_absolute_pathnames()) {
155  nout << filename.get_basename()
156  << " includes absolute pathnames!\n";
157  return nullptr;
158  }
159 
160  DSearchPath file_path;
161  file_path.append_directory(filename.get_dirname());
162 
163  // We always resolve filenames first based on the source egg filename, since
164  // egg files almost always store relative paths. This is a temporary kludge
165  // around integrating the path_replace system with the EggData better.
166  // Update: I believe this kludge is obsolete. Commenting out. - Josh.
167  // data->resolve_filenames(file_path);
168 
169  if (_force_complete) {
170  if (!data->load_externals()) {
171  return nullptr;
172  }
173  }
174 
175  // Now resolve the filenames again according to the user's specified
176  // _path_replace.
177  EggBase::convert_paths(data, _path_replace, file_path);
178 
179  if (_got_coordinate_system) {
180  data->set_coordinate_system(_coordinate_system);
181  } else {
182  _coordinate_system = data->get_coordinate_system();
183  _got_coordinate_system = true;
184  }
185 
186  return data;
187 }
This class stores a list of directories that can be searched, in order, to locate a particular file.
Definition: dSearchPath.h:28
void append_directory(const Filename &directory)
Adds a new directory to the end of the search list.
static void convert_paths(EggNode *node, PathReplace *path_replace, const DSearchPath &additional_path)
Recursively walks the egg hierarchy.
Definition: eggBase.cxx:158
This is the primary interface into all the egg data, and the root of the egg file structure.
Definition: eggData.h:37
void post_process_egg_files()
Performs any processing of the egg file(s) that is appropriate before writing them out.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
std::string get_basename() const
Returns the basename part of the filename.
Definition: filename.I:367
std::string get_dirname() const
Returns the directory part of the filename.
Definition: filename.I:358
This class can be used to test for string matches against standard Unix- shell filename globbing conv...
Definition: globPattern.h:32
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT(EggData) EggMultiBase
Allocates and returns a new EggData structure that represents the indicated egg file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.