Fix for behaviour of scaled particle nodes

Not sure if used in vanilla assets so may be low priority, but couldn't help looking into this.
c++11
scrawl 10 years ago
parent c10c146ad1
commit e91d9d0903

@ -993,6 +993,8 @@ namespace NifOsg
{ {
osg::ref_ptr<ParticleSystem> partsys (new ParticleSystem); osg::ref_ptr<ParticleSystem> partsys (new ParticleSystem);
partsys->setSortMode(osgParticle::ParticleSystem::SORT_BACK_TO_FRONT); 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; const Nif::NiParticleSystemController* partctrl = NULL;
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next) for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next)

@ -49,8 +49,10 @@ void InverseWorldMatrix::operator()(osg::Node *node, osg::NodeVisitor *nv)
osg::MatrixTransform* trans = dynamic_cast<osg::MatrixTransform*>(node); osg::MatrixTransform* trans = dynamic_cast<osg::MatrixTransform*>(node);
osg::Matrix worldMat = osg::computeLocalToWorld( path ); osg::Matrix mat = osg::computeLocalToWorld( path );
trans->setMatrix(osg::Matrix::inverse(worldMat)); mat = osg::Matrix::inverse(mat);
mat.orthoNormalize(mat); // don't undo the scale
trans->setMatrix(mat);
} }
traverse(node,nv); traverse(node,nv);
} }
@ -174,7 +176,7 @@ void GravityAffector::beginOperate(osgParticle::Program* program)
{ {
bool absolute = (program->getReferenceFrame() == osgParticle::ParticleProcessor::ABSOLUTE_RF); bool absolute = (program->getReferenceFrame() == osgParticle::ParticleProcessor::ABSOLUTE_RF);
if (mType == Type_Wind) if (mType == Type_Wind)
mCachedWorldPositionDirection = absolute ? program->rotateLocalToWorld(mDirection) : mDirection; mCachedWorldPositionDirection = absolute ? osg::Matrix::transform3x3(program->getLocalToWorldMatrix(), mDirection) : mDirection;
else // Type_Point else // Type_Point
mCachedWorldPositionDirection = absolute ? program->transformLocalToWorld(mPosition) : mPosition; mCachedWorldPositionDirection = absolute ? program->transformLocalToWorld(mPosition) : mPosition;
} }
@ -241,10 +243,10 @@ void Emitter::emitParticles(double dt)
worldToPs = osg::Matrix::inverse(psToWorld); worldToPs = osg::Matrix::inverse(psToWorld);
} }
worldToPs.orthoNormalize(worldToPs);
const osg::Matrix& ltw = getLocalToWorldMatrix(); const osg::Matrix& ltw = getLocalToWorldMatrix();
const osg::Matrix& previous_ltw = getPreviousLocalToWorldMatrix();
const osg::Matrix emitterToPs = ltw * worldToPs; const osg::Matrix emitterToPs = ltw * worldToPs;
const osg::Matrix prevEmitterToPs = previous_ltw * worldToPs;
int n = mCounter->numParticlesToCreate(dt); int n = mCounter->numParticlesToCreate(dt);
@ -275,15 +277,11 @@ void Emitter::emitParticles(double dt)
{ {
mPlacer->place(P); mPlacer->place(P);
P->transformPositionVelocity(transform);
mShooter->shoot(P); mShooter->shoot(P);
// Now need to transform the position and velocity because we having a moving model. P->transformPositionVelocity(transform);
// (is this actually how MW works?)
float r = ((float)rand()/(float)RAND_MAX); P->transformPositionVelocity(emitterToPs);
P->transformPositionVelocity(emitterToPs, prevEmitterToPs, r);
//P->transformPositionVelocity(ltw);
} }
} }
} }

Loading…
Cancel
Save