/* This example demostrates physics actions, like applying impulses and forces * to a body. * * There are two ways of interacting with bodies. One is using the wanted * action in a program. E.g.: * * action: PHYSICS_VEL_SET 0 -200 0; * target: "part_name"; * * The other way is via script. The same action described above would be * physics_set_velocity(PART:"part_name", 0, -200, 0); * * This a very extensive example, because it illustrate the usage of all * the possible actions in the both ways. * * It can be tested with edje_player slave mode * $ edje_player -S -p physics_actions.edj * * signal up impulse -> will throw both balls up * signal down impulse -> will throw both balls down * signal left impulse -> will throw blue ball to the left * signal right impulse -> will throw red ball to the right * 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 * signal up velocity -> will set a velocity up in blue ball * signal down velocity -> will set a velocity down in blue ball * signal left velocity -> will set a velocity left in blue ball * signal right velocity -> will set a velocity right in blue ball * signal clockwise velocity -> will set a clockwise velocity in blue ball * signal counterclockwise velocity -> will set a counterclockwise velocity * in blue ball * signal stop velocity -> will stop the blue ball * signal clockwise rotation -> will rotate blue ball 90o degrees clockwise * signal counterclockwise rotation -> will rotate blue ball 90o degrees * counterclockwise * * 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. * message 8 FLOAT_SET 3 300 -103.2 0 -> set linear velocity of the blue ball * with x = 300, y = -103.2, z = 150, for example * message 9 STRING "blue_circle" -> return a message with part's linear * velocity. * message 10 FLOAT_SET 3 0 0 150 -> set angular velocity of the blue ball * with x = 0, y = 0, z = 150, for example * message 11 STRING "blue_circle" -> return a message with part's angular * velocity. * message 12 STRING "blue_circle" -> stop the part. * message 13 FLOAT_SET 4 0.707 0 0 0.707 -> set blue ball rotation with * quaternion w = 0.707, x = 0, y = 0, z = 0.707 * message 14 STRING "blue_circle" -> return a message with part's rotation */ #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) #define ID_VEL_SET (8) #define ID_VEL_GET (9) #define ID_ANG_VEL_SET (10) #define ID_ANG_VEL_GET (11) #define ID_STOP (12) #define ID_ROT_SET (13) #define ID_ROT_GET (14) collections { images { image: "bubble-blue.png" COMP; } group { name: "example_group"; script { public message(Msg_Type:type, id, ...) { if ((id == ID_IMPULSE) && (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_impulse(PART:"blue_circle", x, y, z); } else if ((id == ID_TORQUE_IMPULSE) && (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_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_clear_forces(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_get_forces(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_get_torques(pid, x, y, z); send_message(MSG_FLOAT_SET, id, x, y, z); } else if ((id == ID_VEL_SET) && (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_set_velocity(PART:"blue_circle", x, y, z); } else if ((id == ID_VEL_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_get_velocity(pid, x, y, z); send_message(MSG_FLOAT_SET, id, x, y, z); } else if ((id == ID_ANG_VEL_SET) && (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_set_ang_velocity(PART:"blue_circle", x, y, z); } else if ((id == ID_ANG_VEL_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_get_ang_velocity(pid, x, y, z); send_message(MSG_FLOAT_SET, id, x, y, z); } else if ((id == ID_STOP) && (type == MSG_STRING)) { new pid, name[1024]; getsarg(2, name, sizeof(name)); pid = get_part_id(name); if (!pid) return; physics_stop(pid); } else if ((id == ID_ROT_SET) && (type == MSG_FLOAT_SET)) { new Float:w, Float:x, Float:y, Float:z; new n = numargs(); if (n < 6) return; w = getfarg(2); x = getfarg(3); y = getfarg(4); z = getfarg(5); physics_set_rotation(PART:"blue_circle", w, x, y, z); } else if ((id == ID_ROT_GET) && (type == MSG_STRING)) { new Float:w, Float:x, Float:y, Float:z; new pid, name[1024]; getsarg(2, name, sizeof(name)); pid = get_part_id(name); if (!pid) return; physics_get_rotation(pid, w, x, y, z); send_message(MSG_FLOAT_SET, id, w, x, y, z); } } } 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: "blue_circle"; type: IMAGE; physics_body: RIGID_SPHERE; description { state: "default" 0.0; rel1.relative: 0.35 0.1; rel2.relative: 0.55 0.2; aspect: 1 1; image { normal: "bubble-blue.png"; } physics { restitution: 0.85; friction: 1.0; } } } part { name: "red_circle"; type: IMAGE; physics_body: RIGID_SPHERE; description { state: "default" 0.0; color: 255 0 0 255; /* light red */ rel1.relative: 0.65 0.1; rel2.relative: 0.85 0.2; aspect: 1 1; image { normal: "bubble-blue.png"; } physics { restitution: 0.85; friction: 1.0; } } } part { name: "floor"; type: RECT; physics_body: BOUNDARY_BOTTOM; description { state: "default" 0.0; visible: 0; physics { restitution: 0.6; friction: 1.0; } } } part { name: "right_wall"; type: RECT; physics_body: BOUNDARY_RIGHT; description { state: "default" 0.0; visible: 0; physics { restitution: 0.3; } } } part { name: "left_wall"; type: RECT; physics_body: BOUNDARY_LEFT; description { state: "default" 0.0; visible: 0; physics { restitution: 0.3; } } } part { name: "roof"; type: RECT; physics_body: BOUNDARY_TOP; description { state: "default" 0.0; visible: 0; physics { restitution: 0.2; } } } } programs { program { name: "impulse_up"; signal: "up"; source: "impulse"; action: PHYSICS_IMPULSE 0 -300 0; target: "blue_circle"; target: "red_circle"; } program { name: "impulse_down"; signal: "down"; source: "impulse"; action: PHYSICS_IMPULSE 0 300 0; target: "red_circle"; target: "blue_circle"; } program { name: "impulse_left"; signal: "left"; source: "impulse"; action: PHYSICS_IMPULSE -300 0 0; target: "blue_circle"; } program { name: "impulse_right"; signal: "right"; source: "impulse"; action: PHYSICS_IMPULSE 300 0 0; target: "red_circle"; } program { name: "impulse_clockwise"; signal: "clockwise"; source: "impulse"; action: PHYSICS_TORQUE_IMPULSE 0 0 4; target: "blue_circle"; } program { name: "impulse_counterclockwise"; signal: "counterclockwise"; source: "impulse"; action: PHYSICS_TORQUE_IMPULSE 0 0 -4; 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"; } program { name: "velocity_up"; signal: "up"; source: "velocity"; action: PHYSICS_VEL_SET 0 -200 0; target: "blue_circle"; } program { name: "velocity_down"; signal: "down"; source: "velocity"; action: PHYSICS_VEL_SET 0 200 0; target: "blue_circle"; } program { name: "velocity_left"; signal: "left"; source: "velocity"; action: PHYSICS_VEL_SET -200 0 0; target: "blue_circle"; } program { name: "velocity_right"; signal: "right"; source: "velocity"; action: PHYSICS_VEL_SET 200 0 0; target: "blue_circle"; } program { name: "velocity_clockwise"; signal: "clockwise"; source: "velocity"; action: PHYSICS_ANG_VEL_SET 0 0 80; target: "blue_circle"; } program { name: "velocity_counterclockwise"; signal: "counterclockwise"; source: "velocity"; action: PHYSICS_ANG_VEL_SET 0 0 -80; target: "blue_circle"; } program { name: "stop"; signal: "stop"; source: "velocity"; action: PHYSICS_STOP; target: "blue_circle"; } program { name: "rotation_clockwise"; signal: "clockwise"; source: "rotation"; action: PHYSICS_ROT_SET 0.707 0 0 0.707; target: "blue_circle"; } program { name: "rotation_counterclockwise"; signal: "counterclockwise"; source: "rotation"; action: PHYSICS_ROT_SET 0.707 0 0 -0.707; target: "blue_circle"; } program { name: "customize"; signal: "custom"; script { new Float: mass, Float:rest, Float:fric; new Float: linear, Float:angular; new val; custom_state(PART:"red_circle", "default", 0.0); set_state_val(PART:"red_circle", STATE_COLOR, 0, 0, 0, 255); set_state_val(PART:"red_circle", STATE_PHYSICS_MASS, 4.5); set_state_val(PART:"red_circle", STATE_PHYSICS_RESTITUTION, 0.1); set_state_val(PART:"red_circle", STATE_PHYSICS_FRICTION, 0.345); set_state_val(PART:"red_circle", STATE_PHYSICS_DAMPING, 0.3, 0.1); set_state_val(PART:"red_circle", STATE_PHYSICS_SLEEP, 34.1, 12.83); set_state_val(PART:"red_circle", STATE_PHYSICS_LIGHT_ON, 1); set_state_val(PART:"red_circle", STATE_PHYSICS_IGNORE_PART_POS, 1); set_state_val(PART:"red_circle", STATE_PHYSICS_Z, -40); set_state_val(PART:"red_circle", STATE_PHYSICS_DEPTH, 80); set_state(PART:"red_circle", "custom", 0.0); get_state_val(PART:"red_circle", STATE_PHYSICS_MASS, mass); get_state_val(PART:"red_circle", STATE_PHYSICS_RESTITUTION, rest); get_state_val(PART:"red_circle", STATE_PHYSICS_FRICTION, fric); send_message(MSG_STRING_FLOAT_SET, 1, "Mass", mass); send_message(MSG_STRING_FLOAT_SET, 1, "Friction", fric); send_message(MSG_STRING_FLOAT_SET, 1, "Restitution", rest); get_state_val(PART:"red_circle", STATE_PHYSICS_DAMPING, linear, angular); send_message(MSG_STRING_FLOAT_SET, 1, "Damping", linear, angular); get_state_val(PART:"red_circle", STATE_PHYSICS_SLEEP, linear, angular); send_message(MSG_STRING_FLOAT_SET, 1, "Sleep", linear, angular); get_state_val(PART:"red_circle", STATE_PHYSICS_LIGHT_ON, val); send_message(MSG_STRING_INT, 1, "Light On", val); get_state_val(PART:"red_circle", STATE_PHYSICS_IGNORE_PART_POS, val); send_message(MSG_STRING_INT, 1, "Ignore Part Pos", val); get_state_val(PART:"red_circle", STATE_PHYSICS_Z, val); send_message(MSG_STRING_INT, 1, "Z", val); get_state_val(PART:"red_circle", STATE_PHYSICS_DEPTH, val); send_message(MSG_STRING_INT, 1, "Depth", val); } } } } }