BsAnimation.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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,
  30. Layout = 2
  31. };
  32. typedef Flags<AnimDirtyStateFlag> AnimDirtyState;
  33. BS_FLAGS_OPERATORS(AnimDirtyStateFlag)
  34. /** Contains information about a currently playing animation clip. */
  35. struct AnimationClipState
  36. {
  37. AnimationClipState() { }
  38. /** Layer the clip is playing on. Multiple clips can be played simulatenously on different layers. */
  39. UINT32 layer = 0;
  40. float time = 0.0f; /**< Current time the animation is playing from. */
  41. float speed = 1.0f; /**< Speed at which the animation is playing. */
  42. float weight = 1.0f; /**< Determines how much of an influence does the clip have on the final pose. */
  43. /** Determines what happens to other animation clips when a new clip starts playing. */
  44. AnimWrapMode wrapMode = AnimWrapMode::Loop;
  45. };
  46. /** Internal information about a single playing animation clip within Animation. */
  47. struct PlayingClipInfo
  48. {
  49. PlayingClipInfo() { }
  50. PlayingClipInfo(const HAnimationClip& clip);
  51. HAnimationClip clip;
  52. AnimationClipState state;
  53. };
  54. /** Represents a copy of the Animation data for use specifically on the animation thread. */
  55. struct AnimationProxy
  56. {
  57. AnimationProxy();
  58. ~AnimationProxy();
  59. /**
  60. * Updates the proxy data with a new skeleton and clips. Very expensive update operation.
  61. *
  62. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  63. */
  64. void updateSkeleton(const SPtr<Skeleton>& skeleton, const Vector<PlayingClipInfo>& clipInfos);
  65. /**
  66. * Updates the proxy data with new clips. Very expensive update operation.
  67. *
  68. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  69. */
  70. void updateLayout(const Vector<PlayingClipInfo>& clipInfos);
  71. /**
  72. * Updates the proxy data with new information about the clips. Caller must guarantee that clip layout didn't
  73. * change. Fairly cheap update operation.
  74. *
  75. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  76. */
  77. void updateValues(const Vector<PlayingClipInfo>& clipInfos);
  78. /**
  79. * Updates the proxy data with new clip times. Caller must guarantee that clip layout didn't change. Very cheap
  80. * update operation.
  81. *
  82. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  83. */
  84. void updateTime(const Vector<PlayingClipInfo>& clipInfos);
  85. AnimationStateLayer* layers;
  86. UINT32 numLayers;
  87. SPtr<Skeleton> skeleton;
  88. SkeletonPose pose;
  89. };
  90. /**
  91. * Handles animation playback. Takes one or multiple animation clips as input and evaluates them every animation update
  92. * tick depending on set properties. The evaluated data is used by the core thread for skeletal animation, by the sim
  93. * thread for updating attached scene objects and bones (if skeleton is attached), or the data is made available for
  94. * manual queries in the case of generic animation.
  95. */
  96. class BS_CORE_EXPORT Animation : public CoreObject
  97. {
  98. public:
  99. ~Animation();
  100. /**
  101. * Changes the skeleton which will the translation/rotation/scale animation values manipulate. If no skeleton is set
  102. * the animation will only evaluate the generic curves, and the root translation/rotation/scale curves.
  103. */
  104. void setSkeleton(const SPtr<Skeleton>& skeleton);
  105. /**
  106. * Changes the wrap mode for all active animations. Wrap mode determines what happens when animation reaches the
  107. * first or last frame.
  108. *
  109. * @see AnimWrapMode
  110. */
  111. void setWrapMode(AnimWrapMode wrapMode);
  112. /** Changes the speed for all animations. The default value is 1.0f. Use negative values to play-back in reverse. */
  113. void setSpeed(float speed);
  114. /**
  115. * Plays the specified animation clip at the specified layer.
  116. *
  117. * @param[in] clip Clip to play.
  118. * @param[in] layer Layer to play the clip in. Multiple clips can be playing at once in separate layers.
  119. * @param[in] playMode Determines how are other playing animations handled when this animation starts.
  120. */
  121. void play(const HAnimationClip& clip, UINT32 layer = 0, AnimPlayMode playMode = AnimPlayMode::StopLayer);
  122. /**
  123. * Blends the specified animation clip with other animation clips playing in the specified layer.
  124. *
  125. * @param[in] clip Clip to blend.
  126. * @param[in] weight Determines how much of an effect will the blended animation have on the final output.
  127. * In range [0, 1]. All animation weights on the same layer will be normalized.
  128. * @param[in] fadeLength Applies the blend over a specified time period, increasing the weight as the time
  129. * passes. Set to zero to blend immediately. In seconds.
  130. * @param[in] layer Layer to play the clip in. Multiple clips can be playing at once in separate layers.
  131. */
  132. void blend(const HAnimationClip& clip, float weight, float fadeLength = 0.0f, UINT32 layer = 0);
  133. /**
  134. * Fades the specified animation clip in, while fading other playing animations out, over the specified time
  135. * period.
  136. *
  137. * @param[in] clip Clip to fade in.
  138. * @param[in] fadeLength Determines the time period over which the fade occurs. In seconds.
  139. * @param[in] layer Layer to play the clip in. Multiple clips can be playing at once in separate layers.
  140. * @param[in] playMode Determines should all other animations be faded out, or just the ones on the same layer.
  141. */
  142. void crossFade(const HAnimationClip& clip, float fadeLength, UINT32 layer = 0,
  143. AnimPlayMode playMode = AnimPlayMode::StopLayer);
  144. /** Stops playing all animations on the provided layer. */
  145. void stop(UINT32 layer);
  146. /** Stops playing all animations. */
  147. void stopAll();
  148. /** Checks if any animation clips are currently playing. */
  149. bool isPlaying() const;
  150. /**
  151. * Retrieves detailed information about a currently playing animation clip.
  152. *
  153. * @param[in] clip Clip to retrieve the information for.
  154. * @param[out] state Animation clip state containing the requested information. Only valid if the method returns
  155. * true.
  156. * @return True if the state was found (animation clip is playing), false otherwise.
  157. */
  158. bool getState(const HAnimationClip& clip, AnimationClipState& state);
  159. /**
  160. * Changes the state of a playing animation clip. If animation clip is not currently playing the state change is
  161. * ignored.
  162. *
  163. * @param[in] clip Clip to change the state for.
  164. * @param[in] state New state of the animation (e.g. changing the time for seeking).
  165. */
  166. void setState(const HAnimationClip& clip, AnimationClipState state);
  167. /** Creates a new empty Animation object. */
  168. static SPtr<Animation> create();
  169. private:
  170. friend class AnimationManager;
  171. Animation();
  172. /**
  173. * Updates the animation proxy object based on the currently set skeleton, playing clips and dirty flags.
  174. *
  175. * @param[in] timeDelta Seconds passed since the last call to this method.
  176. */
  177. void updateAnimProxy(float timeDelta);
  178. UINT64 mId;
  179. AnimWrapMode mDefaultWrapMode;
  180. float mDefaultSpeed;
  181. AnimDirtyState mDirty;
  182. SPtr<Skeleton> mSkeleton;
  183. Vector<PlayingClipInfo> mPlayingClips;
  184. // Animation thread only
  185. AnimationProxy mAnimProxy;
  186. };
  187. /** @} */
  188. }