Caelum
CaelumSystem.cpp
1 /*
2 This file is part of Caelum.
3 See http://www.ogre3d.org/wiki/index.php/Caelum
4 
5 Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
6 
7 Caelum is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Caelum is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License
18 along with Caelum. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include "CaelumPrecompiled.h"
22 #include "CaelumSystem.h"
23 #include "CaelumExceptions.h"
24 #include "InternalUtilities.h"
25 #include "Astronomy.h"
26 #include "CaelumPlugin.h"
27 #include "FlatCloudLayer.h"
28 
29 using namespace Ogre;
30 
31 namespace Caelum
32 {
33  const String CaelumSystem::DEFAULT_SKY_GRADIENTS_IMAGE = "EarthClearSky2.png";
34  const String CaelumSystem::DEFAULT_SUN_COLOURS_IMAGE = "SunGradient.png";
35 
36  CaelumSystem::CaelumSystem
37  (
38  Ogre::Root *root,
39  Ogre::SceneManager *sceneMgr,
40  CaelumComponent componentsToCreate/* = CAELUM_COMPONENTS_DEFAULT*/
41  ):
42  mOgreRoot (root),
43  mSceneMgr (sceneMgr),
44  mCleanup (false)
45  {
46  LogManager::getSingleton().logMessage ("Caelum: Initialising Caelum system...");
47  //LogManager::getSingleton().logMessage ("Caelum: CaelumSystem* at d" +
48  // StringConverter::toString (reinterpret_cast<uint>(this)));
49 
50  Ogre::String uniqueId = Ogre::StringConverter::toString ((size_t)this);
51  if (!CaelumPlugin::getSingletonPtr ()) {
52  LogManager::getSingleton().logMessage ("Caelum: Plugin not installed; installing now.");
53  new CaelumPlugin ();
54  CaelumPlugin::getSingletonPtr ()->install ();
55  CaelumPlugin::getSingletonPtr ()->initialise ();
56  }
57 
58  mCaelumCameraNode.reset(mSceneMgr->getRootSceneNode ()->createChildSceneNode ("Caelum/CameraNode/" + uniqueId));
59  mCaelumGroundNode.reset(mSceneMgr->getRootSceneNode ()->createChildSceneNode ("Caelum/GroundNode/" + uniqueId));
60  mUniversalClock.reset(new UniversalClock ());
61 
62  // If the "Caelum" resource group does not exist; create it.
63  // This resource group is never released; which may be bad.
64  // What does ogre do for it's own runtime resources?
65  Ogre::StringVector groups = ResourceGroupManager::getSingleton ().getResourceGroups ();
66  if (std::find (groups.begin(), groups.end(), Caelum::RESOURCE_GROUP_NAME) == groups.end()) {
67  LogManager::getSingleton ().logMessage (
68  "Caelum: Creating required internal resource group \'" + RESOURCE_GROUP_NAME + "\'");
69  ResourceGroupManager::getSingleton ().createResourceGroup (Caelum::RESOURCE_GROUP_NAME);
70  }
71 
72  // Autoconfigure. Calls clear first to set defaults.
73  autoConfigure (componentsToCreate);
74  }
75 
76  void CaelumSystem::destroySubcomponents (bool destroyEverything)
77  {
78  // Destroy sub-components
79  setSkyDome (0);
80  setSun (0);
81  setImageStarfield (0);
82  setPointStarfield (0);
83  setCloudSystem (0);
84  setPrecipitationController (0);
85  setDepthComposer (0);
86  setGroundFog (0);
87  setMoon (0);
88  mSkyGradientsImage.reset ();
89  mSunColoursImage.reset ();
90 
91  // These things can't be rebuilt.
92  if (destroyEverything) {
93  LogManager::getSingleton ().logMessage("Caelum: Delete UniversalClock");
94  mUniversalClock.reset ();
95  mCaelumCameraNode.reset ();
96  mCaelumGroundNode.reset ();
97  }
98  }
99 
100  CaelumSystem::~CaelumSystem () {
101  destroySubcomponents (true);
102  LogManager::getSingleton ().logMessage ("Caelum: CaelumSystem destroyed.");
103  }
104 
105  void CaelumSystem::clear()
106  {
107  // Destroy all subcomponents first.
108  destroySubcomponents (false);
109 
110  // Some "magical" behaviour.
111  mAutoMoveCameraNode = true;
112  mAutoNotifyCameraChanged = true;
113  mAutoAttachViewportsToComponents = true;
114  mAutoViewportBackground = true;
115 
116  // Default lookups.
117  setSkyGradientsImage(DEFAULT_SKY_GRADIENTS_IMAGE);
118  setSunColoursImage(DEFAULT_SUN_COLOURS_IMAGE);
119 
120  // Fog defaults.
121  setManageSceneFog (Ogre::FOG_EXP2);
122  setManageSceneFogStart(900);
123  setManageSceneFogEnd(1000);
124  mGlobalFogDensityMultiplier = 1;
125  mGlobalFogColourMultiplier = Ogre::ColourValue(1.0, 1.0, 1.0, 1.0);
126  mSceneFogDensityMultiplier = 1;
127  mSceneFogColourMultiplier = Ogre::ColourValue(0.7, 0.7, 0.7, 0.7);
128  mGroundFogDensityMultiplier = 1;
129  mGroundFogColourMultiplier = Ogre::ColourValue(1.0, 1.0, 1.0, 1.0);
130 
131  // Ambient lighting.
132  setManageAmbientLight (true);
133  setMinimumAmbientLight (Ogre::ColourValue (0.1, 0.1, 0.3));
134  mEnsureSingleLightSource = false;
135  mEnsureSingleShadowSource = false;
136 
137  // Observer time & position. J2000 is midday.
138  mObserverLatitude = Ogre::Degree(45);
139  mObserverLongitude = Ogre::Degree(0);
140  mUniversalClock->setJulianDay (Astronomy::J2000);
141  }
142 
143  void CaelumSystem::autoConfigure
144  (
145  CaelumComponent componentsToCreate/* = CAELUM_COMPONENTS_DEFAULT*/
146  )
147  {
148  // Clear everything; revert to default.
149  clear();
150 
151  if (componentsToCreate == 0) {
152  // Nothing to do. Don't print junk if not creating anything.
153  return;
154  }
155  LogManager::getSingleton ().logMessage ("Caelum: Creating caelum sub-components.");
156 
157  // Init skydome
158  if (componentsToCreate & CAELUM_COMPONENT_SKY_DOME) {
159  try {
160  this->setSkyDome (new SkyDome (mSceneMgr, getCaelumCameraNode ()));
161  } catch (Caelum::UnsupportedException& ex) {
162  LogManager::getSingleton ().logMessage (
163  "Caelum: Failed to initialize skydome: " + ex.getFullDescription());
164  }
165  }
166 
167  // Init sun
168  if (componentsToCreate & CAELUM_COMPONENT_SUN) {
169  try {
170  this->setSun (new SpriteSun (mSceneMgr, getCaelumCameraNode ()));
171  this->getSun ()->setAmbientMultiplier (Ogre::ColourValue (0.5, 0.5, 0.5));
172  this->getSun ()->setDiffuseMultiplier (Ogre::ColourValue (3, 3, 2.7));
173  this->getSun ()->setSpecularMultiplier (Ogre::ColourValue (5, 5, 5));
174 
175  this->getSun ()->setAutoDisable (true);
176  this->getSun ()->setAutoDisableThreshold (0.05);
177  } catch (Caelum::UnsupportedException& ex) {
178  LogManager::getSingleton ().logMessage (
179  "Caelum: Failed to initialize sun: " + ex.getFullDescription());
180  }
181  }
182 
183  // Init moon
184  if (componentsToCreate & CAELUM_COMPONENT_MOON) {
185  try {
186  this->setMoon (new Moon (mSceneMgr, getCaelumCameraNode ()));
187  this->getMoon ()->setAutoDisable (true);
188  this->getMoon ()->setAutoDisableThreshold (0.05);
189  } catch (Caelum::UnsupportedException& ex) {
190  LogManager::getSingleton ().logMessage (
191  "Caelum: Failed to initialize moon: " + ex.getFullDescription());
192  }
193  }
194  if (componentsToCreate & CAELUM_COMPONENT_IMAGE_STARFIELD) {
195  try {
196  this->setImageStarfield (new ImageStarfield (mSceneMgr, getCaelumCameraNode ()));
197  } catch (Caelum::UnsupportedException& ex) {
198  LogManager::getSingleton ().logMessage (
199  "Caelum: Failed to initialize the old image starfield: " + ex.getFullDescription());
200  }
201  }
202  if (componentsToCreate & CAELUM_COMPONENT_POINT_STARFIELD) {
203  try {
204  this->setPointStarfield (new PointStarfield (mSceneMgr, getCaelumCameraNode ()));
205  } catch (Caelum::UnsupportedException& ex) {
206  LogManager::getSingleton ().logMessage (
207  "Caelum: Failed to initialize starfield: " + ex.getFullDescription());
208  }
209  }
210  if (componentsToCreate & CAELUM_COMPONENT_GROUND_FOG) {
211  try {
212  this->setGroundFog (new GroundFog (mSceneMgr, getCaelumCameraNode ()));
213  } catch (Caelum::UnsupportedException& ex) {
214  LogManager::getSingleton ().logMessage (
215  "Caelum: Failed to initialize ground fog: " + ex.getFullDescription());
216  }
217  }
218  if (componentsToCreate & CAELUM_COMPONENT_CLOUDS) {
219  try {
220  this->setCloudSystem (new CloudSystem (mSceneMgr, getCaelumGroundNode ()));
221  getCloudSystem ()->createLayerAtHeight (3000);
222  getCloudSystem ()->getLayer (0)->setCloudCover (0.3);
223  } catch (Caelum::UnsupportedException& ex) {
224  LogManager::getSingleton ().logMessage (
225  "Caelum: Failed to initialize clouds: " + ex.getFullDescription());
226  }
227  }
228  if (componentsToCreate & CAELUM_COMPONENT_PRECIPITATION) {
229  try {
230  this->setPrecipitationController (new PrecipitationController (mSceneMgr));
231  } catch (Caelum::UnsupportedException& ex) {
232  LogManager::getSingleton ().logMessage (
233  "Caelum: Failed to initialize precipitation: " + ex.getFullDescription());
234  }
235  }
236  if (componentsToCreate & CAELUM_COMPONENT_SCREEN_SPACE_FOG) {
237  try {
238  this->setDepthComposer (new DepthComposer (mSceneMgr));
239  } catch (Caelum::UnsupportedException& ex) {
240  LogManager::getSingleton ().logMessage (
241  "Caelum: Failed to initialize precipitation: " + ex.getFullDescription());
242  }
243  }
244 
245  LogManager::getSingleton ().logMessage ("Caelum: DONE initializing");
246  }
247 
248  void CaelumSystem::shutdown (const bool cleanup) {
249  LogManager::getSingleton ().logMessage ("Caelum: Shutting down Caelum system...");
250 
251  destroySubcomponents (true);
252 
253  if (cleanup) {
254  mOgreRoot->removeFrameListener (this);
255  delete this;
256  } else {
257  // We'll delete later. Make sure we're registered as a frame listener, or we'd leak.
258  mOgreRoot->addFrameListener(this);
259  mCleanup = true;
260  }
261  }
262 
263  void CaelumSystem::attachViewportImpl (Ogre::Viewport* vp)
264  {
265  LogManager::getSingleton().getDefaultLog ()->logMessage (
266  "CaelumSystem: Attached to"
267  " viewport " + StringConverter::toString ((long)vp) +
268  " render target " + vp->getTarget ()->getName ());
269  if (getAutoAttachViewportsToComponents ()) {
270  if (getPrecipitationController ()) {
271  getPrecipitationController ()->createViewportInstance (vp);
272  }
273  if (getDepthComposer ()) {
274  getDepthComposer ()->createViewportInstance (vp);
275  }
276  }
277  }
278 
279  void CaelumSystem::detachViewportImpl (Ogre::Viewport* vp)
280  {
281  LogManager::getSingleton().getDefaultLog ()->logMessage (
282  "CaelumSystem: Detached from "
283  " viewport " + StringConverter::toString ((long)vp) +
284  " render target " + vp->getTarget ()->getName ());
285  if (getAutoAttachViewportsToComponents ()) {
286  if (getPrecipitationController ()) {
287  getPrecipitationController ()->destroyViewportInstance (vp);
288  }
289  if (getDepthComposer ()) {
290  getDepthComposer ()->destroyViewportInstance (vp);
291  }
292  }
293  }
294 
295  void CaelumSystem::attachViewport (Ogre::Viewport* vp)
296  {
297  bool found = !mAttachedViewports.insert (vp).second;
298  if (!found) {
299  attachViewportImpl (vp);
300  }
301  }
302 
303  void CaelumSystem::detachViewport (Ogre::Viewport* vp)
304  {
305  std::set<Viewport*>::size_type erase_result = mAttachedViewports.erase(vp);
306  assert(erase_result == 0 || erase_result == 1);
307  bool found = erase_result == 1;
308  if (found) {
309  detachViewportImpl (vp);
310  }
311  }
312 
313  void CaelumSystem::detachAllViewports ()
314  {
315  std::set<Viewport*>::const_iterator it = mAttachedViewports.begin(), end = mAttachedViewports.end();
316  for (; it != end; ++it) {
317  detachViewportImpl (*it);
318  }
319  mAttachedViewports.clear();
320  }
321 
322  bool CaelumSystem::isViewportAttached (Ogre::Viewport* vp) const {
323  return mAttachedViewports.find (vp) != mAttachedViewports.end();
324  }
325 
326  void CaelumSystem::setSkyDome (SkyDome *obj) {
327  mSkyDome.reset (obj);
328  }
329 
330  void CaelumSystem::setSun (BaseSkyLight* obj) {
331  mSun.reset (obj);
332  }
333 
334  void CaelumSystem::setMoon (Moon* obj) {
335  mMoon.reset (obj);
336  }
337 
338  void CaelumSystem::setImageStarfield (ImageStarfield* obj) {
339  mImageStarfield.reset (obj);
340  }
341 
342  void CaelumSystem::setPointStarfield (PointStarfield* obj) {
343  mPointStarfield.reset (obj);
344  }
345 
346  void CaelumSystem::setGroundFog (GroundFog* obj) {
347  mGroundFog.reset (obj);
348  }
349 
350  void CaelumSystem::setCloudSystem (CloudSystem* obj) {
351  mCloudSystem.reset (obj);
352  }
353 
354  void CaelumSystem::setPrecipitationController (PrecipitationController* newptr) {
355  PrecipitationController* oldptr = getPrecipitationController ();
356  if (oldptr == newptr) {
357  return;
358  }
359  // Detach old
360  if (getAutoAttachViewportsToComponents() && oldptr) {
361  std::for_each (mAttachedViewports.begin(), mAttachedViewports.end(),
362  std::bind1st (std::mem_fun (&PrecipitationController::destroyViewportInstance), oldptr));
363  }
364  // Attach new.
365  if (getAutoAttachViewportsToComponents() && newptr) {
366  std::for_each (mAttachedViewports.begin(), mAttachedViewports.end(),
367  std::bind1st (std::mem_fun (&PrecipitationController::createViewportInstance), newptr));
368  }
369  mPrecipitationController.reset(newptr);
370  }
371 
372  void CaelumSystem::setDepthComposer (DepthComposer* ptr) {
373  mDepthComposer.reset(ptr);
374  if (getAutoAttachViewportsToComponents() && getDepthComposer ()) {
375  std::for_each (
376  mAttachedViewports.begin(), mAttachedViewports.end(),
377  std::bind1st (
378  std::mem_fun (&DepthComposer::createViewportInstance),
379  getDepthComposer ()));
380  }
381  }
382 
383  void CaelumSystem::preViewportUpdate (const Ogre::RenderTargetViewportEvent &e) {
384  Ogre::Viewport *viewport = e.source;
385  Ogre::Camera *camera = viewport->getCamera ();
386 
387  if (getAutoViewportBackground ()) {
388  viewport->setBackgroundColour (Ogre::ColourValue::Black);
389  }
390  if (getAutoNotifyCameraChanged ()) {
391  this->notifyCameraChanged (camera);
392  }
393  }
394 
395  void CaelumSystem::notifyCameraChanged(Ogre::Camera* cam)
396  {
397  // Move camera node.
398  if (getAutoMoveCameraNode ()) {
399  mCaelumCameraNode->setPosition (cam->getDerivedPosition());
400  mCaelumCameraNode->_update (true, true);
401  }
402 
403  if (getSkyDome ()) {
404  getSkyDome ()->notifyCameraChanged (cam);
405  }
406 
407  if (getSun ()) {
408  getSun ()->notifyCameraChanged (cam);
409  }
410 
411  if (getMoon ()) {
412  getMoon ()->notifyCameraChanged (cam);
413  }
414 
415  if (getImageStarfield ()) {
416  getImageStarfield ()->notifyCameraChanged (cam);
417  }
418 
419  if (getPointStarfield ()) {
420  getPointStarfield ()->notifyCameraChanged (cam);
421  }
422 
423  if (getGroundFog ()) {
424  getGroundFog ()->notifyCameraChanged (cam);
425  }
426  }
427 
428  bool CaelumSystem::frameStarted (const Ogre::FrameEvent &e) {
429  if (mCleanup) {
430  // Delayed destruction.
431  mOgreRoot->removeFrameListener (this);
432  delete this;
433  return true;
434  }
435 
436  updateSubcomponents(e.timeSinceLastFrame);
437 
438  return true;
439  }
440 
441  void CaelumSystem::updateSubcomponents (Real timeSinceLastFrame)
442  {
443  /*
444  LogManager::getSingleton().getDefaultLog()->logMessage(
445  "CaelumSystem::updateSubcomponents: " +
446  StringConverter::toString (timeSinceLastFrame, 10));
447  */
448 
449  mUniversalClock->update (timeSinceLastFrame);
450 
451  // Timing variables
452  LongReal julDay = mUniversalClock->getJulianDay ();
453  LongReal relDayTime = fmod(julDay, 1);
454  Real secondDiff = timeSinceLastFrame * mUniversalClock->getTimeScale ();
455 
456  // Get astronomical parameters.
457  Ogre::Vector3 sunDir = getSunDirection(julDay);
458  Ogre::Vector3 moonDir = getMoonDirection(julDay);
459  Real moonPhase = getMoonPhase(julDay);
460 
461  // Get parameters from sky colour model.
462  Real fogDensity = getFogDensity (relDayTime, sunDir);
463  Ogre::ColourValue fogColour = getFogColour (relDayTime, sunDir);
464  Ogre::ColourValue sunLightColour = getSunLightColour (relDayTime, sunDir);
465  Ogre::ColourValue sunSphereColour = getSunSphereColour (relDayTime, sunDir);
466  Ogre::ColourValue moonLightColour = getMoonLightColour (moonDir);
467  Ogre::ColourValue moonBodyColour = getMoonBodyColour (moonDir);
468 
469  fogDensity *= mGlobalFogDensityMultiplier;
470  fogColour = fogColour * mGlobalFogColourMultiplier;
471 
472  // Update image starfield
473  if (getImageStarfield ()) {
474  getImageStarfield ()->update (relDayTime);
475  getImageStarfield ()->setInclination (-getObserverLatitude ());
476  }
477 
478  // Update point starfield
479  if (getPointStarfield ()) {
480  getPointStarfield ()->setObserverLatitude (getObserverLatitude ());
481  getPointStarfield ()->setObserverLongitude (getObserverLongitude ());
482  getPointStarfield ()->_update (relDayTime);
483  }
484 
485  // Update skydome.
486  if (getSkyDome ()) {
487  getSkyDome ()->setSunDirection (sunDir);
488  getSkyDome ()->setHazeColour (fogColour * mSceneFogColourMultiplier);
489  }
490 
491  // Update scene fog.
492  if (mManageSceneFogMode != Ogre::FOG_NONE) {
493  mSceneMgr->setFog (mManageSceneFogMode,
494  fogColour * mSceneFogColourMultiplier,
495  fogDensity * mSceneFogDensityMultiplier,
496  mManageSceneFogFromDistance,
497  mManageSceneFogToDistance);
498  }
499 
500  // Update ground fog.
501  if (getGroundFog ()) {
502  getGroundFog ()->setColour (fogColour * mGroundFogColourMultiplier);
503  getGroundFog ()->setDensity (fogDensity * mGroundFogDensityMultiplier);
504  }
505 
506  // Choose between sun and moon (should be done before updating)
507  if (getSun() && getMoon ()) {
508  Ogre::Real moonBrightness = moonLightColour.r + moonLightColour.g + moonLightColour.b + moonLightColour.a;
509  Ogre::Real sunBrightness = sunLightColour.r + sunLightColour.g + sunLightColour.b + sunLightColour.a;
510  bool sunBrighterThanMoon = (sunBrightness > moonBrightness);
511 
512  if (getEnsureSingleLightSource ()) {
513  getMoon()->setForceDisable (sunBrighterThanMoon);
514  getSun()->setForceDisable (!sunBrighterThanMoon);
515  }
516  if (getEnsureSingleShadowSource ()) {
517  getMoon()->getMainLight ()->setCastShadows (!sunBrighterThanMoon);
518  getSun()->getMainLight ()->setCastShadows (sunBrighterThanMoon);
519  }
520  }
521 
522  // Update sun
523  if (getSun ()) {
524  mSun->update (sunDir, sunLightColour, sunSphereColour);
525  }
526 
527  // Update moon.
528  if (getMoon ()) {
529  mMoon->update (
530  moonDir,
531  moonLightColour,
532  moonBodyColour);
533  mMoon->setMoonNorthPoleDirection(getEclipticNorthPoleDirection(julDay)); // its not precise, but error is within 1.5 degrees
534  mMoon->setPhase (moonPhase);
535  }
536 
537  // Update clouds
538  if (getCloudSystem ()) {
539  getCloudSystem ()->update (
540  secondDiff, sunDir, sunLightColour, fogColour, sunSphereColour);
541  }
542 
543  // Update precipitation
544  if (getPrecipitationController ()) {
545  getPrecipitationController ()->update (secondDiff, fogColour);
546  }
547 
548  // Update screen space fog
549  if (getDepthComposer ()) {
550  getDepthComposer ()->update ();
551  getDepthComposer ()->setSunDirection (sunDir);
552  getDepthComposer ()->setHazeColour (fogColour);
553  getDepthComposer ()->setGroundFogColour (fogColour * mGroundFogColourMultiplier);
554  getDepthComposer ()->setGroundFogDensity (fogDensity * mGroundFogDensityMultiplier);
555  }
556 
557  // Update ambient lighting.
558  if (getManageAmbientLight ()) {
559  Ogre::ColourValue ambient = Ogre::ColourValue::Black;
560  if (getMoon ()) {
561  ambient += getMoon ()->getLightColour () * getMoon ()->getAmbientMultiplier ();
562  }
563  if (getSun ()) {
564  ambient += getSun ()->getLightColour () * getSun ()->getAmbientMultiplier ();
565  }
566  ambient.r = std::max(ambient.r, mMinimumAmbientLight.r);
567  ambient.g = std::max(ambient.g, mMinimumAmbientLight.g);
568  ambient.b = std::max(ambient.b, mMinimumAmbientLight.b);
569  ambient.a = std::max(ambient.a, mMinimumAmbientLight.a);
570  // Debug ambient factos (ick).
571  /*
572  LogManager::getSingleton().logMessage (
573  "Sun is " + StringConverter::toString(sunLightColour) + "\n"
574  "Moon is " + StringConverter::toString(moonLightColour) + "\n"
575  "Ambient is " + StringConverter::toString(ambient) + "\n"
576  );
577  */
578  mSceneMgr->setAmbientLight (ambient);
579  }
580  }
581 
582  void CaelumSystem::setManageSceneFog (Ogre::FogMode v) {
583  mManageSceneFogMode = v;
584 
585  // Prevent having some stale values around.
586  // also important: we need to initialize this before using any terrain
587  mSceneMgr->setFog (mManageSceneFogMode);
588  }
589 
590  void CaelumSystem::disableFogMangement()
591  {
592  // NO RESET
593  mManageSceneFogMode = Ogre::FOG_NONE;
594  }
595 
596  Ogre::FogMode CaelumSystem::getManageSceneFog () const {
597  return mManageSceneFogMode;
598  }
599 
600  void CaelumSystem::setManageSceneFogStart (Ogre::Real from) {
601  mManageSceneFogFromDistance = from;
602  }
603 
604  Ogre::Real CaelumSystem::getManageSceneFogStart () const {
605  return mManageSceneFogFromDistance;
606  }
607 
608  void CaelumSystem::setManageSceneFogEnd (Ogre::Real from) {
609  mManageSceneFogToDistance = from;
610  }
611 
612  Ogre::Real CaelumSystem::getManageSceneFogEnd () const {
613  return mManageSceneFogToDistance;
614  }
615 
616  void CaelumSystem::setSceneFogDensityMultiplier (Real value) {
617  mSceneFogDensityMultiplier = value;
618  }
619 
620  Real CaelumSystem::getSceneFogDensityMultiplier () const {
621  return mSceneFogDensityMultiplier;
622  }
623 
624  void CaelumSystem::setGroundFogDensityMultiplier (Real value) {
625  mGroundFogDensityMultiplier = value;
626  }
627 
628  Real CaelumSystem::getGroundFogDensityMultiplier () const {
629  return mGroundFogDensityMultiplier;
630  }
631 
632  void CaelumSystem::setGlobalFogDensityMultiplier (Real value) {
633  mGlobalFogDensityMultiplier = value;
634  }
635 
636  Real CaelumSystem::getGlobalFogDensityMultiplier () const {
637  return mGlobalFogDensityMultiplier;
638  }
639 
640  void CaelumSystem::setSkyGradientsImage (const Ogre::String &filename) {
641  mSkyGradientsImage.reset(new Ogre::Image ());
642  mSkyGradientsImage->load (filename, RESOURCE_GROUP_NAME);
643  }
644 
645  void CaelumSystem::setSunColoursImage (const Ogre::String &filename) {
646  mSunColoursImage.reset(new Ogre::Image ());
647  mSunColoursImage->load (filename, RESOURCE_GROUP_NAME);
648  }
649 
650  Ogre::ColourValue CaelumSystem::getFogColour (Real time, const Ogre::Vector3 &sunDir) {
651  if (!mSkyGradientsImage.get()) {
652  return Ogre::ColourValue::Black;
653  }
654 
655  Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
656  Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, 1, mSkyGradientsImage.get(), false);
657  return col;
658  }
659 
660  Real CaelumSystem::getFogDensity (Real time, const Ogre::Vector3 &sunDir)
661  {
662  if (!mSkyGradientsImage.get()) {
663  return 0;
664  }
665 
666  Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
667  Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, 1, mSkyGradientsImage.get(), false);
668  return col.a;
669  }
670 
671  Ogre::ColourValue CaelumSystem::getSunSphereColour (Real time, const Ogre::Vector3 &sunDir)
672  {
673  if (!mSunColoursImage.get()) {
674  return Ogre::ColourValue::White;
675  }
676 
677  Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y);
678  elevation = elevation * 2 + 0.4;
679  return InternalUtilities::getInterpolatedColour (elevation, 1, mSunColoursImage.get(), false);
680  }
681 
682  Ogre::ColourValue CaelumSystem::getSunLightColour (Real time, const Ogre::Vector3 &sunDir)
683  {
684  if (!mSkyGradientsImage.get()) {
685  exit(-1);
686  return Ogre::ColourValue::White;
687  }
688  Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
689 
690  // Hack: return averaged sky colours.
691  // Don't use an alpha value for lights, this can cause nasty problems.
692  Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, elevation, mSkyGradientsImage.get(), false);
693  Real val = (col.r + col.g + col.b) / 3;
694  col = Ogre::ColourValue(val, val, val, 1.0);
695  assert(Ogre::Math::RealEqual(col.a, 1));
696  return col;
697  }
698 
699  Ogre::ColourValue CaelumSystem::getMoonBodyColour (const Ogre::Vector3 &moonDir) {
700  return Ogre::ColourValue::White;
701  }
702 
703  Ogre::ColourValue CaelumSystem::getMoonLightColour (const Ogre::Vector3 &moonDir)
704  {
705  if (!mSkyGradientsImage.get()) {
706  return Ogre::ColourValue::Blue;
707  }
708  // Scaled version of getSunLightColor
709  Real elevation = moonDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
710  Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, elevation, mSkyGradientsImage.get(), false);
711  Real val = (col.r + col.g + col.b) / 3;
712  col = Ogre::ColourValue(val / 2.5f, val / 2.5f, val / 2.5f, 1.0);
713  assert(Ogre::Math::RealEqual(col.a, 1));
714  return col;
715  }
716 
717  const Ogre::Vector3 CaelumSystem::makeDirection (
718  Ogre::Degree azimuth, Ogre::Degree altitude)
719  {
720  Ogre::Vector3 res;
721  res.z = -Ogre::Math::Cos (azimuth) * Ogre::Math::Cos (altitude); // North
722  res.x = Ogre::Math::Sin (azimuth) * Ogre::Math::Cos (altitude); // East
723  res.y = -Ogre::Math::Sin (altitude); // Zenith
724  return res;
725  }
726 
727  const Ogre::Vector3 CaelumSystem::getSunDirection (LongReal jday)
728  {
729  Ogre::Degree azimuth, altitude;
730  {
731  ScopedHighPrecissionFloatSwitch precissionSwitch;
732 
733  Astronomy::getHorizontalSunPosition(jday,
734  getObserverLongitude(), getObserverLatitude(),
735  azimuth, altitude);
736  }
737  Ogre::Vector3 res = makeDirection(azimuth, altitude);
738 
739  return res;
740  }
741 
742  const Ogre::Vector3 CaelumSystem::getEclipticNorthPoleDirection (LongReal jday)
743  {
744  Ogre::Degree azimuth, altitude;
745  {
746  ScopedHighPrecissionFloatSwitch precissionSwitch;
747 
748  Astronomy::getHorizontalNorthEclipticPolePosition(jday,
749  getObserverLongitude (), getObserverLatitude (),
750  azimuth, altitude);
751  }
752  Ogre::Vector3 res = -makeDirection(azimuth, altitude);
753 
754  return res;
755  }
756 
757  const Ogre::Vector3 CaelumSystem::getMoonDirection (LongReal jday)
758  {
759  Ogre::Degree azimuth, altitude;
760  {
761  ScopedHighPrecissionFloatSwitch precissionSwitch;
762 
763  Astronomy::getHorizontalMoonPosition(jday,
764  getObserverLongitude (), getObserverLatitude (),
765  azimuth, altitude);
766  }
767  Ogre::Vector3 res = makeDirection(azimuth, altitude);
768 
769  return res;
770  }
771 
772  const Ogre::Real CaelumSystem::getMoonPhase (LongReal jday)
773  {
774  // Calculates julian days since June 04, 1993 20:31 (full moon)
775  // and divides by the time between lunations (synodic month)
776  // Formula derived from http://scienceworld.wolfram.com/astronomy/Lunation.html
777  LongReal T = (jday - 2449143.3552943347L) / 29.53058867L;
778 
779  T -= floor(T); // [0..1)
780  return T;
781  }
782 
783  void CaelumSystem::forceSubcomponentQueryFlags (uint flags)
784  {
785  if (getSkyDome ()) getSkyDome ()->setQueryFlags (flags);
786  if (getSun ()) getSun ()->setQueryFlags (flags);
787  if (getMoon ()) getMoon ()->setQueryFlags (flags);
788  if (getImageStarfield ()) getImageStarfield ()->setQueryFlags (flags);
789  if (getPointStarfield ()) getPointStarfield ()->setQueryFlags (flags);
790  if (getGroundFog ()) getGroundFog ()->setQueryFlags (flags);
791  if (getCloudSystem ()) getCloudSystem ()->forceLayerQueryFlags (flags);
792  }
793 
794  void CaelumSystem::forceSubcomponentVisibilityFlags (uint flags)
795  {
796  if (getSkyDome ()) getSkyDome ()->setVisibilityFlags (flags);
797  if (getSun ()) getSun ()->setVisibilityFlags (flags);
798  if (getMoon ()) getMoon ()->setVisibilityFlags (flags);
799  if (getImageStarfield ()) getImageStarfield ()->setVisibilityFlags (flags);
800  if (getPointStarfield ()) getPointStarfield ()->setVisibilityFlags (flags);
801  if (getGroundFog ()) getGroundFog ()->setVisibilityFlags (flags);
802  if (getCloudSystem ()) getCloudSystem ()->forceLayerVisibilityFlags (flags);
803  }
804 }
Image-based starfield class.
Dummy class to increase floting point precission in a block This class will raise precission in the c...
Definition: Astronomy.h:217
Compositor-based precipitation controller.
Compositor-based precipitation controller.
Definition: DepthComposer.h:35
A sky dome element.
Definition: SkyDome.h:33
Base class for sky lights (sun and moon).
Definition: SkyLight.h:31
Class representing the sun as billboard with texture on it.
Definition: Sun.h:84
Point starfield class.
Exponential ground fog system implementation.
Definition: GroundFog.h:47
The system&#39;s time model.
A cloud system is implemented by a number of cloud layers.
Definition: CloudSystem.h:31
Implement an Ogre::Plugin for Caelum.
Definition: CaelumPlugin.h:37
static const String RESOURCE_GROUP_NAME
Resource group name for caelum resources.
Exception class for unsupported features.
CaelumComponent
Flags enumeration for caelum components.
Definition: CaelumSystem.h:218
Class representing the moon.
Definition: Moon.h:35
Caelum namespace.
Definition: Astronomy.cpp:24