/src/ogre/OgreMain/include/OgreShadowCameraSetupFocused.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | Copyright (c) 2006 Matthias Fink, netAllied GmbH <matthias.fink@web.de> |
9 | | |
10 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
11 | | of this software and associated documentation files (the "Software"), to deal |
12 | | in the Software without restriction, including without limitation the rights |
13 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
14 | | copies of the Software, and to permit persons to whom the Software is |
15 | | furnished to do so, subject to the following conditions: |
16 | | |
17 | | The above copyright notice and this permission notice shall be included in |
18 | | all copies or substantial portions of the Software. |
19 | | |
20 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
21 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
22 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
23 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
24 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
25 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
26 | | THE SOFTWARE. |
27 | | ----------------------------------------------------------------------------- |
28 | | */ |
29 | | #ifndef __ShadowCameraSetupFocused_H__ |
30 | | #define __ShadowCameraSetupFocused_H__ |
31 | | |
32 | | #include "OgrePrerequisites.h" |
33 | | #include "OgreShadowCameraSetup.h" |
34 | | #include "OgrePolygon.h" |
35 | | #include "OgreConvexBody.h" |
36 | | #include "OgreHeaderPrefix.h" |
37 | | #include "OgreAxisAlignedBox.h" |
38 | | #include "OgreSceneNode.h" |
39 | | |
40 | | namespace Ogre { |
41 | | |
42 | | /** \addtogroup Core |
43 | | * @{ |
44 | | */ |
45 | | /** \addtogroup Scene |
46 | | * @{ |
47 | | */ |
48 | | /** Implements the uniform shadow mapping algorithm in focused mode. |
49 | | |
50 | | Differs from the default shadow mapping projection in that it focuses the |
51 | | shadow map on the visible areas of the scene. This results in better |
52 | | shadow map texel usage, at the expense of some 'swimming' of the shadow |
53 | | texture on receivers as the basis is constantly being reevaluated. |
54 | | |
55 | | Original implementation by Matthias Fink <matthias.fink@web.de>, 2006. |
56 | | */ |
57 | | class _OgreExport FocusedShadowCameraSetup : public DefaultShadowCameraSetup |
58 | | { |
59 | | // Persistent calculations to prevent reallocation |
60 | | mutable ConvexBody mBodyB; |
61 | | /// Use tighter focus region? |
62 | | bool mUseAggressiveRegion; |
63 | | protected: |
64 | | /** Transform to or from light space as defined by Wimmer et al. |
65 | | |
66 | | Point and spot lights need to be converted to directional lights to enable a 1:1 |
67 | | light mapping. Otherwise a directional light may become a point light or a point |
68 | | sink (opposite of a light source) or point/spot lights may become directional lights |
69 | | or light sinks. The light direction is always -y. |
70 | | */ |
71 | | static const Matrix4 msNormalToLightSpace; |
72 | | static const Matrix4 msLightSpaceToNormal; |
73 | | |
74 | | mutable const Camera* mLightFrustumCamera; |
75 | | mutable bool mLightFrustumCameraCalculated; |
76 | | |
77 | | /** Internal class holding a point list representation of a convex body. |
78 | | */ |
79 | | class _OgreExport PointListBody |
80 | | { |
81 | | Polygon::VertexList mBodyPoints; |
82 | | AxisAlignedBox mAAB; |
83 | | |
84 | | public: |
85 | | PointListBody(); |
86 | | PointListBody(const ConvexBody& body); |
87 | | ~PointListBody(); |
88 | | |
89 | | /** Merges a second PointListBody into this one. |
90 | | */ |
91 | | void merge(const PointListBody& plb); |
92 | | |
93 | | /** Builds a point list body from a 'real' body. |
94 | | |
95 | | Inserts all vertices from a body into the point list with or without adding duplicate vertices. |
96 | | */ |
97 | | void build(const ConvexBody& body, bool filterDuplicates = true); |
98 | | |
99 | | /** Builds a PointListBody from a Body and includes all the space in a given direction. |
100 | | |
101 | | Intersects the bounding box with a ray from each available point of the body with the given |
102 | | direction. Base and intersection points are stored in a PointListBody structure. |
103 | | @note |
104 | | Duplicate vertices are not filtered. |
105 | | @note |
106 | | Body is not checked for correctness. |
107 | | */ |
108 | | void buildAndIncludeDirection(const ConvexBody& body, |
109 | | Real extrudeDist, const Vector3& dir); |
110 | | |
111 | | /** Returns the bounding box representation. |
112 | | */ |
113 | | const AxisAlignedBox& getAAB(void) const; |
114 | | |
115 | | /** Adds a specific point to the body list. |
116 | | */ |
117 | | void addPoint(const Vector3& point); |
118 | | |
119 | | /** Adds all points of an AAB. |
120 | | */ |
121 | | void addAAB(const AxisAlignedBox& aab); |
122 | | |
123 | | /** Returns a point. |
124 | | */ |
125 | | const Vector3& getPoint(size_t cnt) const; |
126 | | |
127 | | /** Returns the point count. |
128 | | */ |
129 | | size_t getPointCount(void) const; |
130 | | |
131 | | /** Resets the body. |
132 | | */ |
133 | | void reset(void); |
134 | | |
135 | | }; |
136 | | |
137 | | // Persistent calculations to prevent reallocation |
138 | | mutable PointListBody mPointListBodyB; |
139 | | mutable PointListBody mPointListBodyLVS; |
140 | | |
141 | | protected: |
142 | | /** Calculates the intersection bodyB. |
143 | | |
144 | | The intersection bodyB consists of the concatenation the cam frustum clipped |
145 | | by the scene bounding box followed by a convex hullification with the light's |
146 | | position and the clipping with the scene bounding box and the light frustum: |
147 | | ((V \cap S) + l) \cap S \cap L (\cap: convex intersection, +: convex hull |
148 | | operation). |
149 | | For directional lights the bodyB is assembled out of the camera frustum |
150 | | clipped by the scene bounding box followed by the extrusion of all available |
151 | | bodyB points towards the negative light direction. The rays are intersected |
152 | | by a maximum bounding box and added to the bodyB points to form the final |
153 | | intersection bodyB point list. |
154 | | @param sm |
155 | | Scene manager. |
156 | | @param cam |
157 | | Currently active camera. |
158 | | @param light |
159 | | Currently active light. |
160 | | @param sceneBB |
161 | | Scene bounding box for clipping operations. |
162 | | @param receiverBB |
163 | | Bounding information for just the receivers. |
164 | | @param out_bodyB |
165 | | Final intersection bodyB point list. |
166 | | */ |
167 | | void calculateB(const SceneManager& sm, const Camera& cam, const Light& light, |
168 | | const AxisAlignedBox& sceneBB, const AxisAlignedBox& receiverBB, PointListBody *out_bodyB) const; |
169 | | |
170 | | /** Calculates the bodyLVS. |
171 | | |
172 | | Calculates the bodyLVS which consists of the convex intersection operation |
173 | | affecting the light frustum, the view frustum, and the current scene bounding |
174 | | box is used to find suitable positions in the viewer's frustum to build the |
175 | | rotation matrix L_r. This matrix is applied after the projection matrix L_p to |
176 | | avoid an accidental flip of the frustum orientation for views tilted with |
177 | | respect to the shadow map. |
178 | | @param cam |
179 | | Current viewer camera. |
180 | | @param light |
181 | | Current light. |
182 | | @param sceneBB |
183 | | Holds all potential occluders / receivers as one single bounding box |
184 | | of the currently active scene node. |
185 | | @param out_LVS |
186 | | Intersection body LVS (world coordinates). |
187 | | */ |
188 | | void calculateLVS(const SceneManager& sm, const Camera& cam, const Light& light, |
189 | | const AxisAlignedBox& sceneBB, PointListBody *out_LVS) const; |
190 | | |
191 | | /** Returns the projection view direction. |
192 | | |
193 | | After the matrix L_p is applied the orientation of the light space may tilt for |
194 | | non-identity projections. To prevent a false shadow cast the real view direction |
195 | | is evaluated and applied to the light matrix L. |
196 | | @param lightSpace |
197 | | Matrix of the light space transformation. |
198 | | @param cam |
199 | | Current viewer camera. |
200 | | @param bodyLVS |
201 | | Intersection body LVS (relevant space in front of the camera). |
202 | | */ |
203 | | Vector3 getLSProjViewDir(const Matrix4& lightSpace, const Camera& cam, |
204 | | const PointListBody& bodyLVS) const; |
205 | | |
206 | | /** Returns a valid near-point seen by the camera. |
207 | | |
208 | | Returns a point that is situated near the camera by analyzing the bodyLVS that |
209 | | contains all the relevant scene space in front of the light and the camera in |
210 | | a point list array. The view matrix is relevant because the nearest point in |
211 | | front of the camera should be determined. |
212 | | @param viewMatrix |
213 | | View matrix of the current camera. |
214 | | @param bodyLVS |
215 | | Intersection body LVS (relevant space in front of the camera). |
216 | | */ |
217 | | Vector3 getNearCameraPoint_ws(const Affine3& viewMatrix, |
218 | | const PointListBody& bodyLVS) const; |
219 | | |
220 | | /** Transforms a given body to the unit cube (-1,-1,-1) / (+1,+1,+1) with a specific |
221 | | shadow matrix enabled. |
222 | | |
223 | | Transforms a given point list body object with the matrix m and then maps its |
224 | | extends to a (-1,-1,-1) / (+1,+1,+1) unit cube. |
225 | | @param m |
226 | | Transformation matrix applied on the point list body. |
227 | | @param body |
228 | | Contains the points of the extends of all valid scene elements which |
229 | | are mapped to the unit cube. |
230 | | */ |
231 | | Matrix4 transformToUnitCube(const Matrix4& m, const PointListBody& body) const; |
232 | | public: |
233 | | /// @deprecated use create() |
234 | | FocusedShadowCameraSetup(bool useAggressiveRegion = true); |
235 | | |
236 | | ~FocusedShadowCameraSetup(); |
237 | | |
238 | | /** Create an instance |
239 | | |
240 | | There are 2 approaches that can be used to define the focus region, |
241 | | the more aggressive way introduced by Wimmer et al, or the original |
242 | | way as described in Stamminger et al. Wimmer et al's way tends to |
243 | | come up with a tighter focus region but in rare cases (mostly highly |
244 | | glancing angles) can cause some shadow casters to be clipped |
245 | | incorrectly. By default the more aggressive approach is used since it |
246 | | leads to significantly better results in most cases, but if you experience |
247 | | clipping issues, you can use the less aggressive version. |
248 | | @param useAggressiveRegion |
249 | | True to use the more aggressive approach, false otherwise. |
250 | | */ |
251 | | static ShadowCameraSetupPtr create(bool useAggressiveRegion = true) |
252 | 0 | { |
253 | 0 | return std::make_shared<FocusedShadowCameraSetup>(useAggressiveRegion); |
254 | 0 | } |
255 | | |
256 | | /** Returns a uniform shadow camera with a focused view. |
257 | | */ |
258 | | void getShadowCamera(const SceneManager *sm, const Camera *cam, |
259 | | const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const override; |
260 | | |
261 | | /** Sets whether or not to use the more aggressive approach to deciding on |
262 | | the focus region or not. |
263 | | */ |
264 | 0 | void setUseAggressiveFocusRegion(bool aggressive) { mUseAggressiveRegion = aggressive; } |
265 | | |
266 | 0 | bool getUseAggressiveFocusRegion() const { return mUseAggressiveRegion; } |
267 | | |
268 | | }; |
269 | | |
270 | | /** @} */ |
271 | | /** @} */ |
272 | | |
273 | | } // namespace Ogre |
274 | | |
275 | | #include "OgreHeaderSuffix.h" |
276 | | |
277 | | #endif // __ShadowCameraSetupFocused_H__ |