From b68f64ed97aff7c48d6878241ecd64d6acaba2f5 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 6 Sep 2015 21:46:05 +0200 Subject: [PATCH 1/2] adjust FindMyGUI.cmake to correctly handle REQUIRED and QUIETLY --- cmake/FindMyGUI.cmake | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cmake/FindMyGUI.cmake b/cmake/FindMyGUI.cmake index f85b6ba52..6e93a92ce 100644 --- a/cmake/FindMyGUI.cmake +++ b/cmake/FindMyGUI.cmake @@ -146,11 +146,12 @@ IF (MYGUI_FOUND) IF (NOT MYGUI_FIND_QUIETLY) MESSAGE(STATUS "MyGUI version: ${MYGUI_VERSION}") ENDIF (NOT MYGUI_FIND_QUIETLY) - -ELSE (MYGUI_FOUND) - IF (MYGUI_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find MYGUI") - ENDIF (MYGUI_FIND_REQUIRED) ENDIF (MYGUI_FOUND) +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(MyGUI DEFAULT_MSG + MYGUI_INCLUDE_DIRS + FREETYPE_LIBRARIES + MYGUI_LIBRARIES) + CMAKE_POLICY(POP) From 29d74f024910c36ad6a474dbca4ccffe7db2e073 Mon Sep 17 00:00:00 2001 From: slothlife Date: Tue, 8 Sep 2015 22:05:33 -0500 Subject: [PATCH 2/2] Improve thunderstorm support. Reversed settings for thunderstorms. Added thunder support to all weather types. Implemented a simple lightning flash effect similar to MW. --- apps/openmw/mwrender/sky.cpp | 14 --- apps/openmw/mwrender/sky.hpp | 2 - apps/openmw/mwworld/weather.cpp | 169 +++++++++++++++++--------------- apps/openmw/mwworld/weather.hpp | 32 +++--- 4 files changed, 109 insertions(+), 108 deletions(-) diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 138365ae4..dba2e5b0e 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -1181,20 +1181,6 @@ void SkyManager::setSecundaState(const MoonState& state) mSecunda->setState(state); } -void SkyManager::setLightningStrength(const float factor) -{ - if (!mCreated) return; - /* - if (factor > 0.f) - { - mLightning->setDiffuseColour (ColourValue(2*factor, 2*factor, 2*factor)); - mLightning->setVisible(true); - } - else - mLightning->setVisible(false); - */ -} - void SkyManager::setDate(int day, int month) { mDay = day; diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 3855136a9..de27cf447 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -140,8 +140,6 @@ namespace MWRender void setMasserState(const MoonState& state); void setSecundaState(const MoonState& state); - void setLightningStrength(const float factor); - void setGlare(const float glare); void setGlareEnabled(bool enabled); diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index e7c67d2e1..cdd0a8d79 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -80,15 +80,24 @@ Weather::Weather(const std::string& name, , mRainEffect(fallback.getFallbackBool("Weather_" + name + "_Using_Precip") ? "meshes\\raindrop.nif" : "") , mTransitionDelta(fallback.getFallbackFloat("Weather_" + name + "_Transition_Delta")) , mCloudsMaximumPercent(fallback.getFallbackFloat("Weather_" + name + "_Clouds_Maximum_Percent")) + , mThunderFrequency(fallback.getFallbackFloat("Weather_" + name + "_Thunder_Frequency")) + , mThunderThreshold(fallback.getFallbackFloat("Weather_" + name + "_Thunder_Threshold")) + , mThunderSoundID() + , mFlashDecrement(fallback.getFallbackFloat("Weather_" + name + "_Flash_Decrement")) + , mFlashBrightness(0.0f) { -/* -Unhandled: -Rain Diameter=600 ? -Rain Height Min=200 ? -Rain Height Max=700 ? -Rain Threshold=0.6 ? -Max Raindrops=650 ? -*/ + mThunderSoundID[0] = fallback.getFallbackString("Weather_" + name + "_Thunder_Sound_ID_0"); + mThunderSoundID[1] = fallback.getFallbackString("Weather_" + name + "_Thunder_Sound_ID_1"); + mThunderSoundID[2] = fallback.getFallbackString("Weather_" + name + "_Thunder_Sound_ID_2"); + mThunderSoundID[3] = fallback.getFallbackString("Weather_" + name + "_Thunder_Sound_ID_3"); + /* + Unhandled: + Rain Diameter=600 ? + Rain Height Min=200 ? + Rain Height Max=700 ? + Rain Threshold=0.6 ? + Max Raindrops=650 ? + */ } float Weather::transitionDelta() const @@ -98,12 +107,66 @@ float Weather::transitionDelta() const return mTransitionDelta; } -float Weather::cloudBlendFactor(float transitionRatio) const +float Weather::cloudBlendFactor(const float transitionRatio) const { // Clouds Maximum Percent affects how quickly the sky transitions from one sky texture to the next. return transitionRatio / mCloudsMaximumPercent; } +float Weather::calculateThunder(const float transitionRatio, const float elapsedSeconds, const bool isPaused) +{ + // When paused, the flash brightness remains the same and no new strikes can occur. + if(!isPaused) + { + // Morrowind doesn't appear to do any calculations unless the transition ratio is higher than the Thunder Threshold. + if(transitionRatio >= mThunderThreshold && mThunderFrequency > 0.0f) + { + flashDecrement(elapsedSeconds); + + if(Misc::Rng::rollProbability() <= thunderChance(transitionRatio, elapsedSeconds)) + { + lightningAndThunder(); + } + } + else + { + mFlashBrightness = 0.0f; + } + } + + return mFlashBrightness; +} + +inline void Weather::flashDecrement(const float elapsedSeconds) +{ + // The Flash Decrement is measured in whole units per second. This means that if the flash brightness was + // currently 1.0, then it should take approximately 0.25 seconds to decay to 0.0 (the minimum). + float decrement = mFlashDecrement * elapsedSeconds; + mFlashBrightness = decrement > mFlashBrightness ? 0.0f : mFlashBrightness - decrement; +} + +inline float Weather::thunderChance(const float transitionRatio, const float elapsedSeconds) const +{ + // This formula is reversed from the observation that with Thunder Frequency set to 1, there are roughly 10 strikes + // per minute. It doesn't appear to be tied to in game time as Timescale doesn't affect it. Various values of + // Thunder Frequency seem to change the average number of strikes in a linear fashion.. During a transition, it appears to + // scaled based on how far past it is past the Thunder Threshold. + float scaleFactor = (transitionRatio - mThunderThreshold) / (1.0f - mThunderThreshold); + return ((mThunderFrequency * 10.0f) / 60.0f) * elapsedSeconds * scaleFactor; +} + +inline void Weather::lightningAndThunder(void) +{ + // Morrowind seems to vary the intensity of the brightness based on which of the four sound IDs it selects. + // They appear to go from 0 (brightest, closest) to 3 (faintest, farthest). The value of 0.25 per distance + // was derived by setting the Flash Decrement to 0.1 and measuring how long each value took to decay to 0. + // TODO: Determine the distribution of each distance to see if it's evenly weighted. + unsigned int distance = Misc::Rng::rollDice(4); + // Flash brightness appears additive, since if multiple strikes occur, it takes longer for it to decay to 0. + mFlashBrightness += 1 - (distance * 0.25f); + MWBase::Environment::get().getSoundManager()->playSound(mThunderSoundID[distance], 1.0, 1.0); +} + RegionWeather::RegionWeather(const ESM::Region& region) : mWeather(invalidWeatherID) , mChances() @@ -378,19 +441,9 @@ WeatherManager::WeatherManager(MWRender::RenderingManager& rendering, const MWWo , mWeatherSettings() , mMasser("Masser", fallback) , mSecunda("Secunda", fallback) - , mThunderFrequency(fallback.getFallbackFloat("Weather_Thunderstorm_Thunder_Frequency")) - , mThunderThreshold(fallback.getFallbackFloat("Weather_Thunderstorm_Thunder_Threshold")) - , mThunderSoundID0(fallback.getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0")) - , mThunderSoundID1(fallback.getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_1")) - , mThunderSoundID2(fallback.getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_2")) - , mThunderSoundID3(fallback.getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_3")) , mWindSpeed(0.f) , mIsStorm(false) , mStormDirection(0,1,0) - , mThunderSoundDelay(0.25) - , mThunderFlash(0) - , mThunderChance(0) - , mThunderChanceNeeded(50) , mCurrentRegion() , mTimePassed(0) , mFastForward(false) @@ -515,12 +568,11 @@ void WeatherManager::update(float duration, bool paused) if(!exterior) { mRendering.setSkyEnabled(false); - //mRendering->getSkyManager()->setLightningStrength(0.f); stopSounds(); return; } - calculateWeatherResult(time.getHour()); + calculateWeatherResult(time.getHour(), duration, paused); mWindSpeed = mResult.mWindSpeed; mIsStorm = mResult.mIsStorm; @@ -536,8 +588,6 @@ void WeatherManager::update(float duration, bool paused) mRendering.getSkyManager()->setStormDirection(mStormDirection); } - mRendering.configureFog(mResult.mFogDepth, mResult.mFogColor); - // disable sun during night if (time.getHour() >= mNightStart || time.getHour() <= mSunriseTime) mRendering.getSkyManager()->sunDisable(); @@ -577,56 +627,7 @@ void WeatherManager::update(float duration, bool paused) mRendering.getSkyManager()->setMasserState(mMasser.calculateState(time)); mRendering.getSkyManager()->setSecundaState(mSecunda.calculateState(time)); - if (!paused) - { - if(mCurrentWeather == 5 && !inTransition()) - { - if (mThunderFlash > 0) - { - // play the sound after a delay - mThunderSoundDelay -= duration; - if (mThunderSoundDelay <= 0) - { - // pick a random sound - int sound = Misc::Rng::rollDice(4); - std::string* soundName = NULL; - if (sound == 0) soundName = &mThunderSoundID0; - else if (sound == 1) soundName = &mThunderSoundID1; - else if (sound == 2) soundName = &mThunderSoundID2; - else if (sound == 3) soundName = &mThunderSoundID3; - if (soundName) - MWBase::Environment::get().getSoundManager()->playSound(*soundName, 1.0, 1.0); - mThunderSoundDelay = 1000; - } - - mThunderFlash -= duration; - //if (mThunderFlash > 0) - //mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold ); - //else - { - mThunderChanceNeeded = static_cast(Misc::Rng::rollDice(100)); - mThunderChance = 0; - //mRendering->getSkyManager()->setLightningStrength( 0.f ); - } - } - else - { - // no thunder active - mThunderChance += duration*4; // chance increases by 4 percent every second - if (mThunderChance >= mThunderChanceNeeded) - { - mThunderFlash = mThunderThreshold; - - //mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold ); - - mThunderSoundDelay = 0.25; - } - } - } - //else - //mRendering->getSkyManager()->setLightningStrength(0.f); - } - + mRendering.configureFog(mResult.mFogDepth, mResult.mFogColor); mRendering.setAmbientColour(mResult.mAmbientColor); mRendering.setSunColour(mResult.mSunColor); @@ -765,10 +766,6 @@ void WeatherManager::clear() { stopSounds(); - mThunderFlash = 0.0; - mThunderChance = 0.0; - mThunderChanceNeeded = 50.0; - mCurrentRegion = ""; mTimePassed = 0.0f; mWeatherUpdateTime = 0.0f; @@ -921,16 +918,32 @@ inline void WeatherManager::addWeatherTransition(const int weatherID) } } -inline void WeatherManager::calculateWeatherResult(const float gameHour) +inline void WeatherManager::calculateWeatherResult(const float gameHour, + const float elapsedSeconds, + const bool isPaused) { + float flash = 0.0f; if(!inTransition()) { calculateResult(mCurrentWeather, gameHour); + flash = mWeatherSettings[mCurrentWeather].calculateThunder(1.0f, elapsedSeconds, isPaused); } else { calculateTransitionResult(1 - mTransitionFactor, gameHour); + float currentFlash = mWeatherSettings[mCurrentWeather].calculateThunder(mTransitionFactor, + elapsedSeconds, + isPaused); + float nextFlash = mWeatherSettings[mNextWeather].calculateThunder(1 - mTransitionFactor, + elapsedSeconds, + isPaused); + flash = currentFlash + nextFlash; } + osg::Vec4f flashColor(flash, flash, flash, 0.0f); + + mResult.mFogColor += flashColor; + mResult.mAmbientColor += flashColor; + mResult.mSunColor += flashColor; } inline void WeatherManager::calculateResult(const int weatherID, const float gameHour) diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index c808b029b..a0c93a460 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -113,11 +113,27 @@ namespace MWWorld // is broken in the vanilla game and was disabled. float transitionDelta() const; - float cloudBlendFactor(float transitionRatio) const; + float cloudBlendFactor(const float transitionRatio) const; + + float calculateThunder(const float transitionRatio, const float elapsedSeconds, const bool isPaused); private: float mTransitionDelta; float mCloudsMaximumPercent; + + // Note: In MW, only thunderstorms support these attributes, but in the interest of making weather more + // flexible, these settings are imported for all weather types. Only thunderstorms will normally have any + // non-zero values. + float mThunderFrequency; + float mThunderThreshold; + std::string mThunderSoundID[4]; + float mFlashDecrement; + + float mFlashBrightness; + + void flashDecrement(const float elapsedSeconds); + float thunderChance(const float transitionRatio, const float elapsedSeconds) const; + void lightningAndThunder(void); }; /// A class for storing a region's weather. @@ -242,22 +258,10 @@ namespace MWWorld MoonModel mMasser; MoonModel mSecunda; - float mThunderFrequency; - float mThunderThreshold; - std::string mThunderSoundID0; - std::string mThunderSoundID1; - std::string mThunderSoundID2; - std::string mThunderSoundID3; - float mWindSpeed; bool mIsStorm; osg::Vec3f mStormDirection; - float mThunderSoundDelay; - float mThunderFlash; - float mThunderChance; - float mThunderChanceNeeded; - std::string mCurrentRegion; float mTimePassed; bool mFastForward; @@ -288,7 +292,7 @@ namespace MWWorld bool inTransition(); void addWeatherTransition(const int weatherID); - void calculateWeatherResult(const float gameHour); + void calculateWeatherResult(const float gameHour, const float elapsedSeconds, const bool isPaused); void calculateResult(const int weatherID, const float gameHour); void calculateTransitionResult(const float factor, const float gameHour); };