/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 |