1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-04-10 15:45:37 +00:00

rain independent from camera plus wrap-around

This commit is contained in:
Miloslav Číž 2017-10-04 16:41:55 +02:00
parent 4999c667b6
commit b95c9ba483
3 changed files with 57 additions and 5 deletions

View File

@ -255,7 +255,7 @@ namespace MWRender
mRootNode->getOrCreateStateSet()->addUniform(mUniformRainIntensity); mRootNode->getOrCreateStateSet()->addUniform(mUniformRainIntensity);
mSky.reset(new SkyManager(sceneRoot, resourceSystem->getSceneManager())); mSky.reset(new SkyManager(sceneRoot, resourceSystem->getSceneManager(), this));
source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON); source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON);

View File

@ -39,6 +39,7 @@
#include <components/sceneutil/statesetupdater.hpp> #include <components/sceneutil/statesetupdater.hpp>
#include <components/sceneutil/controller.hpp> #include <components/sceneutil/controller.hpp>
#include <components/sceneutil/visitor.hpp> #include <components/sceneutil/visitor.hpp>
#include <components/nifosg/particle.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -46,6 +47,8 @@
#include "vismask.hpp" #include "vismask.hpp"
#include "renderbin.hpp" #include "renderbin.hpp"
#define PARTICLE_WIDTH 600.0
namespace namespace
{ {
@ -1091,8 +1094,9 @@ private:
} }
}; };
SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager) SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager, MWRender::RenderingManager *renderingManager)
: mSceneManager(sceneManager) : mSceneManager(sceneManager)
, mRendering(renderingManager)
, mAtmosphereNightRoll(0.f) , mAtmosphereNightRoll(0.f)
, mCreated(false) , mCreated(false)
, mIsStorm(false) , mIsStorm(false)
@ -1337,6 +1341,43 @@ protected:
osg::Uniform* mRainIntensityUniform; osg::Uniform* mRainIntensityUniform;
}; };
class WeatherParticleDrawCallback : public osg::Drawable::DrawCallback
{
public:
WeatherParticleDrawCallback(MWRender::RenderingManager *renderingManager) : osg::Drawable::DrawCallback()
{
mRendering = renderingManager;
}
virtual void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable *drawable) const
{
osg::Vec3 cameraPos = mRendering->getCameraPosition();
osg::Vec3 cameraOffset = osg::Vec3(
PARTICLE_WIDTH - fmod(cameraPos.x(), PARTICLE_WIDTH / 2),
PARTICLE_WIDTH - fmod(cameraPos.y(), PARTICLE_WIDTH / 2),
0);
osgParticle::ParticleSystem *ps = (osgParticle::ParticleSystem *) drawable;
for (int xOff = 0; xOff < 3; xOff++)
for (int yOff = 0; yOff < 3; yOff++)
{
osg::Vec3 offset = cameraOffset + osg::Vec3(-1 * xOff * PARTICLE_WIDTH, -1 * yOff * PARTICLE_WIDTH,0);
for(int i = 0; i < ps->numParticles(); i++)
ps->getParticle(i)->setPosition(ps->getParticle(i)->getPosition() + offset);
ps->drawImplementation(renderInfo);
for(int i = 0; i < ps->numParticles(); i++)
ps->getParticle(i)->setPosition(ps->getParticle(i)->getPosition() - offset);
}
}
protected:
MWRender::RenderingManager *mRendering;
};
void SkyManager::createRain() void SkyManager::createRain()
{ {
if (mRainNode) if (mRainNode)
@ -1345,6 +1386,8 @@ void SkyManager::createRain()
mRainNode = new osg::Group; mRainNode = new osg::Group;
mRainParticleSystem = new osgParticle::ParticleSystem; mRainParticleSystem = new osgParticle::ParticleSystem;
mRainParticleSystem->setDrawCallback(new WeatherParticleDrawCallback(mRendering));
mRainParticleSystem->setParticleAlignment(osgParticle::ParticleSystem::FIXED); mRainParticleSystem->setParticleAlignment(osgParticle::ParticleSystem::FIXED);
mRainParticleSystem->setAlignVectorX(osg::Vec3f(0.1,0,0)); mRainParticleSystem->setAlignVectorX(osg::Vec3f(0.1,0,0));
mRainParticleSystem->setAlignVectorY(osg::Vec3f(0,0,1)); mRainParticleSystem->setAlignVectorY(osg::Vec3f(0,0,1));
@ -1370,8 +1413,8 @@ void SkyManager::createRain()
emitter->setParticleSystem(mRainParticleSystem); emitter->setParticleSystem(mRainParticleSystem);
osg::ref_ptr<osgParticle::BoxPlacer> placer (new osgParticle::BoxPlacer); osg::ref_ptr<osgParticle::BoxPlacer> placer (new osgParticle::BoxPlacer);
placer->setXRange(-300, 300); // Rain_Diameter placer->setXRange(-PARTICLE_WIDTH / 2, PARTICLE_WIDTH / 2); // Rain_Diameter
placer->setYRange(-300, 300); placer->setYRange(-PARTICLE_WIDTH / 2, PARTICLE_WIDTH / 2);
placer->setZRange(300, 300); placer->setZRange(300, 300);
emitter->setPlacer(placer); emitter->setPlacer(placer);
@ -1559,6 +1602,12 @@ void SkyManager::setWeather(const WeatherResult& weather)
SceneUtil::DisableFreezeOnCullVisitor disableFreezeOnCullVisitor; SceneUtil::DisableFreezeOnCullVisitor disableFreezeOnCullVisitor;
mParticleEffect->accept(disableFreezeOnCullVisitor); mParticleEffect->accept(disableFreezeOnCullVisitor);
osgParticle::ParticleSystem *ps = (osgParticle::ParticleSystem *)
(mParticleEffect->asGroup()->getChild(1)->asGroup()->getChild(0)
->asGroup()->getChild(2));
ps->setDrawCallback(new WeatherParticleDrawCallback(mRendering));
} }
} }

View File

@ -9,6 +9,8 @@
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osg/Vec4f> #include <osg/Vec4f>
#include <apps/openmw/mwrender/renderingmanager.hpp>
namespace osg namespace osg
{ {
class Group; class Group;
@ -108,7 +110,7 @@ namespace MWRender
class SkyManager class SkyManager
{ {
public: public:
SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager); SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager, MWRender::RenderingManager *renderingManager);
~SkyManager(); ~SkyManager();
void update(float duration); void update(float duration);
@ -170,6 +172,7 @@ namespace MWRender
void updateRainParameters(); void updateRainParameters();
Resource::SceneManager* mSceneManager; Resource::SceneManager* mSceneManager;
MWRender::RenderingManager *mRendering;
osg::ref_ptr<osg::Group> mRootNode; osg::ref_ptr<osg::Group> mRootNode;
osg::ref_ptr<osg::Group> mEarlyRenderBinRoot; osg::ref_ptr<osg::Group> mEarlyRenderBinRoot;