jaehyun pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=9eb0b28cc735326ab0079f49af0ae2668f9d5942

commit 9eb0b28cc735326ab0079f49af0ae2668f9d5942
Author: Jaehyun Cho <jae_hyun....@samsung.com>
Date:   Tue Jun 4 18:52:14 2019 +0900

    efl_canvas_animation: fix numerical error on map effect calculation
    
    Previously, for a single canvas animation, map effect was applied in
    animator callback without resetting previously applied map effect.
    This increased numerical error because each time map effect factors
    (e.g. scale, degree) should be calculated based on the current map
    coordinates.
    
    To resolve this numerical error, now the previously applied map effect
    is reset before applying the current map effect in animator callback.
---
 src/lib/evas/canvas/efl_canvas_animation_player.c  | 16 ++++++++--
 src/lib/evas/canvas/efl_canvas_animation_private.h |  2 +-
 src/lib/evas/canvas/efl_canvas_animation_rotate.c  | 25 ++++------------
 src/lib/evas/canvas/efl_canvas_animation_scale.c   | 35 ++++------------------
 .../evas/canvas/efl_canvas_animation_translate.c   | 27 ++++-------------
 5 files changed, 29 insertions(+), 76 deletions(-)

diff --git a/src/lib/evas/canvas/efl_canvas_animation_player.c 
b/src/lib/evas/canvas/efl_canvas_animation_player.c
index 42fb2c4127..edb4d66c53 100644
--- a/src/lib/evas/canvas/efl_canvas_animation_player.c
+++ b/src/lib/evas/canvas/efl_canvas_animation_player.c
@@ -107,6 +107,10 @@ _animator_cb(void *data)
         pd->progress = (double)(pd->is_direction_forward);
      }
 
+   /* The previously applied map effect should be reset before applying the
+    * current map effect. Otherwise, the incrementally added map effects
+    * increase numerical error. */
+   efl_gfx_mapping_reset(efl_animation_player_target_get(eo_obj));
    efl_animation_apply(anim, pd->progress, 
efl_animation_player_target_get(eo_obj));
 
    Efl_Canvas_Animation_Player_Event_Running event_running;
