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 SMDLoader.h
|
nuclear@0
|
42 * @brief Defintion of the Valve SMD file format
|
nuclear@0
|
43 */
|
nuclear@0
|
44
|
nuclear@0
|
45 #ifndef AI_SMDLOADER_H_INCLUDED
|
nuclear@0
|
46 #define AI_SMDLOADER_H_INCLUDED
|
nuclear@0
|
47
|
nuclear@0
|
48 // internal headers
|
nuclear@0
|
49 #include "BaseImporter.h"
|
nuclear@0
|
50 #include "ParsingUtils.h"
|
nuclear@0
|
51
|
nuclear@0
|
52 // public Assimp headers
|
nuclear@0
|
53 #include "assimp/types.h"
|
nuclear@0
|
54 #include "assimp/texture.h"
|
nuclear@0
|
55 #include "assimp/anim.h"
|
nuclear@0
|
56 #include "assimp/material.h"
|
nuclear@0
|
57 struct aiNode;
|
nuclear@0
|
58
|
nuclear@0
|
59 // STL headers
|
nuclear@0
|
60 #include <vector>
|
nuclear@0
|
61
|
nuclear@0
|
62 namespace Assimp {
|
nuclear@0
|
63
|
nuclear@0
|
64
|
nuclear@0
|
65 namespace SMD {
|
nuclear@0
|
66
|
nuclear@0
|
67 // ---------------------------------------------------------------------------
|
nuclear@0
|
68 /** Data structure for a vertex in a SMD file
|
nuclear@0
|
69 */
|
nuclear@0
|
70 struct Vertex
|
nuclear@0
|
71 {
|
nuclear@0
|
72 Vertex() : iParentNode(UINT_MAX)
|
nuclear@0
|
73 {}
|
nuclear@0
|
74
|
nuclear@0
|
75 //! Vertex position, normal and texture coordinate
|
nuclear@0
|
76 aiVector3D pos,nor,uv;
|
nuclear@0
|
77
|
nuclear@0
|
78 //! Vertex parent node
|
nuclear@0
|
79 unsigned int iParentNode;
|
nuclear@0
|
80
|
nuclear@0
|
81 //! Links to bones: pair.first is the bone index,
|
nuclear@0
|
82 //! pair.second is the vertex weight.
|
nuclear@0
|
83 //! WARN: The remaining weight (to reach 1.0f) is assigned
|
nuclear@0
|
84 //! to the parent node/bone
|
nuclear@0
|
85 std::vector<std::pair<unsigned int, float> > aiBoneLinks;
|
nuclear@0
|
86 };
|
nuclear@0
|
87
|
nuclear@0
|
88 // ---------------------------------------------------------------------------
|
nuclear@0
|
89 /** Data structure for a face in a SMD file
|
nuclear@0
|
90 */
|
nuclear@0
|
91 struct Face
|
nuclear@0
|
92 {
|
nuclear@0
|
93 Face() : iTexture(0x0)
|
nuclear@0
|
94 {}
|
nuclear@0
|
95
|
nuclear@0
|
96 //! Texture index for the face
|
nuclear@0
|
97 unsigned int iTexture;
|
nuclear@0
|
98
|
nuclear@0
|
99 //! The three vertices of the face
|
nuclear@0
|
100 Vertex avVertices[3];
|
nuclear@0
|
101 };
|
nuclear@0
|
102
|
nuclear@0
|
103 // ---------------------------------------------------------------------------
|
nuclear@0
|
104 /** Data structure for a bone in a SMD file
|
nuclear@0
|
105 */
|
nuclear@0
|
106 struct Bone
|
nuclear@0
|
107 {
|
nuclear@0
|
108 //! Default constructor
|
nuclear@0
|
109 Bone() : iParent(UINT_MAX), bIsUsed(false)
|
nuclear@0
|
110 {
|
nuclear@0
|
111 }
|
nuclear@0
|
112
|
nuclear@0
|
113 //! Destructor
|
nuclear@0
|
114 ~Bone()
|
nuclear@0
|
115 {
|
nuclear@0
|
116 }
|
nuclear@0
|
117
|
nuclear@0
|
118 //! Name of the bone
|
nuclear@0
|
119 std::string mName;
|
nuclear@0
|
120
|
nuclear@0
|
121 //! Parent of the bone
|
nuclear@0
|
122 uint32_t iParent;
|
nuclear@0
|
123
|
nuclear@0
|
124 //! Animation of the bone
|
nuclear@0
|
125 struct Animation
|
nuclear@0
|
126 {
|
nuclear@0
|
127 //! Public default constructor
|
nuclear@0
|
128 Animation()
|
nuclear@0
|
129 {
|
nuclear@0
|
130 asKeys.reserve(20);
|
nuclear@0
|
131 }
|
nuclear@0
|
132
|
nuclear@0
|
133 //! Data structure for a matrix key
|
nuclear@0
|
134 struct MatrixKey
|
nuclear@0
|
135 {
|
nuclear@0
|
136 //! Matrix at this time
|
nuclear@0
|
137 aiMatrix4x4 matrix;
|
nuclear@0
|
138
|
nuclear@0
|
139 //! Absolute transformation matrix
|
nuclear@0
|
140 aiMatrix4x4 matrixAbsolute;
|
nuclear@0
|
141
|
nuclear@0
|
142 //! Position
|
nuclear@0
|
143 aiVector3D vPos;
|
nuclear@0
|
144
|
nuclear@0
|
145 //! Rotation (euler angles)
|
nuclear@0
|
146 aiVector3D vRot;
|
nuclear@0
|
147
|
nuclear@0
|
148 //! Current time. may be negative, this
|
nuclear@0
|
149 //! will be fixed later
|
nuclear@0
|
150 double dTime;
|
nuclear@0
|
151 };
|
nuclear@0
|
152
|
nuclear@0
|
153 //! Index of the key with the smallest time value
|
nuclear@0
|
154 uint32_t iFirstTimeKey;
|
nuclear@0
|
155
|
nuclear@0
|
156 //! Array of matrix keys
|
nuclear@0
|
157 std::vector<MatrixKey> asKeys;
|
nuclear@0
|
158
|
nuclear@0
|
159 } sAnim;
|
nuclear@0
|
160
|
nuclear@0
|
161 //! Offset matrix of the bone
|
nuclear@0
|
162 aiMatrix4x4 mOffsetMatrix;
|
nuclear@0
|
163
|
nuclear@0
|
164 //! true if the bone is referenced by at least one mesh
|
nuclear@0
|
165 bool bIsUsed;
|
nuclear@0
|
166 };
|
nuclear@0
|
167
|
nuclear@0
|
168 } //! namespace SMD
|
nuclear@0
|
169
|
nuclear@0
|
170 // ---------------------------------------------------------------------------
|
nuclear@0
|
171 /** Used to load Half-life 1 and 2 SMD models
|
nuclear@0
|
172 */
|
nuclear@0
|
173 class SMDImporter : public BaseImporter
|
nuclear@0
|
174 {
|
nuclear@0
|
175 public:
|
nuclear@0
|
176 SMDImporter();
|
nuclear@0
|
177 ~SMDImporter();
|
nuclear@0
|
178
|
nuclear@0
|
179
|
nuclear@0
|
180 public:
|
nuclear@0
|
181
|
nuclear@0
|
182 // -------------------------------------------------------------------
|
nuclear@0
|
183 /** Returns whether the class can handle the format of the given file.
|
nuclear@0
|
184 * See BaseImporter::CanRead() for details.
|
nuclear@0
|
185 */
|
nuclear@0
|
186 bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
nuclear@0
|
187 bool checkSig) const;
|
nuclear@0
|
188
|
nuclear@0
|
189 // -------------------------------------------------------------------
|
nuclear@0
|
190 /** Called prior to ReadFile().
|
nuclear@0
|
191 * The function is a request to the importer to update its configuration
|
nuclear@0
|
192 * basing on the Importer's configuration property list.
|
nuclear@0
|
193 */
|
nuclear@0
|
194 void SetupProperties(const Importer* pImp);
|
nuclear@0
|
195
|
nuclear@0
|
196 protected:
|
nuclear@0
|
197
|
nuclear@0
|
198
|
nuclear@0
|
199 // -------------------------------------------------------------------
|
nuclear@0
|
200 /** Return importer meta information.
|
nuclear@0
|
201 * See #BaseImporter::GetInfo for the details
|
nuclear@0
|
202 */
|
nuclear@0
|
203 const aiImporterDesc* GetInfo () const;
|
nuclear@0
|
204
|
nuclear@0
|
205 // -------------------------------------------------------------------
|
nuclear@0
|
206 /** Imports the given file into the given scene structure.
|
nuclear@0
|
207 * See BaseImporter::InternReadFile() for details
|
nuclear@0
|
208 */
|
nuclear@0
|
209 void InternReadFile( const std::string& pFile, aiScene* pScene,
|
nuclear@0
|
210 IOSystem* pIOHandler);
|
nuclear@0
|
211
|
nuclear@0
|
212 protected:
|
nuclear@0
|
213
|
nuclear@0
|
214 // -------------------------------------------------------------------
|
nuclear@0
|
215 /** Parse the SMD file and create the output scene
|
nuclear@0
|
216 */
|
nuclear@0
|
217 void ParseFile();
|
nuclear@0
|
218
|
nuclear@0
|
219 // -------------------------------------------------------------------
|
nuclear@0
|
220 /** Parse the triangles section of the SMD file
|
nuclear@0
|
221 * \param szCurrent Current position in the file. Points to the first
|
nuclear@0
|
222 * data line of the section.
|
nuclear@0
|
223 * \param szCurrentOut Receives a pointer to the heading line of
|
nuclear@0
|
224 * the next section (or to EOF)
|
nuclear@0
|
225 */
|
nuclear@0
|
226 void ParseTrianglesSection(const char* szCurrent,
|
nuclear@0
|
227 const char** szCurrentOut);
|
nuclear@0
|
228
|
nuclear@0
|
229 // -------------------------------------------------------------------
|
nuclear@0
|
230 /** Parse the vertex animation section in VTA files
|
nuclear@0
|
231 * \param szCurrent Current position in the file. Points to the first
|
nuclear@0
|
232 * data line of the section.
|
nuclear@0
|
233 * \param szCurrentOut Receives a pointer to the heading line of
|
nuclear@0
|
234 * the next section (or to EOF)
|
nuclear@0
|
235 */
|
nuclear@0
|
236 void ParseVASection(const char* szCurrent,
|
nuclear@0
|
237 const char** szCurrentOut);
|
nuclear@0
|
238
|
nuclear@0
|
239 // -------------------------------------------------------------------
|
nuclear@0
|
240 /** Parse the nodes section of the SMD file
|
nuclear@0
|
241 * \param szCurrent Current position in the file. Points to the first
|
nuclear@0
|
242 * data line of the section.
|
nuclear@0
|
243 * \param szCurrentOut Receives a pointer to the heading line of
|
nuclear@0
|
244 * the next section (or to EOF)
|
nuclear@0
|
245 */
|
nuclear@0
|
246 void ParseNodesSection(const char* szCurrent,
|
nuclear@0
|
247 const char** szCurrentOut);
|
nuclear@0
|
248
|
nuclear@0
|
249 // -------------------------------------------------------------------
|
nuclear@0
|
250 /** Parse the skeleton section of the SMD file
|
nuclear@0
|
251 * \param szCurrent Current position in the file. Points to the first
|
nuclear@0
|
252 * data line of the section.
|
nuclear@0
|
253 * \param szCurrentOut Receives a pointer to the heading line of
|
nuclear@0
|
254 * the next section (or to EOF)
|
nuclear@0
|
255 */
|
nuclear@0
|
256 void ParseSkeletonSection(const char* szCurrent,
|
nuclear@0
|
257 const char** szCurrentOut);
|
nuclear@0
|
258
|
nuclear@0
|
259 // -------------------------------------------------------------------
|
nuclear@0
|
260 /** Parse a single triangle in the SMD file
|
nuclear@0
|
261 * \param szCurrent Current position in the file. Points to the first
|
nuclear@0
|
262 * data line of the section.
|
nuclear@0
|
263 * \param szCurrentOut Receives the output cursor position
|
nuclear@0
|
264 */
|
nuclear@0
|
265 void ParseTriangle(const char* szCurrent,
|
nuclear@0
|
266 const char** szCurrentOut);
|
nuclear@0
|
267
|
nuclear@0
|
268
|
nuclear@0
|
269 // -------------------------------------------------------------------
|
nuclear@0
|
270 /** Parse a single vertex in the SMD file
|
nuclear@0
|
271 * \param szCurrent Current position in the file. Points to the first
|
nuclear@0
|
272 * data line of the section.
|
nuclear@0
|
273 * \param szCurrentOut Receives the output cursor position
|
nuclear@0
|
274 * \param vertex Vertex to be filled
|
nuclear@0
|
275 */
|
nuclear@0
|
276 void ParseVertex(const char* szCurrent,
|
nuclear@0
|
277 const char** szCurrentOut, SMD::Vertex& vertex,
|
nuclear@0
|
278 bool bVASection = false);
|
nuclear@0
|
279
|
nuclear@0
|
280 // -------------------------------------------------------------------
|
nuclear@0
|
281 /** Get the index of a texture. If the texture was not yet known
|
nuclear@0
|
282 * it will be added to the internal texture list.
|
nuclear@0
|
283 * \param filename Name of the texture
|
nuclear@0
|
284 * \return Value texture index
|
nuclear@0
|
285 */
|
nuclear@0
|
286 unsigned int GetTextureIndex(const std::string& filename);
|
nuclear@0
|
287
|
nuclear@0
|
288 // -------------------------------------------------------------------
|
nuclear@0
|
289 /** Computes absolute bone transformations
|
nuclear@0
|
290 * All output transformations are in worldspace.
|
nuclear@0
|
291 */
|
nuclear@0
|
292 void ComputeAbsoluteBoneTransformations();
|
nuclear@0
|
293
|
nuclear@0
|
294
|
nuclear@0
|
295 // -------------------------------------------------------------------
|
nuclear@0
|
296 /** Parse a line in the skeleton section
|
nuclear@0
|
297 */
|
nuclear@0
|
298 void ParseSkeletonElement(const char* szCurrent,
|
nuclear@0
|
299 const char** szCurrentOut,int iTime);
|
nuclear@0
|
300
|
nuclear@0
|
301 // -------------------------------------------------------------------
|
nuclear@0
|
302 /** Parse a line in the nodes section
|
nuclear@0
|
303 */
|
nuclear@0
|
304 void ParseNodeInfo(const char* szCurrent,
|
nuclear@0
|
305 const char** szCurrentOut);
|
nuclear@0
|
306
|
nuclear@0
|
307
|
nuclear@0
|
308 // -------------------------------------------------------------------
|
nuclear@0
|
309 /** Parse a floating-point value
|
nuclear@0
|
310 */
|
nuclear@0
|
311 bool ParseFloat(const char* szCurrent,
|
nuclear@0
|
312 const char** szCurrentOut, float& out);
|
nuclear@0
|
313
|
nuclear@0
|
314 // -------------------------------------------------------------------
|
nuclear@0
|
315 /** Parse an unsigned integer. There may be no sign!
|
nuclear@0
|
316 */
|
nuclear@0
|
317 bool ParseUnsignedInt(const char* szCurrent,
|
nuclear@0
|
318 const char** szCurrentOut, unsigned int& out);
|
nuclear@0
|
319
|
nuclear@0
|
320 // -------------------------------------------------------------------
|
nuclear@0
|
321 /** Parse a signed integer. Signs (+,-) are handled.
|
nuclear@0
|
322 */
|
nuclear@0
|
323 bool ParseSignedInt(const char* szCurrent,
|
nuclear@0
|
324 const char** szCurrentOut, int& out);
|
nuclear@0
|
325
|
nuclear@0
|
326 // -------------------------------------------------------------------
|
nuclear@0
|
327 /** Fix invalid time values in the file
|
nuclear@0
|
328 */
|
nuclear@0
|
329 void FixTimeValues();
|
nuclear@0
|
330
|
nuclear@0
|
331 // -------------------------------------------------------------------
|
nuclear@0
|
332 /** Add all children of a bone as subnodes to a node
|
nuclear@0
|
333 * \param pcNode Parent node
|
nuclear@0
|
334 * \param iParent Parent bone index
|
nuclear@0
|
335 */
|
nuclear@0
|
336 void AddBoneChildren(aiNode* pcNode, uint32_t iParent);
|
nuclear@0
|
337
|
nuclear@0
|
338 // -------------------------------------------------------------------
|
nuclear@0
|
339 /** Build output meshes/materials/nodes/animations
|
nuclear@0
|
340 */
|
nuclear@0
|
341 void CreateOutputMeshes();
|
nuclear@0
|
342 void CreateOutputNodes();
|
nuclear@0
|
343 void CreateOutputAnimations();
|
nuclear@0
|
344 void CreateOutputMaterials();
|
nuclear@0
|
345
|
nuclear@0
|
346
|
nuclear@0
|
347 // -------------------------------------------------------------------
|
nuclear@0
|
348 /** Print a log message together with the current line number
|
nuclear@0
|
349 */
|
nuclear@0
|
350 void LogErrorNoThrow(const char* msg);
|
nuclear@0
|
351 void LogWarning(const char* msg);
|
nuclear@0
|
352
|
nuclear@0
|
353
|
nuclear@0
|
354 // -------------------------------------------------------------------
|
nuclear@0
|
355 inline bool SkipLine( const char* in, const char** out)
|
nuclear@0
|
356 {
|
nuclear@0
|
357 Assimp::SkipLine(in,out);
|
nuclear@0
|
358 ++iLineNumber;
|
nuclear@0
|
359 return true;
|
nuclear@0
|
360 }
|
nuclear@0
|
361 // -------------------------------------------------------------------
|
nuclear@0
|
362 inline bool SkipSpacesAndLineEnd( const char* in, const char** out)
|
nuclear@0
|
363 {
|
nuclear@0
|
364 ++iLineNumber;
|
nuclear@0
|
365 return Assimp::SkipSpacesAndLineEnd(in,out);
|
nuclear@0
|
366 }
|
nuclear@0
|
367
|
nuclear@0
|
368 private:
|
nuclear@0
|
369
|
nuclear@0
|
370 /** Configuration option: frame to be loaded */
|
nuclear@0
|
371 unsigned int configFrameID;
|
nuclear@0
|
372
|
nuclear@0
|
373 /** Buffer to hold the loaded file */
|
nuclear@0
|
374 const char* mBuffer;
|
nuclear@0
|
375
|
nuclear@0
|
376 /** Output scene to be filled
|
nuclear@0
|
377 */
|
nuclear@0
|
378 aiScene* pScene;
|
nuclear@0
|
379
|
nuclear@0
|
380 /** Size of the input file in bytes
|
nuclear@0
|
381 */
|
nuclear@0
|
382 unsigned int iFileSize;
|
nuclear@0
|
383
|
nuclear@0
|
384 /** Array of textures found in the file
|
nuclear@0
|
385 */
|
nuclear@0
|
386 std::vector<std::string> aszTextures;
|
nuclear@0
|
387
|
nuclear@0
|
388 /** Array of triangles found in the file
|
nuclear@0
|
389 */
|
nuclear@0
|
390 std::vector<SMD::Face> asTriangles;
|
nuclear@0
|
391
|
nuclear@0
|
392 /** Array of bones found in the file
|
nuclear@0
|
393 */
|
nuclear@0
|
394 std::vector<SMD::Bone> asBones;
|
nuclear@0
|
395
|
nuclear@0
|
396 /** Smallest frame index found in the skeleton
|
nuclear@0
|
397 */
|
nuclear@0
|
398 int iSmallestFrame;
|
nuclear@0
|
399
|
nuclear@0
|
400 /** Length of the whole animation, in frames
|
nuclear@0
|
401 */
|
nuclear@0
|
402 double dLengthOfAnim;
|
nuclear@0
|
403
|
nuclear@0
|
404 /** Do we have texture coordinates?
|
nuclear@0
|
405 */
|
nuclear@0
|
406 bool bHasUVs;
|
nuclear@0
|
407
|
nuclear@0
|
408 /** Current line numer
|
nuclear@0
|
409 */
|
nuclear@0
|
410 unsigned int iLineNumber;
|
nuclear@0
|
411
|
nuclear@0
|
412 };
|
nuclear@0
|
413
|
nuclear@0
|
414 } // end of namespace Assimp
|
nuclear@0
|
415
|
nuclear@0
|
416 #endif // AI_SMDIMPORTER_H_INC
|