| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #pragma once
- #include "BsCorePrerequisites.h"
- #include "Animation/BsCurveCache.h"
- #include "Math/BsVector3.h"
- #include "Math/BsQuaternion.h"
- namespace bs
- {
- /** @addtogroup Animation-Internal
- * @{
- */
- /** Animation keyframe, represented as an endpoint of a cubic hermite spline. */
- template <class T>
- struct TKeyframe
- {
- T value; /**< Value of the key. */
- T inTangent; /**< Input tangent (going from the previous key to this one) of the key. */
- T outTangent; /**< Output tangent (going from this key to next one) of the key. */
- float time; /**< Position of the key along the animation spline. */
- };
- template struct BS_SCRIPT_EXPORT(m:Animation,n:KeyFrame,pl:true) TKeyframe<float>;
- template struct BS_SCRIPT_EXPORT(m:Animation,n:KeyFrameVec3,pl:true) TKeyframe<Vector3>;
- template struct BS_SCRIPT_EXPORT(m:Animation,n:KeyFrameQuat,pl:true) TKeyframe<Quaternion>;
- /**
- * Animation spline represented by a set of keyframes, each representing an endpoint of a cubic hermite curve. The
- * spline can be evaluated at any time, and uses caching to speed up multiple sequential evaluations.
- */
- template <class T>
- class BS_CORE_EXPORT TAnimationCurve // Note: Curves are expected to be immutable for threading purposes
- {
- public:
- typedef TKeyframe<T> KeyFrame;
- TAnimationCurve();
- /**
- * Creates a new animation curve.
- *
- * @param[in] keyframes Keyframes to initialize the curve with
- */
- BS_SCRIPT_EXPORT()
- TAnimationCurve(const Vector<KeyFrame>& keyframes);
- /**
- * Evaluate the animation curve using caching. Caching can significantly speed of evaluation if the evaluation
- * happens sequential order (which should be true for most curves). If evaluation is not happening in sequential
- * order using the non-caching version of evaluate() might yield better performance.
- *
- * @param[in] time %Time to evaluate the curve at.
- * @param[in] cache Cached data from previous requests that can be used for speeding up sequential calls
- * to this method. Caller should ensure to maintain a persistent instance of this data
- * for every animation using this curve in order to ensure cache is maintained.
- * @param[in] loop If true the curve will loop when it goes past the end or beggining. Otherwise the
- * curve value will be clamped.
- * @return Interpolated value from the curve at provided time.
- */
- T evaluate(float time, const TCurveCache<T>& cache, bool loop = true) const;
- /**
- * Evaluate the animation curve at the specified time. If evaluating multiple values in a sequential order consider
- * using the cached version of evaluate() for better performance.
- *
- * @param[in] time %Time to evaluate the curve at.
- * @param[in] loop If true the curve will loop when it goes past the end or beggining. Otherwise the curve
- * value will be clamped.
- * @return Interpolated value from the curve at provided time.
- */
- BS_SCRIPT_EXPORT(n:Evaluate)
- T evaluate(float time, bool loop = true) const;
- /**
- * Evaluate the animation curve at the specified time and returns a new keyframe containing the evaluated value
- * and tangents.
- *
- * @param[in] time %Time to evaluate the curve at.
- * @param[in] loop If true the curve will loop when it goes past the end or beggining. Otherwise the curve
- * value will be clamped.
- * @return Keyframe containing the interpolated value and tangents at provided time.
- */
- KeyFrame evaluateKey(float time, bool loop = true) const;
- /**
- * Splits a piece of the animation curve into a separate animation curve.
- *
- * @param[in] start Beginning time of the split curve.
- * @param[in] end End time of the split curve.
- * @return New curve with data corresponding to the provided split times.
- */
- TAnimationCurve<T> split(float start, float end);
- /**
- * Converts a normal curve into an additive curve. It is assumed the first keyframe in the curve is the reference
- * key from which to generate the additive curve. Such curves can then be added on top of a curve containing
- * reference keys.
- */
- void makeAdditive();
- /** Returns the length of the animation curve, from time zero to last keyframe. */
- float getLength() const { return mEnd; }
- /** Returns the total number of key-frames in the curve. */
- UINT32 getNumKeyFrames() const { return (UINT32)mKeyframes.size(); }
- /** Returns a keyframe at the specified index. */
- const TKeyframe<T>& getKeyFrame(UINT32 idx) const { return mKeyframes[idx]; }
- /** Returns a list of all keyframes in the curve. */
- BS_SCRIPT_EXPORT(n:KeyFrames,pr:getter)
- const Vector<TKeyframe<T>>& getKeyFrames() const { return mKeyframes; }
- private:
- friend struct RTTIPlainType<TAnimationCurve<T>>;
- /**
- * Returns a pair of keys that can be used for interpolating to field the value at the provided time. This attempts
- * to find keys using the cache first, and if not possible falls back to a full search.
- *
- * @param[in] time Time for which to find the relevant keys from. It is expected to be clamped to a
- * valid range within the curve.
- * @param[in] cache Animation instance data holding the time to evaluate the curve at, and any cached
- * data from previous requests. Time is expected to be clamped to a valid range
- * within the curve.
- * @param[out] leftKey Index of the key to interpolate from.
- * @param[out] rightKey Index of the key to interpolate to.
- */
- void findKeys(float time, const TCurveCache<T>& cache, UINT32& leftKey, UINT32& rightKey) const;
- /**
- * Returns a pair of keys that can be used for interpolating to field the value at the provided time.
- *
- * @param[in] time Time for which to find the relevant keys from. It is expected to be clamped to a
- * valid range within the curve.
- * @param[out] leftKey Index of the key to interpolate from.
- * @param[out] rightKey Index of the key to interpolate to.
- */
- void findKeys(float time, UINT32& leftKey, UINT32& rightKey) const;
- /** Returns a keyframe index nearest to the provided time. */
- UINT32 findKey(float time);
- /**
- * Calculates a key in-between the provided two keys.
- *
- * @param[in] lhs Key to interpolate from.
- * @param[in] rhs Key to interpolate to.
- * @param[in] time Curve time to interpolate the keys at.
- * @return Interpolated key value.
- */
- KeyFrame evaluateKey(const KeyFrame& lhs, const KeyFrame& rhs, float time) const;
- /**
- * Evaluates a value at the cached curve. Caller must ensure the request time falls within the cached curve range.
- *
- * @param[in] time Time to evaluate the curve at.
- * @param[in] animInstance Animation instance data holding the time to evaluate the curve at, and any cached
- * data from previous requests.
- * @return Interpolated value from the curve at provided time.
- */
- T evaluateCache(float time, const TCurveCache<T>& animInstance) const;
- static const UINT32 CACHE_LOOKAHEAD;
- Vector<KeyFrame> mKeyframes;
- float mStart;
- float mEnd;
- float mLength;
- };
- #ifdef BS_SBGEN
- template class BS_SCRIPT_EXPORT(m:Animation,n:AnimationCurve) TAnimationCurve<float>;
- template class BS_SCRIPT_EXPORT(m:Animation,n:Vector3Curve) TAnimationCurve<Vector3>;
- template class BS_SCRIPT_EXPORT(m:Animation,n:QuaternionCurve) TAnimationCurve<Quaternion>;
- #endif
- /** Flags that describe an animation curve. */
- enum BS_SCRIPT_EXPORT(n:AnimationCurveFlags) class AnimationCurveFlag
- {
- /**
- * If enabled, the curve was imported from an external file and not created within the engine. This will affect
- * how are animation results applied to scene objects (with imported animations it is assumed the curve is
- * animating bones and with in-engine curves it is assumed the curve is animating scene objects).
- */
- ImportedCurve = 1 << 0,
- /** Signifies the curve is used to animate between different frames within a morph channel. In range [0, 1]. */
- MorphFrame = 1 << 1,
- /** Signifies the curve is used to adjust the weight of a morph channel. In range [0, 1]. */
- MorphWeight = 1 << 2
- };
- typedef Flags<AnimationCurveFlag> AnimationCurveFlags;
- BS_FLAGS_OPERATORS(AnimationCurveFlag);
- /** An animation curve and its name. */
- template <class T>
- struct TNamedAnimationCurve
- {
- TNamedAnimationCurve() { }
- /**
- * Constructs a new named animation curve.
- *
- * @param[in] name Name of the curve.
- * @param[in] curve Curve containing the animation data.
- */
- TNamedAnimationCurve(const String& name, const TAnimationCurve<T> curve)
- :name(name), curve(curve)
- { }
- /**
- * Constructs a new named animation curve.
- *
- * @param[in] name Name of the curve.
- * @param[in] flags Flags that describe the animation curve.
- * @param[in] curve Curve containing the animation data.
- */
- TNamedAnimationCurve(const String& name, AnimationCurveFlags flags, const TAnimationCurve<T> curve)
- :name(name), curve(curve)
- { }
- /** Name of the curve. */
- String name;
- /** Flags that describe the animation curve. */
- AnimationCurveFlags flags;
- /** Actual curve containing animation data. */
- TAnimationCurve<T> curve;
- };
- #ifdef BS_SBGEN
- template class BS_SCRIPT_EXPORT(m:Animation,n:NamedFloatCurve,pl:true) TNamedAnimationCurve<float>;
- template class BS_SCRIPT_EXPORT(m:Animation,n:NamedVector3Curve,pl:true) TNamedAnimationCurve<Vector3>;
- template class BS_SCRIPT_EXPORT(m:Animation,n:NamedQuaternionCurve,pl:true) TNamedAnimationCurve<Quaternion>;
- #endif
- /** @} */
- }
|