summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaehyun Cho <jae_hyun.cho@samsung.com>2019-06-04 18:52:14 +0900
committerJaehyun Cho <jae_hyun.cho@samsung.com>2019-06-04 21:56:58 +0900
commit9eb0b28cc735326ab0079f49af0ae2668f9d5942 (patch)
tree1b17cd5e59d4cec616a41240c9d954bf6eab002d
parent28adabd21481ea244a800b1a31c69271ad619d2d (diff)
downloadefl-9eb0b28cc735326ab0079f49af0ae2668f9d5942.tar.gz
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.
-rw-r--r--src/lib/evas/canvas/efl_canvas_animation_player.c16
-rw-r--r--src/lib/evas/canvas/efl_canvas_animation_private.h2
-rw-r--r--src/lib/evas/canvas/efl_canvas_animation_rotate.c25
-rw-r--r--src/lib/evas/canvas/efl_canvas_animation_scale.c35
-rw-r--r--src/lib/evas/canvas/efl_canvas_animation_translate.c27
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;
}