Lephisto/src/Frustum.cpp
2012-04-07 16:38:56 +01:00

136 lines
4.9 KiB
C++

/* This software is the propery of 'SaraCraft' - developed by Allanis.
* Only members directly assosiated with the SaraCraft project may view/change
* this code.
*/
#if defined WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <GL/gl.h>
#include "Point.h"
#include "BoundBox.h"
#include "Frustum.h"
void Frustum::getFrustum() {
float proj[16];
float modl[16];
float clip[16];
//float t;
// Get the current PROJECTION matrix
glGetFloatv(GL_PROJECTION_MATRIX, proj);
// Get the current MODELVIEW matrix
glGetFloatv(GL_MODELVIEW_MATRIX, modl);
// Combine the two matrices (multiply projection by modelview)
clip[0] = modl[0]*proj[0] + modl[1]*proj[4] + modl[2]*proj[8] + modl[3]*proj[12];
clip[1] = modl[0]*proj[1] + modl[1]*proj[5] + modl[2]*proj[9] + modl[3]*proj[13];
clip[2] = modl[0]*proj[2] + modl[1]*proj[6] + modl[2]*proj[10] + modl[3]*proj[14];
clip[3] = modl[0]*proj[3] + modl[1]*proj[7] + modl[2]*proj[11] + modl[3]*proj[15];
clip[4] = modl[4]*proj[0] + modl[5]*proj[4] + modl[6]*proj[8] + modl[7]*proj[12];
clip[5] = modl[4]*proj[1] + modl[5]*proj[5] + modl[6]*proj[9] + modl[7]*proj[13];
clip[6] = modl[4]*proj[2] + modl[5]*proj[6] + modl[6]*proj[10] + modl[7]*proj[14];
clip[7] = modl[4]*proj[3] + modl[5]*proj[7] + modl[6]*proj[11] + modl[7]*proj[15];
clip[8] = modl[8]*proj[0] + modl[9]*proj[4] + modl[10]*proj[8] + modl[11]*proj[12];
clip[9] = modl[8]*proj[1] + modl[9]*proj[5] + modl[10]*proj[9] + modl[11]*proj[13];
clip[10] = modl[8]*proj[2] + modl[9]*proj[6] + modl[10]*proj[10] + modl[11]*proj[14];
clip[11] = modl[8]*proj[3] + modl[9]*proj[7] + modl[10]*proj[11] + modl[11]*proj[15];
clip[12] = modl[12]*proj[0] + modl[13]*proj[4] + modl[14]*proj[8] + modl[15]*proj[12];
clip[13] = modl[12]*proj[1] + modl[13]*proj[5] + modl[14]*proj[9] + modl[15]*proj[13];
clip[14] = modl[12]*proj[2] + modl[13]*proj[6] + modl[14]*proj[10] + modl[15]*proj[14];
clip[15] = modl[12]*proj[3] + modl[13]*proj[7] + modl[14]*proj[11] + modl[15]*proj[15];
// Extract the numbers for the RIGHT plane
frustum[0][0] = clip[3] - clip[0];
frustum[0][1] = clip[7] - clip[4];
frustum[0][2] = clip[11] - clip[8];
frustum[0][3] = clip[15] - clip[12];
// Normalize the result (not needed for boxes)
/*
t = sqrt(frustum[0][0]*frustum[0][0] + frustum[0][1]*frustum[0][1] + frustum[0][2]*frustum[0][2]);
frustum[0][0] /= t;
frustum[0][1] /= t;
frustum[0][2] /= t;
frustum[0][3] /= t;
*/
// Extract the numbers for the LEFT plane
frustum[1][0] = clip[3] + clip[0];
frustum[1][1] = clip[7] + clip[4];
frustum[1][2] = clip[11] + clip[ 8];
frustum[1][3] = clip[15] + clip[12];
// Normalize the result (not needed for boxes)
// Extract the BOTTOM plane
frustum[2][0] = clip[3] + clip[1];
frustum[2][1] = clip[7] + clip[5];
frustum[2][2] = clip[11] + clip[9];
frustum[2][3] = clip[15] + clip[13];
// Normalize the result (not needed for boxes)
// Extract the TOP plane
frustum[3][0] = clip[3] - clip[1];
frustum[3][1] = clip[7] - clip[5];
frustum[3][2] = clip[11] - clip[ 9];
frustum[3][3] = clip[15] - clip[13];
// Normalize the result (not needed for boxes)
// Extract the FAR plane
frustum[4][0] = clip[3] - clip[2];
frustum[4][1] = clip[7] - clip[6];
frustum[4][2] = clip[11] - clip[10];
frustum[4][3] = clip[15] - clip[14];
// Normalize the result (not needed for boxes)
// Extract the NEAR plane
frustum[5][0] = clip[3] + clip[2];
frustum[5][1] = clip[7] + clip[6];
frustum[5][2] = clip[11] + clip[10];
frustum[5][3] = clip[15] + clip[14];
// Normalize the result (not needed for boxes)
}
bool Frustum::checkBox(BoundBox *box) {
// Check each frustum plane
for(int p=0; p<6; p++) {
// Check each point of the box
// Bottom points
if(frustum[p][0]*box->b1->x + frustum[p][1]*box->b1->y + frustum[p][2]*box->b1->z + frustum[p][3] > 0)
continue;
if(frustum[p][0]*box->b2->x + frustum[p][1]*box->b2->y + frustum[p][2]*box->b2->z + frustum[p][3] > 0)
continue;
if(frustum[p][0]*box->b3->x + frustum[p][1]*box->b3->y + frustum[p][2]*box->b3->z + frustum[p][3] > 0)
continue;
if(frustum[p][0]*box->b4->x + frustum[p][1]*box->b4->y + frustum[p][2]*box->b4->z + frustum[p][3] > 0)
continue;
// Top points
if(frustum[p][0]*box->t1->x + frustum[p][1]*box->t1->y + frustum[p][2]*box->t1->z + frustum[p][3] > 0)
continue;
if(frustum[p][0]*box->t2->x + frustum[p][1]*box->t2->y + frustum[p][2]*box->t2->z + frustum[p][3] > 0)
continue;
if(frustum[p][0]*box->t3->x + frustum[p][1]*box->t3->y + frustum[p][2]*box->t3->z + frustum[p][3] > 0)
continue;
if(frustum[p][0]*box->t4->x + frustum[p][1]*box->t4->y + frustum[p][2]*box->t4->z + frustum[p][3] > 0)
continue;
// It's not in front of ANY plane, return false
return false;
}
// Got through all the checks, it passed
return true;
}