Use Glare View for visibility of celestial bodies

Fixed memory leak from Sun and Moon objects by pulling Updaters back out
into separate objects. Removed code related to
mCelestialBodyTransparency.
This commit is contained in:
slothlife 2015-08-07 00:08:18 -05:00
parent 238ae419a3
commit 3235cecddf
4 changed files with 140 additions and 132 deletions

View file

@ -322,8 +322,7 @@ private:
};
/// A base class for the sun and moons.
/// \note Must be stored in an osg::ref_ptr due to being derived from osg::Referenced.
class CelestialBody : public SceneUtil::StateSetUpdater
class CelestialBody
{
public:
CelestialBody(osg::Group* parentNode, float scaleFactor, int numUvSets)
@ -336,14 +335,9 @@ public:
mTransform->addChild(mGeode);
parentNode->addChild(mTransform);
mGeode->addUpdateCallback(this);
}
virtual ~CelestialBody()
{
mGeode->removeUpdateCallback(this);
}
virtual ~CelestialBody() {}
virtual void adjustTransparency(const float ratio) = 0;
@ -365,7 +359,39 @@ class Sun : public CelestialBody
public:
Sun(osg::Group* parentNode, Resource::TextureManager& textureManager)
: CelestialBody(parentNode, 1.0f, 1)
, mTextureManager(textureManager)
, mUpdater(new Updater(textureManager))
{
mGeode->addUpdateCallback(mUpdater);
}
~Sun()
{
mGeode->removeUpdateCallback(mUpdater);
}
virtual void adjustTransparency(const float ratio)
{
mUpdater->mColor.a() = ratio;
}
void setDirection(const osg::Vec3f& direction)
{
osg::Vec3f normalizedDirection = direction / direction.length();
mTransform->setPosition(normalizedDirection * mDistance);
osg::Quat quat;
quat.makeRotate(osg::Vec3f(0.0f, 0.0f, 1.0f), normalizedDirection);
mTransform->setAttitude(quat);
}
private:
struct Updater : public SceneUtil::StateSetUpdater
{
Resource::TextureManager& mTextureManager;
osg::Vec4f mColor;
Updater(Resource::TextureManager& textureManager)
: mTextureManager(textureManager)
, mColor(0.0f, 0.0f, 0.0f, 1.0f)
{
}
@ -386,25 +412,9 @@ public:
osg::Material* mat = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
mat->setDiffuse(osg::Material::FRONT_AND_BACK, mColor);
}
};
virtual void adjustTransparency(const float ratio)
{
mColor.a() = ratio;
}
void setDirection(const osg::Vec3f& direction)
{
osg::Vec3f normalizedDirection = direction / direction.length();
mTransform->setPosition(normalizedDirection * mDistance);
osg::Quat quat;
quat.makeRotate(osg::Vec3f(0.0f, 0.0f, 1.0f), normalizedDirection);
mTransform->setAttitude(quat);
}
private:
Resource::TextureManager& mTextureManager;
osg::Vec4f mColor;
osg::ref_ptr<Updater> mUpdater;
};
class Moon : public CelestialBody
@ -418,15 +428,90 @@ public:
Moon(osg::Group* parentNode, Resource::TextureManager& textureManager, float scaleFactor, Type type)
: CelestialBody(parentNode, scaleFactor, 2)
, mTextureManager(textureManager)
, mType(type)
, mPhase(MoonState::Phase_Unspecified)
, mTransparency(1.0f)
, mShadowBlend(1.0f)
, mMoonColor(1.0f, 1.0f, 1.0f, 1.0f)
, mUpdater(new Updater(textureManager))
{
setPhase(MoonState::Phase_Full);
setVisible(true);
mGeode->addUpdateCallback(mUpdater);
}
~Moon()
{
mGeode->removeUpdateCallback(mUpdater);
}
virtual void adjustTransparency(const float ratio)
{
mUpdater->mTransparency *= ratio;
}
void setState(const MoonState& state)
{
float radsX = ((state.mRotationFromHorizon) * M_PI) / 180.0f;
float radsZ = ((state.mRotationFromNorth) * M_PI) / 180.0f;
osg::Quat rotX(radsX, osg::Vec3f(1.0f, 0.0f, 0.0f));
osg::Quat rotZ(radsZ, osg::Vec3f(0.0f, 0.0f, 1.0f));
osg::Vec3f direction = rotX * rotZ * osg::Vec3f(0.0f, 1.0f, 0.0f);
mTransform->setPosition(direction * mDistance);
// The moon quad is initially oriented facing down, so we need to offset its X-axis
// rotation to rotate it to face the camera when sitting at the horizon.
osg::Quat attX((-M_PI / 2.0f) + radsX, osg::Vec3f(1.0f, 0.0f, 0.0f));
mTransform->setAttitude(attX * rotZ);
setPhase(state.mPhase);
mUpdater->mTransparency = state.mMoonAlpha;
mUpdater->mShadowBlend = state.mShadowBlend;
}
void setAtmosphereColor(const osg::Vec4f& color)
{
mUpdater->mAtmosphereColor = color;
}
void setColor(const osg::Vec4f& color)
{
mUpdater->mMoonColor = color;
}
unsigned int getPhaseInt() const
{
if (mPhase == MoonState::Phase_New) return 0;
else if (mPhase == MoonState::Phase_WaxingCrescent) return 1;
else if (mPhase == MoonState::Phase_WaningCrescent) return 1;
else if (mPhase == MoonState::Phase_FirstQuarter) return 2;
else if (mPhase == MoonState::Phase_ThirdQuarter) return 2;
else if (mPhase == MoonState::Phase_WaxingGibbous) return 3;
else if (mPhase == MoonState::Phase_WaningGibbous) return 3;
else if (mPhase == MoonState::Phase_Full) return 4;
return 0;
}
private:
struct Updater : public SceneUtil::StateSetUpdater
{
Resource::TextureManager& mTextureManager;
osg::ref_ptr<osg::Texture2D> mPhaseTex;
osg::ref_ptr<osg::Texture2D> mCircleTex;
float mTransparency;
float mShadowBlend;
osg::Vec4f mAtmosphereColor;
osg::Vec4f mMoonColor;
Updater(Resource::TextureManager& textureManager)
: mTextureManager(textureManager)
, mPhaseTex()
, mCircleTex()
, mTransparency(1.0f)
, mShadowBlend(1.0f)
, mAtmosphereColor(1.0f, 1.0f, 1.0f, 1.0f)
, mMoonColor(1.0f, 1.0f, 1.0f, 1.0f)
{
}
virtual void setDefaults(osg::StateSet* stateset)
@ -462,66 +547,6 @@ public:
texEnv2->setConstantColor(osg::Vec4f(mAtmosphereColor.x(), mAtmosphereColor.y(), mAtmosphereColor.z(), mTransparency));
}
virtual void adjustTransparency(const float ratio)
{
mTransparency *= ratio;
}
void setState(const MoonState& state)
{
float radsX = ((state.mRotationFromHorizon) * M_PI) / 180.0f;
float radsZ = ((state.mRotationFromNorth) * M_PI) / 180.0f;
osg::Quat rotX(radsX, osg::Vec3f(1.0f, 0.0f, 0.0f));
osg::Quat rotZ(radsZ, osg::Vec3f(0.0f, 0.0f, 1.0f));
osg::Vec3f direction = rotX * rotZ * osg::Vec3f(0.0f, 1.0f, 0.0f);
mTransform->setPosition(direction * mDistance);
// The moon quad is initially oriented facing down, so we need to offset its X-axis
// rotation to rotate it to face the camera when sitting at the horizon.
osg::Quat attX((-M_PI / 2.0f) + radsX, osg::Vec3f(1.0f, 0.0f, 0.0f));
mTransform->setAttitude(attX * rotZ);
setPhase(state.mPhase);
mTransparency = state.mMoonAlpha;
mShadowBlend = state.mShadowBlend;
}
void setAtmosphereColor(const osg::Vec4f& color)
{
mAtmosphereColor = color;
}
void setColor(const osg::Vec4f& color)
{
mMoonColor = color;
}
unsigned int getPhaseInt() const
{
if (mPhase == MoonState::Phase_New) return 0;
else if (mPhase == MoonState::Phase_WaxingCrescent) return 1;
else if (mPhase == MoonState::Phase_WaningCrescent) return 1;
else if (mPhase == MoonState::Phase_FirstQuarter) return 2;
else if (mPhase == MoonState::Phase_ThirdQuarter) return 2;
else if (mPhase == MoonState::Phase_WaxingGibbous) return 3;
else if (mPhase == MoonState::Phase_WaningGibbous) return 3;
else if (mPhase == MoonState::Phase_Full) return 4;
return 0;
}
private:
Resource::TextureManager& mTextureManager;
Type mType;
MoonState::Phase mPhase;
float mTransparency;
float mShadowBlend;
osg::Vec4f mAtmosphereColor;
osg::Vec4f mMoonColor;
osg::ref_ptr<osg::Texture2D> mPhaseTex;
osg::ref_ptr<osg::Texture2D> mCircleTex;
void setTextures(const std::string& phaseTex, const std::string& circleTex)
{
mPhaseTex = mTextureManager.getTexture2D(phaseTex, osg::Texture::CLAMP, osg::Texture::CLAMP);
@ -529,17 +554,25 @@ private:
reset();
}
};
Type mType;
MoonState::Phase mPhase;
osg::ref_ptr<Updater> mUpdater;
void setPhase(const MoonState::Phase& phase)
{
if(mPhase == phase)
return;
mPhase = phase;
std::string textureName = "textures/tx_";
if (mType == Moon::Type_Secunda) textureName += "secunda_";
else textureName += "masser_";
if (mType == Moon::Type_Secunda)
textureName += "secunda_";
else
textureName += "masser_";
if (phase == MoonState::Phase_New) textureName += "new";
else if(phase == MoonState::Phase_WaxingCrescent) textureName += "one_wax";
@ -553,9 +586,9 @@ private:
textureName += ".dds";
if (mType == Moon::Type_Secunda)
setTextures(textureName, "textures/tx_mooncircle_full_s.dds");
mUpdater->setTextures(textureName, "textures/tx_mooncircle_full_s.dds");
else
setTextures(textureName, "textures/tx_mooncircle_full_m.dds");
mUpdater->setTextures(textureName, "textures/tx_mooncircle_full_m.dds");
}
};
@ -621,11 +654,11 @@ void SkyManager::create()
mAtmosphereNightUpdater = new AtmosphereNightUpdater(mSceneManager->getTextureManager());
atmosphereNight->addUpdateCallback(mAtmosphereNightUpdater);
mSun = new Sun(mRootNode, *mSceneManager->getTextureManager());
mSun.reset(new Sun(mRootNode, *mSceneManager->getTextureManager()));
const MWWorld::Fallback* fallback=MWBase::Environment::get().getWorld()->getFallback();
mMasser = new Moon(mRootNode, *mSceneManager->getTextureManager(), fallback->getFallbackFloat("Moons_Masser_Size")/125, Moon::Type_Masser);
mSecunda = new Moon(mRootNode, *mSceneManager->getTextureManager(), fallback->getFallbackFloat("Moons_Secunda_Size")/125, Moon::Type_Secunda);
mMasser.reset(new Moon(mRootNode, *mSceneManager->getTextureManager(), fallback->getFallbackFloat("Moons_Masser_Size")/125, Moon::Type_Masser));
mSecunda.reset(new Moon(mRootNode, *mSceneManager->getTextureManager(), fallback->getFallbackFloat("Moons_Secunda_Size")/125, Moon::Type_Secunda));
mCloudNode = new osg::PositionAttitudeTransform;
mRootNode->addChild(mCloudNode);
@ -1067,11 +1100,11 @@ void SkyManager::setWeather(const WeatherResult& weather)
mCloudSpeed = weather.mCloudSpeed;
mMasser->adjustTransparency(weather.mCelestialBodyTransparency);
mSecunda->adjustTransparency(weather.mCelestialBodyTransparency);
mSun->adjustTransparency(weather.mCelestialBodyTransparency);
mMasser->adjustTransparency(weather.mGlareView);
mSecunda->adjustTransparency(weather.mGlareView);
mSun->adjustTransparency(weather.mGlareView);
float nextStarsOpacity = weather.mNightFade * weather.mCelestialBodyTransparency;
float nextStarsOpacity = weather.mNightFade * weather.mGlareView;
if(weather.mNight && mStarsOpacity != nextStarsOpacity)
{
mStarsOpacity = nextStarsOpacity;

View file

@ -2,6 +2,7 @@
#define OPENMW_MWRENDER_SKY_H
#include <string>
#include <memory>
#include <osg/ref_ptr>
#include <osg/Vec4f>
@ -75,8 +76,6 @@ namespace MWRender
float mRainSpeed;
float mRainFrequency;
float mCelestialBodyTransparency;
};
struct MoonState
@ -179,9 +178,9 @@ namespace MWRender
osg::ref_ptr<AtmosphereUpdater> mAtmosphereUpdater;
osg::ref_ptr<Sun> mSun;
osg::ref_ptr<Moon> mMasser;
osg::ref_ptr<Moon> mSecunda;
std::auto_ptr<Sun> mSun;
std::auto_ptr<Moon> mMasser;
std::auto_ptr<Moon> mSecunda;
osg::ref_ptr<osg::Group> mRainNode;
osg::ref_ptr<osgParticle::ParticleSystem> mRainParticleSystem;

