From c6eac0ed78717021f23b80cbc9b2010914f972da Mon Sep 17 00:00:00 2001 From: Bruno Dilly Date: Wed, 5 Dec 2012 19:29:54 +0000 Subject: [PATCH] edje: make it possible to not reset body position on state changes To make it possible, a flag was added: ignore_part_position. Enabled by default, it will let part position be update only by physics calculatios. If the body is intended to be moved when state is changed, the flag must to be explicitely disabled. It is required otherwise all the states would inherit position from "default" and reset body's position. SVN revision: 80276 --- legacy/edje/src/bin/edje_cc_handlers.c | 29 +++++ legacy/edje/src/examples/Makefile.am | 4 +- legacy/edje/src/examples/physics_basic.edc | 30 +---- legacy/edje/src/examples/physics_complex.edc | 118 +++++++++++++++++++ legacy/edje/src/lib/edje_calc.c | 25 ++-- legacy/edje/src/lib/edje_data.c | 2 + legacy/edje/src/lib/edje_private.h | 2 + 7 files changed, 177 insertions(+), 33 deletions(-) create mode 100644 legacy/edje/src/examples/physics_complex.edc diff --git a/legacy/edje/src/bin/edje_cc_handlers.c b/legacy/edje/src/bin/edje_cc_handlers.c index c27662f614..52fd13c42a 100644 --- a/legacy/edje/src/bin/edje_cc_handlers.c +++ b/legacy/edje/src/bin/edje_cc_handlers.c @@ -313,6 +313,7 @@ static void st_collections_group_parts_part_description_table_min(void); static void st_collections_group_parts_part_description_physics_mass(void); static void st_collections_group_parts_part_description_physics_restitution(void); static void st_collections_group_parts_part_description_physics_friction(void); +static void st_collections_group_parts_part_description_physics_ignore_part_position(void); #endif static void st_collections_group_parts_part_description_map_perspective(void); static void st_collections_group_parts_part_description_map_light(void); @@ -598,6 +599,7 @@ New_Statement_Handler statement_handlers[] = {"collections.group.parts.part.description.physics.mass", st_collections_group_parts_part_description_physics_mass}, {"collections.group.parts.part.description.physics.restitution", st_collections_group_parts_part_description_physics_restitution}, {"collections.group.parts.part.description.physics.friction", st_collections_group_parts_part_description_physics_friction}, + {"collections.group.parts.part.description.physics.ignore_part_position", st_collections_group_parts_part_description_physics_ignore_part_position}, #endif {"collections.group.parts.part.description.map.perspective", st_collections_group_parts_part_description_map_perspective}, {"collections.group.parts.part.description.map.light", st_collections_group_parts_part_description_map_light}, @@ -1089,6 +1091,7 @@ _edje_part_description_alloc(unsigned char type, const char *collection, const c #ifdef HAVE_EPHYSICS result->physics.mass = FROM_DOUBLE(1.0); result->physics.friction = FROM_DOUBLE(0.5); + result->physics.ignore_part_position = 1; #endif return result; @@ -7176,6 +7179,7 @@ st_collections_group_parts_part_description_table_min(void) description { .. physics { + ignore_part_position: 1; mass: 5.31; friction: 0.5; restitution: 0.82; @@ -7269,6 +7273,31 @@ st_collections_group_parts_part_description_physics_friction(void) } #endif +/** + @page edcref + @property + ignore_part_position + @parameters + [1 or 0] + @effect + If enabled, the body won't be positioned following rel1/rel2. + It will keep its position updated only by physics calculations. + If disabled, when the state is set, the body will be moved to + the position described by the blocks rel1/rel2. + Default is 1 (enabled). + @endproperty + @since 1.8.0 +*/ +#ifdef HAVE_EPHYSICS +static void +st_collections_group_parts_part_description_physics_ignore_part_position(void) +{ + check_arg_count(1); + + current_desc->physics.ignore_part_position = parse_bool(0); +} +#endif + /** @edcsubsection{collections_group_parts_description_map,Map} */ diff --git a/legacy/edje/src/examples/Makefile.am b/legacy/edje/src/examples/Makefile.am index 3f120893c0..645c21128a 100644 --- a/legacy/edje/src/examples/Makefile.am +++ b/legacy/edje/src/examples/Makefile.am @@ -53,7 +53,9 @@ EDCS += multisense.edc endif if ENABLE_EPHYSICS -EDCS += physics_basic.edc +EDCS += \ +physics_basic.edc \ +physics_complex.edc endif .edc.edj: diff --git a/legacy/edje/src/examples/physics_basic.edc b/legacy/edje/src/examples/physics_basic.edc index 8bb843ef9d..8784a044db 100644 --- a/legacy/edje/src/examples/physics_basic.edc +++ b/legacy/edje/src/examples/physics_basic.edc @@ -27,21 +27,11 @@ collections { description { state: "default" 0.0; color: 255 0 0 255; /* red */ - rel1.relative: 0.55 0.1; - rel2.relative: 0.75 0.3; + rel1.relative: 0.75 0.1; + rel2.relative: 0.95 0.3; aspect: 1 1; physics { - mass: 10.8; - restitution: 0.7; - friction: 1.0; - } - } - description { - state: "light" 0.0; - inherit: "default" 0.0; - physics { - mass: 6.66; - friction: 1.2; + restitution: 0.85; } } } @@ -68,20 +58,12 @@ collections { description { state: "default" 0.0; visible: 0; + physics { + restitution: 0.7; + } } } } - programs { - program { - name: "load"; - signal: "load"; - in: 2 0; - action: STATE_SET "light" 0.0; - transition: LINEAR 0.5; - target: "red_box"; - } - } - } } diff --git a/legacy/edje/src/examples/physics_complex.edc b/legacy/edje/src/examples/physics_complex.edc new file mode 100644 index 0000000000..8ea56708b2 --- /dev/null +++ b/legacy/edje/src/examples/physics_complex.edc @@ -0,0 +1,118 @@ +collections { + + images { + image: "bubble-blue.png" COMP; + } + + group { + name: "example_group"; + + parts { + part { + name: "background"; + type: RECT; + physics_body: NONE; + description { + state: "default" 0.0; + color: 255 255 255 255; /* white */ + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + } + } + + part { + name: "red_box"; + type: RECT; + physics_body: RIGID_BOX; + description { + state: "default" 0.0; + color: 255 0 0 255; /* light red */ + rel1.relative: 0.45 0.1; + rel2.relative: 0.55 0.2; + aspect: 1 1; + physics { + mass: 10.8; + restitution: 0.85; + friction: 1.0; + } + } + description { + state: "heavier" 0.0; + inherit: "default" 0.0; + color: 120 0 0 255; /* dark red */ + physics { + mass: 30; + restitution: 0; + } + } + } + + part { + name: "blue_circle"; + type: IMAGE; + physics_body: RIGID_CIRCLE; + description { + state: "default" 0.0; + rel1.relative: 0.75 0.1; + rel2.relative: 1 0.3; + aspect: 1 1; + image { + normal: "bubble-blue.png"; + } + physics { + ignore_part_position: 0; + restitution: 0.6; + } + } + description { + state: "left" 0.0; + inherit: "default" 0.0; + rel1.relative: 0 0.1; + rel2.relative: 0.25 0.3; + } + } + + part { + name: "floor"; + type: RECT; + physics_body: BOUNDARY_BOTTOM; + description { + state: "default" 0.0; + visible: 0; + physics { + restitution: 0.9; + } + } + } + } + + programs { + program { + name: "change_box"; + signal: "load"; + in: 2 0; + action: STATE_SET "heavier" 0.0; + transition: LINEAR 1.5; + target: "red_box"; + } + + program { + name: "change_circle"; + signal: "load"; + in: 3 0; + action: STATE_SET "left" 0.0; + target: "blue_circle"; + after: "change_circle_2"; + } + + program { + name: "change_circle_2"; + in: 3 0; + action: STATE_SET "default" 0.0; + target: "blue_circle"; + after: "change_circle"; + } + } + + } +} diff --git a/legacy/edje/src/lib/edje_calc.c b/legacy/edje/src/lib/edje_calc.c index 796affb9d2..a26dc6241b 100644 --- a/legacy/edje/src/lib/edje_calc.c +++ b/legacy/edje/src/lib/edje_calc.c @@ -2293,6 +2293,7 @@ _edje_part_recalc_single(Edje *ed, params->physics.mass = desc->physics.mass; params->physics.restitution = desc->physics.restitution; params->physics.friction = desc->physics.friction; + params->ignore_part_position = desc->physics.ignore_part_position; #endif _edje_part_recalc_single_map(ed, ep, center, light, persp, desc, chosen_desc, params); } @@ -2443,16 +2444,19 @@ _edje_physics_world_geometry_check(EPhysics_World *world) } static void -_edje_physics_body_props_update(Edje_Real_Part *ep, Edje_Calc_Params *pf) +_edje_physics_body_props_update(Edje_Real_Part *ep, Edje_Calc_Params *pf, Eina_Bool pos_update) { /* Boundaries geometry and mass shouldn't be changed */ if (ep->part->physics_body < EDJE_PART_PHYSICS_BODY_BOUNDARY_TOP) { - Evas_Coord z; - - ephysics_body_geometry_get(ep->body, NULL, NULL, &z, NULL, NULL, NULL); - ephysics_body_move(ep->body, ep->edje->x + pf->x, ep->edje->y + pf->y, - z); + if (pos_update) + { + Evas_Coord z; + ephysics_body_geometry_get(ep->body, NULL, NULL, &z, + NULL, NULL, NULL); + ephysics_body_move(ep->body, ep->edje->x + pf->x, + ep->edje->y + pf->y, z); + } ephysics_body_mass_set(ep->body, pf->physics.mass); } @@ -2897,6 +2901,10 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta pos)); p3->physics.friction = TO_DOUBLE(FINTP(p1->physics.friction, p2->physics.friction, pos)); + if ((p1->ignore_part_position) && (p2->ignore_part_position)) + p3->ignore_part_position = 1; + else + p3->ignore_part_position = 0; #endif switch (part_type) @@ -3093,7 +3101,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta if (_edje_physics_world_geometry_check(ep->edje->world)) { _edje_physics_body_add(ep, ep->edje->world); - _edje_physics_body_props_update(ep, pf); + _edje_physics_body_props_update(ep, pf, EINA_TRUE); } } else if (ep->body) @@ -3101,7 +3109,8 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta if (((ep->prev_description) && (chosen_desc != ep->prev_description)) || (pf != p1)) - _edje_physics_body_props_update(ep, pf); + _edje_physics_body_props_update(ep, pf, + !pf->ignore_part_position); } else #endif diff --git a/legacy/edje/src/lib/edje_data.c b/legacy/edje/src/lib/edje_data.c index a652a300f5..4db53c8016 100644 --- a/legacy/edje/src/lib/edje_data.c +++ b/legacy/edje/src/lib/edje_data.c @@ -516,6 +516,7 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "physics.mass", physics.mass, EET_T_DOUBLE); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "physics.restitution", physics.restitution, EET_T_DOUBLE); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "physics.friction", physics.friction, EET_T_DOUBLE); \ + EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "physics.ignore_part_position", physics.ignore_part_position, EET_T_UCHAR); \ } #else #define EDJE_DATA_DESCRIPTOR_DESCRIPTION_COMMON(Edd, Type) \ @@ -583,6 +584,7 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "physics.mass", Dec.physics.mass, EET_T_DOUBLE); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "physics.restitution", Dec.physics.restitution, EET_T_DOUBLE); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "physics.friction", Dec.physics.friction, EET_T_DOUBLE); \ + EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "physics.ignore_part_position", Dec.physics.ignore_part_position, EET_T_UCHAR); \ } #else #define EDJE_DATA_DESCRIPTOR_DESCRIPTION_COMMON_SUB(Edd, Type, Dec) \ diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index 7e01a1c808..61b8a7fcd7 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -963,6 +963,7 @@ struct _Edje_Part_Description_Common double mass; double restitution; double friction; + unsigned char ignore_part_position; } physics; #endif @@ -1300,6 +1301,7 @@ struct _Edje_Calc_Params double restitution; // 8 double friction; // 8 } physics; // 24 + unsigned char ignore_part_position : 1; #endif unsigned char persp_on : 1; unsigned char lighted : 1;