Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreShadowCameraSetup.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 6.3 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
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
30#include "OgreStableHeaders.h"
31#include "OgreCommon.h"
32#include "OgreSceneManager.h"
33#include "OgreLight.h"
34#include "OgreShadowCameraSetup.h"
35#include "OgreCamera.h"
36#include "OgreViewport.h"
37
38
39namespace Ogre
40{
41        /// Default constructor
42        DefaultShadowCameraSetup::DefaultShadowCameraSetup()  {}
43       
44        /// Destructor
45        DefaultShadowCameraSetup::~DefaultShadowCameraSetup() {}
46       
47        /// Default shadow camera setup implementation
48        void DefaultShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, 
49                const Viewport *vp, const Light *light, Camera *texCam) const
50        {
51                Vector3 pos, dir;
52
53                // reset custom view / projection matrix in case already set
54                texCam->setCustomViewMatrix(false);
55                texCam->setCustomProjectionMatrix(false);
56
57                // get the shadow frustum's far distance
58                Real shadowDist = sm->getShadowFarDistance();
59                if (!shadowDist)
60                {
61                        // need a shadow distance, make one up
62                        shadowDist = cam->getNearClipDistance() * 300;
63                }
64                Real shadowOffset = shadowDist * (sm->getShadowDirLightTextureOffset());
65
66                // Directional lights
67                if (light->getType() == Light::LT_DIRECTIONAL)
68                {
69                        // set up the shadow texture
70                        // Set ortho projection
71                        texCam->setProjectionType(PT_ORTHOGRAPHIC);
72                        // set easy FOV and near dist so that texture covers far dist
73                        texCam->setFOVy(Degree(90));
74                        texCam->setNearClipDistance(shadowDist);
75
76                        // Calculate look at position
77                        // We want to look at a spot shadowOffset away from near plane
78                        // 0.5 is a litle too close for angles
79                        Vector3 target = cam->getDerivedPosition() + 
80                                (cam->getDerivedDirection() * shadowOffset);
81
82                        // Calculate direction, which same as directional light direction
83                        dir = - light->getDerivedDirection(); // backwards since point down -z
84                        dir.normalise();
85
86                        // Calculate position
87                        // We want to be in the -ve direction of the light direction
88                        // far enough to project for the dir light extrusion distance
89                        pos = target + dir * sm->getShadowDirectionalLightExtrusionDistance();
90
91                        // Round local x/y position based on a world-space texel; this helps to reduce
92                        // jittering caused by the projection moving with the camera
93                        // Viewport is 2 * near clip distance across (90 degree fov)
94                        Real worldTexelSize = (texCam->getNearClipDistance() * 20) / vp->getActualWidth();
95                        pos.x -= fmod(pos.x, worldTexelSize);
96                        pos.y -= fmod(pos.y, worldTexelSize);
97                        pos.z -= fmod(pos.z, worldTexelSize);
98                }
99                // Spotlight
100                else if (light->getType() == Light::LT_SPOTLIGHT)
101                {
102                        // Set perspective projection
103                        texCam->setProjectionType(PT_PERSPECTIVE);
104                        // set FOV slightly larger than the spotlight range to ensure coverage
105                        texCam->setFOVy(light->getSpotlightOuterAngle()*1.2);
106                        // set near clip the same as main camera, since they are likely
107                        // to both reflect the nature of the scene
108                        texCam->setNearClipDistance(cam->getNearClipDistance());
109
110                        // Calculate position, which same as spotlight position
111                        pos = light->getDerivedPosition();
112
113                        // Calculate direction, which same as spotlight direction
114                        dir = - light->getDerivedDirection(); // backwards since point down -z
115                        dir.normalise();
116                }
117                // Point light
118                else
119                {
120                        // Set perspective projection
121                        texCam->setProjectionType(PT_PERSPECTIVE);
122                        // Use 120 degree FOV for point light to ensure coverage more area
123                        texCam->setFOVy(Degree(120));
124                        // set near clip the same as main camera, since they are likely
125                        // to both reflect the nature of the scene
126                        texCam->setNearClipDistance(cam->getNearClipDistance());
127
128                        // Calculate look at position
129                        // We want to look at a spot shadowOffset away from near plane
130                        // 0.5 is a litle too close for angles
131                        Vector3 target = cam->getDerivedPosition() + 
132                                (cam->getDerivedDirection() * shadowOffset);
133
134                        // Calculate position, which same as point light position
135                        pos = light->getDerivedPosition();
136
137                        dir = (pos - target); // backwards since point down -z
138                        dir.normalise();
139                }
140
141                // Finally set position
142                texCam->setPosition(pos);
143
144                // Calculate orientation based on direction calculated above
145                /*
146                // Next section (camera oriented shadow map) abandoned
147                // Always point in the same direction, if we don't do this then
148                // we get 'shadow swimming' as camera rotates
149                // As it is, we get swimming on moving but this is less noticeable
150
151                // calculate up vector, we want it aligned with cam direction
152                Vector3 up = cam->getDerivedDirection();
153                // Check it's not coincident with dir
154                if (up.dotProduct(dir) >= 1.0f)
155                {
156                // Use camera up
157                up = cam->getUp();
158                }
159                */
160                Vector3 up = Vector3::UNIT_Y;
161                // Check it's not coincident with dir
162                if (Math::Abs(up.dotProduct(dir)) >= 1.0f)
163                {
164                        // Use camera up
165                        up = Vector3::UNIT_Z;
166                }
167                // cross twice to rederive, only direction is unaltered
168                Vector3 left = dir.crossProduct(up);
169                left.normalise();
170                up = dir.crossProduct(left);
171                up.normalise();
172                // Derive quaternion from axes
173                Quaternion q;
174                q.FromAxes(left, up, dir);
175                texCam->setOrientation(q);
176        }
177
178
179}
Note: See TracBrowser for help on using the repository browser.