mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 15:35:23 +00:00
Add particle and sound fading for weather transitions (Fixes #2130)
This commit is contained in:
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…
x
Reference in New Issue
Block a user