BsAnimation.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  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 "BsIResourceListener.h"
  7. #include "BsFlags.h"
  8. #include "BsSkeleton.h"
  9. #include "BsSkeletonMask.h"
  10. #include "BsVector2.h"
  11. #include "BsAABox.h"
  12. namespace BansheeEngine
  13. {
  14. /** @addtogroup Animation-Internal
  15. * @{
  16. */
  17. /** Determines how an animation clip behaves when it reaches the end. */
  18. enum class AnimWrapMode
  19. {
  20. Loop, /**< Loop around to the beginning/end when the last/first frame is reached. */
  21. Clamp /**< Clamp to end/beginning, keeping the last/first frame active. */
  22. };
  23. /** Flags that determine which portion of Animation was changed and needs to be updated. */
  24. enum class AnimDirtyStateFlag
  25. {
  26. Clean = 0,
  27. Value = 1 << 0,
  28. Layout = 1 << 1,
  29. All = 1 << 2,
  30. Culling = 1 << 3,
  31. MorphWeights = 1 << 4
  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. * Determines should the time be advanced automatically. Certain type of animation clips don't involve playback
  48. * (e.g. for blending where animation weight controls the animation).
  49. */
  50. bool stopped = false;
  51. };
  52. /** Type of playback for animation clips. */
  53. enum class AnimPlaybackType
  54. {
  55. /** Play back the animation normally by advancing time. */
  56. Normal,
  57. /** Sample only a single frame from the animation. */
  58. Sampled,
  59. /** Do not play the animation. */
  60. None
  61. };
  62. /** Internal information about a single playing animation clip within Animation. */
  63. struct AnimationClipInfo
  64. {
  65. AnimationClipInfo();
  66. AnimationClipInfo(const HAnimationClip& clip);
  67. HAnimationClip clip;
  68. AnimationClipState state;
  69. AnimPlaybackType playbackType;
  70. float fadeDirection;
  71. float fadeTime;
  72. float fadeLength;
  73. /**
  74. * Version of the animation curves used by the AnimationProxy. Used to detecting the internal animation curves
  75. * changed.
  76. */
  77. UINT64 curveVersion;
  78. UINT32 layerIdx; /**< Layer index this clip belongs to in AnimationProxy structure. */
  79. UINT32 stateIdx; /**< State index this clip belongs to in AnimationProxy structure. */
  80. };
  81. /** Represents an animation clip used in 1D blending. Each clip has a position on the number line. */
  82. struct BS_CORE_EXPORT BlendClipInfo
  83. {
  84. BlendClipInfo() { }
  85. HAnimationClip clip;
  86. float position = 0.0f;
  87. };
  88. /** Defines a 1D blend where multiple animation clips are blended between each other using linear interpolation. */
  89. struct BS_CORE_EXPORT Blend1DInfo
  90. {
  91. Blend1DInfo(UINT32 numClips);
  92. ~Blend1DInfo();
  93. UINT32 numClips;
  94. BlendClipInfo* clips;
  95. };
  96. /** Defines a 2D blend where two animation clips are blended between each other using bilinear interpolation. */
  97. struct Blend2DInfo
  98. {
  99. HAnimationClip topLeftClip;
  100. HAnimationClip topRightClip;
  101. HAnimationClip botLeftClip;
  102. HAnimationClip botRightClip;
  103. };
  104. /** Contains a mapping between a scene object and an animation curve it is animated with. */
  105. struct AnimatedSceneObject
  106. {
  107. HSceneObject so;
  108. String curveName;
  109. };
  110. /** Information about a set of morph shapes blended sequentially. */
  111. struct MorphChannelInfo
  112. {
  113. float weight;
  114. UINT32 shapeStart;
  115. UINT32 shapeCount;
  116. UINT32 frameCurveIdx;
  117. UINT32 weightCurveIdx;
  118. };
  119. /** Morph shape and its contribution to the final shape. */
  120. struct MorphShapeInfo
  121. {
  122. SPtr<MorphShape> shape;
  123. float frameWeight;
  124. float finalWeight;
  125. };
  126. /** Contains information about a scene object that is animated by a specific animation curve. */
  127. struct AnimatedSceneObjectInfo
  128. {
  129. UINT64 id; /**< Instance ID of the scene object. */
  130. INT32 boneIdx; /**< Bone from which to access the transform. If -1 then no bone mapping is present. */
  131. INT32 layerIdx; /**< If no bone mapping, layer on which the animation containing the referenced curve is in. */
  132. INT32 stateIdx; /**< If no bone mapping, animation state containing the referenced curve. */
  133. AnimationCurveMapping curveIndices; /**< Indices of the curves used for the transform. */
  134. UINT32 hash; /**< Hash value of the scene object's transform. */
  135. };
  136. /** Represents a copy of the Animation data for use specifically on the animation thread. */
  137. struct AnimationProxy
  138. {
  139. AnimationProxy(UINT64 id);
  140. AnimationProxy(const AnimationProxy&) = delete;
  141. ~AnimationProxy();
  142. AnimationProxy& operator=(const AnimationProxy&) = delete;
  143. /**
  144. * Rebuilds the internal proxy data according to the newly assigned skeleton and clips. This should be called
  145. * whenever the animation skeleton changes.
  146. *
  147. * @param[in] skeleton New skeleton to assign to the proxy.
  148. * @param[in] mask Mask that filters which skeleton bones are enabled or disabled.
  149. * @param[in, out] clipInfos Potentially new clip infos that will be used for rebuilding the proxy. Once the
  150. * method completes clip info layout and state indices will be populated for
  151. * further use in the update*() methods.
  152. * @param[in] sceneObjects A list of scene objects that are influenced by specific animation curves.
  153. * @param[in] morphShapes Morph shapes used for per-vertex animation.
  154. *
  155. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  156. */
  157. void rebuild(const SPtr<Skeleton>& skeleton, const SkeletonMask& mask, Vector<AnimationClipInfo>& clipInfos,
  158. const Vector<AnimatedSceneObject>& sceneObjects, const SPtr<MorphShapes>& morphShapes);
  159. /**
  160. * Rebuilds the internal proxy data according to the newly clips. This should be called whenever clips are added
  161. * or removed, or clip layout indices change.
  162. *
  163. * @param[in, out] clipInfos New clip infos that will be used for rebuilding the proxy. Once the method
  164. * completes clip info layout and state indices will be populated for further use
  165. * in the update*() methods.
  166. * @param[in] sceneObjects A list of scene objects that are influenced by specific animation curves.
  167. * * @param[in] morphShapes Morph shapes used for per-vertex animation.
  168. *
  169. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  170. */
  171. void rebuild(Vector<AnimationClipInfo>& clipInfos, const Vector<AnimatedSceneObject>& sceneObjects,
  172. const SPtr<MorphShapes>& morphShapes);
  173. /**
  174. * Updates the proxy data with new information about the clips. Caller must guarantee that clip layout didn't
  175. * change since the last call to rebuild().
  176. *
  177. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  178. */
  179. void updateClipInfos(const Vector<AnimationClipInfo>& clipInfos);
  180. /**
  181. * Updates the proxy data with new weights used for morph shapes. Caller must ensure the weights are ordered so
  182. * they match with the morph shapes provided to the last rebuild() call.
  183. */
  184. void updateMorphChannelWeights(const Vector<float>& weights);
  185. /**
  186. * Updates the proxy data with new scene object transforms. Caller must guarantee that clip layout didn't
  187. * change since the last call to rebuild().
  188. *
  189. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  190. */
  191. void updateTransforms(const Vector<AnimatedSceneObject>& sceneObjects);
  192. /**
  193. * Updates the proxy data with new clip times. Caller must guarantee that clip layout didn't change since the last
  194. * call to rebuild().
  195. *
  196. * @note Should be called from the sim thread when the caller is sure the animation thread is not using it.
  197. */
  198. void updateTime(const Vector<AnimationClipInfo>& clipInfos);
  199. /** Destroys all dynamically allocated objects. */
  200. void clear();
  201. UINT64 id;
  202. // Skeletal animation
  203. AnimationStateLayer* layers;
  204. UINT32 numLayers;
  205. SPtr<Skeleton> skeleton;
  206. SkeletonMask skeletonMask;
  207. UINT32 numSceneObjects;
  208. AnimatedSceneObjectInfo* sceneObjectInfos;
  209. Matrix4* sceneObjectTransforms;
  210. // Morph shape animation
  211. MorphChannelInfo* morphChannelInfos;
  212. MorphShapeInfo* morphShapeInfos;
  213. UINT32 numMorphChannels;
  214. UINT32 numMorphShapes;
  215. UINT32 numMorphVertices;
  216. bool morphChannelWeightsDirty;
  217. // Culling
  218. AABox mBounds;
  219. bool mCullEnabled;
  220. // Evaluation results
  221. LocalSkeletonPose skeletonPose;
  222. LocalSkeletonPose sceneObjectPose;
  223. UINT32 numGenericCurves;
  224. float* genericCurveOutputs;
  225. };
  226. /**
  227. * Handles animation playback. Takes one or multiple animation clips as input and evaluates them every animation update
  228. * tick depending on set properties. The evaluated data is used by the core thread for skeletal animation, by the sim
  229. * thread for updating attached scene objects and bones (if skeleton is attached), or the data is made available for
  230. * manual queries in the case of generic animation.
  231. */
  232. class BS_CORE_EXPORT Animation : public CoreObject, public IResourceListener
  233. {
  234. public:
  235. ~Animation();
  236. /**
  237. * Changes the skeleton which will the translation/rotation/scale animation values manipulate. If no skeleton is set
  238. * the animation will only evaluate the generic curves, and the root translation/rotation/scale curves.
  239. */
  240. void setSkeleton(const SPtr<Skeleton>& skeleton);
  241. /**
  242. * Sets morph shapes that can be used for per-vertex blending animation. After they're set call
  243. * setMorphShapeWeight() to apply morph shapes.
  244. */
  245. void setMorphShapes(const SPtr<MorphShapes>& morphShapes);
  246. /**
  247. * Changes a weight of a single morph channel, determining how much of it to apply on top of the base mesh.
  248. *
  249. * @param idx Index of the morph channel to modify. This must match the channels contained in the object
  250. * provided to setMorphShapes().
  251. * @param weight Weight that determines how much of the channel to apply to the mesh, in range [0, 1].
  252. */
  253. void setMorphChannelWeight(UINT32 idx, float weight);
  254. /**
  255. * Sets a mask that allows certain bones from the skeleton to be disabled. Caller must ensure that the mask matches
  256. * the skeleton assigned to the animation.
  257. */
  258. void setMask(const SkeletonMask& mask);
  259. /**
  260. * Changes the wrap mode for all active animations. Wrap mode determines what happens when animation reaches the
  261. * first or last frame.
  262. *
  263. * @see AnimWrapMode
  264. */
  265. void setWrapMode(AnimWrapMode wrapMode);
  266. /** Changes the speed for all animations. The default value is 1.0f. Use negative values to play-back in reverse. */
  267. void setSpeed(float speed);
  268. /** Sets bounds that will be used for animation culling, if enabled. Bounds must be in world space. */
  269. void setBounds(const AABox& bounds);
  270. /**
  271. * When enabled, animation that is not in a view of any camera will not be evaluated. View determination is done by
  272. * checking the bounds provided in setBounds().
  273. */
  274. void setCulling(bool cull);
  275. /**
  276. * Plays the specified animation clip.
  277. *
  278. * @param[in] clip Clip to play.
  279. */
  280. void play(const HAnimationClip& clip);
  281. /**
  282. * Plays the specified animation clip on top of the animation currently playing in the main layer. Multiple
  283. * such clips can be playing at once, as long as you ensure each is given its own layer. Each animation can
  284. * also have a weight that determines how much it influences the main animation.
  285. *
  286. * @param[in] clip Clip to additively blend. Must contain additive animation curves.
  287. * @param[in] weight Determines how much of an effect will the blended animation have on the final output.
  288. * In range [0, 1].
  289. * @param[in] fadeLength Applies the blend over a specified time period, increasing the weight as the time
  290. * passes. Set to zero to blend immediately. In seconds.
  291. * @param[in] layer Layer to play the clip in. Multiple additive clips can be playing at once in separate
  292. * layers and each layer has its own weight.
  293. */
  294. void blendAdditive(const HAnimationClip& clip, float weight, float fadeLength = 0.0f, UINT32 layer = 0);
  295. /**
  296. * Blend multiple animation clips between each other using linear interpolation. Unlike normal animations these
  297. * animations are not advanced with the progress of time, and is instead expected the user manually changes the
  298. * @p t parameter.
  299. *
  300. * @param[in] info Information about the clips to blend. Clip positions must be sorted from lowest to highest.
  301. * @param[in] t Parameter that controls the blending. Range depends on the positions of the provided
  302. * animation clips.
  303. */
  304. void blend1D(const Blend1DInfo& info, float t);
  305. /**
  306. * Blend four animation clips between each other using bilinear interpolation. Unlike normal animations these
  307. * animations are not advanced with the progress of time, and is instead expected the user manually changes the
  308. * @p t parameter.
  309. *
  310. * @param[in] info Information about the clips to blend.
  311. * @param[in] t Parameter that controls the blending, in range [(0, 0), (1, 1)]. t = (0, 0) means top left
  312. * animation has full influence, t = (0, 1) means top right animation has full influence,
  313. * t = (1, 0) means bottom left animation has full influence, t = (1, 1) means bottom right
  314. * animation has full influence.
  315. */
  316. void blend2D(const Blend2DInfo& info, const Vector2& t);
  317. /**
  318. * Fades the specified animation clip in, while fading other playing animation out, over the specified time
  319. * period.
  320. *
  321. * @param[in] clip Clip to fade in.
  322. * @param[in] fadeLength Determines the time period over which the fade occurs. In seconds.
  323. */
  324. void crossFade(const HAnimationClip& clip, float fadeLength);
  325. /**
  326. * Samples an animation clip at the specified time, displaying only that particular frame without further playback.
  327. *
  328. * @param[in] clip Animation clip to sample.
  329. * @param[in] time Time to sample the clip at.
  330. */
  331. void sample(const HAnimationClip& clip, float time);
  332. /**
  333. * Stops playing all animations on the provided layer. Specify -1 to stop animation on the main layer
  334. * (non-additive animations).
  335. */
  336. void stop(UINT32 layer);
  337. /** Stops playing all animations. */
  338. void stopAll();
  339. /** Checks if any animation clips are currently playing. */
  340. bool isPlaying() const;
  341. /** Returns the total number of animation clips influencing this animation. */
  342. UINT32 getNumClips() const;
  343. /**
  344. * Returns one of the animation clips influencing this animation.
  345. *
  346. * @param[in] idx Sequential index of the animation clip to retrieve. In range [0, getNumClips()].
  347. * @return Animation clip at the specified index, or null if the index is out of range.
  348. */
  349. HAnimationClip getClip(UINT32 idx) const;
  350. /**
  351. * Retrieves detailed information about a currently playing animation clip.
  352. *
  353. * @param[in] clip Clip to retrieve the information for.
  354. * @param[out] state Animation clip state containing the requested information. Only valid if the method returns
  355. * true.
  356. * @return True if the state was found (animation clip is playing), false otherwise.
  357. */
  358. bool getState(const HAnimationClip& clip, AnimationClipState& state);
  359. /**
  360. * Changes the state of a playing animation clip. If animation clip is not currently playing the state change is
  361. * ignored.
  362. *
  363. * @param[in] clip Clip to change the state for.
  364. * @param[in] state New state of the animation (e.g. changing the time for seeking).
  365. */
  366. void setState(const HAnimationClip& clip, AnimationClipState state);
  367. /**
  368. * Ensures that any position/rotation/scale animation of a specific animation curve is transfered to the
  369. * the provided scene object. Also allow the opposite operation which can allow scene object transform changes
  370. * to manipulate object bones.
  371. *
  372. * @param[in] curve Name of the curve (bone) to connect the scene object with. Use empty string to map to the
  373. * root bone, regardless of the bone name.
  374. * @param[in] so Scene object to influence by the curve modifications, and vice versa.
  375. */
  376. void mapCurveToSceneObject(const String& curve, const HSceneObject& so);
  377. /** Removes the curve <-> scene object mapping that was set via mapCurveToSceneObject(). */
  378. void unmapSceneObject(const HSceneObject& so);
  379. /**
  380. * Retrieves an evaluated value for a generic curve with the specified index.
  381. *
  382. * @param[in] curveIdx The curve index referencing a set of curves from the first playing animation clip.
  383. * Generic curves from all other clips are ignored.
  384. * @param[out] value Value of the generic curve. Only valid if the method return true.
  385. * @return True if the value was retrieved successfully. The method might fail if animation update
  386. * didn't yet have a chance to execute and values are not yet available, or if the
  387. * animation clip changed since the last frame (the last problem can be avoided by ensuring
  388. * to read the curve values before changing the clip).
  389. */
  390. bool getGenericCurveValue(UINT32 curveIdx, float& value);
  391. /** Creates a new empty Animation object. */
  392. static SPtr<Animation> create();
  393. /** Triggered whenever an animation event is reached. */
  394. Event<void(const HAnimationClip&, const String&)> onEventTriggered;
  395. /** @name Internal
  396. * @{
  397. */
  398. /** Returns the unique ID for this animation object. */
  399. UINT64 _getId() const { return mId; }
  400. /** Checks if any currently set animation clips perform animation of the root bone. */
  401. bool _getAnimatesRoot() const;
  402. /** @} */
  403. private:
  404. friend class AnimationManager;
  405. Animation();
  406. /**
  407. * Triggers any events between the last frame and current one.
  408. *
  409. * @param[in] lastFrameTime Time of the last frame.
  410. * @param[in] delta Difference between the last and this frame.
  411. */
  412. void triggerEvents(float lastFrameTime, float delta);
  413. /**
  414. * Updates the animation proxy object based on the currently set skeleton, playing clips and dirty flags.
  415. *
  416. * @param[in] timeDelta Seconds passed since the last call to this method.
  417. */
  418. void updateAnimProxy(float timeDelta);
  419. /**
  420. * Applies any outputs stored in the animation proxy (as written by the animation thread), and uses them to update
  421. * the animation state on the simulation thread. Caller must ensure that the animation thread has finished
  422. * with the animation proxy.
  423. */
  424. void updateFromProxy();
  425. /**
  426. * Registers a new animation in the specified layer, or returns an existing animation clip info if the animation is
  427. * already registered. If @p stopExisting is true any existing animations in the layer will be stopped. Layout
  428. * will be marked as dirty if any changes were made.
  429. */
  430. AnimationClipInfo* addClip(const HAnimationClip& clip, UINT32 layer, bool stopExisting = true);
  431. /** @copydoc IResourceListener::getListenerResources */
  432. void getListenerResources(Vector<HResource>& resources) override;
  433. /** @copydoc IResourceListener::notifyResourceLoaded */
  434. void notifyResourceLoaded(const HResource& resource) override;
  435. /** @copydoc IResourceListener::notifyResourceChanged */
  436. void notifyResourceChanged(const HResource& resource) override;
  437. UINT64 mId;
  438. AnimWrapMode mDefaultWrapMode;
  439. float mDefaultSpeed;
  440. AABox mBounds;
  441. bool mCull;
  442. AnimDirtyState mDirty;
  443. SPtr<Skeleton> mSkeleton;
  444. SkeletonMask mSkeletonMask;
  445. SPtr<MorphShapes> mMorphShapes;
  446. Vector<float> mMorphChannelWeights;
  447. Vector<AnimationClipInfo> mClipInfos;
  448. UnorderedMap<UINT64, AnimatedSceneObject> mSceneObjects;
  449. Vector<float> mGenericCurveOutputs;
  450. bool mGenericCurveValuesValid;
  451. // Animation thread only
  452. SPtr<AnimationProxy> mAnimProxy;
  453. };
  454. /** @} */
  455. }