lottie: added support of auto oriented feature in lottie. 33/193133/1
authorsubhransu mohanty <sub.mohanty@samsung.com>
Thu, 15 Nov 2018 04:51:18 +0000 (13:51 +0900)
committersubhransu mohanty <sub.mohanty@samsung.com>
Thu, 15 Nov 2018 04:51:18 +0000 (13:51 +0900)
Change-Id: Id2290aa0949519fc24b165f9a24aff4151871507

example/resource/ao.json [new file with mode: 0755]
src/lottie/lottieitem.cpp
src/lottie/lottiemodel.cpp
src/lottie/lottiemodel.h

diff --git a/example/resource/ao.json b/example/resource/ao.json
new file mode 100755 (executable)
index 0000000..9f78a33
--- /dev/null
@@ -0,0 +1 @@
+{"v":"5.2.1","fr":60,"ip":0,"op":60,"w":500,"h":500,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-89.47,0],[0,-89.47],[89.47,0],[0,89.47]],"o":[[89.47,0],[0,89.47],[-89.47,0],[0,-89.47]],"v":[[0,-162],[162,0],[0,162],[-162,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.562,"y":0.562},"o":{"x":0.167,"y":0.167},"n":"0p562_0p562_0p167_0p167","t":8,"s":[250,88,0],"e":[412,250,0],"to":[89.4701232910156,0,0],"ti":[0,-89.4701232910156,0]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.311,"y":0.311},"n":"0p656_0p656_0p311_0p311","t":38,"s":[412,250,0],"e":[250,412,0],"to":[0,89.4701232910156,0],"ti":[89.4701232910156,0,0]},{"i":{"x":0.689,"y":0.689},"o":{"x":0.343,"y":0.343},"n":"0p689_0p689_0p343_0p343","t":68,"s":[250,412,0],"e":[88,250,0],"to":[-89.4701232910156,0,0],"ti":[0,89.4701232910156,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.437,"y":0.437},"n":"0p833_0p833_0p437_0p437","t":98,"s":[88,250,0],"e":[250,88,0],"to":[0,-89.4701232910156,0],"ti":[-89.4701232910156,0,0]},{"t":128}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":1,"shapes":[{"ty":"rc","d":1,"s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":60,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
index cb36b13..d190483 100644 (file)
@@ -299,10 +299,10 @@ float LOTLayerItem::opacity(int frameNo) const
 VMatrix LOTLayerItem::matrix(int frameNo) const
 {
     if (mParentLayer)
-        return mLayerData->mTransform->matrix(frameNo) *
+        return mLayerData->mTransform->matrix(frameNo, mLayerData->autoOrient()) *
                mParentLayer->matrix(frameNo);
     else
-        return mLayerData->mTransform->matrix(frameNo);
+        return mLayerData->mTransform->matrix(frameNo, mLayerData->autoOrient());
 }
 
 bool LOTLayerItem::visible() const
index d6f50ce..e5283be 100644 (file)
@@ -47,12 +47,12 @@ void LOTCompositionData::processRepeaterObjects()
     visitor.visit(mRootLayer.get());
 }
 
-VMatrix LOTTransformData::matrix(int frameNo) const
+VMatrix LOTTransformData::matrix(int frameNo, bool autoOrient) const
 {
     if (mStaticMatrix)
         return mCachedMatrix;
     else
-        return computeMatrix(frameNo);
+        return computeMatrix(frameNo, autoOrient);
 }
 
 float LOTTransformData::opacity(int frameNo) const
@@ -65,7 +65,7 @@ void LOTTransformData::cacheMatrix()
     mCachedMatrix = computeMatrix(0);
 }
 
-VMatrix LOTTransformData::computeMatrix(int frameNo) const
+VMatrix LOTTransformData::computeMatrix(int frameNo, bool autoOrient) const
 {
     VMatrix m;
     VPointF position = mPosition.value(frameNo);
@@ -73,8 +73,11 @@ VMatrix LOTTransformData::computeMatrix(int frameNo) const
         position.setX(mX.value(frameNo));
         position.setY(mY.value(frameNo));
     }
+
+    float angle = autoOrient ? mPosition.angle(frameNo) : 0;
     m.translate(position)
         .rotate(mRotation.value(frameNo))
