{
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;
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;
*
* 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();
* @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
/**
* @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
*/
* @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
*/
}
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;
_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
{
if (!body)
{
- ERR("Can't set body position, body is null.");
+ ERR("Can't set body geometry, body is null.");
return;
}
}
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;