1 // Copyright (C) 2007-2012 Nikolaus Gebhardt / Thomas Alten
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #ifndef __I_ANIMATED_MESH_MD3_H_INCLUDED__
\r
6 #define __I_ANIMATED_MESH_MD3_H_INCLUDED__
\r
8 #include "IAnimatedMesh.h"
\r
9 #include "IQ3Shader.h"
\r
10 #include "quaternion.h"
\r
27 enum EMD3_ANIMATION_TYPE
\r
29 // Animations for both lower and upper parts of the player
\r
30 EMD3_BOTH_DEATH_1 = 0,
\r
37 // Animations for the upper part
\r
39 EMD3_TORSO_ATTACK_1,
\r
40 EMD3_TORSO_ATTACK_2,
\r
46 // Animations for the lower part
\r
47 EMD3_LEGS_WALK_CROUCH,
\r
57 EMD3_LEGS_IDLE_CROUCH,
\r
60 //! Not an animation, but amount of animation types.
\r
61 EMD3_ANIMATION_COUNT
\r
64 struct SMD3AnimationInfo
\r
72 //! Frames per second
\r
77 // byte-align structures
\r
78 #include "irrpack.h"
\r
80 //! this holds the header info of the MD3 file
\r
83 c8 headerID[4]; //id of file, always "IDP3"
\r
84 s32 Version; //this is a version number, always 15
\r
85 s8 fileName[68];//sometimes left Blank... 65 chars, 32bit aligned == 68 chars
\r
86 s32 numFrames; //number of KeyFrames
\r
87 s32 numTags; //number of 'tags' per frame
\r
88 s32 numMeshes; //number of meshes/skins
\r
89 s32 numMaxSkins;//maximum number of unique skins used in md3 file. artefact md2
\r
90 s32 frameStart; //starting position of frame-structur
\r
91 s32 tagStart; //starting position of tag-structures
\r
92 s32 tagEnd; //ending position of tag-structures/starting position of mesh-structures
\r
96 //! this holds the header info of an MD3 mesh section
\r
97 struct SMD3MeshHeader
\r
99 c8 meshID[4]; //id, must be IDP3
\r
100 c8 meshName[68]; //name of mesh 65 chars, 32 bit aligned == 68 chars
\r
102 s32 numFrames; //number of meshframes in mesh
\r
103 s32 numShader; //number of skins in mesh
\r
104 s32 numVertices; //number of vertices
\r
105 s32 numTriangles; //number of Triangles
\r
107 s32 offset_triangles; //starting position of Triangle data, relative to start of Mesh_Header
\r
108 s32 offset_shaders; //size of header
\r
109 s32 offset_st; //starting position of texvector data, relative to start of Mesh_Header
\r
110 s32 vertexStart; //starting position of vertex data,relative to start of Mesh_Header
\r
115 //! Compressed Vertex Data
\r
122 //! Texture Coordinate
\r
123 struct SMD3TexCoord
\r
136 // Default alignment
\r
137 #include "irrunpack.h"
\r
139 //! Holding Frame Data for a Mesh
\r
140 struct SMD3MeshBuffer : public IReferenceCounted
\r
142 SMD3MeshHeader MeshHeader;
\r
144 core::stringc Shader;
\r
145 core::array < s32 > Indices;
\r
146 core::array < SMD3Vertex > Vertices;
\r
147 core::array < SMD3TexCoord > Tex;
\r
150 //! hold a tag info for connecting meshes
\r
151 /** Basically its an alternate way to describe a transformation. */
\r
152 struct SMD3QuaternionTag
\r
154 virtual ~SMD3QuaternionTag()
\r
159 // construct copy constructor
\r
160 SMD3QuaternionTag( const SMD3QuaternionTag & copyMe )
\r
165 // construct for searching
\r
166 SMD3QuaternionTag( const core::stringc& name )
\r
169 // construct from a position and euler angles in degrees
\r
170 SMD3QuaternionTag ( const core::vector3df &pos, const core::vector3df &angle )
\r
171 : position(pos), rotation(angle * core::DEGTORAD) {}
\r
174 void setto ( core::matrix4 &m )
\r
176 rotation.getMatrix ( m, position );
\r
179 bool operator == ( const SMD3QuaternionTag &other ) const
\r
181 return Name == other.Name;
\r
184 SMD3QuaternionTag & operator=( const SMD3QuaternionTag & copyMe )
\r
186 Name = copyMe.Name;
\r
187 position = copyMe.position;
\r
188 rotation = copyMe.rotation;
\r
192 core::stringc Name;
\r
193 core::vector3df position;
\r
194 core::quaternion rotation;
\r
197 //! holds a associative list of named quaternions
\r
198 struct SMD3QuaternionTagList
\r
200 SMD3QuaternionTagList()
\r
202 Container.setAllocStrategy(core::ALLOC_STRATEGY_SAFE);
\r
205 // construct copy constructor
\r
206 SMD3QuaternionTagList(const SMD3QuaternionTagList& copyMe)
\r
211 virtual ~SMD3QuaternionTagList() {}
\r
213 SMD3QuaternionTag* get(const core::stringc& name)
\r
215 SMD3QuaternionTag search ( name );
\r
216 s32 index = Container.linear_search ( search );
\r
218 return &Container[index];
\r
224 return Container.size();
\r
227 void set_used(u32 new_size)
\r
229 s32 diff = (s32) new_size - (s32) Container.allocated_size();
\r
232 SMD3QuaternionTag e("");
\r
233 for ( s32 i = 0; i < diff; ++i )
\r
234 Container.push_back(e);
\r
238 const SMD3QuaternionTag& operator[](u32 index) const
\r
240 return Container[index];
\r
243 SMD3QuaternionTag& operator[](u32 index)
\r
245 return Container[index];
\r
248 void push_back(const SMD3QuaternionTag& other)
\r
250 Container.push_back(other);
\r
253 SMD3QuaternionTagList& operator = (const SMD3QuaternionTagList & copyMe)
\r
255 Container = copyMe.Container;
\r
260 core::array < SMD3QuaternionTag > Container;
\r
264 //! Holding Frames Buffers and Tag Infos
\r
265 struct SMD3Mesh: public IReferenceCounted
\r
269 MD3Header.numFrames = 0;
\r
272 virtual ~SMD3Mesh()
\r
274 for (u32 i=0; i<Buffer.size(); ++i)
\r
278 core::stringc Name;
\r
279 core::array<SMD3MeshBuffer*> Buffer;
\r
280 SMD3QuaternionTagList TagList;
\r
281 SMD3Header MD3Header;
\r
285 //! Interface for using some special functions of MD3 meshes
\r
286 class IAnimatedMeshMD3 : public IAnimatedMesh
\r
290 //! tune how many frames you want to render in between.
\r
291 virtual void setInterpolationShift(u32 shift, u32 loopMode) =0;
\r
293 //! get the tag list of the mesh.
\r
294 virtual SMD3QuaternionTagList* getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) =0;
\r
296 //! get the original md3 mesh.
\r
297 virtual SMD3Mesh* getOriginalMesh() =0;
\r
300 } // end namespace scene
\r
301 } // end namespace irr
\r