Irrlicht 3D Engine
SViewFrustum.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4 
5 #ifndef __S_VIEW_FRUSTUM_H_INCLUDED__
6 #define __S_VIEW_FRUSTUM_H_INCLUDED__
7 
8 #include "plane3d.h"
9 #include "vector3d.h"
10 #include "line3d.h"
11 #include "aabbox3d.h"
12 #include "matrix4.h"
13 #include "IVideoDriver.h"
14 
15 namespace irr
16 {
17 namespace scene
18 {
19 
21 
25  struct SViewFrustum
26  {
27  enum VFPLANES
28  {
41 
44  };
45 
46 
48  SViewFrustum() : BoundingRadius(0.f), FarNearDistance(0.f) {}
49 
51  SViewFrustum(const SViewFrustum& other);
52 
54  //\param zClipFromZero: Clipping of z can be projected from 0 to w when true (D3D style) and from -w to w when false (OGL style).
55  SViewFrustum(const core::matrix4& mat, bool zClipFromZero);
56 
58  //\param zClipFromZero: Clipping of z can be projected from 0 to w when true (D3D style) and from -w to w when false (OGL style).
59  inline void setFrom(const core::matrix4& mat, bool zClipFromZero);
60 
62 
63  void transform(const core::matrix4& mat);
64 
67 
70 
73 
76 
79 
82 
85 
88 
90  const core::aabbox3d<f32> &getBoundingBox() const;
91 
93  inline void recalculateBoundingBox();
94 
96  float getBoundingRadius() const;
97 
100 
102  void setFarNearDistance(float distance);
103 
106 
109 
111 
112  bool clipLine(core::line3d<f32>& line) const;
113 
116 
119 
122 
123  private:
125  enum E_TRANSFORMATION_STATE_FRUSTUM
126  {
127  ETS_VIEW = 0,
128  ETS_PROJECTION = 1,
129  ETS_COUNT_FRUSTUM
130  };
131 
133  inline void recalculateBoundingSphere();
134 
136  core::matrix4 Matrices[ETS_COUNT_FRUSTUM];
137 
138  float BoundingRadius;
139  float FarNearDistance;
140  core::vector3df BoundingCenter;
141  };
142 
143 
148  {
150  boundingBox=other.boundingBox;
151 
152  u32 i;
153  for (i=0; i<VF_PLANE_COUNT; ++i)
154  planes[i]=other.planes[i];
155 
156  for (i=0; i<ETS_COUNT_FRUSTUM; ++i)
157  Matrices[i]=other.Matrices[i];
158 
159  BoundingRadius = other.BoundingRadius;
160  FarNearDistance = other.FarNearDistance;
161  BoundingCenter = other.BoundingCenter;
162  }
163 
164  inline SViewFrustum::SViewFrustum(const core::matrix4& mat, bool zClipFromZero)
165  {
166  setFrom(mat, zClipFromZero);
167  }
168 
169 
170  inline void SViewFrustum::transform(const core::matrix4& mat)
171  {
172  for (u32 i=0; i<VF_PLANE_COUNT; ++i)
173  mat.transformPlane(planes[i]);
174 
177  }
178 
179 
181  {
182  core::vector3df p;
186 
187  return p;
188  }
189 
191  {
192  core::vector3df p;
196 
197  return p;
198  }
199 
201  {
202  core::vector3df p;
206 
207  return p;
208  }
209 
211  {
212  core::vector3df p;
216 
217  return p;
218  }
219 
221  {
222  core::vector3df p;
226 
227  return p;
228  }
229 
231  {
232  core::vector3df p;
236 
237  return p;
238  }
239 
241  {
242  core::vector3df p;
246 
247  return p;
248  }
249 
251  {
252  core::vector3df p;
256 
257  return p;
258  }
259 
261  {
262  return boundingBox;
263  }
264 
266  {
275 
276  // Also recalculate the bounding sphere when the bbox changes
277  recalculateBoundingSphere();
278  }
279 
280  inline float SViewFrustum::getBoundingRadius() const
281  {
282  return BoundingRadius;
283  }
284 
286  {
287  return BoundingCenter;
288  }
289 
290  inline void SViewFrustum::setFarNearDistance(float distance)
291  {
292  FarNearDistance = distance;
293  }
294 
297  inline void SViewFrustum::setFrom(const core::matrix4& mat, bool zClipFromZero)
298  {
299  // left clipping plane
300  planes[VF_LEFT_PLANE].Normal.X = mat[3 ] + mat[0];
301  planes[VF_LEFT_PLANE].Normal.Y = mat[7 ] + mat[4];
302  planes[VF_LEFT_PLANE].Normal.Z = mat[11] + mat[8];
303  planes[VF_LEFT_PLANE].D = mat[15] + mat[12];
304 
305  // right clipping plane
306  planes[VF_RIGHT_PLANE].Normal.X = mat[3 ] - mat[0];
307  planes[VF_RIGHT_PLANE].Normal.Y = mat[7 ] - mat[4];
308  planes[VF_RIGHT_PLANE].Normal.Z = mat[11] - mat[8];
309  planes[VF_RIGHT_PLANE].D = mat[15] - mat[12];
310 
311  // top clipping plane
312  planes[VF_TOP_PLANE].Normal.X = mat[3 ] - mat[1];
313  planes[VF_TOP_PLANE].Normal.Y = mat[7 ] - mat[5];
314  planes[VF_TOP_PLANE].Normal.Z = mat[11] - mat[9];
315  planes[VF_TOP_PLANE].D = mat[15] - mat[13];
316 
317  // bottom clipping plane
318  planes[VF_BOTTOM_PLANE].Normal.X = mat[3 ] + mat[1];
319  planes[VF_BOTTOM_PLANE].Normal.Y = mat[7 ] + mat[5];
320  planes[VF_BOTTOM_PLANE].Normal.Z = mat[11] + mat[9];
321  planes[VF_BOTTOM_PLANE].D = mat[15] + mat[13];
322 
323  // far clipping plane
324  planes[VF_FAR_PLANE].Normal.X = mat[3 ] - mat[2];
325  planes[VF_FAR_PLANE].Normal.Y = mat[7 ] - mat[6];
326  planes[VF_FAR_PLANE].Normal.Z = mat[11] - mat[10];
327  planes[VF_FAR_PLANE].D = mat[15] - mat[14];
328 
329  // near clipping plane
330  if ( zClipFromZero )
331  {
332  planes[VF_NEAR_PLANE].Normal.X = mat[2];
333  planes[VF_NEAR_PLANE].Normal.Y = mat[6];
334  planes[VF_NEAR_PLANE].Normal.Z = mat[10];
335  planes[VF_NEAR_PLANE].D = mat[14];
336  }
337  else
338  {
339  // near clipping plane
340  planes[VF_NEAR_PLANE].Normal.X = mat[3 ] + mat[2];
341  planes[VF_NEAR_PLANE].Normal.Y = mat[7 ] + mat[6];
342  planes[VF_NEAR_PLANE].Normal.Z = mat[11] + mat[10];
343  planes[VF_NEAR_PLANE].D = mat[15] + mat[14];
344  }
345 
346  // normalize normals
347  u32 i;
348  for ( i=0; i != VF_PLANE_COUNT; ++i)
349  {
350  const f32 len = -core::reciprocal_squareroot(
351  planes[i].Normal.getLengthSQ());
352  planes[i].Normal *= len;
353  planes[i].D *= len;
354  }
355 
356  // make bounding box
358  }
359 
364  {
365  u32 index = 0;
366  switch ( state )
367  {
369  index = SViewFrustum::ETS_PROJECTION; break;
370  case video::ETS_VIEW:
371  index = SViewFrustum::ETS_VIEW; break;
372  default:
373  break;
374  }
375  return Matrices [ index ];
376  }
377 
382  {
383  u32 index = 0;
384  switch ( state )
385  {
387  index = SViewFrustum::ETS_PROJECTION; break;
388  case video::ETS_VIEW:
389  index = SViewFrustum::ETS_VIEW; break;
390  default:
391  break;
392  }
393  return Matrices [ index ];
394  }
395 
397  inline bool SViewFrustum::clipLine(core::line3d<f32>& line) const
398  {
399  bool wasClipped = false;
400  for (u32 i=0; i < VF_PLANE_COUNT; ++i)
401  {
402  if (planes[i].classifyPointRelation(line.start) == core::ISREL3D_FRONT)
403  {
404  line.start = line.start.getInterpolated(line.end,
405  1.f-planes[i].getKnownIntersectionWithLine(line.start, line.end));
406  wasClipped = true;
407  }
408  if (planes[i].classifyPointRelation(line.end) == core::ISREL3D_FRONT)
409  {
410  line.end = line.start.getInterpolated(line.end,
411  1.f-planes[i].getKnownIntersectionWithLine(line.start, line.end));
412  wasClipped = true;
413  }
414  }
415  return wasClipped;
416  }
417 
418  inline void SViewFrustum::recalculateBoundingSphere()
419  {
420  // Find the center
421  const float shortlen = (getNearLeftUp() - getNearRightUp()).getLength();
422  const float longlen = (getFarLeftUp() - getFarRightUp()).getLength();
423 
424  const float farlen = FarNearDistance;
425  const float fartocenter = (farlen + (shortlen - longlen) * (shortlen + longlen)/(4*farlen)) / 2;
426  const float neartocenter = farlen - fartocenter;
427 
428  BoundingCenter = cameraPosition + -planes[VF_NEAR_PLANE].Normal * neartocenter;
429 
430  // Find the radius
431  core::vector3df dir[8];
432  dir[0] = getFarLeftUp() - BoundingCenter;
433  dir[1] = getFarRightUp() - BoundingCenter;
434  dir[2] = getFarLeftDown() - BoundingCenter;
435  dir[3] = getFarRightDown() - BoundingCenter;
436  dir[4] = getNearRightDown() - BoundingCenter;
437  dir[5] = getNearLeftDown() - BoundingCenter;
438  dir[6] = getNearRightUp() - BoundingCenter;
439  dir[7] = getNearLeftUp() - BoundingCenter;
440 
441  u32 i = 0;
442  float diam[8] = { 0.f };
443 
444  for (i = 0; i < 8; ++i)
445  diam[i] = dir[i].getLengthSQ();
446 
447  float longest = 0;
448 
449  for (i = 0; i < 8; ++i)
450  {
451  if (diam[i] > longest)
452  longest = diam[i];
453  }
454 
455  BoundingRadius = sqrtf(longest);
456  }
457 
458 } // end namespace scene
459 } // end namespace irr
460 
461 #endif
462 
core::vector3df getNearLeftUp() const
returns the point which is on the near left upper corner inside the the view frustum.
Definition: SViewFrustum.h:220
T D
Distance from origin.
Definition: plane3d.h:231
T Y
Y coordinate of the vector.
Definition: vector3d.h:413
void transform(const core::matrix4 &mat)
transforms the frustum by the matrix
Definition: SViewFrustum.h:170
core::plane3d< f32 > planes[VF_PLANE_COUNT]
all planes enclosing the view frustum.
Definition: SViewFrustum.h:118
float f32
32 bit floating point variable.
Definition: irrTypes.h:108
vector3d< T > getInterpolated(const vector3d< T > &other, f64 d) const
Creates an interpolated vector between this vector and another vector.
Definition: vector3d.h:247
f32 getKnownIntersectionWithLine(const vector3d< T > &linePoint1, const vector3d< T > &linePoint2) const
Get percentage of line between two points where an intersection with this plane happens.
Definition: plane3d.h:107
void transformPlane(core::plane3d< f32 > &plane) const
Transforms a plane by this matrix.
Definition: matrix4.h:1243
const core::aabbox3d< f32 > & getBoundingBox() const
returns a bounding box enclosing the whole view frustum
Definition: SViewFrustum.h:260
vector3d< T > Normal
Normal vector of the plane.
Definition: plane3d.h:228
core::vector3df getFarLeftDown() const
returns the point which is on the far left bottom corner inside the the view frustum.
Definition: SViewFrustum.h:190
Left plane of the frustum.
Definition: SViewFrustum.h:34
void setFrom(const core::matrix4 &mat, bool zClipFromZero)
This constructor creates a view frustum based on a projection and/or view matrix.
Definition: SViewFrustum.h:297
T X
X coordinate of the vector.
Definition: vector3d.h:410
core::vector3df getNearRightUp() const
returns the point which is on the near right top corner inside the the view frustum.
Definition: SViewFrustum.h:240
core::vector3df getFarLeftUp() const
returns the point which is on the far left upper corner inside the the view frustum.
Definition: SViewFrustum.h:180
Everything in the Irrlicht Engine can be found in this namespace.
Definition: aabbox3d.h:12
Top plane of the frustum.
Definition: SViewFrustum.h:40
3D line between two points with intersection methods.
Definition: line3d.h:18
Defines the view frustum. That's the space visible by the camera.
Definition: SViewFrustum.h:25
void reset(T x, T y, T z)
Resets the bounding box to a one-point box.
Definition: aabbox3d.h:50
bool getIntersectionWithPlanes(const plane3d< T > &o1, const plane3d< T > &o2, vector3d< T > &outPoint) const
Get the intersection point with two other planes if there is one.
Definition: plane3d.h:195
Projection transformation.
Definition: IVideoDriver.h:60
core::vector3df getBoundingCenter() const
get the bounding sphere's radius (of an optimized sphere, not the AABB's)
Definition: SViewFrustum.h:285
core::vector3df getFarRightDown() const
returns the point which is on the far right bottom corner inside the the view frustum.
Definition: SViewFrustum.h:210
core::aabbox3d< f32 > boundingBox
bounding box around the view frustum
Definition: SViewFrustum.h:121
Right plane of the frustum.
Definition: SViewFrustum.h:36
core::vector3df getFarRightUp() const
returns the point which is on the far right top corner inside the the view frustum.
Definition: SViewFrustum.h:200
E_TRANSFORMATION_STATE
enumeration for geometry transformation states
Definition: IVideoDriver.h:53
float getBoundingRadius() const
get the bounding sphere's radius (of an optimized sphere, not the AABB's)
Definition: SViewFrustum.h:280
bool clipLine(core::line3d< f32 > &line) const
clips a line to the view frustum.
Definition: SViewFrustum.h:397
vector3d< T > end
End point of line.
Definition: line3d.h:132
unsigned int u32
32 bit unsigned variable.
Definition: irrTypes.h:62
Amount of planes enclosing the view frustum. Should be 6.
Definition: SViewFrustum.h:43
void transformVect(vector3df &vect) const
Transforms the vector by this matrix.
Definition: matrix4.h:1192
core::vector3df cameraPosition
the position of the camera
Definition: SViewFrustum.h:115
core::vector3df getNearRightDown() const
returns the point which is on the near right bottom corner inside the the view frustum.
Definition: SViewFrustum.h:250
SViewFrustum()
Default Constructor.
Definition: SViewFrustum.h:48
void setFarNearDistance(float distance)
the cam should tell the frustum the distance between far and near
Definition: SViewFrustum.h:290
Near plane of the frustum. That is the plane nearest to the eye.
Definition: SViewFrustum.h:32
View transformation.
Definition: IVideoDriver.h:56
4x4 matrix. Mostly used as transformation matrix for 3d calculations.
Definition: matrix4.h:45
vector3d< T > start
Start point of line.
Definition: line3d.h:130
void addInternalPoint(const vector3d< T > &p)
Adds a point to the bounding box.
Definition: aabbox3d.h:74
core::matrix4 & getTransform(video::E_TRANSFORMATION_STATE state)
get the given state's matrix based on frustum E_TRANSFORMATION_STATE
Definition: SViewFrustum.h:363
T Z
Z coordinate of the vector.
Definition: vector3d.h:416
Far plane of the frustum. That is the plane furthest away from the eye.
Definition: SViewFrustum.h:30
void recalculateBoundingBox()
recalculates the bounding box and sphere based on the planes
Definition: SViewFrustum.h:265
core::vector3df getNearLeftDown() const
returns the point which is on the near left bottom corner inside the the view frustum.
Definition: SViewFrustum.h:230
REALINLINE f64 reciprocal_squareroot(const f64 x)
Definition: irrMath.h:532
Bottom plane of the frustum.
Definition: SViewFrustum.h:38