AaronCameron.net
Not Left, nor right. Just correct.
Not a Member? - Login or Create an Account
Wednesday the 23rd of May 2012 @ 05:03pm
Front Page Journal Projects Your Profile About
[]

LibN2L-4 Library Code Reference

Classes
Compounds
Files
Members
Method Index
Full Reference

cRFrustum.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002 Nova-2 Library (libN2L, or simply n2l) Game development C++ Library
00003 Copyright (C) 2003  Aaron Cameron
00004 
00005 This library is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU Lesser General Public
00007 License as published by the Free Software Foundation; either
00008 version 2.1 of the License, or (at your option) any later version.
00009 
00010 This library is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 Lesser General Public License for more details.
00014 
00015 You should have received a copy of the GNU Lesser General Public
00016 License along with this library; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00018 
00019 A copy of the GNU Lesser General Public License has been provided with
00020 this library in the file 'COPYING'.
00021 
00022 Contact information for the author of this library has been provided
00023 with this library in the file 'AUTHOR'.
00024 ************************************************************************/
00025 #include "renderObjects/cRFrustum.h"
00026 #include "n2l/renderTools.h"
00027 
00028 #include <iostream>
00029 using namespace std;
00030 
00031 /******************************************************************************/
00032 namespace n2l
00033 {
00034     /**************************************************************************/
00035     cRFrustum::cRFrustum()
00036     {
00037         tMatrix44f identMatrix;
00038         identMatrix.identity();
00039         set( identMatrix,identMatrix );
00040     }
00041 
00042     /**************************************************************************/
00043     cRFrustum::cRFrustum( const tMatrix44f &iProjectionMatrix,
00044         const tMatrix44f &iModelViewMatrix )
00045     {
00046         set( iProjectionMatrix, iModelViewMatrix );
00047     }
00048 
00049     /**************************************************************************/
00050     cRFrustum::cRFrustum( const cRFrustum &iFrustum )
00051     {
00052         *this = iFrustum;
00053     }
00054 
00055     /**************************************************************************/
00056     cRFrustum::~cRFrustum()
00057     {
00058     }
00059 
00060     /**************************************************************************/
00061     void cRFrustum::set( const tMatrix44f &iProjectionMatrix,
00062         const tMatrix44f &iModelViewMatrix )
00063     {
00064         // Keep these around for project calls we might want
00065         // to do later.  Bah, it's only 32 floats.
00066         mProj = iProjectionMatrix;
00067         mModel = iModelViewMatrix;
00068 
00069         tMatrix44f combo;
00070         iProjectionMatrix.multiply( combo, iModelViewMatrix );
00071 
00072         // Extract the clipping planes
00073         mPlane[ ClipPlane_Right ].set(
00074             combo[3] - combo[0],
00075             combo[7] - combo[4],
00076             combo[11] - combo[8],
00077             combo[15] - combo[12] );
00078         mPlane[ ClipPlane_Right ].normalize();
00079 
00080         mPlane[ ClipPlane_Left ].set(
00081             combo[3] + combo[0],
00082             combo[7] + combo[4],
00083             combo[11] + combo[8],
00084             combo[15] + combo[12] );
00085         mPlane[ ClipPlane_Left ].normalize();
00086 
00087         mPlane[ ClipPlane_Bottom ].set(
00088             combo[3] + combo[1],
00089             combo[7] + combo[5],
00090             combo[11] + combo[9],
00091             combo[15] + combo[13] );
00092         mPlane[ ClipPlane_Bottom ].normalize();
00093 
00094         mPlane[ ClipPlane_Top ].set(
00095             combo[3] - combo[1],
00096             combo[7] - combo[5],
00097             combo[11] - combo[9],
00098             combo[15] - combo[13] );
00099         mPlane[ ClipPlane_Top ].normalize();
00100 
00101         mPlane[ ClipPlane_Far ].set(
00102             combo[3] - combo[2],
00103             combo[7] - combo[6],
00104             combo[11] - combo[10],
00105             combo[15] - combo[14] );
00106         mPlane[ ClipPlane_Far ].normalize();
00107 
00108         mPlane[ ClipPlane_Near ].set(
00109             combo[3] + combo[2],
00110             combo[7] + combo[6],
00111             combo[11] + combo[10],
00112             combo[15] + combo[14] );
00113         mPlane[ ClipPlane_Near ].normalize();
00114     }
00115 
00116     /**************************************************************************/
00117     cRFrustum &cRFrustum::operator =( const cRFrustum &iFrustum )
00118     {
00119         mProj = iFrustum.mProj;
00120         mModel = iFrustum.mModel;
00121         for (tUint i=0; i<ClipPlane_NumClipPlanes; ++i)
00122             mPlane[i] = iFrustum.mPlane[i];
00123         return *this;
00124     }
00125     
00126     /**************************************************************************/
00127     const tBool cRFrustum::testSphere( const tVector3f &iCenter, 
00128         const tFloat &iRadius ) const
00129     {
00130         for (tUint i=0; i<ClipPlane_NumClipPlanes; ++i)
00131             if (mPlane[i].normal().dot(iCenter) + mPlane[i].d()<-iRadius)
00132                 return false;
00133         return true;
00134     }
00135 
00136     /**************************************************************************/
00137     const tBool cRFrustum::testSphere( const tVector3f &iCenter, 
00138         const tFloat &iRadius, const tUint &iMask ) const
00139     {
00140         for (tUint i=0; i<ClipPlane_NumClipPlanes; ++i) {
00141             switch (i) {
00142                 case ClipPlane_Right:
00143                     if (iMask&ClipPlaneMask_Right) continue;
00144                     break;
00145                 case ClipPlane_Left:
00146                     if (iMask&ClipPlaneMask_Left) continue;
00147                     break;
00148                 case ClipPlane_Bottom:
00149                     if (iMask&ClipPlaneMask_Bottom) continue;
00150                     break;
00151                 case ClipPlane_Top:
00152                     if (iMask&ClipPlaneMask_Top) continue;
00153                     break;
00154                 case ClipPlane_Far:
00155                     if (iMask&ClipPlaneMask_Far) continue;
00156                     break;
00157                 case ClipPlane_Near:
00158                     if (iMask&ClipPlaneMask_Near) continue;
00159                     break;
00160             }
00161             if (mPlane[i].normal().dot(iCenter) + mPlane[i].d()<-iRadius)
00162                 return false;
00163         }
00164         return true;
00165     }
00166 
00167     /**************************************************************************/
00168     const tBool cRFrustum::testAABox( const tVector3f &mC, 
00169         const tVector3f &mDistance ) const
00170     {
00171         const tVector3f hd( mDistance*0.5f );
00172         for (tUint i=0; i<ClipPlane_NumClipPlanes; ++i) {
00173             if (mPlane[i].pointInFront(tVector3f(
00174                 mC.x()+hd.x(), mC.y()+hd.y(), mC.z()+hd.z()))) continue;
00175 
00176             if (mPlane[i].pointInFront(tVector3f(
00177                 mC.x()-hd.x(), mC.y()+hd.y(), mC.z()+hd.z()))) continue;
00178 
00179             if (mPlane[i].pointInFront(tVector3f(
00180                 mC.x()+hd.x(), mC.y()-hd.y(), mC.z()+hd.z()))) continue;
00181 
00182             if (mPlane[i].pointInFront(tVector3f(
00183                 mC.x()-hd.x(), mC.y()-hd.y(), mC.z()+hd.z()))) continue;
00184 
00185             if (mPlane[i].pointInFront(tVector3f(
00186                 mC.x()+hd.x(), mC.y()+hd.y(), mC.z()-hd.z()))) continue;
00187 
00188             if (mPlane[i].pointInFront(tVector3f(
00189                 mC.x()-hd.x(), mC.y()+hd.y(), mC.z()-hd.z()))) continue;
00190 
00191             if (mPlane[i].pointInFront(tVector3f(
00192                 mC.x()+hd.x(), mC.y()-hd.y(), mC.z()-hd.z()))) continue;
00193 
00194             if (mPlane[i].pointInFront(tVector3f(
00195                 mC.x()-hd.x(), mC.y()-hd.y(), mC.z()-hd.z()))) continue;
00196             // Isn't visible.
00197             return false;
00198         }
00199         return true;
00200     }
00201 
00202     /**************************************************************************/
00203     const tBool cRFrustum::testPoint( const tVector3f &mPoint ) const
00204     {
00205         for (tUint i=0; i<ClipPlane_NumClipPlanes; ++i) {
00206             if (mPlane[i].pointInFront(mPoint)) continue;
00207             return false;
00208         }
00209         return true;
00210     }
00211 
00212     /**************************************************************************/
00213     const tBool cRFrustum::testQuad(
00214             const tVector3f &m0, const tVector3f &m1, 
00215             const tVector3f &m2, const tVector3f &m3 ) const
00216     {
00217         for (tUint i=0; i<ClipPlane_NumClipPlanes; ++i) {
00218             if (mPlane[i].pointInFront(m0)) continue;
00219             if (mPlane[i].pointInFront(m1)) continue;
00220             if (mPlane[i].pointInFront(m2)) continue;
00221             if (mPlane[i].pointInFront(m3)) continue;
00222             // Isn't visible.
00223             return false;
00224         }
00225         return true;
00226     }
00227 
00228     /**************************************************************************/
00229     void cRFrustum::halfNearFarVectorBase( tVector3f &oBottomLeftPos,
00230         tVector3f &oRightDir, tVector3f &oUpDir ) const
00231     {
00232         tVector3f nearBL = mPlane[ClipPlane_Near].intersect(
00233             mPlane[ClipPlane_Left], mPlane[ClipPlane_Bottom] );
00234 
00235         tVector3f nearBR = mPlane[ClipPlane_Near].intersect(
00236             mPlane[ClipPlane_Right], mPlane[ClipPlane_Bottom] );
00237 
00238         tVector3f nearTL = mPlane[ClipPlane_Near].intersect(
00239             mPlane[ClipPlane_Left], mPlane[ClipPlane_Top] );
00240 
00241         tVector3f farBL = mPlane[ClipPlane_Far].intersect(
00242             mPlane[ClipPlane_Left], mPlane[ClipPlane_Bottom] );
00243 
00244         tVector3f farBR = mPlane[ClipPlane_Far].intersect(
00245             mPlane[ClipPlane_Right], mPlane[ClipPlane_Bottom] );
00246 
00247         tVector3f farTL = mPlane[ClipPlane_Far].intersect(
00248             mPlane[ClipPlane_Left], mPlane[ClipPlane_Top] );
00249 
00250         oBottomLeftPos = nearBL + (farBL-nearBL)*0.5f;
00251         oRightDir = (nearBR-nearBL) + ( (farBR-farBL)-(nearBR-nearBL) )*0.5f;
00252         oUpDir = (nearTL-nearBL) + ( (farTL-farBL)-(nearTL-nearBL) )*0.5f;
00253     }
00254 
00255     /**************************************************************************/
00256     void cRFrustum::projectPoint( tVector3f &oPos,
00257         const tVector3f &iPos ) const
00258     {
00259         tFloat objC[4] = { iPos[0],iPos[1],iPos[2], 1.0f };
00260         tFloat eyeC[4];
00261         tFloat clipC[4];
00262         mModel.multiply( eyeC, objC );
00263         mProj.multiply( clipC, eyeC );
00264 
00265         oPos.x( clipC[0]/clipC[3] );
00266         oPos.y( clipC[1]/clipC[3] );
00267         oPos.z( clipC[2]/clipC[3] );
00268 
00269         oPos *= 0.5f;
00270         oPos += 0.5f;
00271     }
00272 
00273 } // namespace
©2012 Aaron Cameron