Coverage Report

Created: 2026-01-07 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/assimp/code/AssetLib/Ogre/OgreBinarySerializer.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
#ifndef AI_OGREBINARYSERIALIZER_H_INC
43
#define AI_OGREBINARYSERIALIZER_H_INC
44
45
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
46
47
#include "OgreStructs.h"
48
#include <assimp/StreamReader.h>
49
50
namespace Assimp {
51
namespace Ogre {
52
53
typedef Assimp::StreamReaderLE MemoryStreamReader;
54
typedef std::shared_ptr<MemoryStreamReader> MemoryStreamReaderPtr;
55
56
class OgreBinarySerializer {
57
public:
58
    /// Imports mesh and returns the result.
59
    /** @note Fatal unrecoverable errors will throw a DeadlyImportError. */
60
    static Mesh *ImportMesh(MemoryStreamReader *reader);
61
62
    /// Imports skeleton to @c mesh into Mesh::skeleton.
63
    /** If mesh does not have a skeleton reference or the skeleton file
64
        cannot be found it is not a fatal DeadlyImportError.
65
        @return If skeleton import was successful. */
66
    static bool ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh);
67
    static bool ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh);
68
69
private:
70
    enum AssetMode {
71
        AM_Mesh,
72
        AM_Skeleton
73
    };
74
75
    OgreBinarySerializer(MemoryStreamReader *reader, AssetMode mode) :
76
0
            m_currentLen(0),
77
0
            m_reader(reader),
78
0
            assetMode(mode) {
79
0
    }
80
81
    static MemoryStreamReaderPtr OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename);
82
83
    // Header
84
85
    uint16_t ReadHeader(bool readLen = true);
86
    void RollbackHeader();
87
88
    // Mesh
89
90
    void ReadMesh(Mesh *mesh);
91
    void ReadMeshLodInfo(Mesh *mesh);
92
    void ReadMeshSkeletonLink(Mesh *mesh);
93
    void ReadMeshBounds(Mesh *mesh);
94
    void ReadMeshExtremes(Mesh *mesh);
95
96
    void ReadSubMesh(Mesh *mesh);
97
    void ReadSubMeshNames(Mesh *mesh);
98
    void ReadSubMeshOperation(SubMesh *submesh);
99
    void ReadSubMeshTextureAlias(SubMesh *submesh);
100
101
    void ReadBoneAssignment(VertexData *dest);
102
103
    void ReadGeometry(VertexData *dest);
104
    void ReadGeometryVertexDeclaration(VertexData *dest);
105
    void ReadGeometryVertexElement(VertexData *dest);
106
    void ReadGeometryVertexBuffer(VertexData *dest);
107
108
    void ReadEdgeList(Mesh *mesh);
109
    void ReadPoses(Mesh *mesh);
110
    void ReadPoseVertices(Pose *pose);
111
112
    void ReadAnimations(Mesh *mesh);
113
    void ReadAnimation(Animation *anim);
114
    void ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *track);
115
116
    void NormalizeBoneWeights(VertexData *vertexData) const;
117
118
    // Skeleton
119
120
    void ReadSkeleton(Skeleton *skeleton);
121
122
    void ReadBone(Skeleton *skeleton);
123
    void ReadBoneParent(Skeleton *skeleton);
124
125
    void ReadSkeletonAnimation(Skeleton *skeleton);
126
    void ReadSkeletonAnimationTrack(Skeleton *skeleton, Animation *dest);
127
    void ReadSkeletonAnimationKeyFrame(VertexAnimationTrack *dest);
128
    void ReadSkeletonAnimationLink(Skeleton *skeleton);
129
130
    // Reader utils
131
    bool AtEnd() const;
132
133
    template <typename T>
134
    inline T Read();
135
136
    void ReadBytes(char *dest, size_t numBytes);
137
    void ReadBytes(uint8_t *dest, size_t numBytes);
138
    void ReadBytes(void *dest, size_t numBytes);
139
    uint8_t *ReadBytes(size_t numBytes);
140
141
    void ReadVector(aiVector3D &vec);
142
    void ReadQuaternion(aiQuaternion &quat);
143
144
    std::string ReadString(size_t len);
145
    std::string ReadLine();
146
147
    void SkipBytes(size_t numBytes);
148
149
    uint32_t m_currentLen;
150
    MemoryStreamReader *m_reader;
151
152
    AssetMode assetMode;
