Page principale   Liste des namespaces   Hiérarchie des classes   Liste par ordre alphabétique   Liste des composants   Liste des fichiers   Membres des namespaces   Composants   Déclarations  

ExCFrustum.cpp

Aller à la documentation de ce fichier.
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 }  

Généré le Tue Dec 10 18:18:08 2002 pour ExNihilo par doxygen1.3-rc1