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

📄 frustum.cpp

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

#include <math.h>
#include "frustum.h"


//
//
//
CFrustum::CFrustum()
{
	for (BYTE x=0; x<6; x++)
	{
		VectorSet(m_Planes[x].vNormal, 0,0,0);
		m_Planes[x].iDist = 0;
	}
}


//
//
//
CFrustum::~CFrustum()
{
}


//
// Create Frustum planes from projection matrix
//
void CFrustum::InitFromProjectionMatrix(matrix_t mProjection)
{
	#define PROJ_NORM TRUE

	int a, b, c, d;

	#ifdef PROJ_NORM
		vec3f_t vTmp;
	#endif

	// left
	a = mProjection.m[3*4+0] + mProjection.m[0*4+0];
	b = mProjection.m[3*4+1] + mProjection.m[0*4+1];
	c = mProjection.m[3*4+2] + mProjection.m[0*4+2];
	d = mProjection.m[3*4+3] + mProjection.m[0*4+3];
	#if PROJ_NORM
		VectorSet(vTmp, XTOF(-a), XTOF(-b), XTOF(-c));
		VectorNormalizef(vTmp);
		VectorSet(m_Planes[0].vNormal, FTOX(vTmp[0]),FTOX(vTmp[1]),FTOX(vTmp[2]));
	#else
		VectorSet(m_Planes[0].vNormal, -a, -b, -c);
	#endif
	m_Planes[0].iDist = d;

	// right
	a = mProjection.m[3*4+0] - mProjection.m[0*4+0];
	b = mProjection.m[3*4+1] - mProjection.m[0*4+1];
	c = mProjection.m[3*4+2] - mProjection.m[0*4+2];
	d = mProjection.m[3*4+3] - mProjection.m[0*4+3];
	#if PROJ_NORM
		VectorSet(vTmp, XTOF(-a), XTOF(-b), XTOF(-c));
		VectorNormalizef(vTmp);
		VectorSet(m_Planes[1].vNormal, FTOX(vTmp[0]),FTOX(vTmp[1]),FTOX(vTmp[2]));
	#else
		VectorSet(m_Planes[1].vNormal, -a, -b, -c);
	#endif
	m_Planes[1].iDist = d;

	// bottom
	a = mProjection.m[3*4+0] + mProjection.m[1*4+0];
	b = mProjection.m[3*4+1] + mProjection.m[1*4+1];
	c = mProjection.m[3*4+2] + mProjection.m[1*4+2];
	d = mProjection.m[3*4+3] + mProjection.m[1*4+3];
	#if PROJ_NORM
		VectorSet(vTmp, XTOF(-a), XTOF(-b), XTOF(-c));
		VectorNormalizef(vTmp);
		VectorSet(m_Planes[2].vNormal, FTOX(vTmp[0]),FTOX(vTmp[1]),FTOX(vTmp[2]));
	#else
		VectorSet(m_Planes[2].vNormal, -a, -b, -c);
	#endif
	m_Planes[2].iDist = d;

	// top
	a = mProjection.m[3*4+0] - mProjection.m[1*4+0];
	b = mProjection.m[3*4+1] - mProjection.m[1*4+1];
	c = mProjection.m[3*4+2] - mProjection.m[1*4+2];
	d = mProjection.m[3*4+3] - mProjection.m[1*4+3];
	#if PROJ_NORM
		VectorSet(vTmp, XTOF(-a), XTOF(-b), XTOF(-c));
		VectorNormalizef(vTmp);
		VectorSet(m_Planes[3].vNormal, FTOX(vTmp[0]),FTOX(vTmp[1]),FTOX(vTmp[2]));
	#else
		VectorSet(m_Planes[3].vNormal, -a, -b, -c);
	#endif
	m_Planes[3].iDist = d;

	// near
	a = mProjection.m[3*4+0] + mProjection.m[2*4+0];
	b = mProjection.m[3*4+1] + mProjection.m[2*4+1];
	c = mProjection.m[3*4+2] + mProjection.m[2*4+2];
	d = 0; //mProjection.m[3*4+3] + mProjection.m[2*4+3];
	#if PROJ_NORM
		VectorSet(vTmp, XTOF(-a), XTOF(-b), XTOF(-c));
		VectorNormalizef(vTmp);
		VectorSet(m_Planes[4].vNormal, FTOX(vTmp[0]),FTOX(vTmp[1]),FTOX(vTmp[2]));
	#else
		VectorSet(m_Planes[4].vNormal, -a, -b, -c);
	#endif
	m_Planes[4].iDist = d;

	// far
	a = mProjection.m[3*4+0] - mProjection.m[2*4+0];
	b = mProjection.m[3*4+1] - mProjection.m[2*4+1];
	c = mProjection.m[3*4+2] - mProjection.m[2*4+2];
	d = mProjection.m[3*4+3] - mProjection.m[2*4+3];
	#if PROJ_NORM
		VectorSet(vTmp, XTOF(-a), XTOF(-b), XTOF(-c));
		VectorNormalizef(vTmp);
		VectorSet(m_Planes[5].vNormal, FTOX(vTmp[0]),FTOX(vTmp[1]),FTOX(vTmp[2]));
	#else
		VectorSet(m_Planes[5].vNormal, -a, -b, -c);
	#endif
	m_Planes[5].iDist = d;
}


//
// Check if a box (in camera space) is inside Frustum
//
FRUSTUM_RELATION CFrustum::BoxRelation(vec3_t vMin, vec3_t vMax)
{
	vec3_t Point[8] =
	{
		{ vMin[0], vMax[1], vMin[2] },
		{ vMax[0], vMax[1], vMin[2] },
		{ vMax[0], vMin[1], vMin[2] },
		{ vMin[0], vMin[1], vMin[2] },
		{ vMin[0], vMax[1], vMax[2] },
		{ vMax[0], vMax[1], vMax[2] },
		{ vMax[0], vMin[1], vMax[2] },
		{ vMin[0], vMin[1], vMax[2] }
	};

	//
	// Loop through each Frustum plane
	// Checking if one of the box vertices is INSIDE of ALL Frustum planes
	//

	WORD i,j;

	// entirely inside flag
	boolean bInside = TRUE;

	for(j=0; j<5; j++)
	{
		// entirely out flag
		boolean bOutside = TRUE;

		// loop through box vertices
		for(i = 0; i < 8; i++)
		{
			int iDist = VectorPlaneDistance(Point[i], m_Planes[j]);
			if(iDist > 0)
				// if one vertex is IN, the box is at least partially inside the plane
				bOutside = FALSE;
			else
				// if one vertex is OUT, the box cannot be entirelly inside Frustum.
				bInside = FALSE;
		}

		// if all vertices are OUT of a plane, the box is OUTSIDE Frustum
		if (bOutside) return FRUSTUM_OUTSIDE;
	}

	if (bInside)
		return FRUSTUM_INSIDE;
	else
		return FRUSTUM_INTERSECTING;
}

⌨️ 快捷键说明

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