search for particle system by class name

new-script-api
Miloslav Číž 7 years ago
parent b95c9ba483
commit 33a1459b11

@ -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…
Cancel
Save