00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef LILITH_MD2_INCLUDED
00024 #define LILITH_MD2_INCLUDED
00025
00026 #include "animated.h"
00027 #include "../grinliz/glvector.h"
00028
00029 namespace lilith3d
00030 {
00031
00032 enum {
00033 MD2_STAND,
00034 MD2_RUN,
00035 MD2_ATTACK,
00036 MD2_PAIN0,
00037 MD2_PAIN1,
00038 MD2_PAIN2,
00039 MD2_JUMP,
00040 MD2_FLIP,
00041 MD2_SALUTE,
00042 MD2_TAUNT,
00043 MD2_WAVE,
00044 MD2_POINT,
00045 MD2_CRSTAND,
00046 MD2_CRWALK,
00047 MD2_CRATTACK,
00048 MD2_CRPAIN,
00049 MD2_CRDEATH,
00050 MD2_DEATH0,
00051 MD2_DEATH1,
00052 MD2_DEATH2,
00053 MD2_COUNT,
00054
00055 MD2_PAIN = MD2_PAIN0,
00056 MD2_DEATH = MD2_DEATH0,
00057 };
00058
00059 struct LMD2Vertex
00060 {
00061 grinliz::Vector3F pos;
00062 grinliz::Vector3F normal;
00063 };
00064
00065
00066 struct LMD2RenderIn
00067 {
00068 U32 actionID;
00069 U32 time;
00070 };
00071
00072 struct LMD2RenderOut
00073 {
00074
00075 U32 nVertex[2];
00076 const Texture* texture[2];
00077
00078
00079 LMD2Vertex* vertex[2];
00080 };
00081
00086 class MD2Resource : public AnimatedResource
00087 {
00088 public:
00089 MD2Resource( const std::string& name );
00090 virtual ~MD2Resource();
00091 virtual const MD2Resource* ToMD2() const { return this; }
00092
00093 enum {
00094 SPRITE,
00095 WEAPON
00096 };
00097
00102 bool Load( const std::string& filename, int type );
00103
00105 void SetTexture( const Texture* tex, int type ) {
00106 if ( type == SPRITE )
00107 sprite.texture = tex;
00108 else if ( type == WEAPON )
00109 weapon.texture = tex;
00110 }
00111
00112 U32 AnimationLength( int action ) const;
00113
00115 void SetMelee( bool _melee ) { this->melee = _melee; }
00117 bool Melee() const { return melee; }
00119 bool Ranged() const { return !melee; }
00120
00121
00122 int IntersectRay( const LMD2RenderOut& out, const grinliz::Matrix4& m,
00123 const grinliz::Vector3F& point, const grinliz::Vector3F& dir, grinliz::Vector3F* intersection ) const;
00124
00125 const grinliz::Vector3F& WeaponOrigin() const { return weaponOrigin; }
00126 const grinliz::Matrix4& ResXForm() const { return resXForm; }
00127 void GenerateVertex( const LMD2RenderIn& in, LMD2RenderOut* out ) const;
00128 void StreamOutMD2( int i, const LMD2RenderOut& out ) const;
00129 void StreamOutShadowMD2( ShadowVolumeCache* cache, const LMD2RenderOut& out, const grinliz::Matrix4& mat ) const;
00130 bool IsLooping( int action ) const;
00131
00132 private:
00133
00134
00135
00136 static grinliz::Vector3F normals[256];
00137 static bool normalsFlipped;
00138
00139 struct MD2Header
00140 {
00141 U32 magic;
00142 U32 version;
00143
00144 U32 textureWidth;
00145 U32 textureHeight;
00146
00147 U32 frameSize;
00148
00149 U32 numSkins;
00150 U32 numVertices;
00151 U32 numST;
00152 U32 numTri;
00153 U32 numGlCmds;
00154 U32 numFrames;
00155
00156 U32 offsetSkins;
00157 U32 offsetST;
00158 U32 offsetTris;
00159 U32 offsetFrames;
00160 U32 offsetGlCmds;
00161 U32 offsetEnd;
00162 };
00163
00164 struct MD2Tri
00165 {
00166 U16 vertexIndex[3];
00167 U16 textureIndex[3];
00168 };
00169
00170
00171
00172
00173 struct MD2TexST
00174 {
00175 S16 s;
00176 S16 t;
00177 };
00178
00179
00180
00181 struct MD2Vertex
00182 {
00183 U8 x, y, z;
00184 U8 normal;
00185 };
00186
00187 struct MD2Frame
00188 {
00189 grinliz::Vector3F scale;
00190 grinliz::Vector3F translate;
00191 char name[16];
00192 MD2Vertex md2Vertex[2048];
00193 };
00194
00195 struct Action
00196 {
00197 U32 numFrames;
00198 U32 startFrame;
00199 U32 msecPerFrame;
00200 };
00201
00202 struct LObject
00203 {
00204 const MD2Header* header;
00205 const Texture* texture;
00206
00207 enum { MAX_INDEX = 4096*3 };
00208 mutable U16 index[MAX_INDEX];
00209 mutable bool hasIndex;
00210 grinliz::Vector2F st[2048];
00211
00212 #ifdef DEBUG
00213 void* memStart;
00214 void* memEnd;
00215 #endif
00216
00217 const MD2Frame* GetFrame( int i ) const {
00218 const size_t FRAME_SIZE = sizeof(float)*6 + sizeof(char)*16 + 4*header->numVertices;
00219
00220 const MD2Frame* frame = (const MD2Frame*)((U8*)header + header->offsetFrames + FRAME_SIZE*i );
00221 GLASSERT( frame > memStart );
00222 GLASSERT( frame < memEnd );
00223 return frame;
00224 }
00225 const MD2TexST* GetTexST() const {
00226 const MD2TexST* texst = (const MD2TexST*)((U8*)header + header->offsetST );
00227 GLASSERT( texst > memStart );
00228 GLASSERT( texst < memEnd );
00229 return texst;
00230 }
00231 const MD2Tri* GetTri() const {
00232 const MD2Tri* tri = (const MD2Tri*)((U8*)header + header->offsetTris );
00233 GLASSERT( tri > memStart );
00234 GLASSERT( tri < memEnd );
00235 return tri;
00236 }
00237 };
00238
00239 void GenerateObjectVertex( const LObject* obj,
00240 int frameId,
00241 float frame,
00242 LMD2Vertex* vertex,
00243 U32 *nVertex ) const;
00244
00245 bool LoadInner( FILE* fp, LObject* obj, int type );
00246
00247 inline static void Transform( const MD2Vertex& md2Vertex,
00248 const MD2Frame* frame,
00249 grinliz::Vector3F* out )
00250 {
00251 out->x = (frame->scale.x * (float)md2Vertex.x + frame->translate.x);
00252 out->y = -(frame->scale.y * (float)md2Vertex.y + frame->translate.y);
00253 out->z = (frame->scale.z * (float)md2Vertex.z + frame->translate.z);
00254 }
00255
00256 LObject sprite,
00257 weapon;
00258
00259 float allScale;
00260
00261 float deltaZ;
00262
00263
00264 Action actions[ MD2_COUNT ];
00265 grinliz::Vector3F weaponOrigin;
00266 bool melee;
00267 grinliz::Matrix4 resXForm;
00268 };
00269
00270
00273 class MD2Mesh : public AnimatedMesh
00274 {
00275 public:
00276 MD2Mesh( const MD2Resource* meshResource );
00277 virtual ~MD2Mesh();
00278
00280 void SetAction( int action );
00282 int GetAction();
00283
00289 bool ActionOkay( int newAction );
00290
00291 void StreamOutMesh( ELightPass light, EPass pass );
00292
00293 #ifdef SHADOW_VOLUME
00294 virtual void StreamOutShadow( ShadowVolumeCache* cache );
00295 #endif
00296
00297
00298
00299
00301 void CalcWeaponOrigin( grinliz::Vector3F* origin ) const;
00302
00304 const MD2Resource* GetMD2Resource() const { return md2Resource; }
00305
00306 virtual void IntersectRay( int flags,
00307 const grinliz::Vector3F& point,
00308 const grinliz::Vector3F& dir,
00309 LilithObjectList* vec );
00310
00311 protected:
00312 void VertexCacheCurrent();
00313
00314 const MD2Resource* md2Resource;
00315 int action;
00316 U32 actionStart;
00317 U32 lastAttack;
00318
00319 LMD2RenderIn renderIn;
00320 LMD2RenderOut renderOut;
00321 bool texGen;
00322
00323 LMD2Vertex vertex0[2048];
00324 LMD2Vertex vertex1[2048];
00325 };
00326
00327
00328 };
00329 #endif