From 721553a34e6be054d11120d92b8941384a9f222e Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Fri, 5 Jan 2018 13:20:11 -0500 Subject: [skotty] Cubic Bezier lerp Change-Id: I7eda67fb89c1ef54f4bc1470d10ee5ab797a8b6e Reviewed-on: https://skia-review.googlesource.com/91445 Reviewed-by: Mike Reed Reviewed-by: Florin Malita Commit-Queue: Florin Malita --- experimental/skotty/SkottyAnimator.cpp | 6 +++--- experimental/skotty/SkottyAnimator.h | 23 ++++++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) (limited to 'experimental') diff --git a/experimental/skotty/SkottyAnimator.cpp b/experimental/skotty/SkottyAnimator.cpp index d4c5c96c1a..7c4c16e780 100644 --- a/experimental/skotty/SkottyAnimator.cpp +++ b/experimental/skotty/SkottyAnimator.cpp @@ -43,12 +43,12 @@ void KeyframeInterval::lerp(float t, ShapeValue* v) const { } float AnimatorBase::ComputeLocalT(float t, float t0, float t1, - const SkPoint& c0, const SkPoint& c1) { + const SkCubicMap* cubicMap) { SkASSERT(t1 > t0); auto lt = (t - t0) / (t1 - t0); - if (c0 != SkPoint({0, 0}) || c1 != SkPoint({1, 1})) { - // TODO: lt = CubicBezier(lt, c0, c1); + if (cubicMap) { + lt = cubicMap->computeYFromX(lt); } return SkTPin(lt, 0, 1); diff --git a/experimental/skotty/SkottyAnimator.h b/experimental/skotty/SkottyAnimator.h index f8d1c3abb6..1b519c9aa6 100644 --- a/experimental/skotty/SkottyAnimator.h +++ b/experimental/skotty/SkottyAnimator.h @@ -8,6 +8,8 @@ #ifndef SkottyAnimator_DEFINED #define SkottyAnimator_DEFINED +#include "SkCubicMap.h" +#include "SkMakeUnique.h" #include "SkottyPriv.h" #include "SkottyProperties.h" #include "SkTArray.h" @@ -29,7 +31,7 @@ protected: // Compute a cubic-Bezier-interpolated t relative to [t0..t1]. static float ComputeLocalT(float t, float t0, float t1, - const SkPoint& c0, const SkPoint& c1); + const SkCubicMap*); }; // Describes a keyframe interpolation interval (v0@t0) -> (v1@t1). @@ -44,9 +46,8 @@ struct KeyframeInterval { float fT0 = 0, fT1 = 0; - // Cubic Bezier interpolation control pts. - SkPoint fC0, - fC1; + // Initialized for non-linear lerp. + std::unique_ptr fCubicMap; // Parse the current interval AND back-fill prev interval t1. bool parse(const Json::Value& k, KeyframeInterval* prev) { @@ -75,8 +76,16 @@ struct KeyframeInterval { } // default is linear lerp - fC0 = ParsePoint(k["i"], SkPoint::Make(0, 0)); - fC1 = ParsePoint(k["o"], SkPoint::Make(1, 1)); + static constexpr SkPoint kDefaultC0 = { 0, 0 }, + kDefaultC1 = { 1, 1 }; + const auto c0 = ParsePoint(k["i"], kDefaultC0), + c1 = ParsePoint(k["o"], kDefaultC1); + + if (c0 != kDefaultC0 || c1 != kDefaultC1) { + fCubicMap = skstd::make_unique(); + // TODO: why do we have to plug these inverted? + fCubicMap->setPts(c1, c0); + } return true; } @@ -95,7 +104,7 @@ public: const auto& frame = this->findInterval(t); ValT val; - frame.lerp(ComputeLocalT(t, frame.fT0, frame.fT1, frame.fC0, frame.fC1), &val); + frame.lerp(ComputeLocalT(t, frame.fT0, frame.fT1, frame.fCubicMap.get()), &val); fFunc(fTarget, val.template as()); } -- cgit v1.2.3