rlottie: Fix issue with repeater object.
authorsubhransu mohanty <sub.mohanty@samsung.com>
Thu, 18 Apr 2019 07:03:21 +0000 (16:03 +0900)
committerHermet Park <hermetpark@gmail.com>
Thu, 25 Apr 2019 04:13:48 +0000 (13:13 +0900)
Below issues are fixed
   1. when repeater has 0 copies.
   2. when "copies" property has animation.
   3. Wrong matrix computation when repeater transformation has anchor value.

Fixed abstract_circle.json resource.

Change-Id: Iaef475b1bc98bf7b4b68076fb9078d11bac362a3

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

index 22466311d70a625f043cc477337055b081a286e7..e3ac115d2ab0d07e50c2e21140c6e5f9a2cde426 100644 (file)
@@ -1383,7 +1383,9 @@ LOTRepeaterItem::LOTRepeaterItem(LOTRepeaterData *data) : mData(data)
     LOTGroupData *root = reinterpret_cast<LOTGroupData *>(mData->mChildren[0].get());
     assert(root);
 
-    for (int i= 0; i < mData->copies(0); i++) {
+    mCopies = mData->maxCopies();
+
+    for (int i= 0; i < mCopies; i++) {
         auto content = std::make_unique<LOTContentGroupItem>(static_cast<LOTGroupData *>(root));
         content->setParent(this);
         mContents.push_back(std::move(content));
@@ -1395,27 +1397,43 @@ void LOTRepeaterItem::update(int frameNo, const VMatrix &parentMatrix, float par
 
     DirtyFlag newFlag = flag;
 
+    float copies = mData->copies(frameNo);
+    int visibleCopies = int(copies);
+
+    if (visibleCopies == 0) {
+        mHidden = true;
+        return;
+    } else {
+        mHidden = false;
+    }
+
     if (mData->hasMtrixChange(frameNo)) {
         newFlag |= DirtyFlagBit::Matrix;
     }
 
-    float multiplier = mData->offset(frameNo);
+    float offset = mData->offset(frameNo);
     float startOpacity = mData->mTransform->startOpacity(frameNo);
     float endOpacity = mData->mTransform->endOpacity(frameNo);
-    float index = 0;
-    float copies = mData->copies(frameNo);
-    if (!vCompare(copies, 1)) copies -=1;
 
     newFlag |= DirtyFlagBit::Alpha;
-    for (const auto &content : mContents) {
-        float newAlpha = parentAlpha * lerp(startOpacity, endOpacity, index / copies);
-        VMatrix result = mData->mTransform->matrixForRepeater(frameNo, multiplier) * parentMatrix;
-        content->update(frameNo, result, newAlpha, newFlag);
-        multiplier += 1;
-        index +=1;
+
+    for (int i = 0; i < mCopies; ++i) {
+        float newAlpha = parentAlpha * lerp(startOpacity, endOpacity, i / copies);
+
+        // hide rest of the copies , @TODO find a better solution.
+        if ( i >= visibleCopies) newAlpha = 0;
+
+        VMatrix result = mData->mTransform->matrixForRepeater(frameNo, i + offset) * parentMatrix;
+        mContents[i]->update(frameNo, result, newAlpha, newFlag);
     }
 }
 
+void LOTRepeaterItem::renderList(std::vector<VDrawable *> &list)
+{
+    if (mHidden) return;
+    return LOTContentGroupItem::renderList(list);
+}
+
 static void updateGStops(LOTNode *n, const VGradient *grad)
 {
     if (grad->mStops.size() != n->mGradient.stopCount) {
index bdf13626b152a5f58851032c771ba60131c2fd88..88bab8da9142f85cc775816a079f2be37ab764e2 100644 (file)
@@ -268,7 +268,7 @@ public:
    void applyTrim();
    void processTrimItems(std::vector<LOTPathDataItem *> &list);
    void processPaintItems(std::vector<LOTPathDataItem *> &list);
-   void renderList(std::vector<VDrawable *> &list) final;
+   void renderList(std::vector<VDrawable *> &list);
    const VMatrix & matrix() const { return mMatrix;}
 protected:
    LOTGroupData                                  *mData{nullptr};
@@ -488,8 +488,11 @@ class LOTRepeaterItem : public LOTContentGroupItem
 public:
    LOTRepeaterItem(LOTRepeaterData *data);
    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
+   void renderList(std::vector<VDrawable *> &list) final;
 private:
    LOTRepeaterData             *mData;
+   bool                         mHidden{false};
+   int                          mCopies{0};
 };
 
 
index 7ebed12e7b7ab2d7e1dd32f26a13221914ad38c1..aee0c4974de79d57ee68923bfca6d0cb6c95e795 100644 (file)
@@ -94,9 +94,10 @@ VMatrix LOTTransformData::matrixForRepeater(int frameNo, float multiplier) const
     scale.setY(std::pow(scale.y(), multiplier));
     VMatrix m;
     m.translate(mPosition.value(frameNo) * multiplier)
-     .rotate(mRotation.value(frameNo) * multiplier)
      .scale(scale)
-     .translate(mAnchor.value(frameNo));
+     .translate(mAnchor.value(frameNo))
+     .rotate(mRotation.value(frameNo) * multiplier)
+     .translate(-mAnchor.value(frameNo));
     return m;
 }
 
index 376b873d5ef0432aadac05f484b1a17562ae6d5f..f9f38ccf5863476b2724ca67a0d3278c66543f85 100644 (file)
@@ -821,11 +821,13 @@ public:
     bool hasMtrixChange(int /*frameNo*/) const {
         return !(mTransform->isStatic() && mOffset.isStatic());
     }
+    int maxCopies() const { return int(mMaxCopies);}
     float copies(int frameNo) const {return mCopies.value(frameNo);}
     float offset(int frameNo) const {return mOffset.value(frameNo);}
 public:
     LOTAnimatable<float>             mCopies{0};
     LOTAnimatable<float>             mOffset{0};
+    float                            mMaxCopies{0.0};
 };
 
 class LOTModel
index f55fba8237f5e370faec24ba2453d3fdec2c8e3c..9afdc2d54e1bb6ad63007293f5d6fb597c7aaf28 100644 (file)
@@ -1282,6 +1282,18 @@ std::shared_ptr<LOTData> LottieParserImpl::parseReapeaterObject()
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "c")) {
             parseProperty(obj->mCopies);
+            float maxCopy= 0.0;
+            if (!obj->mCopies.isStatic()) {
+                for(auto &keyFrame : obj->mCopies.mAnimInfo->mKeyFrames) {
+                    if (maxCopy < keyFrame.mValue.mStartValue)
+                        maxCopy = keyFrame.mValue.mStartValue;
+                    if (maxCopy < keyFrame.mValue.mEndValue)
+                        maxCopy = keyFrame.mValue.mEndValue;
+                }
+            } else {
+                maxCopy = obj->mCopies.mValue;
+            }
+            obj->mMaxCopies = maxCopy;
         } else if (0 == strcmp(key, "o")) {
             parseProperty(obj->mOffset);
         } else if (0 == strcmp(key, "tr")) {
@@ -2109,7 +2121,7 @@ public:
         case LOTData::Type::Repeater: {
             auto r = static_cast<LOTRepeaterData *>(obj);
             vDebug << level << "{ Repeater: a:" << !obj->isStatic()
-                   << ", copies:" << r->copies(0)
+                   << ", copies:" << r->maxCopies()
                    << ", offset:" << r->offset(0);
             visitChildren(static_cast<LOTGroupData *>(obj), level);
             vDebug << level << "} Repeater";