mirror of
https://github.com/minetest/irrlicht.git
synced 2024-12-27 08:27:30 +01:00
305 lines
6.8 KiB
C
305 lines
6.8 KiB
C
|
// Copyright (C) 2007-2012 Nikolaus Gebhardt / Thomas Alten
|
||
|
// This file is part of the "Irrlicht Engine".
|
||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||
|
|
||
|
#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
|
||
|
};
|
||
|
|
||
|
//! Animation list
|
||
|
enum EMD3_ANIMATION_TYPE
|
||
|
{
|
||
|
// Animations for both lower and upper parts of the player
|
||
|
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,
|
||
|
|
||
|
// Animations for the upper part
|
||
|
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,
|
||
|
|
||
|
// Animations for the lower part
|
||
|
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,
|
||
|
|
||
|
//! Not an animation, but amount of animation types.
|
||
|
EMD3_ANIMATION_COUNT
|
||
|
};
|
||
|
|
||
|
struct SMD3AnimationInfo
|
||
|
{
|
||
|
//! First frame
|
||
|
s32 first;
|
||
|
//! Last frame
|
||
|
s32 num;
|
||
|
//! Looping frames
|
||
|
s32 looping;
|
||
|
//! Frames per second
|
||
|
s32 fps;
|
||
|
};
|
||
|
|
||
|
|
||
|
// byte-align structures
|
||
|
#include "irrpack.h"
|
||
|
|
||
|
//! this holds the header info of the MD3 file
|
||
|
struct SMD3Header
|
||
|
{
|
||
|
c8 headerID[4]; //id of file, always "IDP3"
|
||
|
s32 Version; //this is a version number, always 15
|
||
|
s8 fileName[68];//sometimes left Blank... 65 chars, 32bit aligned == 68 chars
|
||
|
s32 numFrames; //number of KeyFrames
|
||
|
s32 numTags; //number of 'tags' per frame
|
||
|
s32 numMeshes; //number of meshes/skins
|
||
|
s32 numMaxSkins;//maximum number of unique skins used in md3 file. artefact md2
|
||
|
s32 frameStart; //starting position of frame-structur
|
||
|
s32 tagStart; //starting position of tag-structures
|
||
|
s32 tagEnd; //ending position of tag-structures/starting position of mesh-structures
|
||
|
s32 fileSize;
|
||
|
} PACK_STRUCT;
|
||
|
|
||
|
//! this holds the header info of an MD3 mesh section
|
||
|
struct SMD3MeshHeader
|
||
|
{
|
||
|
c8 meshID[4]; //id, must be IDP3
|
||
|
c8 meshName[68]; //name of mesh 65 chars, 32 bit aligned == 68 chars
|
||
|
|
||
|
s32 numFrames; //number of meshframes in mesh
|
||
|
s32 numShader; //number of skins in mesh
|
||
|
s32 numVertices; //number of vertices
|
||
|
s32 numTriangles; //number of Triangles
|
||
|
|
||
|
s32 offset_triangles; //starting position of Triangle data, relative to start of Mesh_Header
|
||
|
s32 offset_shaders; //size of header
|
||
|
s32 offset_st; //starting position of texvector data, relative to start of Mesh_Header
|
||
|
s32 vertexStart; //starting position of vertex data,relative to start of Mesh_Header
|
||
|
s32 offset_end;
|
||
|
} PACK_STRUCT;
|
||
|
|
||
|
|
||
|
//! Compressed Vertex Data
|
||
|
struct SMD3Vertex
|
||
|
{
|
||
|
s16 position[3];
|
||
|
u8 normal[2];
|
||
|
} PACK_STRUCT;
|
||
|
|
||
|
//! Texture Coordinate
|
||
|
struct SMD3TexCoord
|
||
|
{
|
||
|
f32 u;
|
||
|
f32 v;
|
||
|
} PACK_STRUCT;
|
||
|
|
||
|
//! Triangle Index
|
||
|
struct SMD3Face
|
||
|
{
|
||
|
s32 Index[3];
|
||
|
} PACK_STRUCT;
|
||
|
|
||
|
|
||
|
// Default alignment
|
||
|
#include "irrunpack.h"
|
||
|
|
||
|
//! Holding Frame Data for a Mesh
|
||
|
struct SMD3MeshBuffer : public IReferenceCounted
|
||
|
{
|
||
|
SMD3MeshHeader MeshHeader;
|
||
|
|
||
|
core::stringc Shader;
|
||
|
core::array < s32 > Indices;
|
||
|
core::array < SMD3Vertex > Vertices;
|
||
|
core::array < SMD3TexCoord > Tex;
|
||
|
};
|
||
|
|
||
|
//! hold a tag info for connecting meshes
|
||
|
/** Basically its an alternate way to describe a transformation. */
|
||
|
struct SMD3QuaternionTag
|
||
|
{
|
||
|
virtual ~SMD3QuaternionTag()
|
||
|
{
|
||
|
position.X = 0.f;
|
||
|
}
|
||
|
|
||
|
// construct copy constructor
|
||
|
SMD3QuaternionTag( const SMD3QuaternionTag & copyMe )
|
||
|
{
|
||
|
*this = copyMe;
|
||
|
}
|
||
|
|
||
|
// construct for searching
|
||
|
SMD3QuaternionTag( const core::stringc& name )
|
||
|
: Name ( name ) {}
|
||
|
|
||
|
// construct from a position and euler angles in degrees
|
||
|
SMD3QuaternionTag ( const core::vector3df &pos, const core::vector3df &angle )
|
||
|
: position(pos), rotation(angle * core::DEGTORAD) {}
|
||
|
|
||
|
// set to matrix
|
||
|
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;
|
||
|
};
|
||
|
|
||
|
//! holds a associative list of named quaternions
|
||
|
struct SMD3QuaternionTagList
|
||
|
{
|
||
|
SMD3QuaternionTagList()
|
||
|
{
|
||
|
Container.setAllocStrategy(core::ALLOC_STRATEGY_SAFE);
|
||
|
}
|
||
|
|
||
|
// construct copy constructor
|
||
|
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;
|
||
|
};
|
||
|
|
||
|
|
||
|
//! Holding Frames Buffers and Tag Infos
|
||
|
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;
|
||
|
};
|
||
|
|
||
|
|
||
|
//! Interface for using some special functions of MD3 meshes
|
||
|
class IAnimatedMeshMD3 : public IAnimatedMesh
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
//! tune how many frames you want to render in between.
|
||
|
virtual void setInterpolationShift(u32 shift, u32 loopMode) =0;
|
||
|
|
||
|
//! get the tag list of the mesh.
|
||
|
virtual SMD3QuaternionTagList* getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) =0;
|
||
|
|
||
|
//! get the original md3 mesh.
|
||
|
virtual SMD3Mesh* getOriginalMesh() =0;
|
||
|
};
|
||
|
|
||
|
} // end namespace scene
|
||
|
} // end namespace irr
|
||
|
|
||
|
#endif
|
||
|
|