📄 md2.cpp
字号:
#include "md2.h"
// CalculateNormal()
// desc: given 3 points, calculates the normal to the points
void CalculateNormal( float *p1, float *p2, float *p3 )
{
float a[3], b[3], result[3];
float length;
a[0] = p1[0] - p2[0];
a[1] = p1[1] - p2[1];
a[2] = p1[2] - p2[2];
b[0] = p1[0] - p3[0];
b[1] = p1[1] - p3[1];
b[2] = p1[2] - p3[2];
result[0] = a[1] * b[2] - b[1] * a[2];
result[1] = b[0] * a[2] - a[0] * b[2];
result[2] = a[0] * b[1] - b[0] * a[1];
// calculate the length of the normal
length = (float)sqrt(result[0]*result[0] + result[1]*result[1] + result[2]*result[2]);
// normalize and specify the normal
glNormal3f(result[0]/length, result[1]/length, result[2]/length);
}
// vector subtraction
vector_t operator-(vector_t a, vector_t b)
{
vector_t c;
c.point[0] = a.point[0] - b.point[0];
c.point[1] = a.point[1] - b.point[1];
c.point[2] = a.point[2] - b.point[2];
return c;
}
// scalar-vector multiplication
vector_t operator*(float f, vector_t b)
{
vector_t c;
c.point[0] = f * b.point[0];
c.point[1] = f * b.point[1];
c.point[2] = f * b.point[2];
return c;
}
// vector division
vector_t operator/(vector_t a, vector_t b)
{
vector_t c;
c.point[0] = a.point[0] / b.point[0];
c.point[1] = a.point[1] / b.point[1];
c.point[2] = a.point[2] / b.point[2];
return c;
}
// vector addition
vector_t operator+(vector_t a, vector_t b)
{
vector_t c;
c.point[0] = a.point[0] + b.point[0];
c.point[1] = a.point[1] + b.point[1];
c.point[2] = a.point[2] + b.point[2];
return c;
}
// CMD2Model constructor
CMD2Model::CMD2Model()
{
numVertices = 0; // vertices
numTriangles = 0; // triangles
numFrames = 0; // frames
numST = 0; // texture coordinates
frameSize = 0; // needed?
currentFrame = 0; // current keyframe
nextFrame = 1; // next keyframe
interpol = 0.0; // interpolation percent
triIndex = NULL; // triangle indices
st = NULL; // texture coordinate indices
vertexList = NULL; // vertices
modelTex = new CTexture; // skin/texture
modelState = MODEL_IDLE;
}
// CMD2Model destructor
CMD2Model::~CMD2Model()
{
Unload();
}
// CMD2Model::SetupSkin()
// access: private
// desc: sets up the model skin/texture for OpenGL
void CMD2Model::SetupSkin(CTexture *thisTexture)
{
// set the proper parameters for an MD2 texture
glGenTextures(1, &thisTexture->texID);
glBindTexture(GL_TEXTURE_2D, thisTexture->texID);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_NEAREST);
switch (thisTexture->textureType)
{
case BMP:
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, thisTexture->width, thisTexture->height,
GL_RGB, GL_UNSIGNED_BYTE, thisTexture->data);
break;
case PCX:
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, thisTexture->width, thisTexture->height,
GL_RGBA, GL_UNSIGNED_BYTE, thisTexture->data);
break;
case TGA:
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, thisTexture->width, thisTexture->height,
GL_RGB, GL_UNSIGNED_BYTE, thisTexture->data);
break;
default:
break;
}
}
// CMD2Model::Load()
// access: public
// desc: loads model and skin
int CMD2Model::Load(char *modelFile, char *skinFile)
{
FILE *filePtr; // file pointer
int fileLen; // length of model file
char *buffer; // file buffer
modelHeader_t *modelHeader; // model header
stIndex_t *stPtr; // texture data
frame_t *frame; // frame data
vector_t *vertexListPtr; // index variable
mesh_t *bufIndexPtr; // index variables
int i, j; // index variables
// open the model file
filePtr = fopen(modelFile, "rb");
if (filePtr == NULL)
return FALSE;
// find length of file
fseek(filePtr, 0, SEEK_END);
fileLen = ftell(filePtr);
fseek(filePtr, 0, SEEK_SET);
// read entire file into buffer
buffer = new char [fileLen+1];
fread(buffer, sizeof(char), fileLen, filePtr);
// extract model file header from buffer
modelHeader = (modelHeader_t*)buffer;
vertexList = new vector_t [modelHeader->numXYZ * modelHeader->numFrames];
numVertices = modelHeader->numXYZ;
numFrames = modelHeader->numFrames;
frameSize = modelHeader->framesize;
for (j = 0; j < numFrames; j++)
{
frame = (frame_t*)&buffer[modelHeader->offsetFrames + frameSize * j];
vertexListPtr = (vector_t*)&vertexList[numVertices * j];
for (i = 0; i < numVertices; i++)
{
vertexListPtr[i].point[0] = frame->scale[0] * frame->fp[i].v[0] + frame->translate[0];
vertexListPtr[i].point[1] = frame->scale[1] * frame->fp[i].v[1] + frame->translate[1];
vertexListPtr[i].point[2] = frame->scale[2] * frame->fp[i].v[2] + frame->translate[2];
}
}
modelTex->LoadTexture(skinFile);// = LoadTexture(skinFile);
if (modelTex != NULL)
SetupSkin(modelTex);
else
return FALSE;
numST = modelHeader->numST;
st = new texCoord_t [numST];
stPtr = (stIndex_t*)&buffer[modelHeader->offsetST];
for (i = 0; i < numST; i++)
{
st[i].s = (float)stPtr[i].s / (float)modelTex->width;
st[i].t = (float)stPtr[i].t / (float)modelTex->height;
}
numTriangles = modelHeader->numTris;
triIndex = new mesh_t [numTriangles];
// point to triangle indexes in buffer
bufIndexPtr = (mesh_t*)&buffer[modelHeader->offsetTris];
// create a mesh (triangle) list
for (j = 0; j < numFrames; j++)
{
// for all triangles in each frame
for(i = 0; i < numTriangles; i++)
{
triIndex[i].meshIndex[0] = bufIndexPtr[i].meshIndex[0];
triIndex[i].meshIndex[1] = bufIndexPtr[i].meshIndex[1];
triIndex[i].meshIndex[2] = bufIndexPtr[i].meshIndex[2];
triIndex[i].stIndex[0] = bufIndexPtr[i].stIndex[0];
triIndex[i].stIndex[1] = bufIndexPtr[i].stIndex[1];
triIndex[i].stIndex[2] = bufIndexPtr[i].stIndex[2];
}
}
// close file and free memory
fclose(filePtr);
delete buffer;
currentFrame = 0;
nextFrame = 1;
interpol = 0.0;
return TRUE;
}
// CMD2Model::LoadModel()
// access: public
// desc: loads model from file
int CMD2Model::LoadModel(char *modelFile)
{
FILE *filePtr; // file pointer
int fileLen; // length of model file
char *buffer; // file buffer
modelHeader_t *modelHeader; // model header
stIndex_t *stPtr; // texture data
frame_t *frame; // frame data
vector_t *vertexListPtr; // index variable
mesh_t *triIndex, *bufIndexPtr; // index variables
int i, j; // index variables
// open the model file
filePtr = fopen(modelFile, "rb");
if (filePtr == NULL)
return FALSE;
// find length of file
fseek(filePtr, 0, SEEK_END);
fileLen = ftell(filePtr);
fseek(filePtr, 0, SEEK_SET);
// read entire file into buffer
buffer = new char [fileLen+1];
fread(buffer, sizeof(char), fileLen, filePtr);
// extract model file header from buffer
modelHeader = (modelHeader_t*)buffer;
// allocate vertex list
vertexList = new vector_t [modelHeader->numXYZ * modelHeader->numFrames];
numVertices = modelHeader->numXYZ;
numFrames = modelHeader->numFrames;
frameSize = modelHeader->framesize;
for (j = 0; j < numFrames; j++)
{
frame = (frame_t*)&buffer[modelHeader->offsetFrames + frameSize * j];
vertexListPtr = (vector_t*)&vertexList[numVertices * j];
for (i = 0; i < numVertices; i++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -