From 74c56556cc474d205757b1f8111c19f6a80d299d Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 5 Apr 2015 14:10:05 +0200 Subject: [PATCH] More fixes for scaled particle systems --- components/nifosg/nifloader.cpp | 4 +--- components/nifosg/particle.cpp | 18 ++++++++---------- components/resource/scenemanager.cpp | 1 + 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index dd9dbc328..2a3d0322d 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -974,7 +974,7 @@ namespace NifOsg } else if (affectors->recType == Nif::RC_NiParticleRotation) { - // unused? + // unused } else std::cerr << "Unhandled particle modifier " << affectors->recName << std::endl; @@ -1064,8 +1064,6 @@ namespace NifOsg { osg::ref_ptr partsys (new ParticleSystem); partsys->setSortMode(osgParticle::ParticleSystem::SORT_BACK_TO_FRONT); - // Scaling the particle node should also scale particles, even when the worldspace flag is enabled - partsys->setParticleScaleReferenceFrame(osgParticle::ParticleSystem::LOCAL_COORDINATES); const Nif::NiParticleSystemController* partctrl = NULL; for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next) diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index 143a73e08..c4bf69579 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -50,8 +50,8 @@ void InverseWorldMatrix::operator()(osg::Node *node, osg::NodeVisitor *nv) osg::MatrixTransform* trans = dynamic_cast(node); osg::Matrix mat = osg::computeLocalToWorld( path ); - mat = osg::Matrix::inverse(mat); mat.orthoNormalize(mat); // don't undo the scale + mat = osg::Matrix::inverse(mat); trans->setMatrix(mat); } traverse(node,nv); @@ -239,6 +239,7 @@ void Emitter::setCounter(osgParticle::Counter *counter) void Emitter::emitParticles(double dt) { osg::Matrix worldToPs; + // maybe this could be optimized by halting at the lowest common ancestor of the particle and emitter nodes osg::MatrixList worldMats = getParticleSystem()->getWorldMatrices(); if (!worldMats.empty()) { @@ -246,14 +247,9 @@ void Emitter::emitParticles(double dt) worldToPs = osg::Matrix::inverse(psToWorld); } - worldToPs.orthoNormalize(worldToPs); - const osg::Matrix& ltw = getLocalToWorldMatrix(); - const osg::Matrix emitterToPs = ltw * worldToPs; + osg::Matrix emitterToPs = ltw * worldToPs; - int n = mCounter->numParticlesToCreate(dt); - - osg::Matrix transform; if (!mTargets.empty()) { int randomRecIndex = mTargets[(std::rand() / (static_cast(RAND_MAX)+1.0)) * mTargets.size()]; @@ -270,9 +266,13 @@ void Emitter::emitParticles(double dt) osg::NodePath path = visitor.mFoundPath; path.erase(path.begin()); - transform = osg::computeLocalToWorld(path); + emitterToPs = osg::computeLocalToWorld(path) * emitterToPs; } + emitterToPs.orthoNormalize(emitterToPs); + + int n = mCounter->numParticlesToCreate(dt); + for (int i=0; icreateParticle(0); @@ -282,8 +282,6 @@ void Emitter::emitParticles(double dt) mShooter->shoot(P); - P->transformPositionVelocity(transform); - P->transformPositionVelocity(emitterToPs); } } diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index e626a9f08..ead6a9669 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -51,6 +51,7 @@ namespace void transformInitialParticles(osgParticle::ParticleSystem* partsys, osg::Node* node) { osg::Matrix worldMat = node->getWorldMatrices()[0]; + worldMat.orthoNormalize(worldMat); // scale is already applied on the particle node for (int i=0; inumParticles(); ++i) { partsys->getParticle(i)->transformPositionVelocity(worldMat);