?? md3.cpp
字號:
// -----------------------------------------------------
// File: md3.cpp
// Description: methods to load and render a *.md3 file
//
// Author: Wolfgang Engel (wolf@direct3d.net)
// Internet: www.direct3d.net
// Last modified: 20. December 2000
//
// Copyright (c) 1999-2001 Wolfgang Engel wolf@direct3d.net
// -----------------------------------------------------
#include "md3.h"
// custom vertex structure
// Quake 3 uses hardware transformation, but not hardware lighting
struct MD3VERTEXBUFFERSTRUCT
{
D3DXVECTOR3 p;
FLOAT tu, tv;
};
// Our custom FVF, which describes our custom vertex structure
#define FVF_MD3VERTEXBUFFERSTRUCT (D3DFVF_XYZ|D3DFVF_TEX1)
//-----------------------------------------------------------------------------
// Name: CMD3Model()
// Desc: The konstructor
//-----------------------------------------------------------------------------
CMD3Model::CMD3Model()
{
m_pVB = NULL; // vertex buffer
iNumMeshes = 0;
}
//-----------------------------------------------------------------------------
// Name: CMD3Model()
// Desc: The konstructor
//-----------------------------------------------------------------------------
CMD3Model::~CMD3Model()
{
DeleteModel();
}
//-----------------------------------------------------------------------------
// Name: CreateModel()
// Desc: Loads the *.md3 file
//-----------------------------------------------------------------------------
BOOL CMD3Model::CreateModel( char *fname, LPDIRECT3DDEVICE8 lpD3Ddevice)
{
MD3HEADER md3Header;
MD3MESHFILE md3MeshFile;
FILE *md3File;
DWORD m_dwNumberofVertices = 0; // to fprintf the number of vertices
DWORD m_dwNumberofTriangles = 0; // to fprintf the number of triangles
// if there are old vertex buffers and textures: delete them
DeleteVB();
DeleteTextures();
DeleteModel(); // delete old model data
// open file
md3File = fopen( fname, "rb" );
if( !md3File )
return FALSE;
// create and open log file
LogFile = fopen("md3 geometry data.txt","w");
// read MD3HEADER
fread( &md3Header, sizeof( MD3HEADER ) ,1, md3File );
fprintf(LogFile,"--- MD3 Header --- \n");
fprintf(LogFile,"id: %s\niVersion: %d\n", md3Header.id, md3Header.iVersion);
fprintf(LogFile,"Name of file: %s\n", md3Header.cFileName);
fprintf(LogFile,"Number of bone frames: %d\n", md3Header.iBoneFrameNum);
fprintf(LogFile,"Number of tags: %d\n", md3Header.iTagNum);
fprintf(LogFile,"Number of meshes: %d\n", md3Header.iMeshNum);
fprintf(LogFile,"Max. number of textures: %d\n", md3Header.iMaxTextureNum);
fprintf(LogFile,"Header size: %d\n", md3Header.iHeaderSize);
fprintf(LogFile,"Starting position of tag data: %d\n", md3Header.iTagStart);
fprintf(LogFile,"End tag data: starting position of mesh data: %d\n", md3Header.iMeshStart);
fprintf(LogFile,"Size of file: %d\n\n", md3Header.iFileSize);
if (//(strcmp(md3Header.id,"IDP3")==0)&&
(md3Header.iHeaderSize == 108)&&
(md3Header.iFileSize > md3Header.iTagStart)&&
(md3Header.iFileSize > md3Header.iMeshStart)&&
(md3Header.iVersion == 15))
{
//---------------------------------------------------------------------------
// Reads in the following order
// 1. read bone frames
// 2. read tags
// 3. read meshes
//---------------------------------------------------------------------------
// read MD3BONEFRAME
md3BoneFrame = new MD3BONEFRAME[md3Header.iBoneFrameNum];
for(int i = 0; i < md3Header.iBoneFrameNum; i++)
{
fread( &md3BoneFrame[i], sizeof( MD3BONEFRAME ), 1, md3File );
}
delete[] md3BoneFrame; // we won't use it here
fprintf(LogFile,"--- Tags --- \n");
// if there are tags: get them
md3Tags = (MD3TAG**)new MD3TAG[md3Header.iBoneFrameNum];
if (md3Header.iTagNum != 0)
{
for (i=0;i < md3Header.iBoneFrameNum;i++)
{
md3Tags[i] = (MD3TAG*)new MD3TAG[md3Header.iTagNum];
// fprintf(LogFile,"\nBone Frame Num: %d\n", i);
for (int j=0;j < md3Header.iTagNum; j++)
{
fread( &md3Tags[i][j], sizeof( MD3TAG ), 1, md3File );
// fprintf(LogFile,"Tag name: %s\n", md3Tags[i][j].cTagName);
}
}
delete[] md3Tags; // we won't use it here
}
// read MD3MESHes
iNumMeshes = md3Header.iMeshNum;
pMd3Meshes = new MD3MESH[iNumMeshes];
fprintf(LogFile,"\n--- MD3 Meshes ---\n");
for(int j = 0; j < iNumMeshes; j++)
{
// Read MD3MESHFILE
fread( &md3MeshFile, sizeof( MD3MESHFILE ), 1, md3File );
// Log MD3MESHFILE
fprintf(LogFile,"id: %s\n", md3MeshFile.cId);
fprintf(LogFile,"Name of mesh: %s\n", &md3MeshFile.cName);
fprintf(LogFile,"Number of mesh frames: %d\n", md3MeshFile.iMeshFrameNum);
fprintf(LogFile,"Number of textures: %d\n", md3MeshFile.iTextureNum);
fprintf(LogFile,"Number of vertices: %d\n", md3MeshFile.iVertexNum);
fprintf(LogFile,"Number of triangles: %d\n", md3MeshFile.iTriangleNum);
fprintf(LogFile,"Starting position of triangle data: %d\n", md3MeshFile.iTriangleStart);
fprintf(LogFile,"Header size: %d\n", md3MeshFile.iHeaderSize);
fprintf(LogFile,"Starting position of texture coordiantes data: %d\n", md3MeshFile.iTecVecStart);
fprintf(LogFile,"Starting position of vertex data: %d\n", md3MeshFile.iVertexStart);
fprintf(LogFile,"Size of MD3MESHFILE: %d\n", &md3MeshFile.iMeshSize);
strcpy (pMd3Meshes[j].cName, md3MeshFile.cName);
//-------------------------------------------------------------------------
// Loading the mesh data in the following order:
// 1. texnames
// 2. triangles
// 3. texcoords
// 4. vertices
//-------------------------------------------------------------------------
pMd3Meshes[j].iNumTextures = md3MeshFile.iTextureNum;
pMd3Meshes[j].pTexNames = new TEXNAMES[pMd3Meshes[j].iNumTextures];
// always one mesh >= one texture
for(i = 0; i < pMd3Meshes[j].iNumTextures; i++)
{
/* a few graphic tools write the wrong texture path
in the *.md3 file. Instead of
models\players\conni
they write
odels\players\conni
with a space at the beginning. fread() ends reading
when a space shows up. The hack is reading in the
whole stuff with fgetc() ... a little bit slower.
This one takes me hours :-( .
*/
char cTemp[68];
for (int w = 0; w < 68; w++)
{
cTemp[w] = fgetc(md3File);
}
cTemp[0] = 'M'; // hack !!!!!!!
strcpy (pMd3Meshes[j].pTexNames[i], cTemp);
}
// triangles
pMd3Meshes[j].pTriangles= new TRIANGLEVERT[md3MeshFile.iTriangleNum];
DWORD x, y, z;
for(i = 0; i < md3MeshFile.iTriangleNum; i++)
{
// Another hack:
// some tools do not produce the right triangle data here.
// This is normally the case at the end of the
// triangle data stream.
// I try to filter out the grab by using a high and low
// limit, which I have choosed by try and error.
// BTW.: Loading the corrupted md3 file into milkshape and
// saving it unchanged helps a lot :-)
if (((x = ReadLong(md3File))< 0) || (x > 20000))
x = 0;
if (((y = ReadLong(md3File))< 0) || (y > 20000))
y = 0;
if (((z = ReadLong(md3File))< 0) || (z > 20000))
z = 0;
pMd3Meshes[j].pTriangles[i][0]= x;
pMd3Meshes[j].pTriangles[i][1]= y;
pMd3Meshes[j].pTriangles[i][2]= z;
}
// texture coordinates
pMd3Meshes[j].pfTextureCoords = new TEXCOORDS [md3MeshFile.iVertexNum];
for(i = 0; i < md3MeshFile.iVertexNum; i++)
{
pMd3Meshes[j].pfTextureCoords[i].u = ReadFloat(md3File);
pMd3Meshes[j].pfTextureCoords[i].v = ReadFloat(md3File);
}
// vertices ...
pMd3Meshes[j].vMeshFrames= new VMESHFRAME[md3MeshFile.iMeshFrameNum];
for(i = 0; i < md3MeshFile.iMeshFrameNum; i++)
{
pMd3Meshes[j].vMeshFrames[i] = new D3DXVECTOR3[md3MeshFile.iVertexNum];
for(int w = 0; w < md3MeshFile.iVertexNum; w++)
{
/* To handle a file from a right handed coordinates
system, you might exchange the y and z value.
*/
pMd3Meshes[j].vMeshFrames[i][w].x = ReadShort(md3File) / 64.0f;
pMd3Meshes[j].vMeshFrames[i][w].z = ReadShort(md3File) / 64.0f;
pMd3Meshes[j].vMeshFrames[i][w].y = ReadShort(md3File) / 64.0f;
ReadShort(md3File); // unknown
}
}
pMd3Meshes[j].iNumVertices = md3MeshFile.iVertexNum;
pMd3Meshes[j].iMeshFrameNum = md3MeshFile.iMeshFrameNum;
pMd3Meshes[j].iNumTriangles = md3MeshFile.iTriangleNum;
m_dwNumberofVertices += pMd3Meshes[j].iNumVertices;
m_dwNumberofTriangles += pMd3Meshes[j].iNumTriangles;
// md3 file read length
int End = ftell(md3File);
fprintf(LogFile,"End of Mesh in md3File at: %d\n\n", End);
} //for nummeshes
// close the *.md3 file
fclose(md3File);
}
else
return FALSE;
fprintf(LogFile,"\n--- Model statistic ---\n");
fprintf(LogFile,"Number of vertices: %d\n", m_dwNumberofVertices);
fprintf(LogFile,"Number of triangles: %d\n", m_dwNumberofTriangles);
// close the LogFile
fclose(LogFile);
// creates vertex buffer and textures
CreateVB(lpD3Ddevice);
CreateTextures(lpD3Ddevice);
return TRUE;
}
//-----------------------------------------------------------------------------
// Name: DeleteModel()
// Desc: de allocate memory
//-----------------------------------------------------------------------------
void CMD3Model::DeleteModel()
{
/*
if (md3BoneFrame)
delete[] md3BoneFrame;
if (md3Tags)
delete[] md3Tags;
*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -