forked from mirror/openmw-tes3mp
search for particle system by class name
This commit is contained in:
parent
b95c9ba483
commit
33a1459b11
6 changed files with 65 additions and 17 deletions
|
@ -47,7 +47,7 @@
|
||||||
#include "vismask.hpp"
|
#include "vismask.hpp"
|
||||||
#include "renderbin.hpp"
|
#include "renderbin.hpp"
|
||||||
|
|
||||||
#define PARTICLE_WIDTH 600.0
|
#define RAIN_WIDTH 600.0
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -1344,17 +1344,19 @@ protected:
|
||||||
class WeatherParticleDrawCallback : public osg::Drawable::DrawCallback
|
class WeatherParticleDrawCallback : public osg::Drawable::DrawCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WeatherParticleDrawCallback(MWRender::RenderingManager *renderingManager) : osg::Drawable::DrawCallback()
|
WeatherParticleDrawCallback(MWRender::RenderingManager *renderingManager, float rangeX, float rangeY) : osg::Drawable::DrawCallback()
|
||||||
{
|
{
|
||||||
mRendering = renderingManager;
|
mRendering = renderingManager;
|
||||||
|
mRangeX = rangeX;
|
||||||
|
mRangeY = rangeY;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable *drawable) const
|
virtual void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable *drawable) const
|
||||||
{
|
{
|
||||||
osg::Vec3 cameraPos = mRendering->getCameraPosition();
|
osg::Vec3 cameraPos = mRendering->getCameraPosition();
|
||||||
osg::Vec3 cameraOffset = osg::Vec3(
|
osg::Vec3 cameraOffset = osg::Vec3(
|
||||||
PARTICLE_WIDTH - fmod(cameraPos.x(), PARTICLE_WIDTH / 2),
|
mRangeX - fmod(cameraPos.x(), mRangeX / 2),
|
||||||
PARTICLE_WIDTH - fmod(cameraPos.y(), PARTICLE_WIDTH / 2),
|
mRangeY - fmod(cameraPos.y(), mRangeY / 2),
|
||||||
0);
|
0);
|
||||||
|
|
||||||
osgParticle::ParticleSystem *ps = (osgParticle::ParticleSystem *) drawable;
|
osgParticle::ParticleSystem *ps = (osgParticle::ParticleSystem *) drawable;
|
||||||
|
@ -1362,7 +1364,7 @@ public:
|
||||||
for (int xOff = 0; xOff < 3; xOff++)
|
for (int xOff = 0; xOff < 3; xOff++)
|
||||||
for (int yOff = 0; yOff < 3; yOff++)
|
for (int yOff = 0; yOff < 3; yOff++)
|
||||||
{
|
{
|
||||||
osg::Vec3 offset = cameraOffset + osg::Vec3(-1 * xOff * PARTICLE_WIDTH, -1 * yOff * PARTICLE_WIDTH,0);
|
osg::Vec3 offset = cameraOffset + osg::Vec3(-1 * xOff * mRangeX, -1 * yOff * mRangeY,0);
|
||||||
|
|
||||||
for(int i = 0; i < ps->numParticles(); i++)
|
for(int i = 0; i < ps->numParticles(); i++)
|
||||||
ps->getParticle(i)->setPosition(ps->getParticle(i)->getPosition() + offset);
|
ps->getParticle(i)->setPosition(ps->getParticle(i)->getPosition() + offset);
|
||||||
|
@ -1376,6 +1378,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MWRender::RenderingManager *mRendering;
|
MWRender::RenderingManager *mRendering;
|
||||||
|
float mRangeX, mRangeY;
|
||||||
};
|
};
|
||||||
|
|
||||||
void SkyManager::createRain()
|
void SkyManager::createRain()
|
||||||
|
@ -1386,7 +1389,7 @@ 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->setDrawCallback(new WeatherParticleDrawCallback(mRendering,RAIN_WIDTH,RAIN_WIDTH));
|
||||||
|
|
||||||
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));
|
||||||
|
@ -1413,8 +1416,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(-PARTICLE_WIDTH / 2, PARTICLE_WIDTH / 2); // Rain_Diameter
|
placer->setXRange(-RAIN_WIDTH / 2, RAIN_WIDTH / 2); // Rain_Diameter
|
||||||
placer->setYRange(-PARTICLE_WIDTH / 2, PARTICLE_WIDTH / 2);
|
placer->setYRange(-RAIN_WIDTH / 2, RAIN_WIDTH / 2);
|
||||||
placer->setZRange(300, 300);
|
placer->setZRange(300, 300);
|
||||||
emitter->setPlacer(placer);
|
emitter->setPlacer(placer);
|
||||||
|
|
||||||
|
@ -1493,8 +1496,6 @@ void SkyManager::update(float duration)
|
||||||
osg::Quat quat;
|
osg::Quat quat;
|
||||||
quat.makeRotate(osg::Vec3f(0,1,0), mStormDirection);
|
quat.makeRotate(osg::Vec3f(0,1,0), mStormDirection);
|
||||||
|
|
||||||
if (mParticleNode)
|
|
||||||
mParticleNode->setAttitude(quat);
|
|
||||||
mCloudNode->setAttitude(quat);
|
mCloudNode->setAttitude(quat);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1586,7 +1587,7 @@ void SkyManager::setWeather(const WeatherResult& weather)
|
||||||
{
|
{
|
||||||
if (!mParticleNode)
|
if (!mParticleNode)
|
||||||
{
|
{
|
||||||
mParticleNode = new osg::PositionAttitudeTransform;
|
mParticleNode = new osg::Group;
|
||||||
mParticleNode->addCullCallback(mUnderwaterSwitch);
|
mParticleNode->addCullCallback(mUnderwaterSwitch);
|
||||||
mParticleNode->setNodeMask(Mask_WeatherParticles);
|
mParticleNode->setNodeMask(Mask_WeatherParticles);
|
||||||
mRootNode->addChild(mParticleNode);
|
mRootNode->addChild(mParticleNode);
|
||||||
|
@ -1603,11 +1604,29 @@ void SkyManager::setWeather(const WeatherResult& weather)
|
||||||
SceneUtil::DisableFreezeOnCullVisitor disableFreezeOnCullVisitor;
|
SceneUtil::DisableFreezeOnCullVisitor disableFreezeOnCullVisitor;
|
||||||
mParticleEffect->accept(disableFreezeOnCullVisitor);
|
mParticleEffect->accept(disableFreezeOnCullVisitor);
|
||||||
|
|
||||||
osgParticle::ParticleSystem *ps = (osgParticle::ParticleSystem *)
|
SceneUtil::FindByClassVisitor findEmitterVisitor(std::string("Emitter"));
|
||||||
(mParticleEffect->asGroup()->getChild(1)->asGroup()->getChild(0)
|
mParticleEffect->accept(findEmitterVisitor);
|
||||||
->asGroup()->getChild(2));
|
|
||||||
|
|
||||||
ps->setDrawCallback(new WeatherParticleDrawCallback(mRendering));
|
float rangeX = RAIN_WIDTH;
|
||||||
|
float rangeY = RAIN_WIDTH;
|
||||||
|
|
||||||
|
if (findEmitterVisitor.mFoundNode)
|
||||||
|
{
|
||||||
|
osgParticle::Placer *placer = ((NifOsg::Emitter *) findEmitterVisitor.mFoundNode)->getPlacer();
|
||||||
|
|
||||||
|
if (placer && strcmp(placer->className(),"BoxPlacer") == 0)
|
||||||
|
{
|
||||||
|
rangeX = ((osgParticle::BoxPlacer *) placer)->getXRange().maximum;
|
||||||
|
rangeY = ((osgParticle::BoxPlacer *) placer)->getYRange().maximum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SceneUtil::FindByClassVisitor findPSVisitor(std::string("ParticleSystem"));
|
||||||
|
mParticleEffect->accept(findPSVisitor);
|
||||||
|
|
||||||
|
if (findPSVisitor.mFoundNode)
|
||||||
|
((osgParticle::ParticleSystem *) findPSVisitor.mFoundNode)->setDrawCallback(new WeatherParticleDrawCallback(mRendering,rangeX,rangeY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,7 @@ namespace MWRender
|
||||||
osg::ref_ptr<osg::Group> mRootNode;
|
osg::ref_ptr<osg::Group> mRootNode;
|
||||||
osg::ref_ptr<osg::Group> mEarlyRenderBinRoot;
|
osg::ref_ptr<osg::Group> mEarlyRenderBinRoot;
|
||||||
|
|
||||||
osg::ref_ptr<osg::PositionAttitudeTransform> mParticleNode;
|
osg::ref_ptr<osg::Group> 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<UnderwaterSwitchCallback> mUnderwaterSwitch;
|
||||||
|
|
|
@ -250,6 +250,11 @@ void Emitter::setPlacer(osgParticle::Placer *placer)
|
||||||
mPlacer = placer;
|
mPlacer = placer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osgParticle::Placer *Emitter::getPlacer()
|
||||||
|
{
|
||||||
|
return mPlacer;
|
||||||
|
}
|
||||||
|
|
||||||
void Emitter::setCounter(osgParticle::Counter *counter)
|
void Emitter::setCounter(osgParticle::Counter *counter)
|
||||||
{
|
{
|
||||||
mCounter = counter;
|
mCounter = counter;
|
||||||
|
|
|
@ -225,6 +225,7 @@ namespace NifOsg
|
||||||
|
|
||||||
void setShooter(osgParticle::Shooter* shooter);
|
void setShooter(osgParticle::Shooter* shooter);
|
||||||
void setPlacer(osgParticle::Placer* placer);
|
void setPlacer(osgParticle::Placer* placer);
|
||||||
|
osgParticle::Placer *getPlacer();
|
||||||
void setCounter(osgParticle::Counter* counter);
|
void setCounter(osgParticle::Counter* counter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -19,6 +19,14 @@ namespace SceneUtil
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FindByClassVisitor::apply(osg::Node &node)
|
||||||
|
{
|
||||||
|
if (Misc::StringUtils::ciEqual(node.className(), mNameToFind))
|
||||||
|
mFoundNode = &node;
|
||||||
|
else
|
||||||
|
traverse(node);
|
||||||
|
}
|
||||||
|
|
||||||
void FindByNameVisitor::apply(osg::Group &group)
|
void FindByNameVisitor::apply(osg::Group &group)
|
||||||
{
|
{
|
||||||
if (!checkGroup(group))
|
if (!checkGroup(group))
|
||||||
|
|
|
@ -20,7 +20,6 @@ namespace SceneUtil
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void apply(osg::Group& group);
|
virtual void apply(osg::Group& group);
|
||||||
|
|
||||||
virtual void apply(osg::MatrixTransform& node);
|
virtual void apply(osg::MatrixTransform& node);
|
||||||
virtual void apply(osg::Geometry& node);
|
virtual void apply(osg::Geometry& node);
|
||||||
|
|
||||||
|
@ -30,6 +29,22 @@ namespace SceneUtil
|
||||||
osg::Group* mFoundNode;
|
osg::Group* mFoundNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FindByClassVisitor : public osg::NodeVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FindByClassVisitor(const std::string& nameToFind)
|
||||||
|
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||||
|
, mNameToFind(nameToFind)
|
||||||
|
, mFoundNode(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void apply(osg::Node &node);
|
||||||
|
|
||||||
|
std::string mNameToFind;
|
||||||
|
osg::Node* mFoundNode;
|
||||||
|
};
|
||||||
|
|
||||||
// Disable freezeOnCull for all visited particlesystems
|
// Disable freezeOnCull for all visited particlesystems
|
||||||
class DisableFreezeOnCullVisitor : public osg::NodeVisitor
|
class DisableFreezeOnCullVisitor : public osg::NodeVisitor
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue