# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

frustum.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "std3d.h"
00027 
00028 #include "nel/3d/frustum.h"
00029 #include "nel/misc/matrix.h"
00030 #include <math.h>
00031 
00032 
00033 using namespace NLMISC;
00034 
00035 namespace NL3D
00036 {
00037 
00038 
00039 void                    CFrustum::init(float left, float right, float bottom, float top, float znear, float zfar, bool perspective)
00040 {
00041         Left= left;
00042         Right= right;
00043         Bottom= bottom;
00044         Top= top;
00045         Near= znear;
00046         Far= zfar;
00047         Perspective= perspective;
00048 }
00049 
00050 void                    CFrustum::init(float width, float height, float znear, float zfar, bool perspective)
00051 {
00052         init(-width/2, width/2, -height/2, height/2, znear, zfar, perspective);
00053 }
00054 void                    CFrustum::initPerspective(float fov, float aspectRatio, float znear, float zfar)
00055 {
00056         float   w,h;
00057         w= 2*znear*(float)tan(fov/2);
00058         h= w/aspectRatio;
00059         init(w,h,znear,zfar,true);
00060 }
00061 void                    CFrustum::getValues(float &left, float &right, float &bottom, float &top, float &znear, float &zfar) const
00062 {
00063         left= Left;
00064         right= Right;
00065         bottom= Bottom;
00066         top= Top;
00067         znear= Near;
00068         zfar= Far;
00069 }
00070 
00071 
00072 // ***************************************************************************
00073 CVector                 CFrustum::project(const CVector &vec) const
00074 {
00075         CVector         ret;
00076         float           decalX, decalY;
00077         float           w, h;
00078         float           OOw, OOh;
00079 
00080         // Fast transform to openGL like axis.
00081         CVector         pt;
00082         pt.x= vec.x;
00083         pt.y= vec.z;
00084         pt.z= -vec.y;
00085 
00086         decalX= (Right+Left);
00087         decalY= (Top+Bottom);
00088         w= Right-Left;
00089         h= Top-Bottom;
00090         OOw= 1.0f/w;
00091         OOh= 1.0f/h;
00092 
00093         // project to -1..+1.
00094         if(Perspective)
00095         {
00096                 ret.x= (2*Near*pt.x + decalX*pt.z)*OOw;
00097                 ret.x/= -pt.z;
00098                 ret.y= (2*Near*pt.y + decalY*pt.z)*OOh;
00099                 ret.y/= -pt.z;
00100         }
00101         else
00102         {
00103                 ret.x= (2*pt.x-decalX)*OOw;
00104                 ret.y= (2*pt.y-decalY)*OOh;
00105         }
00106 
00107 
00108         // Map it to 0..1.
00109         ret.x= 0.5f*(ret.x+1);
00110         ret.y= 0.5f*(ret.y+1);
00111         ret.z= 0;
00112 
00113         return ret;
00114 }
00115 
00116 
00117 
00118 // ***************************************************************************
00119 CVector                 CFrustum::unProject(const CVector &vec) const
00120 {
00121         CVector         ret;
00122         float           decalX, decalY;
00123         float           w, h;
00124         float           OOw, OOh;
00125 
00126         decalX= (Right+Left);
00127         decalY= (Top+Bottom);
00128         w= Right-Left;
00129         h= Top-Bottom;
00130         OOw= 1.0f/w;
00131         OOh= 1.0f/h;
00132 
00133         // vec is a vector in a left hand axis.
00134         CVector         pt;
00135         pt.x= vec.x;
00136         pt.y= vec.y;
00137         pt.z= vec.z;
00138         
00139         // Map it to -1..1
00140         pt.x= 2*(pt.x-0.5f);
00141         pt.y= 2*(pt.y-0.5f);
00142 
00143         // Map Z to Near..Far.
00144         // Z IN is 1/Z, and is in 0..1.
00145         // inverse to 1..0.
00146         pt.z= 1-pt.z;
00147         // Map ret.z to 1/Far..1/Near.
00148         pt.z= 1/Far+(1/Near-1/Far)*pt.z;
00149         // Inverse, so ret.z E Near..Far.
00150         pt.z= 1/pt.z;
00151         // Actually, pt.z==w, homogenous coordinate.
00152 
00153 
00154         // unproject
00155         if(Perspective)
00156         {
00157                 // w of homogenous coordinate.
00158                 float   Wh;
00159                 float   Zin;
00160                 Wh= pt.z;
00161                 Zin= -pt.z;
00162 
00163                 // unproject.  (Projection is: x'= x/w.  y'= y/w).
00164                 pt.x= pt.x*Wh;
00165                 pt.y= pt.y*Wh;
00166                 ret.x= (pt.x*w-decalX*Zin)/(2*Near);
00167                 ret.y= (pt.y*w-decalY*Zin)/(2*Near);
00168                 ret.z= Zin;
00169         }
00170         else
00171         {
00172                 // NOT DONE YET.
00173                 nlstop;
00174                 /*ret.x= (pt.x*w+decalX)/2;
00175                 ret.y= (pt.y*h+decalY)/2;
00176                 */
00177         }
00178 
00179         // Fast transform from openGL like axis.
00180         pt =ret;
00181         ret.x= pt.x;
00182         ret.y= -pt.z;
00183         ret.z= pt.y;
00184 
00185         return ret;
00186 }
00187 
00188 
00189 
00190 } // NL3D