forked from mirror/openmw-tes3mp
Rain effect
This commit is contained in:
parent
5ac502d104
commit
3a21f05f6e
2 changed files with 152 additions and 19 deletions
|
@ -7,10 +7,16 @@
|
|||
#include <osg/Material>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
|
||||
#include <osg/TexEnvCombine>
|
||||
#include <osg/TexMat>
|
||||
|
||||
#include <osgParticle/ParticleSystem>
|
||||
#include <osgParticle/ParticleSystemUpdater>
|
||||
#include <osgParticle/ModularEmitter>
|
||||
#include <osgParticle/BoxPlacer>
|
||||
#include <osgParticle/ConstantRateCounter>
|
||||
#include <osgParticle/RadialShooter>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <components/misc/rng.hpp>
|
||||
|
@ -573,6 +579,7 @@ SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneMana
|
|||
, mRainEnabled(false)
|
||||
, mRainSpeed(0)
|
||||
, mRainFrequency(1)
|
||||
, mWindSpeed(0.f)
|
||||
, mEnabled(true)
|
||||
, mSunEnabled(true)
|
||||
{
|
||||
|
@ -642,9 +649,112 @@ void SkyManager::create()
|
|||
mCreated = true;
|
||||
}
|
||||
|
||||
class RainShooter : public osgParticle::Shooter
|
||||
{
|
||||
public:
|
||||
RainShooter()
|
||||
: mAngle(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void shoot(osgParticle::Particle* particle) const
|
||||
{
|
||||
particle->setVelocity(mVelocity);
|
||||
particle->setAngle(osg::Vec3f(-mAngle, 0, (Misc::Rng::rollProbability() * 2 - 1) * osg::PI));
|
||||
}
|
||||
|
||||
void setVelocity(const osg::Vec3f& velocity)
|
||||
{
|
||||
mVelocity = velocity;
|
||||
}
|
||||
|
||||
void setAngle(float angle)
|
||||
{
|
||||
mAngle = angle;
|
||||
}
|
||||
|
||||
virtual osg::Object* cloneType() const
|
||||
{
|
||||
return new RainShooter;
|
||||
}
|
||||
virtual osg::Object* clone(const osg::CopyOp &) const
|
||||
{
|
||||
return new RainShooter(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
osg::Vec3f mVelocity;
|
||||
float mAngle;
|
||||
};
|
||||
|
||||
void SkyManager::createRain()
|
||||
{
|
||||
if (mRainNode)
|
||||
return;
|
||||
|
||||
mRainNode = new osg::Group;
|
||||
|
||||
mRainParticleSystem = new osgParticle::ParticleSystem;
|
||||
mRainParticleSystem->setParticleAlignment(osgParticle::ParticleSystem::FIXED);
|
||||
mRainParticleSystem->setAlignVectorX(osg::Vec3f(0.1,0,0));
|
||||
mRainParticleSystem->setAlignVectorY(osg::Vec3f(0,0,-1));
|
||||
|
||||
osg::ref_ptr<osg::StateSet> stateset (mRainParticleSystem->getOrCreateStateSet());
|
||||
stateset->setTextureAttributeAndModes(0, mSceneManager->getTextureManager()->getTexture2D("textures/tx_raindrop_01.dds",
|
||||
osg::Texture::CLAMP, osg::Texture::CLAMP), osg::StateAttribute::ON);
|
||||
stateset->setNestRenderBins(false);
|
||||
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
|
||||
|
||||
osgParticle::Particle& particleTemplate = mRainParticleSystem->getDefaultParticleTemplate();
|
||||
particleTemplate.setSizeRange(osgParticle::rangef(5.f, 15.f));
|
||||
particleTemplate.setAlphaRange(osgParticle::rangef(1.f, 1.f));
|
||||
particleTemplate.setLifeTime(1);
|
||||
|
||||
osg::ref_ptr<osgParticle::ModularEmitter> emitter (new osgParticle::ModularEmitter);
|
||||
emitter->setParticleSystem(mRainParticleSystem);
|
||||
|
||||
osg::ref_ptr<osgParticle::BoxPlacer> placer (new osgParticle::BoxPlacer);
|
||||
placer->setXRange(-300, 300); // Rain_Diameter
|
||||
placer->setYRange(-300, 300);
|
||||
placer->setZRange(300, 300);
|
||||
emitter->setPlacer(placer);
|
||||
|
||||
osg::ref_ptr<osgParticle::ConstantRateCounter> counter (new osgParticle::ConstantRateCounter);
|
||||
counter->setNumberOfParticlesPerSecondToCreate(600.0);
|
||||
emitter->setCounter(counter);
|
||||
|
||||
osg::ref_ptr<RainShooter> shooter (new RainShooter);
|
||||
mRainShooter = shooter;
|
||||
emitter->setShooter(shooter);
|
||||
|
||||
osg::ref_ptr<osgParticle::ParticleSystemUpdater> updater (new osgParticle::ParticleSystemUpdater);
|
||||
updater->addParticleSystem(mRainParticleSystem);
|
||||
|
||||
osg::ref_ptr<osg::Geode> geode (new osg::Geode);
|
||||
geode->addDrawable(mRainParticleSystem);
|
||||
|
||||
mRainNode->addChild(emitter);
|
||||
mRainNode->addChild(geode);
|
||||
mRainNode->addChild(updater);
|
||||
|
||||
mRootNode->addChild(mRainNode);
|
||||
}
|
||||
|
||||
void SkyManager::destroyRain()
|
||||
{
|
||||
if (!mRainNode)
|
||||
return;
|
||||
|
||||
mRootNode->removeChild(mRainNode);
|
||||
mRainNode = NULL;
|
||||
mRainParticleSystem = NULL;
|
||||
mRainShooter = NULL;
|
||||
}
|
||||
|
||||
SkyManager::~SkyManager()
|
||||
{
|
||||
clearRain();
|
||||
if (mRootNode)
|
||||
{
|
||||
mRootNode->getParent(0)->removeChild(mRootNode);
|
||||
|
@ -664,14 +774,6 @@ int SkyManager::getSecundaPhase() const
|
|||
return mSecunda->getPhaseInt();
|
||||
}
|
||||
|
||||
void SkyManager::clearRain()
|
||||
{
|
||||
}
|
||||
|
||||
void SkyManager::updateRain(float dt)
|
||||
{
|
||||
}
|
||||
|
||||
void SkyManager::update(float duration)
|
||||
{
|
||||
if (!mEnabled) return;
|
||||
|
@ -688,8 +790,6 @@ void SkyManager::update(float duration)
|
|||
else
|
||||
mCloudNode->setAttitude(osg::Quat());
|
||||
|
||||
updateRain(duration);
|
||||
|
||||
// UV Scroll the clouds
|
||||
mCloudAnimationTimer += duration * mCloudSpeed * 0.003;
|
||||
mCloudUpdater->setAnimationTimer(mCloudAnimationTimer);
|
||||
|
@ -736,9 +836,6 @@ void SkyManager::setEnabled(bool enabled)
|
|||
if (enabled && !mCreated)
|
||||
create();
|
||||
|
||||
if (!enabled)
|
||||
clearRain();
|
||||
|
||||
mRootNode->setNodeMask(enabled ? Mask_Sky : 0);
|
||||
|
||||
mEnabled = enabled;
|
||||
|
@ -750,14 +847,38 @@ void SkyManager::setMoonColour (bool red)
|
|||
mSecunda->setColor(red ? mMoonScriptColor : osg::Vec4f(1,1,1,1));
|
||||
}
|
||||
|
||||
void SkyManager::updateRainParameters()
|
||||
{
|
||||
if (mRainShooter)
|
||||
{
|
||||
float angle = mWindSpeed/2.f * osg::PI/4;
|
||||
mRainShooter->setVelocity(osg::Vec3f(0, mRainSpeed * mWindSpeed / 2.f, -mRainSpeed));
|
||||
mRainShooter->setAngle(angle);
|
||||
}
|
||||
}
|
||||
|
||||
void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
|
||||
{
|
||||
if (!mCreated) return;
|
||||
|
||||
mRainEffect = weather.mRainEffect;
|
||||
mRainEnabled = !mRainEffect.empty();
|
||||
if (mRainEffect != weather.mRainEffect)
|
||||
{
|
||||
mRainEffect = weather.mRainEffect;
|
||||
if (!mRainEffect.empty())
|
||||
{
|
||||
createRain();
|
||||
}
|
||||
else
|
||||
{
|
||||
destroyRain();
|
||||
}
|
||||
}
|
||||
|
||||
mRainFrequency = weather.mRainFrequency;
|
||||
mRainSpeed = weather.mRainSpeed;
|
||||
mWindSpeed = weather.mWindSpeed;
|
||||
updateRainParameters();
|
||||
|
||||
mIsStorm = weather.mIsStorm;
|
||||
|
||||
if (mCurrentParticleEffect != weather.mParticleEffect)
|
||||
|
|
|
@ -12,6 +12,11 @@ namespace osg
|
|||
class Material;
|
||||
}
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
class ParticleSystem;
|
||||
}
|
||||
|
||||
namespace Resource
|
||||
{
|
||||
class SceneManager;
|
||||
|
@ -24,6 +29,7 @@ namespace MWRender
|
|||
class CloudUpdater;
|
||||
class Sun;
|
||||
class Moon;
|
||||
class RainShooter;
|
||||
|
||||
class SkyManager
|
||||
{
|
||||
|
@ -87,8 +93,9 @@ namespace MWRender
|
|||
void create();
|
||||
///< no need to call this, automatically done on first enable()
|
||||
|
||||
void updateRain(float dt);
|
||||
void clearRain();
|
||||
void createRain();
|
||||
void destroyRain();
|
||||
void updateRainParameters();
|
||||
|
||||
Resource::SceneManager* mSceneManager;
|
||||
|
||||
|
@ -116,6 +123,10 @@ namespace MWRender
|
|||
std::auto_ptr<Moon> mMasser;
|
||||
std::auto_ptr<Moon> mSecunda;
|
||||
|
||||
osg::ref_ptr<osg::Group> mRainNode;
|
||||
osg::ref_ptr<osgParticle::ParticleSystem> mRainParticleSystem;
|
||||
osg::ref_ptr<RainShooter> mRainShooter;
|
||||
|
||||
bool mCreated;
|
||||
|
||||
bool mIsStorm;
|
||||
|
@ -151,6 +162,7 @@ namespace MWRender
|
|||
std::string mRainEffect;
|
||||
float mRainSpeed;
|
||||
float mRainFrequency;
|
||||
float mWindSpeed;
|
||||
|
||||
bool mEnabled;
|
||||
bool mSunEnabled;
|
||||
|
|
Loading…
Reference in a new issue