View file

@ -294,54 +294,44 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::F
//Weather
Weather clear;
clear.mObstructsCelestialBodies = false;
setFallbackWeather(clear,"clear");
Weather cloudy;
cloudy.mObstructsCelestialBodies = false;
setFallbackWeather(cloudy,"cloudy");
Weather foggy;
foggy.mObstructsCelestialBodies = false;
setFallbackWeather(foggy,"foggy");
Weather thunderstorm;
thunderstorm.mAmbientLoopSoundID = "rain heavy";
thunderstorm.mRainEffect = "meshes\\raindrop.nif";
thunderstorm.mObstructsCelestialBodies = true;
setFallbackWeather(thunderstorm,"thunderstorm");
Weather rain;
rain.mAmbientLoopSoundID = "rain";
rain.mRainEffect = "meshes\\raindrop.nif";
rain.mObstructsCelestialBodies = true;
setFallbackWeather(rain,"rain");
Weather overcast;
overcast.mObstructsCelestialBodies = true;
setFallbackWeather(overcast,"overcast");
Weather ashstorm;
ashstorm.mAmbientLoopSoundID = "ashstorm";
ashstorm.mParticleEffect = "meshes\\ashcloud.nif";
ashstorm.mObstructsCelestialBodies = true;
setFallbackWeather(ashstorm,"ashstorm");
Weather blight;
blight.mAmbientLoopSoundID = "blight";
blight.mParticleEffect = "meshes\\blightcloud.nif";
blight.mObstructsCelestialBodies = true;
setFallbackWeather(blight,"blight");
Weather snow;
snow.mParticleEffect = "meshes\\snow.nif";
snow.mObstructsCelestialBodies = true;
setFallbackWeather(snow, "snow");
Weather blizzard;
blizzard.mAmbientLoopSoundID = "BM Blizzard";
blizzard.mParticleEffect = "meshes\\blizzard.nif";
blizzard.mObstructsCelestialBodies = true;
setFallbackWeather(blizzard,"blizzard");
}
@ -475,8 +465,6 @@ void WeatherManager::setResult(const std::string& weatherType)
mResult.mNightFade = factor;
}
}
mResult.mCelestialBodyTransparency = current.mObstructsCelestialBodies ? 0.0f : 1.0f;
}
void WeatherManager::transition(float factor)
@ -530,16 +518,6 @@ void WeatherManager::transition(float factor)
mResult.mEffectFade = mResult.mAmbientSoundVolume;
mResult.mAmbientLoopSoundID = other.mAmbientLoopSoundID;
}
const Weather& currentSettings = mWeatherSettings[mCurrentWeather];
const Weather& nextSettings = mWeatherSettings[mNextWeather];
if(currentSettings.mObstructsCelestialBodies && !nextSettings.mObstructsCelestialBodies)
mResult.mCelestialBodyTransparency = factor;
else if(!currentSettings.mObstructsCelestialBodies && nextSettings.mObstructsCelestialBodies)
mResult.mCelestialBodyTransparency = 1 - factor;
else
mResult.mCelestialBodyTransparency = current.mCelestialBodyTransparency;
}
void WeatherManager::update(float duration, bool paused)

View file

@ -80,7 +80,8 @@ namespace MWWorld
// Multiplier for clouds transparency
float mCloudsMaximumPercent;
// Value between 0 and 1, defines the strength of the sun glare effect
// Value between 0 and 1, defines the strength of the sun glare effect.
// Also appears to modify how visible the sun, moons, and stars are for various weather effects.
float mGlareView;
// Sound effect
@ -106,9 +107,6 @@ namespace MWWorld
// Note: For Weather Blight, there is a "Disease Chance" (=0.1) setting. But according to MWSFD this feature
// is broken in the vanilla game and was disabled.
// Some weather patterns will obstruct the moons, sun, and stars.
bool mObstructsCelestialBodies;
};
class MoonModel