forked from mirror/openmw-tes3mp
Transform world-space particle systems in update callback so that animations are accounted for
This commit is contained in:
parent
0fbd29ccb8
commit
3693f05ef5
1 changed files with 41 additions and 27 deletions
|
@ -31,37 +31,18 @@
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
/// @todo Do this in updateCallback so that animations are accounted for.
|
class InitWorldSpaceParticlesCallback : public osg::NodeCallback
|
||||||
class InitWorldSpaceParticlesVisitor : public osg::NodeVisitor
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// @param mask The node mask to set on ParticleSystem nodes.
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
InitWorldSpaceParticlesVisitor(unsigned int mask)
|
|
||||||
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
|
||||||
, mMask(mask)
|
|
||||||
{
|
{
|
||||||
}
|
osgParticle::ParticleSystem* partsys = static_cast<osgParticle::ParticleSystem*>(node);
|
||||||
|
|
||||||
bool isWorldSpaceParticleSystem(osgParticle::ParticleSystem* partsys)
|
|
||||||
{
|
|
||||||
// HACK: ParticleSystem has no getReferenceFrame()
|
|
||||||
return (partsys->getUserDataContainer()
|
|
||||||
&& partsys->getUserDataContainer()->getNumDescriptions() > 0
|
|
||||||
&& partsys->getUserDataContainer()->getDescriptions()[0] == "worldspace");
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply(osg::Drawable& drw)
|
|
||||||
{
|
|
||||||
if (osgParticle::ParticleSystem* partsys = dynamic_cast<osgParticle::ParticleSystem*>(&drw))
|
|
||||||
{
|
|
||||||
if (isWorldSpaceParticleSystem(partsys))
|
|
||||||
{
|
|
||||||
// HACK: Ignore the InverseWorldMatrix transform the particle system is attached to
|
// HACK: Ignore the InverseWorldMatrix transform the particle system is attached to
|
||||||
if (partsys->getNumParents() && partsys->getParent(0)->getNumParents())
|
if (partsys->getNumParents() && partsys->getParent(0)->getNumParents())
|
||||||
transformInitialParticles(partsys, partsys->getParent(0)->getParent(0));
|
transformInitialParticles(partsys, partsys->getParent(0)->getParent(0));
|
||||||
}
|
|
||||||
partsys->setNodeMask(mMask);
|
node->removeUpdateCallback(this);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void transformInitialParticles(osgParticle::ParticleSystem* partsys, osg::Node* node)
|
void transformInitialParticles(osgParticle::ParticleSystem* partsys, osg::Node* node)
|
||||||
|
@ -83,6 +64,39 @@ namespace
|
||||||
box.expandBy(sphere);
|
box.expandBy(sphere);
|
||||||
partsys->setInitialBound(box);
|
partsys->setInitialBound(box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class InitParticlesVisitor : public osg::NodeVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// @param mask The node mask to set on ParticleSystem nodes.
|
||||||
|
InitParticlesVisitor(unsigned int mask)
|
||||||
|
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||||
|
, mMask(mask)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWorldSpaceParticleSystem(osgParticle::ParticleSystem* partsys)
|
||||||
|
{
|
||||||
|
// HACK: ParticleSystem has no getReferenceFrame()
|
||||||
|
return (partsys->getUserDataContainer()
|
||||||
|
&& partsys->getUserDataContainer()->getNumDescriptions() > 0
|
||||||
|
&& partsys->getUserDataContainer()->getDescriptions()[0] == "worldspace");
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply(osg::Drawable& drw)
|
||||||
|
{
|
||||||
|
if (osgParticle::ParticleSystem* partsys = dynamic_cast<osgParticle::ParticleSystem*>(&drw))
|
||||||
|
{
|
||||||
|
if (isWorldSpaceParticleSystem(partsys))
|
||||||
|
{
|
||||||
|
partsys->addUpdateCallback(new InitWorldSpaceParticlesCallback);
|
||||||
|
}
|
||||||
|
partsys->setNodeMask(mMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int mMask;
|
unsigned int mMask;
|
||||||
};
|
};
|
||||||
|
@ -489,7 +503,7 @@ namespace Resource
|
||||||
// we can skip any scene graphs without update callbacks since we know that particle emitters will have an update callback set
|
// we can skip any scene graphs without update callbacks since we know that particle emitters will have an update callback set
|
||||||
if (node->getNumChildrenRequiringUpdateTraversal() > 0)
|
if (node->getNumChildrenRequiringUpdateTraversal() > 0)
|
||||||
{
|
{
|
||||||
InitWorldSpaceParticlesVisitor visitor (mParticleSystemMask);
|
InitParticlesVisitor visitor (mParticleSystemMask);
|
||||||
node->accept(visitor);
|
node->accept(visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue