source: trunk/VUT/work/ogre_changes/OgreMain/include/OgreFrustum.h @ 61

Revision 61, 20.6 KB checked in by mattausch, 20 years ago (diff)
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#ifndef __Frustum_H__
26#define __Frustum_H__
27
28#include "OgrePrerequisites.h"
29#include "OgreMovableObject.h"
30#include "OgreRenderable.h"
31#include "OgreAxisAlignedBox.h"
32#include "OgreVertexIndexData.h"
33#include "OgreMovablePlane.h"
34
35namespace Ogre
36{
37    /** Specifies perspective (realistic) or orthographic (architectural) projection.
38    */
39    enum ProjectionType
40    {
41        PT_ORTHOGRAPHIC,
42        PT_PERSPECTIVE
43    };
44
45    /** Worldspace clipping planes.
46    */
47    enum FrustumPlane
48    {
49        FRUSTUM_PLANE_NEAR   = 0,
50        FRUSTUM_PLANE_FAR    = 1,
51        FRUSTUM_PLANE_LEFT   = 2,
52        FRUSTUM_PLANE_RIGHT  = 3,
53        FRUSTUM_PLANE_TOP    = 4,
54        FRUSTUM_PLANE_BOTTOM = 5
55    };
56
57    /** A frustum represents a pyramid, capped at the near and far end which is
58        used to represent either a visible area or a projection area. Can be used
59        for a number of applications.
60    */
61    class _OgreExport Frustum : public MovableObject, public Renderable
62    {
63    protected:
64        /// Orthographic or perspective?
65        ProjectionType mProjType;
66
67        /// y-direction field-of-view (default 45)
68        Radian mFOVy;
69        /// Far clip distance - default 10000
70        Real mFarDist;
71        /// Near clip distance - default 100
72        Real mNearDist;
73        /// x/y viewport ratio - default 1.3333
74        Real mAspect;
75
76        /// The 6 main clipping planes
77        mutable Plane mFrustumPlanes[6];
78
79        /// Stored versions of parent orientation / position
80        mutable Quaternion mLastParentOrientation;
81        mutable Vector3 mLastParentPosition;
82
83        /// Pre-calced projection matrix
84        mutable Matrix4 mProjMatrix;
85        /// Pre-calced standard projection matrix
86        mutable Matrix4 mStandardProjMatrix;
87        /// Pre-calced view matrix
88        mutable Matrix4 mViewMatrix;
89        /// Something's changed in the frustrum shape?
90        mutable bool mRecalcFrustum;
91        /// Something re the view pos has changed
92        mutable bool mRecalcView;
93
94
95        /** Temp coefficient values calculated from a frustum change,
96            used when establishing the frustum planes when the view changes
97        */
98        mutable Real mCoeffL[2], mCoeffR[2], mCoeffB[2], mCoeffT[2];
99
100
101
102               
103        // Internal functions for calcs
104        virtual void updateFrustum(void) const;
105        virtual void updateView(void) const;
106        virtual bool isViewOutOfDate(void) const;
107        virtual bool isFrustumOutOfDate(void) const;
108        /// Signal to update frustum information.
109        virtual void invalidateFrustum(void) const;
110        /// Signal to update view information.
111        virtual void invalidateView(void) const;
112
113        /// Shared class-level name for Movable type
114        static String msMovableType;
115
116        mutable AxisAlignedBox mBoundingBox;
117        mutable VertexData mVertexData;
118
119        MaterialPtr mMaterial;
120        mutable Vector3 mWorldSpaceCorners[8];
121
122        /// Is this frustum to act as a reflection of itself?
123        bool mReflect;
124                /// Derived reflection matrix
125        mutable Matrix4 mReflectMatrix;
126        /// Fixed reflection plane
127                mutable Plane mReflectPlane;
128                /// Pointer to a reflection plane (automatically updated)
129                const MovablePlane* mLinkedReflectPlane;
130                /// Record of the last world-space reflection plane info used
131                mutable Plane mLastLinkedReflectionPlane;
132               
133        /// Is this frustum using an oblique depth projection?
134                bool mObliqueDepthProjection;
135                /// Fixed oblique projection plane
136                mutable Plane mObliqueProjPlane;
137                /// Pointer to oblique projection plane (automatically updated)
138                const MovablePlane* mLinkedObliqueProjPlane;
139                /// Record of the last world-space oblique depth projection plane info used
140                mutable Plane mLastLinkedObliqueProjPlane;
141
142               
143                /** Get the derived position of this frustum. */
144        virtual const Vector3& getPositionForViewUpdate(void) const;
145        /** Get the derived orientation of this frustum. */
146        virtual const Quaternion& getOrientationForViewUpdate(void) const;
147
148
149    public:
150
151        Frustum();
152        virtual ~Frustum();
153        /** Sets the Y-dimension Field Of View (FOV) of the frustum.
154            @remarks
155                Field Of View (FOV) is the angle made between the frustum's position, and the edges
156                of the 'screen' onto which the scene is projected. High values (90+ degrees) result in a wide-angle,
157                fish-eye kind of view, low values (30- degrees) in a stretched, telescopic kind of view. Typical values
158                are between 45 and 60 degrees.
159            @par
160                This value represents the VERTICAL field-of-view. The horizontal field of view is calculated from
161                this depending on the dimensions of the viewport (they will only be the same if the viewport is square).
162            @note
163                Setting the FOV overrides the value supplied for frustum::setNearClipPlane.
164         */
165        virtual void setFOVy(const Radian& fovy);
166#ifndef OGRE_FORCE_ANGLE_TYPES
167        inline void setFOVy(Real fovy) {
168            setFOVy ( Angle(fovy) );
169        }
170#endif//OGRE_FORCE_ANGLE_TYPES
171
172        /** Retrieves the frustums Y-dimension Field Of View (FOV).
173        */
174        virtual const Radian& getFOVy(void) const;
175
176        /** Sets the position of the near clipping plane.
177            @remarks
178                The position of the near clipping plane is the distance from the frustums position to the screen
179                on which the world is projected. The near plane distance, combined with the field-of-view and the
180                aspect ratio, determines the size of the viewport through which the world is viewed (in world
181                co-ordinates). Note that this world viewport is different to a screen viewport, which has it's
182                dimensions expressed in pixels. The frustums viewport should have the same aspect ratio as the
183                screen viewport it renders into to avoid distortion.
184            @param
185                near The distance to the near clipping plane from the frustum in world coordinates.
186         */
187        virtual void setNearClipDistance(Real nearDist);
188
189        /** Sets the position of the near clipping plane.
190        */
191        virtual Real getNearClipDistance(void) const;
192
193        /** Sets the distance to the far clipping plane.
194            @remarks
195                The view frustrum is a pyramid created from the frustum position and the edges of the viewport.
196                This method sets the distance for the far end of that pyramid.
197                Different applications need different values: e.g. a flight sim
198                needs a much further far clipping plane than a first-person
199                shooter. An important point here is that the larger the ratio
200                between near and far clipping planes, the lower the accuracy of
201                the Z-buffer used to depth-cue pixels. This is because the
202                Z-range is limited to the size of the Z buffer (16 or 32-bit)
203                and the max values must be spread over the gap between near and
204                far clip planes. As it happens, you can affect the accuracy far
205                more by altering the near distance rather than the far distance,
206                but keep this in mind.
207            @param
208                far The distance to the far clipping plane from the frustum in
209                world coordinates.If you specify 0, this means an infinite view
210                distance which is useful especially when projecting shadows; but
211                be careful not to use a near distance too close.
212        */
213        virtual void setFarClipDistance(Real farDist);
214
215        /** Retrieves the distance from the frustum to the far clipping plane.
216        */
217        virtual Real getFarClipDistance(void) const;
218
219        /** Sets the aspect ratio for the frustum viewport.
220            @remarks
221                The ratio between the x and y dimensions of the rectangular area visible through the frustum
222                is known as aspect ratio: aspect = width / height .
223            @par
224                The default for most fullscreen windows is 1.3333 - this is also assumed by Ogre unless you
225                use this method to state otherwise.
226        */
227        virtual void setAspectRatio(Real ratio);
228
229        /** Retreives the current aspect ratio.
230        */
231        virtual Real getAspectRatio(void) const;
232
233        /** Gets the projection matrix for this frustum. Mainly for use by OGRE internally.
234        @remarks
235            This method retrieves the rendering-API dependent version of the projection
236            matrix. If you want a 'typical' projection matrix then use
237            getStandardProjectionMatrix.
238
239        */
240        virtual const Matrix4& getProjectionMatrix(void) const;
241        /** Gets the 'standard' projection matrix for this frustum, ie the
242        projection matrix which conforms to standard right-handed rules.
243        @remarks
244            This differs from the rendering-API dependent getProjectionMatrix
245            in that it always returns a right-handed projection matrix result
246            no matter what rendering API is being used - this is required for
247            vertex and fragment programs for example. However, the resulting depth
248            range may still vary between render systems since D3D uses [0,1] and
249            GL uses [-1,1], and the range must be kept the same between programmable
250            and fixed-function pipelines.
251        */
252        virtual const Matrix4& getStandardProjectionMatrix(void) const;
253
254        /** Gets the view matrix for this frustum. Mainly for use by OGRE internally.
255        */
256        virtual const Matrix4& getViewMatrix(void) const;
257
258        /** Retrieves a specified plane of the frustum.
259            @remarks
260                Gets a reference to one of the planes which make up the frustum frustum, e.g. for clipping purposes.
261        */
262        virtual const Plane& getFrustumPlane( unsigned short plane ) const;
263
264        /** Tests whether the given container is visible in the Frustum.
265            @param
266                bound Bounding box to be checked
267            @param
268                culledBy Optional pointer to an int which will be filled by the plane number which culled
269                the box if the result was false;
270            @returns
271                If the box was visible, true is returned.
272            @par
273                Otherwise, false is returned.
274        */
275        virtual bool isVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy = 0) const;
276
277        /** Tests whether the given container is visible in the Frustum.
278            @param
279                bound Bounding sphere to be checked
280            @param
281                culledBy Optional pointer to an int which will be filled by the plane number which culled
282                the box if the result was false;
283            @returns
284                If the sphere was visible, true is returned.
285            @par
286                Otherwise, false is returned.
287        */
288        virtual bool isVisible(const Sphere& bound, FrustumPlane* culledBy = 0) const;
289
290        /** Tests whether the given vertex is visible in the Frustum.
291            @param
292                vert Vertex to be checked
293            @param
294                culledBy Optional pointer to an int which will be filled by the plane number which culled
295                the box if the result was false;
296            @returns
297                If the box was visible, true is returned.
298            @par
299                Otherwise, false is returned.
300        */
301        virtual bool isVisible(const Vector3& vert, FrustumPlane* culledBy = 0) const;
302
303
304        /** Overridden from MovableObject */
305        const AxisAlignedBox& getBoundingBox(void) const;
306
307        /** Overridden from MovableObject */
308                Real getBoundingRadius(void) const;
309
310                /** Overridden from MovableObject */
311        void _updateRenderQueue(RenderQueue* queue);
312
313        /** Overridden from MovableObject */
314        const String& getMovableType(void) const;
315
316        /** Overridden from MovableObject */
317        const String& getName(void) const;
318
319        /** Overridden from MovableObject */
320        void _notifyCurrentCamera(Camera* cam);
321
322        /** Overridden from Renderable */
323        const MaterialPtr& getMaterial(void) const;
324
325        /** Overridden from Renderable */
326        void getRenderOperation(RenderOperation& op);
327
328        /** Overridden from Renderable */
329        void getWorldTransforms(Matrix4* xform) const;
330
331        /** Overridden from Renderable */
332        const Quaternion& getWorldOrientation(void) const;
333
334        /** Overridden from Renderable */
335        const Vector3& getWorldPosition(void) const;
336
337        /** Overridden from Renderable */
338        Real getSquaredViewDepth(const Camera* cam) const;
339
340        /** Overridden from Renderable */
341        const LightList& getLights(void) const;
342
343        /** Gets the world space corners of the frustum.
344        @remarks
345            The corners are ordered as follows: top-right near,
346            top-left near, bottom-left near, bottom-right near,
347            top-right far, top-left far, bottom-left far, bottom-right far.
348        */
349        virtual const Vector3* getWorldSpaceCorners(void) const;
350
351        /** Sets the type of projection to use (orthographic or perspective). Default is perspective.
352        */
353        virtual void setProjectionType(ProjectionType pt);
354
355        /** Retrieves info on the type of projection used (orthographic or perspective).
356        */
357        virtual ProjectionType getProjectionType(void) const;
358
359        /** Modifies this frustum so it always renders from the reflection of itself through the
360        plane specified.
361        @remarks
362        This is obviously useful for performing planar reflections.
363        */
364        virtual void enableReflection(const Plane& p);
365        /** Modifies this frustum so it always renders from the reflection of itself through the
366        plane specified. Note that this version of the method links to a plane
367                so that changes to it are picked up automatically. It is important that
368                this plane continues to exist whilst this object does; do not destroy
369                the plane before the frustum.
370        @remarks
371        This is obviously useful for performing planar reflections.
372        */
373        virtual void enableReflection(const MovablePlane* p);
374
375        /** Disables reflection modification previously turned on with enableReflection */
376        virtual void disableReflection(void);
377
378        /// Returns whether this frustum is being reflected
379        virtual bool isReflected(void) const { return mReflect; }
380        /// Returns the reflection matrix of the frustum if appropriate
381        virtual const Matrix4& getReflectionMatrix(void) const { return mReflectMatrix; }
382        /// Returns the reflection plane of the frustum if appropriate
383        virtual const Plane& getReflectionPlane(void) const { return mReflectPlane; }
384
385        /** Project a sphere onto the near plane and get the bounding rectangle.
386        @param sphere The world-space sphere to project
387        @param radius Radius of the sphere
388        @param left, top, right, bottom Pointers to destination values, these
389            will be completed with the normalised device coordinates (in the
390            range {-1,1})
391        @returns true if the sphere was projected to a subset of the near plane,
392            false if the entire near plane was contained
393        */
394        virtual bool projectSphere(const Sphere& sphere,
395            Real* left, Real* top, Real* right, Real* bottom) const;
396
397
398                /** Links the frustum to a custom near clip plane, which can be used
399                        to clip geometry in a custom manner without using user clip planes.
400                @remarks
401                        There are several applications for clipping a scene arbitrarily by
402                        a single plane; the most common is when rendering a reflection to
403                        a texture, and you only want to render geometry that is above the
404                        water plane (to do otherwise results in artefacts). Whilst it is
405                        possible to use user clip planes, they are not supported on all
406                        cards, and sometimes are not hardware accelerated when they are
407                        available. Instead, where a single clip plane is involved, this
408                        technique uses a 'fudging' of the near clip plane, which is
409                        available and fast on all hardware, to perform as the arbitrary
410                        clip plane. This does change the shape of the frustum, leading
411                        to some depth buffer loss of precision, but for many of the uses of
412                        this technique that is not an issue.
413                @par
414                        This version of the method links to a plane, rather than requiring
415                        a by-value plane definition, and therefore you can
416                        make changes to the plane (e.g. by moving / rotating the node it is
417                        attached to) and they will automatically affect this object.
418                @note This technique only works for perspective projection.
419                @param plane The plane to link to to perform the clipping. This plane
420                        must continue to exist while the camera is linked to it; do not
421                        destroy it before the frustum.
422                */
423                virtual void enableCustomNearClipPlane(const MovablePlane* plane);
424                /** Links the frustum to a custom near clip plane, which can be used
425                        to clip geometry in a custom manner without using user clip planes.
426                @remarks
427                        There are several applications for clipping a scene arbitrarily by
428                        a single plane; the most common is when rendering a reflection to 
429                        a texture, and you only want to render geometry that is above the
430                        water plane (to do otherwise results in artefacts). Whilst it is
431                        possible to use user clip planes, they are not supported on all
432                        cards, and sometimes are not hardware accelerated when they are
433                        available. Instead, where a single clip plane is involved, this
434                        technique uses a 'fudging' of the near clip plane, which is
435                        available and fast on all hardware, to perform as the arbitrary
436                        clip plane. This does change the shape of the frustum, leading
437                        to some depth buffer loss of precision, but for many of the uses of
438                        this technique that is not an issue.
439                @note This technique only works for perspective projection.
440                @param plane The plane to link to to perform the clipping. This plane
441                        must continue to exist while the camera is linked to it; do not
442                        destroy it before the frustum.
443                */
444                virtual void enableCustomNearClipPlane(const Plane& plane);
445                /** Disables any custom near clip plane. */
446                virtual void disableCustomNearClipPlane(void);
447               
448
449        /// Small constant used to reduce far plane projection to avoid inaccuracies
450        static const Real INFINITE_FAR_PLANE_ADJUST;
451
452#ifdef GTP_VISIBILITY_MODIFIED_OGRE
453                //added by matt: 050405
454                /** Tests whether the given container is visible in the Frustum.
455            @param
456                bound Bounding box to be checked
457            @param
458                culledBy Optional pointer to an int which will be filled by the plane number which culled
459                the box if the result was false;
460                        @param
461                                intersects returns the information if the box intersects the near plane.
462            @returns
463                If the box was visible, true is returned.
464            @par
465                Otherwise, false is returned.
466        */
467        virtual bool isVisible(const AxisAlignedBox& bound, bool &intersects, FrustumPlane* culledBy = 0) const;
468#endif // GTP_VISIBILITY_MODIFIED_OGRE
469    };
470
471
472}
473
474#endif
Note: See TracBrowser for help on using the repository browser.