📄 mesh.cpp
字号:
#include "Mesh.h"
#include "..\System\simplememory.h"
#include "..\System\resfile.h"
#include "Texture.h"
#include "..\System\bufReader.h"
CMesh::CMesh()
{
Release();
}
CMesh::~CMesh()
{
}
void CMesh::Release()
{
m_iCurFrame = -1;
m_vertexnum = 0;
m_texcoordnum = 0;
m_pvertexlist = NULL;
m_ptexcoordlist = NULL;
m_pSubMeshs = NULL;
m_pBones = NULL;
m_boneNum = 0;
m_frameCount = 0;
m_pVertexRenderBuf = NULL;
m_submeshCount = 0;
m_oneBoneVertex = NULL;
m_twoBoneVertex = NULL;
m_oneBVCount = 0;
m_twoBVCount = 0;
}
extern CResFile *pResFile;
extern CSimpleMemory *SMemory;
extern CGraphics3D *pG3D;
extern int OpenModelFrameCount;
extern char ResFileName[MAX_PATH];
bool CMesh::LoadMesh(CGraphics3D *pG3d, const char* filename)
{
if (m_submeshCount > 0)
return TRUE;
void *pFile;
DBGPRINTF("BEGIN LOAD MESH: %s", filename);
//CEngine *pEngine = pG3d->GetEngine();
CResFile *pRes = pResFile;
int rest_size = pRes->LoadFileToStack(filename,&pFile);
DBGPRINTF("LoadFileToStack: SUCCESS");
CBufReader pData;
if( pFile )
{
pData.CBufReader_init( pFile, rest_size);
}
else
return false;
//FILE FLAG's values
//0x80;// if have the texture
//0x20;// we have the normal
//0x10;// we have the animation
//0x01;// we USE the VERTEX animation
//0x02;// we have the Maximam TWO BONES for one vertex to do animation.
m_fileflag = pData.ReadChar();
m_vertexnum = pData.ReadUShort();// the num of the point
DBGPRINTF("vertex number: %d", m_vertexnum);
m_texcoordnum = pData.ReadUShort();//
DBGPRINTF("texture coord number: %d", m_texcoordnum);
m_submeshCount = pData.ReadUShort();//
DBGPRINTF("SubMeshCount coord number: %d", m_submeshCount);
DBGPRINTF("READ INFO: SUCCESS");
m_pvertexlist = (Vertex *)SMemory->HeapMalloc(m_vertexnum * sizeof(Vertex));
int i, j;
DBGPRINTF("SIZE OF VERTEX: %d", sizeof(Vertex));
if( (m_fileflag&0x20) == 0)
pData.ReadBlock(m_pvertexlist, m_vertexnum*6);
else
{
int temp[6];
for(i=0;i<m_vertexnum;i++)
{
pData.ReadBlock((void*)&m_pvertexlist[i], 6);
{
pData.ReadBlock(temp, 6);
//to save memory, we remove the normal from vertex struct, we could add it back as need
//m_pvertexlist[i].normal_x = pData.ReadShort();
//m_pvertexlist[i].normal_y = pData.ReadShort();
//m_pvertexlist[i].normal_z = pData.ReadShort();
}
}
}
DBGPRINTF("READ VERTEX: SUCCESS");
m_ptexcoordlist = (Texcoord *)SMemory->HeapMalloc(m_texcoordnum * sizeof(Texcoord));
pData.ReadBlock((void*)m_ptexcoordlist, m_texcoordnum * sizeof(Texcoord));
for (i=0; i<m_texcoordnum; i++)
{
m_ptexcoordlist[i].u >>= 2;
m_ptexcoordlist[i].v >>= 2;
}
DBGPRINTF("READ TEX COORD: SUCCESS");
char textureFileName[30], temp[MAX_PATH];
m_pSubMeshs = (Submesh *)SMemory->HeapMalloc(m_submeshCount * sizeof(Submesh));
for (i=0; i<m_submeshCount; i++)
{
pData.ReadString(textureFileName);
STRCPY(temp, ResFileName);
STRCAT(temp, textureFileName);
m_pSubMeshs[i].m_material.texid = pG3d->LoadTexture(temp);
m_pSubMeshs[i].m_facenum = pData.ReadUShort();
m_pSubMeshs[i].m_pfaceIndics = (Face *)SMemory->HeapMalloc(m_pSubMeshs[i].m_facenum * sizeof(Face));
for (j=0;j<m_pSubMeshs[i].m_facenum;j++) {
pData.ReadBlock((void*)(&m_pSubMeshs[i].m_pfaceIndics[j]), 2*6);
}
}
//read animation data
if ((m_fileflag&0x10) != 0)
{
m_frameCount = pData.ReadShort();
if (m_frameCount>0)
{
m_boneNum = pData.ReadShort();
m_pBones = (Bone *)SMemory->HeapMalloc(m_boneNum * sizeof(Bone));
if ((m_fileflag&0x02) != 0) //two bones
{
m_oneBVCount = pData.ReadShort();
m_twoBVCount = pData.ReadShort();
m_oneBoneVertex = (OneBoneVertex *)SMemory->HeapMalloc(m_oneBVCount * sizeof(OneBoneVertex));
m_twoBoneVertex = (TwoBoneVertex *)SMemory->HeapMalloc(m_twoBVCount * sizeof(TwoBoneVertex));
for (j=0; j<m_oneBVCount; j++)
{
m_oneBoneVertex[j].vertexIndex = pData.ReadShort();
m_oneBoneVertex[j].boneIndex = pData.ReadChar();
}
for (j=0; j<m_twoBVCount; j++)
{
m_twoBoneVertex[j].vertexIndex = pData.ReadShort();
m_twoBoneVertex[j].boneIndex1 = pData.ReadChar();
m_twoBoneVertex[j].boneWeight1 = pData.ReadUChar();
m_twoBoneVertex[j].boneIndex2 = pData.ReadChar();
m_twoBoneVertex[j].boneWeight2 = pData.ReadUChar();
}
}
for (j=0; j<m_boneNum; j++)
{
if ((m_fileflag&0x02) == 0) //ONE bone
{
m_pBones[j].vertexCount = pData.ReadShort();
m_pBones[j].vertexIndics = (short *)SMemory->HeapMalloc(m_pBones[j].vertexCount * sizeof(short));
pData.ReadBlock(m_pBones[j].vertexIndics, m_pBones[j].vertexCount*2); //short
}
//bone's transformations
m_pBones[j].transforms = (CMatrix44 *)SMemory->HeapMalloc(m_frameCount*sizeof(CMatrix44));
pData.ReadBlock(m_pBones[j].transforms, m_frameCount*24); //short
for (i=0; i<m_frameCount; i++)
{
for (int k=0; k<9; k++)
m_pBones[j].transforms[i].m[k] *= 16; //(1<<4)
}
}
OpenModelFrameCount = m_frameCount;
}
}
//read bonding box data
int count;
for (i=0; i<m_submeshCount; i++)
{
count = m_frameCount;
if ((m_fileflag&0x10) == 0)
{
count = 1;
}
m_pSubMeshs[i].m_bbox = (BBox *)SMemory->HeapMalloc(count*sizeof(BBox));
pData.ReadBlock(m_pSubMeshs[i].m_bbox, count*12);
}
DBGPRINTF("read all: SUCCESS");
pFile = NULL;
SMemory->StackFree(0);
if (m_frameCount>0)
{
m_pVertexRenderBuf = (Vertex *)SMemory->HeapMalloc(m_vertexnum * sizeof(Vertex));
MEMCPY(m_pVertexRenderBuf, m_pvertexlist, sizeof(Vertex)*m_vertexnum);
}
else
{
GenerateFaceNormal();
}
/*
if (m_frameCount>0) {
// allocate 2000 vertex container for animation vertics
m_pVertexRenderBuf = (Vertex *)SMemory->HeapMalloc(m_vertexnum * sizeof(Vertex));
// MEMCPY(m_pVertexRenderBuf, m_pvertexlist, sizeof(Vertex)*m_vertexnum);
for (k=0; k<m_submeshCount; k++)
m_pSubMeshs[k].m_bbox = (BBox *)SMemory->HeapMalloc(m_frameCount * sizeof(BBox));
for (i=0; i<m_frameCount; i++) {
SetCurrentFrame(i);
for (k=0; k<m_submeshCount; k++) {
m_pSubMeshs[k].m_bbox[i].vtmin = m_pVertexRenderBuf[m_pSubMeshs[k].m_pfaceIndics[0].ver1];
m_pSubMeshs[k].m_bbox[i].vtmax = m_pVertexRenderBuf[m_pSubMeshs[k].m_pfaceIndics[0].ver1];
for (j=0;j<m_pSubMeshs[k].m_facenum;j++) {
m_pSubMeshs[k].m_bbox[i].vtmin.VMin(m_pVertexRenderBuf[m_pSubMeshs[k].m_pfaceIndics[j].ver1]);
m_pSubMeshs[k].m_bbox[i].vtmin.VMin(m_pVertexRenderBuf[m_pSubMeshs[k].m_pfaceIndics[j].ver2]);
m_pSubMeshs[k].m_bbox[i].vtmin.VMin(m_pVertexRenderBuf[m_pSubMeshs[k].m_pfaceIndics[j].ver3]);
m_pSubMeshs[k].m_bbox[i].vtmax.VMax(m_pVertexRenderBuf[m_pSubMeshs[k].m_pfaceIndics[j].ver1]);
m_pSubMeshs[k].m_bbox[i].vtmax.VMax(m_pVertexRenderBuf[m_pSubMeshs[k].m_pfaceIndics[j].ver2]);
m_pSubMeshs[k].m_bbox[i].vtmax.VMax(m_pVertexRenderBuf[m_pSubMeshs[k].m_pfaceIndics[j].ver3]);
}
}
}
} else {
for (k=0; k<m_submeshCount; k++) {
m_pSubMeshs[k].m_bbox = (BBox *)SMemory->HeapMalloc(sizeof(BBox));
m_pSubMeshs[k].m_bbox->vtmin = m_pvertexlist[m_pSubMeshs[k].m_pfaceIndics[0].ver1];
m_pSubMeshs[k].m_bbox->vtmax = m_pvertexlist[m_pSubMeshs[k].m_pfaceIndics[0].ver1];
for (j=0;j<m_pSubMeshs[k].m_facenum;j++) {
m_pSubMeshs[k].m_bbox->vtmin.VMin(m_pvertexlist[m_pSubMeshs[k].m_pfaceIndics[j].ver1]);
m_pSubMeshs[k].m_bbox->vtmin.VMin(m_pvertexlist[m_pSubMeshs[k].m_pfaceIndics[j].ver2]);
m_pSubMeshs[k].m_bbox->vtmin.VMin(m_pvertexlist[m_pSubMeshs[k].m_pfaceIndics[j].ver3]);
m_pSubMeshs[k].m_bbox->vtmax.VMax(m_pvertexlist[m_pSubMeshs[k].m_pfaceIndics[j].ver1]);
m_pSubMeshs[k].m_bbox->vtmax.VMax(m_pvertexlist[m_pSubMeshs[k].m_pfaceIndics[j].ver2]);
m_pSubMeshs[k].m_bbox->vtmax.VMax(m_pvertexlist[m_pSubMeshs[k].m_pfaceIndics[j].ver3]);
}
}
GenerateFaceNormal();
}
*/
DBGPRINTF("end read mesh");
return true;
}
void CMesh::DrawMesh(CGraphics3D *pG3d)
{
pG3d->SetPreciseMat(m_fileflag&FLAG_UNITDIV16);
m_pG3d = pG3d;
for (int i=0; i<m_submeshCount; i++)
{
if( m_pSubMeshs[i].m_material.texid != -1 )
{
m_pG3d->SetTexture(m_pSubMeshs[i].m_material.texid);
DrawSubMesh(i);
}
}
}
void CMesh::DrawTexturedMesh(CGraphics3D *pG3d, int texid)
{
m_pG3d = pG3d;
for (int i=0; i<m_submeshCount; i++)
{
m_pG3d->SetTexture(texid);
DrawSubMesh(i);
}
}
void CMesh::DrawSubMesh(int submeshIndex)
{
// DBGPRINTF("%d", m_pSubMeshs[submeshIndex].m_facenum);
if (m_iCurFrame <= 0)
{
if (!m_pG3d->BBCheck(m_pSubMeshs[submeshIndex].m_bbox->vtmin, m_pSubMeshs[submeshIndex].m_bbox->vtmax))
return;
}
else
{
if (!m_pG3d->BBCheck(m_pSubMeshs[submeshIndex].m_bbox[m_iCurFrame].vtmin, m_pSubMeshs[submeshIndex].m_bbox[m_iCurFrame].vtmax))
return;
}
if (m_frameCount > 0)
m_pG3d->RenderIndexdPrimitives(m_pVertexRenderBuf, m_ptexcoordlist, m_pSubMeshs[submeshIndex].m_pfaceIndics, m_pSubMeshs[submeshIndex].m_facenum);
else
m_pG3d->RenderIndexdPrimitives(m_pvertexlist, m_ptexcoordlist, m_pSubMeshs[submeshIndex].m_pfaceIndics, m_pSubMeshs[submeshIndex].m_facenum);
}
void CMesh::SetCurrentFrame(int frameid)
{
if (m_frameCount == 0)
return;
// DBGPRINTF("SetFrame");
int id = frameid%m_frameCount;
if (m_iCurFrame == id)
return;
m_iCurFrame = id;
int i, j;
Vertex temp1, temp2;
unsigned int weight1, weight2;
if ((m_fileflag&0x02) != 0) //two bones
{
for (i=0; i<m_oneBVCount; i++)
{
m_pVertexRenderBuf[m_oneBoneVertex[i].vertexIndex] =
m_pBones[m_oneBoneVertex[i].boneIndex].transforms[id].Transform(m_pvertexlist[m_oneBoneVertex[i].vertexIndex]);
}
for (i=0; i<m_twoBVCount; i++)
{
temp1 = m_pBones[m_twoBoneVertex[i].boneIndex1].transforms[id].Transform(m_pvertexlist[m_twoBoneVertex[i].vertexIndex]);
temp2 = m_pBones[m_twoBoneVertex[i].boneIndex2].transforms[id].Transform(m_pvertexlist[m_twoBoneVertex[i].vertexIndex]);
weight1 = m_twoBoneVertex[i].boneWeight1;
weight2 = m_twoBoneVertex[i].boneWeight2;
m_pVertexRenderBuf[m_twoBoneVertex[i].vertexIndex].x = (weight1*temp1.x + weight2*temp2.x)>>7;
m_pVertexRenderBuf[m_twoBoneVertex[i].vertexIndex].y = (weight1*temp1.y + weight2*temp2.y)>>7;
m_pVertexRenderBuf[m_twoBoneVertex[i].vertexIndex].z = (weight1*temp1.z + weight2*temp2.z)>>7;
}
}
else // one bone
{
for (i=0; i<m_boneNum; i++)
{
for (j=0; j<m_pBones[i].vertexCount; j++)
{
m_pVertexRenderBuf[m_pBones[i].vertexIndics[j]] = m_pBones[i].transforms[id].Transform(m_pvertexlist[m_pBones[i].vertexIndics[j]]);
}
}
}
GenerateFaceNormal();
// DBGPRINTF("End SetFrame");
}
void CMesh::GenerateFaceNormal()
{
int i, j;
Face *pFace;
Vertex v1, v2, v3;
Vector4s vec;
for (i=0; i<m_submeshCount; i++)
{
for (j=0; j<m_pSubMeshs[i].m_facenum; j++)
{
pFace = &m_pSubMeshs[i].m_pfaceIndics[j];
if (m_frameCount > 0)
{//animation model, generate from render buf
v1 = m_pVertexRenderBuf[pFace->ver[0]];
v2 = m_pVertexRenderBuf[pFace->ver[1]];
v3 = m_pVertexRenderBuf[pFace->ver[2]];
}
else
{
v1 = m_pvertexlist[pFace->ver[0]];
v2 = m_pvertexlist[pFace->ver[1]];
v3 = m_pvertexlist[pFace->ver[2]];
}
//cross (v2-v1)*(v3-v1)
v2 -= v1;
v3 -= v1;
vec.x = v2.y * v3.z - v2.z * v3.y;
vec.y = v2.z * v3.x - v2.x * v3.z;
vec.z = v2.x * v3.y - v2.y * v3.x;
vec.Normalize();
pFace->normalx = vec.x;
pFace->normaly = vec.y;
pFace->normalz = vec.z;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -