SO3Engine
SO3SkyLight.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
35
36namespace SO3
37{
38
39SSkyLight::SSkyLight(SEnvironment* parent, const std::string& skyLightName, const Ogre::ColourValue& defaultBaseColour) : SData(skyLightName)
40{
41 parentEnvironment = parent;
43 lastJulDay = 0;
44 ogreSkyLight = 0;
46 lastLatitude = Ogre::Degree(-91); // Invalid value to force first update
47 lastLongitude = Ogre::Degree(-181); // Invalid value to force first update
48 forceUpdate = false;
49
50 // Create a scene node
51 ogreSkyLightSceneNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode(skyLightName +"/Node");
52
53 // Create a light.
54 ogreSkyLight = ogreSceneManager->createLight(skyLightName +"/Light");
55 ogreSkyLight->setType(Ogre::Light::LT_DIRECTIONAL);
56 ogreSkyLight->setAttenuation(100000.0f, 1.0f, 0.0f, 0.0f);
57
58 UpdateShadowFarDistance(ogreSceneManager->getShadowFarDistance());
59 UpdateShadowFarClipDistance(ogreSceneManager->getShadowDirectionalLightExtrusionDistance());
60
61 // Attach the light to the node
63 ogreSkyLight->setVisible(false);
64
65 // Configure light colour
66 SetLightColour(defaultBaseColour);
67}
68
69SSkyLight::SSkyLight() : SData("")
70{
71 // Forbiden (private)
72}
73
75{
76 if(ogreSkyLight)
77 {
79 {
81 ogreSceneManager->getRootSceneNode()->removeAndDestroyChild(ogreSkyLightSceneNode->getName());
83 }
84
85 ogreSceneManager->destroyLight(ogreSkyLight);
86 ogreSkyLight = 0;
87 }
88
89 //restore default ambient light
91
94}
95
97{
98 if(ogreSkyLight)
99 return ogreSkyLight->getVisible();
100 else
101 return false;
102}
103
104void SSkyLight::SetEnable(const bool& enable)
105{
106 if(ogreSkyLight)
107 ogreSkyLight->setVisible(enable);
108
109 //restore default ambient light
110 if(!enable)
112}
113
118
120{
122 Ogre::Degree latitude = parentEnvironment->GetLatitude();
123 Ogre::Degree longitude = parentEnvironment->GetLongitude();
124
125 // Update only when necessary
126 if((forceUpdate)||
127 (lastJulDay == 0)||(lastJulDay != julDay)||
128 (lastLatitude == Ogre::Degree(-91))||(lastLatitude != latitude)||
129 (lastLongitude == Ogre::Degree(-181))||(lastLongitude != longitude))
130 {
131 // Update position
132 Ogre::Vector3 tmpLightDirection = ComputeDirectionImpl(julDay);
133 SetLightDirection(tmpLightDirection);
134 lastJulDay = julDay;
135 lastLatitude = latitude;
136 lastLongitude = longitude;
137 forceUpdate = false;
138
139 // Update colour
140 float gradientPoint = std::max(tmpLightDirection.y, 0.0f);
141 if(ogreSkyLight)
142 {
143 ogreSkyLight->setDiffuseColour(lightColourGradient.GetColour(gradientPoint));
144 ogreSkyLight->setSpecularColour(lightColourGradient.GetColour(gradientPoint));
145
146 // update the scene ambient light color
147 // hack to test for the sun
148 if (ogreSkyLight->getCastShadows())
149 {
150 Ogre::ColourValue ccolor = parentEnvironment->GetScene()->GetAmbientLight();
151 Ogre::ColourValue ncolor = lightColourGradient.GetColour(gradientPoint) * ccolor;
152 if (((ncolor.r + ncolor.g + ncolor.b) / 3) >= ((ccolor.r + ccolor.g + ccolor.b) / 3))
153 ogreSceneManager->setAmbientLight(ncolor);
154 }
155 }
156
157 // Disable shadow when under horizon
158 /*
159 if(tmpLightDirection.y > -0.015f)
160 {
161 if(ogreSkyLight)
162 ogreSkyLight->setCastShadows(true);
163 }
164 else
165 {
166 if(ogreSkyLight)
167 ogreSkyLight->setCastShadows(false);
168 }
169 */
170 }
171}
172
173const Ogre::Vector3 SSkyLight::GetLightDirection() const
174{
175 if(ogreSkyLight)
176 return -(ogreSkyLight->getParentSceneNode()->_getDerivedOrientation() * Ogre::Vector3::NEGATIVE_UNIT_Z);
177 else
178 return Ogre::Vector3::ZERO;
179}
180
181void SSkyLight::SetLightDirection(const Ogre::Vector3& direction)
182{
183 if(ogreSkyLight)
184 ogreSkyLight->getParentSceneNode()->setDirection(-direction);
185}
186
187const Ogre::ColourValue SSkyLight::GetLightColour(const float& level) const
188{
189 if(level == 1.0f)
190 return baseColour;
191 else
192 return lightColourGradient.GetColour(level);
193}
194
195void SSkyLight::SetLightColour(const Ogre::ColourValue& newColour)
196{
197 baseColour = newColour;
198 RefreshLightColourGradient();
199 forceUpdate = true;
200}
201
202const Ogre::Vector3 SSkyLight::MakeDirection(const Ogre::Degree& azimuth, const Ogre::Degree& altitude)
203{
204 Ogre::Vector3 res;
205 res.z = -Ogre::Math::Cos(azimuth) * Ogre::Math::Cos(altitude); // North
206 res.x = Ogre::Math::Sin(azimuth) * Ogre::Math::Cos(altitude); // East
207 res.y = Ogre::Math::Sin(altitude); // Zenith
208 return res;
209}
210
211void SSkyLight::RefreshLightColourGradient()
212{
213 // Alpha is not managed by Hydrax, which only use a Ogre::Vector3 for rgb values, so do not care about alpha that will be less than 1 after those multiplications.
220 lightColourGradient.AddColourFrame(0.0, Ogre::ColourValue::Black);
221}
222
224{
225 return ogreSkyLight->getCastShadows();
226}
227
228void SSkyLight::SetCastShadowEnable(const bool& enable)
229{
230 ogreSkyLight->setCastShadows(enable);
231}
232
233void SSkyLight::UpdateShadowFarDistance(const float& distance)
234{
235 ogreSkyLight->setShadowFarDistance(distance);
236}
237
238void SSkyLight::UpdateShadowFarClipDistance(const float& distance)
239{
240 ogreSkyLight->setShadowNearClipDistance(0.1f);
241 ogreSkyLight->setShadowFarClipDistance(distance);
242}
243
245{
246 return ogreSkyLight;
247}
248
249}
void AddColourFrame(const ColourFrame &colourFrame)
const Ogre::ColourValue GetColour(const float &gradientPosition) const
SUniversalClock * GetUniversalClock()
Ogre::Degree GetLatitude()
Ogre::Degree GetLongitude()
Ogre::SceneManager * GetOgreScenePointer()
Definition SO3Scene.cpp:449
Ogre::ColourValue GetAmbientLight()
Ogre::SceneManager * ogreSceneManager
Definition SO3SkyLight.h:46
void SetLightColour(const Ogre::ColourValue &newColour)
void SetCastShadowEnable(const bool &enable)
SEnvironment * parentEnvironment
Definition SO3SkyLight.h:45
Ogre::Degree lastLatitude
Definition SO3SkyLight.h:50
const Ogre::Vector3 MakeDirection(const Ogre::Degree &azimuth, const Ogre::Degree &altitude)
Ogre::SceneNode * ogreSkyLightSceneNode
Definition SO3SkyLight.h:48
bool GetCastShadowEnable()
void UpdateShadowFarDistance(const float &distance)
void SetLightDirection(const Ogre::Vector3 &direction)
const Ogre::ColourValue GetLightColour(const float &level=1.0f) const
Ogre::Degree lastLongitude
Definition SO3SkyLight.h:51
Ogre::Light * ogreSkyLight
Definition SO3SkyLight.h:47
double lastJulDay
Definition SO3SkyLight.h:49
void UpdateShadowFarClipDistance(const float &distance)
void SetEnable(const bool &enable)
const Ogre::Vector3 GetLightDirection() const
SColourGradient lightColourGradient
Definition SO3SkyLight.h:53
virtual const Ogre::Vector3 ComputeDirectionImpl(const double &julianDay)=0
Ogre::ColourValue baseColour
Definition SO3SkyLight.h:52
virtual ~SSkyLight()
Ogre::Light * GetOgreLight()
SEnvironment * GetEnvironment()