forked from mirror/openmw-tes3mp
Create TimeOfDayInterpolator class to refactor time handling in WeatherManager
This commit is contained in:
parent
8da4530957
commit
45bf3e6788
2 changed files with 138 additions and 178 deletions
|
@ -31,17 +31,74 @@ namespace
|
|||
{
|
||||
static const int invalidWeatherID = -1;
|
||||
|
||||
// linear interpolate between x and y based on factor.
|
||||
float lerp (float x, float y, float factor)
|
||||
{
|
||||
return x * (1-factor) + y * factor;
|
||||
}
|
||||
|
||||
// linear interpolate between x and y based on factor.
|
||||
osg::Vec4f lerp (const osg::Vec4f& x, const osg::Vec4f& y, float factor)
|
||||
{
|
||||
return x * (1-factor) + y * factor;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T TimeOfDayInterpolator<T>::getValue(const float gameHour, const TimeOfDaySettings& timeSettings) const
|
||||
{
|
||||
// TODO: use pre/post sunset/sunrise time values in [Weather] section
|
||||
|
||||
// night
|
||||
if (gameHour <= timeSettings.mNightEnd || gameHour >= timeSettings.mNightStart + 1)
|
||||
return mNightValue;
|
||||
// sunrise
|
||||
else if (gameHour >= timeSettings.mNightEnd && gameHour <= timeSettings.mDayStart + 1)
|
||||
{
|
||||
if (gameHour <= timeSettings.mSunriseTime)
|
||||
{
|
||||
// fade in
|
||||
float advance = timeSettings.mSunriseTime - gameHour;
|
||||
float factor = advance / 0.5f;
|
||||
return lerp(mSunriseValue, mNightValue, factor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// fade out
|
||||
float advance = gameHour - timeSettings.mSunriseTime;
|
||||
float factor = advance / 3.f;
|
||||
return lerp(mSunriseValue, mDayValue, factor);
|
||||
}
|
||||
}
|
||||
// day
|
||||
else if (gameHour >= timeSettings.mDayStart + 1 && gameHour <= timeSettings.mDayEnd - 1)
|
||||
return mDayValue;
|
||||
// sunset
|
||||
else if (gameHour >= timeSettings.mDayEnd - 1 && gameHour <= timeSettings.mNightStart + 1)
|
||||
{
|
||||
if (gameHour <= timeSettings.mDayEnd + 1)
|
||||
{
|
||||
// fade in
|
||||
float advance = (timeSettings.mDayEnd + 1) - gameHour;
|
||||
float factor = (advance / 2);
|
||||
return lerp(mSunsetValue, mDayValue, factor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// fade out
|
||||
float advance = gameHour - (timeSettings.mDayEnd + 1);
|
||||
float factor = advance / 2.f;
|
||||
return lerp(mSunsetValue, mNightValue, factor);
|
||||
}
|
||||
}
|
||||
// shut up compiler
|
||||
return T();
|
||||
}
|
||||
|
||||
|
||||
|
||||
template class TimeOfDayInterpolator<float>;
|
||||
template class TimeOfDayInterpolator<osg::Vec4f>;
|
||||
|
||||
Weather::Weather(const std::string& name,
|
||||
const MWWorld::Fallback& fallback,
|
||||
float stormWindSpeed,
|
||||
|
@ -49,22 +106,22 @@ Weather::Weather(const std::string& name,
|
|||
const std::string& ambientLoopSoundID,
|
||||
const std::string& particleEffect)
|
||||
: mCloudTexture(fallback.getFallbackString("Weather_" + name + "_Cloud_Texture"))
|
||||
, mSkySunriseColor(fallback.getFallbackColour("Weather_" + name +"_Sky_Sunrise_Color"))
|
||||
, mSkyDayColor(fallback.getFallbackColour("Weather_" + name + "_Sky_Day_Color"))
|
||||
, mSkySunsetColor(fallback.getFallbackColour("Weather_" + name + "_Sky_Sunset_Color"))
|
||||
, mSkyNightColor(fallback.getFallbackColour("Weather_" + name + "_Sky_Night_Color"))
|
||||
, mFogSunriseColor(fallback.getFallbackColour("Weather_" + name + "_Fog_Sunrise_Color"))
|
||||
, mFogDayColor(fallback.getFallbackColour("Weather_" + name + "_Fog_Day_Color"))
|
||||
, mFogSunsetColor(fallback.getFallbackColour("Weather_" + name + "_Fog_Sunset_Color"))
|
||||
, mFogNightColor(fallback.getFallbackColour("Weather_" + name + "_Fog_Night_Color"))
|
||||
, mAmbientSunriseColor(fallback.getFallbackColour("Weather_" + name + "_Ambient_Sunrise_Color"))
|
||||
, mAmbientDayColor(fallback.getFallbackColour("Weather_" + name + "_Ambient_Day_Color"))
|
||||
, mAmbientSunsetColor(fallback.getFallbackColour("Weather_" + name + "_Ambient_Sunset_Color"))
|
||||
, mAmbientNightColor(fallback.getFallbackColour("Weather_" + name + "_Ambient_Night_Color"))
|
||||
, mSunSunriseColor(fallback.getFallbackColour("Weather_" + name + "_Sun_Sunrise_Color"))
|
||||
, mSunDayColor(fallback.getFallbackColour("Weather_" + name + "_Sun_Day_Color"))
|
||||
, mSunSunsetColor(fallback.getFallbackColour("Weather_" + name + "_Sun_Sunset_Color"))
|
||||
, mSunNightColor(fallback.getFallbackColour("Weather_" + name + "_Sun_Night_Color"))
|
||||
, mSkyColor(fallback.getFallbackColour("Weather_" + name +"_Sky_Sunrise_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Sky_Day_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Sky_Sunset_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Sky_Night_Color"))
|
||||
, mFogColor(fallback.getFallbackColour("Weather_" + name + "_Fog_Sunrise_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Fog_Day_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Fog_Sunset_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Fog_Night_Color"))
|
||||
, mAmbientColor(fallback.getFallbackColour("Weather_" + name + "_Ambient_Sunrise_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Ambient_Day_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Ambient_Sunset_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Ambient_Night_Color"))
|
||||
, mSunColor(fallback.getFallbackColour("Weather_" + name + "_Sun_Sunrise_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Sun_Day_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Sun_Sunset_Color"),
|
||||
fallback.getFallbackColour("Weather_" + name + "_Sun_Night_Color"))
|
||||
, mLandFogDayDepth(fallback.getFallbackFloat("Weather_" + name + "_Land_Fog_Day_Depth"))
|
||||
, mLandFogNightDepth(fallback.getFallbackFloat("Weather_" + name + "_Land_Fog_Night_Depth"))
|
||||
, mSunDiscSunsetColor(fallback.getFallbackColour("Weather_" + name + "_Sun_Disc_Sunset_Color"))
|
||||
|
@ -432,16 +489,13 @@ WeatherManager::WeatherManager(MWRender::RenderingManager& rendering, const MWWo
|
|||
, mSunriseDuration(fallback.getFallbackFloat("Weather_Sunrise_Duration"))
|
||||
, mSunsetDuration(fallback.getFallbackFloat("Weather_Sunset_Duration"))
|
||||
, mSunPreSunsetTime(fallback.getFallbackFloat("Weather_Sun_Pre-Sunset_Time"))
|
||||
, mNightStart(mSunsetTime + mSunsetDuration)
|
||||
, mNightEnd(mSunriseTime - 0.5f)
|
||||
, mDayStart(mSunriseTime + mSunriseDuration)
|
||||
, mDayEnd(mSunsetTime)
|
||||
, mNightFade(0, 0, 0, 1)
|
||||
, mHoursBetweenWeatherChanges(fallback.getFallbackFloat("Weather_Hours_Between_Weather_Changes"))
|
||||
, mRainSpeed(fallback.getFallbackFloat("Weather_Precip_Gravity"))
|
||||
, mUnderwaterSunriseFog(fallback.getFallbackFloat("Water_UnderwaterSunriseFog"))
|
||||
, mUnderwaterDayFog(fallback.getFallbackFloat("Water_UnderwaterDayFog"))
|
||||
, mUnderwaterSunsetFog(fallback.getFallbackFloat("Water_UnderwaterSunsetFog"))
|
||||
, mUnderwaterNightFog(fallback.getFallbackFloat("Water_UnderwaterNightFog"))
|
||||
, mUnderwaterFog(fallback.getFallbackFloat("Water_UnderwaterSunriseFog"),
|
||||
fallback.getFallbackFloat("Water_UnderwaterDayFog"),
|
||||
fallback.getFallbackFloat("Water_UnderwaterSunsetFog"),
|
||||
fallback.getFallbackFloat("Water_UnderwaterNightFog"))
|
||||
, mWeatherSettings()
|
||||
, mMasser("Masser", fallback)
|
||||
, mSecunda("Secunda", fallback)
|
||||
|
@ -461,6 +515,12 @@ WeatherManager::WeatherManager(MWRender::RenderingManager& rendering, const MWWo
|
|||
, mAmbientSound()
|
||||
, mPlayingSoundID()
|
||||
{
|
||||
mTimeSettings.mNightStart = mSunsetTime + mSunsetDuration;
|
||||
mTimeSettings.mNightEnd = mSunriseTime - 0.5f;
|
||||
mTimeSettings.mDayStart = mSunriseTime + mSunriseDuration;
|
||||
mTimeSettings.mDayEnd = mSunsetTime;
|
||||
mTimeSettings.mSunriseTime = mSunriseTime;
|
||||
|
||||
mWeatherSettings.reserve(10);
|
||||
addWeather("Clear", fallback); // 0
|
||||
addWeather("Cloudy", fallback); // 1
|
||||
|
@ -593,7 +653,7 @@ void WeatherManager::update(float duration, bool paused)
|
|||
}
|
||||
|
||||
// disable sun during night
|
||||
if (time.getHour() >= mNightStart || time.getHour() <= mSunriseTime)
|
||||
if (time.getHour() >= mTimeSettings.mNightStart || time.getHour() <= mSunriseTime)
|
||||
mRendering.getSkyManager()->sunDisable();
|
||||
else
|
||||
mRendering.getSkyManager()->sunEnable();
|
||||
|
@ -604,10 +664,10 @@ void WeatherManager::update(float duration, bool paused)
|
|||
{
|
||||
// Shift times into a 24-hour window beginning at mSunriseTime...
|
||||
float adjustedHour = time.getHour();
|
||||
float adjustedNightStart = mNightStart;
|
||||
float adjustedNightStart = mTimeSettings.mNightStart;
|
||||
if ( time.getHour() < mSunriseTime )
|
||||
adjustedHour += 24.f;
|
||||
if ( mNightStart < mSunriseTime )
|
||||
if ( mTimeSettings.mNightStart < mSunriseTime )
|
||||
adjustedNightStart += 24.f;
|
||||
|
||||
const bool is_night = adjustedHour >= adjustedNightStart;
|
||||
|
@ -628,52 +688,7 @@ void WeatherManager::update(float duration, bool paused)
|
|||
mRendering.setSunDirection( final * -1 );
|
||||
}
|
||||
|
||||
// TODO: use pre/post sunset/sunrise time values in [Weather] section
|
||||
// TODO: factor out the time of day interpolation code to reuse for calculateWeatherResult()
|
||||
float gameHour = time.getHour();
|
||||
float underwaterFog;
|
||||
// night
|
||||
if (gameHour <= mNightEnd || gameHour >= mNightStart + 1)
|
||||
underwaterFog = mUnderwaterNightFog;
|
||||
// sunrise
|
||||
else if (gameHour >= mNightEnd && gameHour <= mDayStart + 1)
|
||||
{
|
||||
if (gameHour <= mSunriseTime)
|
||||
{
|
||||
// fade in
|
||||
float advance = mSunriseTime - gameHour;
|
||||
float factor = advance / 0.5f;
|
||||
underwaterFog = lerp(mUnderwaterSunriseFog, mUnderwaterNightFog, factor);
|
||||
}
|
||||
else //if (gameHour >= 6)
|
||||
{
|
||||
// fade out
|
||||
float advance = gameHour - mSunriseTime;
|
||||
float factor = advance / 3.f;
|
||||
underwaterFog = lerp(mUnderwaterSunriseFog, mUnderwaterDayFog, factor);
|
||||
}
|
||||
}
|
||||
// day
|
||||
else if (gameHour >= mDayStart + 1 && gameHour <= mDayEnd - 1)
|
||||
underwaterFog = mUnderwaterDayFog;
|
||||
// sunset
|
||||
else if (gameHour >= mDayEnd - 1 && gameHour <= mNightStart + 1)
|
||||
{
|
||||
if (gameHour <= mDayEnd + 1)
|
||||
{
|
||||
// fade in
|
||||
float advance = (mDayEnd + 1) - gameHour;
|
||||
float factor = (advance / 2);
|
||||
underwaterFog = lerp(mUnderwaterSunsetFog, mUnderwaterDayFog, factor);
|
||||
}
|
||||
else //if (gameHour >= 19)
|
||||
{
|
||||
// fade out
|
||||
float advance = gameHour - (mDayEnd + 1);
|
||||
float factor = advance / 2.f;
|
||||
underwaterFog = lerp(mUnderwaterSunsetFog, mUnderwaterNightFog, factor);
|
||||
}
|
||||
}
|
||||
float underwaterFog = mUnderwaterFog.getValue(time.getHour(), mTimeSettings);
|
||||
|
||||
float peakHour = mSunriseTime + (mSunsetTime - mSunriseTime) / 2;
|
||||
if (time.getHour() < mSunriseTime || time.getHour() > mSunsetTime)
|
||||
|
@ -748,7 +763,7 @@ bool WeatherManager::isDark() const
|
|||
TimeStamp time = MWBase::Environment::get().getWorld()->getTimeStamp();
|
||||
bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior()
|
||||
|| MWBase::Environment::get().getWorld()->isCellQuasiExterior());
|
||||
return exterior && (time.getHour() < mSunriseTime || time.getHour() > mNightStart - 1);
|
||||
return exterior && (time.getHour() < mSunriseTime || time.getHour() > mTimeSettings.mNightStart - 1);
|
||||
}
|
||||
|
||||
void WeatherManager::write(ESM::ESMWriter& writer, Loading::Listener& progress)
|
||||
|
@ -1026,81 +1041,15 @@ inline void WeatherManager::calculateResult(const int weatherID, const float gam
|
|||
mResult.mParticleEffect = current.mParticleEffect;
|
||||
mResult.mRainEffect = current.mRainEffect;
|
||||
|
||||
mResult.mNight = (gameHour < mSunriseTime || gameHour > mNightStart - 1);
|
||||
mResult.mNight = (gameHour < mSunriseTime || gameHour > mTimeSettings.mNightStart - 1);
|
||||
|
||||
mResult.mFogDepth = mResult.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth;
|
||||
|
||||
// TODO: use pre/post sunset/sunrise time values in [Weather] section
|
||||
// night
|
||||
if (gameHour <= mNightEnd || gameHour >= mNightStart + 1)
|
||||
{
|
||||
mResult.mFogColor = current.mFogNightColor;
|
||||
mResult.mAmbientColor = current.mAmbientNightColor;
|
||||
mResult.mSunColor = current.mSunNightColor;
|
||||
mResult.mSkyColor = current.mSkyNightColor;
|
||||
mResult.mNightFade = 1.f;
|
||||
}
|
||||
|
||||
// sunrise
|
||||
else if (gameHour >= mNightEnd && gameHour <= mDayStart + 1)
|
||||
{
|
||||
if (gameHour <= mSunriseTime)
|
||||
{
|
||||
// fade in
|
||||
float advance = mSunriseTime - gameHour;
|
||||
float factor = advance / 0.5f;
|
||||
mResult.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor, factor);
|
||||
mResult.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor, factor);
|
||||
mResult.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor, factor);
|
||||
mResult.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor, factor);
|
||||
mResult.mNightFade = factor;
|
||||
}
|
||||
else //if (gameHour >= 6)
|
||||
{
|
||||
// fade out
|
||||
float advance = gameHour - mSunriseTime;
|
||||
float factor = advance / 3.f;
|
||||
mResult.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor, factor);
|
||||
mResult.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor, factor);
|
||||
mResult.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor, factor);
|
||||
mResult.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor, factor);
|
||||
}
|
||||
}
|
||||
|
||||
// day
|
||||
else if (gameHour >= mDayStart + 1 && gameHour <= mDayEnd - 1)
|
||||
{
|
||||
mResult.mFogColor = current.mFogDayColor;
|
||||
mResult.mAmbientColor = current.mAmbientDayColor;
|
||||
mResult.mSunColor = current.mSunDayColor;
|
||||
mResult.mSkyColor = current.mSkyDayColor;
|
||||
}
|
||||
|
||||
// sunset
|
||||
else if (gameHour >= mDayEnd - 1 && gameHour <= mNightStart + 1)
|
||||
{
|
||||
if (gameHour <= mDayEnd + 1)
|
||||
{
|
||||
// fade in
|
||||
float advance = (mDayEnd + 1) - gameHour;
|
||||
float factor = (advance / 2);
|
||||
mResult.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor, factor);
|
||||
mResult.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor, factor);
|
||||
mResult.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor, factor);
|
||||
mResult.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor, factor);
|
||||
}
|
||||
else //if (gameHour >= 19)
|
||||
{
|
||||
// fade out
|
||||
float advance = gameHour - (mDayEnd + 1);
|
||||
float factor = advance / 2.f;
|
||||
mResult.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor, factor);
|
||||
mResult.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor, factor);
|
||||
mResult.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor, factor);
|
||||
mResult.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor, factor);
|
||||
mResult.mNightFade = factor;
|
||||
}
|
||||
}
|
||||
mResult.mFogColor = current.mFogColor.getValue(gameHour, mTimeSettings);
|
||||
mResult.mAmbientColor = current.mAmbientColor.getValue(gameHour, mTimeSettings);
|
||||
mResult.mSunColor = current.mSunColor.getValue(gameHour, mTimeSettings);
|
||||
mResult.mSkyColor = current.mSkyColor.getValue(gameHour, mTimeSettings);
|
||||
mResult.mNightFade = mNightFade.getValue(gameHour, mTimeSettings);
|
||||
|
||||
if (gameHour >= mSunsetTime - mSunPreSunsetTime)
|
||||
{
|
||||
|
|
|
@ -34,6 +34,33 @@ namespace MWWorld
|
|||
class Fallback;
|
||||
class TimeStamp;
|
||||
|
||||
|
||||
struct TimeOfDaySettings
|
||||
{
|
||||
float mNightStart;
|
||||
float mNightEnd;
|
||||
float mDayStart;
|
||||
float mDayEnd;
|
||||
float mSunriseTime;
|
||||
};
|
||||
|
||||
/// Interpolates between 4 data points (sunrise, day, sunset, night) based on the time of day.
|
||||
/// The template value could be a floating point number, or a color.
|
||||
template <typename T>
|
||||
class TimeOfDayInterpolator
|
||||
{
|
||||
public:
|
||||
TimeOfDayInterpolator(const T& sunrise, const T& day, const T& sunset, const T& night)
|
||||
: mSunriseValue(sunrise), mDayValue(day), mSunsetValue(sunset), mNightValue(night)
|
||||
{
|
||||
}
|
||||
|
||||
T getValue (const float gameHour, const TimeOfDaySettings& timeSettings) const;
|
||||
|
||||
private:
|
||||
T mSunriseValue, mDayValue, mSunsetValue, mNightValue;
|
||||
};
|
||||
|
||||
/// Defines a single weather setting (according to INI)
|
||||
class Weather
|
||||
{
|
||||
|
@ -47,29 +74,14 @@ namespace MWWorld
|
|||
|
||||
std::string mCloudTexture;
|
||||
|
||||
// Sky (atmosphere) colors
|
||||
osg::Vec4f mSkySunriseColor;
|
||||
osg::Vec4f mSkyDayColor;
|
||||
osg::Vec4f mSkySunsetColor;
|
||||
osg::Vec4f mSkyNightColor;
|
||||
|
||||
// Fog colors
|
||||
osg::Vec4f mFogSunriseColor;
|
||||
osg::Vec4f mFogDayColor;
|
||||
osg::Vec4f mFogSunsetColor;
|
||||
osg::Vec4f mFogNightColor;
|
||||
|
||||
// Ambient lighting colors
|
||||
osg::Vec4f mAmbientSunriseColor;
|
||||
osg::Vec4f mAmbientDayColor;
|
||||
osg::Vec4f mAmbientSunsetColor;
|
||||
osg::Vec4f mAmbientNightColor;
|
||||
|
||||
// Sun (directional) lighting colors
|
||||
osg::Vec4f mSunSunriseColor;
|
||||
osg::Vec4f mSunDayColor;
|
||||
osg::Vec4f mSunSunsetColor;
|
||||
osg::Vec4f mSunNightColor;
|
||||
// Sky (atmosphere) color
|
||||
TimeOfDayInterpolator<osg::Vec4f> mSkyColor;
|
||||
// Fog color
|
||||
TimeOfDayInterpolator<osg::Vec4f> mFogColor;
|
||||
// Ambient lighting color
|
||||
TimeOfDayInterpolator<osg::Vec4f> mAmbientColor;
|
||||
// Sun (directional) lighting color
|
||||
TimeOfDayInterpolator<osg::Vec4f> mSunColor;
|
||||
|
||||
// Fog depth/density
|
||||
float mLandFogDayDepth;
|
||||
|
@ -243,18 +255,17 @@ namespace MWWorld
|
|||
float mSunriseDuration;
|
||||
float mSunsetDuration;
|
||||
float mSunPreSunsetTime;
|
||||
float mNightStart;
|
||||
float mNightEnd;
|
||||
float mDayStart;
|
||||
float mDayEnd;
|
||||
|
||||
TimeOfDaySettings mTimeSettings;
|
||||
|
||||
// fading of night skydome
|
||||
TimeOfDayInterpolator<float> mNightFade;
|
||||
|
||||
float mHoursBetweenWeatherChanges;
|
||||
float mRainSpeed;
|
||||
|
||||
// underwater fog not really related to weather, but we handle it here because it's convenient
|
||||
float mUnderwaterSunriseFog;
|
||||
float mUnderwaterDayFog;
|
||||
float mUnderwaterSunsetFog;
|
||||
float mUnderwaterNightFog;
|
||||
TimeOfDayInterpolator<float> mUnderwaterFog;
|
||||
|
||||
std::vector<Weather> mWeatherSettings;
|
||||
MoonModel mMasser;
|
||||
|
|
Loading…
Reference in a new issue