From 2235e1f7e827b520972e4fe0688dba36a1424c16 Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Wed, 21 Nov 2018 15:37:28 +0900 Subject: [PATCH] lottie: refactor trim object handling 1. compute start and end with offset in the model before returning the segment. 2. modify pathmesure object to only handle start and end. Change-Id: I8db4c2f818e8ef8c777bf1618aa143a83dabb5c0 --- src/lottie/lottieitem.cpp | 43 +++++++------------------------- src/lottie/lottieitem.h | 4 +-- src/lottie/lottiemodel.h | 35 +++++++++++++++++++++++--- src/vector/vpathmesure.cpp | 62 ++++++++++++++-------------------------------- src/vector/vpathmesure.h | 2 -- 5 files changed, 61 insertions(+), 85 deletions(-) diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index a882a0a..009b3ba 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -948,16 +948,12 @@ void LOTTrimItem::update(int frameNo, const VMatrix &/*parentMatrix*/, if (mCache.mFrameNo == frameNo) return; - float start = mData->start(frameNo); - float end = mData->end(frameNo); - float offset = mData->offset(frameNo); + LOTTrimData::Segment segment = mData->segment(frameNo); - if (!(vCompare(mCache.mStart, start) && vCompare(mCache.mEnd, end) && - vCompare(mCache.mOffset, offset))) { + if (!(vCompare(mCache.mSegment.start, segment.start) && + vCompare(mCache.mSegment.end, segment.end))) { mDirty = true; - mCache.mStart = start; - mCache.mEnd = end; - mCache.mOffset = offset; + mCache.mSegment = segment; } mCache.mFrameNo = frameNo; } @@ -967,7 +963,7 @@ void LOTTrimItem::update() // when both path and trim are not dirty if (!(mDirty || pathDirty())) return; - if (vCompare(mCache.mStart, mCache.mEnd)) { + if (vCompare(mCache.mSegment.start, mCache.mSegment.end)) { for (auto &i : mPathItems) { i->updatePath(VPath()); } @@ -978,9 +974,8 @@ void LOTTrimItem::update() if (mData->type() == LOTTrimData::TrimType::Simultaneously) { for (auto &i : mPathItems) { VPathMesure pm; - pm.setStart(mCache.mStart); - pm.setEnd(mCache.mEnd); - pm.setOffset(mCache.mOffset); + pm.setStart(mCache.mSegment.start); + pm.setEnd(mCache.mSegment.end); i->updatePath(pm.trim(i->localPath())); } } else { // LOTTrimData::TrimType::Individually @@ -988,28 +983,8 @@ void LOTTrimItem::update() for (auto &i : mPathItems) { totalLength += i->localPath().length(); } - float offset = totalLength * mCache.mOffset; - float start = totalLength * mCache.mStart; - float end = totalLength * mCache.mEnd; - start += offset; - end +=offset; - // normalize start, end value to 0 - totalLength - if (fabs(start) > totalLength) start = fmod(start, totalLength); - if (fabs(end) > totalLength) end = fmod(end, totalLength); - - if (start >= 0 && end >= 0) { - if (start > end) std::swap(start, end); - } else if ( start < 0 && end < 0) { - start += totalLength; - end += totalLength; - if (start > end) std::swap(start, end); - } else { - // one is +ve and one is -ve so the - // segment will be wrapped from end segment to start segment. - // we need to split it in two segment. - //@TODO - return; - } + float start = totalLength * mCache.mSegment.start; + float end = totalLength * mCache.mSegment.end; if (start < end ) { float curLen = 0.0; diff --git a/src/lottie/lottieitem.h b/src/lottie/lottieitem.h index 9a5f1dc..4f14597 100644 --- a/src/lottie/lottieitem.h +++ b/src/lottie/lottieitem.h @@ -466,9 +466,7 @@ private: } struct Cache { int mFrameNo{-1}; - float mStart{0}; - float mEnd{0}; - float mOffset{0}; + LOTTrimData::Segment mSegment{}; }; Cache mCache; std::vector mPathItems; diff --git a/src/lottie/lottiemodel.h b/src/lottie/lottiemodel.h index 226cee5..01ab083 100644 --- a/src/lottie/lottiemodel.h +++ b/src/lottie/lottiemodel.h @@ -677,14 +677,43 @@ public: class LOTTrimData : public LOTData { public: + struct Segment { + float start{0}; + float end{0}; + }; enum class TrimType { Simultaneously, Individually }; LOTTrimData():LOTData(LOTData::Type::Trim){} - float start(int frameNo) const {return mStart.value(frameNo)/100.0f;} - float end(int frameNo) const {return mEnd.value(frameNo)/100.0f;} - float offset(int frameNo) const {return fmod(mOffset.value(frameNo), 360.0f)/ 360.0f;} + Segment segment(int frameNo) const { + float start = mStart.value(frameNo)/100.0f; + float end = mEnd.value(frameNo)/100.0f; + float offset = fmod(mOffset.value(frameNo), 360.0f)/ 360.0f; + start += offset; + end += offset; + // normalize start, end value to 0 - 1 + if (fabs(start) > 1) start = fmod(start, 1); + if (fabs(end) > 1) end = fmod(end, 1); + Segment s; + if (start >= 0 && end >= 0) { + s.start = std::min(start, end); + s.end = std::max(start, end); + } else if (start < 0 && end < 0) { + start += 1; + end +=1; + s.start = std::min(start, end); + s.end = std::max(start, end); + } else { + // one of them is -ve so it a loop + if (start < 0) start +=1; + if (end < 0) end +=1; + s.start = std::max(start, end); + s.end = std::min(start, end); + } + return s; + + } LOTTrimData::TrimType type() const {return mTrimType;} public: LOTAnimatable mStart{0}; diff --git a/src/vector/vpathmesure.cpp b/src/vector/vpathmesure.cpp index 81a4ebd..2b7f400 100644 --- a/src/vector/vpathmesure.cpp +++ b/src/vector/vpathmesure.cpp @@ -5,16 +5,12 @@ V_BEGIN_NAMESPACE -VPath oneSegment(float start, float end, const VPath & path) -{ - if (start > end) { - std::swap(start, end); - } - float array[5] = {0.0f, start, end - start, std::numeric_limits::max(), 0.0f}; - VDasher dasher(array, 5); - return dasher.dashed(path); -} - +/* + * start and end value must be normalized to [0 - 1] + * Path mesure trims the path from [start --> end] + * if start > end it treates as a loop and trims as two segment + * [0-->end] and [start --> 1] + */ VPath VPathMesure::trim(const VPath &path) { if (vCompare(mStart, mEnd)) return VPath(); @@ -22,40 +18,20 @@ VPath VPathMesure::trim(const VPath &path) if ((vCompare(mStart, 0.0f) && (vCompare(mEnd, 1.0f))) || (vCompare(mStart, 1.0f) && (vCompare(mEnd, 0.0f)))) return path; - if (vIsZero(mOffset)) { - float length = path.length(); - return oneSegment(length * mStart, length * mEnd, path); - } else { - float length = path.length(); - float offset = length * mOffset; - float start = length * mStart; - float end = length * mEnd; - start += offset; - end +=offset; + float length = path.length(); - if (start < 0 && end < 0) { - return oneSegment(length + start, length + end, path); - } else if (start > 0 && end > 0) { - if (start > length && end > length) - return oneSegment(start - length, end - length, path); - else if (start < length && end < length) - return oneSegment(start, end, path); - else { - float len1 = start > end ? start - length : end - length; - float start2 = start < end ? start : end; - float gap1 = start2 - len1; - float array[5] = {len1, gap1, length - start2, 1000, 0.0f}; - VDasher dasher(array, 5); - return dasher.dashed(path); - } - } else { - float len1 = start > end ? start : end; - float start2 = start < end ? length + start : length + end; - float gap1 = start2 - len1; - float array[5] = {len1, gap1, length - start2, 1000, 0.0f}; - VDasher dasher(array, 5); - return dasher.dashed(path); - } + if (mStart < mEnd) { + float array[4] = {0.0f, length * mStart, //1st segment + (mEnd - mStart) * length, std::numeric_limits::max(), //2nd segment + }; + VDasher dasher(array, 4); + return dasher.dashed(path); + } else { + float array[4] = {length * mEnd, (mStart - mEnd) * length, //1st segment + (1 - mStart) * length, std::numeric_limits::max(), //2nd segment + }; + VDasher dasher(array, 4); + return dasher.dashed(path); } } diff --git a/src/vector/vpathmesure.h b/src/vector/vpathmesure.h index 8202913..7c7b745 100644 --- a/src/vector/vpathmesure.h +++ b/src/vector/vpathmesure.h @@ -9,12 +9,10 @@ class VPathMesure { public: void setStart(float start){mStart = start;} void setEnd(float end){mEnd = end;} - void setOffset(float offset){mOffset = offset;} VPath trim(const VPath &path); private: float mStart{0.0f}; float mEnd{1.0f}; - float mOffset{0.0f}; }; V_END_NAMESPACE -- 2.7.4