BsAnimation.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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 PlayingClipInfo
  49. {
  50. PlayingClipInfo();
  51. PlayingClipInfo(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();
  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<PlayingClipInfo>& 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<PlayingClipInfo>& 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<PlayingClipInfo>& 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<PlayingClipInfo>& clipInfos);
  104. AnimationStateLayer* layers;
  105. UINT32 numLayers;
  106. SPtr<Skeleton> skeleton;
  107. SkeletonPose pose;
  108. };
  109. /**
  110. * Handles animation playback. Takes one or multiple animation clips as input and evaluates them every animation update
  111. * tick depending on set properties. The evaluated data is used by the core thread for skeletal animation, by the sim
  112. * thread for updating attached scene objects and bones (if skeleton is attached), or the data is made available for
  113. * manual queries in the case of generic animation.
  114. */
  115. class BS_CORE_EXPORT Animation : public CoreObject
  116. {
  117. public:
  118. ~Animation();
  119. /**
  120. * Changes the skeleton which will the translation/rotation/scale animation values manipulate. If no skeleton is set
  121. * the animation will only evaluate the generic curves, and the root translation/rotation/scale curves.
  122. */
  123. void setSkeleton(const SPtr<Skeleton>& skeleton);
  124. /**
  125. * Changes the wrap mode for all active animations. Wrap mode determines what happens when animation reaches the
  126. * first or last frame.
  127. *
  128. * @see AnimWrapMode
  129. */
  130. void setWrapMode(AnimWrapMode wrapMode);
  131. /** Changes the speed for all animations. The default value is 1.0f. Use negative values to play-back in reverse. */
  132. void setSpeed(float speed);
  133. /**
  134. * Plays the specified animation clip at the specified layer.
  135. *
  136. * @param[in] clip Clip to play.
  137. * @param[in] layer Layer to play the clip in. Multiple clips can be playing at once in separate layers.
  138. * @param[in] playMode Determines how are other playing animations handled when this animation starts.
  139. */
  140. void play(const HAnimationClip& clip, UINT32 layer = 0, AnimPlayMode playMode = AnimPlayMode::StopLayer);
  141. /**
  142. * Blends the specified animation clip with other animation clips playing in the specified layer.
  143. *
  144. * @param[in] clip Clip to blend.
  145. * @param[in] weight Determines how much of an effect will the blended animation have on the final output.
  146. * In range [0, 1]. All animation weights on the same layer will be normalized.
  147. * @param[in] fadeLength Applies the blend over a specified time period, increasing the weight as the time
  148. * passes. Set to zero to blend immediately. In seconds.
  149. * @param[in] layer Layer to play the clip in. Multiple clips can be playing at once in separate layers.
  150. */
  151. void blend(const HAnimationClip& clip, float weight, float fadeLength = 0.0f, UINT32 layer = 0);
  152. /**
  153. * Fades the specified animation clip in, while fading other playing animations out, over the specified time
  154. * period.
  155. *
  156. * @param[in] clip Clip to fade in.
  157. * @param[in] fadeLength Determines the time period over which the fade occurs. In seconds.
  158. * @param[in] layer Layer to play the clip in. Multiple clips can be playing at once in separate layers.
  159. * @param[in] playMode Determines should all other animations be faded out, or just the ones on the same layer.
  160. */
  161. void crossFade(const HAnimationClip& clip, float fadeLength, UINT32 layer = 0,
  162. AnimPlayMode playMode = AnimPlayMode::StopLayer);
  163. /** Stops playing all animations on the provided layer. */
  164. void stop(UINT32 layer);
  165. /** Stops playing all animations. */
  166. void stopAll();
  167. /** Checks if any animation clips are currently playing. */
  168. bool isPlaying() const;
  169. /**
  170. * Retrieves detailed information about a currently playing animation clip.
  171. *
  172. * @param[in] clip Clip to retrieve the information for.
  173. * @param[out] state Animation clip state containing the requested information. Only valid if the method returns
  174. * true.
  175. * @return True if the state was found (animation clip is playing), false otherwise.
  176. */
  177. bool getState(const HAnimationClip& clip, AnimationClipState& state);
  178. /**
  179. * Changes the state of a playing animation clip. If animation clip is not currently playing the state change is
  180. * ignored.
  181. *
  182. * @param[in] clip Clip to change the state for.
  183. * @param[in] state New state of the animation (e.g. changing the time for seeking).
  184. */
  185. void setState(const HAnimationClip& clip, AnimationClipState state);
  186. /** Creates a new empty Animation object. */
  187. static SPtr<Animation> create();
  188. private:
  189. friend class AnimationManager;
  190. Animation();
  191. /**
  192. * Updates the animation proxy object based on the currently set skeleton, playing clips and dirty flags.
  193. *
  194. * @param[in] timeDelta Seconds passed since the last call to this method.
  195. */
  196. void updateAnimProxy(float timeDelta);
  197. UINT64 mId;
  198. AnimWrapMode mDefaultWrapMode;
  199. float mDefaultSpeed;
  200. AnimDirtyState mDirty;
  201. SPtr<Skeleton> mSkeleton;
  202. Vector<PlayingClipInfo> mPlayingClips;
  203. // Animation thread only
  204. SPtr<AnimationProxy> mAnimProxy;
  205. };
  206. /** @} */
  207. }