lottie/model: refactor Keyframe class for space optimization. 53/185353/3
authorsub.mohanty@samsung.com <smohantty@gmail.com>
Sun, 29 Jul 2018 08:51:17 +0000 (17:51 +0900)
committerSubhransu Mohanty <sub.mohanty@samsung.com>
Mon, 30 Jul 2018 00:47:16 +0000 (00:47 +0000)
Change-Id: I5b5a614ef69ab430459003764e7707ace4575ebd

src/lottie/lottiemodel.h
src/lottie/lottieparser.cpp

index 93bcf4bcb906d820fb66f46f6387a8dc432d199f..d20d5540fc252d1951364cdcd28bde9ff8138630 100644 (file)
@@ -132,119 +132,74 @@ public:
 };
 
 
+
 template<typename T>
-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<VInterpolator> 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 <typename T>
+struct LOTKeyFrameValue
+{
+    T mStartValue;
+    T mEndValue;
+    T value(float t) const {
+        return lerp(mStartValue, mEndValue, t);
+    }
 };
 
-template<>
-class LOTKeyFrame<VPointF>
+template <>
+struct LOTKeyFrameValue<VPointF>
 {
-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<VInterpolator> 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<LottieShapeData>
+
+template<typename T>
+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<VInterpolator> 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<T>  mValue;
 };
 
 template<typename T>
@@ -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)
index 11001df589128c0db04fe0030a2f3a9488afe014..cf296c8d266d5014b43ca915d0b736e8532bad06 100644 (file)
@@ -166,6 +166,8 @@ public:
     void getValue(LottieShapeData &shape);
     void getValue(LottieGradient &gradient);
     template<typename T>
+    bool parseKeyFrameValue(const char* key, LOTKeyFrameValue<T> &value);
+    template<typename T>
     void parseKeyFrame(LOTAnimInfo<T> &obj);
     template<typename T>
     void parseProperty(LOTAnimatable<T> &obj);
@@ -1592,6 +1594,38 @@ LottieParserImpl::parseInperpolatorPoint()
     return cp;
 }
 
+template<typename T>
+bool LottieParserImpl::parseKeyFrameValue(const char* key, LOTKeyFrameValue<T> &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<VPointF> &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<T> &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<T> &obj)
          interpolatorKey = "hold_interpolator";
          inTangent = VPointF();
          outTangent = VPointF();
-         keyframe.mEndValue = keyframe.mStartValue;
+         keyframe.mValue.mEndValue = keyframe.mValue.mStartValue;
          keyframe.mEndFrame = keyframe.mStartFrame;
      }