1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-25 20:02:40 +01:00

Interpolate between weather types too

This commit is contained in:
Daniel Evans 2018-01-30 01:47:04 +00:00
parent 23fc9bbbe8
commit 9f68e4c95d
4 changed files with 64 additions and 43 deletions

View File

@ -1,34 +1,59 @@
#include "Weather.hpp"
#define MIXPROP(prop) data.prop = glm::mix(x.prop, y.prop, a)
Weather::Entry Weather::getWeatherData(WeatherCondition cond, float tod) {
const auto i = size_t(cond) * 24;
RW_ASSERT(i < entries.size());
size_t hour = std::floor(tod);
const auto& x = entries[i + hour];
const auto& y = entries[i + (hour + 1) % 24];
const float a = tod - std::floor(tod);
Entry data;
MIXPROP(ambientColor);
MIXPROP(directLightColor);
MIXPROP(skyTopColor);
MIXPROP(skyBottomColor);
MIXPROP(sunCoreColor);
MIXPROP(sunCoreSize);
MIXPROP(sunCoronaSize);
MIXPROP(sunBrightness);
MIXPROP(shadowIntensity);
MIXPROP(lightShading);
MIXPROP(poleShading);
MIXPROP(farClipping);
MIXPROP(fogStart);
MIXPROP(amountGroundLight);
MIXPROP(lowCloudColor);
MIXPROP(topCloudColor);
MIXPROP(bottomCloudColor);
return data;
namespace {
Weather::Entry interpolateWeather(const Weather::Entry& a,
const Weather::Entry& b,
float t) {
#define MIXPROP(prop) glm::mix(a.prop, b.prop, t)
return {
MIXPROP(ambientColor),
MIXPROP(directLightColor),
MIXPROP(skyTopColor),
MIXPROP(skyBottomColor),
MIXPROP(sunCoreColor),
MIXPROP(sunCoronaColor),
MIXPROP(sunCoreSize),
MIXPROP(sunCoronaSize),
MIXPROP(sunBrightness),
MIXPROP(shadowIntensity),
MIXPROP(lightShading),
MIXPROP(poleShading),
MIXPROP(farClipping),
MIXPROP(fogStart),
MIXPROP(amountGroundLight),
MIXPROP(lowCloudColor),
MIXPROP(topCloudColor),
MIXPROP(bottomCloudColor),
{}
};
#undef MIXPROP
}
}
Weather::Entry Weather::interpolate(WeatherCondition prev,
WeatherCondition next,
float a, float tod) {
const float t = tod - std::floor(tod);
const auto nI = size_t(next) * 24;
const auto pI = size_t(prev) * 24;
const auto hour = size_t(tod);
RW_ASSERT(nI < entries.size());
const auto& x = entries[nI + hour];
const auto& y = entries[nI + (hour + 1) % 24];
const auto& nextWeather = interpolateWeather(x, y, t);
if (a >= 1.0f) {
return nextWeather;
}
RW_ASSERT(pI < entries.size());
const auto& z = entries[pI + hour];
const auto& w = entries[pI + (hour + 1) % 24];
const auto& prevWeather = interpolateWeather(z, w, t);
return interpolateWeather(prevWeather, nextWeather, a);
}

View File

@ -34,14 +34,9 @@ public:
uint8_t unknown[4];
};
/**
* @brief getWeatherData returns interpolated Weather data for the time of
* day.
* @param cond weather condition
* @param tod float time of day
* @return Correctly interpolated values.
*/
Entry getWeatherData(WeatherCondition condition, float tod);
Entry interpolate(WeatherCondition lastWeather,
WeatherCondition nextWeather,
float a, float tod);
std::vector<Entry> entries;
};

View File

@ -21,7 +21,7 @@ BasicState::BasicState()
, lastWeather{0}
, nextWeather{0}
, forcedWeather{0}
, weatherInterpolation{0}
, weatherInterpolation{1.0}
, weatherType{0}
, cameraData{0}
, cameraData2{0} {

View File

@ -243,10 +243,11 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera& camera,
const auto currentWeather = WeatherCondition(state->basic.nextWeather);
const auto lastWeather = WeatherCondition(state->basic.lastWeather);
/// @todo Interpolate when weatherInterpolation is < 1
RW_UNUSED(lastWeather);
auto weather = world->data->weather.getWeatherData(currentWeather, tod);
const auto weatherTransition = state->basic.weatherInterpolation;
auto weather = world->data->weather.interpolate(lastWeather,
currentWeather,
weatherTransition,
tod);
float theta = (tod / (60.f * 24.f) - 0.5f) * 2.f * glm::pi<float>();
glm::vec3 sunDirection{