#ifndef __C_ANIMATED_MESH_HALFLIFE_H_INCLUDED__
#define __C_ANIMATED_MESH_HALFLIFE_H_INCLUDED__
#include "IAnimatedMesh.h"
#include "ISceneManager.h"
#include "irrArray.h"
#include "irrString.h"
#include "IMeshLoader.h"
#include "SMesh.h"
#include "IReadFile.h"
namespace irr
{
namespace scene
{
#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
#define MAXSTUDIOTRIANGLES 20000
#define MAXSTUDIOVERTS 2048
#define MAXSTUDIOSEQUENCES 256
#define MAXSTUDIOSKINS 100
#define MAXSTUDIOSRCBONES 512
#define MAXSTUDIOBONES 128
#define MAXSTUDIOMODELS 32
#define MAXSTUDIOBODYPARTS 32
#define MAXSTUDIOGROUPS 4
#define MAXSTUDIOANIMATIONS 512
#define MAXSTUDIOMESHES 256
#define MAXSTUDIOEVENTS 1024
#define MAXSTUDIOPIVOTS 256
#define MAXSTUDIOCONTROLLERS 8
typedef f32 vec3_hl[3];
typedef f32 vec4_hl[4];
struct SHalflifeHeader
{
c8 id[4];
s32 version;
c8 name[64];
s32 length;
vec3_hl eyeposition;
vec3_hl min;
vec3_hl max;
vec3_hl bbmin;
vec3_hl bbmax;
s32 flags;
u32 numbones;
u32 boneindex;
u32 numbonecontrollers;
u32 bonecontrollerindex;
u32 numhitboxes;
u32 hitboxindex;
u32 numseq;
u32 seqindex;
u32 numseqgroups;
u32 seqgroupindex;
u32 numtextures;
u32 textureindex;
u32 texturedataindex;
u32 numskinref;
u32 numskinfamilies;
u32 skinindex;
u32 numbodyparts;
u32 bodypartindex;
u32 numattachments;
u32 attachmentindex;
s32 soundtable;
s32 soundindex;
s32 soundgroups;
s32 soundgroupindex;
s32 numtransitions;
s32 transitionindex;
};
typedef struct
{
s32 id;
s32 version;
c8 name[64];
s32 length;
} studioseqhdr_t;
struct SHalflifeBone
{
c8 name[32];
s32 parent;
s32 flags;
s32 bonecontroller[6];
f32 value[6];
f32 scale[6];
};
struct SHalflifeBoneController
{
s32 bone;
s32 type;
f32 start;
f32 end;
s32 rest;
s32 index;
};
struct SHalflifeBBox
{
s32 bone;
s32 group;
vec3_hl bbmin;
vec3_hl bbmax;
};
#ifndef ZONE_H
typedef void *cache_user_t;
#endif
struct SHalflifeSequenceGroup
{
c8 label[32];
c8 name[64];
cache_user_t cache;
s32 data;
};
struct SHalflifeSequence
{
c8 label[32];
f32 fps;
s32 flags;
s32 activity;
s32 actweight;
s32 numevents;
s32 eventindex;
s32 numframes;
u32 numpivots;
u32 pivotindex;
s32 motiontype;
s32 motionbone;
vec3_hl linearmovement;
s32 automoveposindex;
s32 automoveangleindex;
vec3_hl bbmin;
vec3_hl bbmax;
s32 numblends;
s32 animindex;
s32 blendtype[2];
f32 blendstart[2];
f32 blendend[2];
s32 blendparent;
s32 seqgroup;
s32 entrynode;
s32 exitnode;
s32 nodeflags;
s32 nextseq;
};
typedef struct
{
s32 frame;
s32 event;
s32 type;
c8 options[64];
} mstudioevent_t;
typedef struct
{
vec3_hl org;
s32 start;
s32 end;
} mstudiopivot_t;
struct SHalfelifeAttachment
{
c8 name[32];
s32 type;
s32 bone;
vec3_hl org;
vec3_hl vectors[3];
};
struct SHalflifeAnimOffset
{
u16 offset[6];
};
union SHalfelifeAnimationFrame
{
struct {
u8 valid;
u8 total;
} num;
s16 value;
};
struct SHalflifeBody
{
c8 name[64];
u32 nummodels;
u32 base;
u32 modelindex;
};
struct SHalflifeTexture
{
c8 name[64];
s32 flags;
s32 width;
s32 height;
s32 index;
};
struct SHalflifeModel
{
c8 name[64];
s32 type;
f32 boundingradius;
u32 nummesh;
u32 meshindex;
u32 numverts;
u32 vertinfoindex;
u32 vertindex;
u32 numnorms;
u32 norminfoindex;
u32 normindex;
u32 numgroups;
u32 groupindex;
};
typedef struct
{
u32 numtris;
u32 triindex;
u32 skinref;
u32 numnorms;
u32 normindex;
} SHalflifeMesh;
#define STUDIO_NF_FLATSHADE 0x0001
#define STUDIO_NF_CHROME 0x0002
#define STUDIO_NF_FULLBRIGHT 0x0004
#define STUDIO_X 0x0001
#define STUDIO_Y 0x0002
#define STUDIO_Z 0x0004
#define STUDIO_XR 0x0008
#define STUDIO_YR 0x0010
#define STUDIO_ZR 0x0020
#define STUDIO_LX 0x0040
#define STUDIO_LY 0x0080
#define STUDIO_LZ 0x0100
#define STUDIO_AX 0x0200
#define STUDIO_AY 0x0400
#define STUDIO_AZ 0x0800
#define STUDIO_AXR 0x1000
#define STUDIO_AYR 0x2000
#define STUDIO_AZR 0x4000
#define STUDIO_TYPES 0x7FFF
#define STUDIO_RLOOP 0x8000
#define STUDIO_LOOPING 0x0001
#define STUDIO_HAS_NORMALS 0x0001
#define STUDIO_HAS_VERTICES 0x0002
#define STUDIO_HAS_BBOX 0x0004
#define STUDIO_HAS_CHROME 0x0008
#define RAD_TO_STUDIO (32768.0/M_PI)
#define STUDIO_TO_RAD (M_PI/32768.0)
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
#undef PACK_STRUCT
struct STextureAtlas
{
STextureAtlas ()
{
release();
}
virtual ~STextureAtlas ()
{
release ();
}
void release ();
void addSource ( const c8 * name, video::IImage * image );
void create ( u32 pixelborder, video::E_TEXTURE_CLAMP texmode );
void getScale ( core::vector2df &scale );
void getTranslation ( const c8 * name, core::vector2di &pos );
struct TextureAtlasEntry
{
io::path name;
u32 width;
u32 height;
core::vector2di pos;
video::IImage * image;
bool operator < ( const TextureAtlasEntry & other )
{
return height > other.height;
}
};
core::array < TextureAtlasEntry > atlas;
video::IImage * Master;
};
class CAnimatedMeshHalfLife : public IAnimatedMesh
{
public:
CAnimatedMeshHalfLife( );
virtual ~CAnimatedMeshHalfLife();
virtual bool loadModelFile( io::IReadFile* file, ISceneManager * smgr );
virtual u32 getFrameCount() const;
virtual IMesh* getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop);
virtual const core::aabbox3d<f32>& getBoundingBox() const;
virtual E_ANIMATED_MESH_TYPE getMeshType() const;
virtual void renderModel ( u32 param, video::IVideoDriver * driver, const core::matrix4 &absoluteTransformation);
virtual u32 getMeshBufferCount() const;
virtual IMeshBuffer* getMeshBuffer(u32 nr) const;
virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const;
virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue);
virtual void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX);
virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX);
virtual void setBoundingBox(const core::aabbox3df& box);
virtual IAnimationList* getAnimList () { return &AnimList; }
virtual IBodyList *getBodyList() { return &BodyList; }
private:
IAnimationList AnimList;
u32 FrameCount;
IBodyList BodyList;
SMesh MeshIPol;
ISceneManager *SceneManager;
SHalflifeHeader *Header;
SHalflifeHeader *TextureHeader;
bool OwnTexModel;
SHalflifeHeader *AnimationHeader[32];
void initData ();
void freeModel ();
SHalflifeHeader * loadModel( io::IReadFile* file, const io::path &filename );
bool postLoadModel( const io::path &filename );
u32 SequenceIndex;
f32 CurrentFrame;
#define MOUTH_CONTROLLER 4
u8 BoneController[4 + 1 ];
u8 Blending[2];
f32 SetController( s32 controllerIndex, f32 value );
u32 SkinGroupSelection;
u32 SetSkin( u32 value );
void initModel ();
void dumpModelInfo ( u32 level);
void ExtractBbox( s32 sequence, core::aabbox3df &box );
void setUpBones ();
SHalflifeAnimOffset * getAnim( SHalflifeSequence *seq );
void slerpBones( vec4_hl q1[], vec3_hl pos1[], vec4_hl q2[], vec3_hl pos2[], f32 s );
void calcRotations ( vec3_hl *pos, vec4_hl *q, SHalflifeSequence *seq, SHalflifeAnimOffset *anim, f32 f );
vec4_hl BoneAdj;
void calcBoneAdj();
void calcBoneQuaternion( s32 frame, f32 s, SHalflifeBone *bone, SHalflifeAnimOffset *anim, f32 *q ) const;
void calcBonePosition( s32 frame, f32 s, SHalflifeBone *bone, SHalflifeAnimOffset *anim, f32 *pos ) const;
void buildVertices ();
io::path TextureBaseName;
#define HL_TEXTURE_ATLAS
#ifdef HL_TEXTURE_ATLAS
STextureAtlas TextureAtlas;
video::ITexture *TextureMaster;
#endif
};
class CHalflifeMDLMeshFileLoader : public IMeshLoader
{
public:
CHalflifeMDLMeshFileLoader( scene::ISceneManager* smgr );
virtual bool isALoadableFileExtension(const io::path& filename) const;
virtual IAnimatedMesh* createMesh(io::IReadFile* file);
private:
scene::ISceneManager* SceneManager;
};
}
}
#endif