| Flutter Impeller |

animation_clip.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "impeller/scene/animation/animation_clip.h"
6
7 #include <algorithm>
8 #include <cmath>
9 #include <memory>
10 #include <valarray>
11
12 #include "impeller/scene/node.h"
13
14 namespace impeller {
15 namespace scene {
16
17 AnimationClip::AnimationClip(std::shared_ptr<Animation> animation,
18 Node* bind_target)
19 : animation_(std::move(animation)) {
20 BindToTarget(bind_target);
21 }
22
23 AnimationClip::~AnimationClip() = default;
24
25 AnimationClip::AnimationClip(AnimationClip&&) = default;
26 AnimationClip& AnimationClip::operator=(AnimationClip&&) = default;
27
28 bool AnimationClip::IsPlaying() const {
29 return playing_;
30 }
31
32 void AnimationClip::SetPlaying(bool playing) {
33 playing_ = playing;
34 }
35
36 void AnimationClip::Play() {
37 SetPlaying(true);
38 }
39
40 void AnimationClip::Pause() {
41 SetPlaying(false);
42 }
43
44 void AnimationClip::Stop() {
45 SetPlaying(false);
46 Seek(SecondsF::zero());
47 }
48
49 bool AnimationClip::GetLoop() const {
50 return loop_;
51 }
52
53 void AnimationClip::SetLoop(bool looping) {
54 loop_ = looping;
55 }
56
57 Scalar AnimationClip::GetPlaybackTimeScale() const {
58 return playback_time_scale_;
59 }
60
61 void AnimationClip::SetPlaybackTimeScale(Scalar playback_speed) {
62 playback_time_scale_ = playback_speed;
63 }
64
65 Scalar AnimationClip::GetWeight() const {
66 return weight_;
67 }
68
69 void AnimationClip::SetWeight(Scalar weight) {
70 weight_ = std::max(0.0f, weight);
71 }
72
73 SecondsF AnimationClip::GetPlaybackTime() const {
74 return playback_time_;
75 }
76
77 void AnimationClip::Seek(SecondsF time) {
78 playback_time_ = std::clamp(time, SecondsF::zero(), animation_->GetEndTime());
79 }
80
81 void AnimationClip::Advance(SecondsF delta_time) {
82 if (!playing_ || delta_time <= SecondsF::zero()) {
83 return;
84 }
85 delta_time *= playback_time_scale_;
86 playback_time_ += delta_time;
87
88 /// Handle looping behavior.
89
90 auto end_time = animation_->GetEndTime();
91 if (end_time == SecondsF::zero()) {
92 playback_time_ = SecondsF::zero();
93 return;
94 }
95 if (!loop_ &&
96 (playback_time_ < SecondsF::zero() || playback_time_ > end_time)) {
97 // If looping is disabled, clamp to the end (or beginning, if playing in
98 // reverse) and pause.
99 Pause();
100 playback_time_ = std::clamp(playback_time_, SecondsF::zero(), end_time);
101 } else if (/* loop && */ playback_time_ > end_time) {
102 // If looping is enabled and we ran off the end, loop to the beginning.
103 playback_time_ =
104 SecondsF(std::fmod(std::abs(playback_time_.count()), end_time.count()));
105 } else if (/* loop && */ playback_time_ < SecondsF::zero()) {
106 // If looping is enabled and we ran off the beginning, loop to the end.
107 playback_time_ =
108 end_time -
109 SecondsF(std::fmod(std::abs(playback_time_.count()), end_time.count()));
110 }
111 }
112
113 void AnimationClip::ApplyToBindings(
114 std::unordered_map<Node*, AnimationTransforms>& transform_decomps,
115 Scalar weight_multiplier) const {
116 for (auto& binding : bindings_) {
117 auto transforms = transform_decomps.find(binding.node);
118 if (transforms == transform_decomps.end()) {
119 continue;
120 }
121 binding.channel.resolver->Apply(transforms->second, playback_time_,
122 weight_ * weight_multiplier);
123 }
124 }
125
126 void AnimationClip::BindToTarget(Node* node) {
127 const auto& channels = animation_->GetChannels();
128 bindings_.clear();
129 bindings_.reserve(channels.size());
130
131 for (const auto& channel : channels) {
132 Node* channel_target;
133 if (channel.bind_target.node_name == node->GetName()) {
134 channel_target = node;
135 } else if (auto result =
136 node->FindChildByName(channel.bind_target.node_name, true)) {
137 channel_target = result.get();
138 } else {
139 continue;
140 }
141 bindings_.push_back(
142 ChannelBinding{.channel = channel, .node = channel_target});
143 }
144 }
145
146 } // namespace scene
147 } // namespace impeller
impeller::Scalar
float Scalar
Definition: scalar.h:15
impeller::scene::Node::FindChildByName
std::shared_ptr< Node > FindChildByName(const std::string &name, bool exclude_animation_players=false) const
Definition: node.cc:253
impeller::scene::AnimationClip::SetPlaybackTimeScale
void SetPlaybackTimeScale(Scalar playback_speed)
Sets the animation playback speed. Negative values make the clip play in reverse.
Definition: animation_clip.cc:61
impeller::scene::AnimationClip::GetLoop
bool GetLoop() const
Definition: animation_clip.cc:49
impeller::scene::AnimationClip::SetLoop
void SetLoop(bool looping)
Definition: animation_clip.cc:53
impeller::scene::AnimationClip::GetWeight
Scalar GetWeight() const
Definition: animation_clip.cc:65
impeller::scene::AnimationClip::Play
void Play()
Definition: animation_clip.cc:36
impeller::scene::AnimationClip::ApplyToBindings
void ApplyToBindings(std::unordered_map< Node *, AnimationTransforms > &transform_decomps, Scalar weight_multiplier) const
Applies the animation to all binded properties in the scene.
Definition: animation_clip.cc:113
impeller::scene::AnimationClip
Definition: animation_clip.h:21
impeller::scene::Node::GetName
const std::string & GetName() const
Definition: node.cc:241
impeller::SecondsF
std::chrono::duration< float > SecondsF
Definition: timing.h:12
impeller::scene::AnimationClip::GetPlaybackTime
SecondsF GetPlaybackTime() const
Get the current playback time of the animation.
Definition: animation_clip.cc:73
impeller::scene::AnimationClip::IsPlaying
bool IsPlaying() const
Definition: animation_clip.cc:28
node.h
animation_clip.h
impeller::scene::AnimationClip::Advance
void Advance(SecondsF delta_time)
Advance the animation by delta_time seconds. Negative delta_time values do nothing.
Definition: animation_clip.cc:81
impeller::scene::AnimationClip::GetPlaybackTimeScale
Scalar GetPlaybackTimeScale() const
Definition: animation_clip.cc:57
impeller::scene::AnimationClip::SetWeight
void SetWeight(Scalar weight)
Definition: animation_clip.cc:69
impeller::scene::AnimationClip::Pause
void Pause()
Definition: animation_clip.cc:40
std
Definition: comparable.h:98
impeller::scene::Node
Definition: node.h:29
impeller::scene::AnimationClip::Seek
void Seek(SecondsF time)
Move the animation to the specified time. The given time is clamped to the animation's playback range...
Definition: animation_clip.cc:77
impeller::scene::AnimationClip::~AnimationClip
~AnimationClip()
impeller::scene::AnimationClip::SetPlaying
void SetPlaying(bool playing)
Definition: animation_clip.cc:32
impeller::scene::AnimationClip::AnimationClip
AnimationClip(std::shared_ptr< Animation > animation, Node *bind_target)
Definition: animation_clip.cc:17
impeller
Definition: aiks_context.cc:10
impeller::scene::AnimationClip::operator=
AnimationClip & operator=(AnimationClip &&)
impeller::scene::AnimationClip::Stop
void Stop()
Definition: animation_clip.cc:44