#ifndef COMPONENTS_NIFOSG_CONTROLLER_H #define COMPONENTS_NIFOSG_CONTROLLER_H #include #include #include #include #include #include #include //UVController #include namespace osg { class Node; class StateSet; } namespace osgAnimation { class MorphGeometry; } namespace NifOsg { // FIXME: Should not be here. We might also want to use this for non-NIF model formats class ValueInterpolator { protected: float interpKey(const Nif::FloatKeyMap::MapType &keys, float time, float def=0.f) const; osg::Vec3f interpKey(const Nif::Vector3KeyMap::MapType &keys, float time) const; }; // FIXME: Should not be here. We might also want to use this for non-NIF model formats class ControllerFunction { private: float mFrequency; float mPhase; float mStartTime; bool mDeltaInput; float mDeltaCount; public: float mStopTime; public: ControllerFunction(const Nif::Controller *ctrl, bool deltaInput); float calculate(float value); }; typedef ControllerFunction DefaultFunction; class ControllerSource { public: virtual float getValue() const = 0; }; // FIXME: Should return a dt instead of time class FrameTimeSource : public ControllerSource { public: virtual float getValue() const { return mTimer.time_s(); } private: osg::Timer mTimer; }; class ControllerValue { public: virtual void setValue(float value) = 0; }; class Controller { public: Controller (boost::shared_ptr src, boost::shared_ptr dest, boost::shared_ptr function); virtual void update(); boost::shared_ptr mSource; boost::shared_ptr mDestValue; // The source value gets passed through this function before it's passed on to the DestValue. boost::shared_ptr mFunction; }; // FIXME: Should be with other general extensions. class NodeTargetValue : public ControllerValue { protected: osg::Node *mNode; public: NodeTargetValue(osg::Node *target) : mNode(target) { } virtual osg::Vec3f getTranslation(float value) const = 0; osg::Node *getNode() const { return mNode; } }; class GeomMorpherControllerValue : public ControllerValue, public ValueInterpolator { public: // FIXME: don't copy the morph data? GeomMorpherControllerValue(osgAnimation::MorphGeometry* geom, const Nif::NiMorphData *data); virtual void setValue(float time); private: osgAnimation::MorphGeometry* mGeom; std::vector mMorphs; }; class KeyframeControllerValue : public NodeTargetValue, public ValueInterpolator { private: const Nif::QuaternionKeyMap* mRotations; const Nif::FloatKeyMap* mXRotations; const Nif::FloatKeyMap* mYRotations; const Nif::FloatKeyMap* mZRotations; const Nif::Vector3KeyMap* mTranslations; const Nif::FloatKeyMap* mScales; Nif::NIFFilePtr mNif; // Hold a SharedPtr to make sure key lists stay valid osg::Quat mInitialQuat; float mInitialScale; using ValueInterpolator::interpKey; osg::Quat interpKey(const Nif::QuaternionKeyMap::MapType &keys, float time); osg::Quat getXYZRotation(float time) const; public: /// @note The NiKeyFrameData must be valid as long as this KeyframeController exists. KeyframeControllerValue(osg::Node *target, const Nif::NIFFilePtr& nif, const Nif::NiKeyframeData *data, osg::Quat initialQuat, float initialScale); virtual osg::Vec3f getTranslation(float time) const; virtual void setValue(float time); }; class UVControllerValue : public ControllerValue, ValueInterpolator { private: osg::StateSet* mStateSet; Nif::FloatKeyMap mUTrans; Nif::FloatKeyMap mVTrans; Nif::FloatKeyMap mUScale; Nif::FloatKeyMap mVScale; std::set mTextureUnits; public: UVControllerValue(osg::StateSet* target, const Nif::NiUVData *data, std::set textureUnits); virtual void setValue(float value); }; class VisControllerValue : public NodeTargetValue { private: std::vector mData; bool calculate(float time) const; public: VisControllerValue(osg::Node *target, const Nif::NiVisData *data) : NodeTargetValue(target) , mData(data->mVis) { } virtual osg::Vec3f getTranslation(float time) const { return osg::Vec3f(); } virtual void setValue(float time); }; } #endif