#ifndef __I_ANIMATED_MESH_MD3_H_INCLUDED__
#define __I_ANIMATED_MESH_MD3_H_INCLUDED__
#include "IAnimatedMesh.h"
#include "IQ3Shader.h"
#include "quaternion.h"
namespace irr
{
namespace scene
{
enum eMD3Models
{
EMD3_HEAD = 0,
EMD3_UPPER,
EMD3_LOWER,
EMD3_WEAPON,
EMD3_NUMMODELS
};
enum EMD3_ANIMATION_TYPE
{
EMD3_BOTH_DEATH_1 = 0,
EMD3_BOTH_DEAD_1,
EMD3_BOTH_DEATH_2,
EMD3_BOTH_DEAD_2,
EMD3_BOTH_DEATH_3,
EMD3_BOTH_DEAD_3,
EMD3_TORSO_GESTURE,
EMD3_TORSO_ATTACK_1,
EMD3_TORSO_ATTACK_2,
EMD3_TORSO_DROP,
EMD3_TORSO_RAISE,
EMD3_TORSO_STAND_1,
EMD3_TORSO_STAND_2,
EMD3_LEGS_WALK_CROUCH,
EMD3_LEGS_WALK,
EMD3_LEGS_RUN,
EMD3_LEGS_BACK,
EMD3_LEGS_SWIM,
EMD3_LEGS_JUMP_1,
EMD3_LEGS_LAND_1,
EMD3_LEGS_JUMP_2,
EMD3_LEGS_LAND_2,
EMD3_LEGS_IDLE,
EMD3_LEGS_IDLE_CROUCH,
EMD3_LEGS_TURN,
EMD3_ANIMATION_COUNT
};
struct SMD3AnimationInfo
{
s32 first;
s32 num;
s32 looping;
s32 fps;
};
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
#elif defined( __GNUC__ )
# define PACK_STRUCT __attribute__((packed))
#else
# error compiler not supported
#endif
struct SMD3Header
{
c8 headerID[4];
s32 Version;
s8 fileName[68];
s32 numFrames;
s32 numTags;
s32 numMeshes;
s32 numMaxSkins;
s32 frameStart;
s32 tagStart;
s32 tagEnd;
s32 fileSize;
};
struct SMD3MeshHeader
{
c8 meshID[4];
c8 meshName[68];
s32 numFrames;
s32 numShader;
s32 numVertices;
s32 numTriangles;
s32 offset_triangles;
s32 offset_shaders;
s32 offset_st;
s32 vertexStart;
s32 offset_end;
};
struct SMD3Vertex
{
s16 position[3];
u8 normal[2];
};
struct SMD3TexCoord
{
f32 u;
f32 v;
};
struct SMD3Face
{
s32 Index[3];
};
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
#undef PACK_STRUCT
struct SMD3MeshBuffer : public IReferenceCounted
{
SMD3MeshHeader MeshHeader;
core::stringc Shader;
core::array < s32 > Indices;
core::array < SMD3Vertex > Vertices;
core::array < SMD3TexCoord > Tex;
};
struct SMD3QuaternionTag
{
virtual ~SMD3QuaternionTag()
{
position.X = 0.f;
}
SMD3QuaternionTag( const SMD3QuaternionTag & copyMe )
{
*this = copyMe;
}
SMD3QuaternionTag( const core::stringc& name )
: Name ( name ) {}
SMD3QuaternionTag ( const core::stringc& name, const core::matrix4 &m )
: Name(name), position(m.getTranslation()), rotation(m) {}
SMD3QuaternionTag ( const core::vector3df &pos, const core::vector3df &angle )
: position(pos), rotation(angle * core::DEGTORAD) {}
void setto ( core::matrix4 &m )
{
rotation.getMatrix ( m, position );
}
bool operator == ( const SMD3QuaternionTag &other ) const
{
return Name == other.Name;
}
SMD3QuaternionTag & operator=( const SMD3QuaternionTag & copyMe )
{
Name = copyMe.Name;
position = copyMe.position;
rotation = copyMe.rotation;
return *this;
}
core::stringc Name;
core::vector3df position;
core::quaternion rotation;
};
struct SMD3QuaternionTagList
{
SMD3QuaternionTagList ()
{
Container.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE );
}
SMD3QuaternionTagList( const SMD3QuaternionTagList & copyMe )
{
*this = copyMe;
}
virtual ~SMD3QuaternionTagList () {}
SMD3QuaternionTag* get ( const core::stringc& name )
{
SMD3QuaternionTag search ( name );
s32 index = Container.linear_search ( search );
if ( index >= 0 )
return &Container[index];
return 0;
}
u32 size () const
{
return Container.size();
}
void set_used ( u32 new_size)
{
s32 diff = (s32) new_size - (s32) Container.allocated_size ();
if ( diff > 0 )
{
SMD3QuaternionTag e ( "" );
for ( s32 i = 0; i < diff; ++i )
Container.push_back ( e );
}
}
const SMD3QuaternionTag& operator[](u32 index) const
{
return Container[index];
}
SMD3QuaternionTag& operator[](u32 index)
{
return Container[index];
}
void push_back ( const SMD3QuaternionTag& other )
{
Container.push_back ( other );
}
SMD3QuaternionTagList& operator = (const SMD3QuaternionTagList & copyMe)
{
Container = copyMe.Container;
return *this;
}
private:
core::array < SMD3QuaternionTag > Container;
};
struct SMD3Mesh: public IReferenceCounted
{
SMD3Mesh ()
{
MD3Header.numFrames = 0;
}
virtual ~SMD3Mesh()
{
for (u32 i=0; i<Buffer.size(); ++i)
Buffer[i]->drop();
}
core::stringc Name;
core::array < SMD3MeshBuffer * > Buffer;
SMD3QuaternionTagList TagList;
SMD3Header MD3Header;
};
class IAnimatedMeshMD3 : public IAnimatedMesh
{
public:
virtual void setInterpolationShift ( u32 shift, u32 loopMode ) = 0;
virtual SMD3QuaternionTagList *getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) = 0;
virtual SMD3Mesh * getOriginalMesh () = 0;
};
}
}
#endif