153
};
154
155
enum MeshChunkId {
156
    M_HEADER = 0x1000,
157
    // char*          version          : Version number check
158
    M_MESH = 0x3000,
159
    // bool skeletallyAnimated   // important flag which affects h/w buffer policies
160
    // Optional M_GEOMETRY chunk
161
    M_SUBMESH = 0x4000,
162
    // char* materialName
163
    // bool useSharedVertices
164
    // unsigned int indexCount
165
    // bool indexes32Bit
166
    // unsigned int* faceVertexIndices (indexCount)
167
    // OR
168
    // unsigned short* faceVertexIndices (indexCount)
169
    // M_GEOMETRY chunk (Optional: present only if useSharedVertices = false)
170
    M_SUBMESH_OPERATION = 0x4010, // optional, trilist assumed if missing
171
    // unsigned short operationType
172
    M_SUBMESH_BONE_ASSIGNMENT = 0x4100,
173
    // Optional bone weights (repeating section)
174
    // unsigned int vertexIndex;
175
    // unsigned short boneIndex;
176
    // float weight;
177
    // Optional chunk that matches a texture name to an alias
178
    // a texture alias is sent to the submesh material to use this texture name
179
    // instead of the one in the texture unit with a matching alias name
180
    M_SUBMESH_TEXTURE_ALIAS = 0x4200, // Repeating section
181
    // char* aliasName;
182
    // char* textureName;
183
184
    M_GEOMETRY = 0x5000, // NB this chunk is embedded within M_MESH and M_SUBMESH
185
    // unsigned int vertexCount
186
    M_GEOMETRY_VERTEX_DECLARATION = 0x5100,
187
    M_GEOMETRY_VERTEX_ELEMENT = 0x5110, // Repeating section
188
    // unsigned short source;   // buffer bind source
189
    // unsigned short type;     // VertexElementType
190
    // unsigned short semantic; // VertexElementSemantic
191
    // unsigned short offset;   // start offset in buffer in bytes
192
    // unsigned short index;    // index of the semantic (for colours and texture coords)
193
    M_GEOMETRY_VERTEX_BUFFER = 0x5200, // Repeating section
194
    // unsigned short bindIndex;    // Index to bind this buffer to
195
    // unsigned short vertexSize;   // Per-vertex size, must agree with declaration at this index
196
    M_GEOMETRY_VERTEX_BUFFER_DATA = 0x5210,
197
    // raw buffer data
198
    M_MESH_SKELETON_LINK = 0x6000,
199
    // Optional link to skeleton
200
    // char* skeletonName          : name of .skeleton to use
201
    M_MESH_BONE_ASSIGNMENT = 0x7000,
202
    // Optional bone weights (repeating section)
203
    // unsigned int vertexIndex;
204
    // unsigned short boneIndex;
205
    // float weight;
206
    M_MESH_LOD = 0x8000,
207
    // Optional LOD information
208
    // string strategyName;
209
    // unsigned short numLevels;
210
    // bool manual;  (true for manual alternate meshes, false for generated)
211
    M_MESH_LOD_USAGE = 0x8100,
212
    // Repeating section, ordered in increasing depth
213
    // NB LOD 0 (full detail from 0 depth) is omitted
214
    // LOD value - this is a distance, a pixel count etc, based on strategy
215
    // float lodValue;
216
    M_MESH_LOD_MANUAL = 0x8110,
217
    // Required if M_MESH_LOD section manual = true
218
    // String manualMeshName;
219
    M_MESH_LOD_GENERATED = 0x8120,
220
    // Required if M_MESH_LOD section manual = false
221
    // Repeating section (1 per submesh)
222
    // unsigned int indexCount;
223
    // bool indexes32Bit
224
    // unsigned short* faceIndexes;  (indexCount)
225
    // OR
226
    // unsigned int* faceIndexes;  (indexCount)
227
    M_MESH_BOUNDS = 0x9000,
228
    // float minx, miny, minz
229
    // float maxx, maxy, maxz
230
    // float radius
231
232
    // Added By DrEvil
233
    // optional chunk that contains a table of submesh indexes and the names of
234
    // the sub-meshes.
235
    M_SUBMESH_NAME_TABLE = 0xA000,
236
    // Subchunks of the name table. Each chunk contains an index & string
237
    M_SUBMESH_NAME_TABLE_ELEMENT = 0xA100,
238
    // short index
239
    // char* name
240
    // Optional chunk which stores precomputed edge data
241
    M_EDGE_LISTS = 0xB000,
242
    // Each LOD has a separate edge list
243
    M_EDGE_LIST_LOD = 0xB100,
244
    // unsigned short lodIndex
245
    // bool isManual            // If manual, no edge data here, loaded from manual mesh
246
    // bool isClosed
247
    // unsigned long numTriangles
248
    // unsigned long numEdgeGroups
249
    // Triangle* triangleList
250
    // unsigned long indexSet
251
    // unsigned long vertexSet
252
    // unsigned long vertIndex[3]
253
    // unsigned long sharedVertIndex[3]
254
    // float normal[4]
255
256
    M_EDGE_GROUP = 0xB110,
257
    // unsigned long vertexSet
258
    // unsigned long triStart
259
    // unsigned long triCount
260
    // unsigned long numEdges
261
    // Edge* edgeList
262
    // unsigned long  triIndex[2]
263
    // unsigned long  vertIndex[2]
264
    // unsigned long  sharedVertIndex[2]
265
    // bool degenerate
266
    // Optional poses section, referred to by pose keyframes
267
    M_POSES = 0xC000,
268
    M_POSE = 0xC100,
269
    // char* name (may be blank)
270
    // unsigned short target    // 0 for shared geometry,
271
    // 1+ for submesh index + 1
272
    // bool includesNormals [1.8+]
273
    M_POSE_VERTEX = 0xC111,
274
    // unsigned long vertexIndex
275
    // float xoffset, yoffset, zoffset
276
    // float xnormal, ynormal, znormal (optional, 1.8+)
277
    // Optional vertex animation chunk
278
    M_ANIMATIONS = 0xD000,
279
    M_ANIMATION = 0xD100,
280
    // char* name
281
    // float length
282
    M_ANIMATION_BASEINFO = 0xD105,
283
    // [Optional] base keyframe information (pose animation only)
284
    // char* baseAnimationName (blank for self)
285
    // float baseKeyFrameTime
286
    M_ANIMATION_TRACK = 0xD110,
287
    // unsigned short type          // 1 == morph, 2 == pose
288
    // unsigned short target        // 0 for shared geometry,
289
    // 1+ for submesh index + 1
290
    M_ANIMATION_MORPH_KEYFRAME = 0xD111,
291
    // float time
292
    // bool includesNormals [1.8+]
293
    // float x,y,z          // repeat by number of vertices in original geometry
294
    M_ANIMATION_POSE_KEYFRAME = 0xD112,
295
    // float time
296
    M_ANIMATION_POSE_REF = 0xD113, // repeat for number of referenced poses
297
    // unsigned short poseIndex
298
    // float influence
299
    // Optional submesh extreme vertex list chink
300
    M_TABLE_EXTREMES = 0xE000
301
    // unsigned short submesh_index;
302
    // float extremes [n_extremes][3];
303
};
304
305
/*
306
static std::string MeshHeaderToString(MeshChunkId id)
307
{
308
    switch(id)
309
    {
310
        case M_HEADER:                      return "HEADER";
311
        case M_MESH:                        return "MESH";
312
        case M_SUBMESH:                     return "SUBMESH";
313
        case M_SUBMESH_OPERATION:           return "SUBMESH_OPERATION";
314
        case M_SUBMESH_BONE_ASSIGNMENT:     return "SUBMESH_BONE_ASSIGNMENT";
315
        case M_SUBMESH_TEXTURE_ALIAS:       return "SUBMESH_TEXTURE_ALIAS";
316
        case M_GEOMETRY:                    return "GEOMETRY";
317
        case M_GEOMETRY_VERTEX_DECLARATION: return "GEOMETRY_VERTEX_DECLARATION";
318
        case M_GEOMETRY_VERTEX_ELEMENT:     return "GEOMETRY_VERTEX_ELEMENT";
319
        case M_GEOMETRY_VERTEX_BUFFER:      return "GEOMETRY_VERTEX_BUFFER";
320
        case M_GEOMETRY_VERTEX_BUFFER_DATA: return "GEOMETRY_VERTEX_BUFFER_DATA";
321
        case M_MESH_SKELETON_LINK:          return "MESH_SKELETON_LINK";
322
        case M_MESH_BONE_ASSIGNMENT:        return "MESH_BONE_ASSIGNMENT";
323
        case M_MESH_LOD:                    return "MESH_LOD";
324
        case M_MESH_LOD_USAGE:              return "MESH_LOD_USAGE";
325
        case M_MESH_LOD_MANUAL:             return "MESH_LOD_MANUAL";
326
        case M_MESH_LOD_GENERATED:          return "MESH_LOD_GENERATED";
327
        case M_MESH_BOUNDS:                 return "MESH_BOUNDS";
328
        case M_SUBMESH_NAME_TABLE:          return "SUBMESH_NAME_TABLE";
329
        case M_SUBMESH_NAME_TABLE_ELEMENT:  return "SUBMESH_NAME_TABLE_ELEMENT";
330
        case M_EDGE_LISTS:                  return "EDGE_LISTS";
331
        case M_EDGE_LIST_LOD:               return "EDGE_LIST_LOD";
332
        case M_EDGE_GROUP:                  return "EDGE_GROUP";
333
        case M_POSES:                       return "POSES";
334
        case M_POSE:                        return "POSE";
335
        case M_POSE_VERTEX:                 return "POSE_VERTEX";
336
        case M_ANIMATIONS:                  return "ANIMATIONS";
337
        case M_ANIMATION:                   return "ANIMATION";
338
        case M_ANIMATION_BASEINFO:          return "ANIMATION_BASEINFO";
339
        case M_ANIMATION_TRACK:             return "ANIMATION_TRACK";
340
        case M_ANIMATION_MORPH_KEYFRAME:    return "ANIMATION_MORPH_KEYFRAME";
341
        case M_ANIMATION_POSE_KEYFRAME:     return "ANIMATION_POSE_KEYFRAME";
342
        case M_ANIMATION_POSE_REF:          return "ANIMATION_POSE_REF";
343
        case M_TABLE_EXTREMES:              return "TABLE_EXTREMES";
344
    }
345
    return "Unknown_MeshChunkId";
346
}
347
*/
348
349
enum SkeletonChunkId {
350
    SKELETON_HEADER = 0x1000,
351
    // char* version           : Version number check
352
    SKELETON_BLENDMODE = 0x1010, // optional
353
    // unsigned short blendmode     : SkeletonAnimationBlendMode
354
    SKELETON_BONE = 0x2000,
355
    // Repeating section defining each bone in the system.
356
    // Bones are assigned indexes automatically based on their order of declaration
357
    // starting with 0.
358
    // char* name                      : name of the bone
359
    // unsigned short handle            : handle of the bone, should be contiguous & start at 0
360
    // Vector3 position              : position of this bone relative to parent
361
    // Quaternion orientation          : orientation of this bone relative to parent
362
    // Vector3 scale                    : scale of this bone relative to parent
363
    SKELETON_BONE_PARENT = 0x3000,
364
    // Record of the parent of a single bone, used to build the node tree
365
    // Repeating section, listed in Bone Index order, one per Bone
366
    // unsigned short handle             : child bone
367
    // unsigned short parentHandle   : parent bone
368
    SKELETON_ANIMATION = 0x4000,
369
    // A single animation for this skeleton
370
    // char* name                      : Name of the animation
371
    // float length                   : Length of the animation in seconds
372
    SKELETON_ANIMATION_BASEINFO = 0x4010,
373
    // [Optional] base keyframe information
374
    // char* baseAnimationName (blank for self)
375
    // float baseKeyFrameTime
376
    SKELETON_ANIMATION_TRACK = 0x4100,
377
    // A single animation track (relates to a single bone)
378
    // Repeating section (within SKELETON_ANIMATION)
379
    // unsigned short boneIndex  : Index of bone to apply to
380
    SKELETON_ANIMATION_TRACK_KEYFRAME = 0x4110,
381
    // A single keyframe within the track
382
    // Repeating section
383
    // float time                   : The time position (seconds)
384
    // Quaternion rotate            : Rotation to apply at this keyframe
385
    // Vector3 translate            : Translation to apply at this keyframe
386
    // Vector3 scale                : Scale to apply at this keyframe
387
    SKELETON_ANIMATION_LINK = 0x5000
388
    // Link to another skeleton, to re-use its animations
389
    // char* skeletonName                   : name of skeleton to get animations from
390
    // float scale                          : scale to apply to trans/scale keys
391
};
392
393
/*
394
static std::string SkeletonHeaderToString(SkeletonChunkId id)
395
{
396
    switch(id)
397
    {
398
        case SKELETON_HEADER:                   return "HEADER";
399
        case SKELETON_BLENDMODE:                return "BLENDMODE";
400
        case SKELETON_BONE:                     return "BONE";
401
        case SKELETON_BONE_PARENT:              return "BONE_PARENT";
402
        case SKELETON_ANIMATION:                return "ANIMATION";
403
        case SKELETON_ANIMATION_BASEINFO:       return "ANIMATION_BASEINFO";
404
        case SKELETON_ANIMATION_TRACK:          return "ANIMATION_TRACK";
405
        case SKELETON_ANIMATION_TRACK_KEYFRAME: return "ANIMATION_TRACK_KEYFRAME";
406
        case SKELETON_ANIMATION_LINK:           return "ANIMATION_LINK";
407
    }
408
    return "Unknown_SkeletonChunkId";
409
}
410
*/
411
} // namespace Ogre
412
} // namespace Assimp
413
414
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
415
#endif // AI_OGREBINARYSERIALIZER_H_INC