⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loadmeshes.cpp

📁 VC++ DEMO, used for the beginners and the amour
💻 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 + -