1
// Copyright (C) 2002-2011 Nikolaus Gebhardt
2
// This file is part of the "Irrlicht Engine".
3
// For conditions of distribution and use, see copyright notice in irrlicht.h
5
#ifndef __S_VIEW_FRUSTUM_H_INCLUDED__
6
#define __S_VIEW_FRUSTUM_H_INCLUDED__
13
#include "IVideoDriver.h"
20
//! Defines the view frustum. That's the space visible by the camera.
21
/** The view frustum is enclosed by 6 planes. These six planes share
22
four points. A bounding box around these four points is also stored in
29
//! Far plane of the frustum. That is the plane farest away from the eye.
31
//! Near plane of the frustum. That is the plane nearest to the eye.
33
//! Left plane of the frustum.
35
//! Right plane of the frustum.
37
//! Bottom plane of the frustum.
39
//! Top plane of the frustum.
42
//! Amount of planes enclosing the view frustum. Should be 6.
47
//! Default Constructor
51
SViewFrustum(const SViewFrustum& other);
53
//! This constructor creates a view frustum based on a projection and/or view matrix.
54
SViewFrustum(const core::matrix4& mat);
56
//! This constructor creates a view frustum based on a projection and/or view matrix.
57
inline void setFrom(const core::matrix4& mat);
59
//! transforms the frustum by the matrix
60
/** \param mat: Matrix by which the view frustum is transformed.*/
61
void transform(const core::matrix4& mat);
63
//! returns the point which is on the far left upper corner inside the the view frustum.
64
core::vector3df getFarLeftUp() const;
66
//! returns the point which is on the far left bottom corner inside the the view frustum.
67
core::vector3df getFarLeftDown() const;
69
//! returns the point which is on the far right top corner inside the the view frustum.
70
core::vector3df getFarRightUp() const;
72
//! returns the point which is on the far right bottom corner inside the the view frustum.
73
core::vector3df getFarRightDown() const;
75
//! returns the point which is on the near left upper corner inside the the view frustum.
76
core::vector3df getNearLeftUp() const;
78
//! returns the point which is on the near left bottom corner inside the the view frustum.
79
core::vector3df getNearLeftDown() const;
81
//! returns the point which is on the near right top corner inside the the view frustum.
82
core::vector3df getNearRightUp() const;
84
//! returns the point which is on the near right bottom corner inside the the view frustum.
85
core::vector3df getNearRightDown() const;
87
//! returns a bounding box enclosing the whole view frustum
88
const core::aabbox3d<f32> &getBoundingBox() const;
90
//! recalculates the bounding box member based on the planes
91
inline void recalculateBoundingBox();
93
//! get the given state's matrix based on frustum E_TRANSFORMATION_STATE
94
core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state);
96
//! get the given state's matrix based on frustum E_TRANSFORMATION_STATE
97
const core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state) const;
99
//! clips a line to the view frustum.
100
/** \return True if the line was clipped, false if not */
101
bool clipLine(core::line3d<f32>& line) const;
103
//! the position of the camera
104
core::vector3df cameraPosition;
106
//! all planes enclosing the view frustum.
107
core::plane3d<f32> planes[VF_PLANE_COUNT];
109
//! bounding box around the view frustum
110
core::aabbox3d<f32> boundingBox;
113
//! Hold a copy of important transform matrices
114
enum E_TRANSFORMATION_STATE_FRUSTUM
121
//! Hold a copy of important transform matrices
122
core::matrix4 Matrices[ETS_COUNT_FRUSTUM];
127
Copy constructor ViewFrustum
129
inline SViewFrustum::SViewFrustum(const SViewFrustum& other)
131
cameraPosition=other.cameraPosition;
132
boundingBox=other.boundingBox;
135
for (i=0; i<VF_PLANE_COUNT; ++i)
136
planes[i]=other.planes[i];
138
for (i=0; i<ETS_COUNT_FRUSTUM; ++i)
139
Matrices[i]=other.Matrices[i];
142
inline SViewFrustum::SViewFrustum(const core::matrix4& mat)
148
inline void SViewFrustum::transform(const core::matrix4& mat)
150
for (u32 i=0; i<VF_PLANE_COUNT; ++i)
151
mat.transformPlane(planes[i]);
153
mat.transformVect(cameraPosition);
154
recalculateBoundingBox();
158
inline core::vector3df SViewFrustum::getFarLeftUp() const
161
planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
162
planes[scene::SViewFrustum::VF_TOP_PLANE],
163
planes[scene::SViewFrustum::VF_LEFT_PLANE], p);
168
inline core::vector3df SViewFrustum::getFarLeftDown() const
171
planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
172
planes[scene::SViewFrustum::VF_BOTTOM_PLANE],
173
planes[scene::SViewFrustum::VF_LEFT_PLANE], p);
178
inline core::vector3df SViewFrustum::getFarRightUp() const
181
planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
182
planes[scene::SViewFrustum::VF_TOP_PLANE],
183
planes[scene::SViewFrustum::VF_RIGHT_PLANE], p);
188
inline core::vector3df SViewFrustum::getFarRightDown() const
191
planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes(
192
planes[scene::SViewFrustum::VF_BOTTOM_PLANE],
193
planes[scene::SViewFrustum::VF_RIGHT_PLANE], p);
198
inline core::vector3df SViewFrustum::getNearLeftUp() const
201
planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes(
202
planes[scene::SViewFrustum::VF_TOP_PLANE],
203
planes[scene::SViewFrustum::VF_LEFT_PLANE], p);
208
inline core::vector3df SViewFrustum::getNearLeftDown() const
211
planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes(
212
planes[scene::SViewFrustum::VF_BOTTOM_PLANE],
213
planes[scene::SViewFrustum::VF_LEFT_PLANE], p);
218
inline core::vector3df SViewFrustum::getNearRightUp() const
221
planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes(
222
planes[scene::SViewFrustum::VF_TOP_PLANE],
223
planes[scene::SViewFrustum::VF_RIGHT_PLANE], p);
228
inline core::vector3df SViewFrustum::getNearRightDown() const
231
planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes(
232
planes[scene::SViewFrustum::VF_BOTTOM_PLANE],
233
planes[scene::SViewFrustum::VF_RIGHT_PLANE], p);
238
inline const core::aabbox3d<f32> &SViewFrustum::getBoundingBox() const
243
inline void SViewFrustum::recalculateBoundingBox()
245
boundingBox.reset ( cameraPosition );
247
boundingBox.addInternalPoint(getFarLeftUp());
248
boundingBox.addInternalPoint(getFarRightUp());
249
boundingBox.addInternalPoint(getFarLeftDown());
250
boundingBox.addInternalPoint(getFarRightDown());
253
//! This constructor creates a view frustum based on a projection
254
//! and/or view matrix.
255
inline void SViewFrustum::setFrom(const core::matrix4& mat)
257
// left clipping plane
258
planes[VF_LEFT_PLANE].Normal.X = mat[3 ] + mat[0];
259
planes[VF_LEFT_PLANE].Normal.Y = mat[7 ] + mat[4];
260
planes[VF_LEFT_PLANE].Normal.Z = mat[11] + mat[8];
261
planes[VF_LEFT_PLANE].D = mat[15] + mat[12];
263
// right clipping plane
264
planes[VF_RIGHT_PLANE].Normal.X = mat[3 ] - mat[0];
265
planes[VF_RIGHT_PLANE].Normal.Y = mat[7 ] - mat[4];
266
planes[VF_RIGHT_PLANE].Normal.Z = mat[11] - mat[8];
267
planes[VF_RIGHT_PLANE].D = mat[15] - mat[12];
269
// top clipping plane
270
planes[VF_TOP_PLANE].Normal.X = mat[3 ] - mat[1];
271
planes[VF_TOP_PLANE].Normal.Y = mat[7 ] - mat[5];
272
planes[VF_TOP_PLANE].Normal.Z = mat[11] - mat[9];
273
planes[VF_TOP_PLANE].D = mat[15] - mat[13];
275
// bottom clipping plane
276
planes[VF_BOTTOM_PLANE].Normal.X = mat[3 ] + mat[1];
277
planes[VF_BOTTOM_PLANE].Normal.Y = mat[7 ] + mat[5];
278
planes[VF_BOTTOM_PLANE].Normal.Z = mat[11] + mat[9];
279
planes[VF_BOTTOM_PLANE].D = mat[15] + mat[13];
281
// far clipping plane
282
planes[VF_FAR_PLANE].Normal.X = mat[3 ] - mat[2];
283
planes[VF_FAR_PLANE].Normal.Y = mat[7 ] - mat[6];
284
planes[VF_FAR_PLANE].Normal.Z = mat[11] - mat[10];
285
planes[VF_FAR_PLANE].D = mat[15] - mat[14];
287
// near clipping plane
288
planes[VF_NEAR_PLANE].Normal.X = mat[2];
289
planes[VF_NEAR_PLANE].Normal.Y = mat[6];
290
planes[VF_NEAR_PLANE].Normal.Z = mat[10];
291
planes[VF_NEAR_PLANE].D = mat[14];
295
for ( i=0; i != VF_PLANE_COUNT; ++i)
297
const f32 len = -core::reciprocal_squareroot(
298
planes[i].Normal.getLengthSQ());
299
planes[i].Normal *= len;
304
recalculateBoundingBox();
308
View Frustum depends on Projection & View Matrix
310
inline core::matrix4& SViewFrustum::getTransform(video::E_TRANSFORMATION_STATE state )
315
case video::ETS_PROJECTION:
316
index = SViewFrustum::ETS_PROJECTION; break;
317
case video::ETS_VIEW:
318
index = SViewFrustum::ETS_VIEW; break;
322
return Matrices [ index ];
326
View Frustum depends on Projection & View Matrix
328
inline const core::matrix4& SViewFrustum::getTransform(video::E_TRANSFORMATION_STATE state ) const
333
case video::ETS_PROJECTION:
334
index = SViewFrustum::ETS_PROJECTION; break;
335
case video::ETS_VIEW:
336
index = SViewFrustum::ETS_VIEW; break;
340
return Matrices [ index ];
343
//! Clips a line to the frustum
344
inline bool SViewFrustum::clipLine(core::line3d<f32>& line) const
346
bool wasClipped = false;
347
for (u32 i=0; i < VF_PLANE_COUNT; ++i)
349
if (planes[i].classifyPointRelation(line.start) == core::ISREL3D_FRONT)
351
line.start = line.start.getInterpolated(line.end,
352
planes[i].getKnownIntersectionWithLine(line.start, line.end));
355
if (planes[i].classifyPointRelation(line.end) == core::ISREL3D_FRONT)
357
line.end = line.start.getInterpolated(line.end,
358
planes[i].getKnownIntersectionWithLine(line.start, line.end));
366
} // end namespace scene
367
} // end namespace irr