|
|
|
@ -25,6 +25,9 @@
|
|
|
|
|
#include <osgParticle/ConstantRateCounter>
|
|
|
|
|
#include <osgParticle/RadialShooter>
|
|
|
|
|
|
|
|
|
|
#include <osgParticle/Operator>
|
|
|
|
|
#include <osgParticle/ModularProgram>
|
|
|
|
|
|
|
|
|
|
#include <components/misc/rng.hpp>
|
|
|
|
|
|
|
|
|
|
#include <components/misc/resourcehelpers.hpp>
|
|
|
|
@ -48,7 +51,6 @@
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Material> createAlphaTrackingUnlitMaterial()
|
|
|
|
|
{
|
|
|
|
|
osg::ref_ptr<osg::Material> mat = new osg::Material;
|
|
|
|
@ -1093,6 +1095,7 @@ private:
|
|
|
|
|
|
|
|
|
|
SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager)
|
|
|
|
|
: mSceneManager(sceneManager)
|
|
|
|
|
, mCamera(NULL)
|
|
|
|
|
, mAtmosphereNightRoll(0.f)
|
|
|
|
|
, mCreated(false)
|
|
|
|
|
, mIsStorm(false)
|
|
|
|
@ -1337,6 +1340,87 @@ protected:
|
|
|
|
|
osg::Uniform* mRainIntensityUniform;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void SkyManager::setCamera(osg::Camera *camera)
|
|
|
|
|
{
|
|
|
|
|
mCamera = camera;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class WrapAroundOperator : public osgParticle::Operator
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
WrapAroundOperator(osg::Camera *camera, const osg::Vec3 &wrapRange): osgParticle::Operator()
|
|
|
|
|
{
|
|
|
|
|
mCamera = camera;
|
|
|
|
|
mWrapRange = wrapRange;
|
|
|
|
|
mHalfWrapRange = mWrapRange / 2.0;
|
|
|
|
|
mPreviousCameraPosition = getCameraPosition();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual osg::Object *cloneType() const override
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual osg::Object *clone(const osg::CopyOp &op) const override
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void operate(osgParticle::Particle *P, double dt) override
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void operateParticles(osgParticle::ParticleSystem *ps, double dt) override
|
|
|
|
|
{
|
|
|
|
|
osg::Vec3 position = getCameraPosition();
|
|
|
|
|
osg::Vec3 positionDifference = position - mPreviousCameraPosition;
|
|
|
|
|
|
|
|
|
|
osg::Matrix toWorld, toLocal;
|
|
|
|
|
|
|
|
|
|
std::vector<osg::Matrix> worldMatrices = ps->getWorldMatrices();
|
|
|
|
|
|
|
|
|
|
if (!worldMatrices.empty())
|
|
|
|
|
{
|
|
|
|
|
toWorld = worldMatrices[0];
|
|
|
|
|
toLocal.invert(toWorld);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ps->numParticles(); ++i)
|
|
|
|
|
{
|
|
|
|
|
osgParticle::Particle *p = ps->getParticle(i);
|
|
|
|
|
p->setPosition(toWorld.preMult(p->getPosition()));
|
|
|
|
|
p->setPosition(p->getPosition() - positionDifference);
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < 3; ++j) // wrap-around in all 3 dimensions
|
|
|
|
|
{
|
|
|
|
|
osg::Vec3 pos = p->getPosition();
|
|
|
|
|
|
|
|
|
|
if (pos[j] < -mHalfWrapRange[j])
|
|
|
|
|
pos[j] = mHalfWrapRange[j] + fmod(pos[j] - mHalfWrapRange[j],mWrapRange[j]);
|
|
|
|
|
else if (pos[j] > mHalfWrapRange[j])
|
|
|
|
|
pos[j] = fmod(pos[j] + mHalfWrapRange[j],mWrapRange[j]) - mHalfWrapRange[j];
|
|
|
|
|
|
|
|
|
|
p->setPosition(pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p->setPosition(toLocal.preMult(p->getPosition()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mPreviousCameraPosition = position;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
osg::Camera *mCamera;
|
|
|
|
|
osg::Vec3 mPreviousCameraPosition;
|
|
|
|
|
osg::Vec3 mWrapRange;
|
|
|
|
|
osg::Vec3 mHalfWrapRange;
|
|
|
|
|
|
|
|
|
|
osg::Vec3 getCameraPosition()
|
|
|
|
|
{
|
|
|
|
|
return mCamera->getInverseViewMatrix().getTrans();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void SkyManager::createRain()
|
|
|
|
|
{
|
|
|
|
|
if (mRainNode)
|
|
|
|
@ -1345,6 +1429,8 @@ void SkyManager::createRain()
|
|
|
|
|
mRainNode = new osg::Group;
|
|
|
|
|
|
|
|
|
|
mRainParticleSystem = new osgParticle::ParticleSystem;
|
|
|
|
|
osg::Vec3 rainRange = osg::Vec3(600,600,600);
|
|
|
|
|
|
|
|
|
|
mRainParticleSystem->setParticleAlignment(osgParticle::ParticleSystem::FIXED);
|
|
|
|
|
mRainParticleSystem->setAlignVectorX(osg::Vec3f(0.1,0,0));
|
|
|
|
|
mRainParticleSystem->setAlignVectorY(osg::Vec3f(0,0,1));
|
|
|
|
@ -1370,8 +1456,8 @@ void SkyManager::createRain()
|
|
|
|
|
emitter->setParticleSystem(mRainParticleSystem);
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osgParticle::BoxPlacer> placer (new osgParticle::BoxPlacer);
|
|
|
|
|
placer->setXRange(-300, 300); // Rain_Diameter
|
|
|
|
|
placer->setYRange(-300, 300);
|
|
|
|
|
placer->setXRange(-rainRange.x() / 2, rainRange.x() / 2); // Rain_Diameter
|
|
|
|
|
placer->setYRange(-rainRange.y() / 2, rainRange.y() / 2);
|
|
|
|
|
placer->setZRange(300, 300);
|
|
|
|
|
emitter->setPlacer(placer);
|
|
|
|
|
|
|
|
|
@ -1386,6 +1472,11 @@ void SkyManager::createRain()
|
|
|
|
|
osg::ref_ptr<osgParticle::ParticleSystemUpdater> updater (new osgParticle::ParticleSystemUpdater);
|
|
|
|
|
updater->addParticleSystem(mRainParticleSystem);
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osgParticle::ModularProgram> program (new osgParticle::ModularProgram);
|
|
|
|
|
program->addOperator(new WrapAroundOperator(mCamera,rainRange));
|
|
|
|
|
program->setParticleSystem(mRainParticleSystem);
|
|
|
|
|
mRainNode->addChild(program);
|
|
|
|
|
|
|
|
|
|
mRainNode->addChild(emitter);
|
|
|
|
|
mRainNode->addChild(mRainParticleSystem);
|
|
|
|
|
mRainNode->addChild(updater);
|
|
|
|
@ -1452,6 +1543,7 @@ void SkyManager::update(float duration)
|
|
|
|
|
|
|
|
|
|
if (mParticleNode)
|
|
|
|
|
mParticleNode->setAttitude(quat);
|
|
|
|
|
|
|
|
|
|
mCloudNode->setAttitude(quat);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -1559,6 +1651,22 @@ void SkyManager::setWeather(const WeatherResult& weather)
|
|
|
|
|
|
|
|
|
|
SceneUtil::DisableFreezeOnCullVisitor disableFreezeOnCullVisitor;
|
|
|
|
|
mParticleEffect->accept(disableFreezeOnCullVisitor);
|
|
|
|
|
|
|
|
|
|
if (!weather.mIsStorm)
|
|
|
|
|
{
|
|
|
|
|
SceneUtil::FindByClassVisitor findPSVisitor(std::string("ParticleSystem"));
|
|
|
|
|
mParticleEffect->accept(findPSVisitor);
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < findPSVisitor.mFoundNodes.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
osgParticle::ParticleSystem *ps = static_cast<osgParticle::ParticleSystem *>(findPSVisitor.mFoundNodes[i]);
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osgParticle::ModularProgram> program (new osgParticle::ModularProgram);
|
|
|
|
|
program->addOperator(new WrapAroundOperator(mCamera,osg::Vec3(1024,1024,800)));
|
|
|
|
|
program->setParticleSystem(ps);
|
|
|
|
|
mParticleNode->addChild(program);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|