~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to include/SViewFrustum.h

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
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
        four points. A bounding box around these four 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