Coverage Report

Created: 2026-01-07 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/assimp/code/AssetLib/MD3/MD3FileData.h
Line
Count
Source
1
/*
2
Open Asset Import Library (assimp)
3
----------------------------------------------------------------------
4
5
Copyright (c) 2006-2025, assimp team
6
7
All rights reserved.
8
9
Redistribution and use of this software in source and binary forms,
10
with or without modification, are permitted provided that the
11
following 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
27
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37
OF 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
61
namespace Assimp {
62
namespace MD3 {
63
64
// to make it easier for us, we test the magic word against both "endiannesses"
65
4
#define AI_MD3_MAGIC_NUMBER_BE  AI_MAKE_MAGIC("IDP3")
66
0
#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
0
#define AI_MD3_MAX_FRAMES       1024
73
#define AI_MD3_MAX_TAGS         16
74
#define AI_MD3_MAX_SURFACES     32
75
0
#define AI_MD3_MAX_SHADERS      256
76
0
#define AI_MD3_MAX_VERTS        4096
77
0
#define AI_MD3_MAX_TRIANGLES    8192
78
79
// master scale factor for all vertices in a MD3 model
80
0
#define AI_MD3_XYZ_SCALE        (1.0f/64.0f)
81
82
// -------------------------------------------------------------------------------
83
/** @brief Data structure for the MD3 main header
84
 */
85
struct 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
 */
128
struct 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
 */
152
struct 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
 */
166
struct 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
 */
207
struct 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
 */
219
struct 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
 */
229
struct TexCoord
230
{
231
    //! UV coordinates
232
    ai_real U,V;
233
} /*PACK_STRUCT*/;
234
235
236
// -------------------------------------------------------------------------------
237
/** @brief Data structure for a vertex
238
 */
239
struct 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 <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
 */
258
inline void LatLngNormalToVec3(uint16_t p_iNormal, ai_real* p_afOut)
259
0
{
260
0
    ai_real lat = (ai_real)(( p_iNormal >> 8u ) & 0xff);
261
0
    ai_real lng = (ai_real)(( p_iNormal & 0xff ));
262
0
    const ai_real invVal( ai_real( 1.0 ) / ai_real( 128.0 ) );
263
0
    lat *= ai_real( 3.141926 ) * invVal;
264
0
    lng *= ai_real( 3.141926 ) * invVal;
265
266
0
    p_afOut[ 0 ] = std::cos(lat) * std::sin(lng);
267
0
    p_afOut[ 1 ] = std::sin(lat) * std::sin(lng);
268
0
    p_afOut[ 2 ] = std::cos(lng);
269
0
}
270
271
272
// -------------------------------------------------------------------------------
273
/** @brief Pack a Q3 normal into 16bit latitude/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
 */
279
inline void Vec3NormalToLatLng( const aiVector3D& p_vIn, uint16_t& p_iOut )
280
0
{
281
0
    // check for singularities
282
0
    if ( 0.0f == p_vIn[0] && 0.0f == p_vIn[1] )
283
0
    {
284
0
        if ( p_vIn[2] > 0.0f )
285
0
        {
286
0
            ((unsigned char*)&p_iOut)[0] = 0;
287
0
            ((unsigned char*)&p_iOut)[1] = 0;       // lat = 0, long = 0
288
0
        }
289
0
        else
290
0
        {
291
0
            ((unsigned char*)&p_iOut)[0] = 128;
292
0
            ((unsigned char*)&p_iOut)[1] = 0;       // lat = 0, long = 128
293
0
        }
294
0
    }
295
0
    else
296
0
    {
297
0
        int a, b;
298
0
299
0
        a = int(57.2957795f * ( std::atan2( p_vIn[1], p_vIn[0] ) ) * (255.0f / 360.0f ));
300
0
        a &= 0xff;
301
0
302
0
        b = int(57.2957795f * ( std::acos( p_vIn[2] ) ) * ( 255.0f / 360.0f ));
303
0
        b &= 0xff;
304
0
305
0
        ((unsigned char*)&p_iOut)[0] = (unsigned char) b;   // longitude
306
0
        ((unsigned char*)&p_iOut)[1] = (unsigned char) a;   // latitude
307
0
    }
308
0
}
309
310
} // Namespace MD3
311
} // Namespace Assimp
312
313
#endif // !! AI_MD3FILEHELPER_H_INC