1 /*
2     Copyright (c) 2008-2009 NetAllied Systems GmbH
3 
4     This file is part of COLLADASaxFrameworkLoader.
5 
6     Licensed under the MIT Open Source License,
7     for details please see LICENSE file or the website
8     http://www.opensource.org/licenses/mit-license.php
9 */
10 
11 #ifndef __COLLADASAXFWL_MESHLOADER_H__
12 #define __COLLADASAXFWL_MESHLOADER_H__
13 
14 #include "COLLADASaxFWLPrerequisites.h"
15 #include "COLLADASaxFWLVertices.h"
16 #include "COLLADASaxFWLSource.h"
17 #include "COLLADASaxFWLMeshPrimitiveInputList.h"
18 #include "COLLADASaxFWLSourceArrayLoader.h"
19 
20 #include "COLLADAFWMesh.h"
21 
22 
23 namespace COLLADASaxFWL
24 {
25 
26     /**
27      * Describes basic geometric meshes using vertex and primitive information.
28      * Meshes embody a general form of geometric description that primarily
29      * includes vertex and primitive information.
30      * Vertex information is the set of attributes associated with a point on
31      * the surface of the mesh. Each vertex includes data for attributes such as:
32      * - Vertex position
33      * - Vertex color
34      * - Vertex normal
35      * - Vertex texture coordinate
36      * The mesh also includes a description of how the vertices are organized to
37      * form the geometric shape of the mesh. The mesh vertices are collated into
38      * geometric primitives such as polygons, triangles, or lines.
39      */
40     class MeshLoader : public SourceArrayLoader
41     {
42     public:
43 
44         struct PrimitiveInput
45         {
46             String mName;
47             size_t mOffset;
48             size_t mStride;
49             size_t mSetIndex;
50             size_t mInitialIndex;
51         };
52 
53 	private:
54 		enum PrimitiveType
55 		{
56 			NONE,
57 			TRIANGLES,
58 			TRISTRIPS,
59 			TRIFANS,
60 			POLYGONS,
61 			POLYGONS_HOLE,
62 			POLYLIST,
63 			LINESTRIPS,
64 			LINES
65 		};
66     private:
67 
68 		/** The unique id of the mesh.*/
69 		COLLADAFW::UniqueId mMeshUniqueId;
70 
71         /**
72          * The framework mesh element, to load the data.
73          */
74         COLLADAFW::Mesh* mMesh;
75 
76 		/** The mapping of collada symbols to material ids.*/
77 		GeometryMaterialIdInfo& mMaterialIdInfo;
78 
79 		/** The material symbol of the current mesh. Is only used for primitives, for which the
80 		the framework object is not created in the begin__* method.*/
81 		String mCurrentMeshMaterial;
82 
83 		/** The mesh primitive being filled by the parser.*/
84 		COLLADAFW::MeshPrimitive* mCurrentMeshPrimitive;
85 
86         /**
87          * Describes the mesh-vertex attributes and establishes
88          * their topological identity.
89          */
90         Vertices mVerticesInputs;
91 
92         /** Flag is true, if we are currently in the vertices part. */
93         bool mInVertices;
94 
95 		/** The vertex input being parse.*/
96 		InputUnshared* mCurrentVertexInput;
97 
98 		/**
99 		* Describes the mesh-vertex attributes and establishes
100 		* their topological identity.
101 		*/
102 		MeshPrimitiveInputList mMeshPrimitiveInputs;
103 
104 		/** The mesh primitive input being parse.*/
105 		InputSharedArray* mCurrentMeshPrimitiveInput;
106 
107 		/** The offset of the next index received from the sax parser.*/
108 		size_t mCurrentOffset;
109 
110 		/** The max offset of the current MeshPrimitive.*/
111 		size_t mCurrentMaxOffset;
112 
113 		/** The vertex count of the current MeshPrimitive.*/
114 		size_t mCurrentVertexCount;
115 
116 		/** The vertex count after the last face of the current MeshPrimitive was completed.*/
117 		size_t mCurrentLastPrimitiveVertexCount;
118 
119 		/** Used only when loading ph elements of polygons. Indicates, if the last found p element,
120 		which is a child of a ph element is empty, i.e. contains no indices. This memeber is set in
121 		end__ph__p and read in end__h and data__h*/
122 		bool mCurrentPhHasEmptyP;
123 
124 		/** The expected vertex count of the current MeshPrimitive. Uses this, if the face vertex count can be
125 		predicted or calculated, before reading the p elements.*/
126 		size_t mCurrentExpectedVertexCount;
127 
128 		/** The number of faces of the current MeshPrimitive. Uses this, if the face count cannot be calculated
129 		using the values above. (for collada polygons).*/
130 		size_t mCurrentFaceOrLineCount;
131 
132 		/** The value of the count attribute in the COLLADA primitive. Might be used to pre-alloc memory.*/
133 		size_t mCurrentCOLLADAPrimitiveCount;
134 
135         /** Variables for the offsets of the index input elements. */
136         unsigned long long mPositionsOffset;
137 		unsigned int mPositionsIndexOffset;
138         bool mUsePositions;
139 
140         unsigned long long mNormalsOffset;
141 		unsigned int mNormalsIndexOffset;
142         bool mUseNormals;
143 
144         unsigned long long mTangentsOffset;
145         unsigned int mTangentsIndexOffset;
146         bool mUseTangents;
147 
148         unsigned long long mBinormalsOffset;
149         unsigned int mBinormalsIndexOffset;
150         bool mUseBinormals;
151 
152         /** Multiple colors. */
153         std::vector<PrimitiveInput> mColorList;
154 
155         /** Multiple texcoordinates. */
156         std::vector<PrimitiveInput> mTexCoordList;
157 
158         /** The type of the current primitive element. */
159 		PrimitiveType mCurrentPrimitiveType;
160 
161 		/** Number of already closed p elements in current primitive.*/
162 		unsigned int mPOrPhElementCountOfCurrentPrimitive;
163 
164         /** We need a variable for the second key name. */
165         String mSecondKey;
166 
167         /** Flag for the extra tag preservation, to know if we are parsing in the mesh. */
168         bool mInMesh;
169 
170     public:
171 
172         /** Constructor. */
173 		MeshLoader ( IFilePartLoader* callingFilePartLoader, const String& geometryId, const String& geometryName );
174 
175         /** Destructor. */
~MeshLoader()176         virtual ~MeshLoader () { delete mMesh; }
177 
178         /** Returns the unique id of the current parsed object. */
179         virtual const COLLADAFW::UniqueId& getUniqueId();
180 
181         /** Returns the mesh that has just been loaded.*/
getMesh()182 		COLLADAFW::Mesh* getMesh() { return mMesh; }
183 
184 		/** Sax callback function for the beginning of a source element.*/
185 		virtual bool begin__source(const source__AttributeData& attributes);
186 
187 		/** Sax callback function for the ending of a source element.*/
188 		virtual bool end__source();
189 
190 		/** Cleans up everything and gives control to calling file part loader.*/
191 		virtual bool end__mesh();
192 
193         /** Flag for the extra tag preservation, to know if we are parsing in the mesh. */
isInMesh()194         const bool& isInMesh () const { return mInMesh; }
setInMesh(const bool & val)195         void setInMesh ( const bool& val ) { mInMesh = val; }
196 
197 		/** Sax callback function for the beginning of a vertices element.*/
198 		virtual bool begin__vertices( const vertices__AttributeData& attributeData );
199 
200 		/** Sax callback function for the ending of a vertices element.*/
201 		virtual bool end__vertices();
202 
203 
204 		/** Sax callback function for the beginning of a input element.*/
205 		virtual bool begin__input____InputLocal( const input____InputLocal__AttributeData& attributeData );
206 
207 		/** Sax callback function for the ending of a input element.*/
208 		virtual bool end__input____InputLocal();
209 
210 
211 		/** Sax callback function for the beginning of a triangles element.*/
212 		virtual bool begin__triangles( const triangles__AttributeData& attributeData );
213 
214 		/** Sax callback function for the ending of a triangles element.*/
215 		virtual bool end__triangles();
216 
217 
218 		/** Sax callback function for the beginning of a triangles input element.*/
219 		virtual bool begin__input____InputLocalOffset( const input____InputLocalOffset__AttributeData& attributeData );
220 
221 		/** Sax callback function for the ending of a triangles input element.*/
222 		virtual bool end__input____InputLocalOffset();
223 
224 
225 		/** Sax callback function for the beginning of a p.*/
226 		virtual bool begin__p();
227 
228 		/** Sax callback function for the ending of a p.*/
229 		virtual bool end__p();
230 
231 		/** Sax callback function for the data of a p within a triangles element element.*/
232 		virtual bool data__p( const unsigned long long* data, size_t length );
233 
234 
235 		/** Sax callback function for the beginning of a polylist element.*/
236 		virtual bool begin__polylist( const polylist__AttributeData& attributeData );
237 
238 		/** Sax callback function for the ending of a polylist element.*/
239 		virtual bool end__polylist();
240 
241 
242 		/** Sax callback function for the beginning of a lines element.*/
243 		virtual bool begin__lines( const lines__AttributeData& attributeData );
244 
245 		/** Sax callback function for the ending of a lines element.*/
246 		virtual bool end__lines();
247 
248 
249 		/** Sax callback function for the beginning of a line strips element.*/
250 		virtual bool begin__linestrips( const linestrips__AttributeData& attributeData );
251 
252 		/** Sax callback function for the ending of a line strips element.*/
253 		virtual bool end__linestrips();
254 
255 
256 		/** Sax callback function for the beginning of a polylist vcount element.*/
257 		virtual bool begin__vcount();
258 
259 		/** Sax callback function for the ending of a polylist vcount element.*/
260 		virtual bool end__vcount();
261 
262 		/** Sax callback function for the data of a polylist vcount element.*/
263 		virtual bool data__vcount( const unsigned long long*, size_t length );
264 
265 
266 		/** Sax callback function for the beginning of a polygons element.*/
267 		virtual bool begin__polygons( const polygons__AttributeData& attributeData );
268 
269 		/** Sax callback function for the ending of a polygons element.*/
270 		virtual bool end__polygons();
271 
272 
273 		/** Sax callback function for the beginning of a polygons ph element.*/
274 		virtual bool begin__ph();
275 
276 		/** Sax callback function for the ending of a polygons ph element.*/
277 		virtual bool end__ph();
278 
279 
280 		/** Sax callback function for the beginning of a polygons h element inside a ph element.*/
281 		virtual bool begin__h();
282 
283 		/** Sax callback function for the ending of a polygons h element inside a ph element.*/
284 		virtual bool end__h();
285 
286 		/** Sax callback function for the data of a polygons h element inside a ph element.*/
287 		virtual bool data__h( const uint64* data, size_t length );
288 
289 
290 		/** Sax callback function for the beginning of a polygons element.*/
291 		virtual bool begin__tristrips( const tristrips__AttributeData& attributeData );
292 
293 		/** Sax callback function for the ending of a polygons element.*/
294 		virtual bool end__tristrips();
295 
296 
297 		/** Sax callback function for the beginning of a polygons element.*/
298 		virtual bool begin__trifans( const trifans__AttributeData& attributeData );
299 
300 		/** Sax callback function for the ending of a polygons element.*/
301 		virtual bool end__trifans();
302 
303 
304 		/** Stores the information provided by the attributes of an input element for all mesh primitives.*/
305 		bool beginInput(const input____InputLocalOffset__AttributeData& attributeData);
306 
307 
308 	private:
309 
310 		/** Initializes all the current values, i.e. values used while parsing a mesh primitive.*/
311 		void initCurrentValues();
312 
313         /**
314         * Returns the vertex input element with the given semantic or 0 if it not exist.
315         * @param semantic The semantic of the searched input element.
316         * @return InputShared* Pointer to the searched input element or 0 if it not exist.
317         */
318         const InputUnshared* getVertexInputBySemantic ( const InputSemantic::Semantic& semantic ) const;
319 
320         /**
321          * Returns a pointer to the searched source element of the given input semantic,
322          * if it is a vertex input element.
323          * @param semantic The input semantic, from which the source element is searched.
324          * @return Source* Pointer to the searched source element.
325          */
326         const SourceBase* getSourceByInputSemanticFromVertices ( const InputSemantic::Semantic& semantic ) const;
327 
328         /**
329         * Returns a pointer to the positions source element.
330         * @return Source* Pointer to the positions source element.
331         */
332         const SourceBase* getPositionsSource () const;
333 
334         /**
335         * Returns a pointer to the positions source element with float values.
336         * @return Source* Pointer to the positions source element.
337         */
338         const FloatSource* getPositionsFloatSource () const;
339 
340         /**
341         * Returns a pointer to the positions source element with float values.
342         * @return Source* Pointer to the positions source element.
343         */
344         const DoubleSource* getPositionsDoubleSource () const;
345 
346         /**
347          * Describes the mesh-vertex attributes and establishes their topological identity.
348          * @return const Vertices The mesh-vertex attributes.
349          */
getVertices()350         Vertices& getVertices () { return mVerticesInputs; }
351 
352         /**
353         * Describes the mesh-vertex attributes and establishes their topological identity.
354         * @return const Vertices The mesh-vertex attributes.
355         */
getVertices()356         const Vertices& getVertices () const { return mVerticesInputs; }
357 
358         /**
359          * Describes the mesh-vertex attributes and establishes their topological identity.
360          * @param vertices The mesh-vertex attributes.
361          */
setVertices(const Vertices & vertices)362         void setVertices ( const Vertices& vertices ) { mVerticesInputs = vertices; }
363 
364 
365 		/** Sets the offsets for the different semantics (positions normals etc)*/
366         bool initializeOffsets();
367         bool initializeTexCoordsOffset ();
368         bool initializeColorsOffset ();
369         void initializeNormalsOffset ();
370         void initializeTangentsOffset ();
371         void initializeBinormalsOffset ();
372         bool initializePositionsOffset ();
373 
374 		/** Writes all the indices in data into the indices array of the current mesh primitive.*/
375 		bool writePrimitiveIndices ( const unsigned long long* data, size_t length );
376 
377         /**
378          * Get the number of all indices in all p elements in the current primitive element.
379          */
380         size_t getNumOfPrimitiveIndices ( const MeshPrimitiveInputList* polyBaseElement );
381 
382         /**
383          * Go through the list of input elements of the current poly base and get the
384          * source data of the input elements and write it into the source elements.
385          * Attention: if there are multiple sources for the same semantic, we have to
386          * concat the source arrays and the indices!
387          */
388         void loadSourceElements ( const MeshPrimitiveInputList& polyBaseElement );
389 
390         /**
391          * Load the source element of the current input element into the framework mesh.
392          */
393         bool loadSourceElement ( const InputShared& input );
394 
395         /**
396         * Load the positions source element of the current input element into the framework mesh.
397         */
398         bool loadPositionsSourceElement ( const InputShared& input );
399 
400         /**
401         * Load the normals source element of the current input element into the framework mesh.
402         */
403         bool loadNormalsSourceElement ( const InputShared& input );
404 
405         /**
406         * Load the colors source element of the current input element into the framework mesh.
407         */
408         bool loadColorsSourceElement ( const InputShared& input );
409 
410         /**
411         * Load the uv coordinates source element of the current input element into the framework mesh.
412         */
413         bool loadTexCoordsSourceElement ( const InputShared& input );
414 
415         /**
416         * Load the tangent source element of the current input element into the framework mesh
417         */
418 
419         bool loadTexBinormalSourceElement( const InputShared & input );
420 
421         /**
422         * Load the tangent source element of the current input element into the framework mesh
423         */
424 
425         bool loadTexTangentSourceElement( const InputShared & input );
426 
427         /**
428         * Appends the values of the source in the list with the dimension of source's stride.
429         */
430         bool appendVertexValues (
431             SourceBase* sourceBase,
432             COLLADAFW::MeshVertexData& vertexData );
433     };
434 }
435 
436 #endif // __COLLADASAXFWL_MESHLOADER_H__
437