diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index f6841ee619..bbb2f57fe6 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -16,57 +16,6 @@ namespace NifOsg { -float ValueInterpolator::interpKey(const Nif::FloatKeyMap::MapType &keys, float time, float def) const -{ - if (keys.size() == 0) - return def; - - if(time <= keys.begin()->first) - return keys.begin()->second.mValue; - - Nif::FloatKeyMap::MapType::const_iterator it = keys.lower_bound(time); - if (it != keys.end()) - { - float aTime = it->first; - const Nif::FloatKey* aKey = &it->second; - - assert (it != keys.begin()); // Shouldn't happen, was checked at beginning of this function - - Nif::FloatKeyMap::MapType::const_iterator last = --it; - float aLastTime = last->first; - const Nif::FloatKey* aLastKey = &last->second; - - float a = (time - aLastTime) / (aTime - aLastTime); - return aLastKey->mValue + ((aKey->mValue - aLastKey->mValue) * a); - } - else - return keys.rbegin()->second.mValue; -} - -osg::Vec3f ValueInterpolator::interpKey(const Nif::Vector3KeyMap::MapType &keys, float time) const -{ - if(time <= keys.begin()->first) - return keys.begin()->second.mValue; - - Nif::Vector3KeyMap::MapType::const_iterator it = keys.lower_bound(time); - if (it != keys.end()) - { - float aTime = it->first; - const Nif::KeyT* aKey = &it->second; - - assert (it != keys.begin()); // Shouldn't happen, was checked at beginning of this function - - Nif::Vector3KeyMap::MapType::const_iterator last = --it; - float aLastTime = last->first; - const Nif::KeyT* aLastKey = &last->second; - - float a = (time - aLastTime) / (aTime - aLastTime); - return aLastKey->mValue + ((aKey->mValue - aLastKey->mValue) * a); - } - else - return keys.rbegin()->second.mValue; -} - ControllerFunction::ControllerFunction(const Nif::Controller *ctrl, bool deltaInput) : mDeltaInput(deltaInput) , mFrequency(ctrl->frequency) diff --git a/components/nifosg/controller.hpp b/components/nifosg/controller.hpp index cc176e76e6..c92a778165 100644 --- a/components/nifosg/controller.hpp +++ b/components/nifosg/controller.hpp @@ -42,9 +42,33 @@ namespace NifOsg class ValueInterpolator { protected: - float interpKey(const Nif::FloatKeyMap::MapType &keys, float time, float def=0.f) const; + template + T interpKey (const std::map< float, Nif::KeyT >& keys, float time, T defaultValue = T()) const + { + if (keys.size() == 0) + return defaultValue; + + if(time <= keys.begin()->first) + return keys.begin()->second.mValue; + + typename std::map< float, Nif::KeyT >::const_iterator it = keys.lower_bound(time); + if (it != keys.end()) + { + float aTime = it->first; + const Nif::KeyT* aKey = &it->second; - osg::Vec3f interpKey(const Nif::Vector3KeyMap::MapType &keys, float time) const; + assert (it != keys.begin()); // Shouldn't happen, was checked at beginning of this function + + typename std::map< float, Nif::KeyT >::const_iterator last = --it; + float aLastTime = last->first; + const Nif::KeyT* aLastKey = &last->second; + + float a = (time - aLastTime) / (aTime - aLastTime); + return aLastKey->mValue + ((aKey->mValue - aLastKey->mValue) * a); + } + else + return keys.rbegin()->second.mValue; + } }; // FIXME: Should not be here. We might also want to use this for non-NIF model formats diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index 3fcc02bcff..58501763b2 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -45,11 +45,10 @@ ParticleShooter::ParticleShooter(const osgParticle::Shooter ©, const osg::Co void ParticleShooter::shoot(osgParticle::Particle *particle) const { - // NOTE: We do not use mDirection/mAngle for the initial direction. float hdir = mHorizontalDir + mHorizontalAngle * (2.f * (std::rand() / static_cast(RAND_MAX)) - 1.f); float vdir = mVerticalDir + mVerticalAngle * (2.f * (std::rand() / static_cast(RAND_MAX)) - 1.f); - osg::Vec3f dir = osg::Quat(hdir, osg::Vec3f(0,0,1)) * osg::Quat(vdir, osg::Vec3f(1,0,0)) - // ^ Vec3f(0,1,0) according to nifskope, TODO: test in mw + float vdir2 = mVerticalDir + mVerticalAngle * (2.f * (std::rand() / static_cast(RAND_MAX)) - 1.f); + osg::Vec3f dir = osg::Quat(hdir, osg::Vec3f(0,0,1)) * osg::Quat(vdir, osg::Vec3f(0,1,0)) * osg::Quat(vdir2, osg::Vec3f(1,0,0)) * osg::Vec3f(0,0,1); float vel = mMinSpeed + (mMaxSpeed - mMinSpeed) * std::rand() / static_cast(RAND_MAX); @@ -111,34 +110,10 @@ ParticleColorAffector::ParticleColorAffector(const ParticleColorAffector ©, *this = copy; } -osg::Vec4f ParticleColorAffector::interpolate(const float time, const Nif::Vector4KeyMap::MapType &keys) -{ - if(time <= keys.begin()->first) - return keys.begin()->second.mValue; - - Nif::Vector4KeyMap::MapType::const_iterator it = keys.lower_bound(time); - if (it != keys.end()) - { - float aTime = it->first; - const Nif::KeyT* aKey = &it->second; - - assert (it != keys.begin()); // Shouldn't happen, was checked at beginning of this function - - Nif::Vector4KeyMap::MapType::const_iterator last = --it; - float aLastTime = last->first; - const Nif::KeyT* aLastKey = &last->second; - - float a = (time - aLastTime) / (aTime - aLastTime); - return aLastKey->mValue + ((aKey->mValue - aLastKey->mValue) * a); - } - else - return keys.rbegin()->second.mValue; -} - void ParticleColorAffector::operate(osgParticle::Particle* particle, double /* dt */) { float time = static_cast(particle->getAge()/particle->getLifeTime()); - osg::Vec4f color = interpolate(time, mData.mKeyMap.mKeys); + osg::Vec4f color = interpKey(mData.mKeyMap.mKeys, time, osg::Vec4f(1,1,1,1)); particle->setColorRange(osgParticle::rangev4(color, color)); } diff --git a/components/nifosg/particle.hpp b/components/nifosg/particle.hpp index 0336d3392b..13010fbac9 100644 --- a/components/nifosg/particle.hpp +++ b/components/nifosg/particle.hpp @@ -10,6 +10,8 @@ #include #include +#include "controller.hpp" // ValueInterpolator + namespace Nif { class NiGravity; @@ -90,7 +92,7 @@ namespace NifOsg float mCachedDefaultSize; }; - class ParticleColorAffector : public osgParticle::Operator + class ParticleColorAffector : public osgParticle::Operator, public ValueInterpolator { public: ParticleColorAffector(const Nif::NiColorData* clrdata);