Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/include/OgreFrustum.h @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 26.5 KB
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-2006 Torus Knot Software Ltd
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
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#ifndef __Frustum_H__
30#define __Frustum_H__
31
32#include "OgrePrerequisites.h"
33#include "OgreMovableObject.h"
34#include "OgreRenderable.h"
35#include "OgreAxisAlignedBox.h"
36#include "OgreVertexIndexData.h"
37#include "OgreMovablePlane.h"
38
39namespace Ogre
40{
41    /** Specifies perspective (realistic) or orthographic (architectural) projection.
42    */
43    enum ProjectionType
44    {
45        PT_ORTHOGRAPHIC,
46        PT_PERSPECTIVE
47    };
48
49    /** Worldspace clipping planes.
50    */
51    enum FrustumPlane
52    {
53        FRUSTUM_PLANE_NEAR   = 0,
54        FRUSTUM_PLANE_FAR    = 1,
55        FRUSTUM_PLANE_LEFT   = 2,
56        FRUSTUM_PLANE_RIGHT  = 3,
57        FRUSTUM_PLANE_TOP    = 4,
58        FRUSTUM_PLANE_BOTTOM = 5
59    };
60
61    /** A frustum represents a pyramid, capped at the near and far end which is
62        used to represent either a visible area or a projection area. Can be used
63        for a number of applications.
64    */
65    class _OgreExport Frustum : public MovableObject, public Renderable
66    {
67    protected:
68        /// Orthographic or perspective?
69        ProjectionType mProjType;
70
71        /// y-direction field-of-view (default 45)
72        Radian mFOVy;
73        /// Far clip distance - default 10000
74        Real mFarDist;
75        /// Near clip distance - default 100
76        Real mNearDist;
77        /// x/y viewport ratio - default 1.3333
78        Real mAspect;
79        /// Off-axis frustum center offset - default (0.0, 0.0)
80        Vector2 mFrustumOffset;
81        /// Focal length of frustum (for stereo rendering, defaults to 1.0)
82        Real mFocalLength;
83
84        /// The 6 main clipping planes
85        mutable Plane mFrustumPlanes[6];
86
87        /// Stored versions of parent orientation / position
88        mutable Quaternion mLastParentOrientation;
89        mutable Vector3 mLastParentPosition;
90
91        /// Pre-calced projection matrix for the specific render system
92        mutable Matrix4 mProjMatrixRS;
93        /// Pre-calced standard projection matrix but with render system depth range
94        mutable Matrix4 mProjMatrixRSDepth;
95        /// Pre-calced standard projection matrix
96        mutable Matrix4 mProjMatrix;
97        /// Pre-calced view matrix
98        mutable Matrix4 mViewMatrix;
99        /// Something's changed in the frustrum shape?
100        mutable bool mRecalcFrustum;
101        /// Something re the view pos has changed
102        mutable bool mRecalcView;
103        /// Something re the frustum planes has changed
104        mutable bool mRecalcFrustumPlanes;
105        /// Something re the world space corners has changed
106        mutable bool mRecalcWorldSpaceCorners;
107        /// Something re the vertex data has changed
108        mutable bool mRecalcVertexData;
109                /// Are we using a custom view matrix?
110                bool mCustomViewMatrix;
111                /// Are we using a custom projection matrix?
112                bool mCustomProjMatrix;
113
114               
115        // Internal functions for calcs
116        virtual void calcProjectionParameters(Real& left, Real& right, Real& bottom, Real& top) const;
117                /// Update frustum if out of date
118        virtual void updateFrustum(void) const;
119                /// Update view if out of date
120        virtual void updateView(void) const;
121                /// Implementation of updateFrustum (called if out of date)
122                virtual void updateFrustumImpl(void) const;
123                /// Implementation of updateView (called if out of date)
124                virtual void updateViewImpl(void) const;
125        virtual void updateFrustumPlanes(void) const;
126                /// Implementation of updateFrustumPlanes (called if out of date)
127                virtual void updateFrustumPlanesImpl(void) const;
128        virtual void updateWorldSpaceCorners(void) const;
129                /// Implementation of updateWorldSpaceCorners (called if out of date)
130                virtual void updateWorldSpaceCornersImpl(void) const;
131        virtual void updateVertexData(void) const;
132        virtual bool isViewOutOfDate(void) const;
133        virtual bool isFrustumOutOfDate(void) const;
134        /// Signal to update frustum information.
135        virtual void invalidateFrustum(void) const;
136        /// Signal to update view information.
137        virtual void invalidateView(void) const;
138
139        /// Shared class-level name for Movable type
140        static String msMovableType;
141
142        mutable AxisAlignedBox mBoundingBox;
143        mutable VertexData mVertexData;
144
145        MaterialPtr mMaterial;
146        mutable Vector3 mWorldSpaceCorners[8];
147
148        /// Is this frustum to act as a reflection of itself?
149        bool mReflect;
150                /// Derived reflection matrix
151        mutable Matrix4 mReflectMatrix;
152        /// Fixed reflection plane
153                mutable Plane mReflectPlane;
154                /// Pointer to a reflection plane (automatically updated)
155                const MovablePlane* mLinkedReflectPlane;
156                /// Record of the last world-space reflection plane info used
157                mutable Plane mLastLinkedReflectionPlane;
158               
159        /// Is this frustum using an oblique depth projection?
160                bool mObliqueDepthProjection;
161                /// Fixed oblique projection plane
162                mutable Plane mObliqueProjPlane;
163                /// Pointer to oblique projection plane (automatically updated)
164                const MovablePlane* mLinkedObliqueProjPlane;
165                /// Record of the last world-space oblique depth projection plane info used
166                mutable Plane mLastLinkedObliqueProjPlane;
167
168               
169                /** Get the derived position of this frustum. */
170        virtual const Vector3& getPositionForViewUpdate(void) const;
171        /** Get the derived orientation of this frustum. */
172        virtual const Quaternion& getOrientationForViewUpdate(void) const;
173
174
175    public:
176
177        Frustum();
178        virtual ~Frustum();
179        /** Sets the Y-dimension Field Of View (FOV) of the frustum.
180            @remarks
181                Field Of View (FOV) is the angle made between the frustum's position, and the edges
182                of the 'screen' onto which the scene is projected. High values (90+ degrees) result in a wide-angle,
183                fish-eye kind of view, low values (30- degrees) in a stretched, telescopic kind of view. Typical values
184                are between 45 and 60 degrees.
185            @par
186                This value represents the VERTICAL field-of-view. The horizontal field of view is calculated from
187                this depending on the dimensions of the viewport (they will only be the same if the viewport is square).
188            @note
189                Setting the FOV overrides the value supplied for frustum::setNearClipPlane.
190         */
191        virtual void setFOVy(const Radian& fovy);
192#ifndef OGRE_FORCE_ANGLE_TYPES
193        inline void setFOVy(Real fovy) {
194            setFOVy ( Angle(fovy) );
195        }
196#endif//OGRE_FORCE_ANGLE_TYPES
197
198        /** Retrieves the frustums Y-dimension Field Of View (FOV).
199        */
200        virtual const Radian& getFOVy(void) const;
201
202        /** Sets the position of the near clipping plane.
203            @remarks
204                The position of the near clipping plane is the distance from the frustums position to the screen
205                on which the world is projected. The near plane distance, combined with the field-of-view and the
206                aspect ratio, determines the size of the viewport through which the world is viewed (in world
207                co-ordinates). Note that this world viewport is different to a screen viewport, which has it's
208                dimensions expressed in pixels. The frustums viewport should have the same aspect ratio as the
209                screen viewport it renders into to avoid distortion.
210            @param
211                near The distance to the near clipping plane from the frustum in world coordinates.
212         */
213        virtual void setNearClipDistance(Real nearDist);
214
215        /** Sets the position of the near clipping plane.
216        */
217        virtual Real getNearClipDistance(void) const;
218
219        /** Sets the distance to the far clipping plane.
220            @remarks
221                The view frustrum is a pyramid created from the frustum position and the edges of the viewport.
222                This method sets the distance for the far end of that pyramid.
223                Different applications need different values: e.g. a flight sim
224                needs a much further far clipping plane than a first-person
225                shooter. An important point here is that the larger the ratio
226                between near and far clipping planes, the lower the accuracy of
227                the Z-buffer used to depth-cue pixels. This is because the
228                Z-range is limited to the size of the Z buffer (16 or 32-bit)
229                and the max values must be spread over the gap between near and
230                far clip planes. As it happens, you can affect the accuracy far
231                more by altering the near distance rather than the far distance,
232                but keep this in mind.
233            @param
234                far The distance to the far clipping plane from the frustum in
235                world coordinates.If you specify 0, this means an infinite view
236                distance which is useful especially when projecting shadows; but
237                be careful not to use a near distance too close.
238        */
239        virtual void setFarClipDistance(Real farDist);
240
241        /** Retrieves the distance from the frustum to the far clipping plane.
242        */
243        virtual Real getFarClipDistance(void) const;
244
245        /** Sets the aspect ratio for the frustum viewport.
246            @remarks
247                The ratio between the x and y dimensions of the rectangular area visible through the frustum
248                is known as aspect ratio: aspect = width / height .
249            @par
250                The default for most fullscreen windows is 1.3333 - this is also assumed by Ogre unless you
251                use this method to state otherwise.
252        */
253        virtual void setAspectRatio(Real ratio);
254
255        /** Retreives the current aspect ratio.
256        */
257        virtual Real getAspectRatio(void) const;
258
259        /** Sets frustum offsets, used in stereo rendering.
260            @remarks
261                You can set both horizontal and vertical plane offsets of "eye"; in
262                stereo rendering frustum is moved in horizontal plane. To be able to
263                render from two "eyes" you'll need two cameras rendering on two
264                RenderTargets.
265            @par
266                The frustum offsets is in world coordinates, and default to (0, 0) - no offsets.
267            @param
268                offset The horizontal and vertical plane offsets.
269        */
270        virtual void setFrustumOffset(const Vector2& offset);
271
272        /** Sets frustum offsets, used in stereo rendering.
273            @remarks
274                You can set both horizontal and vertical plane offsets of "eye"; in
275                stereo rendering frustum is moved in horizontal plane. To be able to
276                render from two "eyes" you'll need two cameras rendering on two
277                RenderTargets.
278            @par
279                The frustum offsets is in world coordinates, and default to (0, 0) - no offsets.
280            @param
281                horizontal The horizontal plane offset.
282            @param
283                vertical The vertical plane offset.
284        */
285        virtual void setFrustumOffset(Real horizontal = 0.0, Real vertical = 0.0);
286
287        /** Retreives the frustum offsets.
288        */
289        virtual const Vector2& getFrustumOffset() const;
290
291        /** Sets frustum focal length (used in stereo rendering).
292            @param
293                focalLength The distance to the focal plane from the frustum in world coordinates.
294        */
295        virtual void setFocalLength(Real focalLength = 1.0);
296
297        /** Returns focal length of frustum.
298        */
299        virtual Real getFocalLength() const;
300
301        /** Gets the projection matrix for this frustum adjusted for the current
302                        rendersystem specifics (may be right or left-handed, depth range
303                        may vary).
304        @remarks
305            This method retrieves the rendering-API dependent version of the projection
306            matrix. If you want a 'typical' projection matrix then use
307            getProjectionMatrix.
308
309        */
310        virtual const Matrix4& getProjectionMatrixRS(void) const;
311        /** Gets the depth-adjusted projection matrix for the current rendersystem,
312                        but one which still conforms to right-hand rules.
313        @remarks
314            This differs from the rendering-API dependent getProjectionMatrix
315            in that it always returns a right-handed projection matrix result
316            no matter what rendering API is being used - this is required for
317            vertex and fragment programs for example. However, the resulting depth
318            range may still vary between render systems since D3D uses [0,1] and
319            GL uses [-1,1], and the range must be kept the same between programmable
320            and fixed-function pipelines.
321        */
322        virtual const Matrix4& getProjectionMatrixWithRSDepth(void) const;
323        /** Gets the normal projection matrix for this frustum, ie the
324        projection matrix which conforms to standard right-handed rules and
325        uses depth range [-1,+1].
326        @remarks
327            This differs from the rendering-API dependent getProjectionMatrixRS
328            in that it always returns a right-handed projection matrix with depth
329            range [-1,+1], result no matter what rendering API is being used - this
330            is required for some uniform algebra for example.
331        */
332        virtual const Matrix4& getProjectionMatrix(void) const;
333
334        /** Gets the view matrix for this frustum. Mainly for use by OGRE internally.
335        */
336        virtual const Matrix4& getViewMatrix(void) const;
337
338                /** Set whether to use a custom view matrix on this frustum.
339                @remarks
340                        This is an advanced method which allows you to manually set
341                        the view matrix on this frustum, rather than having it calculate
342                        itself based on it's position and orientation.
343                @note
344                        After enabling a custom view matrix, the frustum will no longer
345                        update on its own based on position / orientation changes. You
346                        are completely responsible for keeping the view matrix up to date.
347                        The custom matrix will be returned from getViewMatrix.
348                @param enable If true, the custom view matrix passed as the second
349                        parameter will be used in preference to an auto calculated one. If
350                        false, the frustum will revert to auto calculating the view matrix.
351                @param viewMatrix The custom view matrix to use, the matrix must be an
352            affine matrix.
353                @see Frustum::setCustomProjectionMatrix, Matrix4::isAffine
354                */
355                virtual void setCustomViewMatrix(bool enable, 
356                        const Matrix4& viewMatrix = Matrix4::IDENTITY);
357                /// Returns whether a custom view matrix is in use
358                virtual bool isCustomViewMatrixEnabled(void) const 
359                { return mCustomViewMatrix; }
360               
361                /** Set whether to use a custom projection matrix on this frustum.
362                @remarks
363                        This is an advanced method which allows you to manually set
364                        the projection matrix on this frustum, rather than having it
365                        calculate itself based on it's position and orientation.
366                @note
367                        After enabling a custom projection matrix, the frustum will no
368                        longer update on its own based on field of view and near / far
369                        distance changes. You are completely responsible for keeping the
370                        projection matrix up to date if those values change. The custom
371                        matrix will be returned from getProjectionMatrix and derivative
372                        functions.
373                @param enable If true, the custom projection matrix passed as the
374                        second parameter will be used in preference to an auto calculated
375                        one. If false, the frustum will revert to auto calculating the
376                        projection matrix.
377                @param projectionMatrix The custom view matrix to use
378                @see Frustum::setCustomViewMatrix
379                */
380                virtual void setCustomProjectionMatrix(bool enable, 
381                        const Matrix4& projectionMatrix = Matrix4::IDENTITY);
382                /// Returns whether a custom projection matrix is in use
383                virtual bool isCustomProjectionMatrixEnabled(void) const
384                { return mCustomProjMatrix; }
385
386                /** Retrieves the clipping planes of the frustum (world space).
387        @remarks
388            The clipping planes are ordered as declared in enumerate constants FrustumPlane.
389        */
390        virtual const Plane* getFrustumPlanes(void) const;
391
392        /** Retrieves a specified plane of the frustum (world space).
393            @remarks
394                Gets a reference to one of the planes which make up the frustum frustum, e.g. for clipping purposes.
395        */
396        virtual const Plane& getFrustumPlane( unsigned short plane ) const;
397
398        /** Tests whether the given container is visible in the Frustum.
399            @param
400                bound Bounding box to be checked (world space)
401            @param
402                culledBy Optional pointer to an int which will be filled by the plane number which culled
403                the box if the result was false;
404            @returns
405                If the box was visible, true is returned.
406            @par
407                Otherwise, false is returned.
408        */
409        virtual bool isVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy = 0) const;
410
411        /** Tests whether the given container is visible in the Frustum.
412            @param
413                bound Bounding sphere to be checked (world space)
414            @param
415                culledBy Optional pointer to an int which will be filled by the plane number which culled
416                the box if the result was false;
417            @returns
418                If the sphere was visible, true is returned.
419            @par
420                Otherwise, false is returned.
421        */
422        virtual bool isVisible(const Sphere& bound, FrustumPlane* culledBy = 0) const;
423
424        /** Tests whether the given vertex is visible in the Frustum.
425            @param
426                vert Vertex to be checked (world space)
427            @param
428                culledBy Optional pointer to an int which will be filled by the plane number which culled
429                the box if the result was false;
430            @returns
431                If the box was visible, true is returned.
432            @par
433                Otherwise, false is returned.
434        */
435        virtual bool isVisible(const Vector3& vert, FrustumPlane* culledBy = 0) const;
436
437
438        /** Overridden from MovableObject */
439        const AxisAlignedBox& getBoundingBox(void) const;
440
441        /** Overridden from MovableObject */
442                Real getBoundingRadius(void) const;
443
444                /** Overridden from MovableObject */
445        void _updateRenderQueue(RenderQueue* queue);
446
447        /** Overridden from MovableObject */
448        const String& getMovableType(void) const;
449
450        /** Overridden from MovableObject */
451        void _notifyCurrentCamera(Camera* cam);
452
453        /** Overridden from Renderable */
454        const MaterialPtr& getMaterial(void) const;
455
456        /** Overridden from Renderable */
457        void getRenderOperation(RenderOperation& op);
458
459        /** Overridden from Renderable */
460        void getWorldTransforms(Matrix4* xform) const;
461
462        /** Overridden from Renderable */
463        const Quaternion& getWorldOrientation(void) const;
464
465        /** Overridden from Renderable */
466        const Vector3& getWorldPosition(void) const;
467
468        /** Overridden from Renderable */
469        Real getSquaredViewDepth(const Camera* cam) const;
470
471        /** Overridden from Renderable */
472        const LightList& getLights(void) const;
473
474        /** Gets the world space corners of the frustum.
475        @remarks
476            The corners are ordered as follows: top-right near,
477            top-left near, bottom-left near, bottom-right near,
478            top-right far, top-left far, bottom-left far, bottom-right far.
479        */
480        virtual const Vector3* getWorldSpaceCorners(void) const;
481
482        /** Sets the type of projection to use (orthographic or perspective). Default is perspective.
483        */
484        virtual void setProjectionType(ProjectionType pt);
485
486        /** Retrieves info on the type of projection used (orthographic or perspective).
487        */
488        virtual ProjectionType getProjectionType(void) const;
489
490        /** Modifies this frustum so it always renders from the reflection of itself through the
491        plane specified.
492        @remarks
493        This is obviously useful for performing planar reflections.
494        */
495        virtual void enableReflection(const Plane& p);
496        /** Modifies this frustum so it always renders from the reflection of itself through the
497        plane specified. Note that this version of the method links to a plane
498                so that changes to it are picked up automatically. It is important that
499                this plane continues to exist whilst this object does; do not destroy
500                the plane before the frustum.
501        @remarks
502        This is obviously useful for performing planar reflections.
503        */
504        virtual void enableReflection(const MovablePlane* p);
505
506        /** Disables reflection modification previously turned on with enableReflection */
507        virtual void disableReflection(void);
508
509        /// Returns whether this frustum is being reflected
510        virtual bool isReflected(void) const { return mReflect; }
511        /// Returns the reflection matrix of the frustum if appropriate
512        virtual const Matrix4& getReflectionMatrix(void) const { return mReflectMatrix; }
513        /// Returns the reflection plane of the frustum if appropriate
514        virtual const Plane& getReflectionPlane(void) const { return mReflectPlane; }
515
516        /** Project a sphere onto the near plane and get the bounding rectangle.
517        @param sphere The world-space sphere to project
518        @param radius Radius of the sphere
519        @param left, top, right, bottom Pointers to destination values, these
520            will be completed with the normalised device coordinates (in the
521            range {-1,1})
522        @returns true if the sphere was projected to a subset of the near plane,
523            false if the entire near plane was contained
524        */
525        virtual bool projectSphere(const Sphere& sphere, 
526            Real* left, Real* top, Real* right, Real* bottom) const;
527
528
529                /** Links the frustum to a custom near clip plane, which can be used
530                        to clip geometry in a custom manner without using user clip planes.
531                @remarks
532                        There are several applications for clipping a scene arbitrarily by
533                        a single plane; the most common is when rendering a reflection to
534                        a texture, and you only want to render geometry that is above the
535                        water plane (to do otherwise results in artefacts). Whilst it is
536                        possible to use user clip planes, they are not supported on all
537                        cards, and sometimes are not hardware accelerated when they are
538                        available. Instead, where a single clip plane is involved, this
539                        technique uses a 'fudging' of the near clip plane, which is
540                        available and fast on all hardware, to perform as the arbitrary
541                        clip plane. This does change the shape of the frustum, leading
542                        to some depth buffer loss of precision, but for many of the uses of
543                        this technique that is not an issue.
544                @par
545                        This version of the method links to a plane, rather than requiring
546                        a by-value plane definition, and therefore you can
547                        make changes to the plane (e.g. by moving / rotating the node it is
548                        attached to) and they will automatically affect this object.
549                @note This technique only works for perspective projection.
550                @param plane The plane to link to to perform the clipping. This plane
551                        must continue to exist while the camera is linked to it; do not
552                        destroy it before the frustum.
553                */
554                virtual void enableCustomNearClipPlane(const MovablePlane* plane);
555                /** Links the frustum to a custom near clip plane, which can be used
556                        to clip geometry in a custom manner without using user clip planes.
557                @remarks
558                        There are several applications for clipping a scene arbitrarily by
559                        a single plane; the most common is when rendering a reflection to 
560                        a texture, and you only want to render geometry that is above the
561                        water plane (to do otherwise results in artefacts). Whilst it is
562                        possible to use user clip planes, they are not supported on all
563                        cards, and sometimes are not hardware accelerated when they are
564                        available. Instead, where a single clip plane is involved, this
565                        technique uses a 'fudging' of the near clip plane, which is
566                        available and fast on all hardware, to perform as the arbitrary
567                        clip plane. This does change the shape of the frustum, leading
568                        to some depth buffer loss of precision, but for many of the uses of
569                        this technique that is not an issue.
570                @note This technique only works for perspective projection.
571                @param plane The plane to link to to perform the clipping. This plane
572                        must continue to exist while the camera is linked to it; do not
573                        destroy it before the frustum.
574                */
575                virtual void enableCustomNearClipPlane(const Plane& plane);
576                /** Disables any custom near clip plane. */
577                virtual void disableCustomNearClipPlane(void);
578                /** Is a custom near clip plane in use? */
579                virtual bool isCustomNearClipPlaneEnabled(void) const 
580                { return mObliqueDepthProjection; }
581               
582
583        /// Small constant used to reduce far plane projection to avoid inaccuracies
584        static const Real INFINITE_FAR_PLANE_ADJUST;
585    };
586
587
588}
589
590#endif
Note: See TracBrowser for help on using the repository browser.