00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00035 #include "SO3Scene.h"
00036 #include "SO3Sky.h"
00037 #include "SO3Environment.h"
00038 #include "SO3SkyAstronomicalModel.h"
00039 #include "../SO3Renderer/SO3Viewport.h"
00040 #include "SO3Moon.h"
00041
00042 namespace SO3
00043 {
00044
00045 SSky::SSky(SEnvironment* parent, std::string skyName) : SEnvironmentComponent(parent, skyName)
00046 {
00047 parentScene = parent->GetScene();
00048 cloudsAnimationSpeed = 1.0f;
00049 cloudsCeilingHeight = 100.0f;
00050 cachedMoonTextureName = "SkyX_Moon.png";
00051
00052
00053 astronomicalModel = new SSkyAstronomicalModel(this);
00054
00055
00056 skyxManager = new SkyX::SkyX(parentScene->GetOgreScenePointer(), SO3_INTERNAL_SKYX_RESOURCE_GROUP, astronomicalModel);
00057 skyxManager->getMeshManager()->setSkydomeFadingParameters(false);
00058 skyxManager->setTimeMultiplier(1.0f/3600.0f);
00059 skyxOptions = skyxManager->getAtmosphereManager()->getOptions();
00060
00061
00062 skyxOptions.RayleighMultiplier = 0.003075f;
00063 skyxOptions.MieMultiplier = 0.00125f;
00064 skyxOptions.InnerRadius = 9.92f;
00065 skyxOptions.OuterRadius = 10.3311f;
00066 skyxManager->getAtmosphereManager()->setOptions(skyxOptions);
00067
00068
00069 volumetricClouds = new CloudVolumetric(this);
00070 layeredClouds = new CloudLayered(this);
00071 }
00072
00073 SSky::SSky() : SEnvironmentComponent(0, "")
00074 {
00075
00076 }
00077
00078 SSky::~SSky()
00079 {
00080 if(skyxManager)
00081 {
00082 SAFE_DELETE(layeredClouds);
00083 SAFE_DELETE(volumetricClouds);
00084 SAFE_DELETE(skyxManager);
00085 SAFE_DELETE(astronomicalModel);
00086 }
00087 }
00088
00089 void SSky::RegisterViewport(SViewPort* viewport)
00090 {
00091 skyxManager->registerViewport(viewport->GetOgreViewPortPointer());
00092 }
00093
00094 SkyX::SkyX* SSky::GetSkyX()
00095 {
00096 return skyxManager;
00097 }
00098
00099 void SSky::Update(Ogre::Real updateTime)
00100 {
00101 std::string moonNewTextureName = parentEnvironment->GetMoon()->GetTextureName();
00102 if(cachedMoonTextureName != moonNewTextureName)
00103 {
00104 try
00105 {
00106 Ogre::MaterialPtr moonMaterial = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(skyxManager->getGPUManager()->getMoonMaterialName()));
00107 if(!moonMaterial.isNull())
00108 {
00109 Ogre::Technique* ogreTechnique = moonMaterial->getBestTechnique();
00110 if(ogreTechnique != 0)
00111 {
00112 Ogre::Pass* ogrePass = ogreTechnique->getPass(0);
00113 if(ogrePass != 0)
00114 {
00115 Ogre::TextureUnitState* ogreTextureUnit = ogrePass->getTextureUnitState(0);
00116 if(ogreTextureUnit != 0)
00117 {
00118 ogreTextureUnit->setTextureName(moonNewTextureName);
00119 cachedMoonTextureName = moonNewTextureName;
00120 }
00121 }
00122 }
00123 }
00124 }
00125 catch(const Ogre::Exception&)
00126 {
00127
00128 }
00129 }
00130
00131 skyxManager->update(updateTime);
00132 }
00133
00134 SSky::SkyComponent* SSky::GetComponent(SSky::SkyComponentType componentType)
00135 {
00136 SSky::SkyComponent* component = 0;
00137 switch(componentType)
00138 {
00139 case SSky::SO3_SKY_COMPONENT_LAYERER_CLOUD:
00140 component = layeredClouds;
00141 break;
00142 case SSky::SO3_SKY_COMPONENT_VOLUMETRIC_CLOUD:
00143 component = volumetricClouds;
00144 break;
00145 default:
00146 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Invalid sky component type requested!", "SSky::GetComponent");
00147 break;
00148 }
00149 return component;
00150 }
00151
00152 SSky::CloudVolumetric* SSky::GetCloudVolumetric()
00153 {
00154 return volumetricClouds;
00155 }
00156
00157 SSky::CloudLayered* SSky::GetCloudLayered()
00158 {
00159 return layeredClouds;
00160 }
00161
00162 float SSky::GetAnimationSpeed()
00163 {
00164 return cloudsAnimationSpeed;
00165 }
00166
00167 void SSky::SetAnimationSpeed(float animationSpeed)
00168 {
00169 cloudsAnimationSpeed = animationSpeed;
00170 }
00171
00172 float SSky::GetCloudCeiling()
00173 {
00174 return cloudsCeilingHeight;
00175 }
00176
00177 void SSky::SetCloudCeiling(float newCloudCeiling)
00178 {
00179 float oldCloudCeiling = cloudsCeilingHeight;
00180 std::vector<int> layerIndexes = layeredClouds->GetLayerIndexes();
00181 std::vector<int>::iterator iLayerIndexes = layerIndexes.begin();
00182 while(iLayerIndexes != layerIndexes.end())
00183 {
00184 float layerHeightAboveCeiling = layeredClouds->GetHeightFromCloudCeiling(*iLayerIndexes);
00185 cloudsCeilingHeight = newCloudCeiling;
00186 layeredClouds->SetHeightFromCloudCeiling((*iLayerIndexes), layerHeightAboveCeiling);
00187 cloudsCeilingHeight = oldCloudCeiling;
00188 iLayerIndexes++;
00189 }
00190 cloudsCeilingHeight = newCloudCeiling;
00191 }
00192
00193 bool SSky::GetHDREnable()
00194 {
00195 return (skyxManager->getLightingMode() == SkyX::SkyX::LM_HDR);
00196 }
00197
00198 void SSky::SetHDREnable(bool enable)
00199 {
00200 if(enable)
00201 skyxManager->setLightingMode(SkyX::SkyX::LM_HDR);
00202 else
00203 skyxManager->setLightingMode(SkyX::SkyX::LM_LDR);
00204 }
00205
00206
00207
00208
00209
00210
00211 SSky::SkyComponent::SkyComponent(SSky* parentSkyInstance, SSky::SkyComponentType component) : componentType(component)
00212 {
00213 parentSky = parentSkyInstance;
00214 skyxManager = parentSkyInstance->GetSkyX();
00215 skyComponentEnable = true;
00216 }
00217
00218 SSky::SkyComponent::SkyComponent() : componentType(SSky::SO3_SKY_COMPONENT_NONE)
00219 {
00220
00221 }
00222
00223 SSky::SkyComponent::~SkyComponent()
00224 {
00225 skyxManager = 0;
00226 parentSky = 0;
00227 }
00228
00229 bool SSky::SkyComponent::GetEnabled()
00230 {
00231 return skyComponentEnable;
00232 }
00233
00234 void SSky::SkyComponent::SetEnabled(bool enable)
00235 {
00236 skyComponentEnable = enable;
00237 }
00238
00239 SSky::SkyComponentType SSky::SkyComponent::GetType()
00240 {
00241 return componentType;
00242 }
00243
00244
00245
00246
00247 SSky::CloudLayered::CloudLayered(SSky* parentSkyInstance) : SSky::SkyComponent(parentSkyInstance, SSky::SO3_SKY_COMPONENT_LAYERER_CLOUD)
00248 {
00249 }
00250
00251 SSky::CloudLayered::CloudLayered() : SSky::SkyComponent(0, SSky::SO3_SKY_COMPONENT_NONE)
00252 {
00253
00254 }
00255
00256 SSky::CloudLayered::~CloudLayered()
00257 {
00258 RemoveAllLayers();
00259 }
00260
00261 void SSky::CloudLayered::Update(Ogre::Real updateTime)
00262 {
00263 CloudLayerMap::iterator iCloudLayerMap = cloudLayerMap.begin();
00264 while(iCloudLayerMap!=cloudLayerMap.end())
00265 {
00266 SkyX::CloudLayer::Options skyxCloudLayerOptions = iCloudLayerMap->second->getOptions();
00267
00268 skyxCloudLayerOptions.WindDirection = parentSky->GetEnvironment()->GetWindDirection();
00269 skyxCloudLayerOptions.TimeMultiplier = parentSky->GetAnimationSpeed();
00270 iCloudLayerMap->second->setOptions(skyxCloudLayerOptions);
00271 }
00272 }
00273
00274 unsigned int SSky::CloudLayered::AddLayer(Ogre::Real heightFromCloudCeiling, Ogre::Real scale, Ogre::Real distanceAttenuation, Ogre::Real detailAttenuation, Ogre::Real normalMultiplier, Ogre::Real heightVolume, Ogre::Real volumetricDisplacement)
00275 {
00276
00277 unsigned int lowerIndex = 1;
00278 if(!cloudLayerMap.empty())
00279 lowerIndex = cloudLayerMap.upper_bound(0)->first + 1;
00280
00281
00282 SkyX::CloudLayer::Options skyxCloudLayerOptions;
00283 skyxCloudLayerOptions.Height = parentSky->GetCloudCeiling() + heightFromCloudCeiling;
00284 skyxCloudLayerOptions.Scale = scale;
00285 skyxCloudLayerOptions.DistanceAttenuation = distanceAttenuation;
00286 skyxCloudLayerOptions.DetailAttenuation = detailAttenuation;
00287 skyxCloudLayerOptions.NormalMultiplier = normalMultiplier;
00288 skyxCloudLayerOptions.HeightVolume = heightVolume;
00289 skyxCloudLayerOptions.VolumetricDisplacement = volumetricDisplacement;
00290 skyxCloudLayerOptions.WindDirection = parentSky->GetEnvironment()->GetWindDirection();
00291 skyxCloudLayerOptions.TimeMultiplier = parentSky->GetAnimationSpeed();
00292
00293
00294 SkyX::CloudLayer* skyxCloudLayer = skyxManager->getCloudsManager()->add(skyxCloudLayerOptions);
00295
00296
00297 cloudLayerMap.insert(CloudLayerMap::value_type(lowerIndex, skyxCloudLayer));
00298
00299
00300 return lowerIndex;
00301 }
00302
00303 void SSky::CloudLayered::RemoveLayer(unsigned int index)
00304 {
00305 CloudLayerMap::iterator iSearchedLayer = cloudLayerMap.find(index);
00306 if(iSearchedLayer == cloudLayerMap.end())
00307 OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Cannot remove cloud layer, there's no layer associated with this index!", "SSky::CloudLayered::RemoveLayer");
00308
00309
00310 skyxManager->getCloudsManager()->remove(iSearchedLayer->second);
00311
00312
00313 cloudLayerMap.erase(iSearchedLayer);
00314 }
00315
00316 void SSky::CloudLayered::RemoveAllLayers()
00317 {
00318 skyxManager->getCloudsManager()->removeAll();
00319 cloudLayerMap.clear();
00320 }
00321
00322 std::vector<int> SSky::CloudLayered::GetLayerIndexes()
00323 {
00324 std::vector<int> layerIndexes;
00325 CloudLayerMap::iterator iLayers = cloudLayerMap.begin();
00326 while(iLayers != cloudLayerMap.end())
00327 {
00328 layerIndexes.push_back(iLayers->first);
00329 iLayers++;
00330 }
00331 return layerIndexes;
00332 }
00333
00334 SkyX::CloudLayer* SSky::CloudLayered::GetLayer(unsigned int index)
00335 {
00336 CloudLayerMap::iterator iSearchedLayer = cloudLayerMap.find(index);
00337 if(iSearchedLayer == cloudLayerMap.end())
00338 OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Cannot find cloud layer, there's no layer associated with this index!", "SSky::CloudLayered::GetLayer");
00339
00340 return iSearchedLayer->second;
00341 }
00342
00343 void SSky::CloudLayered::SetParameters(unsigned int index, float heightFromCloudCeiling, float scale, float attenuationDistance, float attenuationDetail, float normalMultiplier, float heightVolume, float volumetricDisplacement)
00344 {
00345 SkyX::CloudLayer* skyxCloudLayer = GetLayer(index);
00346 SkyX::CloudLayer::Options skyxCloudLayerOptions = skyxCloudLayer->getOptions();
00347 skyxCloudLayerOptions.Height = parentSky->GetCloudCeiling() + heightFromCloudCeiling;
00348 skyxCloudLayerOptions.Scale = scale;
00349 skyxCloudLayerOptions.DistanceAttenuation = attenuationDistance;
00350 skyxCloudLayerOptions.DetailAttenuation = attenuationDetail;
00351 skyxCloudLayerOptions.NormalMultiplier = normalMultiplier;
00352 skyxCloudLayerOptions.HeightVolume = heightVolume;
00353 skyxCloudLayerOptions.VolumetricDisplacement = volumetricDisplacement;
00354 skyxCloudLayer->setOptions(skyxCloudLayerOptions);
00355 }
00356
00357 Ogre::Real SSky::CloudLayered::GetHeightFromCloudCeiling(unsigned int index)
00358 {
00359 return (parentSky->GetCloudCeiling() - GetLayer(index)->getOptions().Height);
00360 }
00361
00362 void SSky::CloudLayered::SetHeightFromCloudCeiling(unsigned int index, Ogre::Real newHeightFromCloudCeiling)
00363 {
00364 SkyX::CloudLayer* skyxCloudLayer = GetLayer(index);
00365 SkyX::CloudLayer::Options skyxCloudLayerOptions = skyxCloudLayer->getOptions();
00366 skyxCloudLayerOptions.Height = parentSky->GetCloudCeiling() + newHeightFromCloudCeiling;
00367 skyxCloudLayer->setOptions(skyxCloudLayerOptions);
00368 }
00369
00370 Ogre::Real SSky::CloudLayered::GetScale(unsigned int index)
00371 {
00372 return GetLayer(index)->getOptions().Scale;
00373 }
00374
00375 void SSky::CloudLayered::SetScale(unsigned int index, Ogre::Real newScale)
00376 {
00377 SkyX::CloudLayer* skyxCloudLayer = GetLayer(index);
00378 SkyX::CloudLayer::Options skyxCloudLayerOptions = skyxCloudLayer->getOptions();
00379 skyxCloudLayerOptions.Scale = newScale;
00380 skyxCloudLayer->setOptions(skyxCloudLayerOptions);
00381 }
00382
00383
00384 Ogre::Real SSky::CloudLayered::GetAttenuationDistance(unsigned int index)
00385 {
00386 return GetLayer(index)->getOptions().DistanceAttenuation;
00387 }
00388
00389 void SSky::CloudLayered::SetAttenuationDistance(unsigned int index, Ogre::Real newAttenuationDistance)
00390 {
00391 SkyX::CloudLayer* skyxCloudLayer = GetLayer(index);
00392 SkyX::CloudLayer::Options skyxCloudLayerOptions = skyxCloudLayer->getOptions();
00393 skyxCloudLayerOptions.DistanceAttenuation = newAttenuationDistance;
00394 skyxCloudLayer->setOptions(skyxCloudLayerOptions);
00395 }
00396
00397 Ogre::Real SSky::CloudLayered::GetAttenuationDetail(unsigned int index)
00398 {
00399 return GetLayer(index)->getOptions().DetailAttenuation;
00400 }
00401
00402 void SSky::CloudLayered::SetAttenuationDetail(unsigned int index, Ogre::Real newAttenuationDetail)
00403 {
00404 SkyX::CloudLayer* skyxCloudLayer = GetLayer(index);
00405 SkyX::CloudLayer::Options skyxCloudLayerOptions = skyxCloudLayer->getOptions();
00406 skyxCloudLayerOptions.DetailAttenuation = newAttenuationDetail;
00407 skyxCloudLayer->setOptions(skyxCloudLayerOptions);
00408 }
00409
00410 Ogre::Real SSky::CloudLayered::GetNormalMultiplier(unsigned int index)
00411 {
00412 return GetLayer(index)->getOptions().NormalMultiplier;
00413 }
00414
00415 void SSky::CloudLayered::SetNormalMultiplier(unsigned int index, Ogre::Real newNormalMultiplier)
00416 {
00417 SkyX::CloudLayer* skyxCloudLayer = GetLayer(index);
00418 SkyX::CloudLayer::Options skyxCloudLayerOptions = skyxCloudLayer->getOptions();
00419 skyxCloudLayerOptions.NormalMultiplier = newNormalMultiplier;
00420 skyxCloudLayer->setOptions(skyxCloudLayerOptions);
00421 }
00422
00423 Ogre::Real SSky::CloudLayered::GetHeightVolume(unsigned int index)
00424 {
00425 return GetLayer(index)->getOptions().HeightVolume;
00426 }
00427
00428 void SSky::CloudLayered::SetHeightVolume(unsigned int index, Ogre::Real newHeightVolume)
00429 {
00430 SkyX::CloudLayer* skyxCloudLayer = GetLayer(index);
00431 SkyX::CloudLayer::Options skyxCloudLayerOptions = skyxCloudLayer->getOptions();
00432 skyxCloudLayerOptions.HeightVolume = newHeightVolume;
00433 skyxCloudLayer->setOptions(skyxCloudLayerOptions);
00434 }
00435
00436 Ogre::Real SSky::CloudLayered::GetVolumetricDisplacement(unsigned int index)
00437 {
00438 return GetLayer(index)->getOptions().VolumetricDisplacement;
00439 }
00440
00441 void SSky::CloudLayered::SetVolumetricDisplacement(unsigned int index, Ogre::Real newVolumetricDisplacement)
00442 {
00443 SkyX::CloudLayer* skyxCloudLayer = GetLayer(index);
00444 SkyX::CloudLayer::Options skyxCloudLayerOptions = skyxCloudLayer->getOptions();
00445 skyxCloudLayerOptions.VolumetricDisplacement = newVolumetricDisplacement;
00446 skyxCloudLayer->setOptions(skyxCloudLayerOptions);
00447 }
00448
00449
00450
00451
00452 SSky::CloudVolumetric::CloudVolumetric(SSky* parentSkyInstance) : SSky::SkyComponent(parentSkyInstance, SSky::SO3_SKY_COMPONENT_VOLUMETRIC_CLOUD)
00453 {
00454 }
00455
00456 SSky::CloudVolumetric::CloudVolumetric() : SSky::SkyComponent(0, SSky::SO3_SKY_COMPONENT_NONE)
00457 {
00458
00459 }
00460
00461 void SSky::CloudVolumetric::Update(Ogre::Real updateTime)
00462 {
00463
00464 }
00465
00466 }