00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "CaelumPrecompiled.h"
00022 #include "CaelumSystem.h"
00023 #include "CaelumExceptions.h"
00024 #include "InternalUtilities.h"
00025 #include "Astronomy.h"
00026 #include "CaelumPlugin.h"
00027 #include "FlatCloudLayer.h"
00028
00029 using namespace Ogre;
00030
00031 namespace Caelum
00032 {
00033 const String CaelumSystem::DEFAULT_SKY_GRADIENTS_IMAGE = "EarthClearSky2.png";
00034 const String CaelumSystem::DEFAULT_SUN_COLOURS_IMAGE = "SunGradient.png";
00035
00036 CaelumSystem::CaelumSystem
00037 (
00038 Ogre::Root *root,
00039 Ogre::SceneManager *sceneMgr,
00040 CaelumComponent componentsToCreate
00041 ):
00042 mOgreRoot (root),
00043 mSceneMgr (sceneMgr),
00044 mCleanup (false)
00045 {
00046 LogManager::getSingleton().logMessage ("Caelum: Initialising Caelum system...");
00047
00048
00049
00050 Ogre::String uniqueId = Ogre::StringConverter::toString ((size_t)this);
00051 if (!CaelumPlugin::getSingletonPtr ()) {
00052 LogManager::getSingleton().logMessage ("Caelum: Plugin not installed; installing now.");
00053 new CaelumPlugin ();
00054 CaelumPlugin::getSingletonPtr ()->install ();
00055 CaelumPlugin::getSingletonPtr ()->initialise ();
00056 }
00057
00058 mCaelumCameraNode.reset(mSceneMgr->getRootSceneNode ()->createChildSceneNode ("Caelum/CameraNode/" + uniqueId));
00059 mCaelumGroundNode.reset(mSceneMgr->getRootSceneNode ()->createChildSceneNode ("Caelum/GroundNode/" + uniqueId));
00060 mUniversalClock.reset(new UniversalClock ());
00061
00062
00063
00064
00065 Ogre::StringVector groups = ResourceGroupManager::getSingleton ().getResourceGroups ();
00066 if (std::find (groups.begin(), groups.end(), Caelum::RESOURCE_GROUP_NAME) == groups.end()) {
00067 LogManager::getSingleton ().logMessage (
00068 "Caelum: Creating required internal resource group \'" + RESOURCE_GROUP_NAME + "\'");
00069 ResourceGroupManager::getSingleton ().createResourceGroup (Caelum::RESOURCE_GROUP_NAME);
00070 }
00071
00072
00073 autoConfigure (componentsToCreate);
00074 }
00075
00076 void CaelumSystem::destroySubcomponents (bool destroyEverything)
00077 {
00078
00079 setSkyDome (0);
00080 setSun (0);
00081 setImageStarfield (0);
00082 setPointStarfield (0);
00083 setCloudSystem (0);
00084 setPrecipitationController (0);
00085 setDepthComposer (0);
00086 setGroundFog (0);
00087 setMoon (0);
00088 mSkyGradientsImage.reset ();
00089 mSunColoursImage.reset ();
00090
00091
00092 if (destroyEverything) {
00093 LogManager::getSingleton ().logMessage("Caelum: Delete UniversalClock");
00094 mUniversalClock.reset ();
00095 mCaelumCameraNode.reset ();
00096 mCaelumGroundNode.reset ();
00097 }
00098 }
00099
00100 CaelumSystem::~CaelumSystem () {
00101 destroySubcomponents (true);
00102 LogManager::getSingleton ().logMessage ("Caelum: CaelumSystem destroyed.");
00103 }
00104
00105 void CaelumSystem::clear()
00106 {
00107
00108 destroySubcomponents (false);
00109
00110
00111 mAutoMoveCameraNode = true;
00112 mAutoNotifyCameraChanged = true;
00113 mAutoAttachViewportsToComponents = true;
00114 mAutoViewportBackground = true;
00115
00116
00117 setSkyGradientsImage(DEFAULT_SKY_GRADIENTS_IMAGE);
00118 setSunColoursImage(DEFAULT_SUN_COLOURS_IMAGE);
00119
00120
00121 setManageSceneFog (true);
00122 mGlobalFogDensityMultiplier = 1;
00123 mGlobalFogColourMultiplier = Ogre::ColourValue(1.0, 1.0, 1.0, 1.0);
00124 mSceneFogDensityMultiplier = 1;
00125 mSceneFogColourMultiplier = Ogre::ColourValue(0.7, 0.7, 0.7, 0.7);
00126 mGroundFogDensityMultiplier = 1;
00127 mGroundFogColourMultiplier = Ogre::ColourValue(1.0, 1.0, 1.0, 1.0);
00128
00129
00130 setManageAmbientLight (true);
00131 setMinimumAmbientLight (Ogre::ColourValue (0.1, 0.1, 0.3));
00132 mEnsureSingleLightSource = false;
00133 mEnsureSingleShadowSource = false;
00134
00135
00136 mObserverLatitude = Ogre::Degree(45);
00137 mObserverLongitude = Ogre::Degree(0);
00138 mUniversalClock->setJulianDay (Astronomy::J2000);
00139 }
00140
00141 void CaelumSystem::autoConfigure
00142 (
00143 CaelumComponent componentsToCreate
00144 )
00145 {
00146
00147 clear();
00148
00149 if (componentsToCreate == 0) {
00150
00151 return;
00152 }
00153 LogManager::getSingleton ().logMessage ("Caelum: Creating caelum sub-components.");
00154
00155
00156 if (componentsToCreate & CAELUM_COMPONENT_SKY_DOME) {
00157 try {
00158 this->setSkyDome (new SkyDome (mSceneMgr, getCaelumCameraNode ()));
00159 } catch (Caelum::UnsupportedException& ex) {
00160 LogManager::getSingleton ().logMessage (
00161 "Caelum: Failed to initialize skydome: " + ex.getFullDescription());
00162 }
00163 }
00164
00165
00166 if (componentsToCreate & CAELUM_COMPONENT_SUN) {
00167 try {
00168 this->setSun (new SpriteSun (mSceneMgr, getCaelumCameraNode ()));
00169 this->getSun ()->setAmbientMultiplier (Ogre::ColourValue (0.5, 0.5, 0.5));
00170 this->getSun ()->setDiffuseMultiplier (Ogre::ColourValue (3, 3, 2.7));
00171 this->getSun ()->setSpecularMultiplier (Ogre::ColourValue (5, 5, 5));
00172
00173 this->getSun ()->setAutoDisable (true);
00174 this->getSun ()->setAutoDisableThreshold (0.05);
00175 } catch (Caelum::UnsupportedException& ex) {
00176 LogManager::getSingleton ().logMessage (
00177 "Caelum: Failed to initialize sun: " + ex.getFullDescription());
00178 }
00179 }
00180
00181
00182 if (componentsToCreate & CAELUM_COMPONENT_MOON) {
00183 try {
00184 this->setMoon (new Moon (mSceneMgr, getCaelumCameraNode ()));
00185 this->getMoon ()->setAutoDisable (true);
00186 this->getMoon ()->setAutoDisableThreshold (0.05);
00187 } catch (Caelum::UnsupportedException& ex) {
00188 LogManager::getSingleton ().logMessage (
00189 "Caelum: Failed to initialize moon: " + ex.getFullDescription());
00190 }
00191 }
00192 if (componentsToCreate & CAELUM_COMPONENT_IMAGE_STARFIELD) {
00193 try {
00194 this->setImageStarfield (new ImageStarfield (mSceneMgr, getCaelumCameraNode ()));
00195 } catch (Caelum::UnsupportedException& ex) {
00196 LogManager::getSingleton ().logMessage (
00197 "Caelum: Failed to initialize the old image starfield: " + ex.getFullDescription());
00198 }
00199 }
00200 if (componentsToCreate & CAELUM_COMPONENT_POINT_STARFIELD) {
00201 try {
00202 this->setPointStarfield (new PointStarfield (mSceneMgr, getCaelumCameraNode ()));
00203 } catch (Caelum::UnsupportedException& ex) {
00204 LogManager::getSingleton ().logMessage (
00205 "Caelum: Failed to initialize starfield: " + ex.getFullDescription());
00206 }
00207 }
00208 if (componentsToCreate & CAELUM_COMPONENT_GROUND_FOG) {
00209 try {
00210 this->setGroundFog (new GroundFog (mSceneMgr, getCaelumCameraNode ()));
00211 } catch (Caelum::UnsupportedException& ex) {
00212 LogManager::getSingleton ().logMessage (
00213 "Caelum: Failed to initialize ground fog: " + ex.getFullDescription());
00214 }
00215 }
00216 if (componentsToCreate & CAELUM_COMPONENT_CLOUDS) {
00217 try {
00218 this->setCloudSystem (new CloudSystem (mSceneMgr, getCaelumGroundNode ()));
00219 getCloudSystem ()->createLayerAtHeight (3000);
00220 getCloudSystem ()->getLayer (0)->setCloudCover (0.3);
00221 } catch (Caelum::UnsupportedException& ex) {
00222 LogManager::getSingleton ().logMessage (
00223 "Caelum: Failed to initialize clouds: " + ex.getFullDescription());
00224 }
00225 }
00226 if (componentsToCreate & CAELUM_COMPONENT_PRECIPITATION) {
00227 try {
00228 this->setPrecipitationController (new PrecipitationController (mSceneMgr));
00229 } catch (Caelum::UnsupportedException& ex) {
00230 LogManager::getSingleton ().logMessage (
00231 "Caelum: Failed to initialize precipitation: " + ex.getFullDescription());
00232 }
00233 }
00234 if (componentsToCreate & CAELUM_COMPONENT_SCREEN_SPACE_FOG) {
00235 try {
00236 this->setDepthComposer (new DepthComposer (mSceneMgr));
00237 } catch (Caelum::UnsupportedException& ex) {
00238 LogManager::getSingleton ().logMessage (
00239 "Caelum: Failed to initialize precipitation: " + ex.getFullDescription());
00240 }
00241 }
00242
00243 LogManager::getSingleton ().logMessage ("Caelum: DONE initializing");
00244 }
00245
00246 void CaelumSystem::shutdown (const bool cleanup) {
00247 LogManager::getSingleton ().logMessage ("Caelum: Shutting down Caelum system...");
00248
00249 destroySubcomponents (true);
00250
00251 if (cleanup) {
00252 mOgreRoot->removeFrameListener (this);
00253 delete this;
00254 } else {
00255
00256 mOgreRoot->addFrameListener(this);
00257 mCleanup = true;
00258 }
00259 }
00260
00261 void CaelumSystem::attachViewportImpl (Ogre::Viewport* vp)
00262 {
00263 LogManager::getSingleton().getDefaultLog ()->logMessage (
00264 "CaelumSystem: Attached to"
00265 " viewport " + StringConverter::toString ((long)vp) +
00266 " render target " + vp->getTarget ()->getName ());
00267 if (getAutoAttachViewportsToComponents ()) {
00268 if (getPrecipitationController ()) {
00269 getPrecipitationController ()->createViewportInstance (vp);
00270 }
00271 if (getDepthComposer ()) {
00272 getDepthComposer ()->createViewportInstance (vp);
00273 }
00274 }
00275 }
00276
00277 void CaelumSystem::detachViewportImpl (Ogre::Viewport* vp)
00278 {
00279 LogManager::getSingleton().getDefaultLog ()->logMessage (
00280 "CaelumSystem: Detached from "
00281 " viewport " + StringConverter::toString ((long)vp) +
00282 " render target " + vp->getTarget ()->getName ());
00283 if (getAutoAttachViewportsToComponents ()) {
00284 if (getPrecipitationController ()) {
00285 getPrecipitationController ()->destroyViewportInstance (vp);
00286 }
00287 if (getDepthComposer ()) {
00288 getDepthComposer ()->destroyViewportInstance (vp);
00289 }
00290 }
00291 }
00292
00293 void CaelumSystem::attachViewport (Ogre::Viewport* vp)
00294 {
00295 bool found = !mAttachedViewports.insert (vp).second;
00296 if (!found) {
00297 attachViewportImpl (vp);
00298 }
00299 }
00300
00301 void CaelumSystem::detachViewport (Ogre::Viewport* vp)
00302 {
00303 std::set<Viewport*>::size_type erase_result = mAttachedViewports.erase(vp);
00304 assert(erase_result == 0 || erase_result == 1);
00305 bool found = erase_result == 1;
00306 if (found) {
00307 detachViewportImpl (vp);
00308 }
00309 }
00310
00311 void CaelumSystem::detachAllViewports ()
00312 {
00313 std::set<Viewport*>::const_iterator it = mAttachedViewports.begin(), end = mAttachedViewports.end();
00314 for (; it != end; ++it) {
00315 detachViewportImpl (*it);
00316 }
00317 mAttachedViewports.clear();
00318 }
00319
00320 bool CaelumSystem::isViewportAttached (Ogre::Viewport* vp) const {
00321 return mAttachedViewports.find (vp) != mAttachedViewports.end();
00322 }
00323
00324 void CaelumSystem::setSkyDome (SkyDome *obj) {
00325 mSkyDome.reset (obj);
00326 }
00327
00328 void CaelumSystem::setSun (BaseSkyLight* obj) {
00329 mSun.reset (obj);
00330 }
00331
00332 void CaelumSystem::setMoon (Moon* obj) {
00333 mMoon.reset (obj);
00334 }
00335
00336 void CaelumSystem::setImageStarfield (ImageStarfield* obj) {
00337 mImageStarfield.reset (obj);
00338 }
00339
00340 void CaelumSystem::setPointStarfield (PointStarfield* obj) {
00341 mPointStarfield.reset (obj);
00342 }
00343
00344 void CaelumSystem::setGroundFog (GroundFog* obj) {
00345 mGroundFog.reset (obj);
00346 }
00347
00348 void CaelumSystem::setCloudSystem (CloudSystem* obj) {
00349 mCloudSystem.reset (obj);
00350 }
00351
00352 void CaelumSystem::setPrecipitationController (PrecipitationController* newptr) {
00353 PrecipitationController* oldptr = getPrecipitationController ();
00354 if (oldptr == newptr) {
00355 return;
00356 }
00357
00358 if (getAutoAttachViewportsToComponents() && oldptr) {
00359 std::for_each (mAttachedViewports.begin(), mAttachedViewports.end(),
00360 std::bind1st (std::mem_fun (&PrecipitationController::destroyViewportInstance), oldptr));
00361 }
00362
00363 if (getAutoAttachViewportsToComponents() && newptr) {
00364 std::for_each (mAttachedViewports.begin(), mAttachedViewports.end(),
00365 std::bind1st (std::mem_fun (&PrecipitationController::createViewportInstance), newptr));
00366 }
00367 mPrecipitationController.reset(newptr);
00368 }
00369
00370 void CaelumSystem::setDepthComposer (DepthComposer* ptr) {
00371 mDepthComposer.reset(ptr);
00372 if (getAutoAttachViewportsToComponents() && getDepthComposer ()) {
00373 std::for_each (
00374 mAttachedViewports.begin(), mAttachedViewports.end(),
00375 std::bind1st (
00376 std::mem_fun (&DepthComposer::createViewportInstance),
00377 getDepthComposer ()));
00378 }
00379 }
00380
00381 void CaelumSystem::preViewportUpdate (const Ogre::RenderTargetViewportEvent &e) {
00382 Ogre::Viewport *viewport = e.source;
00383 Ogre::Camera *camera = viewport->getCamera ();
00384
00385 if (getAutoViewportBackground ()) {
00386 viewport->setBackgroundColour (Ogre::ColourValue::Black);
00387 }
00388 if (getAutoNotifyCameraChanged ()) {
00389 this->notifyCameraChanged (camera);
00390 }
00391 }
00392
00393 void CaelumSystem::notifyCameraChanged(Ogre::Camera* cam)
00394 {
00395
00396 if (getAutoMoveCameraNode ()) {
00397 mCaelumCameraNode->setPosition (cam->getDerivedPosition());
00398 mCaelumCameraNode->_update (true, true);
00399 }
00400
00401 if (getSkyDome ()) {
00402 getSkyDome ()->notifyCameraChanged (cam);
00403 }
00404
00405 if (getSun ()) {
00406 getSun ()->notifyCameraChanged (cam);
00407 }
00408
00409 if (getMoon ()) {
00410 getMoon ()->notifyCameraChanged (cam);
00411 }
00412
00413 if (getImageStarfield ()) {
00414 getImageStarfield ()->notifyCameraChanged (cam);
00415 }
00416
00417 if (getPointStarfield ()) {
00418 getPointStarfield ()->notifyCameraChanged (cam);
00419 }
00420
00421 if (getGroundFog ()) {
00422 getGroundFog ()->notifyCameraChanged (cam);
00423 }
00424 }
00425
00426 bool CaelumSystem::frameStarted (const Ogre::FrameEvent &e) {
00427 if (mCleanup) {
00428
00429 mOgreRoot->removeFrameListener (this);
00430 delete this;
00431 return true;
00432 }
00433
00434 updateSubcomponents(e.timeSinceLastFrame);
00435
00436 return true;
00437 }
00438
00439 void CaelumSystem::updateSubcomponents (Real timeSinceLastFrame)
00440 {
00441
00442
00443
00444
00445
00446
00447 mUniversalClock->update (timeSinceLastFrame);
00448
00449
00450 LongReal julDay = mUniversalClock->getJulianDay ();
00451 LongReal relDayTime = fmod(julDay, 1);
00452 Real secondDiff = timeSinceLastFrame * mUniversalClock->getTimeScale ();
00453
00454
00455 Ogre::Vector3 sunDir = getSunDirection(julDay);
00456 Ogre::Vector3 moonDir = getMoonDirection(julDay);
00457 Real moonPhase = getMoonPhase(julDay);
00458
00459
00460 Real fogDensity = getFogDensity (relDayTime, sunDir);
00461 Ogre::ColourValue fogColour = getFogColour (relDayTime, sunDir);
00462 Ogre::ColourValue sunLightColour = getSunLightColour (relDayTime, sunDir);
00463 Ogre::ColourValue sunSphereColour = getSunSphereColour (relDayTime, sunDir);
00464 Ogre::ColourValue moonLightColour = getMoonLightColour (moonDir);
00465 Ogre::ColourValue moonBodyColour = getMoonBodyColour (moonDir);
00466
00467 fogDensity *= mGlobalFogDensityMultiplier;
00468 fogColour = fogColour * mGlobalFogColourMultiplier;
00469
00470
00471 if (getImageStarfield ()) {
00472 getImageStarfield ()->update (relDayTime);
00473 getImageStarfield ()->setInclination (-getObserverLatitude ());
00474 }
00475
00476
00477 if (getPointStarfield ()) {
00478 getPointStarfield ()->setObserverLatitude (getObserverLatitude ());
00479 getPointStarfield ()->setObserverLongitude (getObserverLongitude ());
00480 getPointStarfield ()->_update (relDayTime);
00481 }
00482
00483
00484 if (getSkyDome ()) {
00485 getSkyDome ()->setSunDirection (sunDir);
00486 getSkyDome ()->setHazeColour (fogColour * mSceneFogColourMultiplier);
00487 }
00488
00489
00490 if (getManageSceneFog ()) {
00491 mSceneMgr->setFog (Ogre::FOG_EXP2,
00492 fogColour * mSceneFogColourMultiplier,
00493 fogDensity * mSceneFogDensityMultiplier);
00494 }
00495
00496
00497 if (getGroundFog ()) {
00498 getGroundFog ()->setColour (fogColour * mGroundFogColourMultiplier);
00499 getGroundFog ()->setDensity (fogDensity * mGroundFogDensityMultiplier);
00500 }
00501
00502
00503 if (getSun ()) {
00504 mSun->update (sunDir, sunLightColour, sunSphereColour);
00505 }
00506
00507
00508 if (getMoon ()) {
00509 mMoon->update (
00510 moonDir,
00511 moonLightColour,
00512 moonBodyColour);
00513 mMoon->setPhase (moonPhase);
00514 }
00515
00516
00517 if (getCloudSystem ()) {
00518 getCloudSystem ()->update (
00519 secondDiff, sunDir, sunLightColour, fogColour, sunSphereColour);
00520 }
00521
00522
00523 if (getPrecipitationController ()) {
00524 getPrecipitationController ()->update (secondDiff, fogColour);
00525 }
00526
00527
00528 if (getDepthComposer ()) {
00529 getDepthComposer ()->update ();
00530 getDepthComposer ()->setSunDirection (sunDir);
00531 getDepthComposer ()->setHazeColour (fogColour);
00532 getDepthComposer ()->setGroundFogColour (fogColour * mGroundFogColourMultiplier);
00533 getDepthComposer ()->setGroundFogDensity (fogDensity * mGroundFogDensityMultiplier);
00534 }
00535
00536
00537 if (getManageAmbientLight ()) {
00538 Ogre::ColourValue ambient = Ogre::ColourValue::Black;
00539 if (getMoon ()) {
00540 ambient += getMoon ()->getLightColour () * getMoon ()->getAmbientMultiplier ();
00541 }
00542 if (getSun ()) {
00543 ambient += getSun ()->getLightColour () * getSun ()->getAmbientMultiplier ();
00544 }
00545 ambient.r = std::max(ambient.r, mMinimumAmbientLight.r);
00546 ambient.g = std::max(ambient.g, mMinimumAmbientLight.g);
00547 ambient.b = std::max(ambient.b, mMinimumAmbientLight.b);
00548 ambient.a = std::max(ambient.a, mMinimumAmbientLight.a);
00549
00550
00551
00552
00553
00554
00555
00556
00557 mSceneMgr->setAmbientLight (ambient);
00558 }
00559
00560 if (getSun() && getMoon ()) {
00561 Ogre::Real moonBrightness = moonLightColour.r + moonLightColour.g + moonLightColour.b + moonLightColour.a;
00562 Ogre::Real sunBrightness = sunLightColour.r + sunLightColour.g + sunLightColour.b + sunLightColour.a;
00563 bool sunBrighterThanMoon = (sunBrightness > moonBrightness);
00564
00565 if (getEnsureSingleLightSource ()) {
00566 getMoon ()->setForceDisable (sunBrighterThanMoon);
00567 getSun ()->setForceDisable (!sunBrighterThanMoon);
00568 }
00569 if (getEnsureSingleShadowSource ()) {
00570 getMoon ()->getMainLight ()->setCastShadows (!sunBrighterThanMoon);
00571 getSun ()->getMainLight ()->setCastShadows (sunBrighterThanMoon);
00572 }
00573 }
00574 }
00575
00576 void CaelumSystem::setManageSceneFog (bool value) {
00577 mManageSceneFog = value;
00578
00579 if (!value) {
00580 mSceneMgr->setFog (Ogre::FOG_NONE);
00581 }
00582 }
00583
00584 bool CaelumSystem::getManageSceneFog () const {
00585 return mManageSceneFog;
00586 }
00587
00588 void CaelumSystem::setSceneFogDensityMultiplier (Real value) {
00589 mSceneFogDensityMultiplier = value;
00590 }
00591
00592 Real CaelumSystem::getSceneFogDensityMultiplier () const {
00593 return mSceneFogDensityMultiplier;
00594 }
00595
00596 void CaelumSystem::setGroundFogDensityMultiplier (Real value) {
00597 mGroundFogDensityMultiplier = value;
00598 }
00599
00600 Real CaelumSystem::getGroundFogDensityMultiplier () const {
00601 return mGroundFogDensityMultiplier;
00602 }
00603
00604 void CaelumSystem::setGlobalFogDensityMultiplier (Real value) {
00605 mGlobalFogDensityMultiplier = value;
00606 }
00607
00608 Real CaelumSystem::getGlobalFogDensityMultiplier () const {
00609 return mGlobalFogDensityMultiplier;
00610 }
00611
00612 void CaelumSystem::setSkyGradientsImage (const Ogre::String &filename) {
00613 mSkyGradientsImage.reset(new Ogre::Image ());
00614 mSkyGradientsImage->load (filename, RESOURCE_GROUP_NAME);
00615 }
00616
00617 void CaelumSystem::setSunColoursImage (const Ogre::String &filename) {
00618 mSunColoursImage.reset(new Ogre::Image ());
00619 mSunColoursImage->load (filename, RESOURCE_GROUP_NAME);
00620 }
00621
00622 Ogre::ColourValue CaelumSystem::getFogColour (Real time, const Ogre::Vector3 &sunDir) {
00623 if (!mSkyGradientsImage.get()) {
00624 return Ogre::ColourValue::Black;
00625 }
00626
00627 Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
00628 Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, 1, mSkyGradientsImage.get(), false);
00629 return col;
00630 }
00631
00632 Real CaelumSystem::getFogDensity (Real time, const Ogre::Vector3 &sunDir)
00633 {
00634 if (!mSkyGradientsImage.get()) {
00635 return 0;
00636 }
00637
00638 Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
00639 Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, 1, mSkyGradientsImage.get(), false);
00640 return col.a;
00641 }
00642
00643 Ogre::ColourValue CaelumSystem::getSunSphereColour (Real time, const Ogre::Vector3 &sunDir)
00644 {
00645 if (!mSunColoursImage.get()) {
00646 return Ogre::ColourValue::White;
00647 }
00648
00649 Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y);
00650 elevation = elevation * 2 + 0.4;
00651 return InternalUtilities::getInterpolatedColour (elevation, 1, mSunColoursImage.get(), false);
00652 }
00653
00654 Ogre::ColourValue CaelumSystem::getSunLightColour (Real time, const Ogre::Vector3 &sunDir)
00655 {
00656 if (!mSkyGradientsImage.get()) {
00657 exit(-1);
00658 return Ogre::ColourValue::White;
00659 }
00660 Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
00661
00662
00663
00664 Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, elevation, mSkyGradientsImage.get(), false);
00665 Real val = (col.r + col.g + col.b) / 3;
00666 col = Ogre::ColourValue(val, val, val, 1.0);
00667 assert(Ogre::Math::RealEqual(col.a, 1));
00668 return col;
00669 }
00670
00671 Ogre::ColourValue CaelumSystem::getMoonBodyColour (const Ogre::Vector3 &moonDir) {
00672 return Ogre::ColourValue::White;
00673 }
00674
00675 Ogre::ColourValue CaelumSystem::getMoonLightColour (const Ogre::Vector3 &moonDir)
00676 {
00677 if (!mSkyGradientsImage.get()) {
00678 return Ogre::ColourValue::Blue;
00679 }
00680
00681 Real elevation = moonDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
00682 Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, elevation, mSkyGradientsImage.get(), false);
00683 Real val = (col.r + col.g + col.b) / 3;
00684 col = Ogre::ColourValue(val / 2.5f, val / 2.5f, val / 2.5f, 1.0);
00685 assert(Ogre::Math::RealEqual(col.a, 1));
00686 return col;
00687 }
00688
00689 const Ogre::Vector3 CaelumSystem::makeDirection (
00690 Ogre::Degree azimuth, Ogre::Degree altitude)
00691 {
00692 Ogre::Vector3 res;
00693 res.z = -Ogre::Math::Cos (azimuth) * Ogre::Math::Cos (altitude);
00694 res.x = Ogre::Math::Sin (azimuth) * Ogre::Math::Cos (altitude);
00695 res.y = -Ogre::Math::Sin (altitude);
00696 return res;
00697 }
00698
00699 const Ogre::Vector3 CaelumSystem::getSunDirection (LongReal jday)
00700 {
00701 Ogre::Degree azimuth, altitude;
00702 {
00703 ScopedHighPrecissionFloatSwitch precissionSwitch;
00704
00705 Astronomy::getHorizontalSunPosition(jday,
00706 getObserverLongitude(), getObserverLatitude(),
00707 azimuth, altitude);
00708 }
00709 Ogre::Vector3 res = makeDirection(azimuth, altitude);
00710
00711 return res;
00712 }
00713
00714 const Ogre::Vector3 CaelumSystem::getMoonDirection (LongReal jday)
00715 {
00716 Ogre::Degree azimuth, altitude;
00717 {
00718 ScopedHighPrecissionFloatSwitch precissionSwitch;
00719
00720 Astronomy::getHorizontalMoonPosition(jday,
00721 getObserverLongitude (), getObserverLatitude (),
00722 azimuth, altitude);
00723 }
00724 Ogre::Vector3 res = makeDirection(azimuth, altitude);
00725
00726 return res;
00727 }
00728
00729 const Ogre::Real CaelumSystem::getMoonPhase (LongReal jday)
00730 {
00731
00732
00733 LongReal T = (jday - 2454488.0665L) / 29.531026L;
00734
00735 T = fabs(fmod(T, 1));
00736 return -fabs(-4 * T + 2) + 2;
00737 }
00738
00739 void CaelumSystem::forceSubcomponentQueryFlags (uint flags)
00740 {
00741 if (getSkyDome ()) getSkyDome ()->setQueryFlags (flags);
00742 if (getSun ()) getSun ()->setQueryFlags (flags);
00743 if (getMoon ()) getMoon ()->setQueryFlags (flags);
00744 if (getImageStarfield ()) getImageStarfield ()->setQueryFlags (flags);
00745 if (getPointStarfield ()) getPointStarfield ()->setQueryFlags (flags);
00746 if (getGroundFog ()) getGroundFog ()->setQueryFlags (flags);
00747 if (getCloudSystem ()) getCloudSystem ()->forceLayerQueryFlags (flags);
00748 }
00749
00750 void CaelumSystem::forceSubcomponentVisibilityFlags (uint flags)
00751 {
00752 if (getSkyDome ()) getSkyDome ()->setVisibilityFlags (flags);
00753 if (getSun ()) getSun ()->setVisibilityFlags (flags);
00754 if (getMoon ()) getMoon ()->setVisibilityFlags (flags);
00755 if (getImageStarfield ()) getImageStarfield ()->setVisibilityFlags (flags);
00756 if (getPointStarfield ()) getPointStarfield ()->setVisibilityFlags (flags);
00757 if (getGroundFog ()) getGroundFog ()->setVisibilityFlags (flags);
00758 if (getCloudSystem ()) getCloudSystem ()->forceLayerVisibilityFlags (flags);
00759 }
00760 }