📄 frustum.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 + -