Add particle and sound fading for weather transitions (Fixes #2130)

report
scrawl 10 years ago
parent b9d0552166
commit fadbb5ad21

@ -34,6 +34,41 @@
using namespace MWRender;
using namespace Ogre;
namespace
{
void setAlpha (NifOgre::ObjectScenePtr scene, Ogre::MovableObject* movable, float alpha)
{
Ogre::MaterialPtr mat = scene->mMaterialControllerMgr.getWritableMaterial(movable);
Ogre::Material::TechniqueIterator techs = mat->getTechniqueIterator();
while(techs.hasMoreElements())
{
Ogre::Technique *tech = techs.getNext();
Ogre::Technique::PassIterator passes = tech->getPassIterator();
while(passes.hasMoreElements())
{
Ogre::Pass *pass = passes.getNext();
Ogre::ColourValue diffuse = pass->getDiffuse();
diffuse.a = alpha;
pass->setDiffuse(diffuse);
}
}
}
void setAlpha (NifOgre::ObjectScenePtr scene, float alpha)
{
for(size_t i = 0; i < scene->mParticles.size(); ++i)
setAlpha(scene, scene->mParticles[i], alpha);
for(size_t i = 0; i < scene->mEntities.size(); ++i)
{
if (scene->mEntities[i] != scene->mSkelBase)
setAlpha(scene, scene->mEntities[i], alpha);
}
}
}
BillboardObject::BillboardObject( const String& textureName,
const float initialSize,
const Vector3& position,
@ -660,6 +695,11 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
mSun->setVisibility(weather.mGlareView * strength);
mAtmosphereNight->setVisible(weather.mNight && mEnabled);
if (mParticle.get())
setAlpha(mParticle, weather.mEffectFade);
for (std::map<Ogre::SceneNode*, NifOgre::ObjectScenePtr>::iterator it = mRainModels.begin(); it != mRainModels.end(); ++it)
setAlpha(it->second, weather.mEffectFade);
}
void SkyManager::setGlare(const float glare)

@ -6,6 +6,8 @@
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwsound/sound.hpp"
#include "../mwrender/renderingmanager.hpp"
#include "player.hpp"
@ -152,12 +154,12 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fa
setFallbackWeather(foggy,"foggy");
Weather thunderstorm;
thunderstorm.mRainLoopSoundID = "rain heavy";
thunderstorm.mAmbientLoopSoundID = "rain heavy";
thunderstorm.mRainEffect = "meshes\\raindrop.nif";
setFallbackWeather(thunderstorm,"thunderstorm");
Weather rain;
rain.mRainLoopSoundID = "rain";
rain.mAmbientLoopSoundID = "rain";
rain.mRainEffect = "meshes\\raindrop.nif";
setFallbackWeather(rain,"rain");
@ -186,7 +188,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fa
WeatherManager::~WeatherManager()
{
stopSounds(true);
stopSounds();
}
void WeatherManager::setWeather(const String& weather, bool instant)
@ -228,6 +230,8 @@ void WeatherManager::setResult(const String& weatherType)
mResult.mCloudSpeed = current.mCloudSpeed;
mResult.mGlareView = current.mGlareView;
mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
mResult.mAmbientSoundVolume = 1.f;
mResult.mEffectFade = 1.f;
mResult.mSunColor = current.mSunDiscSunsetColor;
mResult.mIsStorm = current.mIsStorm;
@ -341,11 +345,30 @@ void WeatherManager::transition(float factor)
mResult.mNight = current.mNight;
mResult.mIsStorm = current.mIsStorm;
mResult.mParticleEffect = current.mParticleEffect;
mResult.mRainEffect = current.mRainEffect;
mResult.mRainSpeed = current.mRainSpeed;
mResult.mRainFrequency = current.mRainFrequency;
if (factor < 0.5)
{
mResult.mIsStorm = current.mIsStorm;
mResult.mParticleEffect = current.mParticleEffect;
mResult.mRainEffect = current.mRainEffect;
mResult.mParticleEffect = current.mParticleEffect;
mResult.mRainSpeed = current.mRainSpeed;
mResult.mRainFrequency = current.mRainFrequency;
mResult.mAmbientSoundVolume = 1-(factor*2);
mResult.mEffectFade = mResult.mAmbientSoundVolume;
mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
}
else
{
mResult.mIsStorm = other.mIsStorm;
mResult.mParticleEffect = other.mParticleEffect;
mResult.mRainEffect = other.mRainEffect;
mResult.mParticleEffect = other.mParticleEffect;
mResult.mRainSpeed = other.mRainSpeed;
mResult.mRainFrequency = other.mRainFrequency;
mResult.mAmbientSoundVolume = 2*(factor-0.5);
mResult.mEffectFade = mResult.mAmbientSoundVolume;
mResult.mAmbientLoopSoundID = other.mAmbientLoopSoundID;
}
}
void WeatherManager::update(float duration, bool paused)
@ -361,7 +384,7 @@ void WeatherManager::update(float duration, bool paused)
{
mRendering->skyDisable();
mRendering->getSkyManager()->setLightningStrength(0.f);
stopSounds(true);
stopSounds();
return;
}
@ -541,40 +564,25 @@ void WeatherManager::update(float duration, bool paused)
mRendering->getSkyManager()->setWeather(mResult);
// Play sounds
if (mNextWeather == "")
if (mPlayingSoundID != mResult.mAmbientLoopSoundID)
{
std::string ambientSnd = mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID;
if (!ambientSnd.empty() && std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), ambientSnd) == mSoundsPlaying.end())
{
mSoundsPlaying.push_back(ambientSnd);
MWBase::Environment::get().getSoundManager()->playSound(ambientSnd, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
}
stopSounds();
if (!mResult.mAmbientLoopSoundID.empty())
mAmbientSound = MWBase::Environment::get().getSoundManager()->playSound(mResult.mAmbientLoopSoundID, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
std::string rainSnd = mWeatherSettings[mCurrentWeather].mRainLoopSoundID;
if (!rainSnd.empty() && std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), rainSnd) == mSoundsPlaying.end())
{
mSoundsPlaying.push_back(rainSnd);
MWBase::Environment::get().getSoundManager()->playSound(rainSnd, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
}
mPlayingSoundID = mResult.mAmbientLoopSoundID;
}
stopSounds(false);
if (mAmbientSound.get())
mAmbientSound->setVolume(mResult.mAmbientSoundVolume);
}
void WeatherManager::stopSounds(bool stopAll)
void WeatherManager::stopSounds()
{
std::vector<std::string>::iterator it = mSoundsPlaying.begin();
while (it!=mSoundsPlaying.end())
if (mAmbientSound.get())
{
if (stopAll ||
!((*it == mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID) ||
(*it == mWeatherSettings[mCurrentWeather].mRainLoopSoundID)))
{
MWBase::Environment::get().getSoundManager()->stopSound(*it);
it = mSoundsPlaying.erase(it);
}
else
++it;
MWBase::Environment::get().getSoundManager()->stopSound(mAmbientSound);
mAmbientSound.reset();
mPlayingSoundID.clear();
}
}
@ -764,7 +772,7 @@ bool WeatherManager::readRecord(ESM::ESMReader& reader, int32_t type)
state.load(reader);
// reset other temporary state, now that we loaded successfully
stopSounds(true); // let's hope this never throws
stopSounds(); // let's hope this never throws
mRegionOverrides.clear();
mRegionMods.clear();
mThunderFlash = 0.0;

