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 "Moon.h"
00024 #include "PointStarfield.h"
00025
00026 namespace caelum {
00027
00028
00029 Ogre::String RESOURCE_GROUP_NAME = "Caelum";
00030
00031 CaelumSystem::CaelumSystem
00032 (
00033 Ogre::Root *root,
00034 Ogre::SceneManager *sceneMgr,
00035 CaelumComponent componentsToCreate,
00036 bool manageResGroup,
00037 const Ogre::String &resGroupName
00038 ):
00039 mOgreRoot (root),
00040 mSceneMgr (sceneMgr),
00041 mCleanup (false),
00042
00043 mManageSceneFog (false),
00044 mGlobalFogDensityMultiplier (1),
00045 mSceneFogDensityMultiplier (1),
00046 mSceneFogColourMultiplier (0.7, 0.7, 0.7, 0.7),
00047 mGroundFogDensityMultiplier (1),
00048 mGroundFogColourMultiplier (1.0, 1.0, 1.0, 1.0),
00049
00050 mManageAmbientLight (false),
00051 mMinimumAmbientLight (Ogre::ColourValue::Black),
00052 mEnsureSingleLightSource (false),
00053 mEnsureSingleShadowSource (false)
00054 {
00055 Ogre::LogManager::getSingleton().logMessage ("Caelum: Initialising Caelum system...");
00056 mCaelumRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("CaelumRoot");
00057
00058 RESOURCE_GROUP_NAME = resGroupName;
00059
00060
00061 if (manageResGroup) {
00062
00063 Ogre::StringVector resGroups = Ogre::ResourceGroupManager::getSingleton ().getResourceGroups ();
00064 Ogre::StringVector::iterator it = resGroups.begin (), iend = resGroups.end ();
00065 while (it != iend && *it != resGroupName) {
00066 ++it;
00067 }
00068
00069 if (it == iend) {
00070 Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (RESOURCE_GROUP_NAME);
00071 mManageResourceGroup = true;
00072 Ogre::LogManager::getSingleton ().logMessage (
00073 "Caelum: Created resource group (" + RESOURCE_GROUP_NAME + ")");
00074 } else {
00075 mManageResourceGroup = false;
00076 }
00077 } else {
00078 mManageResourceGroup = false;
00079 }
00080
00081
00082 mUniversalClock = new UniversalClock ();
00083
00084 Ogre::LogManager::getSingleton ().logMessage ("Caelum: System attributes set up.");
00085
00086
00087 if (componentsToCreate & CAELUM_COMPONENT_SKY_COLOUR_MODEL) {
00088 this->setSkyColourModel (new SkyColourModel ());
00089 }
00090 if (componentsToCreate & CAELUM_COMPONENT_SOLAR_SYSTEM_MODEL) {
00091 this->setSolarSystemModel (new SolarSystemModel ());
00092 }
00093 if (componentsToCreate & CAELUM_COMPONENT_SKY_DOME) {
00094 this->setSkyDome (new SkyDome (mSceneMgr, mCaelumRootNode));
00095 }
00096 if (componentsToCreate & CAELUM_COMPONENT_SUN) {
00097 this->setSun (new SpriteSun (mSceneMgr, mCaelumRootNode));
00098 }
00099 if (componentsToCreate & CAELUM_COMPONENT_MOON) {
00100 this->setMoon (new Moon (mSceneMgr, mCaelumRootNode));
00101 }
00102 if (componentsToCreate & CAELUM_COMPONENT_IMAGE_STARFIELD) {
00103 this->setImageStarfield (new ImageStarfield (mSceneMgr, mCaelumRootNode));
00104 }
00105 if (componentsToCreate & CAELUM_COMPONENT_POINT_STARFIELD) {
00106 this->setPointStarfield (new PointStarfield (mSceneMgr, mCaelumRootNode));
00107 }
00108 if (componentsToCreate & CAELUM_COMPONENT_CLOUDS) {
00109 this->setClouds (new LayeredClouds (mSceneMgr, mCaelumRootNode));
00110 }
00111 if (componentsToCreate & CAELUM_COMPONENT_GROUND_FOG) {
00112 this->setGroundFog (new GroundFog (mSceneMgr, mCaelumRootNode));
00113 }
00114
00115 Ogre::LogManager::getSingleton ().logMessage ("Caelum: DONE initializing");
00116 }
00117
00118 CaelumSystem::~CaelumSystem () {
00119 destroySubcomponents();
00120 Ogre::LogManager::getSingleton ().logMessage ("Caelum: CaelumSystem destroyed.");
00121 }
00122
00123 void CaelumSystem::destroySubcomponents () {
00124
00125 setSkyDome (0);
00126 setSun (0);
00127 setImageStarfield (0);
00128 setPointStarfield (0);
00129 setClouds (0);
00130 setGroundFog (0);
00131 setSkyColourModel (0);
00132 setMoon (0);
00133
00134
00135 if (mUniversalClock) {
00136 delete mUniversalClock;
00137 mUniversalClock = 0;
00138 }
00139
00140
00141 if (mManageResourceGroup) {
00142 Ogre::ResourceGroupManager::getSingleton ().destroyResourceGroup (RESOURCE_GROUP_NAME);
00143 Ogre::LogManager::getSingleton ().logMessage ("Caelum: Destroyed Caelum resource group");
00144 mManageResourceGroup = false;
00145 }
00146
00147 if (mCaelumRootNode) {
00148 static_cast<Ogre::SceneNode*>(mCaelumRootNode->getParent())->
00149 removeAndDestroyChild(mCaelumRootNode->getName());
00150 mCaelumRootNode = 0;
00151 }
00152 }
00153
00154 void CaelumSystem::shutdown (const bool cleanup) {
00155 Ogre::LogManager::getSingleton ().logMessage ("Caelum: Shutting down Caelum system...");
00156
00157 destroySubcomponents();
00158
00159 if (cleanup) {
00160 mOgreRoot->removeFrameListener (this);
00161 delete this;
00162 } else {
00163
00164 mOgreRoot->addFrameListener(this);
00165 mCleanup = true;
00166 }
00167 }
00168
00169 void CaelumSystem::preViewportUpdate (const Ogre::RenderTargetViewportEvent &e) {
00170 Ogre::Camera *cam = e.source->getCamera ();
00171
00172
00173 mCaelumRootNode->setPosition(cam->getDerivedPosition());
00174 mCaelumRootNode->_update(true, false);
00175
00176 if (getSkyDome ()) {
00177 getSkyDome ()->notifyCameraChanged (cam);
00178 }
00179
00180 if (getSun ()) {
00181 getSun ()->notifyCameraChanged (cam);
00182 }
00183
00184 if (getMoon ()) {
00185 getMoon ()->notifyCameraChanged (cam);
00186 }
00187
00188 if (getImageStarfield ()) {
00189 getImageStarfield ()->notifyCameraChanged (cam);
00190 }
00191
00192 if (getPointStarfield ()) {
00193 getPointStarfield ()->notifyCameraChanged (cam);
00194 }
00195
00196 if (getClouds ()) {
00197 getClouds ()->notifyCameraChanged (cam);
00198 }
00199
00200 if (getGroundFog ()) {
00201 getGroundFog ()->notifyCameraChanged (cam);
00202 }
00203 }
00204
00205 UniversalClock *CaelumSystem::getUniversalClock () const {
00206 return mUniversalClock;
00207 }
00208
00209 bool CaelumSystem::frameStarted (const Ogre::FrameEvent &e) {
00210 if (mCleanup) {
00211
00212 mOgreRoot->removeFrameListener (this);
00213 delete this;
00214 return true;
00215 }
00216
00217 updateSubcomponents(e.timeSinceLastFrame);
00218
00219 return true;
00220 }
00221
00222 void CaelumSystem::updateSubcomponents (double timeSinceLastFrame) {
00223 if (!mUniversalClock->update (timeSinceLastFrame)) {
00224 return;
00225 }
00226
00227
00228 LongReal julDay = mUniversalClock->getJulianDay ();
00229 LongReal relDayTime = fmod(julDay, 1);
00230
00231
00232 Ogre::Vector3 sunDir;
00233 Ogre::Vector3 moonDir;
00234 double moonPhase = 0.3;
00235 if (getSolarSystemModel ()) {
00236 sunDir = getSolarSystemModel ()->getSunDirection(julDay);
00237 moonDir = getSolarSystemModel ()->getMoonDirection(julDay);
00238 moonPhase = getSolarSystemModel ()->getMoonPhase(julDay);
00239 } else {
00240 sunDir = Ogre::Vector3::UNIT_Y;
00241 moonDir = Ogre::Vector3(0.5, 0.5, 0.5).normalisedCopy();
00242 moonPhase = 0.3;
00243 }
00244
00245
00246 double fogDensity;
00247 Ogre::ColourValue fogColour;
00248 Ogre::ColourValue sunLightColour;
00249 Ogre::ColourValue sunSphereColour;
00250 Ogre::ColourValue moonLightColour;
00251 Ogre::ColourValue moonBodyColour;
00252 if (getSkyColourModel ()) {
00253 fogDensity = getSkyColourModel ()->getFogDensity (relDayTime, sunDir);
00254 fogDensity *= mGlobalFogDensityMultiplier;
00255 fogColour = mSkyColourModel->getFogColour (relDayTime, sunDir);
00256 sunLightColour = getSkyColourModel ()->getSunLightColour (relDayTime, sunDir);
00257 sunSphereColour = getSkyColourModel ()->getSunSphereColour (relDayTime, sunDir);
00258 moonLightColour = getSkyColourModel ()->getMoonLightColour (moonDir);
00259 moonBodyColour = getSkyColourModel ()->getMoonBodyColour (moonDir);
00260 } else {
00261 fogDensity = 0;
00262 fogColour = Ogre::ColourValue::Black;
00263 sunLightColour = sunSphereColour = Ogre::ColourValue::White;
00264 moonLightColour = Ogre::ColourValue::Blue / 3;
00265 moonBodyColour = Ogre::ColourValue::White;
00266 }
00267
00268
00269 if (getImageStarfield ()) {
00270 getImageStarfield ()->update (relDayTime);
00271 }
00272
00273
00274 if (getPointStarfield ()) {
00275 getPointStarfield ()->_update (relDayTime);
00276 }
00277
00278
00279 if (getSkyDome ()) {
00280 getSkyDome ()->setSunDirection (sunDir);
00281 getSkyDome ()->setHazeColour (fogColour * mSceneFogColourMultiplier);
00282 }
00283
00284
00285 if (getManageSceneFog ()) {
00286 mSceneMgr->setFog (Ogre::FOG_EXP2,
00287 fogColour * mSceneFogColourMultiplier,
00288 fogDensity * mSceneFogDensityMultiplier);
00289 }
00290
00291
00292 if (getGroundFog ()) {
00293 getGroundFog ()->setColour (fogColour * mGroundFogColourMultiplier);
00294 getGroundFog ()->setDensity (fogDensity * mGroundFogDensityMultiplier);
00295 }
00296
00297
00298 if (getSun ()) {
00299 mSun->update (sunDir, sunLightColour, sunSphereColour);
00300 }
00301
00302
00303 if (getMoon () && getSkyColourModel ()) {
00304 mMoon->update (
00305 moonDir,
00306 moonLightColour,
00307 moonBodyColour);
00308 mMoon->setPhase (moonPhase);
00309 }
00310
00311
00312 if (getClouds()) {
00313 mClouds->update (mUniversalClock->getJulianSecondDifference(),
00314 sunDir, sunLightColour, fogColour);
00315 }
00316
00317
00318 if (getManageAmbientLight ()) {
00319 Ogre::ColourValue ambient = Ogre::ColourValue::Black;
00320 if (getMoon ()) {
00321 ambient += getMoon ()->getLightColour () * getMoon() ->getAmbientMultiplier ();
00322 }
00323 if (getSun ()) {
00324 ambient += getSun ()->getLightColour () * getSun() ->getAmbientMultiplier ();
00325 }
00326 ambient.r = std::max(ambient.r, mMinimumAmbientLight.r);
00327 ambient.g = std::max(ambient.g, mMinimumAmbientLight.g);
00328 ambient.b = std::max(ambient.b, mMinimumAmbientLight.b);
00329 ambient.a = std::max(ambient.a, mMinimumAmbientLight.a);
00330 mSceneMgr->setAmbientLight (ambient);
00331 }
00332
00333 if (getSun() && getMoon ()) {
00334 Ogre::Real moonBrightness = moonLightColour.r + moonLightColour.g + moonLightColour.b + moonLightColour.a;
00335 Ogre::Real sunBrightness = sunLightColour.r + sunLightColour.g + sunLightColour.b + sunLightColour.a;
00336 bool sunBrighterThanMoon = (sunBrightness > moonBrightness);
00337
00338 if (getEnsureSingleLightSource ()) {
00339 getMoon ()->setForceDisable (sunBrighterThanMoon);
00340 getSun ()->setForceDisable (!sunBrighterThanMoon);
00341 }
00342 if (getEnsureSingleShadowSource ()) {
00343 getMoon ()->getMainLight ()->setCastShadows (!sunBrighterThanMoon);
00344 getSun ()->getMainLight ()->setCastShadows (sunBrighterThanMoon);
00345 }
00346 }
00347 }
00348
00349 void CaelumSystem::setManageSceneFog (bool value) {
00350 mManageSceneFog = value;
00351
00352 if (!value) {
00353 mSceneMgr->setFog (Ogre::FOG_NONE);
00354 }
00355 }
00356
00357 bool CaelumSystem::getManageSceneFog () const {
00358 return mManageSceneFog;
00359 }
00360
00361 void CaelumSystem::setSceneFogDensityMultiplier (double value) {
00362 mSceneFogDensityMultiplier = value;
00363 }
00364
00365 double CaelumSystem::getSceneFogDensityMultiplier () const {
00366 return mSceneFogDensityMultiplier;
00367 }
00368
00369 void CaelumSystem::setGroundFogDensityMultiplier (double value) {
00370 mGroundFogDensityMultiplier = value;
00371 }
00372
00373 double CaelumSystem::getGroundFogDensityMultiplier () const {
00374 return mGroundFogDensityMultiplier;
00375 }
00376
00377 void CaelumSystem::setGlobalFogDensityMultiplier (double value) {
00378 mGlobalFogDensityMultiplier = value;
00379 }
00380
00381 double CaelumSystem::getGlobalFogDensityMultiplier () const {
00382 return mGlobalFogDensityMultiplier;
00383 }
00384 }