42 for (
size_t i = 0; i <
count; ++i) {
51VectorValue::operator
SkV3()
const {
54 this->size() > 0 ? (*this)[0] : 0,
55 this->size() > 1 ? (*this)[1] : 0,
56 this->size() > 2 ? (*this)[2] : 0,
61 return static_cast<SkColor4f>(*this).toSkColor();
66 const auto r = this->size() > 0 ?
SkTPin((*
this)[0], 0.0f, 1.0f) : 0,
67 g = this->size() > 1 ?
SkTPin((*
this)[1], 0.0f, 1.0f) : 0,
68 b = this->size() > 2 ?
SkTPin((*
this)[2], 0.0f, 1.0f) : 0,
69 a = this->size() > 3 ?
SkTPin((*
this)[3], 0.0f, 1.0f) : 1;
71 return { r, g,
b,
a };
86class VectorKeyframeAnimator final :
public KeyframeAnimator {
88 VectorKeyframeAnimator(std::vector<Keyframe> kfs,
89 std::vector<SkCubicMap> cms,
90 std::vector<float> storage,
92 std::vector<float>* target_value)
94 , fStorage(
std::move(storage))
96 , fTarget(target_value) {
99 fTarget->resize(fVecLen);
103 StateChanged onSeek(
float t)
override {
104 const auto& lerp_info = this->getLERPInfo(t);
106 SkASSERT(lerp_info.vrec0.idx + fVecLen <= fStorage.size());
107 SkASSERT(lerp_info.vrec1.idx + fVecLen <= fStorage.size());
108 SkASSERT(fTarget->size() == fVecLen);
110 const auto* v0 = fStorage.data() + lerp_info.vrec0.idx;
111 const auto* v1 = fStorage.data() + lerp_info.vrec1.idx;
112 auto* dst = fTarget->data();
114 const auto is_constant = lerp_info.vrec0.equals(lerp_info.vrec1,
117 if (0 != std::memcmp(dst, v0, fVecLen *
sizeof(
float))) {
118 std::copy(v0, v0 + fVecLen, dst);
124 size_t count = fVecLen;
125 bool changed =
false;
133 changed |=
any(new_val != old_val);
142 while (
count-- > 0) {
143 const auto new_val =
Lerp(*v0++, *v1++, lerp_info.weight);
145 changed |= (new_val != *
dst);
152 const std::vector<float> fStorage;
153 const size_t fVecLen;
155 std::vector<float>* fTarget;
160class VectorExpressionAnimator final :
public Animator {
162 VectorExpressionAnimator(
sk_sp<ExpressionEvaluator<std::vector<float>>> expression_evaluator,
163 std::vector<float>* target_value)
164 : fExpressionEvaluator(
std::move(expression_evaluator))
165 , fTarget(target_value) {}
169 StateChanged onSeek(
float t)
override {
170 std::vector<float>
result = fExpressionEvaluator->evaluate(t);
171 bool changed =
false;
172 for (
size_t i = 0; i < fTarget->size(); i++) {
185 std::vector<float>* fTarget;
193 , fParseLen(parse_len)
194 , fParseData(parse_data)
203 if (!jkf0 || !fParseLen((*jkf0)[
"s"], &fVecLen)) {
212 if (!safe || !SkTFitsIn<uint32_t>(
total_size)) {
223 fStorage.resize(fCurrentVec * fVecLen);
224 fStorage.shrink_to_fit();
227 new VectorKeyframeAnimator(std::move(
fKFs),
237 return sk_make_sp<VectorExpressionAnimator>(expression_evaluator, fTarget);
243 if (!this->fParseLen(jv, &vec_len)) {
247 fTarget->resize(vec_len);
248 return fParseData(jv, vec_len, fTarget->data());
255 auto offset = fCurrentVec * fVecLen;
258 if (!fParseData(jv, fVecLen, fStorage.data() +
offset)) {
264 if (fCurrentVec > 0 && !memcmp(fStorage.data() +
offset,
265 fStorage.data() +
offset - fVecLen,
266 fVecLen *
sizeof(
float))) {
288 if (!ParseDefault<bool>((*jprop)[
"s"],
false)) {
305 return this->bindImpl(abuilder, jprop, builder);
310 bool boundX = this->
bind(abuilder, (*jprop)[
"x"], v->data() + 0);
311 bool boundY = this->
bind(abuilder, (*jprop)[
"y"], v->data() + 1);
312 bool boundZ = this->
bind(abuilder, (*jprop)[
"z"], v->data() + 2);
313 return boundX || boundY || boundZ;
322 abuilder.fSlotManager->trackColorValue(
SkString(sid->begin()), v,
sk_ref_sp(
this));
static size_t total_size(SkSBlockAllocator< N > &pool)
#define INHERITED(method,...)
sk_sp< T > sk_ref_sp(T *obj)
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
constexpr uint32_t SkToU32(S x)
size_t mul(size_t x, size_t y)
virtual sk_sp< ExpressionEvaluator< std::vector< float > > > createArrayExpressionEvaluator(const char expression[])=0
bool bind(const AnimationBuilder &, const skjson::ObjectValue *, T *)
std::vector< SkCubicMap > fCMs
bool parseKeyframes(const AnimationBuilder &, const skjson::ArrayValue &)
std::vector< Keyframe > fKFs
bool(*)(const skjson::Value &, size_t, float *) VectorDataParser
bool parseKFValue(const AnimationBuilder &, const skjson::ObjectValue &, const skjson::Value &, Keyframe::Value *) override
sk_sp< Animator > makeFromExpression(ExpressionManager &, const char *) override
bool parseValue(const AnimationBuilder &, const skjson::Value &) const override
sk_sp< KeyframeAnimator > makeFromKeyframes(const AnimationBuilder &, const skjson::ArrayValue &) override
VectorAnimatorBuilder(std::vector< float > *, VectorLenParser, VectorDataParser)
bool(*)(const skjson::Value &, size_t *) VectorLenParser
T Lerp(const T &a, const T &b, float t)
static bool parse_array(const skjson::ArrayValue *ja, float *a, size_t count)
bool Parse(const skjson::Value &, T *)
const skjson::StringValue * ParseSlotID(const skjson::ObjectValue *jobj)
SIT bool any(const Vec< 1, T > &x)
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)