Flutter Engine
The Flutter Engine
Transform.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2020 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
16#include "src/utils/SkJSON.h"
17
18#include <cmath>
19
20namespace skottie {
21namespace internal {
22
24 const skjson::ObjectValue* janchor_point,
25 const skjson::ObjectValue* jposition,
26 const skjson::ObjectValue* jscale,
27 const skjson::ObjectValue* jrotation,
28 const skjson::ObjectValue* jskew,
29 const skjson::ObjectValue* jskew_axis,
30 bool auto_orient)
32
33 this->bind(abuilder, janchor_point, fAnchorPoint);
34 this->bind(abuilder, jscale , fScale);
35 this->bind(abuilder, jrotation , fRotation);
36 this->bind(abuilder, jskew , fSkew);
37 this->bind(abuilder, jskew_axis , fSkewAxis);
38
39 this->bindAutoOrientable(abuilder, jposition, &fPosition, auto_orient ? &fOrientation
40 : nullptr);
41}
42
44
45void TransformAdapter2D::onSync() {
46 this->node()->setMatrix(this->totalMatrix());
47}
48
50 auto skew_matrix = [](float sk, float sa) {
51 if (!sk) return SkMatrix::I();
52
53 // AE control limit.
54 static constexpr float kMaxSkewAngle = 85;
55 sk = -SkDegreesToRadians(SkTPin(sk, -kMaxSkewAngle, kMaxSkewAngle));
56 sa = SkDegreesToRadians(sa);
57
58 // Similar to CSS/SVG SkewX [1] with an explicit rotation.
59 // [1] https://www.w3.org/TR/css-transforms-1/#SkewXDefined
60 return SkMatrix::RotateRad(sa)
61 * SkMatrix::Skew(std::tan(sk), 0)
63 };
64
65 return SkMatrix::Translate(fPosition.x, fPosition.y)
66 * SkMatrix::RotateDeg(fRotation + fOrientation)
67 * skew_matrix (fSkew, fSkewAxis)
68 * SkMatrix::Scale (fScale.x / 100, fScale.y / 100) // 100% based
69 * SkMatrix::Translate(-fAnchorPoint.x, -fAnchorPoint.y);
70}
71
73 return { fAnchorPoint.x, fAnchorPoint.y };
74}
75
77 fAnchorPoint = { ap.x(), ap.y() };
78 this->onSync();
79}
80
82 return { fPosition.x, fPosition.y };
83}
84
86 fPosition = { p.x(), p.y() };
87 this->onSync();
88}
89
91 return { fScale.x, fScale.y };
92}
93
95 fScale = { s.x(), s.y() };
96 this->onSync();
97}
98
100 fRotation = r;
101 this->onSync();
102}
103
105 fSkew = sk;
106 this->onSync();
107}
108
110 fSkewAxis = sa;
111 this->onSync();
112}
113
116 bool auto_orient) const {
117 const auto* jrotation = &jtransform["r"];
118 if (jrotation->is<skjson::NullValue>()) {
119 // Some 2D rotations are disguised as 3D...
120 jrotation = &jtransform["rz"];
121 }
122
123 auto adapter = TransformAdapter2D::Make(*this,
124 jtransform["a"],
125 jtransform["p"],
126 jtransform["s"],
127 *jrotation,
128 jtransform["sk"],
129 jtransform["sa"],
130 auto_orient);
131 SkASSERT(adapter);
132
133 const auto dispatched = this->dispatchTransformProperty(adapter);
134
135 if (adapter->isStatic()) {
136 if (!dispatched && adapter->totalMatrix().isIdentity()) {
137 // The transform has no observable effects - we can discard.
138 return parent;
139 }
140 adapter->seek(0);
141 } else {
142 fCurrentAnimatorScope->push_back(adapter);
143 }
144
145 return sksg::Transform::MakeConcat(std::move(parent), adapter->node());
146}
147
149 const AnimationBuilder& abuilder)
151
152 this->bind(abuilder, jtransform["a"], fAnchorPoint);
153 this->bind(abuilder, jtransform["p"], fPosition);
154 this->bind(abuilder, jtransform["s"], fScale);
155
156 // Axis-wise rotation and orientation are mapped to the same rotation property (3D rotation).
157 // The difference is in how they get interpolated (scalar/decomposed vs. vector).
158 this->bind(abuilder, jtransform["rx"], fRx);
159 this->bind(abuilder, jtransform["ry"], fRy);
160 this->bind(abuilder, jtransform["rz"], fRz);
161 this->bind(abuilder, jtransform["or"], fOrientation);
162}
163
165
166void TransformAdapter3D::onSync() {
167 this->node()->setMatrix(this->totalMatrix());
168}
169
171 return fAnchorPoint;
172}
173
175 return fPosition;
176}
177
179 // orientation and axis-wise rotation map onto the same property.
180 return static_cast<SkV3>(fOrientation) + SkV3{ fRx, fRy, fRz };
181}
182
184 const auto anchor_point = this->anchor_point(),
185 position = this->position(),
186 scale = static_cast<SkV3>(fScale),
187 rotation = this->rotation();
188
193 * SkM44::Scale(scale.x / 100, scale.y / 100, scale.z / 100)
195}
196
199 bool /*TODO: auto_orient*/) const {
200 auto adapter = TransformAdapter3D::Make(jtransform, *this);
201 SkASSERT(adapter);
202
203 if (adapter->isStatic()) {
204 // TODO: SkM44::isIdentity?
205 if (adapter->totalMatrix() == SkM44()) {
206 // The transform has no observable effects - we can discard.
207 return parent;
208 }
209 adapter->seek(0);
210 } else {
211 fCurrentAnimatorScope->push_back(adapter);
212 }
213
214 return sksg::Transform::MakeConcat(std::move(parent), adapter->node());
215}
216
217} // namespace internal
218} // namespace skottie
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SkDegreesToRadians(degrees)
Definition: SkScalar.h:77
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition: SkTPin.h:19
Definition: SkM44.h:150
static SkM44 Rotate(SkV3 axis, SkScalar radians)
Definition: SkM44.h:239
static SkM44 Translate(SkScalar x, SkScalar y, SkScalar z=0)
Definition: SkM44.h:225
static SkM44 Scale(SkScalar x, SkScalar y, SkScalar z=1)
Definition: SkM44.h:232
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition: SkMatrix.h:75
static SkMatrix RotateDeg(SkScalar deg)
Definition: SkMatrix.h:104
static SkMatrix RotateRad(SkScalar rad)
Definition: SkMatrix.h:114
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.h:91
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
static SkMatrix Skew(SkScalar kx, SkScalar ky)
Definition: SkMatrix.h:124
bool bindAutoOrientable(const AnimationBuilder &abuilder, const skjson::ObjectValue *jobject, SkV2 *v, float *orientation)
bool bind(const AnimationBuilder &, const skjson::ObjectValue *, T *)
void sk_sp< sksg::Transform > attachMatrix2D(const skjson::ObjectValue &, sk_sp< sksg::Transform >, bool auto_orient=false) const
Definition: Transform.cpp:114
bool dispatchTransformProperty(const sk_sp< TransformAdapter2D > &) const
Definition: Skottie.cpp:278
sk_sp< sksg::Transform > attachMatrix3D(const skjson::ObjectValue &, sk_sp< sksg::Transform >, bool auto_orient=false) const
Definition: Transform.cpp:197
void setAnchorPoint(const SkPoint &)
Definition: Transform.cpp:76
void setPosition(const SkPoint &)
Definition: Transform.cpp:85
void setScale(const SkVector &)
Definition: Transform.cpp:94
TransformAdapter2D(const AnimationBuilder &, const skjson::ObjectValue *janchor_point, const skjson::ObjectValue *jposition, const skjson::ObjectValue *jscale, const skjson::ObjectValue *jrotation, const skjson::ObjectValue *jskew, const skjson::ObjectValue *jskew_axis, bool auto_orient=false)
Definition: Transform.cpp:23
virtual SkM44 totalMatrix() const
Definition: Transform.cpp:183
TransformAdapter3D(const skjson::ObjectValue &, const AnimationBuilder &)
Definition: Transform.cpp:148
static sk_sp< Transform > MakeConcat(sk_sp< Transform > a, sk_sp< Transform > b)
struct MyStruct s
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
SK_API sk_sp< PrecompileColorFilter > Matrix()
Definition: Skottie.h:32
const Scalar scale
Definition: SkMD5.cpp:134
constexpr float y() const
Definition: SkPoint_impl.h:187
constexpr float x() const
Definition: SkPoint_impl.h:181
float x
Definition: SkM44.h:20
float y
Definition: SkM44.h:20
Definition: SkM44.h:56
float y
Definition: SkM44.h:57
float z
Definition: SkM44.h:57
float x
Definition: SkM44.h:57