1/*
2Open Asset Import Library (assimp)
3----------------------------------------------------------------------
4
5Copyright (c) 2006-2017, assimp team
6
7All rights reserved.
8
9Redistribution and use of this software in source and binary forms,
10with or without modification, are permitted provided that the
11following conditions are met:
12
13* Redistributions of source code must retain the above
14 copyright notice, this list of conditions and the
15 following disclaimer.
16
17* Redistributions in binary form must reproduce the above
18 copyright notice, this list of conditions and the
19 following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21
22* Neither the name of the assimp team, nor the names of its
23 contributors may be used to endorse or promote products
24 derived from this software without specific prior
25 written permission of the assimp team.
26
27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39----------------------------------------------------------------------
40*/
41
42/** @file Md3FileData.h
43 *
44 * @brief Defines helper data structures for importing MD3 files.
45 * http://linux.ucla.edu/~phaethon/q3/formats/md3format.html
46 */
47#ifndef AI_MD3FILEHELPER_H_INC
48#define AI_MD3FILEHELPER_H_INC
49
50#include <string>
51#include <vector>
52#include <sstream>
53#include <stdint.h>
54
55#include <assimp/types.h>
56#include <assimp/mesh.h>
57#include <assimp/anim.h>
58
59#include <assimp/Compiler/pushpack1.h>
60
61namespace Assimp {
62namespace MD3 {
63
64// to make it easier for us, we test the magic word against both "endianesses"
65#define AI_MD3_MAGIC_NUMBER_BE AI_MAKE_MAGIC("IDP3")
66#define AI_MD3_MAGIC_NUMBER_LE AI_MAKE_MAGIC("3PDI")
67
68// common limitations
69#define AI_MD3_VERSION 15
70#define AI_MD3_MAXQPATH 64
71#define AI_MD3_MAXFRAME 16
72#define AI_MD3_MAX_FRAMES 1024
73#define AI_MD3_MAX_TAGS 16
74#define AI_MD3_MAX_SURFACES 32
75#define AI_MD3_MAX_SHADERS 256
76#define AI_MD3_MAX_VERTS 4096
77#define AI_MD3_MAX_TRIANGLES 8192
78
79// master scale factor for all vertices in a MD3 model
80#define AI_MD3_XYZ_SCALE (1.0f/64.0f)
81
82// -------------------------------------------------------------------------------
83/** @brief Data structure for the MD3 main header
84 */
85struct Header
86{
87 //! magic number
88 uint32_t IDENT;
89
90 //! file format version
91 uint32_t VERSION;
92
93 //! original name in .pak archive
94 char NAME[ AI_MD3_MAXQPATH ];
95
96 //! unknown
97 int32_t FLAGS;
98
99 //! number of frames in the file
100 uint32_t NUM_FRAMES;
101
102 //! number of tags in the file
103 uint32_t NUM_TAGS;
104
105 //! number of surfaces in the file
106 uint32_t NUM_SURFACES;
107
108 //! number of skins in the file
109 uint32_t NUM_SKINS;
110
111 //! offset of the first frame
112 uint32_t OFS_FRAMES;
113
114 //! offset of the first tag
115 uint32_t OFS_TAGS;
116
117 //! offset of the first surface
118 uint32_t OFS_SURFACES;
119
120 //! end of file
121 uint32_t OFS_EOF;
122} PACK_STRUCT;
123
124
125// -------------------------------------------------------------------------------
126/** @brief Data structure for the frame header
127 */
128struct Frame
129{
130 //! minimum bounds
131 aiVector3D min;
132
133 //! maximum bounds
134 aiVector3D max;
135
136 //! local origin for this frame
137 aiVector3D origin;
138
139 //! radius of bounding sphere
140 ai_real radius;
141
142 //! name of frame
143 char name[ AI_MD3_MAXFRAME ];
144
145} /* PACK_STRUCT */;
146
147
148// -------------------------------------------------------------------------------
149/**
150 * @brief Data structure for the tag header
151 */
152struct Tag {
153 //! name of the tag
154 char NAME[ AI_MD3_MAXQPATH ];
155
156 //! Local tag origin and orientation
157 aiVector3D origin;
158 ai_real orientation[3][3];
159
160} /* PACK_STRUCT */;
161
162
163// -------------------------------------------------------------------------------
164/** @brief Data structure for the surface header
165 */
166struct Surface {
167 //! magic number
168 int32_t IDENT;
169
170 //! original name of the surface
171 char NAME[ AI_MD3_MAXQPATH ];
172
173 //! unknown
174 int32_t FLAGS;
175
176 //! number of frames in the surface
177 uint32_t NUM_FRAMES;
178
179 //! number of shaders in the surface
180 uint32_t NUM_SHADER;
181
182 //! number of vertices in the surface
183 uint32_t NUM_VERTICES;
184
185 //! number of triangles in the surface
186 uint32_t NUM_TRIANGLES;
187
188 //! offset to the triangle data
189 uint32_t OFS_TRIANGLES;
190
191 //! offset to the shader data
192 uint32_t OFS_SHADERS;
193
194 //! offset to the texture coordinate data
195 uint32_t OFS_ST;
196
197 //! offset to the vertex/normal data
198 uint32_t OFS_XYZNORMAL;
199
200 //! offset to the end of the Surface object
201 int32_t OFS_END;
202} /*PACK_STRUCT*/;
203
204// -------------------------------------------------------------------------------
205/** @brief Data structure for a shader defined in there
206 */
207struct Shader {
208 //! filename of the shader
209 char NAME[ AI_MD3_MAXQPATH ];
210
211 //! index of the shader
212 uint32_t SHADER_INDEX;
213} /*PACK_STRUCT*/;
214
215
216// -------------------------------------------------------------------------------
217/** @brief Data structure for a triangle
218 */
219struct Triangle
220{
221 //! triangle indices
222 uint32_t INDEXES[3];
223} /*PACK_STRUCT*/;
224
225
226// -------------------------------------------------------------------------------
227/** @brief Data structure for an UV coord
228 */
229struct TexCoord
230{
231 //! UV coordinates
232 ai_real U,V;
233} /*PACK_STRUCT*/;
234
235
236// -------------------------------------------------------------------------------
237/** @brief Data structure for a vertex
238 */
239struct Vertex
240{
241 //! X/Y/Z coordinates
242 int16_t X,Y,Z;
243
244 //! encoded normal vector
245 uint16_t NORMAL;
246} /*PACK_STRUCT*/;
247
248#include "./../include/assimp/Compiler/poppack1.h"
249
250// -------------------------------------------------------------------------------
251/** @brief Unpack a Q3 16 bit vector to its full float3 representation
252 *
253 * @param p_iNormal Input normal vector in latitude/longitude form
254 * @param p_afOut Pointer to an array of three floats to receive the result
255 *
256 * @note This has been taken from q3 source (misc_model.c)
257 */
258inline void LatLngNormalToVec3(uint16_t p_iNormal, ai_real* p_afOut)
259{
260 ai_real lat = (ai_real)(( p_iNormal >> 8u ) & 0xff);
261 ai_real lng = (ai_real)(( p_iNormal & 0xff ));
262 const ai_real invVal( ai_real( 1.0 ) / ai_real( 128.0 ) );
263 lat *= ai_real( 3.141926 ) * invVal;
264 lng *= ai_real( 3.141926 ) * invVal;
265
266 p_afOut[ 0 ] = std::cos(lat) * std::sin(lng);
267 p_afOut[ 1 ] = std::sin(lat) * std::sin(lng);
268 p_afOut[ 2 ] = std::cos(lng);
269}
270
271
272// -------------------------------------------------------------------------------
273/** @brief Pack a Q3 normal into 16bit latitute/longitude representation
274 * @param p_vIn Input vector
275 * @param p_iOut Output normal
276 *
277 * @note This has been taken from q3 source (mathlib.c)
278 */
279inline void Vec3NormalToLatLng( const aiVector3D& p_vIn, uint16_t& p_iOut )
280{
281 // check for singularities
282 if ( 0.0f == p_vIn[0] && 0.0f == p_vIn[1] )
283 {
284 if ( p_vIn[2] > 0.0f )
285 {
286 ((unsigned char*)&p_iOut)[0] = 0;
287 ((unsigned char*)&p_iOut)[1] = 0; // lat = 0, long = 0
288 }
289 else
290 {
291 ((unsigned char*)&p_iOut)[0] = 128;
292 ((unsigned char*)&p_iOut)[1] = 0; // lat = 0, long = 128
293 }
294 }
295 else
296 {
297 int a, b;
298
299 a = int(57.2957795f * ( std::atan2( p_vIn[1], p_vIn[0] ) ) * (255.0f / 360.0f ));
300 a &= 0xff;
301
302 b = int(57.2957795f * ( std::acos( p_vIn[2] ) ) * ( 255.0f / 360.0f ));
303 b &= 0xff;
304
305 ((unsigned char*)&p_iOut)[0] = b; // longitude
306 ((unsigned char*)&p_iOut)[1] = a; // latitude
307 }
308}
309
310}
311}
312
313#endif // !! AI_MD3FILEHELPER_H_INC
314