use bbox as wrap range & apply to all particle systems

new-script-api
Miloslav Číž 7 years ago
parent 38bfa64100
commit 380a5799dd

@ -48,6 +48,7 @@
#include "renderbin.hpp" #include "renderbin.hpp"
#define RAIN_WIDTH 600.0 #define RAIN_WIDTH 600.0
#define RAIN_HEIGHT 600.0
namespace namespace
{ {
@ -1343,10 +1344,9 @@ protected:
class WeatherParticleDrawCallback : public osg::Drawable::DrawCallback class WeatherParticleDrawCallback : public osg::Drawable::DrawCallback
{ {
public: public:
WeatherParticleDrawCallback(float rangeX, float rangeY) : osg::Drawable::DrawCallback() WeatherParticleDrawCallback(osg::Vec3 wrapRange) : osg::Drawable::DrawCallback()
{ {
mRangeX = rangeX; mWrapRange = wrapRange;
mRangeY = rangeY;
} }
virtual void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable *drawable) const virtual void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable *drawable) const
@ -1355,8 +1355,8 @@ public:
osg::Vec3 cameraPos = renderInfo.getCurrentCamera()->getInverseViewMatrix().getTrans(); osg::Vec3 cameraPos = renderInfo.getCurrentCamera()->getInverseViewMatrix().getTrans();
osg::Vec3 cameraOffset = osg::Vec3( osg::Vec3 cameraOffset = osg::Vec3(
fmod(cameraPos.x(), mRangeX), fmod(cameraPos.x(), mWrapRange.x()),
fmod(cameraPos.y(), mRangeY), fmod(cameraPos.y(), mWrapRange.y()),
0.0); 0.0);
std::vector<osg::Vec3> positionBackups; std::vector<osg::Vec3> positionBackups;
@ -1381,15 +1381,15 @@ public:
particle->setPosition(toWorld.preMult(particle->getPosition())); particle->setPosition(toWorld.preMult(particle->getPosition()));
particle->setPosition(particle->getPosition() - cameraOffset); particle->setPosition(particle->getPosition() - cameraOffset);
if (particle->getPosition().x() > mRangeX / 2.0) // wrap-around effect if (particle->getPosition().x() > mWrapRange.x() / 2.0) // wrap-around effect
particle->setPosition(particle->getPosition() - osg::Vec3(mRangeX,0,0)); particle->setPosition(particle->getPosition() - osg::Vec3(mWrapRange.x(),0,0));
else if (particle->getPosition().x() < -mRangeX / 2.0) else if (particle->getPosition().x() < -mWrapRange.x() / 2.0)
particle->setPosition(particle->getPosition() + osg::Vec3(mRangeX,0,0)); particle->setPosition(particle->getPosition() + osg::Vec3(mWrapRange.x(),0,0));
if (particle->getPosition().y() > mRangeY / 2.0) if (particle->getPosition().y() > mWrapRange.y() / 2.0)
particle->setPosition(particle->getPosition() - osg::Vec3(0,mRangeY,0)); particle->setPosition(particle->getPosition() - osg::Vec3(0,mWrapRange.y(),0));
else if (particle->getPosition().y() < -mRangeY / 2.0) else if (particle->getPosition().y() < -mWrapRange.y() / 2.0)
particle->setPosition(particle->getPosition() + osg::Vec3(0,mRangeY,0)); particle->setPosition(particle->getPosition() + osg::Vec3(0,mWrapRange.y(),0));
particle->setPosition(toLocal.preMult(particle->getPosition())); particle->setPosition(toLocal.preMult(particle->getPosition()));
} }
@ -1401,8 +1401,7 @@ public:
} }
protected: protected:
float mRangeX, mRangeY; osg::Vec3 mWrapRange;
}; };
void SkyManager::createRain() void SkyManager::createRain()
@ -1413,7 +1412,7 @@ void SkyManager::createRain()
mRainNode = new osg::Group; mRainNode = new osg::Group;
mRainParticleSystem = new osgParticle::ParticleSystem; mRainParticleSystem = new osgParticle::ParticleSystem;
mRainParticleSystem->setDrawCallback(new WeatherParticleDrawCallback(RAIN_WIDTH,RAIN_WIDTH)); mRainParticleSystem->setDrawCallback(new WeatherParticleDrawCallback(osg::Vec3(RAIN_WIDTH,RAIN_WIDTH,RAIN_HEIGHT)));
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));
@ -1635,25 +1634,17 @@ void SkyManager::setWeather(const WeatherResult& weather)
SceneUtil::FindByClassVisitor findEmitterVisitor(std::string("Emitter")); SceneUtil::FindByClassVisitor findEmitterVisitor(std::string("Emitter"));
mParticleEffect->accept(findEmitterVisitor); mParticleEffect->accept(findEmitterVisitor);
float rangeX = RAIN_WIDTH; for (unsigned int i = 0; i < findEmitterVisitor.mFoundNodes.size(); i++)
float rangeY = RAIN_WIDTH; {
NifOsg::Emitter *emitter = (NifOsg::Emitter *) findEmitterVisitor.mFoundNodes[i];
NifOsg::ParticleSystem *ps = (NifOsg::ParticleSystem *) emitter->getParticleSystem();
if (findEmitterVisitor.mFoundNode) osg::BoundingBox box = ps->getBoundingBox();
{
osgParticle::Placer *placer = ((NifOsg::Emitter *) findEmitterVisitor.mFoundNode)->getPlacer();
if (placer && strcmp(placer->className(),"BoxPlacer") == 0) osg::Vec3 wrapRange = osg::Vec3(box.xMax() - box.xMin(),box.yMax() - box.yMin(),box.zMax() - box.zMin());
{
rangeX = ((osgParticle::BoxPlacer *) placer)->getXRange().maximum;
rangeY = ((osgParticle::BoxPlacer *) placer)->getYRange().maximum;
}
}
SceneUtil::FindByClassVisitor findPSVisitor(std::string("ParticleSystem")); ps->setDrawCallback(new WeatherParticleDrawCallback(wrapRange));
mParticleEffect->accept(findPSVisitor); }
if (findPSVisitor.mFoundNode)
((osgParticle::ParticleSystem *) findPSVisitor.mFoundNode)->setDrawCallback(new WeatherParticleDrawCallback(rangeX,rangeY));
} }
} }

@ -22,9 +22,9 @@ namespace SceneUtil
void FindByClassVisitor::apply(osg::Node &node) void FindByClassVisitor::apply(osg::Node &node)
{ {
if (Misc::StringUtils::ciEqual(node.className(), mNameToFind)) if (Misc::StringUtils::ciEqual(node.className(), mNameToFind))
mFoundNode = &node; mFoundNodes.push_back(&node);
else
traverse(node); traverse(node);
} }
void FindByNameVisitor::apply(osg::Group &group) void FindByNameVisitor::apply(osg::Group &group)

@ -35,14 +35,13 @@ namespace SceneUtil
FindByClassVisitor(const std::string& nameToFind) FindByClassVisitor(const std::string& nameToFind)
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
, mNameToFind(nameToFind) , mNameToFind(nameToFind)
, mFoundNode(NULL)
{ {
} }
virtual void apply(osg::Node &node); virtual void apply(osg::Node &node);
std::string mNameToFind; std::string mNameToFind;
osg::Node* mFoundNode; std::vector<osg::Node *> mFoundNodes;
}; };
// Disable freezeOnCull for all visited particlesystems // Disable freezeOnCull for all visited particlesystems

Loading…
Cancel
Save