forked from mirror/openmw-tes3mp
Hide weather particles underwater (Fixes #2701)
This commit is contained in:
parent
e3b30baff9
commit
209fa52883
3 changed files with 79 additions and 1 deletions
|
@ -450,11 +450,13 @@ namespace MWRender
|
||||||
void RenderingManager::setWaterEnabled(bool enabled)
|
void RenderingManager::setWaterEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
mWater->setEnabled(enabled);
|
mWater->setEnabled(enabled);
|
||||||
|
mSky->setWaterEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::setWaterHeight(float height)
|
void RenderingManager::setWaterHeight(float height)
|
||||||
{
|
{
|
||||||
mWater->setHeight(height);
|
mWater->setHeight(height);
|
||||||
|
mSky->setWaterHeight(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotifyDrawCompletedCallback : public osg::Camera::DrawCallback
|
class NotifyDrawCompletedCallback : public osg::Camera::DrawCallback
|
||||||
|
|
|
@ -262,8 +262,18 @@ public:
|
||||||
|
|
||||||
META_Node(MWRender, CameraRelativeTransform)
|
META_Node(MWRender, CameraRelativeTransform)
|
||||||
|
|
||||||
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor*) const
|
const osg::Vec3f& getLastEyePoint() const
|
||||||
{
|
{
|
||||||
|
return mEyePoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
|
||||||
|
{
|
||||||
|
if (nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
|
||||||
|
{
|
||||||
|
mEyePoint = static_cast<osgUtil::CullVisitor*>(nv)->getEyePoint();
|
||||||
|
}
|
||||||
|
|
||||||
if (_referenceFrame==RELATIVE_RF)
|
if (_referenceFrame==RELATIVE_RF)
|
||||||
{
|
{
|
||||||
matrix.setTrans(osg::Vec3f(0.f,0.f,0.f));
|
matrix.setTrans(osg::Vec3f(0.f,0.f,0.f));
|
||||||
|
@ -322,6 +332,9 @@ public:
|
||||||
cv->getCurrentCullingSet().popCurrentMask();
|
cv->getCurrentCullingSet().popCurrentMask();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private:
|
||||||
|
// eyePoint for the current frame
|
||||||
|
mutable osg::Vec3f mEyePoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModVertexAlphaVisitor : public osg::NodeVisitor
|
class ModVertexAlphaVisitor : public osg::NodeVisitor
|
||||||
|
@ -371,6 +384,45 @@ private:
|
||||||
int mMeshType;
|
int mMeshType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief Hides the node subgraph if the eye point is below water.
|
||||||
|
/// @note Must be added as cull callback.
|
||||||
|
/// @note Meant to be used on a node that is child of a CameraRelativeTransform.
|
||||||
|
/// The current eye point must be retrieved by the CameraRelativeTransform since we can't get it anymore once we are in camera-relative space.
|
||||||
|
class UnderwaterSwitchCallback : public osg::NodeCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UnderwaterSwitchCallback(CameraRelativeTransform* cameraRelativeTransform)
|
||||||
|
: mCameraRelativeTransform(cameraRelativeTransform)
|
||||||
|
, mEnabled(true)
|
||||||
|
, mWaterLevel(0.f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
|
{
|
||||||
|
osg::Vec3f eyePoint = mCameraRelativeTransform->getLastEyePoint();
|
||||||
|
|
||||||
|
if (mEnabled && eyePoint.z() < mWaterLevel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
traverse(node, nv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
mEnabled = enabled;
|
||||||
|
}
|
||||||
|
void setWaterLevel(float waterLevel)
|
||||||
|
{
|
||||||
|
mWaterLevel = waterLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
osg::ref_ptr<CameraRelativeTransform> mCameraRelativeTransform;
|
||||||
|
bool mEnabled;
|
||||||
|
float mWaterLevel;
|
||||||
|
};
|
||||||
|
|
||||||
/// A base class for the sun and moons.
|
/// A base class for the sun and moons.
|
||||||
class CelestialBody
|
class CelestialBody
|
||||||
{
|
{
|
||||||
|
@ -1072,6 +1124,8 @@ SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneMana
|
||||||
// Prevent unwanted clipping by water reflection camera's clipping plane
|
// Prevent unwanted clipping by water reflection camera's clipping plane
|
||||||
mEarlyRenderBinRoot->getOrCreateStateSet()->setMode(GL_CLIP_PLANE0, osg::StateAttribute::OFF);
|
mEarlyRenderBinRoot->getOrCreateStateSet()->setMode(GL_CLIP_PLANE0, osg::StateAttribute::OFF);
|
||||||
mRootNode->addChild(mEarlyRenderBinRoot);
|
mRootNode->addChild(mEarlyRenderBinRoot);
|
||||||
|
|
||||||
|
mUnderwaterSwitch = new UnderwaterSwitchCallback(skyroot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkyManager::create()
|
void SkyManager::create()
|
||||||
|
@ -1319,6 +1373,7 @@ void SkyManager::createRain()
|
||||||
|
|
||||||
mRainFader = new RainFader;
|
mRainFader = new RainFader;
|
||||||
mRainNode->addUpdateCallback(mRainFader);
|
mRainNode->addUpdateCallback(mRainFader);
|
||||||
|
mRainNode->addCullCallback(mUnderwaterSwitch);
|
||||||
|
|
||||||
mRootNode->addChild(mRainNode);
|
mRootNode->addChild(mRainNode);
|
||||||
}
|
}
|
||||||
|
@ -1459,6 +1514,7 @@ void SkyManager::setWeather(const WeatherResult& weather)
|
||||||
if (!mParticleNode)
|
if (!mParticleNode)
|
||||||
{
|
{
|
||||||
mParticleNode = new osg::PositionAttitudeTransform;
|
mParticleNode = new osg::PositionAttitudeTransform;
|
||||||
|
mParticleNode->addCullCallback(mUnderwaterSwitch);
|
||||||
mRootNode->addChild(mParticleNode);
|
mRootNode->addChild(mParticleNode);
|
||||||
}
|
}
|
||||||
mParticleEffect = mSceneManager->createInstance(mCurrentParticleEffect, mParticleNode);
|
mParticleEffect = mSceneManager->createInstance(mCurrentParticleEffect, mParticleNode);
|
||||||
|
@ -1607,4 +1663,14 @@ void SkyManager::setGlareTimeOfDayFade(float val)
|
||||||
mSun->setGlareTimeOfDayFade(val);
|
mSun->setGlareTimeOfDayFade(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkyManager::setWaterHeight(float height)
|
||||||
|
{
|
||||||
|
mUnderwaterSwitch->setWaterLevel(height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setWaterEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
mUnderwaterSwitch->setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace MWRender
|
||||||
class RainShooter;
|
class RainShooter;
|
||||||
class RainFader;
|
class RainFader;
|
||||||
class AlphaFader;
|
class AlphaFader;
|
||||||
|
class UnderwaterSwitchCallback;
|
||||||
|
|
||||||
struct WeatherResult
|
struct WeatherResult
|
||||||
{
|
{
|
||||||
|
@ -100,6 +101,8 @@ namespace MWRender
|
||||||
float mMoonAlpha;
|
float mMoonAlpha;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///@brief The SkyManager handles rendering of the sky domes, celestial bodies as well as other objects that need to be rendered
|
||||||
|
/// relative to the camera (e.g. weather particle effects)
|
||||||
class SkyManager
|
class SkyManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -144,6 +147,12 @@ namespace MWRender
|
||||||
|
|
||||||
void setGlareTimeOfDayFade(float val);
|
void setGlareTimeOfDayFade(float val);
|
||||||
|
|
||||||
|
/// Enable or disable the water plane (used to remove underwater weather particles)
|
||||||
|
void setWaterEnabled(bool enabled);
|
||||||
|
|
||||||
|
/// Set height of water plane (used to remove underwater weather particles)
|
||||||
|
void setWaterHeight(float height);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void create();
|
void create();
|
||||||
///< no need to call this, automatically done on first enable()
|
///< no need to call this, automatically done on first enable()
|
||||||
|
@ -160,6 +169,7 @@ namespace MWRender
|
||||||
osg::ref_ptr<osg::PositionAttitudeTransform> mParticleNode;
|
osg::ref_ptr<osg::PositionAttitudeTransform> mParticleNode;
|
||||||
osg::ref_ptr<osg::Node> mParticleEffect;
|
osg::ref_ptr<osg::Node> mParticleEffect;
|
||||||
std::vector<osg::ref_ptr<AlphaFader> > mParticleFaders;
|
std::vector<osg::ref_ptr<AlphaFader> > mParticleFaders;
|
||||||
|
osg::ref_ptr<UnderwaterSwitchCallback> mUnderwaterSwitch;
|
||||||
|
|
||||||
osg::ref_ptr<osg::PositionAttitudeTransform> mCloudNode;
|
osg::ref_ptr<osg::PositionAttitudeTransform> mCloudNode;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue