edje: support forces using programs / script
authorBruno Dilly <bdilly@profusion.mobi>
Thu, 6 Dec 2012 19:20:07 +0000 (19:20 +0000)
committerBruno Dilly <bdilly@profusion.mobi>
Thu, 6 Dec 2012 19:20:07 +0000 (19:20 +0000)
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
legacy/edje/src/bin/edje_cc_handlers.c
legacy/edje/src/examples/physics_actions.edc
legacy/edje/src/lib/Edje.h
legacy/edje/src/lib/edje_embryo.c
legacy/edje/src/lib/edje_program.c

index 93da20c..a358d58 100644 (file)
@@ -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);
index 15f2ae7..714c70c 100644 (file)
@@ -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;
index 9274ed6..0b49439 100644 (file)
@@ -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";
+         }
+
       }
 
    }
index b11a9db..482e192 100644 (file)
@@ -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;
 
 /**
index 0f7356d..985b721 100644 (file)
  *
  * 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
 }
 
index b9962a8..5d57a0a 100644 (file)
@@ -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);