EPhysics: body collision data
This patch introduces a wrapper(EPhysics_Body_Collision) to hold the collision data(the contact body and collision position). This data type is used by EPHYSICS_CALLBACK_BODY_COLLISION callback. The collision detection test is migrated to the new API as well. Patch by: Leandro Dorileo <dorileo@profusion.mobi> SVN revision: 74500
This commit is contained in:
parent
34734a4a72
commit
6a2d290fce
|
@ -14,19 +14,20 @@ struct _Collision_Data {
|
|||
};
|
||||
|
||||
static void
|
||||
_collision_cb(void *data, EPhysics_Body *body __UNUSED__, void *event_info __UNUSED__)
|
||||
_collision_cb(void *data, EPhysics_Body *body __UNUSED__, void *event_info)
|
||||
{
|
||||
EPhysics_Body *contact_body;
|
||||
Collision_Data *collision_data = data;
|
||||
Evas_Object *obj;
|
||||
int x;
|
||||
EPhysics_Body_Collision *collision = event_info;
|
||||
int x, y;
|
||||
|
||||
if (event_info != collision_data->sphere2) return;
|
||||
contact_body = ephysics_body_collision_contact_body_get(collision);
|
||||
if (contact_body != collision_data->sphere2) return;
|
||||
|
||||
ephysics_body_collision_position_get(collision, &x, &y);
|
||||
INF("Collision Detected");
|
||||
|
||||
obj = ephysics_body_evas_object_get(collision_data->sphere);
|
||||
evas_object_geometry_get(obj, &x, NULL, NULL, NULL);
|
||||
evas_object_move(collision_data->impact, x - 4, FLOOR_Y - 80);
|
||||
evas_object_move(collision_data->impact, x, y);
|
||||
elm_object_signal_emit(collision_data->impact, "impact,show",
|
||||
"ephysics_test");
|
||||
}
|
||||
|
|
|
@ -922,6 +922,24 @@ EAPI Eina_Bool ephysics_world_bodies_outside_left_autodel_get(const EPhysics_Wor
|
|||
|
||||
typedef struct _EPhysics_Body EPhysics_Body; /**< Body handle, represents an object on EPhysics world. Created with @ref ephysics_body_circle_add() or @ref ephysics_body_box_add() and deleted with @ref ephysics_body_del(). */
|
||||
|
||||
/**
|
||||
* @typedef EPhysics_Body_Collision
|
||||
*
|
||||
* Body collision wraps collision informations.
|
||||
*
|
||||
* EPhysics_Body_Collision is used on EPHYSICS_CALLBACK_BODY_COLLISION callback
|
||||
* and is mostly interested to hold informations like:
|
||||
* @li contact_body - the body which the collision occurred against;
|
||||
* @li position - points the position where the collision happened;
|
||||
*
|
||||
* @see ephysics_body_collision_position_get()
|
||||
* @see ephysics_body_collision_contact_body_get()
|
||||
* @see EPHYSICS_CALLBACK_BODY_COLLISION and @ref
|
||||
* ephysics_body_event_callback_add() for collision callback.
|
||||
* @ingroup EPhysics_Body
|
||||
*/
|
||||
typedef struct _EPhysics_Body_Collision EPhysics_Body_Collision;
|
||||
|
||||
/**
|
||||
* @enum _EPhysics_Callback_Body_Type
|
||||
* @typedef EPhysics_Callback_Body_Type
|
||||
|
@ -1504,12 +1522,25 @@ EAPI void ephysics_body_evas_object_update(EPhysics_Body *body);
|
|||
*
|
||||
* Update callbacks receives evas object set to body as event_info argument.
|
||||
*
|
||||
* Regarding EPHYSICS_CALLBACK_BODY_COLLISION:
|
||||
* What follows is a list of details about each callback type:
|
||||
*
|
||||
* Callbacks are called just after the collision has been actually processed
|
||||
* by the physics engine.
|
||||
* - #EPHYSICS_CALLBACK_BODY_UPDATE: Called after every physics iteration. @p
|
||||
* body points to the EPhysics_Body itself and @p event_info points to the
|
||||
* evas object associated to the body.
|
||||
*
|
||||
* The other body involved in the collision is passed as event_info argument.
|
||||
* - #EPHYSICS_CALLBACK_BODY_COLLISION: Called just after the collision has
|
||||
* been actually processed by the physics engine. The body involved in the
|
||||
* collision is passed as @p body argument. @p event_info is a pointer to
|
||||
* @ref EPhysics_Body_Collision - note, this structure(@p event_info) is
|
||||
* discarded/freed right after callback returns.
|
||||
*
|
||||
* - #EPHYSICS_CALLBACK_BODY_DEL: Called when a body deletion has been issued
|
||||
* and just before the deletion actually happens. @p body points to the body
|
||||
* being deleted and no @p event_info is provided.
|
||||
*
|
||||
* - #EPHYSICS_CALLBACK_BODY_STOPPED: Called when a body is found to be
|
||||
* stopped. @p body points to the body of interest and @p event_info is a
|
||||
* pointer to the evas object associated to it.
|
||||
*
|
||||
* @param body The physics body.
|
||||
* @param type Type of callback to be listened by @p func.
|
||||
|
@ -1564,6 +1595,39 @@ EAPI void *ephysics_body_event_callback_del(EPhysics_Body *body, EPhysics_Callba
|
|||
*/
|
||||
EAPI void *ephysics_body_event_callback_del_full(EPhysics_Body *body, EPhysics_Callback_Body_Type type, EPhysics_Body_Event_Cb func, void *data);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Get the position(x, y) of a body's collision.
|
||||
*
|
||||
* Given a body collision data, fills @p x and @p y pointers with the position
|
||||
* where the collision occurred.
|
||||
*
|
||||
* @param collision The body collision data of interest.
|
||||
* @param x The x pointer to set the x coordinate to.
|
||||
* @param y The y pointer to set the y coordinate to.
|
||||
*
|
||||
* @see EPHYSICS_CALLBACK_BODY_COLLISION and @ref
|
||||
* ephysics_body_event_callback_add() for collision callback.
|
||||
* @ingroup EPhysics_Body
|
||||
*/
|
||||
EAPI void ephysics_body_collision_position_get(const EPhysics_Body_Collision *collision, Evas_Coord *x, Evas_Coord *y);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Get the body's collision contact body.
|
||||
*
|
||||
* Given a body collision data returns the contact body which a collision
|
||||
* occurred against.
|
||||
*
|
||||
* @param collision The body collision of interest.
|
||||
* @return The contact body of @p collision.
|
||||
*
|
||||
* @see EPHYSICS_CALLBACK_BODY_COLLISION and @ref
|
||||
* ephysics_body_event_callback_add() for collision callback.
|
||||
* @ingroup EPhysics_Body
|
||||
*/
|
||||
EAPI EPhysics_Body *ephysics_body_collision_contact_body_get(const EPhysics_Body_Collision *collision);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Set body's coefficient of restitution.
|
||||
|
|
|
@ -32,6 +32,12 @@ struct _EPhysics_Body {
|
|||
Eina_Bool active:1;
|
||||
};
|
||||
|
||||
struct _EPhysics_Body_Collision {
|
||||
EPhysics_Body *contact_body;
|
||||
Evas_Coord x;
|
||||
Evas_Coord y;
|
||||
};
|
||||
|
||||
void
|
||||
ephysics_body_active_set(EPhysics_Body *body, Eina_Bool active)
|
||||
{
|
||||
|
@ -237,10 +243,50 @@ ephysics_body_evas_object_update_select(EPhysics_Body *body)
|
|||
_ephysics_body_outside_render_area_check(body);
|
||||
}
|
||||
|
||||
static void
|
||||
ephysics_body_collision_set(EPhysics_Body_Collision *collision, EPhysics_Body *contact_body, btVector3 position)
|
||||
{
|
||||
double rate;
|
||||
int height;
|
||||
EPhysics_World *world = contact_body->world;
|
||||
|
||||
ephysics_world_render_geometry_get(world, NULL, NULL, NULL, &height);
|
||||
rate = ephysics_world_rate_get(world);
|
||||
collision->contact_body = contact_body;
|
||||
collision->x = position.getX() * rate;
|
||||
collision->y = height - (position.getY() * rate);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_body_collision_position_get(const EPhysics_Body_Collision *collision, Evas_Coord *x, Evas_Coord *y)
|
||||
{
|
||||
if (!collision)
|
||||
{
|
||||
ERR("Can't get body's collision data, collision is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (x) *x = collision->x;
|
||||
if (y) *y = collision->y;
|
||||
}
|
||||
|
||||
EAPI EPhysics_Body *
|
||||
ephysics_body_collision_contact_body_get(const EPhysics_Body_Collision *collision)
|
||||
{
|
||||
if (!collision)
|
||||
{
|
||||
ERR("Can't get body's collision contact body, collision is null.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return collision->contact_body;
|
||||
}
|
||||
|
||||
void
|
||||
ephysics_body_contact_processed(EPhysics_Body *body, EPhysics_Body *contact_body)
|
||||
ephysics_body_contact_processed(EPhysics_Body *body, EPhysics_Body *contact_body, btVector3 position)
|
||||
{
|
||||
EPhysics_Body_Callback *cb;
|
||||
EPhysics_Body_Collision *collision;
|
||||
|
||||
if ((!body) || (!contact_body))
|
||||
return;
|
||||
|
@ -248,7 +294,18 @@ ephysics_body_contact_processed(EPhysics_Body *body, EPhysics_Body *contact_body
|
|||
EINA_INLIST_FOREACH(body->callbacks, cb)
|
||||
{
|
||||
if (cb->type == EPHYSICS_CALLBACK_BODY_COLLISION)
|
||||
cb->func(cb->data, body, (void *) contact_body);
|
||||
{
|
||||
collision = (EPhysics_Body_Collision*)malloc(
|
||||
sizeof(EPhysics_Body_Collision));
|
||||
if (!collision)
|
||||
{
|
||||
ERR("Can't allocate collision data structure.");
|
||||
continue;
|
||||
}
|
||||
ephysics_body_collision_set(collision, contact_body, position);
|
||||
cb->func(cb->data, body, collision);
|
||||
free(collision);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ Eina_Bool ephysics_world_bodies_outside_autodel_get(const EPhysics_World *world)
|
|||
|
||||
void ephysics_body_evas_object_update_select(EPhysics_Body *body);
|
||||
void ephysics_orphan_body_del(EPhysics_Body *body);
|
||||
void ephysics_body_contact_processed(EPhysics_Body *body, EPhysics_Body *contact_body);
|
||||
void ephysics_body_contact_processed(EPhysics_Body *body, EPhysics_Body *contact_body, btVector3 position);
|
||||
btRigidBody *ephysics_body_rigid_body_get(const EPhysics_Body *body);
|
||||
void ephysics_body_active_set(EPhysics_Body *body, Eina_Bool active);
|
||||
|
||||
|
|
|
@ -123,8 +123,8 @@ _ephysics_world_contact_processed_cb(btManifoldPoint &cp, void *b0, void *b1)
|
|||
body_0 = (EPhysics_Body *) rigid_body_0->getUserPointer();
|
||||
body_1 = (EPhysics_Body *) rigid_body_1->getUserPointer();
|
||||
|
||||
ephysics_body_contact_processed(body_0, body_1);
|
||||
ephysics_body_contact_processed(body_1, body_0);
|
||||
ephysics_body_contact_processed(body_0, body_1, cp.getPositionWorldOnA());
|
||||
ephysics_body_contact_processed(body_1, body_0, cp.getPositionWorldOnB());
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue