📄 frustum.cpp
字号:
#include <windows.h>
#include <gl/gl.h>
#include "math/math.h"
#include "math/matrix.h"
#include "frustum.h"
#include "math/aabb.h"
//////////////////////////////////////////////////////////////////////////////////
static GcFrustum *frust = NULL;
GcFrustum *ActiveFrustum()
{
return frust;
}
//////////////////////////////////////////////////////////////////////////////////
GcFrustum::GcFrustum()
{
frust = this;
}
//////////////////////////////////////////////////////////////////////////////////
GcFrustum::~GcFrustum()
{
frust = NULL;
}
//////////////////////////////////////////////////////////////////////////////////
void GcFrustum::Extract()
{
GcMatrix4 projection;
GcMatrix4 model;
GcMatrix4 clip;
GcVector4 temp[6];
// Get the projection and modelview matrix from OpenGL
glGetFloatv(GL_PROJECTION_MATRIX, projection);
glGetFloatv(GL_MODELVIEW_MATRIX, model);
// Combine the two matrices
clip = projection * model;
// Extract the right plane
temp[0].x = clip[ 3] - clip[ 0];
temp[0].y = clip[ 7] - clip[ 4];
temp[0].z = clip[11] - clip[ 8];
temp[0].w = clip[15] - clip[12];
// Normalize the vector
temp[0].NormalizePlane();
// Extract the left plane
temp[1].x = clip[ 3] + clip[ 0];
temp[1].y = clip[ 7] + clip[ 4];
temp[1].z = clip[11] + clip[ 8];
temp[1].w = clip[15] + clip[12];
// Normalize the vector
temp[1].NormalizePlane();
// Extract the bottom plane
temp[2].x = clip[ 3] + clip[ 1];
temp[2].y = clip[ 7] + clip[ 5];
temp[2].z = clip[11] + clip[ 9];
temp[2].w = clip[15] + clip[13];
// Normalize the vector
temp[2].NormalizePlane();
// Extract the top plane
temp[3].x = clip[ 3] - clip[ 1];
temp[3].y = clip[ 7] - clip[ 5];
temp[3].z = clip[11] - clip[ 9];
temp[3].w = clip[15] - clip[13];
// Normalize the vector
temp[3].NormalizePlane();
// Extract the far plane
temp[4].x = clip[ 3] - clip[ 2];
temp[4].y = clip[ 7] - clip[ 6];
temp[4].z = clip[11] - clip[10];
temp[4].w = clip[15] - clip[14];
// Normalize the vector
temp[4].NormalizePlane();
// Extract the near plane
temp[5].x = clip[ 3] + clip[ 2];
temp[5].y = clip[ 7] + clip[ 6];
temp[5].z = clip[11] + clip[10];
temp[5].w = clip[15] + clip[14];
// Normalize the vector
temp[5].NormalizePlane();
for( int i = 0; i < 6; ++i )
{
m_frustum[i].SetPlane(GcVector3(temp[i].x, temp[i].y, temp[i].z), temp[i].w);
}
}
//////////////////////////////////////////////////////////////////////////////////
/*bool GcFrustum::BoxInFrustum(float x, float y, float z, float size, float height)
{
// Check to see if a box is in the frustum
// Loop through all planes looking to see if the point is infront of it
for(int i = 0; i < 6; i++ )
{
// Check to see if any of the box's points is infront of the plane
// If it is continue to the next plane, if none are then the box outside the frustum
if(frustum[i].x * x + frustum[i].y * y +
frustum[i].z * z + frustum[i].w > 0 ) {
continue;
}
if(frustum[i].x * (x + size) + frustum[i].y * y +
frustum[i].z * z + frustum[i].w > 0 ) {
continue;
}
if(frustum[i].x * x + frustum[i].y * (y + height) +
frustum[i].z * z + frustum[i].w > 0 ) {
continue;
}
if(frustum[i].x * (x + size) + frustum[i].y * (y + height) +
frustum[i].z * z + frustum[i].w > 0 ) {
continue;
}
if(frustum[i].x * x + frustum[i].y * y +
frustum[i].z * (z + size) + frustum[i].w > 0 ) {
continue;
}
if(frustum[i].x * (x + size) + frustum[i].y * y +
frustum[i].z * (z + size) + frustum[i].w > 0 ) {
continue;
}
if(frustum[i].x * x + frustum[i].y * (y +height) +
frustum[i].z * (z + size) + frustum[i].w > 0 ) {
continue;
}
if(frustum[i].x * (x + size) + frustum[i].y * (y + height) +
frustum[i].z * (z + size) + frustum[i].w > 0 ) {
continue;
}
return false;
}
return true;
}
*/
//////////////////////////////////////////////////////////////////////////////////
bool GcFrustum::Contains(GcAABB & aabb)
{
for(int i = 0; i < 6; ++i)
{
if(m_frustum[i].Distance(aabb.Point(0)) > 0) continue;
if(m_frustum[i].Distance(aabb.Point(1)) > 0) continue;
if(m_frustum[i].Distance(aabb.Point(2)) > 0) continue;
if(m_frustum[i].Distance(aabb.Point(3)) > 0) continue;
if(m_frustum[i].Distance(aabb.Point(4)) > 0) continue;
if(m_frustum[i].Distance(aabb.Point(5)) > 0) continue;
if(m_frustum[i].Distance(aabb.Point(6)) > 0) continue;
if(m_frustum[i].Distance(aabb.Point(7)) > 0) continue;
// Ok, give up. The point isn't in the frustum
return false;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -