BsAnimationCurve.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include "Animation/BsCurveCache.h"
  6. #include "Math/BsVector3.h"
  7. #include "Math/BsQuaternion.h"
  8. namespace bs
  9. {
  10. /** @addtogroup Animation-Internal
  11. * @{
  12. */
  13. /** Animation keyframe, represented as an endpoint of a cubic hermite spline. */
  14. template <class T>
  15. struct TKeyframe
  16. {
  17. T value; /**< Value of the key. */
  18. T inTangent; /**< Input tangent (going from the previous key to this one) of the key. */
  19. T outTangent; /**< Output tangent (going from this key to next one) of the key. */
  20. float time; /**< Position of the key along the animation spline. */
  21. };
  22. template struct BS_SCRIPT_EXPORT(m:Animation,n:KeyFrame,pl:true) TKeyframe<float>;
  23. template struct BS_SCRIPT_EXPORT(m:Animation,n:KeyFrameVec3,pl:true) TKeyframe<Vector3>;
  24. template struct BS_SCRIPT_EXPORT(m:Animation,n:KeyFrameQuat,pl:true) TKeyframe<Quaternion>;
  25. /**
  26. * Animation spline represented by a set of keyframes, each representing an endpoint of a cubic hermite curve. The
  27. * spline can be evaluated at any time, and uses caching to speed up multiple sequential evaluations.
  28. */
  29. template <class T>
  30. class BS_CORE_EXPORT TAnimationCurve // Note: Curves are expected to be immutable for threading purposes
  31. {
  32. public:
  33. typedef TKeyframe<T> KeyFrame;
  34. TAnimationCurve();
  35. /**
  36. * Creates a new animation curve.
  37. *
  38. * @param[in] keyframes Keyframes to initialize the curve with
  39. */
  40. BS_SCRIPT_EXPORT()
  41. TAnimationCurve(const Vector<KeyFrame>& keyframes);
  42. /**
  43. * Evaluate the animation curve using caching. Caching can significantly speed of evaluation if the evaluation
  44. * happens sequential order (which should be true for most curves). If evaluation is not happening in sequential
  45. * order using the non-caching version of evaluate() might yield better performance.
  46. *
  47. * @param[in] time %Time to evaluate the curve at.
  48. * @param[in] cache Cached data from previous requests that can be used for speeding up sequential calls
  49. * to this method. Caller should ensure to maintain a persistent instance of this data
  50. * for every animation using this curve in order to ensure cache is maintained.
  51. * @param[in] loop If true the curve will loop when it goes past the end or beggining. Otherwise the
  52. * curve value will be clamped.
  53. * @return Interpolated value from the curve at provided time.
  54. */
  55. T evaluate(float time, const TCurveCache<T>& cache, bool loop = true) const;
  56. /**
  57. * Evaluate the animation curve at the specified time. If evaluating multiple values in a sequential order consider
  58. * using the cached version of evaluate() for better performance.
  59. *
  60. * @param[in] time %Time to evaluate the curve at.
  61. * @param[in] loop If true the curve will loop when it goes past the end or beggining. Otherwise the curve
  62. * value will be clamped.
  63. * @return Interpolated value from the curve at provided time.
  64. */
  65. BS_SCRIPT_EXPORT(n:Evaluate)
  66. T evaluate(float time, bool loop = true) const;
  67. /**
  68. * Evaluate the animation curve at the specified time and returns a new keyframe containing the evaluated value
  69. * and tangents.
  70. *
  71. * @param[in] time %Time to evaluate the curve at.
  72. * @param[in] loop If true the curve will loop when it goes past the end or beggining. Otherwise the curve
  73. * value will be clamped.
  74. * @return Keyframe containing the interpolated value and tangents at provided time.
  75. */
  76. KeyFrame evaluateKey(float time, bool loop = true) const;
  77. /**
  78. * Splits a piece of the animation curve into a separate animation curve.
  79. *
  80. * @param[in] start Beginning time of the split curve.
  81. * @param[in] end End time of the split curve.
  82. * @return New curve with data corresponding to the provided split times.
  83. */
  84. TAnimationCurve<T> split(float start, float end);
  85. /**
  86. * Converts a normal curve into an additive curve. It is assumed the first keyframe in the curve is the reference
  87. * key from which to generate the additive curve. Such curves can then be added on top of a curve containing
  88. * reference keys.
  89. */
  90. void makeAdditive();
  91. /** Returns the length of the animation curve, from time zero to last keyframe. */
  92. float getLength() const { return mEnd; }
  93. /** Returns the total number of key-frames in the curve. */
  94. UINT32 getNumKeyFrames() const { return (UINT32)mKeyframes.size(); }
  95. /** Returns a keyframe at the specified index. */
  96. const TKeyframe<T>& getKeyFrame(UINT32 idx) const { return mKeyframes[idx]; }
  97. /** Returns a list of all keyframes in the curve. */
  98. BS_SCRIPT_EXPORT(n:KeyFrames,pr:getter)
  99. const Vector<TKeyframe<T>>& getKeyFrames() const { return mKeyframes; }
  100. private:
  101. friend struct RTTIPlainType<TAnimationCurve<T>>;
  102. /**
  103. * Returns a pair of keys that can be used for interpolating to field the value at the provided time. This attempts
  104. * to find keys using the cache first, and if not possible falls back to a full search.
  105. *
  106. * @param[in] time Time for which to find the relevant keys from. It is expected to be clamped to a
  107. * valid range within the curve.
  108. * @param[in] cache Animation instance data holding the time to evaluate the curve at, and any cached
  109. * data from previous requests. Time is expected to be clamped to a valid range
  110. * within the curve.
  111. * @param[out] leftKey Index of the key to interpolate from.
  112. * @param[out] rightKey Index of the key to interpolate to.
  113. */
  114. void findKeys(float time, const TCurveCache<T>& cache, UINT32& leftKey, UINT32& rightKey) const;
  115. /**
  116. * Returns a pair of keys that can be used for interpolating to field the value at the provided time.
  117. *
  118. * @param[in] time Time for which to find the relevant keys from. It is expected to be clamped to a
  119. * valid range within the curve.
  120. * @param[out] leftKey Index of the key to interpolate from.
  121. * @param[out] rightKey Index of the key to interpolate to.
  122. */
  123. void findKeys(float time, UINT32& leftKey, UINT32& rightKey) const;
  124. /** Returns a keyframe index nearest to the provided time. */
  125. UINT32 findKey(float time);
  126. /**
  127. * Calculates a key in-between the provided two keys.
  128. *
  129. * @param[in] lhs Key to interpolate from.
  130. * @param[in] rhs Key to interpolate to.
  131. * @param[in] time Curve time to interpolate the keys at.
  132. * @return Interpolated key value.
  133. */
  134. KeyFrame evaluateKey(const KeyFrame& lhs, const KeyFrame& rhs, float time) const;
  135. /**
  136. * Evaluates a value at the cached curve. Caller must ensure the request time falls within the cached curve range.
  137. *
  138. * @param[in] time Time to evaluate the curve at.
  139. * @param[in] animInstance Animation instance data holding the time to evaluate the curve at, and any cached
  140. * data from previous requests.
  141. * @return Interpolated value from the curve at provided time.
  142. */
  143. T evaluateCache(float time, const TCurveCache<T>& animInstance) const;
  144. static const UINT32 CACHE_LOOKAHEAD;
  145. Vector<KeyFrame> mKeyframes;
  146. float mStart;
  147. float mEnd;
  148. float mLength;
  149. };
  150. #ifdef BS_SBGEN
  151. template class BS_SCRIPT_EXPORT(m:Animation,n:AnimationCurve) TAnimationCurve<float>;
  152. template class BS_SCRIPT_EXPORT(m:Animation,n:Vector3Curve) TAnimationCurve<Vector3>;
  153. template class BS_SCRIPT_EXPORT(m:Animation,n:QuaternionCurve) TAnimationCurve<Quaternion>;
  154. #endif
  155. /** Flags that describe an animation curve. */
  156. enum BS_SCRIPT_EXPORT(n:AnimationCurveFlags) class AnimationCurveFlag
  157. {
  158. /**
  159. * If enabled, the curve was imported from an external file and not created within the engine. This will affect
  160. * how are animation results applied to scene objects (with imported animations it is assumed the curve is
  161. * animating bones and with in-engine curves it is assumed the curve is animating scene objects).
  162. */
  163. ImportedCurve = 1 << 0,
  164. /** Signifies the curve is used to animate between different frames within a morph channel. In range [0, 1]. */
  165. MorphFrame = 1 << 1,
  166. /** Signifies the curve is used to adjust the weight of a morph channel. In range [0, 1]. */
  167. MorphWeight = 1 << 2
  168. };
  169. typedef Flags<AnimationCurveFlag> AnimationCurveFlags;
  170. BS_FLAGS_OPERATORS(AnimationCurveFlag);
  171. /** An animation curve and its name. */
  172. template <class T>
  173. struct TNamedAnimationCurve
  174. {
  175. TNamedAnimationCurve() { }
  176. /**
  177. * Constructs a new named animation curve.
  178. *
  179. * @param[in] name Name of the curve.
  180. * @param[in] curve Curve containing the animation data.
  181. */
  182. TNamedAnimationCurve(const String& name, const TAnimationCurve<T> curve)
  183. :name(name), curve(curve)
  184. { }
  185. /**
  186. * Constructs a new named animation curve.
  187. *
  188. * @param[in] name Name of the curve.
  189. * @param[in] flags Flags that describe the animation curve.
  190. * @param[in] curve Curve containing the animation data.
  191. */
  192. TNamedAnimationCurve(const String& name, AnimationCurveFlags flags, const TAnimationCurve<T> curve)
  193. :name(name), curve(curve)
  194. { }
  195. /** Name of the curve. */
  196. String name;
  197. /** Flags that describe the animation curve. */
  198. AnimationCurveFlags flags;
  199. /** Actual curve containing animation data. */
  200. TAnimationCurve<T> curve;
  201. };
  202. #ifdef BS_SBGEN
  203. template class BS_SCRIPT_EXPORT(m:Animation,n:NamedFloatCurve,pl:true) TNamedAnimationCurve<float>;
  204. template class BS_SCRIPT_EXPORT(m:Animation,n:NamedVector3Curve,pl:true) TNamedAnimationCurve<Vector3>;
  205. template class BS_SCRIPT_EXPORT(m:Animation,n:NamedQuaternionCurve,pl:true) TNamedAnimationCurve<Quaternion>;
  206. #endif
  207. /** @} */
  208. }