rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 Open Asset Import Library (assimp)
|
nuclear@0
|
3 ----------------------------------------------------------------------
|
nuclear@0
|
4
|
nuclear@0
|
5 Copyright (c) 2006-2012, assimp team
|
nuclear@0
|
6 All rights reserved.
|
nuclear@0
|
7
|
nuclear@0
|
8 Redistribution and use of this software in source and binary forms,
|
nuclear@0
|
9 with or without modification, are permitted provided that the
|
nuclear@0
|
10 following conditions are met:
|
nuclear@0
|
11
|
nuclear@0
|
12 * Redistributions of source code must retain the above
|
nuclear@0
|
13 copyright notice, this list of conditions and the
|
nuclear@0
|
14 following disclaimer.
|
nuclear@0
|
15
|
nuclear@0
|
16 * Redistributions in binary form must reproduce the above
|
nuclear@0
|
17 copyright notice, this list of conditions and the
|
nuclear@0
|
18 following disclaimer in the documentation and/or other
|
nuclear@0
|
19 materials provided with the distribution.
|
nuclear@0
|
20
|
nuclear@0
|
21 * Neither the name of the assimp team, nor the names of its
|
nuclear@0
|
22 contributors may be used to endorse or promote products
|
nuclear@0
|
23 derived from this software without specific prior
|
nuclear@0
|
24 written permission of the assimp team.
|
nuclear@0
|
25
|
nuclear@0
|
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
nuclear@0
|
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
nuclear@0
|
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
nuclear@0
|
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
nuclear@0
|
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
nuclear@0
|
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
nuclear@0
|
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
nuclear@0
|
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
nuclear@0
|
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
nuclear@0
|
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
nuclear@0
|
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
nuclear@0
|
37
|
nuclear@0
|
38 ----------------------------------------------------------------------
|
nuclear@0
|
39 */
|
nuclear@0
|
40
|
nuclear@0
|
41 /** @file ColladaParser.h
|
nuclear@0
|
42 * @brief Defines the parser helper class for the collada loader
|
nuclear@0
|
43 */
|
nuclear@0
|
44
|
nuclear@0
|
45 #ifndef AI_COLLADAPARSER_H_INC
|
nuclear@0
|
46 #define AI_COLLADAPARSER_H_INC
|
nuclear@0
|
47
|
nuclear@0
|
48 #include "irrXMLWrapper.h"
|
nuclear@0
|
49 #include "ColladaHelper.h"
|
nuclear@0
|
50
|
nuclear@0
|
51 namespace Assimp
|
nuclear@0
|
52 {
|
nuclear@0
|
53
|
nuclear@0
|
54 // ------------------------------------------------------------------------------------------
|
nuclear@0
|
55 /** Parser helper class for the Collada loader.
|
nuclear@0
|
56 *
|
nuclear@0
|
57 * Does all the XML reading and builds internal data structures from it,
|
nuclear@0
|
58 * but leaves the resolving of all the references to the loader.
|
nuclear@0
|
59 */
|
nuclear@0
|
60 class ColladaParser
|
nuclear@0
|
61 {
|
nuclear@0
|
62 friend class ColladaLoader;
|
nuclear@0
|
63
|
nuclear@0
|
64 protected:
|
nuclear@0
|
65 /** Constructor from XML file */
|
nuclear@0
|
66 ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
|
nuclear@0
|
67
|
nuclear@0
|
68 /** Destructor */
|
nuclear@0
|
69 ~ColladaParser();
|
nuclear@0
|
70
|
nuclear@0
|
71 /** Reads the contents of the file */
|
nuclear@0
|
72 void ReadContents();
|
nuclear@0
|
73
|
nuclear@0
|
74 /** Reads the structure of the file */
|
nuclear@0
|
75 void ReadStructure();
|
nuclear@0
|
76
|
nuclear@0
|
77 /** Reads asset informations such as coordinate system informations and legal blah */
|
nuclear@0
|
78 void ReadAssetInfo();
|
nuclear@0
|
79
|
nuclear@0
|
80 /** Reads the animation library */
|
nuclear@0
|
81 void ReadAnimationLibrary();
|
nuclear@0
|
82
|
nuclear@0
|
83 /** Reads an animation into the given parent structure */
|
nuclear@0
|
84 void ReadAnimation( Collada::Animation* pParent);
|
nuclear@0
|
85
|
nuclear@0
|
86 /** Reads an animation sampler into the given anim channel */
|
nuclear@0
|
87 void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
|
nuclear@0
|
88
|
nuclear@0
|
89 /** Reads the skeleton controller library */
|
nuclear@0
|
90 void ReadControllerLibrary();
|
nuclear@0
|
91
|
nuclear@0
|
92 /** Reads a controller into the given mesh structure */
|
nuclear@0
|
93 void ReadController( Collada::Controller& pController);
|
nuclear@0
|
94
|
nuclear@0
|
95 /** Reads the joint definitions for the given controller */
|
nuclear@0
|
96 void ReadControllerJoints( Collada::Controller& pController);
|
nuclear@0
|
97
|
nuclear@0
|
98 /** Reads the joint weights for the given controller */
|
nuclear@0
|
99 void ReadControllerWeights( Collada::Controller& pController);
|
nuclear@0
|
100
|
nuclear@0
|
101 /** Reads the image library contents */
|
nuclear@0
|
102 void ReadImageLibrary();
|
nuclear@0
|
103
|
nuclear@0
|
104 /** Reads an image entry into the given image */
|
nuclear@0
|
105 void ReadImage( Collada::Image& pImage);
|
nuclear@0
|
106
|
nuclear@0
|
107 /** Reads the material library */
|
nuclear@0
|
108 void ReadMaterialLibrary();
|
nuclear@0
|
109
|
nuclear@0
|
110 /** Reads a material entry into the given material */
|
nuclear@0
|
111 void ReadMaterial( Collada::Material& pMaterial);
|
nuclear@0
|
112
|
nuclear@0
|
113 /** Reads the camera library */
|
nuclear@0
|
114 void ReadCameraLibrary();
|
nuclear@0
|
115
|
nuclear@0
|
116 /** Reads a camera entry into the given camera */
|
nuclear@0
|
117 void ReadCamera( Collada::Camera& pCamera);
|
nuclear@0
|
118
|
nuclear@0
|
119 /** Reads the light library */
|
nuclear@0
|
120 void ReadLightLibrary();
|
nuclear@0
|
121
|
nuclear@0
|
122 /** Reads a light entry into the given light */
|
nuclear@0
|
123 void ReadLight( Collada::Light& pLight);
|
nuclear@0
|
124
|
nuclear@0
|
125 /** Reads the effect library */
|
nuclear@0
|
126 void ReadEffectLibrary();
|
nuclear@0
|
127
|
nuclear@0
|
128 /** Reads an effect entry into the given effect*/
|
nuclear@0
|
129 void ReadEffect( Collada::Effect& pEffect);
|
nuclear@0
|
130
|
nuclear@0
|
131 /** Reads an COMMON effect profile */
|
nuclear@0
|
132 void ReadEffectProfileCommon( Collada::Effect& pEffect);
|
nuclear@0
|
133
|
nuclear@0
|
134 /** Read sampler properties */
|
nuclear@0
|
135 void ReadSamplerProperties( Collada::Sampler& pSampler);
|
nuclear@0
|
136
|
nuclear@0
|
137 /** Reads an effect entry containing a color or a texture defining that color */
|
nuclear@0
|
138 void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
|
nuclear@0
|
139
|
nuclear@0
|
140 /** Reads an effect entry containing a float */
|
nuclear@0
|
141 void ReadEffectFloat( float& pFloat);
|
nuclear@0
|
142
|
nuclear@0
|
143 /** Reads an effect parameter specification of any kind */
|
nuclear@0
|
144 void ReadEffectParam( Collada::EffectParam& pParam);
|
nuclear@0
|
145
|
nuclear@0
|
146 /** Reads the geometry library contents */
|
nuclear@0
|
147 void ReadGeometryLibrary();
|
nuclear@0
|
148
|
nuclear@0
|
149 /** Reads a geometry from the geometry library. */
|
nuclear@0
|
150 void ReadGeometry( Collada::Mesh* pMesh);
|
nuclear@0
|
151
|
nuclear@0
|
152 /** Reads a mesh from the geometry library */
|
nuclear@0
|
153 void ReadMesh( Collada::Mesh* pMesh);
|
nuclear@0
|
154
|
nuclear@0
|
155 /** Reads a source element - a combination of raw data and an accessor defining
|
nuclear@0
|
156 * things that should not be redefinable. Yes, that's another rant.
|
nuclear@0
|
157 */
|
nuclear@0
|
158 void ReadSource();
|
nuclear@0
|
159
|
nuclear@0
|
160 /** Reads a data array holding a number of elements, and stores it in the global library.
|
nuclear@0
|
161 * Currently supported are array of floats and arrays of strings.
|
nuclear@0
|
162 */
|
nuclear@0
|
163 void ReadDataArray();
|
nuclear@0
|
164
|
nuclear@0
|
165 /** Reads an accessor and stores it in the global library under the given ID -
|
nuclear@0
|
166 * accessors use the ID of the parent <source> element
|
nuclear@0
|
167 */
|
nuclear@0
|
168 void ReadAccessor( const std::string& pID);
|
nuclear@0
|
169
|
nuclear@0
|
170 /** Reads input declarations of per-vertex mesh data into the given mesh */
|
nuclear@0
|
171 void ReadVertexData( Collada::Mesh* pMesh);
|
nuclear@0
|
172
|
nuclear@0
|
173 /** Reads input declarations of per-index mesh data into the given mesh */
|
nuclear@0
|
174 void ReadIndexData( Collada::Mesh* pMesh);
|
nuclear@0
|
175
|
nuclear@0
|
176 /** Reads a single input channel element and stores it in the given array, if valid */
|
nuclear@0
|
177 void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
|
nuclear@0
|
178
|
nuclear@0
|
179 /** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
|
nuclear@0
|
180 void ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
|
nuclear@0
|
181 size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
|
nuclear@0
|
182
|
nuclear@0
|
183 /** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
|
nuclear@0
|
184 void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);
|
nuclear@0
|
185
|
nuclear@0
|
186 /** Reads the library of node hierarchies and scene parts */
|
nuclear@0
|
187 void ReadSceneLibrary();
|
nuclear@0
|
188
|
nuclear@0
|
189 /** Reads a scene node's contents including children and stores it in the given node */
|
nuclear@0
|
190 void ReadSceneNode( Collada::Node* pNode);
|
nuclear@0
|
191
|
nuclear@0
|
192 /** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
|
nuclear@0
|
193 void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType);
|
nuclear@0
|
194
|
nuclear@0
|
195 /** Reads a mesh reference in a node and adds it to the node's mesh list */
|
nuclear@0
|
196 void ReadNodeGeometry( Collada::Node* pNode);
|
nuclear@0
|
197
|
nuclear@0
|
198 /** Reads the collada scene */
|
nuclear@0
|
199 void ReadScene();
|
nuclear@0
|
200
|
nuclear@0
|
201 // Processes bind_vertex_input and bind elements
|
nuclear@0
|
202 void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
|
nuclear@0
|
203
|
nuclear@0
|
204 protected:
|
nuclear@0
|
205 /** Aborts the file reading with an exception */
|
nuclear@0
|
206 void ThrowException( const std::string& pError) const;
|
nuclear@0
|
207
|
nuclear@0
|
208 /** Skips all data until the end node of the current element */
|
nuclear@0
|
209 void SkipElement();
|
nuclear@0
|
210
|
nuclear@0
|
211 /** Skips all data until the end node of the given element */
|
nuclear@0
|
212 void SkipElement( const char* pElement);
|
nuclear@0
|
213
|
nuclear@0
|
214 /** Compares the current xml element name to the given string and returns true if equal */
|
nuclear@0
|
215 bool IsElement( const char* pName) const;
|
nuclear@0
|
216
|
nuclear@0
|
217 /** Tests for the opening tag of the given element, throws an exception if not found */
|
nuclear@0
|
218 void TestOpening( const char* pName);
|
nuclear@0
|
219
|
nuclear@0
|
220 /** Tests for the closing tag of the given element, throws an exception if not found */
|
nuclear@0
|
221 void TestClosing( const char* pName);
|
nuclear@0
|
222
|
nuclear@0
|
223 /** Checks the present element for the presence of the attribute, returns its index
|
nuclear@0
|
224 or throws an exception if not found */
|
nuclear@0
|
225 int GetAttribute( const char* pAttr) const;
|
nuclear@0
|
226
|
nuclear@0
|
227 /** Returns the index of the named attribute or -1 if not found. Does not throw,
|
nuclear@0
|
228 therefore useful for optional attributes */
|
nuclear@0
|
229 int TestAttribute( const char* pAttr) const;
|
nuclear@0
|
230
|
nuclear@0
|
231 /** Reads the text contents of an element, throws an exception if not given.
|
nuclear@0
|
232 Skips leading whitespace. */
|
nuclear@0
|
233 const char* GetTextContent();
|
nuclear@0
|
234
|
nuclear@0
|
235 /** Reads the text contents of an element, returns NULL if not given.
|
nuclear@0
|
236 Skips leading whitespace. */
|
nuclear@0
|
237 const char* TestTextContent();
|
nuclear@0
|
238
|
nuclear@0
|
239 /** Reads a single bool from current text content */
|
nuclear@0
|
240 bool ReadBoolFromTextContent();
|
nuclear@0
|
241
|
nuclear@0
|
242 /** Reads a single float from current text content */
|
nuclear@0
|
243 float ReadFloatFromTextContent();
|
nuclear@0
|
244
|
nuclear@0
|
245 /** Calculates the resulting transformation from all the given transform steps */
|
nuclear@0
|
246 aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
|
nuclear@0
|
247
|
nuclear@0
|
248 /** Determines the input data type for the given semantic string */
|
nuclear@0
|
249 Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
|
nuclear@0
|
250
|
nuclear@0
|
251 /** Finds the item in the given library by its reference, throws if not found */
|
nuclear@0
|
252 template <typename Type> const Type& ResolveLibraryReference(
|
nuclear@0
|
253 const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
|
nuclear@0
|
254
|
nuclear@0
|
255 protected:
|
nuclear@0
|
256 /** Filename, for a verbose error message */
|
nuclear@0
|
257 std::string mFileName;
|
nuclear@0
|
258
|
nuclear@0
|
259 /** XML reader, member for everyday use */
|
nuclear@0
|
260 irr::io::IrrXMLReader* mReader;
|
nuclear@0
|
261
|
nuclear@0
|
262 /** All data arrays found in the file by ID. Might be referred to by actually
|
nuclear@0
|
263 everyone. Collada, you are a steaming pile of indirection. */
|
nuclear@0
|
264 typedef std::map<std::string, Collada::Data> DataLibrary;
|
nuclear@0
|
265 DataLibrary mDataLibrary;
|
nuclear@0
|
266
|
nuclear@0
|
267 /** Same for accessors which define how the data in a data array is accessed. */
|
nuclear@0
|
268 typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
|
nuclear@0
|
269 AccessorLibrary mAccessorLibrary;
|
nuclear@0
|
270
|
nuclear@0
|
271 /** Mesh library: mesh by ID */
|
nuclear@0
|
272 typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
|
nuclear@0
|
273 MeshLibrary mMeshLibrary;
|
nuclear@0
|
274
|
nuclear@0
|
275 /** node library: root node of the hierarchy part by ID */
|
nuclear@0
|
276 typedef std::map<std::string, Collada::Node*> NodeLibrary;
|
nuclear@0
|
277 NodeLibrary mNodeLibrary;
|
nuclear@0
|
278
|
nuclear@0
|
279 /** Image library: stores texture properties by ID */
|
nuclear@0
|
280 typedef std::map<std::string, Collada::Image> ImageLibrary;
|
nuclear@0
|
281 ImageLibrary mImageLibrary;
|
nuclear@0
|
282
|
nuclear@0
|
283 /** Effect library: surface attributes by ID */
|
nuclear@0
|
284 typedef std::map<std::string, Collada::Effect> EffectLibrary;
|
nuclear@0
|
285 EffectLibrary mEffectLibrary;
|
nuclear@0
|
286
|
nuclear@0
|
287 /** Material library: surface material by ID */
|
nuclear@0
|
288 typedef std::map<std::string, Collada::Material> MaterialLibrary;
|
nuclear@0
|
289 MaterialLibrary mMaterialLibrary;
|
nuclear@0
|
290
|
nuclear@0
|
291 /** Light library: surface light by ID */
|
nuclear@0
|
292 typedef std::map<std::string, Collada::Light> LightLibrary;
|
nuclear@0
|
293 LightLibrary mLightLibrary;
|
nuclear@0
|
294
|
nuclear@0
|
295 /** Camera library: surface material by ID */
|
nuclear@0
|
296 typedef std::map<std::string, Collada::Camera> CameraLibrary;
|
nuclear@0
|
297 CameraLibrary mCameraLibrary;
|
nuclear@0
|
298
|
nuclear@0
|
299 /** Controller library: joint controllers by ID */
|
nuclear@0
|
300 typedef std::map<std::string, Collada::Controller> ControllerLibrary;
|
nuclear@0
|
301 ControllerLibrary mControllerLibrary;
|
nuclear@0
|
302
|
nuclear@0
|
303 /** Pointer to the root node. Don't delete, it just points to one of
|
nuclear@0
|
304 the nodes in the node library. */
|
nuclear@0
|
305 Collada::Node* mRootNode;
|
nuclear@0
|
306
|
nuclear@0
|
307 /** Root animation container */
|
nuclear@0
|
308 Collada::Animation mAnims;
|
nuclear@0
|
309
|
nuclear@0
|
310 /** Size unit: how large compared to a meter */
|
nuclear@0
|
311 float mUnitSize;
|
nuclear@0
|
312
|
nuclear@0
|
313 /** Which is the up vector */
|
nuclear@0
|
314 enum { UP_X, UP_Y, UP_Z } mUpDirection;
|
nuclear@0
|
315
|
nuclear@0
|
316 /** Collada file format version */
|
nuclear@0
|
317 Collada::FormatVersion mFormat;
|
nuclear@0
|
318 };
|
nuclear@0
|
319
|
nuclear@0
|
320 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
321 // Check for element match
|
nuclear@0
|
322 inline bool ColladaParser::IsElement( const char* pName) const
|
nuclear@0
|
323 {
|
nuclear@0
|
324 ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT);
|
nuclear@0
|
325 return ::strcmp( mReader->getNodeName(), pName) == 0;
|
nuclear@0
|
326 }
|
nuclear@0
|
327
|
nuclear@0
|
328 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
329 // Finds the item in the given library by its reference, throws if not found
|
nuclear@0
|
330 template <typename Type>
|
nuclear@0
|
331 const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const
|
nuclear@0
|
332 {
|
nuclear@0
|
333 typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL);
|
nuclear@0
|
334 if( it == pLibrary.end())
|
nuclear@0
|
335 ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL));
|
nuclear@0
|
336 return it->second;
|
nuclear@0
|
337 }
|
nuclear@0
|
338
|
nuclear@0
|
339 } // end of namespace Assimp
|
nuclear@0
|
340
|
nuclear@0
|
341 #endif // AI_COLLADAPARSER_H_INC
|