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)
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)
107 pd->progress = (double)(pd->is_direction_forward); 107 pd->progress = (double)(pd->is_direction_forward);
108 } 108 }
109 109
110 /* The previously applied map effect should be reset before applying the
111 * current map effect. Otherwise, the incrementally added map effects
112 * increase numerical error. */
113 efl_gfx_mapping_reset(efl_animation_player_target_get(eo_obj));
110 efl_animation_apply(anim, pd->progress, efl_animation_player_target_get(eo_obj)); 114 efl_animation_apply(anim, pd->progress, efl_animation_player_target_get(eo_obj));
111 115
112 Efl_Canvas_Animation_Player_Event_Running event_running; 116 Efl_Canvas_Animation_Player_Event_Running event_running;
@@ -207,11 +211,14 @@ _efl_canvas_animation_player_efl_player_stop(Eo *eo_obj,
207 Efl_Canvas_Animation_Player_Data *pd) 211 Efl_Canvas_Animation_Player_Data *pd)
208{ 212{
209 EFL_ANIMATION_PLAYER_ANIMATION_GET(eo_obj, anim); 213 EFL_ANIMATION_PLAYER_ANIMATION_GET(eo_obj, anim);
214
215 //Reset the state of the target to the initial state
216 efl_gfx_mapping_reset(efl_animation_player_target_get(eo_obj));
217
210 Eina_Bool play = efl_player_play_get(eo_obj); 218 Eina_Bool play = efl_player_play_get(eo_obj);
211 if (play) 219 if (play)
212 { 220 {
213 efl_player_play_set(eo_obj, EINA_FALSE); 221 efl_player_play_set(eo_obj, EINA_FALSE);
214 //Reset the state of the target to the initial state
215 if ((efl_animation_final_state_keep_get(anim)) && 222 if ((efl_animation_final_state_keep_get(anim)) &&
216 (efl_animation_repeat_mode_get(anim) != EFL_CANVAS_ANIMATION_REPEAT_MODE_REVERSE) && 223 (efl_animation_repeat_mode_get(anim) != EFL_CANVAS_ANIMATION_REPEAT_MODE_REVERSE) &&
217 (!(efl_animation_repeat_count_get(anim) & 1))) 224 (!(efl_animation_repeat_count_get(anim) & 1)))
@@ -223,14 +230,12 @@ _efl_canvas_animation_player_efl_player_stop(Eo *eo_obj,
223 else 230 else
224 { 231 {
225 pd->progress = 0.0; 232 pd->progress = 0.0;
226 efl_gfx_mapping_reset(efl_animation_player_target_get(eo_obj));
227 } 233 }
228 efl_event_callback_call(eo_obj, EFL_ANIMATION_PLAYER_EVENT_ENDED, NULL); 234 efl_event_callback_call(eo_obj, EFL_ANIMATION_PLAYER_EVENT_ENDED, NULL);
229 } 235 }
230 else 236 else
231 { 237 {
232 pd->progress = 0.0; 238 pd->progress = 0.0;
233 efl_gfx_mapping_reset(efl_animation_player_target_get(eo_obj));
234 } 239 }
235 240
236 if (pd->auto_del) efl_del(eo_obj); 241 if (pd->auto_del) efl_del(eo_obj);
@@ -303,6 +308,11 @@ _efl_canvas_animation_player_efl_player_pos_set(Eo *eo_obj,
303 EFL_ANIMATION_PLAYER_ANIMATION_GET(eo_obj, anim); 308 EFL_ANIMATION_PLAYER_ANIMATION_GET(eo_obj, anim);
304 double length = efl_animation_duration_get(anim); 309 double length = efl_animation_duration_get(anim);
305 pd->progress = sec / length; 310 pd->progress = sec / length;
311
312 /* The previously applied map effect should be reset before applying the
313 * current map effect. Otherwise, the incrementally added map effects
314 * increase numerical error. */
315 efl_gfx_mapping_reset(efl_animation_player_target_get(eo_obj));
306 efl_animation_apply(anim, pd->progress, efl_animation_player_target_get(eo_obj)); 316 efl_animation_apply(anim, pd->progress, efl_animation_player_target_get(eo_obj));
307} 317}
308 318
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
21 Efl_Canvas_Animation_Data *pd = efl_data_scope_get(o, EFL_CANVAS_ANIMATION_CLASS) 21 Efl_Canvas_Animation_Data *pd = efl_data_scope_get(o, EFL_CANVAS_ANIMATION_CLASS)
22 22
23#define GET_STATUS(from, to, progress) \ 23#define GET_STATUS(from, to, progress) \
24 ((from) + (((to) - (from)) * (progress))) 24 ((from * (1.0 - progress)) + (to * progress))
25 25
26#define FINAL_STATE_IS_REVERSE(anim) \ 26#define FINAL_STATE_IS_REVERSE(anim) \
27 ((efl_animation_repeat_mode_get(anim) == EFL_CANVAS_ANIMATION_REPEAT_MODE_REVERSE) && \ 27 ((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 @@
2 2
3#define MY_CLASS EFL_CANVAS_ANIMATION_ROTATE_CLASS 3#define MY_CLASS EFL_CANVAS_ANIMATION_ROTATE_CLASS
4 4
5static double
6_rotation_get(Eo *target)
7{
8 double x1, x2, y1, y2;
9 double theta;
10
11 efl_gfx_mapping_coord_absolute_get(target, 0, &x1, &y1, NULL);
12 efl_gfx_mapping_coord_absolute_get(target, 1, &x2, &y2, NULL);
13 theta = atan((y2 - y1) / (x2 - x1));
14
15 return theta * 180 / M_PI;
16}
17
18EOLIAN static void 5EOLIAN static void
19_efl_canvas_animation_rotate_rotate_set(Eo *eo_obj EINA_UNUSED, 6_efl_canvas_animation_rotate_rotate_set(Eo *eo_obj EINA_UNUSED,
20 Efl_Canvas_Animation_Rotate_Data *pd, 7 Efl_Canvas_Animation_Rotate_Data *pd,
@@ -115,26 +102,24 @@ _efl_canvas_animation_rotate_efl_canvas_animation_animation_apply(Eo *eo_obj,
115 Efl_Canvas_Object *target) 102 Efl_Canvas_Object *target)
116{ 103{
117 double new_degree; 104 double new_degree;
118 double prev_degree;
119 105
120 progress = efl_animation_apply(efl_super(eo_obj, MY_CLASS), progress, target); 106 progress = efl_animation_apply(efl_super(eo_obj, MY_CLASS), progress, target);
121 if (!target) return progress; 107 if (!target) return progress;
122 108
123 prev_degree = _rotation_get(target);
124 new_degree = GET_STATUS(pd->from.degree, pd->to.degree, progress); 109 new_degree = GET_STATUS(pd->from.degree, pd->to.degree, progress);
125 110
126 if (pd->use_rel_pivot) 111 if (pd->use_rel_pivot)
127 { 112 {
128 efl_gfx_mapping_rotate(target, 113 efl_gfx_mapping_rotate(target,
129 new_degree - prev_degree, 114 new_degree,
130 (pd->rel_pivot.obj) ? pd->rel_pivot.obj : target, 115 (pd->rel_pivot.obj) ? pd->rel_pivot.obj : target,
131 pd->rel_pivot.cx, pd->rel_pivot.cy); 116 pd->rel_pivot.cx, pd->rel_pivot.cy);
132 } 117 }
133 else 118 else
134 { 119 {
135 efl_gfx_mapping_rotate_absolute(target, 120 efl_gfx_mapping_rotate_absolute(target,
136 new_degree - prev_degree, 121 new_degree,
137 pd->abs_pivot.cx, pd->abs_pivot.cy); 122 pd->abs_pivot.cx, pd->abs_pivot.cy);
138 } 123 }
139 124
140 return progress; 125 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 @@
2 2
3#define MY_CLASS EFL_CANVAS_ANIMATION_SCALE_CLASS 3#define MY_CLASS EFL_CANVAS_ANIMATION_SCALE_CLASS
4 4
5static Efl_Canvas_Animation_Scale_Property
6_scale_get(Eo *target)
7{
8 double x1, x2, x3, y1, y2, y3, w, h;
9 Efl_Canvas_Animation_Scale_Property scale;
10 Eina_Rect geometry;
11
12 geometry = efl_gfx_entity_geometry_get(target);
13 efl_gfx_mapping_coord_absolute_get(target, 0, &x1, &y1, NULL);
14 efl_gfx_mapping_coord_absolute_get(target, 1, &x2, &y2, NULL);
15 efl_gfx_mapping_coord_absolute_get(target, 2, &x3, &y3, NULL);
16
17 w = sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
18 h = sqrt(((x3 - x2) * (x3 - x2)) + ((y3 - y2) * (y3 - y2)));
19
20 scale.scale_x = w / geometry.w;
21 scale.scale_y = h / geometry.h;
22
23 return scale;
24}
25
26EOLIAN static void 5EOLIAN static void
27_efl_canvas_animation_scale_scale_set(Eo *eo_obj EINA_UNUSED, 6_efl_canvas_animation_scale_scale_set(Eo *eo_obj EINA_UNUSED,
28 Efl_Canvas_Animation_Scale_Data *pd, 7 Efl_Canvas_Animation_Scale_Data *pd,
@@ -149,30 +128,26 @@ _efl_canvas_animation_scale_efl_canvas_animation_animation_apply(Eo *eo_obj,
149 double progress, 128 double progress,
150 Efl_Canvas_Object *target) 129 Efl_Canvas_Object *target)
151{ 130{
152 Efl_Canvas_Animation_Scale_Property prev_scale;
153 Efl_Canvas_Animation_Scale_Property new_scale; 131 Efl_Canvas_Animation_Scale_Property new_scale;
154 132
155 progress = efl_animation_apply(efl_super(eo_obj, MY_CLASS), progress, target); 133 progress = efl_animation_apply(efl_super(eo_obj, MY_CLASS), progress, target);
156 if (!target) return progress; 134 if (!target) return progress;
157 135
158 prev_scale = _scale_get(target);
159 new_scale.scale_x = GET_STATUS(pd->from.scale_x, pd->to.scale_x, progress); 136 new_scale.scale_x = GET_STATUS(pd->from.scale_x, pd->to.scale_x, progress);
160 new_scale.scale_y = GET_STATUS(pd->from.scale_y, pd->to.scale_y, progress); 137 new_scale.scale_y = GET_STATUS(pd->from.scale_y, pd->to.scale_y, progress);
161 138
162 if (pd->use_rel_pivot) 139 if (pd->use_rel_pivot)
163 { 140 {
164 efl_gfx_mapping_zoom(target, 141 efl_gfx_mapping_zoom(target,
165 new_scale.scale_x / prev_scale.scale_x, 142 new_scale.scale_x, new_scale.scale_y,
166 new_scale.scale_y / prev_scale.scale_y, 143 (pd->rel_pivot.obj) ? pd->rel_pivot.obj : target,
167 (pd->rel_pivot.obj) ? pd->rel_pivot.obj : target, 144 pd->rel_pivot.cx, pd->rel_pivot.cy);
168 pd->rel_pivot.cx, pd->rel_pivot.cy);
169 } 145 }
170 else 146 else
171 { 147 {
172 efl_gfx_mapping_zoom_absolute(target, 148 efl_gfx_mapping_zoom_absolute(target,
173 new_scale.scale_x / prev_scale.scale_x, 149 new_scale.scale_x, new_scale.scale_y,
174 new_scale.scale_y / prev_scale.scale_y, 150 pd->abs_pivot.cx, pd->abs_pivot.cy);
175 pd->abs_pivot.cx, pd->abs_pivot.cy);
176 } 151 }
177 152
178 return progress; 153 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
8 double y; 8 double y;
9} _Translate_Property_Double; 9} _Translate_Property_Double;
10 10
11static _Translate_Property_Double
12_translation_get(Eo *target)
13{
14 double x1, x2, y1, y2;
15 _Translate_Property_Double translate;
16 Eina_Rect geometry;
17
18 geometry = efl_gfx_entity_geometry_get(target);
19
20 efl_gfx_mapping_coord_absolute_get(target, 0, &x1, &y1, NULL);
21 efl_gfx_mapping_coord_absolute_get(target, 2, &x2, &y2, NULL);
22 translate.x = ((x1 + x2) / 2.0) - (geometry.x + (geometry.w / 2.0));
23 translate.y = ((y1 + y2) / 2.0) - (geometry.y + (geometry.h / 2.0));
24
25 return translate;
26}
27
28EOLIAN static void 11EOLIAN static void
29_efl_canvas_animation_translate_translate_set(Eo *eo_obj EINA_UNUSED, 12_efl_canvas_animation_translate_translate_set(Eo *eo_obj EINA_UNUSED,
30 Efl_Canvas_Animation_Translate_Data *pd, 13 Efl_Canvas_Animation_Translate_Data *pd,
@@ -115,13 +98,12 @@ _efl_canvas_animation_translate_efl_canvas_animation_animation_apply(Eo *eo_obj,
115 double progress, 98 double progress,
116 Efl_Canvas_Object *target) 99 Efl_Canvas_Object *target)
117{ 100{
118 _Translate_Property_Double prev;
119 _Translate_Property_Double new; 101 _Translate_Property_Double new;
102 Eina_Rect geometry;
120 103
121 progress = efl_animation_apply(efl_super(eo_obj, MY_CLASS), progress, target); 104 progress = efl_animation_apply(efl_super(eo_obj, MY_CLASS), progress, target);
122 if (!target) return progress; 105 if (!target) return progress;
123 106
124 prev = _translation_get(target);
125 if (pd->use_rel_move) 107 if (pd->use_rel_move)
126 { 108 {
127 new.x = GET_STATUS(pd->from.move_x, pd->to.move_x, progress); 109 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,
129 } 111 }
130 else 112 else
131 { 113 {
132 new.x = GET_STATUS(pd->from.x, pd->to.x, progress); 114 geometry = efl_gfx_entity_geometry_get(target);
133 new.y = GET_STATUS(pd->from.y, pd->to.y, progress); 115 new.x = GET_STATUS(pd->from.x, pd->to.x, progress) - geometry.x;
116 new.y = GET_STATUS(pd->from.y, pd->to.y, progress) - geometry.y;
134 } 117 }
135 118
136 efl_gfx_mapping_translate(target, new.x - prev.x, new.y - prev.y, 0.0); 119 efl_gfx_mapping_translate(target, new.x, new.y, 0.0);
137 120
138 return progress; 121 return progress;
139} 122}