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#ifndef AI_OGRESTRUCTS_H_INC
43#define AI_OGRESTRUCTS_H_INC
44
45#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
46
47#include "MemoryIOWrapper.h"
48#include <memory>
49#include <assimp/mesh.h>
50#include <map>
51#include <vector>
52#include <set>
53
54struct aiNodeAnim;
55struct aiAnimation;
56struct aiNode;
57struct aiMaterial;
58struct aiScene;
59
60/** @note Parts of this implementation, for example enums, deserialization constants and logic
61 has been copied directly with minor modifications from the MIT licensed Ogre3D code base.
62 See more from https://bitbucket.org/sinbad/ogre. */
63
64namespace Assimp
65{
66namespace Ogre
67{
68
69// Forward decl
70class Mesh;
71class MeshXml;
72class SubMesh;
73class SubMeshXml;
74class Skeleton;
75
76#define OGRE_SAFE_DELETE(p) delete p; p=0;
77
78// Typedefs
79typedef Assimp::MemoryIOStream MemoryStream;
80typedef std::shared_ptr<MemoryStream> MemoryStreamPtr;
81typedef std::map<uint16_t, MemoryStreamPtr> VertexBufferBindings;
82
83// Ogre Vertex Element
84class VertexElement
85{
86public:
87 /// Vertex element semantics, used to identify the meaning of vertex buffer contents
88 enum Semantic {
89 /// Position, 3 reals per vertex
90 VES_POSITION = 1,
91 /// Blending weights
92 VES_BLEND_WEIGHTS = 2,
93 /// Blending indices
94 VES_BLEND_INDICES = 3,
95 /// Normal, 3 reals per vertex
96 VES_NORMAL = 4,
97 /// Diffuse colours
98 VES_DIFFUSE = 5,
99 /// Specular colours
100 VES_SPECULAR = 6,
101 /// Texture coordinates
102 VES_TEXTURE_COORDINATES = 7,
103 /// Binormal (Y axis if normal is Z)
104 VES_BINORMAL = 8,
105 /// Tangent (X axis if normal is Z)
106 VES_TANGENT = 9,
107 /// The number of VertexElementSemantic elements (note - the first value VES_POSITION is 1)
108 VES_COUNT = 9
109 };
110
111 /// Vertex element type, used to identify the base types of the vertex contents
112 enum Type
113 {
114 VET_FLOAT1 = 0,
115 VET_FLOAT2 = 1,
116 VET_FLOAT3 = 2,
117 VET_FLOAT4 = 3,
118 /// alias to more specific colour type - use the current rendersystem's colour packing
119 VET_COLOUR = 4,
120 VET_SHORT1 = 5,
121 VET_SHORT2 = 6,
122 VET_SHORT3 = 7,
123 VET_SHORT4 = 8,
124 VET_UBYTE4 = 9,
125 /// D3D style compact colour
126 VET_COLOUR_ARGB = 10,
127 /// GL style compact colour
128 VET_COLOUR_ABGR = 11,
129 VET_DOUBLE1 = 12,
130 VET_DOUBLE2 = 13,
131 VET_DOUBLE3 = 14,
132 VET_DOUBLE4 = 15,
133 VET_USHORT1 = 16,
134 VET_USHORT2 = 17,
135 VET_USHORT3 = 18,
136 VET_USHORT4 = 19,
137 VET_INT1 = 20,
138 VET_INT2 = 21,
139 VET_INT3 = 22,
140 VET_INT4 = 23,
141 VET_UINT1 = 24,
142 VET_UINT2 = 25,
143 VET_UINT3 = 26,
144 VET_UINT4 = 27
145 };
146
147 VertexElement();
148
149 /// Size of the vertex element in bytes.
150 size_t Size() const;
151
152 /// Count of components in this element, eg. VET_FLOAT3 return 3.
153 size_t ComponentCount() const;
154
155 /// Type as string.
156 std::string TypeToString();
157
158 /// Semantic as string.
159 std::string SemanticToString();
160
161 static size_t TypeSize(Type type);
162 static size_t ComponentCount(Type type);
163 static std::string TypeToString(Type type);
164 static std::string SemanticToString(Semantic semantic);
165
166 uint16_t index;
167 uint16_t source;
168 uint16_t offset;
169 Type type;
170 Semantic semantic;
171};
172typedef std::vector<VertexElement> VertexElementList;
173
174/// Ogre Vertex Bone Assignment
175struct VertexBoneAssignment
176{
177 uint32_t vertexIndex;
178 uint16_t boneIndex;
179 float weight;
180};
181typedef std::vector<VertexBoneAssignment> VertexBoneAssignmentList;
182typedef std::map<uint32_t, VertexBoneAssignmentList > VertexBoneAssignmentsMap;
183typedef std::map<uint16_t, std::vector<aiVertexWeight> > AssimpVertexBoneWeightList;
184
185// Ogre Vertex Data interface, inherited by the binary and XML implementations.
186class IVertexData
187{
188public:
189 IVertexData();
190
191 /// Returns if bone assignments are available.
192 bool HasBoneAssignments() const;
193
194 /// Add vertex mapping from old to new index.
195 void AddVertexMapping(uint32_t oldIndex, uint32_t newIndex);
196
197 /// Returns re-mapped bone assignments.
198 /** @note Uses mappings added via AddVertexMapping. */
199 AssimpVertexBoneWeightList AssimpBoneWeights(size_t vertices);
200
201 /// Returns a set of bone indexes that are referenced by bone assignments (weights).
202 std::set<uint16_t> ReferencedBonesByWeights() const;
203
204 /// Vertex count.
205 uint32_t count;
206
207 /// Bone assignments.
208 VertexBoneAssignmentList boneAssignments;
209
210private:
211 void BoneAssignmentsForVertex(uint32_t currentIndex, uint32_t newIndex, VertexBoneAssignmentList &dest) const;
212
213 std::map<uint32_t, std::vector<uint32_t> > vertexIndexMapping;
214 VertexBoneAssignmentsMap boneAssignmentsMap;
215};
216
217// Ogre Vertex Data
218class VertexData : public IVertexData
219{
220public:
221 VertexData();
222 ~VertexData();
223
224 /// Releases all memory that this data structure owns.
225 void Reset();
226
227 /// Get vertex size for @c source.
228 uint32_t VertexSize(uint16_t source) const;
229
230 /// Get vertex buffer for @c source.
231 MemoryStream *VertexBuffer(uint16_t source);
232
233 /// Get vertex element for @c semantic for @c index.
234 VertexElement *GetVertexElement(VertexElement::Semantic semantic, uint16_t index = 0);
235
236 /// Vertex elements.
237 VertexElementList vertexElements;
238
239 /// Vertex buffers mapped to bind index.
240 VertexBufferBindings vertexBindings;
241};
242
243// Ogre Index Data
244class IndexData
245{
246public:
247 IndexData();
248 ~IndexData();
249
250 /// Releases all memory that this data structure owns.
251 void Reset();
252
253 /// Index size in bytes.
254 size_t IndexSize() const;
255
256 /// Face size in bytes.
257 size_t FaceSize() const;
258
259 /// Index count.
260 uint32_t count;
261
262 /// Face count.
263 uint32_t faceCount;
264
265 /// If has 32-bit indexes.
266 bool is32bit;
267
268 /// Index buffer.
269 MemoryStreamPtr buffer;
270};
271
272/// Ogre Pose
273class Pose
274{
275public:
276 struct Vertex
277 {
278 uint32_t index;
279 aiVector3D offset;
280 aiVector3D normal;
281 };
282 typedef std::map<uint32_t, Vertex> PoseVertexMap;
283
284 Pose() : target(0), hasNormals(false) {}
285
286 /// Name.
287 std::string name;
288
289 /// Target.
290 uint16_t target;
291
292 /// Does vertices map have normals.
293 bool hasNormals;
294
295 /// Vertex offset and normals.
296 PoseVertexMap vertices;
297};
298typedef std::vector<Pose*> PoseList;
299
300/// Ogre Pose Key Frame Ref
301struct PoseRef
302{
303 uint16_t index;
304 float influence;
305};
306typedef std::vector<PoseRef> PoseRefList;
307
308/// Ogre Pose Key Frame
309struct PoseKeyFrame
310{
311 /// Time position in the animation.
312 float timePos;
313
314 PoseRefList references;
315};
316typedef std::vector<PoseKeyFrame> PoseKeyFrameList;
317
318/// Ogre Morph Key Frame
319struct MorphKeyFrame
320{
321 /// Time position in the animation.
322 float timePos;
323
324 MemoryStreamPtr buffer;
325};
326typedef std::vector<MorphKeyFrame> MorphKeyFrameList;
327
328/// Ogre animation key frame
329struct TransformKeyFrame
330{
331 TransformKeyFrame();
332
333 aiMatrix4x4 Transform();
334
335 float timePos;
336
337 aiQuaternion rotation;
338 aiVector3D position;
339 aiVector3D scale;
340};
341typedef std::vector<TransformKeyFrame> TransformKeyFrameList;
342
343/// Ogre Animation Track
344struct VertexAnimationTrack
345{
346 enum Type
347 {
348 /// No animation
349 VAT_NONE = 0,
350 /// Morph animation is made up of many interpolated snapshot keyframes
351 VAT_MORPH = 1,
352 /// Pose animation is made up of a single delta pose keyframe
353 VAT_POSE = 2,
354 /// Keyframe that has its on pos, rot and scale for a time position
355 VAT_TRANSFORM = 3
356 };
357
358 VertexAnimationTrack();
359
360 /// Convert to Assimp node animation.
361 aiNodeAnim *ConvertToAssimpAnimationNode(Skeleton *skeleton);
362
363 // Animation type.
364 Type type;
365
366 /// Vertex data target.
367 /** 0 == shared geometry
368 >0 == submesh index + 1 */
369 uint16_t target;
370
371 /// Only valid for VAT_TRANSFORM.
372 std::string boneName;
373
374 /// Only one of these will contain key frames, depending on the type enum.
375 PoseKeyFrameList poseKeyFrames;
376 MorphKeyFrameList morphKeyFrames;
377 TransformKeyFrameList transformKeyFrames;
378};
379typedef std::vector<VertexAnimationTrack> VertexAnimationTrackList;
380
381/// Ogre Animation
382class Animation
383{
384public:
385 explicit Animation(Skeleton *parent);
386 explicit Animation(Mesh *parent);
387
388 /// Returns the associated vertex data for a track in this animation.
389 /** @note Only valid to call when parent Mesh is set. */
390 VertexData *AssociatedVertexData(VertexAnimationTrack *track) const;
391
392 /// Convert to Assimp animation.
393 aiAnimation *ConvertToAssimpAnimation();
394
395 /// Parent mesh.
396 /** @note Set only when animation is read from a mesh. */
397 Mesh *parentMesh;
398
399 /// Parent skeleton.
400 /** @note Set only when animation is read from a skeleton. */
401 Skeleton *parentSkeleton;
402
403 /// Animation name.
404 std::string name;
405
406 /// Base animation name.
407 std::string baseName;
408
409 /// Length in seconds.
410 float length;
411
412 /// Base animation key time.
413 float baseTime;
414
415 /// Animation tracks.
416 VertexAnimationTrackList tracks;
417};
418typedef std::vector<Animation*> AnimationList;
419
420/// Ogre Bone
421class Bone
422{
423public:
424 Bone();
425
426 /// Returns if this bone is parented.
427 bool IsParented() const;
428
429 /// Parent index as uint16_t. Internally int32_t as -1 means unparented.
430 uint16_t ParentId() const;
431
432 /// Add child bone.
433 void AddChild(Bone *bone);
434
435 /// Calculates the world matrix for bone and its children.
436 void CalculateWorldMatrixAndDefaultPose(Skeleton *skeleton);
437
438 /// Convert to Assimp node (animation nodes).
439 aiNode *ConvertToAssimpNode(Skeleton *parent, aiNode *parentNode = 0);
440
441 /// Convert to Assimp bone (mesh bones).
442 aiBone *ConvertToAssimpBone(Skeleton *parent, const std::vector<aiVertexWeight> &boneWeights);
443
444 uint16_t id;
445 std::string name;
446
447 Bone *parent;
448 int32_t parentId;
449 std::vector<uint16_t> children;
450
451 aiVector3D position;
452 aiQuaternion rotation;
453 aiVector3D scale;
454
455 aiMatrix4x4 worldMatrix;
456 aiMatrix4x4 defaultPose;
457};
458typedef std::vector<Bone*> BoneList;
459
460/// Ogre Skeleton
461class Skeleton
462{
463public:
464 enum BlendMode
465 {
466 /// Animations are applied by calculating a weighted average of all animations
467 ANIMBLEND_AVERAGE = 0,
468 /// Animations are applied by calculating a weighted cumulative total
469 ANIMBLEND_CUMULATIVE = 1
470 };
471
472 Skeleton();
473 ~Skeleton();
474
475 /// Releases all memory that this data structure owns.
476 void Reset();
477
478 /// Returns unparented root bones.
479 BoneList RootBones() const;
480
481 /// Returns number of unparented root bones.
482 size_t NumRootBones() const;
483
484 /// Get bone by name.
485 Bone *BoneByName(const std::string &name) const;
486
487 /// Get bone by id.
488 Bone *BoneById(uint16_t id) const;
489
490 BoneList bones;
491 AnimationList animations;
492
493 /// @todo Take blend mode into account, but where?
494 BlendMode blendMode;
495};
496
497/// Ogre Sub Mesh interface, inherited by the binary and XML implementations.
498class ISubMesh
499{
500public:
501 /// @note Full list of Ogre types, not all of them are supported and exposed to Assimp.
502 enum OperationType
503 {
504 /// A list of points, 1 vertex per point
505 OT_POINT_LIST = 1,
506 /// A list of lines, 2 vertices per line
507 OT_LINE_LIST = 2,
508 /// A strip of connected lines, 1 vertex per line plus 1 start vertex
509 OT_LINE_STRIP = 3,
510 /// A list of triangles, 3 vertices per triangle
511 OT_TRIANGLE_LIST = 4,
512 /// A strip of triangles, 3 vertices for the first triangle, and 1 per triangle after that
513 OT_TRIANGLE_STRIP = 5,
514 /// A fan of triangles, 3 vertices for the first triangle, and 1 per triangle after that
515 OT_TRIANGLE_FAN = 6
516 };
517
518 ISubMesh();
519
520 /// SubMesh index.
521 unsigned int index;
522
523 /// SubMesh name.
524 std::string name;
525
526 /// Material used by this submesh.
527 std::string materialRef;
528
529 /// Texture alias information.
530 std::string textureAliasName;
531 std::string textureAliasRef;
532
533 /// Assimp scene material index used by this submesh.
534 /** -1 if no material or material could not be imported. */
535 int materialIndex;
536
537 /// If submesh uses shared geometry from parent mesh.
538 bool usesSharedVertexData;
539
540 /// Operation type.
541 OperationType operationType;
542};
543
544/// Ogre SubMesh
545class SubMesh : public ISubMesh
546{
547public:
548 SubMesh();
549 ~SubMesh();
550
551 /// Releases all memory that this data structure owns.
552 /** @note Vertex and index data contains shared ptrs
553 that are freed automatically. In practice the ref count
554 should be 0 after this reset. */
555 void Reset();
556
557 /// Covert to Assimp mesh.
558 aiMesh *ConvertToAssimpMesh(Mesh *parent);
559
560 /// Vertex data.
561 VertexData *vertexData;
562
563 /// Index data.
564 IndexData *indexData;
565};
566typedef std::vector<SubMesh*> SubMeshList;
567
568/// Ogre Mesh
569class Mesh
570{
571public:
572 /// Constructor.
573 Mesh();
574
575 /// Destructor.
576 ~Mesh();
577
578 /// Releases all memory that this data structure owns.
579 void Reset();
580
581 /// Returns number of subMeshes.
582 size_t NumSubMeshes() const;
583
584 /// Returns submesh for @c index.
585 SubMesh *GetSubMesh( size_t index) const;
586
587 /// Convert mesh to Assimp scene.
588 void ConvertToAssimpScene(aiScene* dest);
589
590 /// Mesh has skeletal animations.
591 bool hasSkeletalAnimations;
592
593 /// Skeleton reference.
594 std::string skeletonRef;
595
596 /// Skeleton.
597 Skeleton *skeleton;
598
599 /// Vertex data
600 VertexData *sharedVertexData;
601
602 /// Sub meshes.
603 SubMeshList subMeshes;
604
605 /// Animations
606 AnimationList animations;
607
608 /// Poses
609 PoseList poses;
610};
611
612/// Ogre XML Vertex Data
613class VertexDataXml : public IVertexData
614{
615public:
616 VertexDataXml();
617
618 bool HasPositions() const;
619 bool HasNormals() const;
620 bool HasTangents() const;
621 bool HasUvs() const;
622 size_t NumUvs() const;
623
624 std::vector<aiVector3D> positions;
625 std::vector<aiVector3D> normals;
626 std::vector<aiVector3D> tangents;
627 std::vector<std::vector<aiVector3D> > uvs;
628};
629
630/// Ogre XML Index Data
631class IndexDataXml
632{
633public:
634 IndexDataXml() : faceCount(0) {}
635
636 /// Face count.
637 uint32_t faceCount;
638
639 std::vector<aiFace> faces;
640};
641
642/// Ogre XML SubMesh
643class SubMeshXml : public ISubMesh
644{
645public:
646 SubMeshXml();
647 ~SubMeshXml();
648
649 /// Releases all memory that this data structure owns.
650 void Reset();
651
652 aiMesh *ConvertToAssimpMesh(MeshXml *parent);
653
654 IndexDataXml *indexData;
655 VertexDataXml *vertexData;
656};
657typedef std::vector<SubMeshXml*> SubMeshXmlList;
658
659/// Ogre XML Mesh
660class MeshXml
661{
662public:
663 MeshXml();
664 ~MeshXml();
665
666 /// Releases all memory that this data structure owns.
667 void Reset();
668
669 /// Returns number of subMeshes.
670 size_t NumSubMeshes() const;
671
672 /// Returns submesh for @c index.
673 SubMeshXml *GetSubMesh(uint16_t index) const;
674
675 /// Convert mesh to Assimp scene.
676 void ConvertToAssimpScene(aiScene* dest);
677
678 /// Skeleton reference.
679 std::string skeletonRef;
680
681 /// Skeleton.
682 Skeleton *skeleton;
683
684 /// Vertex data
685 VertexDataXml *sharedVertexData;
686
687 /// Sub meshes.
688 SubMeshXmlList subMeshes;
689};
690
691} // Ogre
692} // Assimp
693
694#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
695#endif // AI_OGRESTRUCTS_H_INC
696