Implement gravity decay (previously unknown float)

pull/638/head
scrawl 10 years ago
parent 92ef9b1c57
commit 167ae600c5

@ -54,10 +54,7 @@ namespace Nif
{ {
Controlled::read(nif); Controlled::read(nif);
float decay = nif->getFloat(); mDecay = nif->getFloat();
if (decay != 0.f)
nif->file->warn("Unhandled gravity decay factor");
mForce = nif->getFloat(); mForce = nif->getFloat();
mType = nif->getUInt(); mType = nif->getUInt();
mPosition = nif->getVector3(); mPosition = nif->getVector3();

@ -92,6 +92,7 @@ public:
* 1 - Point (fixed origin) * 1 - Point (fixed origin)
*/ */
int mType; int mType;
float mDecay;
osg::Vec3f mPosition; osg::Vec3f mPosition;
osg::Vec3f mDirection; osg::Vec3f mDirection;

@ -155,13 +155,14 @@ void ParticleColorAffector::operate(osgParticle::Particle* particle, double /* d
GravityAffector::GravityAffector(const Nif::NiGravity *gravity) GravityAffector::GravityAffector(const Nif::NiGravity *gravity)
: mForce(gravity->mForce) : mForce(gravity->mForce)
, mType(static_cast<ForceType>(gravity->mType)) , mType(static_cast<ForceType>(gravity->mType))
, mDecay(gravity->mDecay)
, mPosition(gravity->mPosition) , mPosition(gravity->mPosition)
, mDirection(gravity->mDirection) , mDirection(gravity->mDirection)
{ {
} }
GravityAffector::GravityAffector() GravityAffector::GravityAffector()
: mForce(0), mType(Type_Wind) : mForce(0), mType(Type_Wind), mDecay(0.f)
{ {
} }
@ -175,10 +176,12 @@ GravityAffector::GravityAffector(const GravityAffector &copy, const osg::CopyOp
void GravityAffector::beginOperate(osgParticle::Program* program) 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)
mCachedWorldPositionDirection = absolute ? program->rotateLocalToWorld(mDirection) : mDirection; if (mType == Type_Point || mDecay != 0.f) // we don't need the position for Wind gravity, except if decay is being applied
else // Type_Point mCachedWorldPosition = absolute ? program->transformLocalToWorld(mPosition) : mPosition;
mCachedWorldPositionDirection = absolute ? program->transformLocalToWorld(mPosition) : mPosition;
mCachedWorldDirection = absolute ? program->rotateLocalToWorld(mDirection) : mDirection;
mCachedWorldDirection.normalize();
} }
void GravityAffector::operate(osgParticle::Particle *particle, double dt) void GravityAffector::operate(osgParticle::Particle *particle, double dt)
@ -187,18 +190,33 @@ void GravityAffector::operate(osgParticle::Particle *particle, double dt)
switch (mType) switch (mType)
{ {
case Type_Wind: case Type_Wind:
particle->addVelocity(mCachedWorldPositionDirection * mForce * dt * magic); {
float decayFactor = 1.f;
if (mDecay != 0.f)
{
osg::Plane gravityPlane(mCachedWorldDirection, mCachedWorldPosition);
float distance = std::abs(gravityPlane.distance(particle->getPosition()));
decayFactor = std::exp(-1.f * mDecay * distance);
}
particle->addVelocity(mCachedWorldDirection * mForce * dt * decayFactor * magic);
break; break;
}
case Type_Point: case Type_Point:
{ {
osg::Vec3f diff = mCachedWorldPositionDirection - particle->getPosition(); osg::Vec3f diff = mCachedWorldPosition - particle->getPosition();
float decayFactor = 1.f;
if (mDecay != 0.f)
decayFactor = std::exp(-1.f * mDecay * diff.length());
diff.normalize(); diff.normalize();
particle->addVelocity(diff * mForce * dt * magic);
particle->addVelocity(diff * mForce * dt * decayFactor * magic);
break; break;
} }
} }
// velocity *= e^-[(dist/decay)^2]
} }
Emitter::Emitter() Emitter::Emitter()

@ -169,7 +169,9 @@ namespace NifOsg
ForceType mType; ForceType mType;
osg::Vec3f mPosition; osg::Vec3f mPosition;
osg::Vec3f mDirection; osg::Vec3f mDirection;
osg::Vec3f mCachedWorldPositionDirection; float mDecay;
osg::Vec3f mCachedWorldPosition;
osg::Vec3f mCachedWorldDirection;
}; };
// NodeVisitor to find a child node with the given record index, stored in the node's user data container. // NodeVisitor to find a child node with the given record index, stored in the node's user data container.

Loading…
Cancel
Save