diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/include/SViewFrustum.h | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/include/SViewFrustum.h b/libraries/irrlicht-1.8/include/SViewFrustum.h new file mode 100644 index 0000000..88d7e2e --- /dev/null +++ b/libraries/irrlicht-1.8/include/SViewFrustum.h | |||
@@ -0,0 +1,370 @@ | |||
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 | |||
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 | eight points. A bounding box around these eight points is also stored in | ||
23 | this structure. | ||
24 | */ | ||
25 | struct SViewFrustum | ||
26 | { | ||
27 | enum VFPLANES | ||
28 | { | ||
29 | //! Far plane of the frustum. That is the plane farest away from the eye. | ||
30 | VF_FAR_PLANE = 0, | ||
31 | //! Near plane of the frustum. That is the plane nearest to the eye. | ||
32 | VF_NEAR_PLANE, | ||
33 | //! Left plane of the frustum. | ||
34 | VF_LEFT_PLANE, | ||
35 | //! Right plane of the frustum. | ||
36 | VF_RIGHT_PLANE, | ||
37 | //! Bottom plane of the frustum. | ||
38 | VF_BOTTOM_PLANE, | ||
39 | //! Top plane of the frustum. | ||
40 | VF_TOP_PLANE, | ||
41 | |||
42 | //! Amount of planes enclosing the view frustum. Should be 6. | ||
43 | VF_PLANE_COUNT | ||
44 | }; | ||
45 | |||
46 | |||
47 | //! Default Constructor | ||
48 | SViewFrustum() {} | ||
49 | |||
50 | //! Copy Constructor | ||
51 | SViewFrustum(const SViewFrustum& other); | ||
52 | |||
53 | //! This constructor creates a view frustum based on a projection and/or view matrix. | ||
54 | SViewFrustum(const core::matrix4& mat); | ||
55 | |||
56 | //! This constructor creates a view frustum based on a projection and/or view matrix. | ||
57 | inline void setFrom(const core::matrix4& mat); | ||
58 | |||
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); | ||
62 | |||
63 | //! returns the point which is on the far left upper corner inside the the view frustum. | ||
64 | core::vector3df getFarLeftUp() const; | ||
65 | |||
66 | //! returns the point which is on the far left bottom corner inside the the view frustum. | ||
67 | core::vector3df getFarLeftDown() const; | ||
68 | |||
69 | //! returns the point which is on the far right top corner inside the the view frustum. | ||
70 | core::vector3df getFarRightUp() const; | ||
71 | |||
72 | //! returns the point which is on the far right bottom corner inside the the view frustum. | ||
73 | core::vector3df getFarRightDown() const; | ||
74 | |||
75 | //! returns the point which is on the near left upper corner inside the the view frustum. | ||
76 | core::vector3df getNearLeftUp() const; | ||
77 | |||
78 | //! returns the point which is on the near left bottom corner inside the the view frustum. | ||
79 | core::vector3df getNearLeftDown() const; | ||
80 | |||
81 | //! returns the point which is on the near right top corner inside the the view frustum. | ||
82 | core::vector3df getNearRightUp() const; | ||
83 | |||
84 | //! returns the point which is on the near right bottom corner inside the the view frustum. | ||
85 | core::vector3df getNearRightDown() const; | ||
86 | |||
87 | //! returns a bounding box enclosing the whole view frustum | ||
88 | const core::aabbox3d<f32> &getBoundingBox() const; | ||
89 | |||
90 | //! recalculates the bounding box member based on the planes | ||
91 | inline void recalculateBoundingBox(); | ||
92 | |||
93 | //! get the given state's matrix based on frustum E_TRANSFORMATION_STATE | ||
94 | core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state); | ||
95 | |||
96 | //! get the given state's matrix based on frustum E_TRANSFORMATION_STATE | ||
97 | const core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state) const; | ||
98 | |||
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; | ||
102 | |||
103 | //! the position of the camera | ||
104 | core::vector3df cameraPosition; | ||
105 | |||
106 | //! all planes enclosing the view frustum. | ||
107 | core::plane3d<f32> planes[VF_PLANE_COUNT]; | ||
108 | |||
109 | //! bounding box around the view frustum | ||
110 | core::aabbox3d<f32> boundingBox; | ||
111 | |||
112 | private: | ||
113 | //! Hold a copy of important transform matrices | ||
114 | enum E_TRANSFORMATION_STATE_FRUSTUM | ||
115 | { | ||
116 | ETS_VIEW = 0, | ||
117 | ETS_PROJECTION = 1, | ||
118 | ETS_COUNT_FRUSTUM | ||
119 | }; | ||
120 | |||
121 | //! Hold a copy of important transform matrices | ||
122 | core::matrix4 Matrices[ETS_COUNT_FRUSTUM]; | ||
123 | }; | ||
124 | |||
125 | |||
126 | /*! | ||
127 | Copy constructor ViewFrustum | ||
128 | */ | ||
129 | inline SViewFrustum::SViewFrustum(const SViewFrustum& other) | ||
130 | { | ||
131 | cameraPosition=other.cameraPosition; | ||
132 | boundingBox=other.boundingBox; | ||
133 | |||
134 | u32 i; | ||
135 | for (i=0; i<VF_PLANE_COUNT; ++i) | ||
136 | planes[i]=other.planes[i]; | ||
137 | |||
138 | for (i=0; i<ETS_COUNT_FRUSTUM; ++i) | ||
139 | Matrices[i]=other.Matrices[i]; | ||
140 | } | ||
141 | |||
142 | inline SViewFrustum::SViewFrustum(const core::matrix4& mat) | ||
143 | { | ||
144 | setFrom ( mat ); | ||
145 | } | ||
146 | |||
147 | |||
148 | inline void SViewFrustum::transform(const core::matrix4& mat) | ||
149 | { | ||
150 | for (u32 i=0; i<VF_PLANE_COUNT; ++i) | ||
151 | mat.transformPlane(planes[i]); | ||
152 | |||
153 | mat.transformVect(cameraPosition); | ||
154 | recalculateBoundingBox(); | ||
155 | } | ||
156 | |||
157 | |||
158 | inline core::vector3df SViewFrustum::getFarLeftUp() const | ||
159 | { | ||
160 | core::vector3df p; | ||
161 | planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes( | ||
162 | planes[scene::SViewFrustum::VF_TOP_PLANE], | ||
163 | planes[scene::SViewFrustum::VF_LEFT_PLANE], p); | ||
164 | |||
165 | return p; | ||
166 | } | ||
167 | |||
168 | inline core::vector3df SViewFrustum::getFarLeftDown() const | ||
169 | { | ||
170 | core::vector3df p; | ||
171 | planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes( | ||
172 | planes[scene::SViewFrustum::VF_BOTTOM_PLANE], | ||
173 | planes[scene::SViewFrustum::VF_LEFT_PLANE], p); | ||
174 | |||
175 | return p; | ||
176 | } | ||
177 | |||
178 | inline core::vector3df SViewFrustum::getFarRightUp() const | ||
179 | { | ||
180 | core::vector3df p; | ||
181 | planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes( | ||
182 | planes[scene::SViewFrustum::VF_TOP_PLANE], | ||
183 | planes[scene::SViewFrustum::VF_RIGHT_PLANE], p); | ||
184 | |||
185 | return p; | ||
186 | } | ||
187 | |||
188 | inline core::vector3df SViewFrustum::getFarRightDown() const | ||
189 | { | ||
190 | core::vector3df p; | ||
191 | planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes( | ||
192 | planes[scene::SViewFrustum::VF_BOTTOM_PLANE], | ||
193 | planes[scene::SViewFrustum::VF_RIGHT_PLANE], p); | ||
194 | |||
195 | return p; | ||
196 | } | ||
197 | |||
198 | inline core::vector3df SViewFrustum::getNearLeftUp() const | ||
199 | { | ||
200 | core::vector3df p; | ||
201 | planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes( | ||
202 | planes[scene::SViewFrustum::VF_TOP_PLANE], | ||
203 | planes[scene::SViewFrustum::VF_LEFT_PLANE], p); | ||
204 | |||
205 | return p; | ||
206 | } | ||
207 | |||
208 | inline core::vector3df SViewFrustum::getNearLeftDown() const | ||
209 | { | ||
210 | core::vector3df p; | ||
211 | planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes( | ||
212 | planes[scene::SViewFrustum::VF_BOTTOM_PLANE], | ||
213 | planes[scene::SViewFrustum::VF_LEFT_PLANE], p); | ||
214 | |||
215 | return p; | ||
216 | } | ||
217 | |||
218 | inline core::vector3df SViewFrustum::getNearRightUp() const | ||
219 | { | ||
220 | core::vector3df p; | ||
221 | planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes( | ||
222 | planes[scene::SViewFrustum::VF_TOP_PLANE], | ||
223 | planes[scene::SViewFrustum::VF_RIGHT_PLANE], p); | ||
224 | |||
225 | return p; | ||
226 | } | ||
227 | |||
228 | inline core::vector3df SViewFrustum::getNearRightDown() const | ||
229 | { | ||
230 | core::vector3df p; | ||
231 | planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes( | ||
232 | planes[scene::SViewFrustum::VF_BOTTOM_PLANE], | ||
233 | planes[scene::SViewFrustum::VF_RIGHT_PLANE], p); | ||
234 | |||
235 | return p; | ||
236 | } | ||
237 | |||
238 | inline const core::aabbox3d<f32> &SViewFrustum::getBoundingBox() const | ||
239 | { | ||
240 | return boundingBox; | ||
241 | } | ||
242 | |||
243 | inline void SViewFrustum::recalculateBoundingBox() | ||
244 | { | ||
245 | boundingBox.reset ( cameraPosition ); | ||
246 | |||
247 | boundingBox.addInternalPoint(getFarLeftUp()); | ||
248 | boundingBox.addInternalPoint(getFarRightUp()); | ||
249 | boundingBox.addInternalPoint(getFarLeftDown()); | ||
250 | boundingBox.addInternalPoint(getFarRightDown()); | ||
251 | } | ||
252 | |||
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) | ||
256 | { | ||
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]; | ||
262 | |||
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]; | ||
268 | |||
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]; | ||
274 | |||
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]; | ||
280 | |||
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]; | ||
286 | |||
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]; | ||
292 | |||
293 | // normalize normals | ||
294 | u32 i; | ||
295 | for ( i=0; i != VF_PLANE_COUNT; ++i) | ||
296 | { | ||
297 | const f32 len = -core::reciprocal_squareroot( | ||
298 | planes[i].Normal.getLengthSQ()); | ||
299 | planes[i].Normal *= len; | ||
300 | planes[i].D *= len; | ||
301 | } | ||
302 | |||
303 | // make bounding box | ||
304 | recalculateBoundingBox(); | ||
305 | } | ||
306 | |||
307 | /*! | ||
308 | View Frustum depends on Projection & View Matrix | ||
309 | */ | ||
310 | inline core::matrix4& SViewFrustum::getTransform(video::E_TRANSFORMATION_STATE state ) | ||
311 | { | ||
312 | u32 index = 0; | ||
313 | switch ( state ) | ||
314 | { | ||
315 | case video::ETS_PROJECTION: | ||
316 | index = SViewFrustum::ETS_PROJECTION; break; | ||
317 | case video::ETS_VIEW: | ||
318 | index = SViewFrustum::ETS_VIEW; break; | ||
319 | default: | ||
320 | break; | ||
321 | } | ||
322 | return Matrices [ index ]; | ||
323 | } | ||
324 | |||
325 | /*! | ||
326 | View Frustum depends on Projection & View Matrix | ||
327 | */ | ||
328 | inline const core::matrix4& SViewFrustum::getTransform(video::E_TRANSFORMATION_STATE state ) const | ||
329 | { | ||
330 | u32 index = 0; | ||
331 | switch ( state ) | ||
332 | { | ||
333 | case video::ETS_PROJECTION: | ||
334 | index = SViewFrustum::ETS_PROJECTION; break; | ||
335 | case video::ETS_VIEW: | ||
336 | index = SViewFrustum::ETS_VIEW; break; | ||
337 | default: | ||
338 | break; | ||
339 | } | ||
340 | return Matrices [ index ]; | ||
341 | } | ||
342 | |||
343 | //! Clips a line to the frustum | ||
344 | inline bool SViewFrustum::clipLine(core::line3d<f32>& line) const | ||
345 | { | ||
346 | bool wasClipped = false; | ||
347 | for (u32 i=0; i < VF_PLANE_COUNT; ++i) | ||
348 | { | ||
349 | if (planes[i].classifyPointRelation(line.start) == core::ISREL3D_FRONT) | ||
350 | { | ||
351 | line.start = line.start.getInterpolated(line.end, | ||
352 | planes[i].getKnownIntersectionWithLine(line.start, line.end)); | ||
353 | wasClipped = true; | ||
354 | } | ||
355 | if (planes[i].classifyPointRelation(line.end) == core::ISREL3D_FRONT) | ||
356 | { | ||
357 | line.end = line.start.getInterpolated(line.end, | ||
358 | planes[i].getKnownIntersectionWithLine(line.start, line.end)); | ||
359 | wasClipped = true; | ||
360 | } | ||
361 | } | ||
362 | return wasClipped; | ||
363 | } | ||
364 | |||
365 | |||
366 | } // end namespace scene | ||
367 | } // end namespace irr | ||
368 | |||
369 | #endif | ||
370 | |||