NcEngine
SkeletalAnimationController.h
Go to the documentation of this file.
1
5#pragma once
6
9
10#include <functional>
11#include <limits>
12
13namespace nc
14{
16using AnimationStateId = uint32_t;
17constexpr auto NullAnimationState = std::numeric_limits<AnimationStateId>::max();
18constexpr auto RootAnimationState = AnimationStateId{0u};
19constexpr auto ImmediateAnimationState = NullAnimationState - 1u;
20constexpr auto MaxAnimationStates = 32ull;
21
23using TransitionCondition = std::move_only_function<bool()>;
24constexpr bool ConditionNever() { return false; }
25constexpr auto UseDefaultTransitionDuration = -1.0f;
26
29{
30 asset::AssetId animId = asset::NullAssetId;
31 TransitionCondition enterWhen = ConditionNever;
32 AnimationStateId enterFrom = RootAnimationState;
33 TransitionCondition exitWhen = ConditionNever;
34 AnimationStateId exitTo = RootAnimationState;
35 float transitionDuration = UseDefaultTransitionDuration;
36};
37
40{
41 asset::AssetId animId = asset::NullAssetId;
42 TransitionCondition enterWhen = ConditionNever;
43 AnimationStateId enterFrom = RootAnimationState;
44 AnimationStateId exitTo = RootAnimationState;
45 float transitionDuration = UseDefaultTransitionDuration;
46};
47
50{
51 TransitionCondition enterWhen = ConditionNever;
52 AnimationStateId enterFrom = RootAnimationState;
53 float transitionDuration = UseDefaultTransitionDuration;
54};
55
57enum class AnimationTransitionType : uint8_t
58{
59 Continue,
60 Loop,
61 PlayOnce,
62 Stop
63};
64
65struct AnimationState
66{
67 asset::AssetId animId = asset::NullAssetId;
68 TransitionCondition enterWhen = ConditionNever;
69 TransitionCondition exitWhen = ConditionNever;
70 AnimationStateId enterFrom = NullAnimationState;
71 AnimationStateId exitTo = NullAnimationState;
72 float transitionDuration = UseDefaultTransitionDuration;
73 AnimationTransitionType action = AnimationTransitionType::Loop;
74 std::vector<AnimationStateId> successors = {};
75};
76
77struct AnimationTransition
78{
79 asset::AssetId toAnimId = asset::NullAssetId;
80 asset::AssetId fromAnimId = asset::NullAssetId;
81 float transitionDuration = 0.0f;
82 AnimationTransitionType type = AnimationTransitionType::Continue;
83};
88{
89 public:
96 explicit SkeletalAnimationController(asset::AssetId animationId = asset::NullAssetId,
97 float defaultTransitionDuration = 0.3f);
98
104 auto GetActiveState() const -> AnimationStateId { return m_activeState; }
105 auto GetCurrentAnimationId() const -> uint64_t;
106 auto AddState(LoopAnimation&& properties) -> AnimationStateId;
107 auto AddState(PlayOnceAnimation&& properties) -> AnimationStateId;
108 auto AddState(StopAnimation&& properties) -> AnimationStateId;
109 auto GetAnimation(AnimationStateId stateId) const -> asset::AssetId;
110 void SetAnimation(AnimationStateId stateId, asset::AssetId animationId);
111 auto GetDefaultTransitionDuration() const -> float { return m_defaultTransitionDuration; }
112 void SetDefaultTransitionDuration(float dur) { m_defaultTransitionDuration = dur; }
113
120 void LoopImmediate(asset::AssetId animId,
121 TransitionCondition&& exitWhen,
122 AnimationStateId exitTo = RootAnimationState,
123 float transitionDuration = UseDefaultTransitionDuration);
124
125 void PlayOnceImmediate(asset::AssetId animId,
126 AnimationStateId exitTo = RootAnimationState,
127 float transitionDuration = UseDefaultTransitionDuration);
128
129 void StopImmediate(TransitionCondition&& exitWhen,
130 AnimationStateId exitTo = RootAnimationState,
131 float transitionDuration = UseDefaultTransitionDuration);
132
134 void RefreshAnimation();
135 void NotifyCompleteState();
136 auto CheckForTransition() -> AnimationTransition;
139 private:
141 std::unique_ptr<AnimationState> m_immediateState;
142 AnimationStateId m_activeState = NullAnimationState;
143 AnimationStateId m_queuedState = RootAnimationState;
144 AnimationStateId m_nextStateId = RootAnimationState + 1;
145 float m_defaultTransitionDuration;
146 asset::AssetId m_prevAnimId = asset::NullAssetId;
147 bool m_cycleCompleted = false;
148
149 auto AddStateImpl(AnimationState&& in) -> AnimationStateId;
150 auto CalculateTransitionDuration(float requestedDuration) const -> float;
151 void QueueImmediateTransition();
152 auto TransitionQueuedState() -> AnimationTransition;
153 auto TransitionState(AnimationState& from, AnimationState& to, AnimationStateId toId) -> AnimationTransition;
154 auto ShouldExitState(AnimationState& current, bool cycleCompleted) -> bool;
155};
156} // namespace nc
State machine that controls animation transitions for a SkinnedMesh.
Definition: SkeletalAnimationController.h:88
void StopImmediate(TransitionCondition &&exitWhen, AnimationStateId exitTo=RootAnimationState, float transitionDuration=UseDefaultTransitionDuration)
void LoopImmediate(asset::AssetId animId, TransitionCondition &&exitWhen, AnimationStateId exitTo=RootAnimationState, float transitionDuration=UseDefaultTransitionDuration)
void PlayOnceImmediate(asset::AssetId animId, AnimationStateId exitTo=RootAnimationState, float transitionDuration=UseDefaultTransitionDuration)
SkeletalAnimationController(asset::AssetId animationId=asset::NullAssetId, float defaultTransitionDuration=0.3f)
Construct a SkeletalAnimationController.
Animation state that loops until the exit condition is met.
Definition: SkeletalAnimationController.h:29
Animation state that plays once before transitioning to the exitTo state.
Definition: SkeletalAnimationController.h:40
Animation state that stops the state machine..
Definition: SkeletalAnimationController.h:50