/***************************************************************************/
/* */
/* File: md3.h */
/* Author: bkenwright@xbdev.net */
/* URL: www.xbdev.net */
/* Date: 25-03-2006 (easter) */
/* */
/***************************************************************************/
/*
Understanding the Quake3 MD3 File Format
*/
//---------------------------------------------------------------------------
#define SZ_MD3_FILE "media\\model\\sarge\\upper.md3"
#define SZ_MD3_ANIM_FILE "media\\model\\sarge\\animation.cfg"
#define SZ_MD3_SKIN_FILE "media\\model\\sarge\\upper_default.skin"
#define MAX_FILENAME_LENGTH 256
//---------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h> //sprintf(...)
#include <string.h>
#pragma comment(lib, "D3d8.lib") //directX 8
#pragma comment(lib, "D3dx8.lib")
#include <d3dx8.h>
//---------------------------------------------------------------------------
//Saving debug information to a log file
void abc(char *str)
{
/*
FILE *fp = fopen("output.txt", "a+");
fprintf(fp, "%s\n", str);
fclose(fp);
*/
}
//---------------------------------------------------------------------------
typedef unsigned int uint32;
typedef int int32;
typedef unsigned short int uint16;
typedef short int int16;
typedef float float32;
struct stMD3Header
{
char ID[4]; // ID of the file is always "IDP3"
int32 Version; // Version number, usually 15
char Filename[68]; // Filename, sometimes left blank
int32 numBoneFrames; // Number of BoneFrames
int32 numTags; // Number of 'tags' per BoneFrame
int32 numMeshes; // Number of Meshes/Skins in MaxSkin
int32 numMaxSkins; // Maximum number of unique skins
int32 ofsFrames; // Always equal to the length this header
int32 ofsTagStart; // Starting position of tag structures
int32 ofMeshSurfaces; // Ending position of tag structure
int32 ofEndOfFile; // Size of file
};
struct stBoneFrame
{
float32 mins[3];
float32 maxs[3];
float32 Position[3];
float32 Scale;
char Creator[16];
};
struct stAnim
{
int32 FirstFrame;
int32 numFrames;
int32 LoopingFrames;
int32 FPS;
};
struct stSkin
{
char Name[64];
int32 index;
};
struct stTag
{
char Name[64];
float32 Position[3];
float32 Rotation[3][3];
};
struct stTriangle
{
int32 Vertex[3];
};
struct stTexCoord
{
float32 Coord[2];
};
struct stVertex // = Record
{
int16 Vertex[3];
unsigned char Normal[2];
};
struct stMeshHeader
{
char ID[4];
char Name[64];
int32 flags;
int32 numMeshFrames;
int32 numSkins;
int32 numVertexes;
int32 numTriangles;
int32 ofsTriangles;
int32 ofsSkins;
int32 ofsTexVector;
int32 ofsVertex;
int32 ofsEndMeshSize;
};
struct stMesh
{
stMeshHeader MeshHeader;
stSkin* pSkins;
stTriangle* pTriangle;
stTexCoord* pTexCoord;
stVertex* pVertex;
};
struct stM3DModel
{
char m_md3FileName[MAX_FILENAME_LENGTH];
stMD3Header m_md3Header;
stBoneFrame* m_pBoneFrame;
stTag* m_pTags;
stMesh* m_pMeshes;
stAnim m_Anim[26];
int m_FPS;
int m_startFrame;
int m_endFrame;
int m_nextFrame;
int m_animLower;
int m_animUpper;
int m_currentframe;
};
//---------------------------------------------------------------------------
long filesize(FILE *stream)
{
long curpos, length;
curpos = ftell(stream);
fseek(stream, 0L, SEEK_END);
length = ftell(stream);
fseek(stream, curpos, SEEK_SET);
return length;
}
//---------------------------------------------------------------------------
enum
{
BOTH_DEATH1 = 0,
BOTH_DEAD1 = 1,
BOTH_DEATH2 = 2,
BOTH_DEAD2 = 3,
BOTH_DEATH3 = 4,
BOTH_DEAD3 = 5,
TORSO_GESTURE = 6,
TORSO_ATTACK = 7,
TORSO_ATTACK2 = 8,
TORSO_DROP = 9,
TORSO_RAISE = 10,
TORSO_STAND = 11,
TORSO_STAND2 = 12,
LEGS_WALKCR = 13,
LEGS_WALK = 14,
LEGS_RUN = 15,
LEGS_BACK = 16,
LEGS_SWIM = 17,
LEGS_JUMP = 18,
LEGS_LAND = 19,
LEGS_JUMPB = 20,
LEGS_LANDB = 21,
LEGS_IDLE = 22,
LEGS_IDLECR = 23,
LEGS_TURN = 24,
MAX_ANIMATIONS
};
//---------------------------------------------------------------------------
extern LPDIRECT3DDEVICE8 g_pD3DDevice;
inline void DbgTriangle(IDirect3DDevice8 * pDevice,
D3DXVECTOR3& a, D3DXVECTOR3& b, D3DXVECTOR3& c,
DWORD colour)
{
struct TLVERTEX
{
float x,y,z;
DWORD col;
enum{ FVF_TLVERTEX = D3DFVF_XYZ | D3DFVF_DIFFUSE};
};
pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
pDevice->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_DIFFUSE);
TLVERTEX Vertex[3] =
{
// x y z colour
{ a.x, a.y, a.z, colour },
{ b.x, b.y, b.z, colour },
{ c.x, c.y, c.z, colour }
};
#if(DIRECT3D_VERSION >= 0x0900)
pDevice->SetFVF( TLVERTEX::FVF_TLVERTEX );
#else
pDevice->SetVertexShader( TLVERTEX::FVF_TLVERTEX );
#endif // DIRECT3D_VERSION
pDevice->SetTexture( 0, NULL );
pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
pDevice->SetRenderState( D3DRS_FILLMODE,
D3DFILL_WIREFRAME );
HRESULT hr = pDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, 1, Vertex, sizeof( TLVERTEX ) );
//g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
}
//---------------------------------------------------------------------
class CMD3
{
public:
stM3DModel m_upper;
float poll;
CMD3()
{
//m_startFrame = 0;
//m_endFrame = 0;
//m_currentframe = 0;
poll = 0;
//m_lastUpdate = 0;
}
void Create(/* file names */)
{
LoadModel(&m_upper, SZ_MD3_FILE);
LoadAnim (&m_upper, SZ_MD3_ANIM_FILE);
LoadSkin (&m_upper, SZ_MD3_SKIN_FILE);
SetAnim (&m_upper, TORSO_STAND);
}
void Release()
{
ReleaseModel(&m_upper);
}
void Update(float time)
{
UpdateFrame(&m_upper, time);
}
void Render()
{
DrawSkeleton(&m_upper);
}
protected:
void UpdateFrame(stM3DModel* pMod, float time)
{
/*
poll = (time - m_lastUpdate);
if (poll > 1/m_FPS)
{
m_frame = m_nextFrame;
m_nextFrame++;
if (m_nextFrame > m_endFrame)
{
m_nextFrame = m_startFrame;
m_lastUpdate = time;
}
}
*/
poll += time;
if (poll>= 1.0f)
{
poll=0.0f;
pMod->m_currentframe = pMod->m_nextFrame;
pMod->m_nextFrame++;
if (pMod->m_nextFrame > pMod->m_endFrame)
{
pMod->m_nextFrame = pMod->m_startFrame;
}
}
}
void DrawSkeleton(stM3DModel* pMod)
{
DrawModel(pMod);
/*
for (int i=0; i<m_md3Header.numTags; i++)
{
float (*Rotation)[3];
Rotation = (m_pTags[m_currentframe * m_md3Header.numTags + i].Rotation); //3x3 mat
float* Position = m_pTags[m_currentframe * m_md3Header.numTags + i].Position; //vector3
char* tagName = m_pTags[m_currentframe * m_md3Header.numTags + i].Name;
D3DXMATRIX m;
m(0,0) = Rotation[0][0];
m(0,1) = Rotation[0][1];
m(0,2) = Rotation[0][2];
m(0,3) = 0;
m(1,0) = Rotation[1][0];
m(1,1) = Rotation[1][1];
m(1,2) = Rotation[1][2];
m(1,3) = 0;
m(2,0) = Rotation[2][0];
m(2,1) = Rotation[2][1];
m(2,2) = Rotation[2][2];
m(2,3) = 0;
m(3,0) = Position[0];
m(3,1) = Position[1];
m(3,2) = Position[2];
m(3,3) = 1;
//D3DXMATRIX tx;
//D3DXMatrixTranslation(&tx, 0, 0, 0);
g_pD3DDevice->SetTransform(D3DTS_WORLD, &m);
if ( strcmp(tagName, "tag_head")==0 )
{
DrawSkeleton()
}
}
*/
}
void DrawModel(stM3DModel* pMod)
{
DrawModelInt(pMod, pMod->m_currentframe, pMod->m_nextFrame, poll);
}
void DrawModelInt(stM3DModel* pMod, const int currentFrame, const int nexFrame, float pol)
{
stMD3Header* pHeader = &pMod->m_md3Header;
stMesh* pMeshes = pMod->m_pMeshes;
for (int k=0; k<pHeader->numMeshes; k++)
{
stMesh* currentMesh = &pMeshes[k];
//char* meshName = currentMesh->MeshHeader.Name;
int currentOffsetVertex = currentFrame * currentMesh->MeshHeader.numVertexes;
//interpolation
int nextCurrentOffsetVertex = nexFrame * currentMesh->MeshHeader.numVertexes;
int TriangleNum = currentMesh->MeshHeader.numTriangles;
// get/set texture
// TO-DO
for (int i=0; i<TriangleNum; i++)
{
D3DXVECTOR3 tri[3];
for (int j=0; j<3; j++)
{
int currentVertex = currentMesh->pTriangle[i].Vertex[j];
float vA[3];
vA[0] = currentMesh->pVertex[currentOffsetVertex + currentVertex].Vertex[0] / 64.0f;
vA[1] = currentMesh->pVertex[currentOffsetVertex + currentVertex].Vertex[1] / 64.0f;
vA[2] = currentMesh->pVertex[currentOffsetVertex + currentVertex].Vertex[2] / 64.0f;
float nextVA[3];
nextVA[0] = currentMesh->pVertex[nextCurrentOffsetVertex + currentVertex].Vertex[0] / 64.0f;
nextVA[1] = currentMesh->pVertex[nextCurrentOffsetVertex + currentVertex].Vertex[1] / 64.0f;
nextVA[2] = currentMesh->pVertex[nextCurrentOffsetVertex + currentVertex].Vertex[2] / 64.0f;
/*
float normU, normV;
normU = currentMesh->pVertex[currentOffsetVertex + currentVertex].Normal[0];
normV = currentMesh->pVertex[currentOffsetVertex + currentVertex].Normal[1];
*/
// Interplated value
float pA0 = vA[0] + pol * (nextVA[0] - vA[0]);
float pA1 = vA[1] + pol * (nextVA[1] - vA[1]);
float pA2 = vA[2] + pol * (nextVA[2] - vA[2]);
tri[j].x = pA0;
tri[j].y = pA1;
tri[j].z = pA2;
}
DbgTriangle(g_pD3DDevice, tri[0], tri[1], tri[2], 0xff00ffff );
}
}
}
bool SetAnim(stM3DModel* pMod, int ani)
{
if ( ani>=0 && ani<=5)
{
}
else if ( ani>=6 && ani<=12)
{
}
else if ( ani>=13 && ani<=24)
{
}
else
{
_asm
{
int 13;
}
}
pMod->m_FPS = pMod->m_Anim[ani].FPS;
pMod->m_startFrame = pMod->m_Anim[ani].FirstFrame;
pMod->m_nextFrame = pMod->m_Anim[ani].FirstFrame;
pMod->m_endFrame = pMod->m_Anim[ani].FirstFrame + pMod->m_Anim[ani].numFrames;
pMod->m_animLower = ani;
pMod->m_animUpper = ani;
pMod->m_currentframe = pMod->m_startFrame;
return true;
}
bool LoadSkin(stM3DModel* pMod, const char* filename)
{
char buf[256];
char MeshName[256] = {0};
char ImageName[256] = {0};
FILE* fp = fopen(filename, "r");
if (fp==NULL)
{
abc("unable to open file");
return false;
}
//char firstWord[256];
char * val = NULL;
int i = 0;
do
{
val = fgets(buf,256,fp);
if (val==NULL)
{
break;
}
//sscanf(buf, "%s", firstWord);
if (buf[ strlen(buf)-1 ] == '\n')
{
buf[ strlen(buf)-1 ] = NULL;
}
if (buf[ strlen(buf)-1 ] == ',')
{
strcpy(MeshName, buf);
MeshName[ strlen(MeshName)-1 ] = NULL;
}
if ( strncmp(buf, "tag_", 4)==0 ) // tags dont have skins
{
continue;
}
//char* pImageName = strstr(MeshName, ","); // get the full image and path name
//strcpy(ImageName, pImageName); // get name from last / (i.e only filename)
char* pName = strrchr(buf, '/');
strcpy(ImageName, pName+1);
// lose the starting /
} while (val);
return true;
}
bool LoadAnim(stM3DModel* pMod, const char* filename)
{
char buf[256];
FILE* fp = fopen(filename, "r");
if (fp==NULL)
{
abc("unable to open file");
return false;
}
char firstWord[256];
char * val = NULL;
int i = 0;
do
{
val = fgets(buf,256,fp);
if (val==NULL)
{
break;
}
sscanf(buf, "%s", firstWord);
if (strcmp("sex", firstWord)==NULL)
{
}
else if (strcmp("headoffset", firstWord)==NULL)
{
}
else if (strcmp("footsteps", firstWord)==NULL)
{
}
else if (strcmp("", firstWord)==NULL)
{
}
else if (strcmp("//", firstWord)==NULL)
{
}
else
{
char words[4][256];
sscanf(buf, "%s %s %s %s", &words[0], &words[1], &words[2], &words[3]);
// Extract the values of FirstFrame, numFrames, LoopingFrames, FPS from the String
int FirstFrame = atoi(words[0]);
int numFrames = atoi(words[1]);
int loopingFrames = atoi(words[2]);
int FPS = atoi(words[3]);
pMod->m_Anim[i].FirstFrame = FirstFrame;
pMod->m_Anim[i].numFrames = numFrames;
pMod->m_Anim[i].LoopingFrames = loopingFrames;
pMod->m_Anim[i].FPS = FPS;
i++;
}
} while (val);
int skip = pMod->m_Anim[LEGS_WALKCR].FirstFrame - pMod->m_Anim[TORSO_GESTURE].FirstFrame;
for (int i=LEGS_WALKCR; i<MAX_ANIMATIONS; i++)
{
pMod->m_Anim[i].FirstFrame = pMod->m_Anim[i].FirstFrame - skip;
}
for (int i=0; i<MAX_ANIMATIONS; i++)
{
if (pMod->m_Anim[i].numFrames > 0)
{
pMod->m_Anim[i].numFrames = pMod->m_Anim[i].numFrames - 1;
}
}
fclose(fp);
return true;
}
//-----------------------------------------------------------------------
//
// Loads model from a .md3 file
//
//-----------------------------------------------------------------------
bool LoadModel(stM3DModel* pMod, const char* filename)
{
char buf[256];
FILE* fp = fopen(filename, "rb");
if (fp==NULL)
{
abc("unable to open file");
return false;
}
// Lets get the size of this md3 file
int md3filesize = filesize(fp);
fseek(fp, 0L, SEEK_SET);
if (strlen(filename)>255)
{
sprintf(buf, "filename is longer than %d", MAX_FILENAME_LENGTH);
abc(buf);
return false;
}
// copy name
strcpy(pMod->m_md3FileName, filename);
sprintf(buf, "MD3 FileName: %s", pMod->m_md3FileName);
abc(buf);
sprintf(buf, "FileSize: %d", md3filesize);
abc(buf);
abc("\n~~MD3 Header~~\n");
stMD3Header* pHeader = &pMod->m_md3Header;
// read header
fread(pHeader, 1, sizeof(stMD3Header), fp);
/*
// log debug information to file
sprintf(buf, "ID %c%c%c%c", pHeader->ID[0], pHeader->ID[1], pHeader->ID[2], pHeader->ID[3]);
abc(buf);
sprintf(buf, "Version: %d", pHeader->Version);
abc(buf);
sprintf(buf, "FileName: %s", pHeader->Filename);
abc(buf);
sprintf(buf, "numBoneFrames: %d", pHeader->numBoneFrames);
abc(buf);
sprintf(buf, "numTags: %d", pHeader->numTags);
abc(buf);
sprintf(buf, "numMeshes: %d", pHeader->numMeshes);
abc(buf);
sprintf(buf, "numMaxSkins: %d", pHeader->numMaxSkins);
abc(buf);
sprintf(buf, "ofsFrames: %d", pHeader->ofsFrames);
abc(buf);
sprintf(buf, "ofsTagStart: %d", pHeader->ofsTagStart);
abc(buf);
sprintf(buf, "ofMeshSurfaces: %d", pHeader->ofMeshSurfaces);
abc(buf);
sprintf(buf, "ofEndOfFile (Filesize): %d", pHeader->ofEndOfFile);
abc(buf);
*/
if (strcmp("IDP3", pHeader->ID)==NULL)
{
sprintf(buf, "Incorrect File Format 'Incorrect ID' ie. ('IDP3')");
abc(buf);
}
// Allocate memory for all or bones/tags/etc
pMod->m_pBoneFrame = new stBoneFrame[pHeader->numBoneFrames];
pMod->m_pTags = new stTag[pHeader->numBoneFrames * pHeader->numTags];
pMod->m_pMeshes = new stMesh[pHeader->numMeshes];
stBoneFrame* pBoneFrame = pMod->m_pBoneFrame;
stTag* pTags = pMod->m_pTags;
stMesh* pMeshes = pMod->m_pMeshes;
// Lets seek to the start of the bone frames & read boneframe
fseek(fp, pHeader->ofsFrames, SEEK_SET);
fread(pBoneFrame, 1, pHeader->numBoneFrames*sizeof(stBoneFrame), fp);
/*
sprintf(buf, "\n~~~~BoneFrames: %d~~~~~~", pHeader->numBoneFrames);
abc(buf);
for (int i=0; i<pHeader->numBoneFrames; i++)
{
abc("#");
sprintf(buf, "mins[%.1f,%.1f,%.1f]", m_pBoneFrame[i].mins[0], m_pBoneFrame[i].mins[1], m_pBoneFrame[i].mins[2]);
abc(buf);
sprintf(buf, "maxs[%.1f,%.1f,%.1f]", m_pBoneFrame[i].maxs[0], m_pBoneFrame[i].maxs[1], m_pBoneFrame[i].maxs[2]);
abc(buf);
sprintf(buf, "Position[%.1f,%.1f,%.1f]", m_pBoneFrame[i].Position[0], m_pBoneFrame[i].Position[1], m_pBoneFrame[i].Position[2]);
abc(buf);
sprintf(buf, "Scale[%.1f]", m_pBoneFrame[i].Scale);
abc(buf);
sprintf(buf, "Creator[%s]", m_pBoneFrame[i].Creator);
abc(buf);
}
*/
// Seek to start of tags and read them all in
fseek(fp, pHeader->ofsTagStart, SEEK_SET);
fread(pTags, 1, pHeader->numBoneFrames * pHeader->numTags*sizeof(stTag), fp);
/*
sprintf(buf, "\n~~~~Tags: %d~~~~~~", pHeader->numTags);
abc(buf);
for (int i=0; i<m_md3Header.numTags; i++)
{
abc("#");
sprintf(buf, "Name[%s]", m_pTags[i].Name);
abc(buf);
sprintf(buf, "Position[%.1f,%.1f,%.1f]", m_pTags[i].Position[0], m_pTags[i].Position[1], m_pTags[i].Position[2]);
abc(buf);
sprintf(buf, "Rotation[%.1f,%.1f,%.1f][...][...]", m_pTags[i].Rotation[0][0], m_pTags[i].Rotation[0][1], m_pTags[i].Rotation[0][2]);
abc(buf);
}
*/
int meshOFS = pHeader->ofMeshSurfaces;
for (int j=0; j<pHeader->numMeshes; j++)
{
stMesh * pMesh = &pMeshes[j];
stMeshHeader * pMeshHeader = &(pMesh->MeshHeader);
fseek(fp, meshOFS, SEEK_SET);
// Seek to the start of the mesh data and read it all in
fread(pMeshHeader, 1, sizeof(stMeshHeader), fp);
// Read in all the sub parts of the mesh data
{
fseek(fp, meshOFS + pMeshHeader->ofsTriangles, SEEK_SET);
pMesh->pTriangle = new stTriangle [pMeshHeader->numTriangles];
fread( pMesh->pTriangle, 1, pMeshHeader->numTriangles * sizeof(stTriangle), fp);
fseek(fp, meshOFS + pMeshHeader->ofsSkins, SEEK_SET);
pMesh->pSkins = new stSkin [pMeshHeader->numSkins];
fread( pMesh->pSkins, 1, pMeshHeader->numSkins * sizeof(stSkin), fp);
fseek(fp, meshOFS + pMeshHeader->ofsTexVector, SEEK_SET);
pMesh->pTexCoord = new stTexCoord [pMeshHeader->numVertexes];
fread( pMesh->pTexCoord, 1, pMeshHeader->numVertexes * sizeof(stTexCoord), fp);
fseek(fp, meshOFS + pMeshHeader->ofsVertex, SEEK_SET);
pMesh->pVertex = new stVertex [pMeshHeader->numVertexes * pMeshHeader->numMeshFrames];
fread( pMesh->pVertex, 1, pMeshHeader->numMeshFrames * pMeshHeader->numVertexes * sizeof(stVertex), fp);
}
meshOFS += pMeshHeader->ofsEndMeshSize;
}//End for meshes
/*
sprintf(buf, "\n~~~~Mesh Surfaces: %d~~~~~~", m_md3Header.numMeshes);
abc(buf);
for (int j=0; j<m_md3Header.numMeshes; j++)
{
abc("#");
stMesh * pMesh = &m_pMeshes[j];
stMeshHeader * pMeshHeader = &(pMesh->MeshHeader);
sprintf(buf, "ID [%c%c%c%c]", pMeshHeader->ID[0], pMeshHeader->ID[1], pMeshHeader->ID[2], pMeshHeader->ID[3]);
abc(buf);
sprintf(buf, "Name [%s]", pMeshHeader->Name);
abc(buf);
sprintf(buf, "flags [0x%.2X]", pMeshHeader->flags);
abc(buf);
sprintf(buf, "numMeshFrames [%d]", pMeshHeader->numMeshFrames);
abc(buf);
sprintf(buf, "numSkins [%d]", pMeshHeader->numSkins);
abc(buf);
sprintf(buf, "numVertexes [%d]", pMeshHeader->numVertexes);
abc(buf);
sprintf(buf, "numVertexes [%d]", pMeshHeader->numVertexes);
abc(buf);
sprintf(buf, "ofsTriangles [%d]", pMeshHeader->ofsTriangles);
abc(buf);
sprintf(buf, "ofsSkins [%d]", pMeshHeader->ofsSkins);
abc(buf);
sprintf(buf, "ofsTexVector [%d]", pMeshHeader->ofsTexVector);
abc(buf);
sprintf(buf, "ofsVertex [%d]", pMeshHeader->ofsVertex);
abc(buf);
sprintf(buf, "ofsEndMeshSize [%d]", pMeshHeader->ofsEndMeshSize);
abc(buf);
// Mesh Triangles
for (int i=0; i<pMeshHeader->numTriangles; i++)
{
stTriangle * pTri = &(pMesh->pTriangle[i]);
sprintf(buf, "Triangle [%d,%d,%d]", pTri->Vertex[0], pTri->Vertex[1], pTri->Vertex[2]);
abc(buf);
}
// Mesh Skins
for (int i=0; i<pMeshHeader->numSkins; i++)
{
stSkin * pSkin = &(pMesh->pSkins[i]);
sprintf(buf, "Skin:Name [%s]", pSkin->Name);
abc(buf);
sprintf(buf, "Skin:Index [%d]", pSkin->index);
abc(buf);
}
for (int i=0; i<pMeshHeader->numVertexes; i++)
{
stTexCoord * pTex = &(pMesh->pTexCoord[i]);
sprintf(buf, "TexCoord:Index [%.1f,%.1f]", pTex->Coord[0], pTex->Coord[1]);
abc(buf);
}
for (int i=0; i<pMeshHeader->numVertexes; i++)
{
stVertex* pVert = &(pMesh->pVertex[i]);
sprintf(buf, "Vertice:Vertex [%d,%d,%d]", pVert->Vertex[0], pVert->Vertex[1], pVert->Vertex[2]);
abc(buf);
}
}
*/
fclose(fp);
/*
for (int j=0; j<m_md3Header.numMeshes; j++)
{
stMesh * pMesh = &m_pMeshes[j];
delete[] pMesh->pSkins;
delete[] pMesh->pTexCoord;
delete[] pMesh->pTriangle;
delete[] pMesh->pVertex;
pMesh->pSkins = NULL;
pMesh->pTexCoord = NULL;
pMesh->pTriangle = NULL;
pMesh->pVertex = NULL;
}
delete[] m_pBoneFrame;
delete[] m_pTags;
delete[] m_pMeshes;
m_pBoneFrame = NULL;
m_pTags = NULL;
m_pMeshes = NULL;
*/
return true;
}// End LoadModel(..)
bool ReleaseModel(stM3DModel* pMod)
{
stMD3Header * pHeader = &pMod->m_md3Header;
stMesh * pMeshes = pMod->m_pMeshes;
for (int j=0; j<pHeader->numMeshes; j++)
{
stMesh * pMesh = &pMeshes[j];
delete[] pMesh->pSkins;
delete[] pMesh->pTexCoord;
delete[] pMesh->pTriangle;
delete[] pMesh->pVertex;
pMesh->pSkins = NULL;
pMesh->pTexCoord = NULL;
pMesh->pTriangle = NULL;
pMesh->pVertex = NULL;
}
stBoneFrame* pBoneFrame = pMod->m_pBoneFrame;
stTag* pTags = pMod->m_pTags;
stMesh *pMshes = pMod->m_pMeshes;
delete[] pBoneFrame;
delete[] pTags;
delete[] pMshes;
pBoneFrame = NULL;
pTags = NULL;
pMshes = NULL;
return true;
}
};
|