1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
#include "clone.hpp"
#include <osg/StateSet>
#include <osgAnimation/MorphGeometry>
#include <osgAnimation/RigGeometry>
#include <osgParticle/Emitter>
#include <osgParticle/ParticleProcessor>
#include <osgParticle/ParticleSystemUpdater>
#include <components/sceneutil/morphgeometry.hpp>
#include <components/sceneutil/riggeometry.hpp>
#include <components/sceneutil/riggeometryosgaextension.hpp>
namespace SceneUtil
{
CopyOp::CopyOp()
{
setCopyFlags(osg::CopyOp::DEEP_COPY_NODES
// Controller might need different inputs per scene instance
| osg::CopyOp::DEEP_COPY_CALLBACKS | osg::CopyOp::DEEP_COPY_USERDATA);
}
osg::Node* CopyOp::operator()(const osg::Node* node) const
{
if (const osgParticle::ParticleProcessor* processor = dynamic_cast<const osgParticle::ParticleProcessor*>(node))
return operator()(processor);
if (const osgParticle::ParticleSystemUpdater* updater
= dynamic_cast<const osgParticle::ParticleSystemUpdater*>(node))
{
osgParticle::ParticleSystemUpdater* cloned
= new osgParticle::ParticleSystemUpdater(*updater, osg::CopyOp::SHALLOW_COPY);
mUpdaterToOldPs[cloned] = updater->getParticleSystem(0);
return cloned;
}
return osg::CopyOp::operator()(node);
}
osg::Drawable* CopyOp::operator()(const osg::Drawable* drawable) const
{
if (const osgParticle::ParticleSystem* partsys = dynamic_cast<const osgParticle::ParticleSystem*>(drawable))
return operator()(partsys);
if (dynamic_cast<const SceneUtil::RigGeometry*>(drawable)
|| dynamic_cast<const SceneUtil::MorphGeometry*>(drawable)
|| dynamic_cast<const osgAnimation::RigGeometry*>(drawable)
|| dynamic_cast<const osgAnimation::MorphGeometry*>(drawable)
|| dynamic_cast<const SceneUtil::RigGeometryHolder*>(drawable))
{
return static_cast<osg::Drawable*>(drawable->clone(*this));
}
return osg::CopyOp::operator()(drawable);
}
osgParticle::ParticleProcessor* CopyOp::operator()(const osgParticle::ParticleProcessor* processor) const
{
osgParticle::ParticleProcessor* cloned
= static_cast<osgParticle::ParticleProcessor*>(processor->clone(osg::CopyOp::DEEP_COPY_CALLBACKS));
for (const auto& oldPsNewPsPair : mOldPsToNewPs)
{
if (processor->getParticleSystem() == oldPsNewPsPair.first)
{
cloned->setParticleSystem(oldPsNewPsPair.second);
return cloned;
}
}
mProcessorToOldPs[cloned] = processor->getParticleSystem();
return cloned;
}
osgParticle::ParticleSystem* CopyOp::operator()(const osgParticle::ParticleSystem* partsys) const
{
osgParticle::ParticleSystem* cloned = static_cast<osgParticle::ParticleSystem*>(partsys->clone(*this));
for (const auto& processorPsPair : mProcessorToOldPs)
{
if (processorPsPair.second == partsys)
{
processorPsPair.first->setParticleSystem(cloned);
}
}
for (const auto& updaterPsPair : mUpdaterToOldPs)
{
if (updaterPsPair.second == partsys)
{
osgParticle::ParticleSystemUpdater* updater = updaterPsPair.first;
updater->removeParticleSystem(updater->getParticleSystem(0));
updater->addParticleSystem(cloned);
}
}
// In rare situations a particle processor may be placed after the particle system in the scene graph.
mOldPsToNewPs[partsys] = cloned;
return cloned;
}
}
|