From 14cf9fe3f77c9e3f8f9e52755f2ad731378216e3 Mon Sep 17 00:00:00 2001 From: Bruno Dilly Date: Thu, 6 Dec 2012 19:20:07 +0000 Subject: [PATCH] edje: support forces using programs / script Implement actions: * PHYSICS_FORCE * PHYSICS_TORQUE * PHYSICS_FORCES_CLEAR and embryo script functions: * physics_force * physics_torque * physics_forces_clear * physics_forces_get * physics_torques_get SVN revision: 80381 --- legacy/edje/data/include/edje.inc | 12 +- legacy/edje/src/bin/edje_cc_handlers.c | 22 ++- legacy/edje/src/examples/physics_actions.edc | 125 ++++++++++++++- legacy/edje/src/lib/Edje.h | 5 +- legacy/edje/src/lib/edje_embryo.c | 151 +++++++++++++++++++ legacy/edje/src/lib/edje_program.c | 41 +++++ 6 files changed, 351 insertions(+), 5 deletions(-) diff --git a/legacy/edje/data/include/edje.inc b/legacy/edje/data/include/edje.inc index 93da20cde0..a358d58334 100644 --- a/legacy/edje/data/include/edje.inc +++ b/legacy/edje/data/include/edje.inc @@ -227,6 +227,16 @@ native play_tone (tone_name[], Float:duration); * * physics_impulse(PART:"logo", 0, 50.8, 0); * physics_torque_impulse(PART:"logo", 0, 0, 3.4); + * + * physics_force(PART:"logo", 0, 240, 0); + * physics_torque(PART:"logo", 0, 0, 2.2); + * physics_forces_clear(PART:"logo"); */ -native physics_impulse (part_id, Float:x, Float:y, Float:z); +native physics_impulse (part_id, Float:x, Float:y, Float:z); native physics_torque_impulse (part_id, Float:x, Float:y, Float:z); + +native physics_torque (part_id, Float:x, Float:y, Float:z); +native physics_torques_get (part_id, &Float:x, &Float:y, &Float:z); +native physics_force (part_id, Float:x, Float:y, Float:z); +native physics_forces_get (part_id, &Float:x, &Float:y, &Float:z); +native physics_forces_clear (part_id); diff --git a/legacy/edje/src/bin/edje_cc_handlers.c b/legacy/edje/src/bin/edje_cc_handlers.c index 15f2ae7489..714c70c84a 100644 --- a/legacy/edje/src/bin/edje_cc_handlers.c +++ b/legacy/edje/src/bin/edje_cc_handlers.c @@ -8031,7 +8031,8 @@ st_collections_group_programs_program_in(void) Action to be performed by the program. Valid actions are: STATE_SET, ACTION_STOP, SIGNAL_EMIT, DRAG_VAL_SET, DRAG_VAL_STEP, DRAG_VAL_PAGE, FOCUS_SET, PARAM_COPY, PARAM_SET, PLAY_SAMPLE, PLAY_TONE, - PHYSICS_IMPULSE, PHYSICS_TORQUE_IMPULSE + PHYSICS_IMPULSE, PHYSICS_TORQUE_IMPULSE, PHYSICS_FORCE, PHYSICS_TORQUE, + PHYSICS_FORCES_CLEAR Only one action can be specified per program. Examples:\n action: STATE_SET "statename" 0.5;\n action: ACTION_STOP;\n @@ -8047,6 +8048,9 @@ st_collections_group_programs_program_in(void) action: PLAY_TONE "tone name" duration in seconds ( Range 0.1 to 10.0 );\n action: PHYSICS_IMPULSE 10 -23.4 0;\n action: PHYSICS_TORQUE_IMPULSE 0 2.1 0.95;\n + action: PHYSICS_FORCE -20.8 0 30.85;\n + action: PHYSICS_TORQUE 0 0 4.8;\n + action: PHYSICS_FORCES_CLEAR;\n @endproperty */ static void @@ -8075,6 +8079,10 @@ st_collections_group_programs_program_action(void) "PHYSICS_IMPULSE", EDJE_ACTION_TYPE_PHYSICS_IMPULSE, "PHYSICS_TORQUE_IMPULSE", EDJE_ACTION_TYPE_PHYSICS_TORQUE_IMPULSE, + "PHYSICS_FORCE", EDJE_ACTION_TYPE_PHYSICS_FORCE, + "PHYSICS_TORQUE", EDJE_ACTION_TYPE_PHYSICS_TORQUE, + "PHYSICS_FORCES_CLEAR", + EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR, NULL); if (ep->action == EDJE_ACTION_TYPE_STATE_SET) { @@ -8162,7 +8170,9 @@ st_collections_group_programs_program_action(void) } #ifdef HAVE_EPHYSICS else if ((ep->action == EDJE_ACTION_TYPE_PHYSICS_IMPULSE) || - (ep->action == EDJE_ACTION_TYPE_PHYSICS_TORQUE_IMPULSE)) + (ep->action == EDJE_ACTION_TYPE_PHYSICS_TORQUE_IMPULSE) || + (ep->action == EDJE_ACTION_TYPE_PHYSICS_FORCE) || + (ep->action == EDJE_ACTION_TYPE_PHYSICS_TORQUE)) { ep->physics.x = parse_float(1); ep->physics.y = parse_float(2); @@ -8197,8 +8207,13 @@ st_collections_group_programs_program_action(void) break; case EDJE_ACTION_TYPE_PHYSICS_IMPULSE: case EDJE_ACTION_TYPE_PHYSICS_TORQUE_IMPULSE: + case EDJE_ACTION_TYPE_PHYSICS_FORCE: + case EDJE_ACTION_TYPE_PHYSICS_TORQUE: check_arg_count(4); break; + case EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR: + check_arg_count(1); + break; default: check_arg_count(3); } @@ -8395,6 +8410,9 @@ st_collections_group_programs_program_target(void) #ifdef HAVE_EPHYSICS case EDJE_ACTION_TYPE_PHYSICS_IMPULSE: case EDJE_ACTION_TYPE_PHYSICS_TORQUE_IMPULSE: + case EDJE_ACTION_TYPE_PHYSICS_FORCE: + case EDJE_ACTION_TYPE_PHYSICS_TORQUE: + case EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR: #endif data_queue_part_lookup(pc, name, &(et->id)); break; diff --git a/legacy/edje/src/examples/physics_actions.edc b/legacy/edje/src/examples/physics_actions.edc index 9274ed698f..0b49439f18 100644 --- a/legacy/edje/src/examples/physics_actions.edc +++ b/legacy/edje/src/examples/physics_actions.edc @@ -1,19 +1,43 @@ /* It can be tested with edje_player slave mode - * $ edje_player -S physics_actions.edj + * $ edje_player -S -p physics_actions.edj * * signal up impulse -> will throw both balls up * signal left impulse -> will throw blue ball to the left * signal clockwise impulse -> will roll blue ball in clockwise * signal counterclockwise impulse -> will roll blue ball in counterclockwise + * signal up force -> will apply a force up in blue ball + * signal down force -> will apply a force down in blue ball + * signal left force -> will apply a force left in blue ball + * signal right force -> will apply a force right in blue ball + * signal clockwise torque -> will apply a clockwise torque in blue ball + * signal counterclockwise torque -> will apply a counterclockwise torque + * in blue ball + * signal clear force -> will clear all forces applied over blue ball * * message 1 FLOAT_SET 3 50 -100 0 -> apply an impulse on blue ball with * x = 50, y = -100, z = 0, for example * message 2 FLOAT_SET 3 0 0 8.2 -> apply a torque impulse on blue ball with * x = 4, y = 0, z = 0.8, for example + * message 3 FLOAT_SET 3 80 100.4 0 -> apply a force on blue ball with + * x = 80, y = 100.4, z = 0, for example + * message 4 FLOAT_SET 3 0 0 -5.6 -> apply a torque on blue ball with + * x = 0, y = 0, z = -5.6, for example + * message 5 STRING "blue_circle" -> clear all forces of part. + * It will clear all forces (linear and torque) over "blue_circle", + * for example. + * message 6 STRING "blue_circle" -> return a message with all forces applied + * over the part. + * message 7 STRING "blue_circle" -> return a message with all torques applied + * over the part. */ #define ID_IMPULSE (1) #define ID_TORQUE_IMPULSE (2) +#define ID_FORCE (3) +#define ID_TORQUE (4) +#define ID_FORCES_CLEAR (5) +#define ID_FORCES_GET (6) +#define ID_TORQUES_GET (7) collections { @@ -44,6 +68,49 @@ collections { z = getfarg(4); physics_torque_impulse(PART:"blue_circle", x, y, z); } + else if ((id == ID_FORCE) && (type == MSG_FLOAT_SET)) { + new Float:x, Float:y, Float:z; + new n = numargs(); + if (n < 5) return; + x = getfarg(2); + y = getfarg(3); + z = getfarg(4); + physics_force(PART:"blue_circle", x, y, z); + } + else if ((id == ID_TORQUE) && (type == MSG_FLOAT_SET)) { + new Float:x, Float:y, Float:z; + new n = numargs(); + if (n < 5) return; + x = getfarg(2); + y = getfarg(3); + z = getfarg(4); + physics_torque(PART:"blue_circle", x, y, z); + } + else if ((id == ID_FORCES_CLEAR) && (type == MSG_STRING)) { + new pid, name[1024]; + getsarg(2, name, sizeof(name)); + pid = get_part_id(name); + if (!pid) return; + physics_forces_clear(pid); + } + else if ((id == ID_FORCES_GET) && (type == MSG_STRING)) { + new Float:x, Float:y, Float:z; + new pid, name[1024]; + getsarg(2, name, sizeof(name)); + pid = get_part_id(name); + if (!pid) return; + physics_forces_get(pid, x, y, z); + send_message(MSG_FLOAT_SET, id, x, y, z); + } + else if ((id == ID_TORQUES_GET) && (type == MSG_STRING)) { + new Float:x, Float:y, Float:z; + new pid, name[1024]; + getsarg(2, name, sizeof(name)); + pid = get_part_id(name); + if (!pid) return; + physics_torques_get(pid, x, y, z); + send_message(MSG_FLOAT_SET, id, x, y, z); + } } } @@ -205,6 +272,62 @@ collections { target: "blue_circle"; } + program { + name: "force_up"; + signal: "up"; + source: "force"; + action: PHYSICS_FORCE 0 -300 0; + target: "blue_circle"; + } + + program { + name: "force_down"; + signal: "down"; + source: "force"; + action: PHYSICS_FORCE 0 300 0; + target: "blue_circle"; + } + + program { + name: "force_left"; + signal: "left"; + source: "force"; + action: PHYSICS_FORCE -300 0 0; + target: "blue_circle"; + } + + program { + name: "force_right"; + signal: "right"; + source: "force"; + action: PHYSICS_FORCE 300 0 0; + target: "blue_circle"; + } + + program { + name: "torque_clockwise"; + signal: "clockwise"; + source: "torque"; + action: PHYSICS_TORQUE 0 0 4; + target: "blue_circle"; + } + + program { + name: "torque_counterclockwise"; + signal: "counterclockwise"; + source: "torque"; + action: PHYSICS_TORQUE 0 0 -4; + target: "blue_circle"; + } + + program { + name: "forces_clear"; + signal: "clear"; + source: "force"; + action: PHYSICS_FORCES_CLEAR; + target: "blue_circle"; + } + } } diff --git a/legacy/edje/src/lib/Edje.h b/legacy/edje/src/lib/Edje.h index b11a9db472..482e192929 100644 --- a/legacy/edje/src/lib/Edje.h +++ b/legacy/edje/src/lib/Edje.h @@ -4157,7 +4157,10 @@ typedef enum _Edje_Action_Type EDJE_ACTION_TYPE_SOUND_TONE = 14, /**< @since 1.1 */ EDJE_ACTION_TYPE_PHYSICS_IMPULSE = 15, /**< @since 1.8 */ EDJE_ACTION_TYPE_PHYSICS_TORQUE_IMPULSE = 16, /**< @since 1.8 */ - EDJE_ACTION_TYPE_LAST = 17 + EDJE_ACTION_TYPE_PHYSICS_FORCE = 17, /**< @since 1.8 */ + EDJE_ACTION_TYPE_PHYSICS_TORQUE = 18, /**< @since 1.8 */ + EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR = 19, /**< @since 1.8 */ + EDJE_ACTION_TYPE_LAST = 20 } Edje_Action_Type; /** diff --git a/legacy/edje/src/lib/edje_embryo.c b/legacy/edje/src/lib/edje_embryo.c index 0f7356d0ce..985b72184f 100644 --- a/legacy/edje/src/lib/edje_embryo.c +++ b/legacy/edje/src/lib/edje_embryo.c @@ -202,6 +202,11 @@ * * physics_impulse(part_id, Float:x, Float:y, Float:z) * physics_torque_impulse(part_id, Float:x, Float:y, Float:z) + * physics_force(part_id, Float:x, Float:y, Float:z) + * physics_torque(part_id, Float:x, Float:y, Float:z) + * physics_forces_clear(part_id) + * physics_forces_get(part_id, &Float:x, &Float:y, &Float:z) + * physics_torques_get(part_id, &Float:x, &Float:y, &Float:z) * * ADD/DEL CUSTOM OBJECTS UNDER SOLE EMBRYO SCRIPT CONTROL * @@ -3094,6 +3099,147 @@ _edje_embryo_fn_physics_torque_impulse(Embryo_Program *ep, Embryo_Cell *params) } return 0; } + +/* physics_force(part_id, Float:x, Float:y, Float:z) */ +static Embryo_Cell +_edje_embryo_fn_physics_force(Embryo_Program *ep, Embryo_Cell *params) +{ + Edje_Real_Part *rp; + int part_id = 0; + Edje *ed; + + CHKPARAM(4); + + ed = embryo_program_data_get(ep); + part_id = params[1]; + if (part_id < 0) return 0; + + rp = ed->table_parts[part_id % ed->table_parts_size]; + if (rp) + { + if (rp->body) + { + double x, y, z; + + x = (double) EMBRYO_CELL_TO_FLOAT(params[2]); + y = (double) EMBRYO_CELL_TO_FLOAT(params[3]); + z = (double) EMBRYO_CELL_TO_FLOAT(params[4]); + + ephysics_body_central_force_apply(rp->body, x, y, z); + } + } + return 0; +} + +/* physics_torque(part_id, Float:x, Float:y, Float:z) */ +static Embryo_Cell +_edje_embryo_fn_physics_torque(Embryo_Program *ep, Embryo_Cell *params) +{ + Edje_Real_Part *rp; + int part_id = 0; + Edje *ed; + + CHKPARAM(4); + + ed = embryo_program_data_get(ep); + part_id = params[1]; + if (part_id < 0) return 0; + + rp = ed->table_parts[part_id % ed->table_parts_size]; + if (rp) + { + if (rp->body) + { + double x, y, z; + + x = (double) EMBRYO_CELL_TO_FLOAT(params[2]); + y = (double) EMBRYO_CELL_TO_FLOAT(params[3]); + z = (double) EMBRYO_CELL_TO_FLOAT(params[4]); + + ephysics_body_torque_apply(rp->body, x, y, z); + } + } + return 0; +} + +/* physics_forces_clear(part_id) */ +static Embryo_Cell +_edje_embryo_fn_physics_forces_clear(Embryo_Program *ep, Embryo_Cell *params) +{ + Edje_Real_Part *rp; + int part_id = 0; + Edje *ed; + + CHKPARAM(1); + + ed = embryo_program_data_get(ep); + part_id = params[1]; + if (part_id < 0) return 0; + + rp = ed->table_parts[part_id % ed->table_parts_size]; + if ((rp) && (rp->body)) + ephysics_body_forces_clear(rp->body); + + return 0; +} + +/* physics_forces_get(part_id, &Float:x, &Float:y, &Float:z) */ +static Embryo_Cell +_edje_embryo_fn_physics_forces_get(Embryo_Program *ep, Embryo_Cell *params) +{ + Edje_Real_Part *rp; + int part_id = 0; + Edje *ed; + + CHKPARAM(4); + + ed = embryo_program_data_get(ep); + part_id = params[1]; + if (part_id < 0) return 0; + + rp = ed->table_parts[part_id % ed->table_parts_size]; + if (rp) + { + if (rp->body) + { + double x, y, z; + ephysics_body_forces_get(rp->body, &x, &y, &z); + SETFLOAT(x, params[2]); + SETFLOAT(y, params[3]); + SETFLOAT(z, params[4]); + } + } + return 0; +} + +/* physics_torques_get(part_id, &Float:x, &Float:y, &Float:z) */ +static Embryo_Cell +_edje_embryo_fn_physics_torques_get(Embryo_Program *ep, Embryo_Cell *params) +{ + Edje_Real_Part *rp; + int part_id = 0; + Edje *ed; + + CHKPARAM(4); + + ed = embryo_program_data_get(ep); + part_id = params[1]; + if (part_id < 0) return 0; + + rp = ed->table_parts[part_id % ed->table_parts_size]; + if (rp) + { + if (rp->body) + { + double x, y, z; + ephysics_body_torques_get(rp->body, &x, &y, &z); + SETFLOAT(x, params[2]); + SETFLOAT(y, params[3]); + SETFLOAT(z, params[4]); + } + } + return 0; +} #endif void @@ -3194,6 +3340,11 @@ _edje_embryo_script_init(Edje_Part_Collection *edc) #ifdef HAVE_EPHYSICS embryo_program_native_call_add(ep, "physics_impulse", _edje_embryo_fn_physics_impulse); embryo_program_native_call_add(ep, "physics_torque_impulse", _edje_embryo_fn_physics_torque_impulse); + embryo_program_native_call_add(ep, "physics_force", _edje_embryo_fn_physics_force); + embryo_program_native_call_add(ep, "physics_torque", _edje_embryo_fn_physics_torque); + embryo_program_native_call_add(ep, "physics_forces_clear", _edje_embryo_fn_physics_forces_clear); + embryo_program_native_call_add(ep, "physics_forces_get", _edje_embryo_fn_physics_forces_get); + embryo_program_native_call_add(ep, "physics_torques_get", _edje_embryo_fn_physics_torques_get); #endif } diff --git a/legacy/edje/src/lib/edje_program.c b/legacy/edje/src/lib/edje_program.c index b9962a8353..5d57a0a792 100644 --- a/legacy/edje/src/lib/edje_program.c +++ b/legacy/edje/src/lib/edje_program.c @@ -962,6 +962,47 @@ _edje_program_run(Edje *ed, Edje_Program *pr, Eina_Bool force, const char *ssig, } } break; + case EDJE_ACTION_TYPE_PHYSICS_FORCE: + if (_edje_block_break(ed)) + goto break_prog; + EINA_LIST_FOREACH(pr->targets, l, pt) + { + if (pt->id >= 0) + { + rp = ed->table_parts[pt->id % ed->table_parts_size]; + if ((rp) && (rp->body)) + ephysics_body_central_force_apply( + rp->body, pr->physics.x, pr->physics.y, pr->physics.z); + } + } + break; + case EDJE_ACTION_TYPE_PHYSICS_TORQUE: + if (_edje_block_break(ed)) + goto break_prog; + EINA_LIST_FOREACH(pr->targets, l, pt) + { + if (pt->id >= 0) + { + rp = ed->table_parts[pt->id % ed->table_parts_size]; + if ((rp) && (rp->body)) + ephysics_body_torque_apply( + rp->body, pr->physics.x, pr->physics.y, pr->physics.z); + } + } + break; + case EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR: + if (_edje_block_break(ed)) + goto break_prog; + EINA_LIST_FOREACH(pr->targets, l, pt) + { + if (pt->id >= 0) + { + rp = ed->table_parts[pt->id % ed->table_parts_size]; + if ((rp) && (rp->body)) + ephysics_body_forces_clear(rp->body); + } + } + break; #endif default: // _edje_emit(ed, "program,start", pr->name);