lottie: remove the duplicated binary search logic.

This commit is contained in:
Hermet Park 2024-02-14 23:04:16 +09:00 committed by Hermet Park
parent 53e2ecd81c
commit 11ddfdb193

View file

@ -183,6 +183,24 @@ struct LottieVectorFrame
}; };
template<typename T>
uint32_t bsearch(T* frames, float frameNo)
{
uint32_t low = 0;
uint32_t high = frames->count - 1;
while (low <= high) {
auto mid = low + (high - low) / 2;
auto frame = frames->data + mid;
if (mathEqual(frameNo, frame->no)) return mid;
else if (frameNo < frame->no) high = mid - 1;
else low = mid + 1;
}
if (high < low) low = high;
return low;
}
template<typename T> template<typename T>
struct LottieProperty struct LottieProperty
{ {
@ -220,19 +238,9 @@ struct LottieProperty
if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value; if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value;
if (frameNo >= frames->last().no) return frames->last().value; if (frameNo >= frames->last().no) return frames->last().value;
uint32_t low = 1; auto frame = frames->data + bsearch(frames, frameNo);
uint32_t high = frames->count - 1; if (frame->no == frameNo) return frame->value;
return frame->interpolate(frame + 1, frameNo);
while (low <= high) {
auto mid = low + (high - low) / 2;
auto frame = frames->data + mid;
if (mathEqual(frameNo, frame->no)) return frame->value;
else if (frameNo > frame->no) low = mid + 1;
else high = mid - 1;
}
auto frame = frames->data + low;
return (frame - 1)->interpolate(frame, frameNo);
} }
float angle(float frameNo) { return 0; } float angle(float frameNo) { return 0; }
@ -302,41 +310,30 @@ struct LottiePathSet
return true; return true;
} }
uint32_t low = 1; auto frame = frames->data + bsearch(frames, frameNo);
uint32_t high = frames->count - 1;
while (low <= high) { if (frame->no == frameNo) {
auto mid = low + (high - low) / 2; copy(frame->value, cmds);
auto frame = frames->data + mid; copy(frame->value, pts);
if (mathEqual(frameNo, frame->no)) {
copy(frame->value, cmds);
copy(frame->value, pts);
return true;
} else if (frameNo > frame->no) {
low = mid + 1;
} else {
high = mid - 1;
}
}
//interpolate
auto frame = frames->data + low;
auto pframe = frame - 1;
copy(pframe->value, cmds);
auto t = (frameNo - pframe->no) / (frame->no - pframe->no);
if (pframe->interpolator) t = pframe->interpolator->progress(t);
if (pframe->hold) {
if (t < 1.0f) copy(pframe->value, pts);
else copy(frame->value, pts);
return true; return true;
} }
auto s = pframe->value.pts; //interpolate
auto e = frame->value.pts; copy(frame->value, cmds);
for (auto i = 0; i < pframe->value.ptsCnt; ++i, ++s, ++e) { auto t = (frameNo - frame->no) / ((frame + 1)->no - frame->no);
if (frame->interpolator) t = frame->interpolator->progress(t);
if (frame->hold) {
if (t < 1.0f) copy(frame->value, pts);
else copy((frame + 1)->value, pts);
return true;
}
auto s = frame->value.pts;
auto e = (frame + 1)->value.pts;
for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e) {
pts.push(mathLerp(*s, *e, t)); pts.push(mathLerp(*s, *e, t));
} }
return true; return true;
@ -399,35 +396,23 @@ struct LottieColorStop
return; return;
} }
uint32_t low = 1; auto frame = frames->data + bsearch(frames, frameNo);
uint32_t high = frames->count - 1; if (frame->no == frameNo) {
fill->colorStops(frame->value.data, count);
while (low <= high) { return;
auto mid = low + (high - low) / 2;
auto frame = frames->data + mid;
if (mathEqual(frameNo, frame->no)) {
fill->colorStops(frame->value.data, count);
return;
} else if (frameNo > frame->no) {
low = mid + 1;
} else {
high = mid - 1;
}
} }
//interpolate //interpolate
auto frame = frames->data + low; auto t = (frameNo - frame->no) / ((frame + 1)->no - frame->no);
auto pframe = frame - 1; if (frame->interpolator) t = frame->interpolator->progress(t);
auto t = (frameNo - pframe->no) / (frame->no - pframe->no);
if (pframe->interpolator) t = pframe->interpolator->progress(t);
if (pframe->hold) { if (frame->hold) {
if (t < 1.0f) fill->colorStops(pframe->value.data, count); if (t < 1.0f) fill->colorStops(frame->value.data, count);
else fill->colorStops(frame->value.data, count); else fill->colorStops((frame + 1)->value.data, count);
} }
auto s = pframe->value.data; auto s = frame->value.data;
auto e = frame->value.data; auto e = (frame + 1)->value.data;
Array<Fill::ColorStop> result; Array<Fill::ColorStop> result;
@ -483,19 +468,9 @@ struct LottiePosition
if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value; if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value;
if (frameNo >= frames->last().no) return frames->last().value; if (frameNo >= frames->last().no) return frames->last().value;
uint32_t low = 1; auto frame = frames->data + bsearch(frames, frameNo);
uint32_t high = frames->count - 1; if (frame->no == frameNo) return frame->value;
return frame->interpolate(frame + 1, frameNo);
while (low <= high) {
auto mid = low + (high - low) / 2;
auto frame = frames->data + mid;
if (mathEqual(frameNo, frame->no)) return frame->value;
else if (frameNo > frame->no) low = mid + 1;
else high = mid - 1;
}
auto frame = frames->data + low;
return (frame - 1)->interpolate(frame, frameNo);
} }
float angle(float frameNo) float angle(float frameNo)
@ -504,18 +479,8 @@ struct LottiePosition
if (frames->count == 1 || frameNo <= frames->first().no) return 0; if (frames->count == 1 || frameNo <= frames->first().no) return 0;
if (frameNo >= frames->last().no) return 0; if (frameNo >= frames->last().no) return 0;
uint32_t low = 1; auto frame = frames->data + bsearch(frames, frameNo);
uint32_t high = frames->count - 1; return frame->angle(frame + 1, frameNo);
while (low <= high) {
auto mid = low + (high - low) / 2;
auto frame = frames->data + mid;
if (frameNo > frame->no) low = mid + 1;
else high = mid - 1;
}
auto frame = frames->data + low;
return (frame - 1)->angle(frame, frameNo);
} }
void prepare() void prepare()
@ -525,7 +490,6 @@ struct LottiePosition
(frame - 1)->prepare(frame); (frame - 1)->prepare(frame);
} }
} }
}; };
@ -570,19 +534,8 @@ struct LottieTextDoc
if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value; if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value;
if (frameNo >= frames->last().no) return frames->last().value; if (frameNo >= frames->last().no) return frames->last().value;
uint32_t low = 0; auto frame = frames->data + bsearch(frames, frameNo);
uint32_t high = frames->count - 1; return frame->value;
while (low <= high) {
auto mid = low + (high - low) / 2;
auto frame = frames->data + mid;
if (mathEqual(frameNo, frame->no)) return frame->value;
else if (frameNo < frame->no) high = mid - 1;
else low = mid + 1;
}
if (high < low) low = high;
return (*frames)[low].value;
} }
void prepare() {} void prepare() {}