Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion impeller/scene/animation/animation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const std::vector<Animation::Channel>& Animation::GetChannels() const {
return channels_;
}

Scalar Animation::GetEndTime() const {
std::chrono::duration<Scalar> Animation::GetEndTime() const {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd put this in //flutter/impeller/base/timing.h and typedef it to SecondsF along with other related stuff from chrono. Something like this perhaps. Your call though. As it reads, duration<Scalar> is a bit unclear.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM, done.

return end_time_;
}

Expand Down
4 changes: 2 additions & 2 deletions impeller/scene/animation/animation.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ class Animation final {

const std::vector<Channel>& GetChannels() const;

Scalar GetEndTime() const;
std::chrono::duration<Scalar> GetEndTime() const;

private:
Animation();

std::string name_;
std::vector<Channel> channels_;
Scalar end_time_ = 0;
std::chrono::duration<Scalar> end_time_;

FML_DISALLOW_COPY_AND_ASSIGN(Animation);
};
Expand Down
36 changes: 22 additions & 14 deletions impeller/scene/animation/animation_clip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "impeller/scene/animation/animation_clip.h"

#include <algorithm>
#include <chrono>
#include <cmath>
#include <memory>
#include <valarray>
Expand Down Expand Up @@ -43,7 +44,7 @@ void AnimationClip::Pause() {

void AnimationClip::Stop() {
SetPlaying(false);
Seek(0);
Seek(std::chrono::duration<Scalar>::zero());
}

bool AnimationClip::GetLoop() const {
Expand All @@ -70,39 +71,46 @@ void AnimationClip::SetWeight(Scalar weight) {
weight_ = weight;
}

Scalar AnimationClip::GetPlaybackTime() const {
std::chrono::duration<Scalar> AnimationClip::GetPlaybackTime() const {
return playback_time_;
}

void AnimationClip::Seek(Scalar time) {
playback_time_ = std::clamp(time, 0.0f, animation_->GetEndTime());
void AnimationClip::Seek(std::chrono::duration<Scalar> time) {
playback_time_ = std::clamp(time, std::chrono::duration<Scalar>::zero(),
animation_->GetEndTime());
}

void AnimationClip::Advance(Scalar delta_time) {
if (!playing_ || delta_time <= 0) {
void AnimationClip::Advance(std::chrono::duration<Scalar> delta_time) {
if (!playing_ || delta_time <= std::chrono::duration<Scalar>::zero()) {
return;
}
delta_time *= playback_time_scale_;
playback_time_ += delta_time;

/// Handle looping behavior.

Scalar end_time = animation_->GetEndTime();
if (end_time == 0) {
playback_time_ = 0;
auto end_time = animation_->GetEndTime();
if (end_time == std::chrono::duration<Scalar>::zero()) {
playback_time_ = std::chrono::duration<Scalar>::zero();
return;
}
if (!loop_ && (playback_time_ < 0 || playback_time_ > end_time)) {
if (!loop_ && (playback_time_ < std::chrono::duration<Scalar>::zero() ||
playback_time_ > end_time)) {
// If looping is disabled, clamp to the end (or beginning, if playing in
// reverse) and pause.
Pause();
playback_time_ = std::clamp(playback_time_, 0.0f, end_time);
playback_time_ = std::clamp(
playback_time_, std::chrono::duration<Scalar>::zero(), end_time);
} else if (/* loop && */ playback_time_ > end_time) {
// If looping is enabled and we ran off the end, loop to the beginning.
playback_time_ = std::fmod(std::abs(playback_time_), end_time);
} else if (/* loop && */ playback_time_ < 0) {
playback_time_ = std::chrono::duration<Scalar>(
std::fmod(std::abs(playback_time_.count()), end_time.count()));
} else if (/* loop && */ playback_time_ <
std::chrono::duration<Scalar>::zero()) {
// If looping is enabled and we ran off the beginning, loop to the end.
playback_time_ = end_time - std::fmod(std::abs(playback_time_), end_time);
playback_time_ =
end_time - std::chrono::duration<Scalar>(std::fmod(
std::abs(playback_time_.count()), end_time.count()));
}
}

Expand Down
8 changes: 4 additions & 4 deletions impeller/scene/animation/animation_clip.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ class AnimationClip final {
void SetWeight(Scalar weight);

/// @brief Get the current playback time of the animation.
Scalar GetPlaybackTime() const;
std::chrono::duration<Scalar> GetPlaybackTime() const;

/// @brief Move the animation to the specified time. The given `time` is
/// clamped to the animation's playback range.
void Seek(Scalar time);
void Seek(std::chrono::duration<Scalar> time);

/// @brief Advance the animation by `delta_time` seconds. Negative
/// `delta_time` values do nothing.
void Advance(Scalar delta_time);
void Advance(std::chrono::duration<Scalar> delta_time);

/// @brief Applies the animation to all binded properties in the scene.
void ApplyToBindings() const;
Expand All @@ -73,7 +73,7 @@ class AnimationClip final {
std::shared_ptr<Animation> animation_;
std::vector<ChannelBinding> bindings_;

Scalar playback_time_ = 0;
std::chrono::duration<Scalar> playback_time_;
Scalar playback_time_scale_ = 1; // Seconds multiplier, can be negative.
Scalar weight_ = 1;
bool playing_ = false;
Expand Down
7 changes: 4 additions & 3 deletions impeller/scene/animation/animation_player.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "impeller/scene/animation/animation_player.h"

#include <chrono>
#include <memory>

#include "flutter/fml/time/time_point.h"
Expand Down Expand Up @@ -36,10 +37,10 @@ AnimationClip& AnimationPlayer::AddAnimation(

void AnimationPlayer::Update() {
if (!previous_time_.has_value()) {
previous_time_ = fml::TimePoint::Now().ToEpochDelta();
previous_time_ = std::chrono::high_resolution_clock::now();
}
auto new_time = fml::TimePoint::Now().ToEpochDelta();
Scalar delta_time = (new_time - previous_time_.value()).ToSecondsF();
auto new_time = std::chrono::high_resolution_clock::now();
auto delta_time = new_time - previous_time_.value();
previous_time_ = new_time;

Reset();
Expand Down
4 changes: 3 additions & 1 deletion impeller/scene/animation/animation_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#pragma once

#include <chrono>
#include <memory>
#include <optional>
#include <unordered_set>
Expand Down Expand Up @@ -42,7 +43,8 @@ class AnimationPlayer final {

std::vector<AnimationClip> clips_;

std::optional<fml::TimeDelta> previous_time_;
std::optional<std::chrono::time_point<std::chrono::high_resolution_clock>>
previous_time_;

FML_DISALLOW_COPY_AND_ASSIGN(AnimationPlayer);
};
Expand Down
27 changes: 16 additions & 11 deletions impeller/scene/animation/property_resolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,35 +51,36 @@ PropertyResolver::~PropertyResolver() = default;

TimelineResolver::~TimelineResolver() = default;

Scalar TimelineResolver::GetEndTime() {
std::chrono::duration<Scalar> TimelineResolver::GetEndTime() {
if (times_.empty()) {
return 0;
return std::chrono::duration<Scalar>::zero();
}
return times_.back();
return std::chrono::duration<Scalar>(times_.back());
}

TimelineResolver::TimelineKey TimelineResolver::GetTimelineKey(Scalar time) {
if (times_.size() <= 1 || time <= times_.front()) {
TimelineResolver::TimelineKey TimelineResolver::GetTimelineKey(
std::chrono::duration<Scalar> time) {
if (times_.size() <= 1 || time.count() <= times_.front()) {
return {.index = 0, .lerp = 1};
}
if (time >= times_.back()) {
if (time.count() >= times_.back()) {
return {.index = times_.size() - 1, .lerp = 1};
}
auto it = std::lower_bound(times_.begin(), times_.end(), time);
auto it = std::lower_bound(times_.begin(), times_.end(), time.count());
size_t index = std::distance(times_.begin(), it);

Scalar previous_time = *(it - 1);
Scalar next_time = *it;
return {.index = index,
.lerp = (time - previous_time) / (next_time - previous_time)};
.lerp = (time.count() - previous_time) / (next_time - previous_time)};
}

TranslationTimelineResolver::TranslationTimelineResolver() = default;

TranslationTimelineResolver::~TranslationTimelineResolver() = default;

void TranslationTimelineResolver::Apply(Node& target,
Scalar time,
std::chrono::duration<Scalar> time,
Scalar weight) {
if (values_.empty()) {
return;
Expand All @@ -97,7 +98,9 @@ RotationTimelineResolver::RotationTimelineResolver() = default;

RotationTimelineResolver::~RotationTimelineResolver() = default;

void RotationTimelineResolver::Apply(Node& target, Scalar time, Scalar weight) {
void RotationTimelineResolver::Apply(Node& target,
std::chrono::duration<Scalar> time,
Scalar weight) {
if (values_.empty()) {
return;
}
Expand All @@ -114,7 +117,9 @@ ScaleTimelineResolver::ScaleTimelineResolver() = default;

ScaleTimelineResolver::~ScaleTimelineResolver() = default;

void ScaleTimelineResolver::Apply(Node& target, Scalar time, Scalar weight) {
void ScaleTimelineResolver::Apply(Node& target,
std::chrono::duration<Scalar> time,
Scalar weight) {
if (values_.empty()) {
return;
}
Expand Down
23 changes: 16 additions & 7 deletions impeller/scene/animation/property_resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#pragma once

#include <chrono>
#include <memory>
#include <string>
#include <vector>
Expand Down Expand Up @@ -38,22 +39,24 @@ class PropertyResolver {

virtual ~PropertyResolver();

virtual Scalar GetEndTime() = 0;
virtual std::chrono::duration<Scalar> GetEndTime() = 0;

/// @brief Resolve and apply the property value to a target node. This
/// operation is additive; a given node property may be amended by
/// many different PropertyResolvers prior to rendering. For example,
/// an AnimationPlayer may blend multiple Animations together by
/// applying several AnimationClips.
virtual void Apply(Node& target, Scalar time, Scalar weight) = 0;
virtual void Apply(Node& target,
std::chrono::duration<Scalar> time,
Scalar weight) = 0;
};

class TimelineResolver : public PropertyResolver {
public:
virtual ~TimelineResolver();

// |Resolver|
Scalar GetEndTime();
std::chrono::duration<Scalar> GetEndTime();

protected:
struct TimelineKey {
Expand All @@ -63,7 +66,7 @@ class TimelineResolver : public PropertyResolver {
/// and `timeline_index`. The range of this value should always be `0>N>=1`.
Scalar lerp = 1;
};
TimelineKey GetTimelineKey(Scalar time);
TimelineKey GetTimelineKey(std::chrono::duration<Scalar> time);

std::vector<Scalar> times_;
};
Expand All @@ -73,7 +76,9 @@ class TranslationTimelineResolver final : public TimelineResolver {
~TranslationTimelineResolver();

// |Resolver|
void Apply(Node& target, Scalar time, Scalar weight) override;
void Apply(Node& target,
std::chrono::duration<Scalar> time,
Scalar weight) override;

private:
TranslationTimelineResolver();
Expand All @@ -90,7 +95,9 @@ class RotationTimelineResolver final : public TimelineResolver {
~RotationTimelineResolver();

// |Resolver|
void Apply(Node& target, Scalar time, Scalar weight) override;
void Apply(Node& target,
std::chrono::duration<Scalar> time,
Scalar weight) override;

private:
RotationTimelineResolver();
Expand All @@ -107,7 +114,9 @@ class ScaleTimelineResolver final : public TimelineResolver {
~ScaleTimelineResolver();

// |Resolver|
void Apply(Node& target, Scalar time, Scalar weight) override;
void Apply(Node& target,
std::chrono::duration<Scalar> time,
Scalar weight) override;

private:
ScaleTimelineResolver();
Expand Down