From 6b363ae02126654c793300a1e45a91b6d44a5191 Mon Sep 17 00:00:00 2001 From: "sub.mohanty@samsung.com" Date: Sun, 29 Jul 2018 17:51:17 +0900 Subject: [PATCH] lottie/model: refactor Keyframe class for space optimization. Change-Id: I5b5a614ef69ab430459003764e7707ace4575ebd --- src/lottie/lottiemodel.h | 139 +++++++++++++++----------------------------- src/lottie/lottieparser.cpp | 50 +++++++++++----- 2 files changed, 83 insertions(+), 106 deletions(-) diff --git a/src/lottie/lottiemodel.h b/src/lottie/lottiemodel.h index 93bcf4b..d20d554 100644 --- a/src/lottie/lottiemodel.h +++ b/src/lottie/lottiemodel.h @@ -132,119 +132,74 @@ public: }; + template -class LOTKeyFrame +inline T lerp(const T& start, const T& end, float t) { -public: - LOTKeyFrame():mStartValue(), - mEndValue(), - mStartFrame(0), - mEndFrame(0), - mInterpolator(nullptr), - mInTangent(), - mOutTangent(), - mPathKeyFrame(false){} + return start + t * (end - start); +} - T value(int frameNo) const { - float progress = mInterpolator->value(float(frameNo - mStartFrame) / float(mEndFrame - mStartFrame)); - return mStartValue + progress * (mEndValue - mStartValue); - } +inline LottieShapeData lerp(const LottieShapeData& start, const LottieShapeData& end, float t) +{ + if (start.mPoints.size() != start.mPoints.size()) + return LottieShapeData(); -public: - T mStartValue; - T mEndValue; - int mStartFrame; - int mEndFrame; - std::shared_ptr mInterpolator; + LottieShapeData result; + result.reserve(start.mPoints.size()); + for (unsigned int i = 0 ; i < start.mPoints.size(); i++) { + result.mPoints.push_back(start.mPoints[i] + t * (end.mPoints[i] - start.mPoints[i])); + } + return result; +} - /* this is for interpolating position along a path - * Need to move to other place because its only applicable - * for positional property. - */ - VPointF mInTangent; - VPointF mOutTangent; - bool mPathKeyFrame; +template +struct LOTKeyFrameValue +{ + T mStartValue; + T mEndValue; + T value(float t) const { + return lerp(mStartValue, mEndValue, t); + } }; -template<> -class LOTKeyFrame +template <> +struct LOTKeyFrameValue { -public: - LOTKeyFrame():mStartValue(), - mEndValue(), - mStartFrame(0), - mEndFrame(0), - mInterpolator(nullptr), - mInTangent(), - mOutTangent(), - mPathKeyFrame(false){} + VPointF mStartValue; + VPointF mEndValue; + VPointF mInTangent; + VPointF mOutTangent; + bool mPathKeyFrame = false; - VPointF value(int frameNo) const { - float progress = mInterpolator->value(float(frameNo - mStartFrame) / float(mEndFrame - mStartFrame)); - if (mPathKeyFrame & 1) { - return VBezier::fromPoints(mStartValue, mStartValue + mOutTangent, mEndValue + mInTangent, mEndValue).pointAt(progress); + VPointF value(float t) const { + if (mPathKeyFrame) { + return VBezier::fromPoints(mStartValue, mStartValue + mOutTangent, + mEndValue + mInTangent, mEndValue).pointAt(t); } else { - return mStartValue + progress * (mEndValue - mStartValue); + return lerp(mStartValue, mEndValue, t); } } - -public: - VPointF mStartValue; - VPointF mEndValue; - int mStartFrame; - int mEndFrame; - std::shared_ptr mInterpolator; - - /* this is for interpolating position along a path - * Need to move to other place because its only applicable - * for positional property. - */ - VPointF mInTangent; - VPointF mOutTangent; - bool mPathKeyFrame; }; -template<> -class LOTKeyFrame + +template +class LOTKeyFrame { public: - LOTKeyFrame():mStartValue(), - mEndValue(), - mStartFrame(0), - mEndFrame(0), - mInterpolator(nullptr), - mInTangent(), - mOutTangent(), - mPathKeyFrame(false){} - - LottieShapeData value(int frameNo) const { - float progress = mInterpolator->value(float(frameNo - mStartFrame) / float(mEndFrame - mStartFrame)); - - if (mStartValue.mPoints.size() != mEndValue.mPoints.size()) - return LottieShapeData(); + LOTKeyFrame(): mStartFrame(0), + mEndFrame(0), + mInterpolator(nullptr){} - LottieShapeData result; - result.reserve(mStartValue.mPoints.size()); - for (unsigned int i = 0 ; i < mStartValue.mPoints.size(); i++) { - result.mPoints.push_back(mStartValue.mPoints[i] + progress * (mEndValue.mPoints[i] - mStartValue.mPoints[i])); - } - return result; + T value(int frameNo) const { + float progress = mInterpolator->value(float(frameNo - mStartFrame) / float(mEndFrame - mStartFrame)); + return mValue.value(progress); } public: - LottieShapeData mStartValue; - LottieShapeData mEndValue; int mStartFrame; int mEndFrame; std::shared_ptr mInterpolator; - - /* this is for interpolating position along a path - * Need to move to other place because its only applicable - * for positional property. - */ - VPointF mInTangent; - VPointF mOutTangent; - bool mPathKeyFrame; + LOTKeyFrameValue mValue; }; template @@ -253,9 +208,9 @@ class LOTAnimInfo public: T value(int frameNo) const { if (mKeyFrames.front().mStartFrame >= frameNo) - return mKeyFrames.front().mStartValue; + return mKeyFrames.front().mValue.mStartValue; if(mKeyFrames.back().mEndFrame <= frameNo) - return mKeyFrames.back().mEndValue; + return mKeyFrames.back().mValue.mEndValue; for(auto keyFrame : mKeyFrames) { if (frameNo >= keyFrame.mStartFrame && frameNo < keyFrame.mEndFrame) diff --git a/src/lottie/lottieparser.cpp b/src/lottie/lottieparser.cpp index 11001df..cf296c8 100644 --- a/src/lottie/lottieparser.cpp +++ b/src/lottie/lottieparser.cpp @@ -166,6 +166,8 @@ public: void getValue(LottieShapeData &shape); void getValue(LottieGradient &gradient); template + bool parseKeyFrameValue(const char* key, LOTKeyFrameValue &value); + template void parseKeyFrame(LOTAnimInfo &obj); template void parseProperty(LOTAnimatable &obj); @@ -1592,6 +1594,38 @@ LottieParserImpl::parseInperpolatorPoint() return cp; } +template +bool LottieParserImpl::parseKeyFrameValue(const char* key, LOTKeyFrameValue &value) +{ + if (0 == strcmp(key, "s")) { + getValue(value.mStartValue); + } else if (0 == strcmp(key, "e")) { + getValue(value.mEndValue); + } else { + return false; + } + return true; +} + +template<> +bool LottieParserImpl::parseKeyFrameValue(const char* key, LOTKeyFrameValue &value) +{ + if (0 == strcmp(key, "s")) { + getValue(value.mStartValue); + } else if (0 == strcmp(key, "e")) { + getValue(value.mEndValue); + } else if (0 == strcmp(key, "ti")) { + value.mPathKeyFrame = true; + getValue(value.mInTangent); + } else if (0 == strcmp(key, "to")) { + value.mPathKeyFrame = true; + getValue(value.mOutTangent); + } else { + return false; + } + return true; +} + /* * https://github.com/airbnb/lottie-web/blob/master/docs/json/properties/multiDimensionalKeyframed.json */ @@ -1623,19 +1657,7 @@ void LottieParserImpl::parseKeyFrame(LOTAnimInfo &obj) continue; } else if (0 == strcmp(key, "t")) { keyframe.mStartFrame = GetDouble(); - } else if (0 == strcmp(key, "s")) { - getValue(keyframe.mStartValue); - continue; - } else if (0 == strcmp(key, "e")) { - getValue(keyframe.mEndValue); - continue; - } else if (0 == strcmp(key, "ti")) { - keyframe.mPathKeyFrame = true; - getValue(keyframe.mInTangent); - continue; - } else if (0 == strcmp(key, "to")) { - keyframe.mPathKeyFrame = true; - getValue(keyframe.mOutTangent); + } else if (parseKeyFrameValue(key, keyframe.mValue)) { continue; } else if (0 == strcmp(key, "h")) { hold = GetInt(); @@ -1657,7 +1679,7 @@ void LottieParserImpl::parseKeyFrame(LOTAnimInfo &obj) interpolatorKey = "hold_interpolator"; inTangent = VPointF(); outTangent = VPointF(); - keyframe.mEndValue = keyframe.mStartValue; + keyframe.mValue.mEndValue = keyframe.mValue.mStartValue; keyframe.mEndFrame = keyframe.mStartFrame; } -- 2.7.4