+        .rotate(angle)
         .scale(mScale.value(frameNo) / 100.f)
         .translate(-mAnchor.value(frameNo));
     return m;
index 385091f..73034eb 100644 (file)
@@ -138,6 +138,7 @@ struct LOTKeyFrameValue
     T value(float t) const {
         return lerp(mStartValue, mEndValue, t);
     }
+    float angle(float ) const { return 0;}
 };
 
 template <>
@@ -163,6 +164,15 @@ struct LOTKeyFrameValue<VPointF>
             return lerp(mStartValue, mEndValue, t);
         }
     }
+
+    float angle(float t) const {
+        if (mPathKeyFrame) {
+            VBezier b = VBezier::fromPoints(mStartValue, mStartValue + mOutTangent,
+                                       mEndValue + mInTangent, mEndValue);
+            return b.angleAt(b.tAtLength(t * b.length()));
+        }
+        return 0;
+    }
 };
 
 
@@ -170,9 +180,14 @@ template<typename T>
 class LOTKeyFrame
 {
 public:
+    float progress(int frameNo) const {
+        return mInterpolator->value((frameNo - mStartFrame) / (mEndFrame - mStartFrame));
+    }
     T value(int frameNo) const {
-        float progress = mInterpolator->value((frameNo - mStartFrame) / (mEndFrame - mStartFrame));
-        return mValue.value(progress);
+        return mValue.value(progress(frameNo));
+    }
+    float angle(int frameNo) const {
+        return mValue.angle(progress(frameNo));
     }
 
 public:
@@ -192,12 +207,25 @@ public:
         if(mKeyFrames.back().mEndFrame <= frameNo)
             return mKeyFrames.back().mValue.mEndValue;
 
-        for(auto keyFrame : mKeyFrames) {
+        for(const auto &keyFrame : mKeyFrames) {
             if (frameNo >= keyFrame.mStartFrame && frameNo < keyFrame.mEndFrame)
                 return keyFrame.value(frameNo);
         }
         return T();
     }
+
+    float angle(int frameNo) const {
+        if ((mKeyFrames.front().mStartFrame >= frameNo) ||
+            (mKeyFrames.back().mEndFrame <= frameNo) )
+            return 0;
+
+        for(const auto &keyFrame : mKeyFrames) {
+            if (frameNo >= keyFrame.mStartFrame && frameNo < keyFrame.mEndFrame)
+                return keyFrame.angle(frameNo);
+        }
+        return 0;
+    }
+
 public:
     std::vector<LOTKeyFrame<T>>    mKeyFrames;
 };
@@ -209,15 +237,15 @@ public:
     LOTAnimatable():mValue(),mAnimInfo(nullptr){}
     LOTAnimatable(const T &value): mValue(value){}
     bool isStatic() const {if (mAnimInfo) return false; else return true;}
-    T value(int frameNo) const{
-        if (isStatic())
-            return mValue;
-        else
-            return mAnimInfo->value(frameNo);
+    T value(int frameNo) const {
+        return isStatic() ? mValue : mAnimInfo->value(frameNo);
+    }
+    float angle(int frameNo) const {
+        return isStatic() ? 0 : mAnimInfo->angle(frameNo);
     }
 public:
-    T                                    mValue;
-    int                                  mPropertyIndex; /* "ix" */
+    T                                 mValue;
+    int                               mPropertyIndex; /* "ix" */
     std::unique_ptr<LOTAnimInfo<T>>   mAnimInfo;
 };
 
@@ -393,12 +421,12 @@ class LOTTransformData : public LOTData
 {
 public:
     LOTTransformData():LOTData(LOTData::Type::Transform),mScale({100, 100}){}
-    VMatrix matrix(int frameNo) const;
+    VMatrix matrix(int frameNo, bool autoOrient = false) const;
     float    opacity(int frameNo) const;
     void cacheMatrix();
     bool staticMatrix() const {return mStaticMatrix;}
 private:
-    VMatrix computeMatrix(int frameNo) const;
+    VMatrix computeMatrix(int frameNo, bool autoOrient = false) const;
 public:
     LOTAnimatable<float>     mRotation{0};  /* "r" */
     LOTAnimatable<VPointF>   mScale;     /* "s" */