aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2018-01-02 15:33:18 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-02 22:24:31 +0000
commit9e73f885c7937c8ce8ba51b240cbfa4c13dbe4cf (patch)
treed7c694f9473ea7a1c2747b436a81f4218d98cc28 /experimental
parentf7ae6e4dbbe2ae4536dbac13fa26b168268d7730 (diff)
[skotty] Native SkPath interpolation
SkPath supports interpolation, no reason to handle that explicitly in Skotty. Change skotty::ShapeValue to convert to SkPaths upfront, when parsing, and then rely in native interpolation. TBR= Change-Id: I32d424ea359e0736909d4e51602ffeb14403feed Reviewed-on: https://skia-review.googlesource.com/90362 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'experimental')
-rw-r--r--experimental/skotty/SkottyAnimator.cpp19
-rw-r--r--experimental/skotty/SkottyProperties.cpp51
-rw-r--r--experimental/skotty/SkottyProperties.h12
3 files changed, 26 insertions, 56 deletions
diff --git a/experimental/skotty/SkottyAnimator.cpp b/experimental/skotty/SkottyAnimator.cpp
index f08e7088da..51c3d33565 100644
--- a/experimental/skotty/SkottyAnimator.cpp
+++ b/experimental/skotty/SkottyAnimator.cpp
@@ -16,12 +16,6 @@ SkScalar lerp_scalar(SkScalar v0, SkScalar v1, float t) {
return v0 * (1 - t) + v1 * t;
}
-SkPoint lerp_point(const SkPoint& v0, const SkPoint& v1, float t) {
- SkASSERT(t >= 0 && t <= 1);
- return SkPoint::Make(lerp_scalar(v0.x(), v1.x(), t),
- lerp_scalar(v0.y(), v1.y(), t));
-}
-
} // namespace
template <>
@@ -45,18 +39,7 @@ void KeyframeInterval<ShapeValue>::lerp(float t, ShapeValue* v) const {
SkASSERT(fV0.cardinality() == fV1.cardinality());
SkASSERT(v->cardinality() == 0);
- v->fVertices.reserve(fV0.cardinality());
- for (int i = 0; i < fV0.fVertices.count(); ++i) {
- v->fVertices.push_back(
- BezierVertex({
- lerp_point(fV0.fVertices[i].fInPoint , fV1.fVertices[i].fInPoint , t),
- lerp_point(fV0.fVertices[i].fOutPoint, fV1.fVertices[i].fOutPoint, t),
- lerp_point(fV0.fVertices[i].fVertex , fV1.fVertices[i].fVertex , t)
- }));
- }
-
- // hmm, any meaningful interpolation to consider here?
- v->fClose = fV0.fClose;
+ SkAssertResult(fV0.fPath.interpolate(fV1.fPath, t, &v->fPath));
}
} // namespace skotty
diff --git a/experimental/skotty/SkottyProperties.cpp b/experimental/skotty/SkottyProperties.cpp
index 7ee4008975..5d94d73ef6 100644
--- a/experimental/skotty/SkottyProperties.cpp
+++ b/experimental/skotty/SkottyProperties.cpp
@@ -70,9 +70,9 @@ bool VectorValue::Parse(const Json::Value& v, VectorValue* vec) {
}
bool ShapeValue::Parse(const Json::Value& v, ShapeValue* shape) {
- PointArray inPts,
- outPts,
- verts;
+ PointArray inPts, // Cubic Bezier "in" control points, relative to vertices.
+ outPts, // Cubic Bezier "out" control points, relative to vertices.
+ verts; // Cubic Bezier vertices.
// Some files appear to wrap keyframes in arrays for no reason.
if (v.isArray() && v.size() == 1) {
@@ -89,12 +89,26 @@ bool ShapeValue::Parse(const Json::Value& v, ShapeValue* shape) {
return false;
}
- SkASSERT(shape->fVertices.empty());
- for (int i = 0; i < inPts.count(); ++i) {
- shape->fVertices.emplace_back(BezierVertex({inPts[i], outPts[i], verts[i]}));
+ SkASSERT(shape->fPath.isEmpty());
+
+ if (!verts.empty()) {
+ shape->fPath.moveTo(verts.front());
+ }
+
+ const auto& addCubic = [&](int from, int to) {
+ shape->fPath.cubicTo(verts[from] + outPts[from],
+ verts[to] + inPts[to],
+ verts[to]);
+ };
+
+ for (int i = 1; i < verts.count(); ++i) {
+ addCubic(i - 1, i);
}
- shape->fClose = ParseBool(v["c"], false);
+ if (!verts.empty() && ParseBool(v["c"], false)) {
+ addCubic(verts.count() - 1, 0);
+ shape->fPath.close();
+ }
return true;
}
@@ -141,28 +155,7 @@ std::vector<SkScalar> VectorValue::as<std::vector<SkScalar>>() const {
template <>
SkPath ShapeValue::as<SkPath>() const {
- SkPath path;
-
- if (!fVertices.empty()) {
- path.moveTo(fVertices.front().fVertex);
- }
-
- const auto& addCubic = [](const BezierVertex& from, const BezierVertex& to, SkPath* path) {
- path->cubicTo(from.fVertex + from.fOutPoint,
- to.fVertex + to.fInPoint,
- to.fVertex);
- };
-
- for (int i = 1; i < fVertices.count(); ++i) {
- addCubic(fVertices[i - 1], fVertices[i], &path);
- }
-
- if (fClose) {
- addCubic(fVertices.back(), fVertices.front(), &path);
- path.close();
- }
-
- return path;
+ return fPath;
}
CompositeRRect::CompositeRRect(sk_sp<sksg::RRect> wrapped_node)
diff --git a/experimental/skotty/SkottyProperties.h b/experimental/skotty/SkottyProperties.h
index e1504747b4..990862f195 100644
--- a/experimental/skotty/SkottyProperties.h
+++ b/experimental/skotty/SkottyProperties.h
@@ -8,6 +8,7 @@
#ifndef SkottyProperties_DEFINED
#define SkottyProperties_DEFINED
+#include "SkPath.h"
#include "SkPoint.h"
#include "SkSize.h"
#include "SkottyPriv.h"
@@ -27,12 +28,6 @@ class Transform;
namespace skotty {
-struct BezierVertex {
- SkPoint fInPoint, // "in" control point, relative to the vertex
- fOutPoint, // "out" control point, relative to the vertex
- fVertex;
-};
-
struct ScalarValue {
float fVal;
@@ -73,8 +68,7 @@ struct VectorValue {
};
struct ShapeValue {
- SkTArray<BezierVertex, true> fVertices;
- bool fClose = false;
+ SkPath fPath;
ShapeValue() = default;
ShapeValue(const ShapeValue&) = delete;
@@ -83,7 +77,7 @@ struct ShapeValue {
static bool Parse(const Json::Value&, ShapeValue*);
- size_t cardinality() const { return SkTo<size_t>(fVertices.count()); }
+ size_t cardinality() const { return SkTo<size_t>(fPath.countVerbs()); }
template <typename T>
T as() const;