Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members | Tutorials

SViewFrustum.h

Go to the documentation of this file.
00001 // Copyright (C) 2002-2010 Nikolaus Gebhardt
00002 // This file is part of the "Irrlicht Engine".
00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
00004 
00005 #ifndef __S_VIEW_FRUSTUM_H_INCLUDED__
00006 #define __S_VIEW_FRUSTUM_H_INCLUDED__
00007 
00008 #include "plane3d.h"
00009 #include "vector3d.h"
00010 #include "line3d.h"
00011 #include "aabbox3d.h"
00012 #include "matrix4.h"
00013 #include "IVideoDriver.h"
00014 
00015 namespace irr
00016 {
00017 namespace scene
00018 {
00019 
00021 
00025         struct SViewFrustum
00026         {
00027                 enum VFPLANES
00028                 {
00030                         VF_FAR_PLANE = 0,
00032                         VF_NEAR_PLANE,
00034                         VF_LEFT_PLANE,
00036                         VF_RIGHT_PLANE,
00038                         VF_BOTTOM_PLANE,
00040                         VF_TOP_PLANE,
00041 
00043                         VF_PLANE_COUNT
00044                 };
00045 
00046 
00048                 SViewFrustum() {}
00049 
00051                 SViewFrustum(const SViewFrustum& other);
00052 
00054                 SViewFrustum(const core::matrix4& mat);
00055 
00057                 inline void setFrom(const core::matrix4& mat);
00058 
00060 
00061                 void transform(const core::matrix4& mat);
00062 
00064                 core::vector3df getFarLeftUp() const;
00065 
00067                 core::vector3df getFarLeftDown() const;
00068 
00070                 core::vector3df getFarRightUp() const;
00071 
00073                 core::vector3df getFarRightDown() const;
00074 
00076                 const core::aabbox3d<f32> &getBoundingBox() const;
00077 
00079                 inline void recalculateBoundingBox();
00080 
00082                 core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state);
00083 
00085                 const core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state) const;
00086 
00088 
00089                 bool clipLine(core::line3d<f32>& line) const;
00090 
00092                 core::vector3df cameraPosition;
00093 
00095                 core::plane3d<f32> planes[VF_PLANE_COUNT];
00096 
00098                 core::aabbox3d<f32> boundingBox;
00099 
00100         private:
00102                 enum E_TRANSFORMATION_STATE_FRUSTUM
00103                 {
00104                         ETS_VIEW = 0,
00105                         ETS_PROJECTION = 1,
00106                         ETS_COUNT_FRUSTUM
00107                 };
00108 
00110                 core::matrix4 Matrices[ETS_COUNT_FRUSTUM];
00111         };
00112 
00113 
00117         inline SViewFrustum::SViewFrustum(const SViewFrustum& other)
00118         {
00119                 cameraPosition=other.cameraPosition;
00120                 boundingBox=other.boundingBox;
00121 
00122                 u32 i;
00123                 for (i=0; i<VF_PLANE_COUNT; ++i)
00124                         planes[i]=other.planes[i];
00125 
00126                 for (i=0; i<ETS_COUNT_FRUSTUM; ++i)
00127                         Matrices[i]=other.Matrices[i];
00128         }
00129 
00130         inline SViewFrustum::SViewFrustum(const core::matrix4& mat)
00131         {
00132                 setFrom ( mat );
00133         }
00134 
00135 
00136         inline void SViewFrustum::transform(const core::matrix4& mat)
00137         {
00138                 for (u32 i=0; i<VF_PLANE_COUNT; ++i)
00139                         mat.transformPlane(planes[i]);
00140 
00141                 mat.transformVect(cameraPosition);
00142                 recalculateBoundingBox();
00143         }
00144 
00145 
00146         inline core::vector3df SViewFrustum::getFarLeftUp() const
00147         {
00148                 core::vector3df p;
00149                 planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
00150                         planes[scene::SViewFrustum::VF_TOP_PLANE],
00151                         planes[scene::SViewFrustum::VF_LEFT_PLANE], p);
00152 
00153                 return p;
00154         }
00155 
00156         inline core::vector3df SViewFrustum::getFarLeftDown() const
00157         {
00158                 core::vector3df p;
00159                 planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
00160                         planes[scene::SViewFrustum::VF_BOTTOM_PLANE],
00161                         planes[scene::SViewFrustum::VF_LEFT_PLANE], p);
00162 
00163                 return p;
00164         }
00165 
00166         inline core::vector3df SViewFrustum::getFarRightUp() const
00167         {
00168                 core::vector3df p;
00169                 planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
00170                         planes[scene::SViewFrustum::VF_TOP_PLANE],
00171                         planes[scene::SViewFrustum::VF_RIGHT_PLANE], p);
00172 
00173                 return p;
00174         }
00175 
00176         inline core::vector3df SViewFrustum::getFarRightDown() const
00177         {
00178                 core::vector3df p;
00179                 planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
00180                         planes[scene::SViewFrustum::VF_BOTTOM_PLANE],
00181                         planes[scene::SViewFrustum::VF_RIGHT_PLANE], p);
00182 
00183                 return p;
00184         }
00185 
00186         inline const core::aabbox3d<f32> &SViewFrustum::getBoundingBox() const
00187         {
00188                 return boundingBox;
00189         }
00190 
00191         inline void SViewFrustum::recalculateBoundingBox()
00192         {
00193                 boundingBox.reset ( cameraPosition );
00194 
00195                 boundingBox.addInternalPoint(getFarLeftUp());
00196                 boundingBox.addInternalPoint(getFarRightUp());
00197                 boundingBox.addInternalPoint(getFarLeftDown());
00198                 boundingBox.addInternalPoint(getFarRightDown());
00199         }
00200 
00203         inline void SViewFrustum::setFrom(const core::matrix4& mat)
00204         {
00205                 // left clipping plane
00206                 planes[VF_LEFT_PLANE].Normal.X = mat[3 ] + mat[0];
00207                 planes[VF_LEFT_PLANE].Normal.Y = mat[7 ] + mat[4];
00208                 planes[VF_LEFT_PLANE].Normal.Z = mat[11] + mat[8];
00209                 planes[VF_LEFT_PLANE].D =        mat[15] + mat[12];
00210 
00211                 // right clipping plane
00212                 planes[VF_RIGHT_PLANE].Normal.X = mat[3 ] - mat[0];
00213                 planes[VF_RIGHT_PLANE].Normal.Y = mat[7 ] - mat[4];
00214                 planes[VF_RIGHT_PLANE].Normal.Z = mat[11] - mat[8];
00215                 planes[VF_RIGHT_PLANE].D =        mat[15] - mat[12];
00216 
00217                 // top clipping plane
00218                 planes[VF_TOP_PLANE].Normal.X = mat[3 ] - mat[1];
00219                 planes[VF_TOP_PLANE].Normal.Y = mat[7 ] - mat[5];
00220                 planes[VF_TOP_PLANE].Normal.Z = mat[11] - mat[9];
00221                 planes[VF_TOP_PLANE].D =        mat[15] - mat[13];
00222 
00223                 // bottom clipping plane
00224                 planes[VF_BOTTOM_PLANE].Normal.X = mat[3 ] + mat[1];
00225                 planes[VF_BOTTOM_PLANE].Normal.Y = mat[7 ] + mat[5];
00226                 planes[VF_BOTTOM_PLANE].Normal.Z = mat[11] + mat[9];
00227                 planes[VF_BOTTOM_PLANE].D =        mat[15] + mat[13];
00228 
00229                 // far clipping plane
00230                 planes[VF_FAR_PLANE].Normal.X = mat[3 ] - mat[2];
00231                 planes[VF_FAR_PLANE].Normal.Y = mat[7 ] - mat[6];
00232                 planes[VF_FAR_PLANE].Normal.Z = mat[11] - mat[10];
00233                 planes[VF_FAR_PLANE].D =        mat[15] - mat[14];
00234 
00235                 // near clipping plane
00236                 planes[VF_NEAR_PLANE].Normal.X = mat[2];
00237                 planes[VF_NEAR_PLANE].Normal.Y = mat[6];
00238                 planes[VF_NEAR_PLANE].Normal.Z = mat[10];
00239                 planes[VF_NEAR_PLANE].D =        mat[14];
00240 
00241                 // normalize normals
00242                 u32 i;
00243                 for ( i=0; i != VF_PLANE_COUNT; ++i)
00244                 {
00245                         const f32 len = -core::reciprocal_squareroot(
00246                                         planes[i].Normal.getLengthSQ());
00247                         planes[i].Normal *= len;
00248                         planes[i].D *= len;
00249                 }
00250 
00251                 // make bounding box
00252                 recalculateBoundingBox();
00253         }
00254 
00258         inline core::matrix4& SViewFrustum::getTransform(video::E_TRANSFORMATION_STATE state )
00259         {
00260                 u32 index = 0;
00261                 switch ( state )
00262                 {
00263                         case video::ETS_PROJECTION:
00264                                 index = SViewFrustum::ETS_PROJECTION; break;
00265                         case video::ETS_VIEW:
00266                                 index = SViewFrustum::ETS_VIEW; break;
00267                         default:
00268                                 break;
00269                 }
00270                 return Matrices [ index ];
00271         }
00272 
00276         inline const core::matrix4& SViewFrustum::getTransform(video::E_TRANSFORMATION_STATE state ) const
00277         {
00278                 u32 index = 0;
00279                 switch ( state )
00280                 {
00281                         case video::ETS_PROJECTION:
00282                                 index = SViewFrustum::ETS_PROJECTION; break;
00283                         case video::ETS_VIEW:
00284                                 index = SViewFrustum::ETS_VIEW; break;
00285                         default:
00286                                 break;
00287                 }
00288                 return Matrices [ index ];
00289         }
00290 
00292         inline bool SViewFrustum::clipLine(core::line3d<f32>& line) const
00293         {
00294                 bool wasClipped = false;
00295                 for (u32 i=0; i < VF_PLANE_COUNT; ++i)
00296                 {
00297                         if (planes[i].classifyPointRelation(line.start) == core::ISREL3D_FRONT)
00298                         {
00299                                 line.start = line.start.getInterpolated(line.end, 
00300                                                 planes[i].getKnownIntersectionWithLine(line.start, line.end));
00301                                 wasClipped = true;
00302                         }
00303                         if (planes[i].classifyPointRelation(line.end) == core::ISREL3D_FRONT)
00304                         {
00305                                 line.end = line.start.getInterpolated(line.end, 
00306                                                 planes[i].getKnownIntersectionWithLine(line.start, line.end));
00307                                 wasClipped = true;
00308                         }
00309                 }
00310                 return wasClipped;
00311         }
00312 
00313 
00314 } // end namespace scene
00315 } // end namespace irr
00316 
00317 #endif
00318 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Sun Oct 24 12:41:58 2010 by Doxygen (1.6.2)