📄 loadmeshes.cpp
字号:
// ObjMesh_t.cpp: implementation of the ObjMesh_t class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "LoadMeshes.h"
#include <stdio.h>
#include <string.h>
#include <algorithm>
/////////////////////////////////////////////////////////////////////
// Name: LoadObjMesh
// Desc: Load model from obj file
/////////////////////////////////////////////////////////////////////
bool cge_mesh::LoadObjMesh(const char *pFilename, ObjMesh_s &OutMesh)
{
int i;
char str[255], *p, *pEnd;
TexCoord_s TexCoord;
Vector3_s Vert;
ObjTriangle_s Triangle;
// Open the file with text mode
FILE *pf = fopen(pFilename, "r");
if (pf == NULL)
return false;
OutMesh.m_bHasTexCoords = false;
OutMesh.m_bHasNormals = false;
while (!feof(pf))
{
// Get a line from file
if (NULL == fgets(str, 256, pf))
break;
// Parse it
switch (str[0])
{
case 'v':
if (str[1] == 't')
{
// 此行是纹理坐标数据
if (sscanf(str + 2, " %f %f", &TexCoord.u, &TexCoord.v))
OutMesh.m_TexCoords.push_back(TexCoord);
}else if (str[1] == 'n')
{
// 此行是法向量数据
if (sscanf(str + 2, " %f %f %f", &Vert.x, &Vert.y, &Vert.z))
OutMesh.m_Normals.push_back(Vert);
}else
{
// 此行是顶点坐标数据
if (sscanf(str + 1, " %f %f %f", &Vert.x, &Vert.y, &Vert.z))
OutMesh.m_Vertices.push_back(Vert);
}
break;
case 'f':
// 此行是三角形面数据
p = str + 1;
for (i = 0; i < 3; i++)
{
// 解释三组顶点数据(以空格开头,空格结尾)
if (*p++ != ' ')
break;
if (NULL == (pEnd = std::find(p, str + strlen(str), ' ')))
break;
// Read vertex index data
sscanf(p, "%d", &Triangle.m_VertexIndices[i]);
// 调整索引值为数组下标
Triangle.m_VertexIndices[i]--;
// Checking validity
if (Triangle.m_VertexIndices[i] < 0 ||
Triangle.m_VertexIndices[i] >= OutMesh.m_Vertices.size())
break;
if((p = std::find(p, pEnd, '/')) && p < pEnd)
{
// If the face not only contain vertices
p++;
if (*p == '/')
{
// If the face contain vertices and vertex normals
p++;
// Read vertex normal data
sscanf(p, "%d", &Triangle.m_NormalIndices[i]);
// Adjust index value
Triangle.m_NormalIndices[i]--;
// Checking validity
if (Triangle.m_NormalIndices[i] < 0 ||
Triangle.m_NormalIndices[i] >= OutMesh.m_Normals.size())
break;
OutMesh.m_bHasNormals = true;
}else
{
// If the face are textured,
sscanf(p, "%d", &Triangle.m_TexCoordIndices[i]);
// Adjust index value
Triangle.m_TexCoordIndices[i]--;
// Checking validity
if (Triangle.m_TexCoordIndices[i] < 0 ||
Triangle.m_TexCoordIndices[i] >= OutMesh.m_TexCoords.size())
break;
OutMesh.m_bHasTexCoords = true;
if ((p = std::find(p, pEnd, '/')) && p < pEnd)
{
// If the face contain vertex normals
p++;
// Read vertex normal data
sscanf(p, "%d", &Triangle.m_NormalIndices[i]);
// Adjust index value
Triangle.m_NormalIndices[i]--;
// Checking validity
if (Triangle.m_NormalIndices[i] < 0 ||
Triangle.m_NormalIndices[i] >= OutMesh.m_Normals.size())
break;
OutMesh.m_bHasNormals = true;
}
}
}
// 解释下一组数据
p = pEnd;
// 如果是正确的三角形数据
if ( i == 2)
OutMesh.m_Triangles.push_back(Triangle);
}
break;
}
}
// Close the file
fclose(pf);
return true;
}
/////////////////////////////////////////////////////////////////////
// Name: LoadMd2Mesh
// Desc: Load model from md2 file
/////////////////////////////////////////////////////////////////////
bool cge_mesh::LoadMd2Mesh(const char *pFilename, Md2Mesh_s &OutMesh)
{
register int i,j;
unsigned char Verts[4];
unsigned short Tex[2];
// Open the file with binary mode
FILE *pf = fopen(pFilename, "rb");
if (pf == NULL)
return false;
// Read the file header
fread(&OutMesh.m_Header, 1, sizeof(Md2Header_s), pf);
// The md2's magic number is "IDP2" and version is 8
if (OutMesh.m_Header.m_iMagicNum != 844121161 &&
OutMesh.m_Header.m_iVersion != 8)
{
fclose(pf);
return false;
}
// Assign memory for md2 model
OutMesh.m_Skins.resize(OutMesh.m_Header.m_iNumSkins);
OutMesh.m_TexCoords.resize(OutMesh.m_Header.m_iNumTexCoords);
OutMesh.m_Triangles.resize(OutMesh.m_Header.m_iNumTriangles);
OutMesh.m_Frames.resize(OutMesh.m_Header.m_iNumFrames);
OutMesh.m_GLCommands.resize(OutMesh.m_Header.m_iNumGLCommands);
// Read the skin data
fseek(pf, OutMesh.m_Header.m_iOffsetSkins, SEEK_SET);
for (i = 0; i < OutMesh.m_Header.m_iNumSkins; i++)
{
fscanf(pf, "%s", OutMesh.m_Skins[i].name);
}
// Read the texture's coordinates data
fseek(pf, OutMesh.m_Header.m_iOffsetTexCoords, SEEK_SET);
for (i = 0; i < OutMesh.m_Header.m_iNumTexCoords; i++)
{
fread(Tex, 1, sizeof(short) * 2, pf);
OutMesh.m_TexCoords[i].u = (float)Tex[0]/OutMesh.m_Header.m_iSkinWidthPx;
OutMesh.m_TexCoords[i].v = (float)Tex[1]/OutMesh.m_Header.m_iSkinHeightPx;
}
// Read the triangles data
fseek(pf, OutMesh.m_Header.m_iOffsetTriangles, SEEK_SET);
for (i = 0; i < OutMesh.m_Header.m_iNumTriangles; i++)
{
fread(OutMesh.m_Triangles[i].m_sVertIndices, 1, sizeof(short) * 3, pf);
fread(OutMesh.m_Triangles[i].m_sTexIndices, 1, sizeof(short) * 3 , pf);
}
// Read the Frames data
fseek(pf, OutMesh.m_Header.m_iOffsetFrames, SEEK_SET);
for (i = 0; i < OutMesh.m_Header.m_iNumFrames; i++)
{
fread(OutMesh.m_Frames[i].m_fScale, 1, 3 * sizeof(float), pf);
fread(OutMesh.m_Frames[i].m_fTrans, 1, 3 * sizeof(float), pf);
fread(OutMesh.m_Frames[i].m_szName, 1, 16, pf);
// Allocate vertices memory for this frame
OutMesh.m_Frames[i].m_Vertices.resize(OutMesh.m_Header.m_iNumVertices);
// Read the vertices data and decompress it
for (j = 0; j < OutMesh.m_Header.m_iNumVertices; j++)
{
fread(Verts, 1, 4, pf);
OutMesh.m_Frames[i].m_Vertices[j].x = Verts[0] * OutMesh.m_Frames[i].m_fScale[0] + OutMesh.m_Frames[i].m_fTrans[0];
OutMesh.m_Frames[i].m_Vertices[j].y = Verts[1] * OutMesh.m_Frames[i].m_fScale[1] + OutMesh.m_Frames[i].m_fTrans[1];
OutMesh.m_Frames[i].m_Vertices[j].z = Verts[2] * OutMesh.m_Frames[i].m_fScale[2] + OutMesh.m_Frames[i].m_fTrans[2];
}
}
// Read the OpenGL commands
fseek(pf, OutMesh.m_Header.m_iOffsetGLCommands, SEEK_SET);
fread(OutMesh.m_GLCommands.begin(), 1, sizeof(long) * OutMesh.m_Header.m_iNumGLCommands, pf);
// Close the file
fclose(pf);
return true;
}
/////////////////////////////////////////////////////////////////////
// Name: LoadMs3dMesh
// Desc: Load model from ms3d file
/////////////////////////////////////////////////////////////////////
bool cge_mesh::LoadMs3dMesh(const char *pFilename, Ms3dMesh_s &Mesh)
{
register int i;
unsigned short Num;
// Open the file with binary mode
FILE *pf = fopen(pFilename, "rb");
if (pf == NULL)
return false;
// Read the file header
fread(&Mesh.m_Header, 1, sizeof(Ms3dHeader_s), pf);
// Checking validity
if (strncmp("MS3D000000", Mesh.m_Header.m_szFlags, 10) != 0 ||
(Mesh.m_Header.m_iVersion != 3 &&
Mesh.m_Header.m_iVersion != 4))
{
fclose(pf);
return false;
}
// Read the number of vertex data
fread(&Num, 1, sizeof(unsigned short), pf);
// Allocate memory and read vertex data
Mesh.m_Vertices.resize(Num);
fread(Mesh.m_Vertices.begin(), 1, Num * sizeof(Ms3dVertex_s), pf);
// Read the number of triangle data
fread(&Num, 1, sizeof(unsigned short), pf);
// Allocate memory and read triangle data
Mesh.m_Triangles.resize(Num);
fread(Mesh.m_Triangles.begin(), 1, Num * sizeof(Ms3dTriangle_s), pf);
// Read the number of group data
fread(&Num, 1, sizeof(unsigned short), pf);
// Allocate memory and read group data
Mesh.m_Groups.resize(Num);
for (i = 0; i < Num; i++)
{
fread(&Mesh.m_Groups[i].m_ucFlags, 1, sizeof(char), pf);
fread(&Mesh.m_Groups[i].m_szName, 1, 32 * sizeof(char), pf);
fread(&Mesh.m_Groups[i].m_usNumTriangles, 1, sizeof(short), pf);
// Allocate memory for triangle indices
Mesh.m_Groups[i].m_TriangleIndices.resize(Mesh.m_Groups[i].m_usNumTriangles);
fread(Mesh.m_Groups[i].m_TriangleIndices.begin(), 1, Mesh.m_Groups[i].m_usNumTriangles * sizeof(short), pf);
fread(&Mesh.m_Groups[i].m_cMaterial, 1, sizeof(char), pf);
}
// Read the number of material data
fread(&Num, 1, sizeof(unsigned short), pf);
// Allocate memory and read material data
Mesh.m_Materials.resize(Num);
fread(Mesh.m_Materials.begin(), 1, sizeof(Ms3dMaterial_s) * Num, pf);
fclose(pf);
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -