Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/include/OgreShadowCameraSetupFocused.h @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 10.7 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) 2006 Torus Knot Software Ltd
8Copyright (c) 2006 Matthias Fink, netAllied GmbH <matthias.fink@web.de>                                                         
9Also see acknowledgements in Readme.html
10
11This program is free software; you can redistribute it and/or modify it under
12the terms of the GNU Lesser General Public License as published by the Free Software
13Foundation; either version 2 of the License, or (at your option) any later
14version.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
19
20You should have received a copy of the GNU Lesser General Public License along with
21this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22Place - Suite 330, Boston, MA 02111-1307, USA, or go to
23http://www.gnu.org/copyleft/lesser.txt.
24
25You may alternatively use this source under the terms of a specific version of
26the OGRE Unrestricted License provided you have obtained such a license from
27Torus Knot Software Ltd.
28-----------------------------------------------------------------------------
29*/
30#ifndef __ShadowCameraSetupFocused_H__
31#define __ShadowCameraSetupFocused_H__
32
33#include "OgrePrerequisites.h"
34#include "OgreShadowCameraSetup.h"
35#include "OgrePolygon.h"
36#include "OgreConvexBody.h"
37
38
39namespace Ogre {
40
41        class ConvexBody;
42
43        /** Implements the uniform shadow mapping algorithm in focused mode.
44        @remarks
45                Differs from the default shadow mapping projection in that it focuses the
46                shadow map on the visible areas of the scene. This results in better
47                shadow map texel usage, at the expense of some 'swimming' of the shadow
48                texture on receivers as the basis is constantly being reevaluated.
49        @note
50                Original implementation by Matthias Fink <matthias.fink@web.de>, 2006.
51        */
52        class _OgreExport FocusedShadowCameraSetup : public ShadowCameraSetup
53        {
54        protected:
55                /** Transform to or from light space as defined by Wimmer et al.
56                @remarks
57                Point and spot lights need to be converted to directional lights to enable a 1:1
58                light mapping. Otherwise a directional light may become a point light or a point
59                sink (opposite of a light source) or point/spot lights may become directional lights
60                or light sinks. The light direction is always -y.
61                */
62                static const Matrix4 msNormalToLightSpace;
63                static const Matrix4 msLightSpaceToNormal;
64
65                /** Temporary preallocated frustum to set up a projection matrix in
66                ::calculateShadowMappingMatrix()
67                */
68                Frustum* mTempFrustum;
69
70                /** Temporary preallocated camera to set up a light frustum for clipping in ::calculateB.
71                */
72                Camera* mLightFrustumCamera;
73                mutable bool mLightFrustumCameraCalculated;
74
75                /// Use tighter focus region?
76                bool mUseAggressiveRegion;
77
78                /** Internal class holding a point list representation of a convex body.
79                */
80                class _OgreExport PointListBody
81                {
82                        Polygon::VertexList mBodyPoints;
83                        AxisAlignedBox          mAAB;
84
85                public:
86                        PointListBody();
87                        PointListBody(const ConvexBody& body);
88                        ~PointListBody();
89
90                        /** Merges a second PointListBody into this one.
91                        */
92                        void merge(const PointListBody& plb);
93
94                        /** Builds a point list body from a 'real' body.
95                        @remarks
96                        Inserts all vertices from a body into the point list with or without adding duplicate vertices.
97                        */
98                        void build(const ConvexBody& body, bool filterDuplicates = true);
99
100                        /** Builds a PointListBody from a Body and includes all the space in a given direction.
101                        @remarks
102                        Intersects the bounding box with a ray from each available point of the body with the given
103                        direction. Base and intersection points are stored in a PointListBody structure.
104                        @note
105                        Duplicate vertices are not filtered.
106                        @note
107                        Body is not checked for correctness.
108                        */
109                        void buildAndIncludeDirection(const ConvexBody& body, 
110                                const AxisAlignedBox& aabMax, const Vector3& dir);
111
112                        /** Returns the bounding box representation.
113                        */
114                        const AxisAlignedBox& getAAB(void) const;       
115
116                        /** Adds a specific point to the body list.
117                        */
118                        void addPoint(const Vector3& point);
119
120                        /** Adds all points of an AAB.
121                        */
122                        void addAAB(const AxisAlignedBox& aab);
123
124                        /** Returns a point.
125                        */
126                        const Vector3& getPoint(size_t cnt) const;
127
128                        /** Returns the point count.
129                        */
130                        size_t getPointCount(void) const;
131
132                        /** Resets the body.
133                        */
134                        void reset(void);
135
136                };
137
138                // Persistent calculations to prevent reallocation
139                mutable ConvexBody mBodyB;
140                mutable PointListBody mPointListBodyB;
141                mutable PointListBody mPointListBodyLVS;
142
143        protected:
144                /** Calculates the standard shadow mapping matrix.
145                @remarks
146                Provides the view and projection matrix for standard shadow mapping.
147                @note
148                You can choose which things you want to have: view matrix and/or projection
149                matrix and/or shadow camera. Passing a NULL value as parameter ignores the
150                generation of this specific value.
151                @param sm: scene manager
152                @param cam: currently active camera
153                @param light: currently active light
154                @param out_view: calculated uniform view shadow mapping matrix (may be NULL)
155                @param out_proj: calculated uniform projection shadow mapping matrix (may be NULL)
156                @param out_cam: calculated uniform shadow camera (may be NULL)
157                */
158                void calculateShadowMappingMatrix(const SceneManager& sm, const Camera& cam, 
159                        const Light& light, Matrix4 *out_view, 
160                        Matrix4 *out_proj, Camera *out_cam) const;
161
162                /** Calculates the intersection bodyB.
163                @remarks
164                The intersection bodyB consists of the concatenation the cam frustum clipped
165                by the scene bounding box followed by a convex hullification with the light's
166                position and the clipping with the scene bounding box and the light frustum:
167                ((V \cap S) + l) \cap S \cap L (\cap: convex intersection, +: convex hull
168                operation).
169                For directional lights the bodyB is assembled out of the camera frustum
170                clipped by the scene bounding box followed by the extrusion of all available
171                bodyB points towards the negative light direction. The rays are intersected
172                by a maximum bounding box and added to the bodyB points to form the final
173                intersection bodyB point list.
174                @param sm: scene manager
175                @param cam: currently active camera
176                @param light: currently active light
177                @param sceneBB: scene bounding box for clipping operations
178                @param out_bodyB: final intersection bodyB point list
179                */
180                void calculateB(const SceneManager& sm, const Camera& cam, const Light& light, 
181                        const AxisAlignedBox& sceneBB, PointListBody *out_bodyB) const;
182
183                /** Calculates the bodyLVS.
184                @remarks
185                Calculates the bodyLVS which consists of the convex intersection operation
186                affecting the light frustum, the view frustum, and the current scene bounding
187                box is used to find suitable positions in the viewer's frustum to build the
188                rotation matrix L_r. This matrix is applied after the projection matrix L_p to
189                avoid an accidental flip of the frustum orientation for views tilted with
190                respect to the shadow map.
191                @param scene: holds all potential occluders / receivers as one single bounding box
192                of the currently active scene node
193                @param cam: current viewer camera
194                @param light: current light
195                @param out_LVS: intersection body LVS (world coordinates)
196                */
197                void calculateLVS(const SceneManager& sm, const Camera& cam, const Light& light,
198                        const AxisAlignedBox& sceneBB, PointListBody *out_LVS) const;
199
200                /**     Returns the projection view direction.
201                @remarks
202                After the matrix L_p is applied the orientation of the light space may tilt for
203                non-identity projections. To prevent a false shadow cast the real view direction
204                is evaluated and applied to the light matrix L.
205                @param lightSpace: matrix of the light space transformation
206                @param cam: current viewer camera
207                @param bodyLVS: intersection body LVS (relevant space in front of the camera)
208                */
209                Vector3 getLSProjViewDir(const Matrix4& lightSpace, const Camera& cam, 
210                        const PointListBody& bodyLVS) const;
211
212                /** Returns a valid near-point seen by the camera.
213                @remarks
214                Returns a point that is situated near the camera by analyzing the bodyLVS that
215                contains all the relevant scene space in front of the light and the camera in
216                a point list array. The view matrix is relevant because the nearest point in
217                front of the camera should be determined.
218                @param viewMatrix: view matrix of the current camera
219                @param bodyLVS: intersection body LVS (relevant space in front of the camera)
220                */
221                Vector3 getNearCameraPoint_ws(const Matrix4& viewMatrix, 
222                        const PointListBody& bodyLVS) const;
223
224                /** Transforms a given body to the unit cube (-1,-1,-1) / (+1,+1,+1) with a specific
225                shadow matrix enabled.
226                @remarks
227                Transforms a given point list body object with the matrix m and then maps its
228                extends to a (-1,-1,-1) / (+1,+1,+1) unit cube
229                @param m: transformation matrix applied on the point list body
230                @param body: contains the points of the extends of all valid scene elements which
231                are mapped to the unit cube
232                */
233                Matrix4 transformToUnitCube(const Matrix4& m, const PointListBody& body) const;
234
235                /** Builds a view matrix.
236                @remarks
237                Builds a standard view matrix out of a given position, direction and up vector.
238                */
239                Matrix4 buildViewMatrix(const Vector3& pos, const Vector3& dir, const Vector3& up) const;
240
241        public:
242                /** Default constructor.
243                @remarks
244                Temporary frustum and camera set up here.
245                */
246                FocusedShadowCameraSetup(void);
247
248                /** Default destructor.
249                @remarks
250                Temporary frustum and camera destroyed here.
251                */
252                virtual ~FocusedShadowCameraSetup(void);
253
254                /** Returns a uniform shadow camera with a focused view.
255                */
256                virtual void getShadowCamera(const SceneManager *sm, const Camera *cam, 
257                        const Viewport *vp, const Light *light, Camera *texCam) const;
258
259                /** Sets whether or not to use the more agressive approach to deciding on
260                        the focus region or not.
261                @note
262                        There are 2 approaches that can  be used to define the focus region,
263                        the more aggressive way introduced by Wimmer et al, or the original
264                        way as described in Stamminger et al. Wimmer et al's way tends to
265                        come up with a tighter focus region but in rare cases (mostly highly
266                        glancing angles) can cause some shadow casters to be clipped
267                        incorrectly. By default the more aggressive approach is used since it
268                        leads to significantly better results in most cases, but if you experience
269                        clipping issues, you can use the less agressive version.
270                @param aggressive True to use the more agressive approach, false otherwise.
271                */
272                void setUseAggressiveFocusRegion(bool aggressive) { mUseAggressiveRegion = aggressive; }
273
274                bool getUseAggressiveFocusRegion() const { return mUseAggressiveRegion; }
275
276        };
277
278
279}
280
281#endif
Note: See TracBrowser for help on using the repository browser.