Panda3D
 All Classes Functions Variables Enumerations
colladaPrimitive.cxx
1 // Filename: colladaPrimitive.cxx
2 // Created by: rdb (23May11)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "colladaPrimitive.h"
16 #include "geomLines.h"
17 #include "geomLinestrips.h"
18 #include "geomTriangles.h"
19 #include "geomTrifans.h"
20 #include "geomTristrips.h"
21 
22 // Collada DOM includes. No other includes beyond this point.
23 #include "pre_collada_include.h"
24 #include <dom/domLines.h>
25 #include <dom/domLinestrips.h>
26 #include <dom/domPolygons.h>
27 #include <dom/domPolylist.h>
28 #include <dom/domTriangles.h>
29 #include <dom/domTrifans.h>
30 #include <dom/domTristrips.h>
31 
32 #if PANDA_COLLADA_VERSION < 15
33 #define domInput_local_offsetRef domInputLocalOffsetRef
34 #endif
35 
36 ////////////////////////////////////////////////////////////////////
37 // Function: ColladaPrimitive::Constructor
38 // Description: Why do I even bother documenting the simplest of
39 // constructors? A private one at that.
40 ////////////////////////////////////////////////////////////////////
41 ColladaPrimitive::
42 ColladaPrimitive(GeomPrimitive *prim, daeTArray<domInput_local_offsetRef> &inputs)
43  : _stride (1), _gprim (prim) {
44 
45  PT(GeomVertexArrayFormat) aformat = new GeomVertexArrayFormat;
46 
47  // Add the inputs one by one.
48  for (size_t in = 0; in < inputs.getCount(); ++in) {
49  PT(ColladaInput) input = ColladaInput::from_dom(*inputs[in]);
50  add_input(input);
51 
52  input->make_vertex_columns(aformat);
53  }
54 
55  // Create the vertex data.
56  PT(GeomVertexFormat) format = new GeomVertexFormat();
57  format->add_array(aformat);
58  _vdata = new GeomVertexData("", GeomVertexFormat::register_format(format), GeomEnums::UH_static);
59  _geom = new Geom(_vdata);
60  _geom->add_primitive(_gprim);
61 }
62 
63 ////////////////////////////////////////////////////////////////////
64 // Function: ColladaPrimitive::from_dom
65 // Description: Returns the ColladaPrimitive object that represents
66 // the provided DOM input element.
67 ////////////////////////////////////////////////////////////////////
69 from_dom(domLines &prim) {
70  // If we already loaded it before, use that.
71  if (prim.getUserData() != NULL) {
72  return (ColladaPrimitive *) prim.getUserData();
73  }
74 
75  ColladaPrimitive *new_prim =
76  new ColladaPrimitive(new GeomLines(GeomEnums::UH_static),
77  prim.getInput_array());
78  new_prim->_material = prim.getMaterial();
79 
80  prim.setUserData(new_prim);
81 
82  domPRef p = prim.getP();
83  if (p != NULL) {
84  new_prim->load_primitive(*p);
85  }
86 
87  return new_prim;
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: ColladaPrimitive::from_dom
92 // Description: Returns the ColladaPrimitive object that represents
93 // the provided DOM input element.
94 ////////////////////////////////////////////////////////////////////
96 from_dom(domLinestrips &prim) {
97  // If we already loaded it before, use that.
98  if (prim.getUserData() != NULL) {
99  return (ColladaPrimitive *) prim.getUserData();
100  }
101 
102  ColladaPrimitive *new_prim =
103  new ColladaPrimitive(new GeomLinestrips(GeomEnums::UH_static),
104  prim.getInput_array());
105  new_prim->_material = prim.getMaterial();
106 
107  prim.setUserData(new_prim);
108 
109  new_prim->load_primitives(prim.getP_array());
110 
111  return new_prim;
112 }
113 
114 ////////////////////////////////////////////////////////////////////
115 // Function: ColladaPrimitive::from_dom
116 // Description: Returns the ColladaPrimitive object that represents
117 // the provided DOM input element.
118 ////////////////////////////////////////////////////////////////////
120 from_dom(domPolygons &prim) {
121  // If we already loaded it before, use that.
122  if (prim.getUserData() != NULL) {
123  return (ColladaPrimitive *) prim.getUserData();
124  }
125 
126  // We use trifans to represent polygons, seems to be easiest.
127  // I tried using tristrips instead, but for some reason,
128  // this resulted in a few flipped polygons. Weird.
129  ColladaPrimitive *new_prim =
130  new ColladaPrimitive(new GeomTrifans(GeomEnums::UH_static),
131  prim.getInput_array());
132  new_prim->_material = prim.getMaterial();
133 
134  prim.setUserData(new_prim);
135 
136  new_prim->load_primitives(prim.getP_array());
137 
138  if (prim.getPh_array().getCount() > 0) {
139  collada_cat.error()
140  << "Polygons with holes are not supported!\n";
141  }
142 
143  return new_prim;
144 }
145 
146 ////////////////////////////////////////////////////////////////////
147 // Function: ColladaPrimitive::from_dom
148 // Description: Returns the ColladaPrimitive object that represents
149 // the provided DOM input element.
150 ////////////////////////////////////////////////////////////////////
152 from_dom(domPolylist &prim) {
153  // If we already loaded it before, use that.
154  if (prim.getUserData() != NULL) {
155  return (ColladaPrimitive *) prim.getUserData();
156  }
157 
158  // We use trifans to represent polygons, seems to be easiest.
159  // I tried using tristrips instead, but for some reason,
160  // this resulted in a few flipped polygons. Weird.
161  PT(GeomPrimitive) gprim = new GeomTrifans(GeomEnums::UH_static);
162 
163  ColladaPrimitive *new_prim =
164  new ColladaPrimitive(gprim, prim.getInput_array());
165  new_prim->_material = prim.getMaterial();
166 
167  prim.setUserData(new_prim);
168 
169  domPRef p = prim.getP();
170  domPolylist::domVcountRef vcounts = prim.getVcount();
171  if (p == NULL || vcounts == NULL) {
172  return new_prim;
173  }
174 
175  new_prim->write_data(new_prim->_vdata, 0, *p);
176 
177  daeTArray<domUint> &values = vcounts->getValue();
178  for (size_t i = 0; i < values.getCount(); ++i) {
179  unsigned int vcount = values[i];
180  gprim->add_next_vertices(vcount);
181  gprim->close_primitive();
182  }
183 
184  return new_prim;
185 }
186 
187 ////////////////////////////////////////////////////////////////////
188 // Function: ColladaPrimitive::from_dom
189 // Description: Returns the ColladaPrimitive object that represents
190 // the provided DOM input element.
191 ////////////////////////////////////////////////////////////////////
193 from_dom(domTriangles &prim) {
194  // If we already loaded it before, use that.
195  if (prim.getUserData() != NULL) {
196  return (ColladaPrimitive *) prim.getUserData();
197  }
198 
199  ColladaPrimitive *new_prim =
200  new ColladaPrimitive(new GeomTriangles(GeomEnums::UH_static),
201  prim.getInput_array());
202  new_prim->_material = prim.getMaterial();
203 
204  prim.setUserData(new_prim);
205 
206  domPRef p = prim.getP();
207  if (p != NULL) {
208  new_prim->load_primitive(*p);
209  }
210 
211  return new_prim;
212 }
213 
214 ////////////////////////////////////////////////////////////////////
215 // Function: ColladaPrimitive::from_dom
216 // Description: Returns the ColladaPrimitive object that represents
217 // the provided DOM input element.
218 ////////////////////////////////////////////////////////////////////
220 from_dom(domTrifans &prim) {
221  // If we already loaded it before, use that.
222  if (prim.getUserData() != NULL) {
223  return (ColladaPrimitive *) prim.getUserData();
224  }
225 
226  ColladaPrimitive *new_prim =
227  new ColladaPrimitive(new GeomTrifans(GeomEnums::UH_static),
228  prim.getInput_array());
229  new_prim->_material = prim.getMaterial();
230 
231  prim.setUserData(new_prim);
232 
233  new_prim->load_primitives(prim.getP_array());
234 
235  return new_prim;
236 }
237 
238 ////////////////////////////////////////////////////////////////////
239 // Function: ColladaPrimitive::from_dom
240 // Description: Returns the ColladaPrimitive object that represents
241 // the provided DOM input element.
242 ////////////////////////////////////////////////////////////////////
244 from_dom(domTristrips &prim) {
245  // If we already loaded it before, use that.
246  if (prim.getUserData() != NULL) {
247  return (ColladaPrimitive *) prim.getUserData();
248  }
249 
250  ColladaPrimitive *new_prim =
251  new ColladaPrimitive(new GeomTristrips(GeomEnums::UH_static),
252  prim.getInput_array());
253  new_prim->_material = prim.getMaterial();
254 
255  prim.setUserData(new_prim);
256 
257  new_prim->load_primitives(prim.getP_array());
258 
259  return new_prim;
260 }
261 
262 ////////////////////////////////////////////////////////////////////
263 // Function: ColladaPrimitive::write_data
264 // Description: Writes the vertex data to the GeomVertexData.
265 // Returns the number of rows written.
266 ////////////////////////////////////////////////////////////////////
267 unsigned int ColladaPrimitive::
268 write_data(GeomVertexData *vdata, int start_row, domP &p) {
269  unsigned int num_vertices = p.getValue().getCount() / _stride;
270 
271  Inputs::iterator it;
272  for (it = _inputs.begin(); it != _inputs.end(); ++it) {
273  (*it)->write_data(vdata, start_row, p, _stride);
274  }
275 
276  return num_vertices;
277 }
278 
279 ////////////////////////////////////////////////////////////////////
280 // Function: ColladaPrimitive::load_primitive
281 // Description: Adds the given indices to the primitive, and
282 // writes the relevant data to the geom.
283 ////////////////////////////////////////////////////////////////////
284 void ColladaPrimitive::
285 load_primitive(domP &p) {
286  _gprim->add_next_vertices(write_data(_vdata, 0, p));
287  _gprim->close_primitive();
288 }
289 
290 ////////////////////////////////////////////////////////////////////
291 // Function: ColladaPrimitive::load_primitives
292 // Description: Adds the given indices to the primitive, and
293 // writes the relevant data to the geom.
294 ////////////////////////////////////////////////////////////////////
295 void ColladaPrimitive::
296 load_primitives(domP_Array &p_array) {
297  int start_row = 0;
298 
299  for (size_t i = 0; i < p_array.getCount(); ++i) {
300  unsigned int num_vertices = write_data(_vdata, start_row, *p_array[i]);
301  _gprim->add_next_vertices(num_vertices);
302  _gprim->close_primitive();
303  start_row += num_vertices;
304  }
305 }
306 
Defines a series of triangle fans.
Definition: geomTrifans.h:25
This class exists just to provide scoping for the various enumerated types used by Geom...
Definition: geomEnums.h:27
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:63
Defines a series of triangle strips.
Definition: geomTristrips.h:25
Class that deals with COLLADA data sources.
Definition: colladaInput.h:45
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
Definition: geom.h:58
Defines a series of disconnected line segments.
Definition: geomLines.h:25
static ColladaPrimitive * from_dom(domLines &lines)
Returns the ColladaPrimitive object that represents the provided DOM input element.
Defines a series of line strips.
Defines a series of disconnected triangles.
Definition: geomTriangles.h:25
Class that deals with COLLADA primitive structures, such as &lt;triangles&gt; and &lt;polylist&gt;.
unsigned int write_data(GeomVertexData *vdata, int start_row, domP &p)
Writes the vertex data to the GeomVertexData.