Flutter Impeller
animation_player.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 <memory>
8 #include <unordered_map>
9 
10 #include "flutter/fml/time/time_point.h"
11 #include "impeller/base/timing.h"
12 #include "impeller/scene/node.h"
13 
14 namespace impeller {
15 namespace scene {
16 
19 
20 AnimationPlayer::AnimationPlayer(AnimationPlayer&&) = default;
21 AnimationPlayer& AnimationPlayer::operator=(AnimationPlayer&&) = default;
22 
24  const std::shared_ptr<Animation>& animation,
25  Node* bind_target) {
26  if (!animation) {
27  VALIDATION_LOG << "Cannot add null animation.";
28  return nullptr;
29  }
30 
31  AnimationClip clip(animation, bind_target);
32 
33  // Record all of the unique default transforms that this AnimationClip
34  // will mutate.
35  for (const auto& binding : clip.bindings_) {
36  auto decomp = binding.node->GetLocalTransform().Decompose();
37  if (!decomp.has_value()) {
38  continue;
39  }
40  target_transforms_.insert(
41  {binding.node, AnimationTransforms{.bind_pose = decomp.value()}});
42  }
43 
44  auto result = clips_.insert({animation->GetName(), std::move(clip)});
45  return &result.first->second;
46 }
47 
48 AnimationClip* AnimationPlayer::GetClip(const std::string& name) const {
49  auto result = clips_.find(name);
50  if (result == clips_.end()) {
51  return nullptr;
52  }
53  return const_cast<AnimationClip*>(&result->second);
54 }
55 
57  if (!previous_time_.has_value()) {
58  previous_time_ = Clock::now();
59  }
60  auto new_time = Clock::now();
61  auto delta_time = new_time - previous_time_.value();
62  previous_time_ = new_time;
63 
64  // Reset the animated pose state.
65  for (auto& [node, transforms] : target_transforms_) {
66  transforms.animated_pose = transforms.bind_pose;
67  }
68 
69  // Compute a weight multiplier for normalizing the animation.
70  Scalar total_weight = 0;
71  for (auto& [_, clip] : clips_) {
72  total_weight += clip.GetWeight();
73  }
74  Scalar weight_multiplier = total_weight > 1 ? 1 / total_weight : 1;
75 
76  // Update and apply all clips to the animation pose state.
77  for (auto& [_, clip] : clips_) {
78  clip.Advance(delta_time);
79  clip.ApplyToBindings(target_transforms_, weight_multiplier);
80  }
81 
82  // Apply the animated pose to the bound joints.
83  for (auto& [node, transforms] : target_transforms_) {
84  node->SetLocalTransform(Matrix(transforms.animated_pose));
85  }
86 }
87 
88 } // namespace scene
89 } // namespace impeller
timing.h
impeller::scene::AnimationTransforms
Definition: animation_transforms.h:13
impeller::scene::AnimationPlayer::AddAnimation
AnimationClip * AddAnimation(const std::shared_ptr< Animation > &animation, Node *bind_target)
Definition: animation_player.cc:23
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::scene::AnimationPlayer::Update
void Update()
Advanced all clips and updates animated properties in the scene.
Definition: animation_player.cc:56
impeller::scene::AnimationTransforms::bind_pose
MatrixDecomposition bind_pose
Definition: animation_transforms.h:14
impeller::scene::AnimationPlayer::~AnimationPlayer
~AnimationPlayer()
animation_player.h
impeller::scene::AnimationClip
Definition: animation_clip.h:22
node.h
impeller::scene::AnimationPlayer::AnimationPlayer
AnimationPlayer()
impeller::scene::AnimationPlayer::GetClip
AnimationClip * GetClip(const std::string &name) const
Definition: animation_player.cc:48
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
impeller::scene::Node
Definition: node.h:30
impeller::scene::AnimationPlayer::operator=
AnimationPlayer & operator=(AnimationPlayer &&)
impeller
Definition: aiks_blur_unittests.cc:20
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37