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

📄 mobmodel.cpp

📁 Torus3D.rar,BREW平台的3D游戏引擎的一个实例.喜欢的朋友可以下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ==========================================================================================================
//
// BREW v2.0+ OPENGLES MICROENGINE
//
// ----------------------------------------
//
// Written by Vander Nunes
//
// ==========================================================================================================

#include "mobmodel.h"
#include "math3d.h"
#include "vfs.h"


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
CMobModel::CMobModel()
{
	m_bZWrite = TRUE;
	m_bBackCull = TRUE;
	m_pVertices = NULL;
	#if INC_NORMALS
		m_pNormals = NULL;
		#if INC_ENVMAP
			m_pEnvNormals = NULL;
			m_pEnvTexCoords = NULL;
		#endif
	#endif
	m_pFaces = NULL;
	m_pColors = NULL;
	m_pTexCoords = NULL;
	m_dwVertexCount = m_dwFaceCount = m_dwTexCoords = 0;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
CMobModel::~CMobModel()
{
	if (m_pVertices) delete[] m_pVertices;
	#if INC_NORMALS
		if (m_pNormals) delete[] m_pNormals;
		#if INC_ENVMAP
			DeletePtrArray(m_pEnvNormals);
			DeletePtrArray(m_pEnvTexCoords);
		#endif
	#endif
	if (m_pFaces) delete[] m_pFaces;
	if (m_pColors) delete[] m_pColors;
	if (m_pTexCoords) delete[] m_pTexCoords;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
boolean CMobModel::Load(AEEApplet* pApplet, char *szPakFile, char *szFile, float fXScale, float fYScale, float fZScale)
{
	//DBGPRINTF("Loading MobModel: %s", szFile);

	uint32 i;
	CVfs Vfs;
	if (!Vfs.Unpack(szPakFile, szFile, pApplet))
		return FALSE;

	//
	// read flag if exported from a 3DS file (if so, will need to negate V coordinate map)
	// 0 == not converted from a 3DS (or 3DSMAX) model
	// 1 == converted from a 3DS (or 3DSMAX) model
	byte bFrom3DS;
	Vfs.Read((void*)&bFrom3DS, 1);

	//
	// read vertices
	//

	Vfs.Read((void*)&m_dwVertexCount, sizeof(dword));

	// allocate space
	m_pVertices = new int[m_dwVertexCount * 3];
	m_pColors = new dword[m_dwVertexCount * 4];
	m_pTexCoords = new dword[m_dwVertexCount * 2];
	#if INC_NORMALS
		m_pNormals = new int[m_dwVertexCount * 3];
		#if INC_ENVMAP
			m_pEnvNormals = new int[m_dwVertexCount * 3];
			m_pEnvTexCoords = new dword[m_dwVertexCount * 2];
		#endif
	#endif

	// reset bounding sphere and bounding box
	m_dwBSphere = 0;
	VectorSet(m_BBMin, ITOX(999999), ITOX(999999), ITOX(999999));
	VectorSet(m_BBMax, ITOX(-999999), ITOX(-999999), ITOX(-999999));

	// load vertices
	for (i = 0; i < m_dwVertexCount; i ++)
	{
		int j;
		int idx2 = i * 2;
		int idx3 = i * 3;
		int idx4 = i * 4;

		// read
		Vfs.Read((void*)&m_pVertices[idx3], sizeof(int) * 3);

		// scale
		m_pVertices[idx3 + 0] = (int)(m_pVertices[idx3 + 0] * fXScale);
		m_pVertices[idx3 + 1] = (int)(m_pVertices[idx3 + 1] * fYScale);
		m_pVertices[idx3 + 2] = (int)(m_pVertices[idx3 + 2] * fZScale);

		// update bounding sphere
		if ((dword)ABS(m_pVertices[idx3 + 0]) > m_dwBSphere) m_dwBSphere = ABS(m_pVertices[idx3 + 0]);
		if ((dword)ABS(m_pVertices[idx3 + 1]) > m_dwBSphere) m_dwBSphere = ABS(m_pVertices[idx3 + 1]);
		if ((dword)ABS(m_pVertices[idx3 + 2]) > m_dwBSphere) m_dwBSphere = ABS(m_pVertices[idx3 + 2]);

		// update bounding box
		if (m_pVertices[idx3 + 0] < m_BBMin[0]) m_BBMin[0] = m_pVertices[idx3 + 0];
		if (m_pVertices[idx3 + 1] < m_BBMin[1]) m_BBMin[1] = m_pVertices[idx3 + 1];
		if (m_pVertices[idx3 + 2] < m_BBMin[2]) m_BBMin[2] = m_pVertices[idx3 + 2];
		if (m_pVertices[idx3 + 0] > m_BBMax[0]) m_BBMax[0] = m_pVertices[idx3 + 0];
		if (m_pVertices[idx3 + 1] > m_BBMax[1]) m_BBMax[1] = m_pVertices[idx3 + 1];
		if (m_pVertices[idx3 + 2] > m_BBMax[2]) m_BBMax[2] = m_pVertices[idx3 + 2];

		// color
		byte c;
		for (j = 0; j < 4; j ++)
		{
			Vfs.Read((void*)&c, sizeof(byte));
			// invert from rgb to bgr
			m_pColors[idx4 + j] = ((dword)c) << 8;		// convert color component to 16.16 fp OGLES format
		}

		// uv
		for (j = 0; j < 2; j ++)
		{
			Vfs.Read((void*)&m_pTexCoords[idx2 + j], sizeof(dword));
		}
		// ### hack needed because of v coordinate being inverted by the 3ds converter
		if (bFrom3DS == 1)
			// this model was converted from 3DS or 3DSMAX, need to negate V mapping
			m_pTexCoords[idx2 + 1] = ITOX(1) - m_pTexCoords[idx2 + 1];	// invert v
	}

	//
	// read faces
	//

	Vfs.Read((void*)&m_dwFaceCount, sizeof(dword));
	m_pFaces = new word[m_dwFaceCount * 3];
	for (i = 0; i < m_dwFaceCount; i ++)
	{
		int j;

		// vertex indexes
		for (j = 0; j < 3; j ++)
		{
			dword tmp;
			Vfs.Read((void*)&tmp, sizeof(dword));
			m_pFaces[i * 3 + j] = (word)tmp;
		}
	}

	//
	// ### IMPORTANT:
	// the latest mob model format includes
	// DWORD LightCount					; Number of billboarded lights in the object
	// DWORD X Y Z							; Coordinates (16:16) for each embedded light
	// (but at this moment we're ignoring lights -- support to be added later)
	//

	#if INC_NORMALS
		RecalculateNormals();
	#endif

	Vfs.Finish();

	return TRUE;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CMobModel::AllocSpace(uint32 dwVertices, uint32 dwFaces)
{
	m_dwVertexCount = dwVertices;
	m_dwFaceCount = dwFaces;
	m_dwTexCoords = m_dwVertexCount;

	m_pVertices = new int[m_dwVertexCount * 3];
	m_pColors = new dword[m_dwVertexCount * 4];
	m_pTexCoords = new dword[m_dwTexCoords * 2];
	m_pFaces = new word[m_dwFaceCount * 3];
	#if INC_NORMALS
		m_pNormals = new int[m_dwVertexCount * 3];
		#if INC_ENVMAP
			m_pEnvNormals = new int[m_dwVertexCount * 3];
			m_pEnvTexCoords = new dword[m_dwTexCoords * 2];
		#endif
	#endif
}


// -------------------------------------------------------------------------------------------
//
// Generate a sphere with user-specified divisions and material.
//
// -------------------------------------------------------------------------------------------
void CMobModel::MakeSphere(float fRadius, word wDivr, word wDivh, boolean bUseUVHack)
{
	uint32 x,y;
	float a,da,yp,ya,yda,yf;
	float U,V,dU,dV;

	m_dwBSphere = FTOX(fRadius);

	if (wDivr < 3) wDivr = 3;
	if (wDivh < 3) wDivh = 3;

	uint32 NF = (wDivr * 2) + ((wDivh - 3) * 2 * wDivr);
	uint32 NV = ((wDivh - 2) * (wDivr + 1) + 2);
	AllocSpace(NV, NF);
	NF *= 3;
	NV *= 3;

	// top vertex
	m_pVertices[0] = 0;
	m_pVertices[1] = FTOX(fRadius);
	m_pVertices[2] = 0;

	// bottom vertex
	m_pVertices[3] = 0;
	m_pVertices[4] = FTOX(-fRadius);
	m_pVertices[5] = 0;

	uint32 dwVIdx = 6;

	ya = 0;
	yda = PI/(wDivh-1);
	da = (2*PI)/wDivr;

	// create all sphere vertices at once
	for (y = 0; y < (uint32)wDivh-2; y++)
	{
		ya += yda;
		yp = (float)cos(ya)*fRadius;
		yf = (float)sin(ya)*fRadius;
		a = 0;
		for (x = 0; x < wDivr; x++)
		{
			m_pVertices[dwVIdx+0] = FTOX((float)cos(a)*yf);
			m_pVertices[dwVIdx+1] = FTOX(yp);
			m_pVertices[dwVIdx+2] = FTOX((float)sin(a)*yf);
			dwVIdx += 3;

			// hack: create the last vertices at the same point,
			// to avoid UV mapping limitation (can't assign a second UV for the same vertice).
			if (x==(uint32)(wDivr-1))
			{
				m_pVertices[dwVIdx+0] = m_pVertices[(y*(wDivr+1)+2)*3+0];
				m_pVertices[dwVIdx+1] = m_pVertices[(y*(wDivr+1)+2)*3+1];
				m_pVertices[dwVIdx+2] = m_pVertices[(y*(wDivr+1)+2)*3+2];
				dwVIdx += 3;
			}

			a += da;
		}
	}

	a = 0;
	U = 1;
	dU = -1.0f/wDivr;
	dV = V = 1.0f/wDivh;

	uint32 dwFIdx = 0;

	// create top faces
	for (x = 0; x < wDivr; x++)
	{
		int v[3] = { 0, (2+x+1), (2+x) };

		m_pFaces[dwFIdx++] = v[0];
		m_pFaces[dwFIdx++] = v[1];
		m_pFaces[dwFIdx++] = v[2];

		m_pTexCoords[v[0]*2] = FTOX(U);
		m_pTexCoords[v[0]*2+1] = FTOX(0);
		m_pTexCoords[v[1]*2] = FTOX(U+dU);
		m_pTexCoords[v[1]*2+1] = FTOX(V);
		m_pTexCoords[v[2]*2] = FTOX(U);
		m_pTexCoords[v[2]*2+1] = FTOX(V);

		U += dU;
	}

	da = 1.0f/(wDivr+1);
	int offv = 2;

	// create main body faces
	for (x = 0; x < (uint32)(wDivh-3); x++)
	{
		U = 1;
		for (y = 0; y < wDivr; y++)
		{
			int v[3] = { (offv+y), (offv+(wDivr+1)+y+1), (offv+y+(wDivr+1)) };

			m_pFaces[dwFIdx++] = v[0];
			m_pFaces[dwFIdx++] = v[1];
			m_pFaces[dwFIdx++] = v[2];

			m_pTexCoords[v[0]*2] = FTOX(U);
			m_pTexCoords[v[0]*2+1] = FTOX(V);
			m_pTexCoords[v[1]*2] = FTOX(U+dU);
			m_pTexCoords[v[1]*2+1] = FTOX(V+dV);
			m_pTexCoords[v[2]*2] = FTOX(U);
			m_pTexCoords[v[2]*2+1] = FTOX(V+dV);

			int vv[3] = { (offv+y), (offv+y+1), (offv+y+1+(wDivr+1)) };

			m_pFaces[dwFIdx++] = vv[0];
			m_pFaces[dwFIdx++] = vv[1];
			m_pFaces[dwFIdx++] = vv[2];

			m_pTexCoords[vv[0]*2] = FTOX(U);
			m_pTexCoords[vv[0]*2+1] = FTOX(V);
			m_pTexCoords[vv[1]*2] = FTOX(U+dU);
			m_pTexCoords[vv[1]*2+1] = FTOX(V);
			m_pTexCoords[vv[2]*2] = FTOX(U+dU);
			m_pTexCoords[vv[2]*2+1] = FTOX(V+dV);

			U += dU;
		}

		V += dV;
		offv += wDivr+1;
	}

	int s = m_dwVertexCount - wDivr - 1;
	U = 1;

	// create bottom faces
	for (x = 0; x < wDivr; x++)
	{
		int v[3] = { 1, (s+x), (s+x+1) };

		m_pFaces[dwFIdx++] = v[0];
		m_pFaces[dwFIdx++] = v[1];
		m_pFaces[dwFIdx++] = v[2];

		m_pTexCoords[v[0]*2] = FTOX(U);
		m_pTexCoords[v[0]*2+1] = FTOX(1.0f);
		m_pTexCoords[v[1]*2] = FTOX(U);
		m_pTexCoords[v[1]*2+1] = FTOX(V);
		m_pTexCoords[v[2]*2] = FTOX(U+dU);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -