Panda3D
xFileMaker.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 xFileMaker.cxx
10  * @author drose
11  * @date 2001-06-19
12  */
13 
14 #include "xFileMaker.h"
15 #include "xFileMesh.h"
16 #include "xFileMaterial.h"
17 #include "config_xfile.h"
18 
19 #include "pnotify.h"
20 #include "eggGroupNode.h"
21 #include "eggGroup.h"
22 #include "eggBin.h"
23 #include "eggPolysetMaker.h"
24 #include "eggVertexPool.h"
25 #include "eggVertex.h"
26 #include "eggPolygon.h"
27 #include "eggData.h"
28 #include "pvector.h"
29 #include "vector_int.h"
30 #include "string_utils.h"
31 #include "datagram.h"
32 
33 /**
34  *
35  */
36 XFileMaker::
37 XFileMaker() {
38  _mesh_index = 0;
39  _x_file = new XFile;
40 }
41 
42 /**
43  *
44  */
45 XFileMaker::
46 ~XFileMaker() {
47 }
48 
49 /**
50  * Writes the .x file data to the indicated filename; returns true on success,
51  * false otherwise.
52  */
53 bool XFileMaker::
54 write(const Filename &filename) {
55  return _x_file->write(filename);
56 }
57 
58 /**
59  * Adds the egg tree rooted at the indicated node to the X structure. This
60  * may be somewhat destructive of the egg tree. Returns true on success,
61  * false on failure.
62  */
63 bool XFileMaker::
64 add_tree(EggData *egg_data) {
65  _meshes.clear();
66 
67  // Now collect all the polygons together into polysets.
68  EggPolysetMaker pmaker;
69  pmaker.make_bins(egg_data);
70 
71  // And now we're ready to traverse the egg hierarchy.
72  if (!recurse_nodes(egg_data, _x_file)) {
73  return false;
74  }
75 
76  // Create X structures for all of the meshes we built up.
77  Meshes::iterator mi;
78  for (mi = _meshes.begin(); mi != _meshes.end(); ++mi) {
79  if (!finalize_mesh((*mi).first, (*mi).second)) {
80  return false;
81  }
82  }
83  _meshes.clear();
84 
85  return true;
86 }
87 
88 /**
89  * Adds the node to the DX structure, in whatever form it is supported.
90  */
91 bool XFileMaker::
92 add_node(EggNode *egg_node, XFileNode *x_parent) {
93  if (egg_node->is_of_type(EggBin::get_class_type())) {
94  return add_bin(DCAST(EggBin, egg_node), x_parent);
95 
96  } else if (egg_node->is_of_type(EggGroup::get_class_type())) {
97  return add_group(DCAST(EggGroup, egg_node), x_parent);
98 
99  } else if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
100  // A grouping node of some kind.
101  EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
102 
103  if (xfile_one_mesh) {
104  // Don't create any additional frames representing the egg hierarchy.
105  if (!recurse_nodes(egg_group, x_parent)) {
106  return false;
107  }
108 
109  } else {
110  // Create a Frame for each EggGroup.
111  XFileDataNode *x_frame = x_parent->add_Frame(egg_group->get_name());
112 
113  if (!recurse_nodes(egg_group, x_frame)) {
114  return false;
115  }
116  }
117 
118  return true;
119  }
120 
121  // Some unsupported node type. Ignore it.
122  return true;
123 }
124 
125 /**
126  * Adds a frame for the indicated group node.
127  */
128 bool XFileMaker::
129 add_group(EggGroup *egg_group, XFileNode *x_parent) {
130  if (xfile_one_mesh) {
131  // Don't create any additional frames representing the egg hierarchy.
132  if (!recurse_nodes(egg_group, x_parent)) {
133  return false;
134  }
135 
136  } else {
137  // Create a frame for each EggGroup.
138  XFileDataNode *x_frame = x_parent->add_Frame(egg_group->get_name());
139 
140  // Set the transform on the frame, if we have one.
141  if (egg_group->has_transform()) {
142  x_frame->add_FrameTransformMatrix(egg_group->get_transform3d());
143  }
144 
145  if (!recurse_nodes(egg_group, x_frame)) {
146  return false;
147  }
148  }
149 
150  return true;
151 }
152 
153 /**
154  * Determines what kind of object needs to be added for the indicated bin
155  * node.
156  */
157 bool XFileMaker::
158 add_bin(EggBin *egg_bin, XFileNode *x_parent) {
159  switch (egg_bin->get_bin_number()) {
160  case EggPolysetMaker::BN_polyset:
161  return add_polyset(egg_bin, x_parent);
162  }
163 
164  xfile_cat.error()
165  << "Unexpected bin type " << egg_bin->get_bin_number() << "\n";
166  return false;
167 }
168 
169 /**
170  * Adds a mesh object corresponding to the collection of polygons within the
171  * indicated bin.
172  */
173 bool XFileMaker::
174 add_polyset(EggBin *egg_bin, XFileNode *x_parent) {
175  // Make sure that all our polygons are reasonable.
176  egg_bin->remove_invalid_primitives(true);
177 
178  XFileMesh *mesh = get_mesh(x_parent);
179 
180  EggGroupNode::iterator ci;
181  for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
182  EggPolygon *poly;
183  DCAST_INTO_R(poly, *ci, false);
184 
185  mesh->add_polygon(poly);
186  }
187 
188  return true;
189 }
190 
191 
192 /**
193  * Adds each child of the indicated Node as a child of the indicated DX
194  * object.
195  */
196 bool XFileMaker::
197 recurse_nodes(EggGroupNode *egg_node, XFileNode *x_parent) {
198  EggGroupNode::iterator ci;
199  for (ci = egg_node->begin(); ci != egg_node->end(); ++ci) {
200  EggNode *child = (*ci);
201  if (!add_node(child, x_parent)) {
202  return false;
203  }
204  }
205 
206  return true;
207 }
208 
209 /**
210  * Returns a suitable XFileMesh object for creating meshes within the
211  * indicated x_parent object.
212  */
213 XFileMesh *XFileMaker::
214 get_mesh(XFileNode *x_parent) {
215  Meshes::iterator mi = _meshes.find(x_parent);
216  if (mi != _meshes.end()) {
217  // We've already started working on this x_parent before; use the same
218  // mesh object.
219  return (*mi).second;
220  }
221 
222  // We haven't seen this x_parent before; create a new mesh object.
223  XFileMesh *mesh = new XFileMesh;
224  _meshes.insert(Meshes::value_type(x_parent, mesh));
225  return mesh;
226 }
227 
228 
229 /**
230  * Creates the actual X structures corresponding to the indicated XFileMesh
231  * object.
232  */
233 bool XFileMaker::
234 finalize_mesh(XFileNode *x_parent, XFileMesh *mesh) {
235  // Get a unique number for each mesh.
236  _mesh_index++;
237  std::string mesh_index = format_string(_mesh_index);
238 
239  // Finally, create the Mesh object.
240  mesh->make_x_mesh(x_parent, mesh_index);
241 
242  return true;
243 }
config_xfile.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
eggData.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
eggVertexPool.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
XFileMesh::add_polygon
void add_polygon(EggPolygon *egg_poly)
Adds the indicated polygon to the mesh.
Definition: xFileMesh.cxx:97
string_utils.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
vector_int.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pvector.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
eggPolysetMaker.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggTransform::get_transform3d
const LMatrix4d & get_transform3d() const
Returns the overall transform as a 4x4 matrix.
Definition: eggTransform.I:212
xFileMaterial.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggGroupNode
A base class for nodes in the hierarchy that are not leaf nodes.
Definition: eggGroupNode.h:46
XFile
This represents the complete contents of an X file (file.x) in memory.
Definition: xFile.h:32
XFileMaker::write
bool write(const Filename &filename)
Writes the .x file data to the indicated filename; returns true on success, false otherwise.
Definition: xFileMaker.cxx:54
XFileMesh
This is a collection of polygons; i.e.
Definition: xFileMesh.h:45
XFileNode
A single node of an X file.
Definition: xFileNode.h:39
pnotify.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggGroupNode::remove_invalid_primitives
int remove_invalid_primitives(bool recurse)
Removes primitives at this level and below which appear to be degenerate; e.g.
Definition: eggGroupNode.cxx:879
XFileMesh::make_x_mesh
XFileDataNode * make_x_mesh(XFileNode *x_parent, const std::string &suffix)
Creates an X structure corresponding to the mesh.
Definition: xFileMesh.cxx:449
EggData
This is the primary interface into all the egg data, and the root of the egg file structure.
Definition: eggData.h:37
EggPolygon
A single polygon.
Definition: eggPolygon.h:24
eggVertex.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
xFileMesh.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
XFileMaker::add_tree
bool add_tree(EggData *egg_data)
Adds the egg tree rooted at the indicated node to the X structure.
Definition: xFileMaker.cxx:64
XFileNode::add_FrameTransformMatrix
XFileDataNode * add_FrameTransformMatrix(const LMatrix4d &mat)
Creates a new FrameTransformMatrix instance, as a child of this node.
Definition: xFileNode.cxx:436
datagram.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
eggGroupNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
eggBin.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggTransform::has_transform
bool has_transform() const
Returns true if the transform is nonempty, false if it is empty (no transform components have been ad...
Definition: eggTransform.I:143
EggBinMaker::make_bins
int make_bins(EggGroupNode *root_group)
The main entry point to EggBinMaker.
Definition: eggBinMaker.cxx:67
XFileDataNode
This is an abstract base class for an XFileNode which is also an XFileDataObject.
Definition: xFileDataNode.h:33
EggNode
A base class for things that may be directly added into the egg hierarchy.
Definition: eggNode.h:35
XFileNode::add_Frame
XFileDataNode * add_Frame(const std::string &name)
Creates a new Frame instance, as a child of this node.
Definition: xFileNode.cxx:421
EggGroup
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition: eggGroup.h:34
xFileMaker.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
eggGroup.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggPolysetMaker
A specialization on EggBinMaker for making polysets that share the same basic rendering characteristi...
Definition: eggPolysetMaker.h:32
Filename
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
EggBin
A type of group node that holds related subnodes.
Definition: eggBin.h:26
TypedObject::is_of_type
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
eggPolygon.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.