BsAnimationCurve.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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 "BsCurveCache.h"
  6. namespace BansheeEngine
  7. {
  8. /** @addtogroup Animation-Internal
  9. * @{
  10. */
  11. /** Animation keyframe, represented as an endpoint of a cubic hermite spline. */
  12. template <class T>
  13. struct TKeyframe
  14. {
  15. T value; /**< Value of the key. */
  16. T inTangent; /**< Input tangent (going from the previous key to this one) of the key. */
  17. T outTangent; /**< Output tangent (going from this key to next one) of the key. */
  18. float time; /**< Position of the key along the animation spline. */
  19. };
  20. /**
  21. * Animation spline represented by a set of keyframes, each representing an endpoint of a cubic hermite curve. The
  22. * spline can be evaluated at any time, and uses caching to speed up multiple sequential evaluations.
  23. */
  24. template <class T>
  25. class BS_CORE_EXPORT TAnimationCurve // Note: Curves are expected to be immutable for threading purposes
  26. {
  27. public:
  28. typedef TKeyframe<T> KeyFrame;
  29. TAnimationCurve();
  30. TAnimationCurve(const Vector<KeyFrame>& keyframes);
  31. /**
  32. * Evaluate the animation curve using caching. Caching can significantly speed of evaluation if the evaluation
  33. * happens sequential order (which should be true for most curves). If evaluation is not happening in sequential
  34. * order using the non-caching version of evaluate() might yield better performance.
  35. *
  36. * @param[in] time Time to evaluate the curve at.
  37. * @param[in] cache Cached data from previous requests that can be used for speeding up sequential calls
  38. * to this method. Caller should ensure to maintain a persistent instance of this data
  39. * for every animation using this curve in order to ensure cache is maintained.
  40. * @param[in] loop If true the curve will loop when it goes past the end or beggining. Otherwise the
  41. * curve value will be clamped.
  42. * @return Interpolated value from the curve at provided time.
  43. */
  44. T evaluate(float time, const TCurveCache<T>& cache, bool loop = true) const;
  45. /**
  46. * Evaluate the animation curve at the specified time. If evaluating multiple values in a sequential order consider
  47. * using the cached version of evaluate() for better performance.
  48. *
  49. * @param[in] time Time to evaluate the curve at.
  50. * @param[in] loop If true the curve will loop when it goes past the end or beggining. Otherwise the curve
  51. * value will be clamped.
  52. * @return Interpolated value from the curve at provided time.
  53. */
  54. T evaluate(float time, bool loop = true) const;
  55. /**
  56. * Evaluate the animation curve at the specified time and returns a new keyframe containing the evaluated value
  57. * and tangents.
  58. *
  59. * @param[in] time Time to evaluate the curve at.
  60. * @param[in] loop If true the curve will loop when it goes past the end or beggining. Otherwise the curve
  61. * value will be clamped.
  62. * @return Keyframe containing the interpolated value and tangents at provided time.
  63. */
  64. KeyFrame evaluateKey(float time, bool loop = true) const;
  65. /**
  66. * Splits a piece of the animation curve into a separate animation curve.
  67. *
  68. * @param[in] start Beginning time of the split curve.
  69. * @param[in] end End time of the split curve.
  70. * @return New curve with data corresponding to the provided split times.
  71. */
  72. TAnimationCurve<T> split(float start, float end);
  73. /**
  74. * Converts a normal curve into an additive curve. It is assumed the first keyframe in the curve is the reference
  75. * key from which to generate the additive curve. Such curves can then be added on top of a curve containing
  76. * reference keys.
  77. */
  78. void makeAdditive();
  79. /** Returns the length of the animation curve, from time zero to last keyframe. */
  80. float getLength() const { return mEnd; }
  81. /** Returns the total number of key-frames in the curve. */
  82. UINT32 getNumKeyFrames() const { return (UINT32)mKeyframes.size(); }
  83. /** Returns a keyframe at the specified index. */
  84. const TKeyframe<T>& getKeyFrame(UINT32 idx) const { return mKeyframes[idx]; }
  85. private:
  86. friend struct RTTIPlainType<TAnimationCurve<T>>;
  87. /**
  88. * Returns a pair of keys that can be used for interpolating to field the value at the provided time. This attempts
  89. * to find keys using the cache first, and if not possible falls back to a full search.
  90. *
  91. * @param[in] time Time for which to find the relevant keys from. It is expected to be clamped to a
  92. * valid range within the curve.
  93. * @param[in] cache Animation instance data holding the time to evaluate the curve at, and any cached
  94. * data from previous requests. Time is expected to be clamped to a valid range
  95. * within the curve.
  96. * @param[out] leftKey Index of the key to interpolate from.
  97. * @param[out] rightKey Index of the key to interpolate to.
  98. */
  99. void findKeys(float time, const TCurveCache<T>& cache, UINT32& leftKey, UINT32& rightKey) const;
  100. /**
  101. * Returns a pair of keys that can be used for interpolating to field the value at the provided time.
  102. *
  103. * @param[in] time Time for which to find the relevant keys from. It is expected to be clamped to a
  104. * valid range within the curve.
  105. * @param[out] leftKey Index of the key to interpolate from.
  106. * @param[out] rightKey Index of the key to interpolate to.
  107. */
  108. void findKeys(float time, UINT32& leftKey, UINT32& rightKey) const;
  109. /** Returns a keyframe index nearest to the provided time. */
  110. UINT32 findKey(float time);
  111. /**
  112. * Calculates a key in-between the provided two keys.
  113. *
  114. * @param[in] lhs Key to interpolate from.
  115. * @param[in] rhs Key to interpolate to.
  116. * @param[in] t Curve time to interpolate the keys at.
  117. * @return Interpolated key value.
  118. */
  119. KeyFrame evaluateKey(const KeyFrame& lhs, const KeyFrame& rhs, float time) const;
  120. /**
  121. * Evaluates a value at the cached curve. Caller must ensure the request time falls within the cached curve range.
  122. *
  123. * @param[in] time Time to evaluate the curve at.
  124. * @param[in] animInstance Animation instance data holding the time to evaluate the curve at, and any cached
  125. * data from previous requests.
  126. * @return Interpolated value from the curve at provided time.
  127. */
  128. T evaluateCache(float time, const TCurveCache<T>& animInstance) const;
  129. static const UINT32 CACHE_LOOKAHEAD;
  130. Vector<KeyFrame> mKeyframes;
  131. float mStart;
  132. float mEnd;
  133. float mLength;
  134. };
  135. /** Flags that described an TAnimationCurve<T>. */
  136. enum class AnimationCurveFlag
  137. {
  138. /** Signifies that the curve was imported from an external file, and not created manually in-engine. */
  139. ImportedCurve
  140. };
  141. typedef Flags<AnimationCurveFlag> AnimationCurveFlags;
  142. BS_FLAGS_OPERATORS(AnimationCurveFlag);
  143. /** An animation curve and its name. */
  144. template <class T>
  145. struct TNamedAnimationCurve
  146. {
  147. String name;
  148. AnimationCurveFlags flags;
  149. TAnimationCurve<T> curve;
  150. };
  151. /** @} */
  152. }