mirror of https://github.com/OpenMW/openmw.git
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