@@ -207,11 +211,14 @@ _efl_canvas_animation_player_efl_player_stop(Eo *eo_obj,
                                       Efl_Canvas_Animation_Player_Data *pd)
 {
    EFL_ANIMATION_PLAYER_ANIMATION_GET(eo_obj, anim);
+
+   //Reset the state of the target to the initial state
+   efl_gfx_mapping_reset(efl_animation_player_target_get(eo_obj));
+
    Eina_Bool play = efl_player_play_get(eo_obj);
    if (play)
      {
         efl_player_play_set(eo_obj, EINA_FALSE);
-        //Reset the state of the target to the initial state
         if ((efl_animation_final_state_keep_get(anim)) &&
             (efl_animation_repeat_mode_get(anim) != 
EFL_CANVAS_ANIMATION_REPEAT_MODE_REVERSE) &&
             (!(efl_animation_repeat_count_get(anim) & 1)))
@@ -223,14 +230,12 @@ _efl_canvas_animation_player_efl_player_stop(Eo *eo_obj,
         else
           {
              pd->progress = 0.0;
-             efl_gfx_mapping_reset(efl_animation_player_target_get(eo_obj));
           }
         efl_event_callback_call(eo_obj, EFL_ANIMATION_PLAYER_EVENT_ENDED, 
NULL);
      }
    else
      {
          pd->progress = 0.0;
-         efl_gfx_mapping_reset(efl_animation_player_target_get(eo_obj));
      }
 
    if (pd->auto_del) efl_del(eo_obj);
@@ -303,6 +308,11 @@ _efl_canvas_animation_player_efl_player_pos_set(Eo *eo_obj,
    EFL_ANIMATION_PLAYER_ANIMATION_GET(eo_obj, anim);
    double length = efl_animation_duration_get(anim);
    pd->progress = sec / length;
+
+   /* The previously applied map effect should be reset before applying the
+    * current map effect. Otherwise, the incrementally added map effects
+    * increase numerical error. */
+   efl_gfx_mapping_reset(efl_animation_player_target_get(eo_obj));
    efl_animation_apply(anim, pd->progress, 
efl_animation_player_target_get(eo_obj));
 }
 
diff --git a/src/lib/evas/canvas/efl_canvas_animation_private.h 
b/src/lib/evas/canvas/efl_canvas_animation_private.h
index c1fe16ff09..c8f0609103 100644
--- a/src/lib/evas/canvas/efl_canvas_animation_private.h
+++ b/src/lib/evas/canvas/efl_canvas_animation_private.h
@@ -21,7 +21,7 @@ typedef struct _Efl_Canvas_Animation_Data
    Efl_Canvas_Animation_Data *pd = efl_data_scope_get(o, 
EFL_CANVAS_ANIMATION_CLASS)
 
 #define GET_STATUS(from, to, progress) \
-   ((from) + (((to) - (from)) * (progress)))
+   ((from * (1.0 - progress)) + (to * progress))
 
 #define FINAL_STATE_IS_REVERSE(anim) \
    ((efl_animation_repeat_mode_get(anim) == 
EFL_CANVAS_ANIMATION_REPEAT_MODE_REVERSE) && \
diff --git a/src/lib/evas/canvas/efl_canvas_animation_rotate.c 
b/src/lib/evas/canvas/efl_canvas_animation_rotate.c
index c57f7e1ac2..fe713dec3c 100644
--- a/src/lib/evas/canvas/efl_canvas_animation_rotate.c
+++ b/src/lib/evas/canvas/efl_canvas_animation_rotate.c
@@ -2,19 +2,6 @@
 
 #define MY_CLASS EFL_CANVAS_ANIMATION_ROTATE_CLASS
 
-static double
-_rotation_get(Eo *target)
-{
-   double x1, x2, y1, y2;
-   double theta;
-
-   efl_gfx_mapping_coord_absolute_get(target, 0, &x1, &y1, NULL);
-   efl_gfx_mapping_coord_absolute_get(target, 1, &x2, &y2, NULL);
-   theta = atan((y2 - y1) / (x2 - x1));
-
-   return theta * 180 / M_PI;
-}
-
 EOLIAN static void
 _efl_canvas_animation_rotate_rotate_set(Eo *eo_obj EINA_UNUSED,
                                  Efl_Canvas_Animation_Rotate_Data *pd,
@@ -115,26 +102,24 @@ 
_efl_canvas_animation_rotate_efl_canvas_animation_animation_apply(Eo *eo_obj,
                                                     Efl_Canvas_Object *target)
 {
    double new_degree;
-   double prev_degree;
 
    progress = efl_animation_apply(efl_super(eo_obj, MY_CLASS), progress, 
target);
    if (!target) return progress;
 
-   prev_degree = _rotation_get(target);
    new_degree = GET_STATUS(pd->from.degree, pd->to.degree, progress);
 
    if (pd->use_rel_pivot)
      {
         efl_gfx_mapping_rotate(target,
-                           new_degree - prev_degree,
-                           (pd->rel_pivot.obj) ? pd->rel_pivot.obj : target,
-                           pd->rel_pivot.cx, pd->rel_pivot.cy);
+                               new_degree,
+                               (pd->rel_pivot.obj) ? pd->rel_pivot.obj : 
target,
+                               pd->rel_pivot.cx, pd->rel_pivot.cy);
      }
    else
      {
         efl_gfx_mapping_rotate_absolute(target,
-                                    new_degree - prev_degree,
-                                    pd->abs_pivot.cx, pd->abs_pivot.cy);
+                                        new_degree,
+                                        pd->abs_pivot.cx, pd->abs_pivot.cy);
      }
 
    return progress;
diff --git a/src/lib/evas/canvas/efl_canvas_animation_scale.c 
b/src/lib/evas/canvas/efl_canvas_animation_scale.c
index 90304defc3..1cccbc61b5 100644
--- a/src/lib/evas/canvas/efl_canvas_animation_scale.c
+++ b/src/lib/evas/canvas/efl_canvas_animation_scale.c
@@ -2,27 +2,6 @@
 
 #define MY_CLASS EFL_CANVAS_ANIMATION_SCALE_CLASS
 
-static Efl_Canvas_Animation_Scale_Property
-_scale_get(Eo *target)
-{
-   double x1, x2, x3, y1, y2, y3, w, h;
-   Efl_Canvas_Animation_Scale_Property scale;
-   Eina_Rect geometry;
-
-   geometry = efl_gfx_entity_geometry_get(target);
-   efl_gfx_mapping_coord_absolute_get(target, 0, &x1, &y1, NULL);
-   efl_gfx_mapping_coord_absolute_get(target, 1, &x2, &y2, NULL);
-   efl_gfx_mapping_coord_absolute_get(target, 2, &x3, &y3, NULL);
-
-   w = sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
-   h = sqrt(((x3 - x2) * (x3 - x2)) + ((y3 - y2) * (y3 - y2)));
-
-   scale.scale_x = w / geometry.w;
-   scale.scale_y = h / geometry.h;
-
-   return scale;
-}
-
 EOLIAN static void
 _efl_canvas_animation_scale_scale_set(Eo *eo_obj EINA_UNUSED,
                                Efl_Canvas_Animation_Scale_Data *pd,
@@ -149,30 +128,26 @@ 
_efl_canvas_animation_scale_efl_canvas_animation_animation_apply(Eo *eo_obj,
                                                    double progress,
                                                    Efl_Canvas_Object *target)
 {
-   Efl_Canvas_Animation_Scale_Property prev_scale;
    Efl_Canvas_Animation_Scale_Property new_scale;
 
    progress = efl_animation_apply(efl_super(eo_obj, MY_CLASS), progress, 
target);
    if (!target) return progress;
 
-   prev_scale = _scale_get(target);
    new_scale.scale_x = GET_STATUS(pd->from.scale_x, pd->to.scale_x, progress);
    new_scale.scale_y = GET_STATUS(pd->from.scale_y, pd->to.scale_y, progress);
 
    if (pd->use_rel_pivot)
      {
         efl_gfx_mapping_zoom(target,
-                         new_scale.scale_x / prev_scale.scale_x,
-                         new_scale.scale_y / prev_scale.scale_y,
-                         (pd->rel_pivot.obj) ? pd->rel_pivot.obj : target,
-                         pd->rel_pivot.cx, pd->rel_pivot.cy);
+                             new_scale.scale_x, new_scale.scale_y,
+                             (pd->rel_pivot.obj) ? pd->rel_pivot.obj : target,
+                             pd->rel_pivot.cx, pd->rel_pivot.cy);
      }
    else
      {
         efl_gfx_mapping_zoom_absolute(target,
-                                  new_scale.scale_x / prev_scale.scale_x,
-                                  new_scale.scale_y / prev_scale.scale_y,
-                                  pd->abs_pivot.cx, pd->abs_pivot.cy);
+                                      new_scale.scale_x, new_scale.scale_y,
+                                      pd->abs_pivot.cx, pd->abs_pivot.cy);
      }
 
    return progress;
diff --git a/src/lib/evas/canvas/efl_canvas_animation_translate.c 
b/src/lib/evas/canvas/efl_canvas_animation_translate.c
index 42748eac99..39a052cf26 100644
--- a/src/lib/evas/canvas/efl_canvas_animation_translate.c
+++ b/src/lib/evas/canvas/efl_canvas_animation_translate.c
@@ -8,23 +8,6 @@ typedef struct __Translate_Property_Double
    double y;
 } _Translate_Property_Double;
 
-static _Translate_Property_Double
-_translation_get(Eo *target)
-{
-   double x1, x2, y1, y2;
-   _Translate_Property_Double translate;
-   Eina_Rect geometry;
-
-   geometry = efl_gfx_entity_geometry_get(target);
-
-   efl_gfx_mapping_coord_absolute_get(target, 0, &x1, &y1, NULL);
-   efl_gfx_mapping_coord_absolute_get(target, 2, &x2, &y2, NULL);
-   translate.x = ((x1 + x2) / 2.0) - (geometry.x + (geometry.w / 2.0));
-   translate.y = ((y1 + y2) / 2.0) - (geometry.y + (geometry.h / 2.0));
-
-   return translate;
-}
-
 EOLIAN static void
 _efl_canvas_animation_translate_translate_set(Eo *eo_obj EINA_UNUSED,
                                        Efl_Canvas_Animation_Translate_Data *pd,
@@ -115,13 +98,12 @@ 
_efl_canvas_animation_translate_efl_canvas_animation_animation_apply(Eo *eo_obj,
                                                        double progress,
                                                        Efl_Canvas_Object 
*target)
 {
-   _Translate_Property_Double prev;
    _Translate_Property_Double new;
+   Eina_Rect geometry;
 
    progress = efl_animation_apply(efl_super(eo_obj, MY_CLASS), progress, 
target);
    if (!target) return progress;
 
-   prev = _translation_get(target);
    if (pd->use_rel_move)
      {
         new.x = GET_STATUS(pd->from.move_x, pd->to.move_x, progress);
@@ -129,11 +111,12 @@ 
_efl_canvas_animation_translate_efl_canvas_animation_animation_apply(Eo *eo_obj,
      }
    else
      {
-        new.x = GET_STATUS(pd->from.x, pd->to.x, progress);
-        new.y = GET_STATUS(pd->from.y, pd->to.y, progress);
+        geometry = efl_gfx_entity_geometry_get(target);
+        new.x = GET_STATUS(pd->from.x, pd->to.x, progress) - geometry.x;
+        new.y = GET_STATUS(pd->from.y, pd->to.y, progress) - geometry.y;
      }
 
-   efl_gfx_mapping_translate(target, new.x - prev.x, new.y - prev.y, 0.0);
+   efl_gfx_mapping_translate(target, new.x, new.y, 0.0);
 
    return progress;
 }

-- 


Reply via email to