2015-03-26 17:02:51 +00:00
|
|
|
#include "clone.hpp"
|
|
|
|
|
|
|
|
#include <osg/StateSet>
|
|
|
|
|
|
|
|
#include <osgParticle/ParticleProcessor>
|
|
|
|
#include <osgParticle/ParticleSystemUpdater>
|
|
|
|
#include <osgParticle/Emitter>
|
2015-04-21 20:53:28 +00:00
|
|
|
|
2019-09-19 07:35:15 +00:00
|
|
|
#include <components/nifosg/userdata.hpp>
|
2015-03-26 17:02:51 +00:00
|
|
|
|
2019-09-19 07:35:15 +00:00
|
|
|
#include <components/sceneutil/morphgeometry.hpp>
|
2015-04-21 20:53:28 +00:00
|
|
|
#include <components/sceneutil/riggeometry.hpp>
|
|
|
|
|
2015-03-26 17:02:51 +00:00
|
|
|
namespace SceneUtil
|
|
|
|
{
|
|
|
|
|
|
|
|
CopyOp::CopyOp()
|
|
|
|
{
|
|
|
|
setCopyFlags(osg::CopyOp::DEEP_COPY_NODES
|
|
|
|
// Controller might need different inputs per scene instance
|
2015-05-12 14:24:53 +00:00
|
|
|
| osg::CopyOp::DEEP_COPY_CALLBACKS
|
|
|
|
| osg::CopyOp::DEEP_COPY_USERDATA);
|
2015-03-26 17:02:51 +00:00
|
|
|
}
|
|
|
|
|
2019-09-19 07:35:15 +00:00
|
|
|
osg::Object* CopyOp::operator ()(const osg::Object* node) const
|
|
|
|
{
|
|
|
|
// We should copy node transformations when we copy node
|
2020-05-16 13:37:00 +00:00
|
|
|
if (dynamic_cast<const NifOsg::NodeUserData*>(node))
|
|
|
|
return static_cast<NifOsg::NodeUserData*>(node->clone(*this));
|
2019-09-19 07:35:15 +00:00
|
|
|
|
|
|
|
return osg::CopyOp::operator()(node);
|
|
|
|
}
|
|
|
|
|
2015-03-26 17:02:51 +00:00
|
|
|
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))
|
|
|
|
{
|
2017-02-26 02:15:57 +00:00
|
|
|
osgParticle::ParticleSystemUpdater* cloned = new osgParticle::ParticleSystemUpdater(*updater, osg::CopyOp::SHALLOW_COPY);
|
2020-04-29 09:25:52 +00:00
|
|
|
mUpdaterToOldPs[cloned] = updater->getParticleSystem(0);
|
2015-03-26 17:02:51 +00:00
|
|
|
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);
|
2015-08-30 18:00:37 +00:00
|
|
|
|
2017-09-01 20:56:09 +00:00
|
|
|
if (dynamic_cast<const SceneUtil::RigGeometry*>(drawable) || dynamic_cast<const SceneUtil::MorphGeometry*>(drawable))
|
2015-05-29 22:59:34 +00:00
|
|
|
{
|
2020-05-16 13:37:00 +00:00
|
|
|
return static_cast<osg::Drawable*>(drawable->clone(*this));
|
2015-05-29 22:59:34 +00:00
|
|
|
}
|
|
|
|
|
2015-03-26 17:02:51 +00:00
|
|
|
return osg::CopyOp::operator()(drawable);
|
|
|
|
}
|
|
|
|
|
|
|
|
osgParticle::ParticleProcessor* CopyOp::operator() (const osgParticle::ParticleProcessor* processor) const
|
|
|
|
{
|
2020-05-16 13:37:00 +00:00
|
|
|
osgParticle::ParticleProcessor* cloned = static_cast<osgParticle::ParticleProcessor*>(processor->clone(osg::CopyOp::DEEP_COPY_CALLBACKS));
|
2020-04-29 09:25:52 +00:00
|
|
|
for (const auto& oldPsNewPsPair : mOldPsToNewPs)
|
2020-04-29 08:06:14 +00:00
|
|
|
{
|
2020-04-29 09:25:52 +00:00
|
|
|
if (processor->getParticleSystem() == oldPsNewPsPair.first)
|
2020-04-29 08:06:14 +00:00
|
|
|
{
|
2020-04-29 09:25:52 +00:00
|
|
|
cloned->setParticleSystem(oldPsNewPsPair.second);
|
2020-04-29 08:06:14 +00:00
|
|
|
return cloned;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-29 09:25:52 +00:00
|
|
|
mProcessorToOldPs[cloned] = processor->getParticleSystem();
|
2015-03-26 17:02:51 +00:00
|
|
|
return cloned;
|
|
|
|
}
|
|
|
|
|
|
|
|
osgParticle::ParticleSystem* CopyOp::operator ()(const osgParticle::ParticleSystem* partsys) const
|
|
|
|
{
|
2020-05-16 13:37:00 +00:00
|
|
|
osgParticle::ParticleSystem* cloned = static_cast<osgParticle::ParticleSystem*>(partsys->clone(*this));
|
2015-03-26 17:02:51 +00:00
|
|
|
|
2020-04-29 09:25:52 +00:00
|
|
|
for (const auto& processorPsPair : mProcessorToOldPs)
|
2015-03-26 17:02:51 +00:00
|
|
|
{
|
2020-04-29 09:25:52 +00:00
|
|
|
if (processorPsPair.second == partsys)
|
2015-03-26 17:02:51 +00:00
|
|
|
{
|
2020-04-29 09:25:52 +00:00
|
|
|
processorPsPair.first->setParticleSystem(cloned);
|
2015-03-26 17:02:51 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-29 09:25:52 +00:00
|
|
|
for (const auto& updaterPsPair : mUpdaterToOldPs)
|
2015-03-26 17:02:51 +00:00
|
|
|
{
|
2020-04-29 09:25:52 +00:00
|
|
|
if (updaterPsPair.second == partsys)
|
2015-03-26 17:02:51 +00:00
|
|
|
{
|
2020-04-29 09:25:52 +00:00
|
|
|
osgParticle::ParticleSystemUpdater* updater = updaterPsPair.first;
|
2015-03-26 17:02:51 +00:00
|
|
|
updater->removeParticleSystem(updater->getParticleSystem(0));
|
|
|
|
updater->addParticleSystem(cloned);
|
|
|
|
}
|
|
|
|
}
|
2020-04-29 08:06:14 +00:00
|
|
|
// In rare situations a particle processor may be placed after the particle system in the scene graph.
|
2020-04-29 09:25:52 +00:00
|
|
|
mOldPsToNewPs[partsys] = cloned;
|
2020-04-29 08:06:14 +00:00
|
|
|
|
2015-03-26 17:02:51 +00:00
|
|
|
return cloned;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|