From df457b46458795a555974226b1842fe91c44a8d5 Mon Sep 17 00:00:00 2001 From: Bruno Dilly Date: Mon, 20 Aug 2012 22:10:52 +0000 Subject: [PATCH] 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 --- legacy/ephysics/src/bin/ephysics_logo.c | 2 +- legacy/ephysics/src/bin/test_win_resize.c | 9 ++- legacy/ephysics/src/lib/EPhysics.h | 88 ++++++++++++++++++++--- legacy/ephysics/src/lib/ephysics_body.cpp | 84 ++++++++++++++++++++-- 4 files changed, 163 insertions(+), 20 deletions(-) diff --git a/legacy/ephysics/src/bin/ephysics_logo.c b/legacy/ephysics/src/bin/ephysics_logo.c index 93503720aa..8c4a1789f5 100644 --- a/legacy/ephysics/src/bin/ephysics_logo.c +++ b/legacy/ephysics/src/bin/ephysics_logo.c @@ -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 diff --git a/legacy/ephysics/src/bin/test_win_resize.c b/legacy/ephysics/src/bin/test_win_resize.c index 9b93b8b110..620b130955 100644 --- a/legacy/ephysics/src/bin/test_win_resize.c +++ b/legacy/ephysics/src/bin/test_win_resize.c @@ -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; diff --git a/legacy/ephysics/src/lib/EPhysics.h b/legacy/ephysics/src/lib/EPhysics.h index 52fb55cafd..5aef0341d5 100644 --- a/legacy/ephysics/src/lib/EPhysics.h +++ b/legacy/ephysics/src/lib/EPhysics.h @@ -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 */ diff --git a/legacy/ephysics/src/lib/ephysics_body.cpp b/legacy/ephysics/src/lib/ephysics_body.cpp index 828b2eb56c..e4aedbfd3e 100644 --- a/legacy/ephysics/src/lib/ephysics_body.cpp +++ b/legacy/ephysics/src/lib/ephysics_body.cpp @@ -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) {