Main Page Namespace List Class Hierarchy Alphabetical List Data Structures File List Namespace Members Data Fields Globals

# ExCFrustum.cpp

Go to the documentation of this file.

    00001 /*
    00002  * ExNihilo 3D Engine
    00003  *
    00004  *  This program is free software; you can redistribute it and/or modify
    00005  *  it under the terms of the GNU General Public License as published by
    00006  *  the Free Software Foundation; either version 2 of the License, or
    00007  *  (at your option) any later version.
    00008  *
    00009  *  This program is distributed in the hope that it will be useful,
    00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00012  *  GNU Library General Public License for more details.
    00013  *
    00014  *  You should have received a copy of the GNU General Public License
    00015  *  along with this program; if not, write to the Free Software
    00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    00017  *
    00018  * Please read AUTHORS file !!!
    00019  *
    00020  * $Id: ExCFrustum.cpp,v 1.5 2002/08/25 15:27:49 data Exp $
    00021  *
    00022  */
    00023
    00024 #include "ExCFrustum.h"
    00025
    00026 enum FrustumSide
    00027 {
    00028         RIGHT   = 0,            // The RIGHT side of the frustum
    00029         LEFT    = 1,            // The LEFT      side of the frustum
    00030         BOTTOM  = 2,            // The BOTTOM side of the frustum
    00031         TOP             = 3,            // The TOP side of the frustum
    00032         BACK    = 4,            // The BACK     side of the frustum
    00033         FRONT   = 5                     // The FRONT side of the frustum
    00034 };
    00035
    00036
    00037 enum PlaneData
    00038 {
    00039         A = 0,                          // The X value of the plane's normal
    00040         B = 1,                          // The Y value of the plane's normal
    00041         C = 2,                          // The Z value of the plane's normal
    00042         D = 3                           // The distance the plane is from the origin
    00043 };
    00044
    00045 ExCFrustum::ExCFrustum(void)
    00046 {
    00047 }
    00048
    00049 ExCFrustum::~ExCFrustum(void)
    00050 {
    00051 }
    00052
    00053 void ExCFrustum::CalculateFrustum()
    00054 {
    00055         float   proj[16];                                                               // This will hold our projection matrix
    00056         float   modl[16];                                                               // This will hold our modelview matrix
    00057         float   clip[16];                                                               // This will hold the clipping planes
    00058
    00059         glGetFloatv( GL_PROJECTION_MATRIX, proj );
    00060         glGetFloatv( GL_MODELVIEW_MATRIX, modl );
    00061
    00062         clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + modl[ 3] * proj[12];
    00063         clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + modl[ 3] * proj[13];
    00064         clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + modl[ 3] * proj[14];
    00065         clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + modl[ 3] * proj[15];
    00066
    00067         clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] + modl[ 7] * proj[12];
    00068         clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + modl[ 7] * proj[13];
    00069         clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + modl[ 7] * proj[14];
    00070         clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + modl[ 7] * proj[15];
    00071
    00072         clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] + modl[11] * proj[12];
    00073         clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + modl[11] * proj[13];
    00074         clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + modl[11] * proj[14];
    00075         clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + modl[11] * proj[15];
    00076
    00077         clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] + modl[15] * proj[12];
    00078         clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + modl[15] * proj[13];
    00079         clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + modl[15] * proj[14];
    00080         clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + modl[15] * proj[15];
    00081
    00082         m_Frustum[RIGHT][A] = clip[ 3] - clip[ 0];
    00083         m_Frustum[RIGHT][B] = clip[ 7] - clip[ 4];
    00084         m_Frustum[RIGHT][C] = clip[11] - clip[ 8];
    00085         m_Frustum[RIGHT][D] = clip[15] - clip[12];
    00086
    00087         NormalizePlane(m_Frustum, RIGHT);
    00088
    00089     m_Frustum[LEFT][A] = clip[ 3] + clip[ 0];
    00090         m_Frustum[LEFT][B] = clip[ 7] + clip[ 4];
    00091         m_Frustum[LEFT][C] = clip[11] + clip[ 8];
    00092         m_Frustum[LEFT][D] = clip[15] + clip[12];
    00093
    00094     NormalizePlane(m_Frustum, LEFT);
    00095
    00096         // This will extract the BOTTOM side of the frustum
    00097         m_Frustum[BOTTOM][A] = clip[ 3] + clip[ 1];
    00098         m_Frustum[BOTTOM][B] = clip[ 7] + clip[ 5];
    00099         m_Frustum[BOTTOM][C] = clip[11] + clip[ 9];
    00100         m_Frustum[BOTTOM][D] = clip[15] + clip[13];
    00101
    00102         // Normalize the BOTTOM side
    00103         NormalizePlane(m_Frustum, BOTTOM);
    00104
    00105         // This will extract the TOP side of the frustum
    00106         m_Frustum[TOP][A] = clip[ 3] - clip[ 1];
    00107         m_Frustum[TOP][B] = clip[ 7] - clip[ 5];
    00108         m_Frustum[TOP][C] = clip[11] - clip[ 9];
    00109         m_Frustum[TOP][D] = clip[15] - clip[13];
    00110
    00111         // Normalize the TOP side
    00112         NormalizePlane(m_Frustum, TOP);
    00113
    00114         // This will extract the BACK side of the frustum
    00115         m_Frustum[BACK][A] = clip[ 3] - clip[ 2];
    00116         m_Frustum[BACK][B] = clip[ 7] - clip[ 6];
    00117         m_Frustum[BACK][C] = clip[11] - clip[10];
    00118         m_Frustum[BACK][D] = clip[15] - clip[14];
    00119
    00120         // Normalize the BACK side
    00121         NormalizePlane(m_Frustum, BACK);
    00122
    00123         // This will extract the FRONT side of the frustum
    00124         m_Frustum[FRONT][A] = clip[ 3] + clip[ 2];
    00125         m_Frustum[FRONT][B] = clip[ 7] + clip[ 6];
    00126         m_Frustum[FRONT][C] = clip[11] + clip[10];
    00127         m_Frustum[FRONT][D] = clip[15] + clip[14];
    00128
    00129         // Normalize the FRONT side
    00130         NormalizePlane(m_Frustum, FRONT);
    00131 }
    00132
    00133
    00134 bool ExCFrustum::PointInFrustum( float x, float y, float z )
    00135 {
    00136
    00137         // Go through all the sides of the frustum
    00138         for(int i = 0; i < 6; i++ )
    00139         {
    00140                 // Calculate the plane equation and check if the point is behind a side of the frustum
    00141                 if(m_Frustum[i][A] * x + m_Frustum[i][B] * y + m_Frustum[i][C] * z + m_Frustum[i][D] <= 0)
    00142                 {
    00143                         // The point was behind a side, so it ISN'T in the frustum
    00144                         return false;
    00145                 }
    00146         }
    00147
    00148         // The point was inside of the frustum (In front of ALL the sides of the frustum)
    00149         return true;
    00150 }
    00151
    00152
    00153 bool ExCFrustum::SphereInFrustum( float x, float y, float z, float radius )
    00154 {
    00155
    00156         // Go through all the sides of the frustum
    00157         for(int i = 0; i < 6; i++ )
    00158         {
    00159                 // If the center of the sphere is farther away from the plane than the radius
    00160                 if( m_Frustum[i][A] * x + m_Frustum[i][B] * y + m_Frustum[i][C] * z + m_Frustum[i][D] <= -radius )
    00161                 {
    00162                         // The distance was greater than the radius so the sphere is outside of the frustum
    00163                         return false;
    00164                 }
    00165         }
    00166
    00167         // The sphere was inside of the frustum!
    00168         return true;
    00169 }
    00170
    00171 bool ExCFrustum::CubeInFrustum( float x, float y, float z, float size )
    00172 {
    00173
    00174         for(int i = 0; i < 6; i++ )
    00175         {
    00176                 if(m_Frustum[i][A] * (x - size) + m_Frustum[i][B] * (y - size) + m_Frustum[i][C] * (z - size) + m_Frustum[i][D] > 0)
    00177                    continue;
    00178                 if(m_Frustum[i][A] * (x + size) + m_Frustum[i][B] * (y - size) + m_Frustum[i][C] * (z - size) + m_Frustum[i][D] > 0)
    00179                    continue;
    00180                 if(m_Frustum[i][A] * (x - size) + m_Frustum[i][B] * (y + size) + m_Frustum[i][C] * (z - size) + m_Frustum[i][D] > 0)
    00181                    continue;
    00182                 if(m_Frustum[i][A] * (x + size) + m_Frustum[i][B] * (y + size) + m_Frustum[i][C] * (z - size) + m_Frustum[i][D] > 0)
    00183                    continue;
    00184                 if(m_Frustum[i][A] * (x - size) + m_Frustum[i][B] * (y - size) + m_Frustum[i][C] * (z + size) + m_Frustum[i][D] > 0)
    00185                    continue;
    00186                 if(m_Frustum[i][A] * (x + size) + m_Frustum[i][B] * (y - size) + m_Frustum[i][C] * (z + size) + m_Frustum[i][D] > 0)
    00187                    continue;
    00188                 if(m_Frustum[i][A] * (x - size) + m_Frustum[i][B] * (y + size) + m_Frustum[i][C] * (z + size) + m_Frustum[i][D] > 0)
    00189                    continue;
    00190                 if(m_Frustum[i][A] * (x + size) + m_Frustum[i][B] * (y + size) + m_Frustum[i][C] * (z + size) + m_Frustum[i][D] > 0)
    00191                    continue;
    00192
    00193                 // If we get here, it isn't in the frustum
    00194                 return false;
    00195         }
    00196
    00197         return true;
    00198 }
    00199
    00200 bool ExCFrustum::BoxInFrustrum(ExCVec3D point[8])
    00201 {
    00202         for(int i=0;i<8;i++)
    00203         {
    00204                 if(PointInFrustum(point[i].GetX(),point[i].GetY(),point[i].GetZ()))
    00205                         return true;
    00206         }
    00207  return false;
    00208 }