@ -7,6 +7,8 @@
#include <OgreColourValue.h>
#include <OgreVector3.h>
#include "../mwbase/soundmanager.hpp"
namespace ESM
{
struct Region;
@ -61,10 +63,12 @@ namespace MWWorld
bool mIsStorm;
std::string mAmbientLoopSoundID;
float mAmbientSoundVolume;
std::string mParticleEffect;
std::string mRainEffect;
float mEffectFade;
float mRainSpeed;
float mRainFrequency;
};
@ -125,9 +129,6 @@ namespace MWWorld
// This is used for Blight, Ashstorm and Blizzard (Bloodmoon)
std::string mAmbientLoopSoundID;
// Rain sound effect
std::string mRainLoopSoundID;
// Is this an ash storm / blight storm? If so, the following will happen:
// - The particles and clouds will be oriented so they appear to come from the Red Mountain.
// - Characters will animate their hand to protect eyes from the storm when looking in its direction (idlestorm animation)
@ -173,7 +174,7 @@ namespace MWWorld
*/
void update(float duration, bool paused = false);
void stopSounds(bool stopAll);
void stopSounds();
void setHour(const float hour);
@ -206,6 +207,9 @@ namespace MWWorld
bool mIsStorm;
Ogre::Vector3 mStormDirection;
MWBase::SoundPtr mAmbientSound;
std::string mPlayingSoundID;
MWWorld::Fallback* mFallback;
void setFallbackWeather(Weather& weather,const std::string& name);
MWRender::RenderingManager* mRendering;
@ -214,8 +218,6 @@ namespace MWWorld
std::map<std::string, std::string> mRegionOverrides;
std::vector<std::string> mSoundsPlaying;
std::string mCurrentWeather;
std::string mNextWeather;

Loading…
Cancel
Save