16#define DUMP_KF_RECORDS 0
25 if (t <= fKFs.front().t) {
27 return { 0, fKFs.front().v, fKFs.front().v };
29 if (t >= fKFs.back().t) {
31 return { 0, fKFs.back().v, fKFs.back().v };
35 if (!fCurrentSegment.contains(t)) {
36 fCurrentSegment = this->find_segment(t);
38 SkASSERT(fCurrentSegment.contains(t));
42 return { 0, fCurrentSegment.kf0->v, fCurrentSegment.kf0->v };
46 this->compute_weight(fCurrentSegment, t),
47 fCurrentSegment.kf0->v,
48 fCurrentSegment.kf1->v,
52KeyframeAnimator::KFSegment KeyframeAnimator::find_segment(
float t)
const {
57 auto kf0 = &fKFs.front(),
61 while (kf0 + 1 != kf1) {
65 const auto mid_kf = kf0 + (kf1 - kf0) / 2;
77float KeyframeAnimator::compute_weight(
const KFSegment &seg,
float t)
const {
81 auto w = (t - seg.kf0->t) / (seg.kf1->t - seg.kf0->t);
86 w = fCMs[mapper_index].computeYFromX(
w);
131 auto parsed = this->
parseKFValue(abuilder, jkf, jkf[
"s"], v);
135 if (!parsed &&
i > 0 &&
i == jkfs.
size() - 1) {
138 parsed = this->
parseKFValue(abuilder, jkf, (*prev_kf)[
"e"], v);
144 bool constant_value =
true;
148 for (
size_t i = 0;
i < jkfs.
size(); ++
i) {
155 if (!Parse<float>((*jkf)[
"t"], &t)) {
160 if (!parse_value(*jkf,
i, &v)) {
165 auto& prev_kf =
fKFs.back();
168 if (t <= prev_kf.t) {
173 if (v.
equals(prev_kf.v, keyframe_type)) {
178 fKFs.push_back({t, v, this->parseMapping(*jkf)});
180 constant_value = constant_value && (v.
equals(
fKFs.front().v, keyframe_type));
184 fCMs.shrink_to_fit();
186 if (constant_value) {
193 SkDEBUGF(
"Animator[%p], values: %lu, KF records: %zu\n",
194 this,
fKFs.back().v_idx + 1,
fKFs.size());
195 for (
const auto& kf :
fKFs) {
196 SkDEBUGF(
" { t: %1.3f, v_idx: %lu, mapping: %lu }\n", kf.t, kf.v_idx, kf.mapping);
208 if (!
Parse(jkf[
"o"], &c0) ||
209 !
Parse(jkf[
"i"], &c1) ||
215 if (c0 != prev_c0 || c1 != prev_c1 ||
fCMs.empty()) {
216 fCMs.emplace_back(c0, c1);
constexpr size_t SkToSizeT(S x)
constexpr uint32_t SkToU32(S x)
static bool IsLinear(SkPoint p1, SkPoint p2)
virtual ~AnimatorBuilder()
std::vector< SkCubicMap > fCMs
bool parseKeyframes(const AnimationBuilder &, const skjson::ArrayValue &)
std::vector< Keyframe > fKFs
virtual bool parseKFValue(const AnimationBuilder &, const skjson::ObjectValue &, const skjson::Value &, Keyframe::Value *)=0
~KeyframeAnimator() override
LERPInfo getLERPInfo(float t) const
bool Parse(const skjson::Value &jv, const internal::AnimationBuilder &abuilder, TextValue *v)
T ParseDefault(const skjson::Value &v, const T &defaultValue)
bool equals(const Value &other, Type ty) const
static constexpr uint32_t kConstantMapping
static constexpr uint32_t kCubicIndexOffset
static constexpr uint32_t kLinearMapping