www.pudn.com > Gimcrack-v0.0051-Source.zip > frustum.cpp
#include#include #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; }