EPhysics: implement body move(), resize()

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
This commit is contained in:
Bruno Dilly 2012-08-20 22:10:52 +00:00
parent 8b9e7449ec
commit df457b4645
4 changed files with 163 additions and 20 deletions

View 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

View 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;

View 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,13 +1478,40 @@ EAPI Evas_Object *ephysics_body_evas_object_get(const EPhysics_Body *body);
/**
* @brief
* Set physics body geometry.
* Set physics body size.
*
* All the physics bodies are created centered on origin (0, 0) and with
* canonical dimensions. Circles have diameter 1, boxes have dimensions 1
* All the physics bodies are 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 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().
@ -1489,15 +1519,53 @@ EAPI Evas_Object *ephysics_body_evas_object_get(const EPhysics_Body *body);
* 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.
* @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 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 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
*/

View File

@ -268,6 +268,52 @@ _ephysics_body_evas_obj_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj
DBG("Evas object deleted. Updating body: %p", 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)
{
@ -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;
}
@ -796,6 +840,36 @@ ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Evas
ephysics_world_rate_get(body->world));
}
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)
{