1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-05 15:40:10 +00:00

Fix particle processor cloning

Extend emitter handling comment in NIF loader
This commit is contained in:
Capostrophic 2020-04-29 11:06:14 +03:00 committed by Bret Curtis
parent 6de951569e
commit a314e3a7f5
3 changed files with 17 additions and 2 deletions

View File

@ -1051,6 +1051,8 @@ namespace NifOsg
emitter->setReferenceFrame(osgParticle::ParticleProcessor::RELATIVE_RF); emitter->setReferenceFrame(osgParticle::ParticleProcessor::RELATIVE_RF);
// The emitter node may not actually be handled yet, so let's delay attaching the emitter to a later moment. // The emitter node may not actually be handled yet, so let's delay attaching the emitter to a later moment.
// If the emitter node is placed later than the particle node, it'll have a single frame delay in particle processing.
// But that shouldn't be a game-breaking issue.
mEmitterQueue.emplace_back(partctrl->emitter->recIndex, emitter); mEmitterQueue.emplace_back(partctrl->emitter->recIndex, emitter);
osg::ref_ptr<ParticleSystemController> callback(new ParticleSystemController(partctrl)); osg::ref_ptr<ParticleSystemController> callback(new ParticleSystemController(partctrl));
@ -1068,7 +1070,7 @@ namespace NifOsg
partsys->update(0.0, nv); partsys->update(0.0, nv);
} }
// affectors must be attached *after* the emitter in the scene graph for correct update order // affectors should be attached *after* the emitter in the scene graph for correct update order
// attach to same node as the ParticleSystem, we need osgParticle Operators to get the correct // attach to same node as the ParticleSystem, we need osgParticle Operators to get the correct
// localToWorldMatrix for transforming to particle space // localToWorldMatrix for transforming to particle space
handleParticlePrograms(partctrl->affectors, partctrl->colliders, parentNode, partsys.get(), rf); handleParticlePrograms(partctrl->affectors, partctrl->colliders, parentNode, partsys.get(), rf);

View File

@ -69,6 +69,15 @@ namespace SceneUtil
osgParticle::ParticleProcessor* CopyOp::operator() (const osgParticle::ParticleProcessor* processor) const osgParticle::ParticleProcessor* CopyOp::operator() (const osgParticle::ParticleProcessor* processor) const
{ {
osgParticle::ParticleProcessor* cloned = osg::clone(processor, osg::CopyOp::DEEP_COPY_CALLBACKS); osgParticle::ParticleProcessor* cloned = osg::clone(processor, osg::CopyOp::DEEP_COPY_CALLBACKS);
for (std::map<const osgParticle::ParticleSystem*, osgParticle::ParticleSystem*>::const_iterator it = mMap3.begin(); it != mMap3.end(); ++it)
{
if (processor->getParticleSystem() == it->first)
{
cloned->setParticleSystem(it->second);
return cloned;
}
}
mMap[cloned] = processor->getParticleSystem(); mMap[cloned] = processor->getParticleSystem();
return cloned; return cloned;
} }
@ -93,6 +102,9 @@ namespace SceneUtil
updater->addParticleSystem(cloned); updater->addParticleSystem(cloned);
} }
} }
// In rare situations a particle processor may be placed after the particle system in the scene graph.
mMap3[partsys] = cloned;
return cloned; return cloned;
} }

View File

@ -35,10 +35,11 @@ namespace SceneUtil
virtual osg::Object* operator ()(const osg::Object* node) const; virtual osg::Object* operator ()(const osg::Object* node) const;
private: private:
// maps new ParticleProcessor to their old ParticleSystem pointer // maps new pointers to their old pointers
// a little messy, but I think this should be the most efficient way // a little messy, but I think this should be the most efficient way
mutable std::map<osgParticle::ParticleProcessor*, const osgParticle::ParticleSystem*> mMap; mutable std::map<osgParticle::ParticleProcessor*, const osgParticle::ParticleSystem*> mMap;
mutable std::map<osgParticle::ParticleSystemUpdater*, const osgParticle::ParticleSystem*> mMap2; mutable std::map<osgParticle::ParticleSystemUpdater*, const osgParticle::ParticleSystem*> mMap2;
mutable std::map<const osgParticle::ParticleSystem*, osgParticle::ParticleSystem*> mMap3;
}; };
} }