Merge branch 'master' into automove
commit
cd97d0c61c
@ -0,0 +1,104 @@
|
||||
#include "fogmanager.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <components/esm/loadcell.hpp>
|
||||
#include <components/fallback/fallback.hpp>
|
||||
#include <components/sceneutil/util.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
float DLLandFogStart;
|
||||
float DLLandFogEnd;
|
||||
float DLUnderwaterFogStart;
|
||||
float DLUnderwaterFogEnd;
|
||||
float DLInteriorFogStart;
|
||||
float DLInteriorFogEnd;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
FogManager::FogManager()
|
||||
: mLandFogStart(0.f)
|
||||
, mLandFogEnd(std::numeric_limits<float>::max())
|
||||
, mUnderwaterFogStart(0.f)
|
||||
, mUnderwaterFogEnd(std::numeric_limits<float>::max())
|
||||
, mFogColor(osg::Vec4f())
|
||||
, mDistantFog(Settings::Manager::getBool("use distant fog", "Fog"))
|
||||
, mUnderwaterColor(Fallback::Map::getColour("Water_UnderwaterColor"))
|
||||
, mUnderwaterWeight(Fallback::Map::getFloat("Water_UnderwaterColorWeight"))
|
||||
, mUnderwaterIndoorFog(Fallback::Map::getFloat("Water_UnderwaterIndoorFog"))
|
||||
{
|
||||
DLLandFogStart = Settings::Manager::getFloat("distant land fog start", "Fog");
|
||||
DLLandFogEnd = Settings::Manager::getFloat("distant land fog end", "Fog");
|
||||
DLUnderwaterFogStart = Settings::Manager::getFloat("distant underwater fog start", "Fog");
|
||||
DLUnderwaterFogEnd = Settings::Manager::getFloat("distant underwater fog end", "Fog");
|
||||
DLInteriorFogStart = Settings::Manager::getFloat("distant interior fog start", "Fog");
|
||||
DLInteriorFogEnd = Settings::Manager::getFloat("distant interior fog end", "Fog");
|
||||
}
|
||||
|
||||
void FogManager::configure(float viewDistance, const ESM::Cell *cell)
|
||||
{
|
||||
osg::Vec4f color = SceneUtil::colourFromRGB(cell->mAmbi.mFog);
|
||||
|
||||
if (mDistantFog)
|
||||
{
|
||||
float density = std::max(0.2f, cell->mAmbi.mFogDensity);
|
||||
mLandFogStart = DLInteriorFogEnd * (1.0f - density) + DLInteriorFogStart*density;
|
||||
mLandFogEnd = DLInteriorFogEnd;
|
||||
mUnderwaterFogStart = DLUnderwaterFogStart;
|
||||
mUnderwaterFogEnd = DLUnderwaterFogEnd;
|
||||
mFogColor = color;
|
||||
}
|
||||
else
|
||||
configure(viewDistance, cell->mAmbi.mFogDensity, mUnderwaterIndoorFog, 1.0f, 0.0f, color);
|
||||
}
|
||||
|
||||
void FogManager::configure(float viewDistance, float fogDepth, float underwaterFog, float dlFactor, float dlOffset, const osg::Vec4f &color)
|
||||
{
|
||||
if (mDistantFog)
|
||||
{
|
||||
mLandFogStart = dlFactor * (DLLandFogStart - dlOffset * DLLandFogEnd);
|
||||
mLandFogEnd = dlFactor * (1.0f - dlOffset) * DLLandFogEnd;
|
||||
mUnderwaterFogStart = DLUnderwaterFogStart;
|
||||
mUnderwaterFogEnd = DLUnderwaterFogEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fogDepth == 0.0)
|
||||
{
|
||||
mLandFogStart = 0.0f;
|
||||
mLandFogEnd = std::numeric_limits<float>::max();
|
||||
}
|
||||
else
|
||||
{
|
||||
mLandFogStart = viewDistance * (1 - fogDepth);
|
||||
mLandFogEnd = viewDistance;
|
||||
}
|
||||
mUnderwaterFogStart = std::min(viewDistance, 6666.f) * (1 - underwaterFog);
|
||||
mUnderwaterFogEnd = std::min(viewDistance, 6666.f);
|
||||
}
|
||||
mFogColor = color;
|
||||
}
|
||||
|
||||
float FogManager::getFogStart(bool isUnderwater) const
|
||||
{
|
||||
return isUnderwater ? mUnderwaterFogStart : mLandFogStart;
|
||||
}
|
||||
|
||||
float FogManager::getFogEnd(bool isUnderwater) const
|
||||
{
|
||||
return isUnderwater ? mUnderwaterFogEnd : mLandFogEnd;
|
||||
}
|
||||
|
||||
osg::Vec4f FogManager::getFogColor(bool isUnderwater) const
|
||||
{
|
||||
if (isUnderwater)
|
||||
{
|
||||
return mUnderwaterColor * mUnderwaterWeight + mFogColor * (1.f-mUnderwaterWeight);
|
||||
}
|
||||
|
||||
return mFogColor;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
#ifndef OPENMW_MWRENDER_FOGMANAGER_H
|
||||
#define OPENMW_MWRENDER_FOGMANAGER_H
|
||||
|
||||
#include <osg/Vec4f>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
struct Cell;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class FogManager
|
||||
{
|
||||
public:
|
||||
FogManager();
|
||||
|
||||
void configure(float viewDistance, const ESM::Cell *cell);
|
||||
void configure(float viewDistance, float fogDepth, float underwaterFog, float dlFactor, float dlOffset, const osg::Vec4f &color);
|
||||
|
||||
osg::Vec4f getFogColor(bool isUnderwater) const;
|
||||
float getFogStart(bool isUnderwater) const;
|
||||
float getFogEnd(bool isUnderwater) const;
|
||||
|
||||
private:
|
||||
float mLandFogStart;
|
||||
float mLandFogEnd;
|
||||
float mUnderwaterFogStart;
|
||||
float mUnderwaterFogEnd;
|
||||
osg::Vec4f mFogColor;
|
||||
bool mDistantFog;
|
||||
|
||||
osg::Vec4f mUnderwaterColor;
|
||||
float mUnderwaterWeight;
|
||||
float mUnderwaterIndoorFog;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,227 @@
|
||||
#include "datetimemanager.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "esmstore.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "timestamp.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
static int getDaysPerMonth(int month)
|
||||
{
|
||||
switch (month)
|
||||
{
|
||||
case 0: return 31;
|
||||
case 1: return 28;
|
||||
case 2: return 31;
|
||||
case 3: return 30;
|
||||
case 4: return 31;
|
||||
case 5: return 30;
|
||||
case 6: return 31;
|
||||
case 7: return 31;
|
||||
case 8: return 30;
|
||||
case 9: return 31;
|
||||
case 10: return 30;
|
||||
case 11: return 31;
|
||||
}
|
||||
|
||||
throw std::runtime_error ("month out of range");
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
void DateTimeManager::setup(Globals& globalVariables)
|
||||
{
|
||||
mGameHour = globalVariables["gamehour"].getFloat();
|
||||
mDaysPassed = globalVariables["dayspassed"].getInteger();
|
||||
mDay = globalVariables["day"].getInteger();
|
||||
mMonth = globalVariables["month"].getInteger();
|
||||
mYear = globalVariables["year"].getInteger();
|
||||
mTimeScale = globalVariables["timescale"].getFloat();
|
||||
}
|
||||
|
||||
void DateTimeManager::setHour(double hour)
|
||||
{
|
||||
if (hour < 0)
|
||||
hour = 0;
|
||||
|
||||
int days = static_cast<int>(hour / 24);
|
||||
hour = std::fmod(hour, 24);
|
||||
mGameHour = static_cast<float>(hour);
|
||||
|
||||
if (days > 0)
|
||||
setDay(days + mDay);
|
||||
}
|
||||
|
||||
void DateTimeManager::setDay(int day)
|
||||
{
|
||||
if (day < 1)
|
||||
day = 1;
|
||||
|
||||
int month = mMonth;
|
||||
while (true)
|
||||
{
|
||||
int days = getDaysPerMonth(month);
|
||||
if (day <= days)
|
||||
break;
|
||||
|
||||
if (month < 11)
|
||||
{
|
||||
++month;
|
||||
}
|
||||
else
|
||||
{
|
||||
month = 0;
|
||||
mYear++;
|
||||
}
|
||||
|
||||
day -= days;
|
||||
}
|
||||
|
||||
mDay = day;
|
||||
mMonth = month;
|
||||
}
|
||||
|
||||
TimeStamp DateTimeManager::getTimeStamp() const
|
||||
{
|
||||
return TimeStamp(mGameHour, mDaysPassed);
|
||||
}
|
||||
|
||||
float DateTimeManager::getTimeScaleFactor() const
|
||||
{
|
||||
return mTimeScale;
|
||||
}
|
||||
|
||||
ESM::EpochTimeStamp DateTimeManager::getEpochTimeStamp() const
|
||||
{
|
||||
ESM::EpochTimeStamp timeStamp;
|
||||
timeStamp.mGameHour = mGameHour;
|
||||
timeStamp.mDay = mDay;
|
||||
timeStamp.mMonth = mMonth;
|
||||
timeStamp.mYear = mYear;
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
void DateTimeManager::setMonth(int month)
|
||||
{
|
||||
if (month < 0)
|
||||
month = 0;
|
||||
|
||||
int years = month / 12;
|
||||
month = month % 12;
|
||||
|
||||
int days = getDaysPerMonth(month);
|
||||
if (mDay > days)
|
||||
mDay = days;
|
||||
|
||||
mMonth = month;
|
||||
|
||||
if (years > 0)
|
||||
mYear += years;
|
||||
}
|
||||
|
||||
void DateTimeManager::advanceTime(double hours, Globals& globalVariables)
|
||||
{
|
||||
hours += mGameHour;
|
||||
setHour(hours);
|
||||
|
||||
int days = static_cast<int>(hours / 24);
|
||||
if (days > 0)
|
||||
mDaysPassed += days;
|
||||
|
||||
globalVariables["gamehour"].setFloat(mGameHour);
|
||||
globalVariables["dayspassed"].setInteger(mDaysPassed);
|
||||
globalVariables["day"].setInteger(mDay);
|
||||
globalVariables["month"].setInteger(mMonth);
|
||||
globalVariables["year"].setInteger(mYear);
|
||||
}
|
||||
|
||||
std::string DateTimeManager::getMonthName(int month) const
|
||||
{
|
||||
if (month == -1)
|
||||
month = mMonth;
|
||||
|
||||
const int months = 12;
|
||||
if (month < 0 || month >= months)
|
||||
return std::string();
|
||||
|
||||
static const char *monthNames[months] =
|
||||
{
|
||||
"sMonthMorningstar", "sMonthSunsdawn", "sMonthFirstseed", "sMonthRainshand",
|
||||
"sMonthSecondseed", "sMonthMidyear", "sMonthSunsheight", "sMonthLastseed",
|
||||
"sMonthHeartfire", "sMonthFrostfall", "sMonthSunsdusk", "sMonthEveningstar"
|
||||
};
|
||||
|
||||
const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(monthNames[month]);
|
||||
return setting->mValue.getString();
|
||||
}
|
||||
|
||||
bool DateTimeManager::updateGlobalFloat(const std::string& name, float value)
|
||||
{
|
||||
if (name=="gamehour")
|
||||
{
|
||||
setHour(value);
|
||||
return true;
|
||||
}
|
||||
else if (name=="day")
|
||||
{
|
||||
setDay(static_cast<int>(value));
|
||||
return true;
|
||||
}
|
||||
else if (name=="month")
|
||||
{
|
||||
setMonth(static_cast<int>(value));
|
||||
return true;
|
||||
}
|
||||
else if (name=="year")
|
||||
{
|
||||
mYear = static_cast<int>(value);
|
||||
}
|
||||
else if (name=="timescale")
|
||||
{
|
||||
mTimeScale = value;
|
||||
}
|
||||
else if (name=="dayspassed")
|
||||
{
|
||||
mDaysPassed = static_cast<int>(value);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DateTimeManager::updateGlobalInt(const std::string& name, int value)
|
||||
{
|
||||
if (name=="gamehour")
|
||||
{
|
||||
setHour(static_cast<float>(value));
|
||||
return true;
|
||||
}
|
||||
else if (name=="day")
|
||||
{
|
||||
setDay(value);
|
||||
return true;
|
||||
}
|
||||
else if (name=="month")
|
||||
{
|
||||
setMonth(value);
|
||||
return true;
|
||||
}
|
||||
else if (name=="year")
|
||||
{
|
||||
mYear = value;
|
||||
}
|
||||
else if (name=="timescale")
|
||||
{
|
||||
mTimeScale = static_cast<float>(value);
|
||||
}
|
||||
else if (name=="dayspassed")
|
||||
{
|
||||
mDaysPassed = value;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
#ifndef GAME_MWWORLD_DATETIMEMANAGER_H
|
||||
#define GAME_MWWORLD_DATETIMEMANAGER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
struct EpochTimeStamp;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Globals;
|
||||
class TimeStamp;
|
||||
|
||||
class DateTimeManager
|
||||
{
|
||||
int mDaysPassed = 0;
|
||||
int mDay = 0;
|
||||
int mMonth = 0;
|
||||
int mYear = 0;
|
||||
float mGameHour = 0.f;
|
||||
float mTimeScale = 0.f;
|
||||
|
||||
void setHour(double hour);
|
||||
void setDay(int day);
|
||||
void setMonth(int month);
|
||||
|
||||
public:
|
||||
std::string getMonthName(int month) const;
|
||||
TimeStamp getTimeStamp() const;
|
||||
ESM::EpochTimeStamp getEpochTimeStamp() const;
|
||||
float getTimeScaleFactor() const;
|
||||
|
||||
void advanceTime(double hours, Globals& globalVariables);
|
||||
|
||||
void setup(Globals& globalVariables);
|
||||
bool updateGlobalInt(const std::string& name, int value);
|
||||
bool updateGlobalFloat(const std::string& name, float value);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue