EPhysics: implement body move(), resize()
authorBruno Dilly <bdilly@profusion.mobi>
Mon, 20 Aug 2012 22:10:52 +0000 (22:10 +0000)
committerBruno Dilly <bdilly@profusion.mobi>
Mon, 20 Aug 2012 22:10:52 +0000 (22:10 +0000)
It was already possible to move and resize using geometry get / set,
but if just one of the actions is wanted, this new API is easier for the user
and save a few operations.

SVN revision: 75471

legacy/ephysics/src/bin/ephysics_logo.c
legacy/ephysics/src/bin/test_win_resize.c
legacy/ephysics/src/lib/EPhysics.h
legacy/ephysics/src/lib/ephysics_body.cpp

index 9350372..8c4a178 100644 (file)
@@ -102,7 +102,7 @@ _update_circle_cb(void *data __UNUSED__, EPhysics_Body *body, void *event_info)
    evas_object_color_set(shadow, alpha, alpha, alpha, alpha);
 
    if (x > E_THRESHOLD)
-     ephysics_body_geometry_set(body, -w - 1, y, w, h);
+     ephysics_body_move(body, -w - 1, y);
 }
 
 static void
index 9b93b8b..620b130 100644 (file)
@@ -22,10 +22,10 @@ _win_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_inf
 {
    Test_Data *test_data = data;
    EPhysics_Body *sphere_body;
-   int ww, wh, x, y, w, h;
    double ratew, rateh;
    Evas_Object *sphere;
    Old_Rate *old_rate;
+   int ww, wh, x, y;
 
    evas_object_geometry_get(obj, NULL, NULL, &ww, &wh);
    ratew = (double) ww / WIDTH;
@@ -59,11 +59,10 @@ _win_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_inf
    sphere_body = old_rate->body;
 
    sphere = ephysics_body_evas_object_get(sphere_body);
-   evas_object_geometry_get(sphere, &x, &y, &w, &h);
+   evas_object_geometry_get(sphere, &x, &y, NULL, NULL);
 
-   /* FIXME: add resize / move to API */
-   ephysics_body_geometry_set(sphere_body, x * (ratew / old_rate->w),
-                              y * (rateh / old_rate->h), 1, 1);
+   ephysics_body_move(sphere_body, x * (ratew / old_rate->w),
+                      y * (rateh / old_rate->h));
    evas_object_resize(sphere, 70 * ratew, 70 * rateh);
 
    old_rate->w = ratew;
index 52fb55c..5aef034 100644 (file)
@@ -1170,7 +1170,8 @@ EAPI void ephysics_world_simulation_get(const EPhysics_World *world, double *fix
  *
  * Bodies can have different shapes that can be created with:
  * @li @ref ephysics_body_circle_add();
- * @li or @ref ephysics_body_box_add().
+ * @li @ref ephysics_body_box_add();
+ * @li or @ref ephysics_body_shape_add().
  *
  * They can collide and have customizable properties, like:
  * @li mass, set with @ref ephysics_body_mass_set();
@@ -1178,12 +1179,14 @@ EAPI void ephysics_world_simulation_get(const EPhysics_World *world, double *fix
  * @ref ephysics_body_restitution_set();
  * @li and friction, set with @ref ephysics_body_friction_set().
  *
- * Bodies can have its position and size directly set by
+ * Bodies can have its position and size directly set by:
+ * @ref ephysics_body_move();
+ * @ref ephysics_body_resize();
  * @ref ephysics_body_geometry_set().
  *
  * Also, they can have an associated evas object, done with
- * @ref ephysics_body_evas_object_set() function, being responsible for updating
- * its position and rotation, or letting a user callback be set
+ * @ref ephysics_body_evas_object_set() function, being responsible for
+ * updating its position and rotation, or letting a user callback be set
  * for this task with @ref ephysics_body_event_callback_add().
  *
  * Also, bodies can have impulses applied over them, and will be affected
@@ -1475,29 +1478,94 @@ EAPI Evas_Object *ephysics_body_evas_object_get(const EPhysics_Body *body);
 
 /**
  * @brief
+ * Set physics body size.
+ *
+ * All the physics bodies are and with canonical dimensions.
+ * Circles have diameter 1, boxes have dimensions 1
+ * on all the axises.
+ *
+ * There are three direct ways of modifying it's size:
+ * @li With @ref ephysics_body_resize();
+ * @li With @ref ephysics_body_geometry_set();
+ * @li When associating an evas object with
+ * @ref ephysics_body_evas_object_set().
+ *
+ * @note The unit used for size is Evas coordinates.
+ *
+ * @param body The body to be resized.
+ * @param w The body width, in pixels.
+ * @param h The body height, in pixels.
+ *
+ * @see ephysics_body_geometry_get().
+ * @see ephysics_body_geometry_set().
+ * @see ephysics_body_move().
+ *
+ * @ingroup EPhysics_Body
+ */
+EAPI void ephysics_body_resize(EPhysics_Body *body, Evas_Coord w, Evas_Coord h);
+
+/**
+ * @brief
+ * Set physics body position.
+ *
+ * All the physics bodies are created centered on origin (0, 0).
+ *
+ * There are three direct ways of modifying this position:
+ * @li With @ref ephysics_body_move();
+ * @li With @ref ephysics_body_geometry_set();
+ * @li When associating an evas object with
+ * @ref ephysics_body_evas_object_set().
+ *
+ * When the world is simulated forces will be applied on objects
+ * with mass and position will be modified too.
+ *
+ * @note The unit used for position is Evas coordinates.
+ *
+ * @param body The body to be positioned.
+ * @param x The position on axis x, in pixels.
+ * @param y The position on axis y, in pixels.
+ *
+ * @see ephysics_body_geometry_get().
+ * @see ephysics_body_geometry_set().
+ * @see ephysics_body_resize().
+ *
+ * @ingroup EPhysics_Body
+ */
+EAPI void ephysics_body_move(EPhysics_Body *body, Evas_Coord x, Evas_Coord y);
+
+/**
+ * @brief
  * Set physics body geometry.
  *
  * All the physics bodies are created centered on origin (0, 0) and with
  * canonical dimensions. Circles have diameter 1, boxes have dimensions 1
  * on all the axises.
  *
- * There are two direct ways of modifying this geometry:
+ * There are four direct ways of modifying this geometry:
  * @li With @ref ephysics_body_geometry_set();
+ * @li With @ref ephysics_body_move();
+ * @li With @ref ephysics_body_resize();
  * @li When associating an evas object with
  * @ref ephysics_body_evas_object_set().
  *
+ * If you just need to move the body, no changes are required to it's size,
+ * use @ref ephysics_body_move(). If you just need to modify the size of
+ * @p body use @ref ephysics_body_resize().
+ *
  * When the world is simulated forces will be applied on objects
  * with mass and position will be modified too.
  *
  * @note The unit used for geometry is Evas coordinates.
  *
- * @param body The body to be positioned.
+ * @param body The body to be modified.
  * @param x The position on axis x, in pixels.
  * @param y The position on axis y, in pixels.
  * @param w The body width, in pixels.
  * @param h The body height, in pixels.
  *
  * @see ephysics_body_geometry_get().
+ * @see ephysics_body_move().
+ * @see ephysics_body_resize().
  *
  * @ingroup EPhysics_Body
  */
@@ -1514,6 +1582,8 @@ EAPI void ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coo
  * @param h The body height, in pixels.
  *
  * @see ephysics_body_geometry_set() for more details.
+ * @see ephysics_body_move().
+ * @see ephysics_body_resize().
  *
  * @ingroup EPhysics_Body
  */
index 828b2eb..e4aedbf 100644 (file)
@@ -269,6 +269,52 @@ _ephysics_body_evas_obj_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj
 }
 
 static void
+_ephysics_body_resize(EPhysics_Body *body, Evas_Coord w, Evas_Coord h)
+{
+   double rate, sx, sy;
+
+   rate = ephysics_world_rate_get(body->world);
+   sx = w / rate;
+   sy = h / rate;
+
+   body->collision_shape->setLocalScaling(btVector3(sx, sy, 1));
+
+   if(!body->rigid_body->isStaticObject())
+      ephysics_body_mass_set(body, ephysics_body_mass_get(body));
+
+   body->w = w;
+   body->h = h;
+
+   body->rigid_body->activate(1);
+
+   DBG("Body %p scale changed to %lf, %lf.", body, sx, sy);
+}
+
+static void
+_ephysics_body_move(EPhysics_Body *body, Evas_Coord x, Evas_Coord y)
+{
+   double rate, mx, my;
+   btTransform trans;
+   int wy, height;
+
+   rate = ephysics_world_rate_get(body->world);
+   ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, &height);
+   height += wy;
+
+   mx = (x + body->w / 2) / rate;
+   my = (height - (y + body->h / 2)) / rate;
+
+   body->rigid_body->getMotionState()->getWorldTransform(trans);
+   trans.setOrigin(btVector3(mx, my, 0));
+   body->rigid_body->proceedToTransform(trans);
+   body->rigid_body->getMotionState()->setWorldTransform(trans);
+
+   body->rigid_body->activate(1);
+
+   DBG("Body %p position changed to %lf, %lf.", body, mx, my);
+}
+
+static void
 _ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, double rate)
 {
    double mx, my, sx, sy;
@@ -307,16 +353,14 @@ static void
 _ephysics_body_evas_obj_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
 {
    EPhysics_Body *body = (EPhysics_Body *) data;
-   int x, y, w, h;
+   int w, h;
 
    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
    if ((w == body->w) && (h == body->h))
      return;
 
    DBG("Resizing body %p to w=%i, h=%i", body, w, h);
-   ephysics_body_geometry_get(body, &x, &y, NULL, NULL);
-   _ephysics_body_geometry_set(body, x, y, w, h,
-                               ephysics_world_rate_get(body->world));
+   _ephysics_body_resize(body, w, h);
 }
 
 static void
@@ -782,7 +826,7 @@ ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Evas
 {
    if (!body)
      {
-        ERR("Can't set body position, body is null.");
+        ERR("Can't set body geometry, body is null.");
         return;
      }
 
@@ -797,6 +841,36 @@ ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Evas
 }
 
 EAPI void
+ephysics_body_resize(EPhysics_Body *body, Evas_Coord w, Evas_Coord h)
+{
+   if (!body)
+     {
+        ERR("Can't set body size, body is null.");
+        return;
+     }
+
+   if ((w <= 0) || (h <= 0))
+     {
+        ERR("Width and height must to be a non-null, positive value.");
+        return;
+     }
+
+   _ephysics_body_resize(body, w, h);
+}
+
+EAPI void
+ephysics_body_move(EPhysics_Body *body, Evas_Coord x, Evas_Coord y)
+{
+   if (!body)
+     {
+        ERR("Can't set body position, body is null.");
+        return;
+     }
+
+   _ephysics_body_move(body, x, y);
+}
+
+EAPI void
 ephysics_body_geometry_get(const EPhysics_Body *body, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
 {
    btTransform trans;