Go to the documentation of this file.00001
00002
00003
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 core::vector3df getNearLeftUp() const;
00077
00079 core::vector3df getNearLeftDown() const;
00080
00082 core::vector3df getNearRightUp() const;
00083
00085 core::vector3df getNearRightDown() const;
00086
00088 const core::aabbox3d<f32> &getBoundingBox() const;
00089
00091 inline void recalculateBoundingBox();
00092
00094 core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state);
00095
00097 const core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state) const;
00098
00100
00101 bool clipLine(core::line3d<f32>& line) const;
00102
00104 core::vector3df cameraPosition;
00105
00107 core::plane3d<f32> planes[VF_PLANE_COUNT];
00108
00110 core::aabbox3d<f32> boundingBox;
00111
00112 private:
00114 enum E_TRANSFORMATION_STATE_FRUSTUM
00115 {
00116 ETS_VIEW = 0,
00117 ETS_PROJECTION = 1,
00118 ETS_COUNT_FRUSTUM
00119 };
00120
00122 core::matrix4 Matrices[ETS_COUNT_FRUSTUM];
00123 };
00124
00125
00129 inline SViewFrustum::SViewFrustum(const SViewFrustum& other)
00130 {
00131 cameraPosition=other.cameraPosition;
00132 boundingBox=other.boundingBox;
00133
00134 u32 i;
00135 for (i=0; i<VF_PLANE_COUNT; ++i)
00136 planes[i]=other.planes[i];
00137
00138 for (i=0; i<ETS_COUNT_FRUSTUM; ++i)
00139 Matrices[i]=other.Matrices[i];
00140 }
00141
00142 inline SViewFrustum::SViewFrustum(const core::matrix4& mat)
00143 {
00144 setFrom ( mat );
00145 }
00146
00147
00148 inline void SViewFrustum::transform(const core::matrix4& mat)
00149 {
00150 for (u32 i=0; i<VF_PLANE_COUNT; ++i)
00151 mat.transformPlane(planes[i]);
00152
00153 mat.transformVect(cameraPosition);
00154 recalculateBoundingBox();
00155 }
00156
00157
00158 inline core::vector3df SViewFrustum::getFarLeftUp() const
00159 {
00160 core::vector3df p;
00161 planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
00162 planes[scene::SViewFrustum::VF_TOP_PLANE],
00163 planes[scene::SViewFrustum::VF_LEFT_PLANE], p);
00164
00165 return p;
00166 }
00167
00168 inline core::vector3df SViewFrustum::getFarLeftDown() const
00169 {
00170 core::vector3df p;
00171 planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
00172 planes[scene::SViewFrustum::VF_BOTTOM_PLANE],
00173 planes[scene::SViewFrustum::VF_LEFT_PLANE], p);
00174
00175 return p;
00176 }
00177
00178 inline core::vector3df SViewFrustum::getFarRightUp() const
00179 {
00180 core::vector3df p;
00181 planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
00182 planes[scene::SViewFrustum::VF_TOP_PLANE],
00183 planes[scene::SViewFrustum::VF_RIGHT_PLANE], p);
00184
00185 return p;
00186 }
00187
00188 inline core::vector3df SViewFrustum::getFarRightDown() const
00189 {
00190 core::vector3df p;
00191 planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
00192 planes[scene::SViewFrustum::VF_BOTTOM_PLANE],
00193 planes[scene::SViewFrustum::VF_RIGHT_PLANE], p);
00194
00195 return p;
00196 }
00197
00198 inline core::vector3df SViewFrustum::getNearLeftUp() const
00199 {
00200 core::vector3df p;
00201 planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes(
00202 planes[scene::SViewFrustum::VF_TOP_PLANE],
00203 planes[scene::SViewFrustum::VF_LEFT_PLANE], p);
00204
00205 return p;
00206 }
00207
00208 inline core::vector3df SViewFrustum::getNearLeftDown() const
00209 {
00210 core::vector3df p;
00211 planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes(
00212 planes[scene::SViewFrustum::VF_BOTTOM_PLANE],
00213 planes[scene::SViewFrustum::VF_LEFT_PLANE], p);
00214
00215 return p;
00216 }
00217
00218 inline core::vector3df SViewFrustum::getNearRightUp() const
00219 {
00220 core::vector3df p;
00221 planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes(
00222 planes[scene::SViewFrustum::VF_TOP_PLANE],
00223 planes[scene::SViewFrustum::VF_RIGHT_PLANE], p);
00224
00225 return p;
00226 }
00227
00228 inline core::vector3df SViewFrustum::getNearRightDown() const
00229 {
00230 core::vector3df p;
00231 planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes(
00232 planes[scene::SViewFrustum::VF_BOTTOM_PLANE],
00233 planes[scene::SViewFrustum::VF_RIGHT_PLANE], p);
00234
00235 return p;
00236 }
00237
00238 inline const core::aabbox3d<f32> &SViewFrustum::getBoundingBox() const
00239 {
00240 return boundingBox;
00241 }
00242
00243 inline void SViewFrustum::recalculateBoundingBox()
00244 {
00245 boundingBox.reset ( cameraPosition );
00246
00247 boundingBox.addInternalPoint(getFarLeftUp());
00248 boundingBox.addInternalPoint(getFarRightUp());
00249 boundingBox.addInternalPoint(getFarLeftDown());
00250 boundingBox.addInternalPoint(getFarRightDown());
00251 }
00252
00255 inline void SViewFrustum::setFrom(const core::matrix4& mat)
00256 {
00257
00258 planes[VF_LEFT_PLANE].Normal.X = mat[3 ] + mat[0];
00259 planes[VF_LEFT_PLANE].Normal.Y = mat[7 ] + mat[4];
00260 planes[VF_LEFT_PLANE].Normal.Z = mat[11] + mat[8];
00261 planes[VF_LEFT_PLANE].D = mat[15] + mat[12];
00262
00263
00264 planes[VF_RIGHT_PLANE].Normal.X = mat[3 ] - mat[0];
00265 planes[VF_RIGHT_PLANE].Normal.Y = mat[7 ] - mat[4];
00266 planes[VF_RIGHT_PLANE].Normal.Z = mat[11] - mat[8];
00267 planes[VF_RIGHT_PLANE].D = mat[15] - mat[12];
00268
00269
00270 planes[VF_TOP_PLANE].Normal.X = mat[3 ] - mat[1];
00271 planes[VF_TOP_PLANE].Normal.Y = mat[7 ] - mat[5];
00272 planes[VF_TOP_PLANE].Normal.Z = mat[11] - mat[9];
00273 planes[VF_TOP_PLANE].D = mat[15] - mat[13];
00274
00275
00276 planes[VF_BOTTOM_PLANE].Normal.X = mat[3 ] + mat[1];
00277 planes[VF_BOTTOM_PLANE].Normal.Y = mat[7 ] + mat[5];
00278 planes[VF_BOTTOM_PLANE].Normal.Z = mat[11] + mat[9];
00279 planes[VF_BOTTOM_PLANE].D = mat[15] + mat[13];
00280
00281
00282 planes[VF_FAR_PLANE].Normal.X = mat[3 ] - mat[2];
00283 planes[VF_FAR_PLANE].Normal.Y = mat[7 ] - mat[6];
00284 planes[VF_FAR_PLANE].Normal.Z = mat[11] - mat[10];
00285 planes[VF_FAR_PLANE].D = mat[15] - mat[14];
00286
00287
00288 planes[VF_NEAR_PLANE].Normal.X = mat[2];
00289 planes[VF_NEAR_PLANE].Normal.Y = mat[6];
00290 planes[VF_NEAR_PLANE].Normal.Z = mat[10];
00291 planes[VF_NEAR_PLANE].D = mat[14];
00292
00293
00294 u32 i;
00295 for ( i=0; i != VF_PLANE_COUNT; ++i)
00296 {
00297 const f32 len = -core::reciprocal_squareroot(
00298 planes[i].Normal.getLengthSQ());
00299 planes[i].Normal *= len;
00300 planes[i].D *= len;
00301 }
00302
00303
00304 recalculateBoundingBox();
00305 }
00306
00310 inline core::matrix4& SViewFrustum::getTransform(video::E_TRANSFORMATION_STATE state )
00311 {
00312 u32 index = 0;
00313 switch ( state )
00314 {
00315 case video::ETS_PROJECTION:
00316 index = SViewFrustum::ETS_PROJECTION; break;
00317 case video::ETS_VIEW:
00318 index = SViewFrustum::ETS_VIEW; break;
00319 default:
00320 break;
00321 }
00322 return Matrices [ index ];
00323 }
00324
00328 inline const core::matrix4& SViewFrustum::getTransform(video::E_TRANSFORMATION_STATE state ) const
00329 {
00330 u32 index = 0;
00331 switch ( state )
00332 {
00333 case video::ETS_PROJECTION:
00334 index = SViewFrustum::ETS_PROJECTION; break;
00335 case video::ETS_VIEW:
00336 index = SViewFrustum::ETS_VIEW; break;
00337 default:
00338 break;
00339 }
00340 return Matrices [ index ];
00341 }
00342
00344 inline bool SViewFrustum::clipLine(core::line3d<f32>& line) const
00345 {
00346 bool wasClipped = false;
00347 for (u32 i=0; i < VF_PLANE_COUNT; ++i)
00348 {
00349 if (planes[i].classifyPointRelation(line.start) == core::ISREL3D_FRONT)
00350 {
00351 line.start = line.start.getInterpolated(line.end,
00352 planes[i].getKnownIntersectionWithLine(line.start, line.end));
00353 wasClipped = true;
00354 }
00355 if (planes[i].classifyPointRelation(line.end) == core::ISREL3D_FRONT)
00356 {
00357 line.end = line.start.getInterpolated(line.end,
00358 planes[i].getKnownIntersectionWithLine(line.start, line.end));
00359 wasClipped = true;
00360 }
00361 }
00362 return wasClipped;
00363 }
00364
00365
00366 }
00367 }
00368
00369 #endif
00370