BsAnimation.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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 "BsCoreObject.h"
  6. #include "BsFlags.h"
  7. #include "BsSkeleton.h"
  8. namespace BansheeEngine
  9. {
  10. /** @addtogroup Animation-Internal
  11. * @{
  12. */
  13. /** Determines how an animation clip behaves when it reaches the end. */
  14. enum class AnimWrapMode
  15. {
  16. Loop, /**< Loop around to the beginning/end when the last/first frame is reached. */
  17. Clamp /**< Clamp to end/beginning, keeping the last/first frame active. */
  18. };
  19. /** Determines what happens to other animation clips when a new clip starts playing. */
  20. enum class AnimPlayMode
  21. {
  22. StopAll, /**< All other animation clips are stopped. */
  23. StopLayer /**< Only the clips within the current layer are stopped. */
  24. };
  25. /** Flags that determine which portion of Animation was changed and needs to be updated. */
  26. enum class AnimDirtyStateFlag
  27. {
  28. Clean = 0,
  29. Value = 1 << 0,
  30. Layout = 1 << 1,
  31. Skeleton = 1 << 2
  32. };
  33. typedef Flags<AnimDirtyStateFlag> AnimDirtyState;
  34. BS_FLAGS_OPERATORS(AnimDirtyStateFlag)
  35. /** Contains information about a currently playing animation clip. */
  36. struct AnimationClipState
  37. {
  38. AnimationClipState() { }
  39. /** Layer the clip is playing on. Multiple clips can be played simulatenously on different layers. */
  40. UINT32 layer = 0;
  41. float time = 0.0f; /**< Current time the animation is playing from. */
  42. float speed = 1.0f; /**< Speed at which the animation is playing. */
  43. float weight = 1.0f; /**< Determines how much of an influence does the clip have on the final pose. */
  44. /** Determines what happens to other animation clips when a new clip starts playing. */
  45. AnimWrapMode wrapMode = AnimWrapMode::Loop;
  46. };
  47. /** Internal information about a single playing animation clip within Animation. */
  48. struct AnimationClipInfo
  49. {
  50. AnimationClipInfo();
  51. AnimationClipInfo(const HAnimationClip& clip);
  52. HAnimationClip clip;
  53. AnimationClipState state;
  54. /**
  55. * Version of the animation curves used by the AnimationProxy. Used to detecting the internal animation curves
  56. * changed.
  57. */
  58. UINT64 curveVersion;
  59. UINT32 layerIdx; /**< Layer index this clip belongs to in AnimationProxy structure. */
  60. UINT32 stateIdx; /**< State index this clip belongs to in AnimationProxy structure. */
  61. };
  62. /** Represents a copy of the Animation data for use specifically on the animation thread. */
  63. struct AnimationProxy
  64. {
  65. AnimationProxy(UINT64 id);
  66. ~AnimationProxy();
  67. /**
  68. * Rebuilds the internal proxy data according to the newly assigned skeleton and clips. This should be called
  69. * whenever the animation skeleton changes.
  70. *
  71. * @param[in] skeleton New skeleton to assign to the proxy.
  72. * @param[in, out] clipInfos Potentially new clip infos that will be used for rebuilding the proxy. Once the
  73. * method completes clip info layout and state indices will be populated for
  74. * further use in the update*() methods.
  75. *
  76. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  77. */
  78. void rebuild(const SPtr<Skeleton>& skeleton, Vector<AnimationClipInfo>& clipInfos);
  79. /**
  80. * Rebuilds the internal proxy data according to the newly clips. This should be called whenever clips are added
  81. * or removed, or clip layout indices change.
  82. *
  83. * @param[in, out] clipInfos New clip infos that will be used for rebuilding the proxy. Once the method completes
  84. * clip info layout and state indices will be populated for further use in the
  85. * update*() methods.
  86. *
  87. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  88. */
  89. void rebuild(Vector<AnimationClipInfo>& clipInfos);
  90. /**
  91. * Updates the proxy data with new information about the clips. Caller must guarantee that clip layout didn't
  92. * change since the last call to rebuild().
  93. *
  94. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  95. */
  96. void updateValues(const Vector<AnimationClipInfo>& clipInfos);
  97. /**
  98. * Updates the proxy data with new clip times. Caller must guarantee that clip layout didn't change since the last
  99. * call to rebuild().
  100. *
  101. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  102. */
  103. void updateTime(const Vector<AnimationClipInfo>& clipInfos);
  104. UINT64 id;
  105. AnimationStateLayer* layers;
  106. UINT32 numLayers;
  107. SPtr<Skeleton> skeleton;
  108. // Evaluation results
  109. LocalSkeletonPose localPose;
  110. float* genericCurveOutputs;
  111. };
  112. /**
  113. * Handles animation playback. Takes one or multiple animation clips as input and evaluates them every animation update
  114. * tick depending on set properties. The evaluated data is used by the core thread for skeletal animation, by the sim
  115. * thread for updating attached scene objects and bones (if skeleton is attached), or the data is made available for
  116. * manual queries in the case of generic animation.
  117. */
  118. class BS_CORE_EXPORT Animation : public CoreObject
  119. {
  120. public:
  121. ~Animation();
  122. /**
  123. * Changes the skeleton which will the translation/rotation/scale animation values manipulate. If no skeleton is set
  124. * the animation will only evaluate the generic curves, and the root translation/rotation/scale curves.
  125. */
  126. void setSkeleton(const SPtr<Skeleton>& skeleton);
  127. /**
  128. * Changes the wrap mode for all active animations. Wrap mode determines what happens when animation reaches the
  129. * first or last frame.
  130. *
  131. * @see AnimWrapMode
  132. */
  133. void setWrapMode(AnimWrapMode wrapMode);
  134. /** Changes the speed for all animations. The default value is 1.0f. Use negative values to play-back in reverse. */
  135. void setSpeed(float speed);
  136. /**
  137. * Plays the specified animation clip at the specified layer.
  138. *
  139. * @param[in] clip Clip to play.
  140. * @param[in] layer Layer to play the clip in. Multiple clips can be playing at once in separate layers.
  141. * @param[in] playMode Determines how are other playing animations handled when this animation starts.
  142. */
  143. void play(const HAnimationClip& clip, UINT32 layer = 0, AnimPlayMode playMode = AnimPlayMode::StopLayer);
  144. /**
  145. * Blends the specified animation clip with other animation clips playing in the specified layer.
  146. *
  147. * @param[in] clip Clip to blend.
  148. * @param[in] weight Determines how much of an effect will the blended animation have on the final output.
  149. * In range [0, 1]. All animation weights on the same layer will be normalized.
  150. * @param[in] fadeLength Applies the blend over a specified time period, increasing the weight as the time
  151. * passes. Set to zero to blend immediately. In seconds.
  152. * @param[in] layer Layer to play the clip in. Multiple clips can be playing at once in separate layers.
  153. */
  154. void blend(const HAnimationClip& clip, float weight, float fadeLength = 0.0f, UINT32 layer = 0);
  155. /**
  156. * Fades the specified animation clip in, while fading other playing animations out, over the specified time
  157. * period.
  158. *
  159. * @param[in] clip Clip to fade in.
  160. * @param[in] fadeLength Determines the time period over which the fade occurs. In seconds.
  161. * @param[in] layer Layer to play the clip in. Multiple clips can be playing at once in separate layers.
  162. * @param[in] playMode Determines should all other animations be faded out, or just the ones on the same layer.
  163. */
  164. void crossFade(const HAnimationClip& clip, float fadeLength, UINT32 layer = 0,
  165. AnimPlayMode playMode = AnimPlayMode::StopLayer);
  166. /** Stops playing all animations on the provided layer. */
  167. void stop(UINT32 layer);
  168. /** Stops playing all animations. */
  169. void stopAll();
  170. /** Checks if any animation clips are currently playing. */
  171. bool isPlaying() const;
  172. /**
  173. * Retrieves detailed information about a currently playing animation clip.
  174. *
  175. * @param[in] clip Clip to retrieve the information for.
  176. * @param[out] state Animation clip state containing the requested information. Only valid if the method returns
  177. * true.
  178. * @return True if the state was found (animation clip is playing), false otherwise.
  179. */
  180. bool getState(const HAnimationClip& clip, AnimationClipState& state);
  181. /**
  182. * Changes the state of a playing animation clip. If animation clip is not currently playing the state change is
  183. * ignored.
  184. *
  185. * @param[in] clip Clip to change the state for.
  186. * @param[in] state New state of the animation (e.g. changing the time for seeking).
  187. */
  188. void setState(const HAnimationClip& clip, AnimationClipState state);
  189. /** Creates a new empty Animation object. */
  190. static SPtr<Animation> create();
  191. /** @name Internal
  192. * @{
  193. */
  194. /** Returns the unique ID for this animation object. */
  195. UINT64 _getId() const { return mId; }
  196. /** @} */
  197. private:
  198. friend class AnimationManager;
  199. Animation();
  200. /**
  201. * Updates the animation proxy object based on the currently set skeleton, playing clips and dirty flags.
  202. *
  203. * @param[in] timeDelta Seconds passed since the last call to this method.
  204. */
  205. void updateAnimProxy(float timeDelta);
  206. /** Checks if all the clips in the provided layer are additive. If not it prints out a warning. */
  207. void checkAdditiveLayer(UINT32 layerIdx);
  208. UINT64 mId;
  209. AnimWrapMode mDefaultWrapMode;
  210. float mDefaultSpeed;
  211. AnimDirtyState mDirty;
  212. SPtr<Skeleton> mSkeleton;
  213. Vector<AnimationClipInfo> mClipInfos;
  214. // Animation thread only
  215. SPtr<AnimationProxy> mAnimProxy;
  216. };
  217. /** @} */
  218. }