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 
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 
24 
27 
29  return playing_;
30 }
31 
32 void 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 
49 bool AnimationClip::GetLoop() const {
50  return loop_;
51 }
52 
53 void 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 
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 
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:18
impeller::scene::Node::FindChildByName
std::shared_ptr< Node > FindChildByName(const std::string &name, bool exclude_animation_players=false) const
Definition: node.cc:244
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:22
impeller::scene::Node::GetName
const std::string & GetName() const
Definition: node.cc:232
impeller::SecondsF
std::chrono::duration< float > SecondsF
Definition: timing.h:13
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:95
impeller::scene::Node
Definition: node.h:30
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_blur_unittests.cc:20
impeller::scene::AnimationClip::operator=
AnimationClip & operator=(AnimationClip &&)
impeller::scene::AnimationClip::Stop
void Stop()
Definition: animation_clip.cc:44