EPhysics: add soft ellipsoid and multi face
implementation This patch introduces the ellipsoid soft body and its multi face implementation. Patch by: Leandro Dorileo <dorileo@profusion.mobi> SVN revision: 79603
This commit is contained in:
parent
f36db0c84d
commit
0e3e700e52
|
@ -2386,6 +2386,28 @@ EAPI void ephysics_body_soft_body_dragging_unset(EPhysics_Body *body);
|
||||||
*/
|
*/
|
||||||
EAPI int ephysics_body_soft_body_triangle_index_get(EPhysics_Body *body, Evas_Coord x, Evas_Coord y);
|
EAPI int ephysics_body_soft_body_triangle_index_get(EPhysics_Body *body, Evas_Coord x, Evas_Coord y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Add a soft ellipsoid.
|
||||||
|
*
|
||||||
|
* Add a new soft 3d ellipsoid to the simulation. The @p granularity defines how
|
||||||
|
* many triangles are to be added.
|
||||||
|
*
|
||||||
|
* @note if no @p granularity is informed(i.e @p granularity = 0) the soft body
|
||||||
|
* will be created with a triangle mesh of 100.
|
||||||
|
*
|
||||||
|
* @param world The world the new soft ellipsoid is to be added.
|
||||||
|
* @param granularity How many triangles the soft body triangle mesh must have.
|
||||||
|
* @return a new body or @c NULL on errors.
|
||||||
|
*
|
||||||
|
* @see ephysics_body_del().
|
||||||
|
* @see ephysics_body_evas_object_set().
|
||||||
|
* @see ephysics_body_face_evas_object_set().
|
||||||
|
*
|
||||||
|
* @ingroup EPhysics_Body
|
||||||
|
*/
|
||||||
|
EAPI EPhysics_Body *ephysics_body_soft_ellipsoid_add(EPhysics_World *world, int granularity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* Apply an impulse on a given soft body triangle.
|
* Apply an impulse on a given soft body triangle.
|
||||||
|
|
|
@ -60,7 +60,7 @@ struct _EPhysics_Body_Face_Obj {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ephysics_body_soft_body_slices_apply(EPhysics_Body *body, Eina_List *slices)
|
_ephysics_body_soft_body_slices_apply(EPhysics_Body *body, Evas_Object *evas_obj, Eina_List *slices)
|
||||||
{
|
{
|
||||||
double rate;
|
double rate;
|
||||||
void *list_data;
|
void *list_data;
|
||||||
|
@ -81,7 +81,7 @@ _ephysics_body_soft_body_slices_apply(EPhysics_Body *body, Eina_List *slices)
|
||||||
rate = ephysics_world_rate_get(body->world);
|
rate = ephysics_world_rate_get(body->world);
|
||||||
ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, NULL, &wh,
|
ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, NULL, &wh,
|
||||||
NULL);
|
NULL);
|
||||||
evas_object_geometry_get(body->evas_obj, NULL, NULL, &w, &h);
|
evas_object_geometry_get(evas_obj, NULL, NULL, &w, &h);
|
||||||
|
|
||||||
if ((body->light_apply) ||
|
if ((body->light_apply) ||
|
||||||
(ephysics_world_light_all_bodies_get(body->world)))
|
(ephysics_world_light_all_bodies_get(body->world)))
|
||||||
|
@ -234,7 +234,7 @@ _ephysics_body_soft_body_slices_init(EPhysics_Body *body, Evas_Object *obj, Eina
|
||||||
if (slice)
|
if (slice)
|
||||||
evas_object_image_source_visible_set(slice->evas_obj, EINA_FALSE);
|
evas_object_image_source_visible_set(slice->evas_obj, EINA_FALSE);
|
||||||
|
|
||||||
_ephysics_body_soft_body_slices_apply(body, slices);
|
_ephysics_body_soft_body_slices_apply(body, obj, slices);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1096,16 +1096,55 @@ _ephysics_body_face_slice_add(EPhysics_Body *body, EPhysics_Body_Face face)
|
||||||
|
|
||||||
face_slice->face = face;
|
face_slice->face = face;
|
||||||
body->faces_slices = eina_list_append(body->faces_slices, face_slice);
|
body->faces_slices = eina_list_append(body->faces_slices, face_slice);
|
||||||
|
face_slice->body = body;
|
||||||
return face_slice;
|
return face_slice;
|
||||||
DBG("New face slice added to body %p", body);
|
DBG("New face slice added to body %p", body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EPhysics_Body_Face_Slice *
|
||||||
|
_ephysics_body_face_slice_get(EPhysics_Body *body, EPhysics_Body_Face face)
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
void *ldata;
|
||||||
|
EPhysics_Body_Face_Slice *face_slice = NULL;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(body->faces_slices, l, ldata)
|
||||||
|
{
|
||||||
|
if (((EPhysics_Body_Face_Slice *)ldata)->face == face)
|
||||||
|
{
|
||||||
|
face_slice = (EPhysics_Body_Face_Slice *)ldata;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return face_slice;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EPhysics_Body_Face_Obj *
|
||||||
|
_ephysics_body_face_evas_object_get(EPhysics_Body *body, EPhysics_Body_Face face)
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
void *ldata;
|
||||||
|
EPhysics_Body_Face_Obj *face_obj;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(body->face_objs, l, ldata)
|
||||||
|
{
|
||||||
|
face_obj = (EPhysics_Body_Face_Obj *)ldata;
|
||||||
|
if (face_obj->face == face)
|
||||||
|
return face_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG("Could not find requested face");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ephysics_body_del(EPhysics_Body *body)
|
_ephysics_body_del(EPhysics_Body *body)
|
||||||
{
|
{
|
||||||
EPhysics_Body_Callback *cb;
|
EPhysics_Body_Callback *cb;
|
||||||
|
void *ldata;
|
||||||
void *group;
|
void *group;
|
||||||
void *face_slice;
|
EPhysics_Body_Face_Slice *face_slice;
|
||||||
|
|
||||||
if (body->evas_obj)
|
if (body->evas_obj)
|
||||||
{
|
{
|
||||||
|
@ -1130,8 +1169,13 @@ _ephysics_body_del(EPhysics_Body *body)
|
||||||
EINA_LIST_FREE(body->collision_groups, group)
|
EINA_LIST_FREE(body->collision_groups, group)
|
||||||
eina_stringshare_del((Eina_Stringshare *)group);
|
eina_stringshare_del((Eina_Stringshare *)group);
|
||||||
|
|
||||||
EINA_LIST_FREE(body->faces_slices, face_slice)
|
EINA_LIST_FREE(body->faces_slices, ldata)
|
||||||
_ephysics_body_face_slice_del((EPhysics_Body_Face_Slice *)face_slice);
|
{
|
||||||
|
face_slice = (EPhysics_Body_Face_Slice *)ldata;
|
||||||
|
if (_ephysics_body_face_evas_object_get(body, face_slice->face))
|
||||||
|
ephysics_body_face_evas_object_unset(body, face_slice->face);
|
||||||
|
_ephysics_body_face_slice_del(face_slice);
|
||||||
|
}
|
||||||
|
|
||||||
if (body->rigid_body)
|
if (body->rigid_body)
|
||||||
{
|
{
|
||||||
|
@ -1402,7 +1446,7 @@ _ephysics_box_face_objs_update(EPhysics_Body *body)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ephysics_body_evas_object_default_update(EPhysics_Body *body)
|
_ephysics_body_evas_object_update(EPhysics_Body *body, Evas_Object *evas_obj)
|
||||||
{
|
{
|
||||||
int bx, by, x, y, z, w, h, wx, wy, wh, cx, cy;
|
int bx, by, x, y, z, w, h, wx, wy, wh, cx, cy;
|
||||||
EPhysics_Camera *camera;
|
EPhysics_Camera *camera;
|
||||||
|
@ -1410,24 +1454,6 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
|
||||||
btQuaternion quat;
|
btQuaternion quat;
|
||||||
Evas_Map *map;
|
Evas_Map *map;
|
||||||
double rate;
|
double rate;
|
||||||
Eina_List *l;
|
|
||||||
void *ldata;
|
|
||||||
|
|
||||||
if (body->face_objs)
|
|
||||||
{
|
|
||||||
if (body->type == EPHYSICS_BODY_TYPE_CLOTH)
|
|
||||||
_ephysics_cloth_face_objs_update(body);
|
|
||||||
else if (body->type == EPHYSICS_BODY_TYPE_RIGID)
|
|
||||||
{
|
|
||||||
if (body->shape == EPHYSICS_BODY_SHAPE_CYLINDER)
|
|
||||||
_ephysics_cylinder_face_objs_update(body);
|
|
||||||
else if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
|
|
||||||
_ephysics_box_face_objs_update(body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!body->evas_obj)
|
|
||||||
return;
|
|
||||||
|
|
||||||
trans = _ephysics_body_transform_get(body);
|
trans = _ephysics_body_transform_get(body);
|
||||||
ephysics_world_render_geometry_get(body->world, &wx, &wy, NULL,
|
ephysics_world_render_geometry_get(body->world, &wx, &wy, NULL,
|
||||||
|
@ -1437,7 +1463,7 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
|
||||||
cx -= wx;
|
cx -= wx;
|
||||||
cy -= wy;
|
cy -= wy;
|
||||||
|
|
||||||
evas_object_geometry_get(body->evas_obj, NULL, NULL, &w, &h);
|
evas_object_geometry_get(evas_obj, NULL, NULL, &w, &h);
|
||||||
rate = ephysics_world_rate_get(body->world);
|
rate = ephysics_world_rate_get(body->world);
|
||||||
bx = (int) (trans.getOrigin().getX() * rate) - cx;
|
bx = (int) (trans.getOrigin().getX() * rate) - cx;
|
||||||
by = wh + wy - (int) (trans.getOrigin().getY() * rate) - cy;
|
by = wh + wy - (int) (trans.getOrigin().getY() * rate) - cy;
|
||||||
|
@ -1445,20 +1471,18 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
|
||||||
y = by - h * body->cm.y;
|
y = by - h * body->cm.y;
|
||||||
z = (int) (trans.getOrigin().getZ() * rate);
|
z = (int) (trans.getOrigin().getZ() * rate);
|
||||||
|
|
||||||
evas_object_move(body->evas_obj, x, y);
|
evas_object_move(evas_obj, x, y);
|
||||||
|
|
||||||
if ((!w) || (!h))
|
if ((!w) || (!h))
|
||||||
{
|
{
|
||||||
DBG("Evas object with no geometry: %p, w=%i h=%i", body->evas_obj,
|
DBG("Evas object with no geometry: %p, w=%i h=%i", evas_obj, w, h);
|
||||||
w, h);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body->type != EPHYSICS_BODY_TYPE_RIGID)
|
if (body->type != EPHYSICS_BODY_TYPE_RIGID)
|
||||||
{
|
{
|
||||||
EINA_LIST_FOREACH(body->faces_slices, l, ldata)
|
_ephysics_body_soft_body_slices_apply(body, body->evas_obj,
|
||||||
_ephysics_body_soft_body_slices_apply(body,
|
body->default_face->slices);
|
||||||
((EPhysics_Body_Face_Slice *)ldata)->slices);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1470,10 +1494,53 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
|
||||||
evas_map_util_quat_rotate(map, quat.x(), -quat.y(), quat.z(), -quat.w(),
|
evas_map_util_quat_rotate(map, quat.x(), -quat.y(), quat.z(), -quat.w(),
|
||||||
bx, by, z);
|
bx, by, z);
|
||||||
|
|
||||||
_ephysics_body_evas_obj_map_apply(body, map, body->evas_obj,
|
_ephysics_body_evas_obj_map_apply(body, map, evas_obj,
|
||||||
body->back_face_culling, EINA_TRUE);
|
body->back_face_culling, EINA_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ephysics_body_soft_body_update(EPhysics_Body *body)
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
void *ldata;
|
||||||
|
EPhysics_Body_Face_Slice *face_slice;
|
||||||
|
EPhysics_Body_Face_Obj *face_obj;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(body->faces_slices, l, ldata)
|
||||||
|
{
|
||||||
|
face_slice = (EPhysics_Body_Face_Slice *)ldata;
|
||||||
|
face_obj = _ephysics_body_face_evas_object_get(body,
|
||||||
|
face_slice->face);
|
||||||
|
if (!face_obj) continue;
|
||||||
|
_ephysics_body_soft_body_slices_apply(body, face_obj->obj,
|
||||||
|
face_slice->slices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ephysics_body_evas_object_default_update(EPhysics_Body *body)
|
||||||
|
{
|
||||||
|
if (body->face_objs)
|
||||||
|
{
|
||||||
|
if (body->type == EPHYSICS_BODY_TYPE_CLOTH)
|
||||||
|
_ephysics_cloth_face_objs_update(body);
|
||||||
|
else if (body->type == EPHYSICS_BODY_TYPE_RIGID)
|
||||||
|
{
|
||||||
|
if (body->shape == EPHYSICS_BODY_SHAPE_CYLINDER)
|
||||||
|
_ephysics_cylinder_face_objs_update(body);
|
||||||
|
else if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
|
||||||
|
_ephysics_box_face_objs_update(body);
|
||||||
|
}
|
||||||
|
else if (body->type == EPHYSICS_BODY_TYPE_SOFT)
|
||||||
|
_ephysics_body_soft_body_update(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!body->evas_obj)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_ephysics_body_evas_object_update(body, body->evas_obj);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ephysics_body_outside_render_area_check(EPhysics_Body *body)
|
_ephysics_body_outside_render_area_check(EPhysics_Body *body)
|
||||||
{
|
{
|
||||||
|
@ -2238,6 +2305,157 @@ ephysics_body_soft_body_triangle_index_get(EPhysics_Body *body, Evas_Coord x, Ev
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EPhysics_Body_Face_Slice *
|
||||||
|
_ephysics_body_soft_ellipsoid_face_slices_add(EPhysics_Body *body, EPhysics_Body_Face face, btVector3 center)
|
||||||
|
{
|
||||||
|
btSoftBody::Face *bt_face;
|
||||||
|
btSoftBody::Node *node;
|
||||||
|
int out;
|
||||||
|
btScalar depth_limit;
|
||||||
|
Eina_List *face_list = NULL;
|
||||||
|
void *data;
|
||||||
|
int *idx, i = 0;
|
||||||
|
EPhysics_Body_Face_Slice *face_slice;
|
||||||
|
|
||||||
|
depth_limit = center.z();
|
||||||
|
|
||||||
|
for (int m = 0; m < body->soft_body->m_faces.size(); m++)
|
||||||
|
{
|
||||||
|
out = 0;
|
||||||
|
bt_face = &body->soft_body->m_faces[m];
|
||||||
|
for (int n = 0; n < 3; n++)
|
||||||
|
{
|
||||||
|
node = bt_face->m_n[n];
|
||||||
|
if ((face == EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_FRONT &&
|
||||||
|
node->m_x.z() > depth_limit) ||
|
||||||
|
(face == EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_BACK &&
|
||||||
|
node->m_x.z() < depth_limit))
|
||||||
|
out++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out < 2)
|
||||||
|
{
|
||||||
|
idx = (int *)malloc(sizeof(int));
|
||||||
|
if (!idx)
|
||||||
|
goto no_deform;
|
||||||
|
*idx = m;
|
||||||
|
face_list = eina_list_append(face_list, idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
face_slice = _ephysics_body_face_slice_add(body, face);
|
||||||
|
if (!face_slice)
|
||||||
|
{
|
||||||
|
ERR("Could not allocate face slice data structure.");
|
||||||
|
goto no_deform;
|
||||||
|
}
|
||||||
|
|
||||||
|
face_slice->slices_cnt = eina_list_count(face_list);
|
||||||
|
face_slice->points_deform = (int *)malloc(face_slice->slices_cnt *
|
||||||
|
sizeof(int));
|
||||||
|
if (!face_slice->points_deform)
|
||||||
|
goto no_points_deform;
|
||||||
|
|
||||||
|
EINA_LIST_FREE(face_list, data)
|
||||||
|
{
|
||||||
|
face_slice->points_deform[i] = *((int *)data);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
face_slice->slices = _ephysics_body_slices_add(body, face_slice->slices_cnt,
|
||||||
|
face_slice->points_deform, -0.5, 1);
|
||||||
|
if (!face_slice->slices)
|
||||||
|
{
|
||||||
|
ERR("Couldn't create slices.");
|
||||||
|
goto no_points_deform;
|
||||||
|
}
|
||||||
|
return face_slice;
|
||||||
|
|
||||||
|
no_points_deform:
|
||||||
|
_ephysics_body_face_slice_del(face_slice);
|
||||||
|
no_deform:
|
||||||
|
EINA_LIST_FREE(face_list, data)
|
||||||
|
free(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI EPhysics_Body *
|
||||||
|
ephysics_body_soft_ellipsoid_add(EPhysics_World *world, int granularity)
|
||||||
|
{
|
||||||
|
EPhysics_Body *body;
|
||||||
|
EPhysics_Body_Face_Slice *front_face, *back_face;
|
||||||
|
btCollisionShape *shape;
|
||||||
|
btSoftBodyWorldInfo *world_info;
|
||||||
|
btSoftBody *soft_body;
|
||||||
|
btVector3 center, radius;
|
||||||
|
int body_granularity = (!granularity) ? 100 : granularity;
|
||||||
|
|
||||||
|
|
||||||
|
if (!world)
|
||||||
|
{
|
||||||
|
ERR("Can't add circle, world is null.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ephysics_world_lock_take(world);
|
||||||
|
shape = new btCylinderShapeZ(btVector3(0.25, 0.25, 0.25));
|
||||||
|
|
||||||
|
if (!shape)
|
||||||
|
{
|
||||||
|
ERR("Couldn't create a new cylinder shape.");
|
||||||
|
goto no_collision_shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
world_info = ephysics_world_info_get(world);
|
||||||
|
center = btVector3(1, 1, 1);
|
||||||
|
radius = btVector3(0.5, 0.5, 0.5);
|
||||||
|
soft_body = btSoftBodyHelpers::CreateEllipsoid(*world_info, center, radius,
|
||||||
|
body_granularity);
|
||||||
|
|
||||||
|
if (!soft_body)
|
||||||
|
{
|
||||||
|
ERR("Couldn't create a new soft body.");
|
||||||
|
goto no_soft_body;
|
||||||
|
}
|
||||||
|
|
||||||
|
body = _ephysics_body_soft_body_add(world, shape, soft_body);
|
||||||
|
if (!body)
|
||||||
|
goto no_body;
|
||||||
|
|
||||||
|
front_face = _ephysics_body_soft_ellipsoid_face_slices_add(body,
|
||||||
|
EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_FRONT, center);
|
||||||
|
if (!front_face)
|
||||||
|
{
|
||||||
|
ERR("Could not create points of deformation mapping for front face.");
|
||||||
|
goto no_front_face;
|
||||||
|
}
|
||||||
|
body->default_face = front_face;
|
||||||
|
|
||||||
|
back_face = _ephysics_body_soft_ellipsoid_face_slices_add(body,
|
||||||
|
EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_BACK, center);
|
||||||
|
if (!back_face)
|
||||||
|
{
|
||||||
|
ERR("Could not create points of deformation mapping for back face.");
|
||||||
|
goto no_back_face;
|
||||||
|
}
|
||||||
|
|
||||||
|
body->shape = EPHYSICS_BODY_SHAPE_ELLIPSOID;
|
||||||
|
ephysics_world_lock_release(world);
|
||||||
|
return body;
|
||||||
|
|
||||||
|
no_back_face:
|
||||||
|
_ephysics_body_face_slice_del(front_face);
|
||||||
|
no_front_face:
|
||||||
|
ephysics_world_body_del(world, body);
|
||||||
|
no_body:
|
||||||
|
delete soft_body;
|
||||||
|
no_soft_body:
|
||||||
|
delete shape;
|
||||||
|
no_collision_shape:
|
||||||
|
ephysics_world_lock_release(world);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
EAPI EPhysics_Body *
|
EAPI EPhysics_Body *
|
||||||
ephysics_body_soft_circle_add(EPhysics_World *world)
|
ephysics_body_soft_circle_add(EPhysics_World *world)
|
||||||
{
|
{
|
||||||
|
@ -3847,6 +4065,14 @@ _ephysics_body_face_obj_unset(Evas_Object *obj, Evas_Object_Event_Cb resize_func
|
||||||
evas_object_event_callback_del(obj, EVAS_CALLBACK_RESIZE, resize_func);
|
evas_object_event_callback_del(obj, EVAS_CALLBACK_RESIZE, resize_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ephysics_body_face_evas_object_del(EPhysics_Body *body, EPhysics_Body_Face_Obj *face_obj, Evas_Object_Event_Cb resize_func)
|
||||||
|
{
|
||||||
|
_ephysics_body_face_obj_unset(face_obj->obj, resize_func);
|
||||||
|
body->face_objs = eina_list_remove(body->face_objs, face_obj);
|
||||||
|
free(face_obj);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ephysics_body_face_evas_object_add(EPhysics_Body *body, EPhysics_Body_Face face, Evas_Object *evas_obj, Evas_Object_Event_Cb resize_func)
|
_ephysics_body_face_evas_object_add(EPhysics_Body *body, EPhysics_Body_Face face, Evas_Object *evas_obj, Evas_Object_Event_Cb resize_func)
|
||||||
{
|
{
|
||||||
|
@ -4303,6 +4529,172 @@ _ephysics_body_cloth_face_evas_object_unset(EPhysics_Body *body, EPhysics_Body_F
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ephysics_body_ellipsoid_face_obj_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
||||||
|
{
|
||||||
|
EPhysics_Body *body = (EPhysics_Body *) data;
|
||||||
|
Evas_Coord bd, w, h;
|
||||||
|
|
||||||
|
evas_object_geometry_get(obj, NULL, NULL, &w, &h);
|
||||||
|
ephysics_body_geometry_get(body, NULL, NULL, NULL, NULL, NULL, &bd);
|
||||||
|
ephysics_world_lock_take(body->world);
|
||||||
|
ephysics_body_resize(body, w, h, bd);
|
||||||
|
ephysics_world_lock_release(body->world);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ephysics_body_ellipsoid_face_evas_object_del_cb(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
void *ldata;
|
||||||
|
EPhysics_Body_Face_Obj *face_obj = NULL;
|
||||||
|
EPhysics_Body_Face_Slice *face_slice = (EPhysics_Body_Face_Slice *)data;
|
||||||
|
EPhysics_Body *body = face_slice->body;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(body->face_objs, l, ldata)
|
||||||
|
{
|
||||||
|
if (((EPhysics_Body_Face_Obj *)ldata)->face == face_slice->face)
|
||||||
|
{
|
||||||
|
face_obj = (EPhysics_Body_Face_Obj *)ldata;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ephysics_body_face_evas_object_del(body, face_obj,
|
||||||
|
_ephysics_body_ellipsoid_face_obj_resize_cb);
|
||||||
|
_ephysics_body_soft_body_slices_clean(face_slice->slices);
|
||||||
|
DBG("Ellipsoid's face cleaned up.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ephysics_body_ellipsoid_face_evas_object_clean(EPhysics_Body *body, EPhysics_Body_Face_Obj *face_obj, Eina_List *slices)
|
||||||
|
{
|
||||||
|
evas_object_map_enable_set(face_obj->obj, EINA_FALSE);
|
||||||
|
evas_object_event_callback_del(face_obj->obj, EVAS_CALLBACK_DEL,
|
||||||
|
_ephysics_body_ellipsoid_face_evas_object_del_cb);
|
||||||
|
evas_object_event_callback_del(face_obj->obj, EVAS_CALLBACK_RESIZE,
|
||||||
|
_ephysics_body_evas_obj_resize_cb);
|
||||||
|
evas_object_event_callback_del(face_obj->obj, EVAS_CALLBACK_RESTACK,
|
||||||
|
_ephysics_body_soft_body_evas_restack_cb);
|
||||||
|
_ephysics_body_soft_body_slices_clean(slices);
|
||||||
|
|
||||||
|
_ephysics_body_face_evas_object_del(body, face_obj,
|
||||||
|
_ephysics_body_ellipsoid_face_obj_resize_cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ephysics_body_ellipsoid_face_evas_object_set(EPhysics_Body *body, EPhysics_Body_Face face, Evas_Object *evas_obj, Eina_Bool use_obj_pos)
|
||||||
|
{
|
||||||
|
int obj_x, obj_y, obj_w, obj_h, bz, bd;
|
||||||
|
double rate;
|
||||||
|
EPhysics_Body_Face_Slice *face_slice = NULL;
|
||||||
|
EPhysics_Body_Face_Obj *face_obj;
|
||||||
|
|
||||||
|
if ((face < EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_FRONT) ||
|
||||||
|
(face > EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_BACK))
|
||||||
|
{
|
||||||
|
ERR("Can't set evas object to body, face is invalid.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!body)
|
||||||
|
{
|
||||||
|
ERR("Can't set evas object to body, the last wasn't provided.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!evas_obj)
|
||||||
|
{
|
||||||
|
ERR("Can't set evas object to body, the first wasn't provided.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
face_slice = _ephysics_body_face_slice_get(body, face);
|
||||||
|
if (!face_slice)
|
||||||
|
{
|
||||||
|
ERR("Could not find pre initialized face slice for the wanted face.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
face_obj = _ephysics_body_face_evas_object_get(body, face);
|
||||||
|
|
||||||
|
if (face_obj)
|
||||||
|
_ephysics_body_ellipsoid_face_evas_object_clean(body, face_obj,
|
||||||
|
face_slice->slices);
|
||||||
|
|
||||||
|
_ephysics_body_face_evas_object_add(body, face, evas_obj,
|
||||||
|
_ephysics_body_ellipsoid_face_obj_resize_cb);
|
||||||
|
|
||||||
|
evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_DEL,
|
||||||
|
_ephysics_body_ellipsoid_face_evas_object_del_cb, face_slice);
|
||||||
|
|
||||||
|
evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_RESTACK,
|
||||||
|
_ephysics_body_soft_body_evas_restack_cb,
|
||||||
|
body);
|
||||||
|
|
||||||
|
_ephysics_body_soft_body_slices_init(body, evas_obj, face_slice->slices);
|
||||||
|
|
||||||
|
if (!use_obj_pos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rate = ephysics_world_rate_get(body->world);
|
||||||
|
evas_object_geometry_get(evas_obj, &obj_x, &obj_y, &obj_w, &obj_h);
|
||||||
|
ephysics_body_geometry_get(body, NULL, NULL, &bz, NULL, NULL, &bd);
|
||||||
|
|
||||||
|
ephysics_world_lock_take(body->world);
|
||||||
|
_ephysics_body_geometry_set(body, obj_x, obj_y, bz, obj_w, obj_h, bd, rate);
|
||||||
|
ephysics_world_lock_release(body->world);
|
||||||
|
evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_RESIZE,
|
||||||
|
_ephysics_body_evas_obj_resize_cb, body);
|
||||||
|
DBG("Ellipsoid face evas object set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static Evas_Object *
|
||||||
|
_ephysics_body_ellipsoid_face_evas_object_get(const EPhysics_Body *body, EPhysics_Body_Face face)
|
||||||
|
{
|
||||||
|
EPhysics_Body_Face_Obj *face_obj = NULL;
|
||||||
|
|
||||||
|
if ((face < EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_FRONT) ||
|
||||||
|
(face > EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_BACK))
|
||||||
|
{
|
||||||
|
ERR("Can't get evas object from body, face is invalid.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
face_obj = _ephysics_body_face_evas_object_get((EPhysics_Body *)body, face);
|
||||||
|
if (face_obj) return face_obj->obj;
|
||||||
|
|
||||||
|
ERR("Couldn't find an object associated to face %i.", face);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Evas_Object *
|
||||||
|
_ephysics_body_ellipsoid_face_evas_object_unset(EPhysics_Body *body, EPhysics_Body_Face face)
|
||||||
|
{
|
||||||
|
EPhysics_Body_Face_Slice *face_slice;
|
||||||
|
EPhysics_Body_Face_Obj *face_obj = NULL;
|
||||||
|
Evas_Object *obj;
|
||||||
|
|
||||||
|
if ((face < EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_FRONT) ||
|
||||||
|
(face > EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_BACK))
|
||||||
|
{
|
||||||
|
ERR("Can't unset evas object from body, face is invalid.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
face_obj = _ephysics_body_face_evas_object_get(body, face);
|
||||||
|
|
||||||
|
if (!face_obj) return NULL;
|
||||||
|
|
||||||
|
obj = face_obj->obj;
|
||||||
|
face_slice = _ephysics_body_face_slice_get(body, face);
|
||||||
|
_ephysics_body_ellipsoid_face_evas_object_clean(body, face_obj,
|
||||||
|
face_slice->slices);
|
||||||
|
|
||||||
|
DBG("EPhysics Body face unset.");
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
ephysics_body_face_evas_object_set(EPhysics_Body *body, EPhysics_Body_Face face, Evas_Object *evas_obj, Eina_Bool use_obj_pos)
|
ephysics_body_face_evas_object_set(EPhysics_Body *body, EPhysics_Body_Face face, Evas_Object *evas_obj, Eina_Bool use_obj_pos)
|
||||||
{
|
{
|
||||||
|
@ -4327,6 +4719,9 @@ ephysics_body_face_evas_object_set(EPhysics_Body *body, EPhysics_Body_Face face,
|
||||||
if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
|
if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
|
||||||
return _ephysics_body_box_face_evas_object_set(body, face, evas_obj,
|
return _ephysics_body_box_face_evas_object_set(body, face, evas_obj,
|
||||||
use_obj_pos);
|
use_obj_pos);
|
||||||
|
if (body->shape == EPHYSICS_BODY_SHAPE_ELLIPSOID)
|
||||||
|
return _ephysics_body_ellipsoid_face_evas_object_set(body, face, evas_obj,
|
||||||
|
use_obj_pos);
|
||||||
|
|
||||||
ERR("Can't handle body %p type.", body);
|
ERR("Can't handle body %p type.", body);
|
||||||
}
|
}
|
||||||
|
@ -4346,6 +4741,8 @@ ephysics_body_face_evas_object_get(const EPhysics_Body *body, EPhysics_Body_Face
|
||||||
return _ephysics_body_cylinder_face_evas_object_get(body, face);
|
return _ephysics_body_cylinder_face_evas_object_get(body, face);
|
||||||
if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
|
if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
|
||||||
return _ephysics_body_box_face_evas_object_get(body, face);
|
return _ephysics_body_box_face_evas_object_get(body, face);
|
||||||
|
if (body->shape == EPHYSICS_BODY_SHAPE_ELLIPSOID)
|
||||||
|
return _ephysics_body_ellipsoid_face_evas_object_get(body, face);
|
||||||
|
|
||||||
ERR("Can't handle body %p type.", body);
|
ERR("Can't handle body %p type.", body);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -4366,6 +4763,8 @@ ephysics_body_face_evas_object_unset(EPhysics_Body *body, EPhysics_Body_Face fac
|
||||||
return _ephysics_body_cylinder_face_evas_object_unset(body, face);
|
return _ephysics_body_cylinder_face_evas_object_unset(body, face);
|
||||||
if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
|
if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
|
||||||
return _ephysics_body_box_face_evas_object_unset(body, face);
|
return _ephysics_body_box_face_evas_object_unset(body, face);
|
||||||
|
if (body->shape == EPHYSICS_BODY_SHAPE_ELLIPSOID)
|
||||||
|
return _ephysics_body_ellipsoid_face_evas_object_unset(body, face);
|
||||||
|
|
||||||
ERR("Can't handle body %p type.", body);
|
ERR("Can't handle body %p type.", body);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -60,6 +60,7 @@ typedef enum _EPhysics_Body_Shape
|
||||||
EPHYSICS_BODY_SHAPE_BOX,
|
EPHYSICS_BODY_SHAPE_BOX,
|
||||||
EPHYSICS_BODY_SHAPE_CUSTOM,
|
EPHYSICS_BODY_SHAPE_CUSTOM,
|
||||||
EPHYSICS_BODY_SHAPE_CYLINDER,
|
EPHYSICS_BODY_SHAPE_CYLINDER,
|
||||||
|
EPHYSICS_BODY_SHAPE_ELLIPSOID,
|
||||||
EPHYSICS_BODY_SHAPE_LAST,
|
EPHYSICS_BODY_SHAPE_LAST,
|
||||||
} EPhysics_Body_Shape;
|
} EPhysics_Body_Shape;
|
||||||
|
|
||||||
|
@ -116,6 +117,7 @@ struct _EPhysics_Body_Size {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _EPhysics_Body_Face_Slice {
|
struct _EPhysics_Body_Face_Slice {
|
||||||
|
EPhysics_Body *body;
|
||||||
EPhysics_Body_Face face;
|
EPhysics_Body_Face face;
|
||||||
int slices_cnt;
|
int slices_cnt;
|
||||||
int *points_deform;
|
int *points_deform;
|
||||||
|
|
Loading…
Reference in New Issue