Flutter Engine
The Flutter Engine
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
6
7#include <algorithm>
8#include <cmath>
9#include <memory>
10#include <valarray>
11
12#include "impeller/scene/node.h"
13
14namespace impeller {
15namespace scene {
16
17AnimationClip::AnimationClip(std::shared_ptr<Animation> animation,
18 Node* bind_target)
19 : animation_(std::move(animation)) {
20 BindToTarget(bind_target);
21}
22
24
27
29 return playing_;
30}
31
32void AnimationClip::SetPlaying(bool playing) {
33 playing_ = playing;
34}
35
37 SetPlaying(true);
38}
39
41 SetPlaying(false);
42}
43
45 SetPlaying(false);
46 Seek(SecondsF::zero());
47}
48
50 return loop_;
51}
52
53void AnimationClip::SetLoop(bool looping) {
54 loop_ = looping;
55}
56
58 return playback_time_scale_;
59}
60
62 playback_time_scale_ = playback_speed;
63}
64
66 return weight_;
67}
68
70 weight_ = std::max(0.0f, weight);
71}
72
74 return playback_time_;
75}
76
78 playback_time_ = std::clamp(time, SecondsF::zero(), animation_->GetEndTime());
79}
80
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
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
126void 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
static unsigned clamp(SkFixed fx, int max)
void SetPlaybackTimeScale(Scalar playback_speed)
Sets the animation playback speed. Negative values make the clip play in reverse.
void SetWeight(Scalar weight)
void ApplyToBindings(std::unordered_map< Node *, AnimationTransforms > &transform_decomps, Scalar weight_multiplier) const
Applies the animation to all binded properties in the scene.
AnimationClip(std::shared_ptr< Animation > animation, Node *bind_target)
SecondsF GetPlaybackTime() const
Get the current playback time of the animation.
void Advance(SecondsF delta_time)
Advance the animation by delta_time seconds. Negative delta_time values do nothing.
AnimationClip & operator=(AnimationClip &&)
void Seek(SecondsF time)
Move the animation to the specified time. The given time is clamped to the animation's playback range...
const std::string & GetName() const
Definition: node.cc:232
std::shared_ptr< Node > FindChildByName(const std::string &name, bool exclude_animation_players=false) const
Definition: node.cc:244
GAsyncResult * result
static float max(float r, float g, float b)
Definition: hsl.cpp:49
float Scalar
Definition: scalar.h:18
std::chrono::duration< float > SecondsF
Definition: timing.h:13
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition: SkVx.h:707
Definition: ref_ptr.h:256
static double time(int loops, Benchmark *bench, Target *target)
Definition: nanobench.cpp:394