1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-10-17 00:46:34 +00:00
openmw/apps/openmw/mwrender/fogmanager.cpp
florent.teppe 531e55e04c Better handling of the esm3 vs esm4 cell problem
Common attribute are in one structure that has two constructors, one for ESM3 vs ESM4 Cell
Mood part of MWWorld::Cell
2023-01-27 13:39:39 +01:00

110 lines
3.8 KiB
C++

#include "fogmanager.hpp"
#include <algorithm>
#include <components/esm/esm3esm4bridge.hpp>
#include <components/esm3/loadcell.hpp>
#include <components/esm4/loadcell.hpp>
#include <components/fallback/fallback.hpp>
#include <components/sceneutil/util.hpp>
#include <components/settings/settings.hpp>
#include <apps/openmw/mwworld/cell.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 MWWorld::Cell& cell)
{
osg::Vec4f color = SceneUtil::colourFromRGB(cell.getMood().mFogColor);
const float fogDensity = cell.getMood().mFogDensity;
if (mDistantFog)
{
float density = std::max(0.2f, fogDensity);
mLandFogStart = DLInteriorFogEnd * (1.0f - density) + DLInteriorFogStart * density;
mLandFogEnd = DLInteriorFogEnd;
mUnderwaterFogStart = DLUnderwaterFogStart;
mUnderwaterFogEnd = DLUnderwaterFogEnd;
mFogColor = color;
}
else
configure(viewDistance, fogDensity, 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, 7168.f) * (1 - underwaterFog);
mUnderwaterFogEnd = std::min(viewDistance, 7168.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;
}
}