From 76fb68a9c0fceb2f7fc047ede26214ff18c5ea56 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 7 Sep 2015 22:07:09 +0200 Subject: [PATCH] Handle particle systems that don't have emitters Fixes a crash in the Magic Diversity mod. --- components/nifosg/nifloader.cpp | 47 ++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index c98008394..54a02c950 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -825,30 +825,33 @@ namespace NifOsg partsys->setFreezeOnCull(true); - osg::ref_ptr emitter = handleParticleEmitter(partctrl); - emitter->setParticleSystem(partsys); - emitter->setReferenceFrame(osgParticle::ParticleProcessor::RELATIVE_RF); - - // Note: we assume that the Emitter node is placed *before* the Particle node in the scene graph. - // This seems to be true for all NIF files in the game that I've checked, suggesting that NIFs work similar to OSG with regards to update order. - // If something ever violates this assumption, the worst that could happen is the culling being one frame late, which wouldn't be a disaster. - - FindRecIndexVisitor find (partctrl->emitter->recIndex); - rootNode->accept(find); - if (!find.mFound) + if (!partctrl->emitter.empty()) { - std::cerr << "can't find emitter node, wrong node order? in " << mFilename << std::endl; - return; + osg::ref_ptr emitter = handleParticleEmitter(partctrl); + emitter->setParticleSystem(partsys); + emitter->setReferenceFrame(osgParticle::ParticleProcessor::RELATIVE_RF); + + // Note: we assume that the Emitter node is placed *before* the Particle node in the scene graph. + // This seems to be true for all NIF files in the game that I've checked, suggesting that NIFs work similar to OSG with regards to update order. + // If something ever violates this assumption, the worst that could happen is the culling being one frame late, which wouldn't be a disaster. + + FindRecIndexVisitor find (partctrl->emitter->recIndex); + rootNode->accept(find); + if (!find.mFound) + { + std::cerr << "can't find emitter node, wrong node order? in " << mFilename << std::endl; + return; + } + osg::Group* emitterNode = find.mFound; + + // Emitter attached to the emitter node. Note one side effect of the emitter using the CullVisitor is that hiding its node + // actually causes the emitter to stop firing. Convenient, because MW behaves this way too! + emitterNode->addChild(emitter); + + osg::ref_ptr callback(new ParticleSystemController(partctrl)); + setupController(partctrl, callback, animflags); + emitter->setUpdateCallback(callback); } - osg::Group* emitterNode = find.mFound; - - // Emitter attached to the emitter node. Note one side effect of the emitter using the CullVisitor is that hiding its node - // actually causes the emitter to stop firing. Convenient, because MW behaves this way too! - emitterNode->addChild(emitter); - - osg::ref_ptr callback(new ParticleSystemController(partctrl)); - setupController(partctrl, callback, animflags); - emitter->setUpdateCallback(callback); // affectors must 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