mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 00:26:39 +00:00 
			
		
		
		
	Add a method to apply a NodeTargetValue-based controller to a specified node.
This commit is contained in:
		
							parent
							
								
									4122b0b55f
								
							
						
					
					
						commit
						ace7d647e5
					
				
					 2 changed files with 82 additions and 67 deletions
				
			
		| 
						 | 
				
			
			@ -104,7 +104,7 @@ public:
 | 
			
		|||
    private:
 | 
			
		||||
        std::vector<Nif::NiVisData::VisData> mData;
 | 
			
		||||
 | 
			
		||||
        virtual bool calculate(Ogre::Real time)
 | 
			
		||||
        bool calculate(Ogre::Real time) const
 | 
			
		||||
        {
 | 
			
		||||
            if(mData.size() == 0)
 | 
			
		||||
                return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -144,16 +144,21 @@ public:
 | 
			
		|||
          , mData(data->mVis)
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        virtual void applyToNode(Ogre::Node *node, float time) const
 | 
			
		||||
        {
 | 
			
		||||
            bool vis = calculate(time);
 | 
			
		||||
            setVisible(node, vis);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual Ogre::Real getValue() const
 | 
			
		||||
        {
 | 
			
		||||
            // Should not be called
 | 
			
		||||
            return 1.0f;
 | 
			
		||||
            return 0.0f;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void setValue(Ogre::Real time)
 | 
			
		||||
        {
 | 
			
		||||
            bool vis = calculate(time);
 | 
			
		||||
            setVisible(mNode, vis);
 | 
			
		||||
            Value::applyToNode(mNode, time);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -170,6 +175,66 @@ public:
 | 
			
		|||
        Nif::Vector3KeyList mTranslations;
 | 
			
		||||
        Nif::FloatKeyList mScales;
 | 
			
		||||
 | 
			
		||||
        static float interpKey(const Nif::FloatKeyList::VecType &keys, float time)
 | 
			
		||||
        {
 | 
			
		||||
            if(time <= keys.front().mTime)
 | 
			
		||||
                return keys.front().mValue;
 | 
			
		||||
            if(time >= keys.back().mTime)
 | 
			
		||||
                return keys.back().mValue;
 | 
			
		||||
 | 
			
		||||
            Nif::FloatKeyList::VecType::const_iterator iter(keys.begin()+1);
 | 
			
		||||
            for(;iter != keys.end();iter++)
 | 
			
		||||
            {
 | 
			
		||||
                if(iter->mTime < time)
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                Nif::FloatKeyList::VecType::const_iterator last(iter-1);
 | 
			
		||||
                float a = (time-last->mTime) / (iter->mTime-last->mTime);
 | 
			
		||||
                return last->mValue + ((iter->mValue - last->mValue)*a);
 | 
			
		||||
            }
 | 
			
		||||
            return keys.back().mValue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static Ogre::Vector3 interpKey(const Nif::Vector3KeyList::VecType &keys, float time)
 | 
			
		||||
        {
 | 
			
		||||
            if(time <= keys.front().mTime)
 | 
			
		||||
                return keys.front().mValue;
 | 
			
		||||
            if(time >= keys.back().mTime)
 | 
			
		||||
                return keys.back().mValue;
 | 
			
		||||
 | 
			
		||||
            Nif::Vector3KeyList::VecType::const_iterator iter(keys.begin()+1);
 | 
			
		||||
            for(;iter != keys.end();iter++)
 | 
			
		||||
            {
 | 
			
		||||
                if(iter->mTime < time)
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                Nif::Vector3KeyList::VecType::const_iterator last(iter-1);
 | 
			
		||||
                float a = (time-last->mTime) / (iter->mTime-last->mTime);
 | 
			
		||||
                return last->mValue + ((iter->mValue - last->mValue)*a);
 | 
			
		||||
            }
 | 
			
		||||
            return keys.back().mValue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static Ogre::Quaternion interpKey(const Nif::QuaternionKeyList::VecType &keys, float time)
 | 
			
		||||
        {
 | 
			
		||||
            if(time <= keys.front().mTime)
 | 
			
		||||
                return keys.front().mValue;
 | 
			
		||||
            if(time >= keys.back().mTime)
 | 
			
		||||
                return keys.back().mValue;
 | 
			
		||||
 | 
			
		||||
            Nif::QuaternionKeyList::VecType::const_iterator iter(keys.begin()+1);
 | 
			
		||||
            for(;iter != keys.end();iter++)
 | 
			
		||||
            {
 | 
			
		||||
                if(iter->mTime < time)
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                Nif::QuaternionKeyList::VecType::const_iterator last(iter-1);
 | 
			
		||||
                float a = (time-last->mTime) / (iter->mTime-last->mTime);
 | 
			
		||||
                return Ogre::Quaternion::nlerp(a, last->mValue, iter->mValue);
 | 
			
		||||
            }
 | 
			
		||||
            return Ogre::Quaternion();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        Value(Ogre::Node *target, const Nif::NiKeyframeData *data)
 | 
			
		||||
          : NodeTargetValue<Ogre::Real>(target)
 | 
			
		||||
| 
						 | 
				
			
			@ -178,6 +243,16 @@ public:
 | 
			
		|||
          , mScales(data->mScales)
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        virtual void applyToNode(Ogre::Node *node, float time) const
 | 
			
		||||
        {
 | 
			
		||||
            if(mRotations.mKeys.size() > 0)
 | 
			
		||||
                node->setOrientation(interpKey(mRotations.mKeys, time));
 | 
			
		||||
            if(mTranslations.mKeys.size() > 0)
 | 
			
		||||
                node->setPosition(interpKey(mTranslations.mKeys, time));
 | 
			
		||||
            if(mScales.mKeys.size() > 0)
 | 
			
		||||
                node->setScale(Ogre::Vector3(interpKey(mScales.mKeys, time)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual Ogre::Real getValue() const
 | 
			
		||||
        {
 | 
			
		||||
            // Should not be called
 | 
			
		||||
| 
						 | 
				
			
			@ -186,69 +261,7 @@ public:
 | 
			
		|||
 | 
			
		||||
        virtual void setValue(Ogre::Real time)
 | 
			
		||||
        {
 | 
			
		||||
            if(mRotations.mKeys.size() > 0)
 | 
			
		||||
            {
 | 
			
		||||
                if(time <= mRotations.mKeys.front().mTime)
 | 
			
		||||
                    mNode->setOrientation(mRotations.mKeys.front().mValue);
 | 
			
		||||
                else if(time >= mRotations.mKeys.back().mTime)
 | 
			
		||||
                    mNode->setOrientation(mRotations.mKeys.back().mValue);
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    Nif::QuaternionKeyList::VecType::const_iterator iter(mRotations.mKeys.begin()+1);
 | 
			
		||||
                    for(;iter != mRotations.mKeys.end();iter++)
 | 
			
		||||
                    {
 | 
			
		||||
                        if(iter->mTime < time)
 | 
			
		||||
                            continue;
 | 
			
		||||
 | 
			
		||||
                        Nif::QuaternionKeyList::VecType::const_iterator last(iter-1);
 | 
			
		||||
                        float a = (time-last->mTime) / (iter->mTime-last->mTime);
 | 
			
		||||
                        mNode->setOrientation(Ogre::Quaternion::nlerp(a, last->mValue, iter->mValue));
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if(mTranslations.mKeys.size() > 0)
 | 
			
		||||
            {
 | 
			
		||||
                if(time <= mTranslations.mKeys.front().mTime)
 | 
			
		||||
                    mNode->setPosition(mTranslations.mKeys.front().mValue);
 | 
			
		||||
                else if(time >= mTranslations.mKeys.back().mTime)
 | 
			
		||||
                    mNode->setPosition(mTranslations.mKeys.back().mValue);
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    Nif::Vector3KeyList::VecType::const_iterator iter(mTranslations.mKeys.begin()+1);
 | 
			
		||||
                    for(;iter != mTranslations.mKeys.end();iter++)
 | 
			
		||||
                    {
 | 
			
		||||
                        if(iter->mTime < time)
 | 
			
		||||
                            continue;
 | 
			
		||||
 | 
			
		||||
                        Nif::Vector3KeyList::VecType::const_iterator last(iter-1);
 | 
			
		||||
                        float a = (time-last->mTime) / (iter->mTime-last->mTime);
 | 
			
		||||
                        mNode->setPosition(last->mValue + ((iter->mValue - last->mValue)*a));
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if(mScales.mKeys.size() > 0)
 | 
			
		||||
            {
 | 
			
		||||
                if(time <= mScales.mKeys.front().mTime)
 | 
			
		||||
                    mNode->setScale(Ogre::Vector3(mScales.mKeys.front().mValue));
 | 
			
		||||
                else if(time >= mScales.mKeys.back().mTime)
 | 
			
		||||
                    mNode->setScale(Ogre::Vector3(mScales.mKeys.back().mValue));
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    Nif::FloatKeyList::VecType::const_iterator iter(mScales.mKeys.begin()+1);
 | 
			
		||||
                    for(;iter != mScales.mKeys.end();iter++)
 | 
			
		||||
                    {
 | 
			
		||||
                        if(iter->mTime < time)
 | 
			
		||||
                            continue;
 | 
			
		||||
 | 
			
		||||
                        Nif::FloatKeyList::VecType::const_iterator last(iter-1);
 | 
			
		||||
                        float a = (time-last->mTime) / (iter->mTime-last->mTime);
 | 
			
		||||
                        mNode->setScale(Ogre::Vector3(last->mValue + ((iter->mValue - last->mValue)*a)));
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Value::applyToNode(mNode, time);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,6 +85,8 @@ public:
 | 
			
		|||
    NodeTargetValue(Ogre::Node *target) : mNode(target)
 | 
			
		||||
    { }
 | 
			
		||||
 | 
			
		||||
    virtual void applyToNode(Ogre::Node *node, float time) const = 0;
 | 
			
		||||
 | 
			
		||||
    void setNode(Ogre::Node *target)
 | 
			
		||||
    { mNode = target; }
 | 
			
		||||
    Ogre::Node *getNode() const
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue