summaryrefslogtreecommitdiff
path: root/legacy/ephysics
diff options
context:
space:
mode:
authorLeandro Dorileo <dorileo@profusion.mobi>2012-11-23 21:51:38 +0000
committerBruno Dilly <bdilly@profusion.mobi>2012-11-23 21:51:38 +0000
commit0e3e700e5278df23ea1aa7914c6a4199951bb0d6 (patch)
tree14bfe1b903d12037355270730c269a9b0da241b9 /legacy/ephysics
parentf36db0c84d2bf69e8a40e834000dc0e25c2721ef (diff)
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
Diffstat (limited to 'legacy/ephysics')
-rw-r--r--legacy/ephysics/src/lib/EPhysics.h22
-rw-r--r--legacy/ephysics/src/lib/ephysics_body.cpp465
-rw-r--r--legacy/ephysics/src/lib/ephysics_private.h2
3 files changed, 456 insertions, 33 deletions
diff --git a/legacy/ephysics/src/lib/EPhysics.h b/legacy/ephysics/src/lib/EPhysics.h
index ee3f3ba89b..2f3a0bcaae 100644
--- a/legacy/ephysics/src/lib/EPhysics.h
+++ b/legacy/ephysics/src/lib/EPhysics.h
@@ -2388,6 +2388,28 @@ EAPI int ephysics_body_soft_body_triangle_index_get(EPhysics_Body *body, Evas_Co
2388 2388
2389/** 2389/**
2390 * @brief 2390 * @brief
2391 * Add a soft ellipsoid.
2392 *
2393 * Add a new soft 3d ellipsoid to the simulation. The @p granularity defines how
2394 * many triangles are to be added.
2395 *
2396 * @note if no @p granularity is informed(i.e @p granularity = 0) the soft body
2397 * will be created with a triangle mesh of 100.
2398 *
2399 * @param world The world the new soft ellipsoid is to be added.
2400 * @param granularity How many triangles the soft body triangle mesh must have.
2401 * @return a new body or @c NULL on errors.
2402 *
2403 * @see ephysics_body_del().
2404 * @see ephysics_body_evas_object_set().
2405 * @see ephysics_body_face_evas_object_set().
2406 *
2407 * @ingroup EPhysics_Body
2408 */
2409EAPI EPhysics_Body *ephysics_body_soft_ellipsoid_add(EPhysics_World *world, int granularity);
2410
2411/**
2412 * @brief
2391 * Apply an impulse on a given soft body triangle. 2413 * Apply an impulse on a given soft body triangle.
2392 * 2414 *
2393 * The impulse is equal to the change of momentum of the body. 2415 * The impulse is equal to the change of momentum of the body.
diff --git a/legacy/ephysics/src/lib/ephysics_body.cpp b/legacy/ephysics/src/lib/ephysics_body.cpp
index d5e1bc8bf8..8085df9446 100644
--- a/legacy/ephysics/src/lib/ephysics_body.cpp
+++ b/legacy/ephysics/src/lib/ephysics_body.cpp
@@ -60,7 +60,7 @@ struct _EPhysics_Body_Face_Obj {
60}; 60};
61 61
62static void 62static void
63_ephysics_body_soft_body_slices_apply(EPhysics_Body *body, Eina_List *slices) 63_ephysics_body_soft_body_slices_apply(EPhysics_Body *body, Evas_Object *evas_obj, Eina_List *slices)
64{ 64{
65 double rate; 65 double rate;
66 void *list_data; 66 void *list_data;
@@ -81,7 +81,7 @@ _ephysics_body_soft_body_slices_apply(EPhysics_Body *body, Eina_List *slices)
81 rate = ephysics_world_rate_get(body->world); 81 rate = ephysics_world_rate_get(body->world);
82 ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, NULL, &wh, 82 ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, NULL, &wh,
83 NULL); 83 NULL);
84 evas_object_geometry_get(body->evas_obj, NULL, NULL, &w, &h); 84 evas_object_geometry_get(evas_obj, NULL, NULL, &w, &h);
85 85
86 if ((body->light_apply) || 86 if ((body->light_apply) ||
87 (ephysics_world_light_all_bodies_get(body->world))) 87 (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
234 if (slice) 234 if (slice)
235 evas_object_image_source_visible_set(slice->evas_obj, EINA_FALSE); 235 evas_object_image_source_visible_set(slice->evas_obj, EINA_FALSE);
236 236
237 _ephysics_body_soft_body_slices_apply(body, slices); 237 _ephysics_body_soft_body_slices_apply(body, obj, slices);
238} 238}
239 239
240static void 240static void
@@ -1096,16 +1096,55 @@ _ephysics_body_face_slice_add(EPhysics_Body *body, EPhysics_Body_Face face)
1096 1096
1097 face_slice->face = face; 1097 face_slice->face = face;
1098 body->faces_slices = eina_list_append(body->faces_slices, face_slice); 1098 body->faces_slices = eina_list_append(body->faces_slices, face_slice);
1099 face_slice->body = body;
1099 return face_slice; 1100 return face_slice;
1100 DBG("New face slice added to body %p", body); 1101 DBG("New face slice added to body %p", body);
1101} 1102}
1102 1103
1104static EPhysics_Body_Face_Slice *
1105_ephysics_body_face_slice_get(EPhysics_Body *body, EPhysics_Body_Face face)
1106{
1107 Eina_List *l;
1108 void *ldata;
1109 EPhysics_Body_Face_Slice *face_slice = NULL;
1110
1111 EINA_LIST_FOREACH(body->faces_slices, l, ldata)
1112 {
1113 if (((EPhysics_Body_Face_Slice *)ldata)->face == face)
1114 {
1115 face_slice = (EPhysics_Body_Face_Slice *)ldata;
1116 break;
1117 }
1118 }
1119
1120 return face_slice;
1121}
1122
1123static EPhysics_Body_Face_Obj *
1124_ephysics_body_face_evas_object_get(EPhysics_Body *body, EPhysics_Body_Face face)
1125{
1126 Eina_List *l;
1127 void *ldata;
1128 EPhysics_Body_Face_Obj *face_obj;
1129
1130 EINA_LIST_FOREACH(body->face_objs, l, ldata)
1131 {
1132 face_obj = (EPhysics_Body_Face_Obj *)ldata;
1133 if (face_obj->face == face)
1134 return face_obj;
1135 }
1136
1137 DBG("Could not find requested face");
1138 return NULL;
1139}
1140
1103static void 1141static void
1104_ephysics_body_del(EPhysics_Body *body) 1142_ephysics_body_del(EPhysics_Body *body)
1105{ 1143{
1106 EPhysics_Body_Callback *cb; 1144 EPhysics_Body_Callback *cb;
1145 void *ldata;
1107 void *group; 1146 void *group;
1108 void *face_slice; 1147 EPhysics_Body_Face_Slice *face_slice;
1109 1148
1110 if (body->evas_obj) 1149 if (body->evas_obj)
1111 { 1150 {
@@ -1130,8 +1169,13 @@ _ephysics_body_del(EPhysics_Body *body)
1130 EINA_LIST_FREE(body->collision_groups, group) 1169 EINA_LIST_FREE(body->collision_groups, group)
1131 eina_stringshare_del((Eina_Stringshare *)group); 1170 eina_stringshare_del((Eina_Stringshare *)group);
1132 1171
1133 EINA_LIST_FREE(body->faces_slices, face_slice) 1172 EINA_LIST_FREE(body->faces_slices, ldata)
1134 _ephysics_body_face_slice_del((EPhysics_Body_Face_Slice *)face_slice); 1173 {
1174 face_slice = (EPhysics_Body_Face_Slice *)ldata;
1175 if (_ephysics_body_face_evas_object_get(body, face_slice->face))
1176 ephysics_body_face_evas_object_unset(body, face_slice->face);
1177 _ephysics_body_face_slice_del(face_slice);
1178 }
1135 1179
1136 if (body->rigid_body) 1180 if (body->rigid_body)
1137 { 1181 {
@@ -1402,7 +1446,7 @@ _ephysics_box_face_objs_update(EPhysics_Body *body)
1402} 1446}
1403 1447
1404static void 1448static void
1405_ephysics_body_evas_object_default_update(EPhysics_Body *body) 1449_ephysics_body_evas_object_update(EPhysics_Body *body, Evas_Object *evas_obj)
1406{ 1450{
1407 int bx, by, x, y, z, w, h, wx, wy, wh, cx, cy; 1451 int bx, by, x, y, z, w, h, wx, wy, wh, cx, cy;
1408 EPhysics_Camera *camera; 1452 EPhysics_Camera *camera;
@@ -1410,24 +1454,6 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
1410 btQuaternion quat; 1454 btQuaternion quat;
1411 Evas_Map *map; 1455 Evas_Map *map;
1412 double rate; 1456 double rate;
1413 Eina_List *l;
1414 void *ldata;
1415
1416 if (body->face_objs)
1417 {
1418 if (body->type == EPHYSICS_BODY_TYPE_CLOTH)
1419 _ephysics_cloth_face_objs_update(body);
1420 else if (body->type == EPHYSICS_BODY_TYPE_RIGID)
1421 {
1422 if (body->shape == EPHYSICS_BODY_SHAPE_CYLINDER)
1423 _ephysics_cylinder_face_objs_update(body);
1424 else if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
1425 _ephysics_box_face_objs_update(body);
1426 }
1427 }
1428
1429 if (!body->evas_obj)
1430 return;
1431 1457
1432 trans = _ephysics_body_transform_get(body); 1458 trans = _ephysics_body_transform_get(body);
1433 ephysics_world_render_geometry_get(body->world, &wx, &wy, NULL, 1459 ephysics_world_render_geometry_get(body->world, &wx, &wy, NULL,
@@ -1437,7 +1463,7 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
1437 cx -= wx; 1463 cx -= wx;
1438 cy -= wy; 1464 cy -= wy;
1439 1465
1440 evas_object_geometry_get(body->evas_obj, NULL, NULL, &w, &h); 1466 evas_object_geometry_get(evas_obj, NULL, NULL, &w, &h);
1441 rate = ephysics_world_rate_get(body->world); 1467 rate = ephysics_world_rate_get(body->world);
1442 bx = (int) (trans.getOrigin().getX() * rate) - cx; 1468 bx = (int) (trans.getOrigin().getX() * rate) - cx;
1443 by = wh + wy - (int) (trans.getOrigin().getY() * rate) - cy; 1469 by = wh + wy - (int) (trans.getOrigin().getY() * rate) - cy;
@@ -1445,20 +1471,18 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
1445 y = by - h * body->cm.y; 1471 y = by - h * body->cm.y;
1446 z = (int) (trans.getOrigin().getZ() * rate); 1472 z = (int) (trans.getOrigin().getZ() * rate);
1447 1473
1448 evas_object_move(body->evas_obj, x, y); 1474 evas_object_move(evas_obj, x, y);
1449 1475
1450 if ((!w) || (!h)) 1476 if ((!w) || (!h))
1451 { 1477 {
1452 DBG("Evas object with no geometry: %p, w=%i h=%i", body->evas_obj, 1478 DBG("Evas object with no geometry: %p, w=%i h=%i", evas_obj, w, h);
1453 w, h);
1454 return; 1479 return;
1455 } 1480 }
1456 1481
1457 if (body->type != EPHYSICS_BODY_TYPE_RIGID) 1482 if (body->type != EPHYSICS_BODY_TYPE_RIGID)
1458 { 1483 {
1459 EINA_LIST_FOREACH(body->faces_slices, l, ldata) 1484 _ephysics_body_soft_body_slices_apply(body, body->evas_obj,
1460 _ephysics_body_soft_body_slices_apply(body, 1485 body->default_face->slices);
1461 ((EPhysics_Body_Face_Slice *)ldata)->slices);
1462 return; 1486 return;
1463 } 1487 }
1464 1488
@@ -1470,11 +1494,54 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
1470 evas_map_util_quat_rotate(map, quat.x(), -quat.y(), quat.z(), -quat.w(), 1494 evas_map_util_quat_rotate(map, quat.x(), -quat.y(), quat.z(), -quat.w(),
1471 bx, by, z); 1495 bx, by, z);
1472 1496
1473 _ephysics_body_evas_obj_map_apply(body, map, body->evas_obj, 1497 _ephysics_body_evas_obj_map_apply(body, map, evas_obj,
1474 body->back_face_culling, EINA_TRUE); 1498 body->back_face_culling, EINA_TRUE);
1475} 1499}
1476 1500
1477static void 1501static void
1502_ephysics_body_soft_body_update(EPhysics_Body *body)
1503{
1504 Eina_List *l;
1505 void *ldata;
1506 EPhysics_Body_Face_Slice *face_slice;
1507 EPhysics_Body_Face_Obj *face_obj;
1508
1509 EINA_LIST_FOREACH(body->faces_slices, l, ldata)
1510 {
1511 face_slice = (EPhysics_Body_Face_Slice *)ldata;
1512 face_obj = _ephysics_body_face_evas_object_get(body,
1513 face_slice->face);
1514 if (!face_obj) continue;
1515 _ephysics_body_soft_body_slices_apply(body, face_obj->obj,
1516 face_slice->slices);
1517 }
1518}
1519
1520static void
1521_ephysics_body_evas_object_default_update(EPhysics_Body *body)
1522{
1523 if (body->face_objs)
1524 {
1525 if (body->type == EPHYSICS_BODY_TYPE_CLOTH)
1526 _ephysics_cloth_face_objs_update(body);
1527 else if (body->type == EPHYSICS_BODY_TYPE_RIGID)
1528 {
1529 if (body->shape == EPHYSICS_BODY_SHAPE_CYLINDER)
1530 _ephysics_cylinder_face_objs_update(body);
1531 else if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
1532 _ephysics_box_face_objs_update(body);
1533 }
1534 else if (body->type == EPHYSICS_BODY_TYPE_SOFT)
1535 _ephysics_body_soft_body_update(body);
1536 }
1537
1538 if (!body->evas_obj)
1539 return;
1540
1541 _ephysics_body_evas_object_update(body, body->evas_obj);
1542}
1543
1544static void
1478_ephysics_body_outside_render_area_check(EPhysics_Body *body) 1545_ephysics_body_outside_render_area_check(EPhysics_Body *body)
1479{ 1546{
1480 int wx, wy, wz, ww, wh, wd, bx, by, bz, bw, bh, bd; 1547 int wx, wy, wz, ww, wh, wd, bx, by, bz, bw, bh, bd;
@@ -2238,6 +2305,157 @@ ephysics_body_soft_body_triangle_index_get(EPhysics_Body *body, Evas_Coord x, Ev
2238 return index; 2305 return index;
2239} 2306}
2240 2307
2308static EPhysics_Body_Face_Slice *
2309_ephysics_body_soft_ellipsoid_face_slices_add(EPhysics_Body *body, EPhysics_Body_Face face, btVector3 center)
2310{
2311 btSoftBody::Face *bt_face;
2312 btSoftBody::Node *node;
2313 int out;
2314 btScalar depth_limit;
2315 Eina_List *face_list = NULL;
2316 void *data;
2317 int *idx, i = 0;
2318 EPhysics_Body_Face_Slice *face_slice;
2319
2320 depth_limit = center.z();
2321
2322 for (int m = 0; m < body->soft_body->m_faces.size(); m++)
2323 {
2324 out = 0;
2325 bt_face = &body->soft_body->m_faces[m];
2326 for (int n = 0; n < 3; n++)
2327 {
2328 node = bt_face->m_n[n];
2329 if ((face == EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_FRONT &&
2330 node->m_x.z() > depth_limit) ||
2331 (face == EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_BACK &&
2332 node->m_x.z() < depth_limit))
2333 out++;
2334 }
2335
2336 if (out < 2)
2337 {
2338 idx = (int *)malloc(sizeof(int));
2339 if (!idx)
2340 goto no_deform;
2341 *idx = m;
2342 face_list = eina_list_append(face_list, idx);
2343 }
2344 }
2345
2346 face_slice = _ephysics_body_face_slice_add(body, face);
2347 if (!face_slice)
2348 {
2349 ERR("Could not allocate face slice data structure.");
2350 goto no_deform;
2351 }
2352
2353 face_slice->slices_cnt = eina_list_count(face_list);
2354 face_slice->points_deform = (int *)malloc(face_slice->slices_cnt *
2355 sizeof(int));
2356 if (!face_slice->points_deform)
2357 goto no_points_deform;
2358
2359 EINA_LIST_FREE(face_list, data)
2360 {
2361 face_slice->points_deform[i] = *((int *)data);
2362 i++;
2363 }
2364
2365 face_slice->slices = _ephysics_body_slices_add(body, face_slice->slices_cnt,
2366 face_slice->points_deform, -0.5, 1);
2367 if (!face_slice->slices)
2368 {
2369 ERR("Couldn't create slices.");
2370 goto no_points_deform;
2371 }
2372 return face_slice;
2373
2374no_points_deform:
2375 _ephysics_body_face_slice_del(face_slice);
2376no_deform:
2377 EINA_LIST_FREE(face_list, data)
2378 free(data);
2379 return NULL;
2380}
2381
2382EAPI EPhysics_Body *
2383ephysics_body_soft_ellipsoid_add(EPhysics_World *world, int granularity)
2384{
2385 EPhysics_Body *body;
2386 EPhysics_Body_Face_Slice *front_face, *back_face;
2387 btCollisionShape *shape;
2388 btSoftBodyWorldInfo *world_info;
2389 btSoftBody *soft_body;
2390 btVector3 center, radius;
2391 int body_granularity = (!granularity) ? 100 : granularity;
2392
2393
2394 if (!world)
2395 {
2396 ERR("Can't add circle, world is null.");
2397 return NULL;
2398 }
2399
2400 ephysics_world_lock_take(world);
2401 shape = new btCylinderShapeZ(btVector3(0.25, 0.25, 0.25));
2402
2403 if (!shape)
2404 {
2405 ERR("Couldn't create a new cylinder shape.");
2406 goto no_collision_shape;
2407 }
2408
2409 world_info = ephysics_world_info_get(world);
2410 center = btVector3(1, 1, 1);
2411 radius = btVector3(0.5, 0.5, 0.5);
2412 soft_body = btSoftBodyHelpers::CreateEllipsoid(*world_info, center, radius,
2413 body_granularity);
2414
2415 if (!soft_body)
2416 {
2417 ERR("Couldn't create a new soft body.");
2418 goto no_soft_body;
2419 }
2420
2421 body = _ephysics_body_soft_body_add(world, shape, soft_body);
2422 if (!body)
2423 goto no_body;
2424
2425 front_face = _ephysics_body_soft_ellipsoid_face_slices_add(body,
2426 EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_FRONT, center);
2427 if (!front_face)
2428 {
2429 ERR("Could not create points of deformation mapping for front face.");
2430 goto no_front_face;
2431 }
2432 body->default_face = front_face;
2433
2434 back_face = _ephysics_body_soft_ellipsoid_face_slices_add(body,
2435 EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_BACK, center);
2436 if (!back_face)
2437 {
2438 ERR("Could not create points of deformation mapping for back face.");
2439 goto no_back_face;
2440 }
2441
2442 body->shape = EPHYSICS_BODY_SHAPE_ELLIPSOID;
2443 ephysics_world_lock_release(world);
2444 return body;
2445
2446no_back_face:
2447 _ephysics_body_face_slice_del(front_face);
2448no_front_face:
2449 ephysics_world_body_del(world, body);
2450no_body:
2451 delete soft_body;
2452no_soft_body:
2453 delete shape;
2454no_collision_shape:
2455 ephysics_world_lock_release(world);
2456 return NULL;
2457}
2458
2241EAPI EPhysics_Body * 2459EAPI EPhysics_Body *
2242ephysics_body_soft_circle_add(EPhysics_World *world) 2460ephysics_body_soft_circle_add(EPhysics_World *world)
2243{ 2461{
@@ -3848,6 +4066,14 @@ _ephysics_body_face_obj_unset(Evas_Object *obj, Evas_Object_Event_Cb resize_func
3848} 4066}
3849 4067
3850static void 4068static void
4069_ephysics_body_face_evas_object_del(EPhysics_Body *body, EPhysics_Body_Face_Obj *face_obj, Evas_Object_Event_Cb resize_func)
4070{
4071 _ephysics_body_face_obj_unset(face_obj->obj, resize_func);
4072 body->face_objs = eina_list_remove(body->face_objs, face_obj);
4073 free(face_obj);
4074}
4075
4076static void
3851_ephysics_body_face_evas_object_add(EPhysics_Body *body, EPhysics_Body_Face face, Evas_Object *evas_obj, Evas_Object_Event_Cb resize_func) 4077_ephysics_body_face_evas_object_add(EPhysics_Body *body, EPhysics_Body_Face face, Evas_Object *evas_obj, Evas_Object_Event_Cb resize_func)
3852{ 4078{
3853 EPhysics_Body_Face_Obj *face_obj; 4079 EPhysics_Body_Face_Obj *face_obj;
@@ -4303,6 +4529,172 @@ _ephysics_body_cloth_face_evas_object_unset(EPhysics_Body *body, EPhysics_Body_F
4303 return NULL; 4529 return NULL;
4304} 4530}
4305 4531
4532static void
4533_ephysics_body_ellipsoid_face_obj_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
4534{
4535 EPhysics_Body *body = (EPhysics_Body *) data;
4536 Evas_Coord bd, w, h;
4537
4538 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
4539 ephysics_body_geometry_get(body, NULL, NULL, NULL, NULL, NULL, &bd);
4540 ephysics_world_lock_take(body->world);
4541 ephysics_body_resize(body, w, h, bd);
4542 ephysics_world_lock_release(body->world);
4543}
4544
4545static void
4546_ephysics_body_ellipsoid_face_evas_object_del_cb(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
4547{
4548 Eina_List *l;
4549 void *ldata;
4550 EPhysics_Body_Face_Obj *face_obj = NULL;
4551 EPhysics_Body_Face_Slice *face_slice = (EPhysics_Body_Face_Slice *)data;
4552 EPhysics_Body *body = face_slice->body;
4553
4554 EINA_LIST_FOREACH(body->face_objs, l, ldata)
4555 {
4556 if (((EPhysics_Body_Face_Obj *)ldata)->face == face_slice->face)
4557 {
4558 face_obj = (EPhysics_Body_Face_Obj *)ldata;
4559 break;
4560 }
4561 }
4562
4563 _ephysics_body_face_evas_object_del(body, face_obj,
4564 _ephysics_body_ellipsoid_face_obj_resize_cb);
4565 _ephysics_body_soft_body_slices_clean(face_slice->slices);
4566 DBG("Ellipsoid's face cleaned up.");
4567}
4568
4569static void
4570_ephysics_body_ellipsoid_face_evas_object_clean(EPhysics_Body *body, EPhysics_Body_Face_Obj *face_obj, Eina_List *slices)
4571{
4572 evas_object_map_enable_set(face_obj->obj, EINA_FALSE);
4573 evas_object_event_callback_del(face_obj->obj, EVAS_CALLBACK_DEL,
4574 _ephysics_body_ellipsoid_face_evas_object_del_cb);
4575 evas_object_event_callback_del(face_obj->obj, EVAS_CALLBACK_RESIZE,
4576 _ephysics_body_evas_obj_resize_cb);
4577 evas_object_event_callback_del(face_obj->obj, EVAS_CALLBACK_RESTACK,
4578 _ephysics_body_soft_body_evas_restack_cb);
4579 _ephysics_body_soft_body_slices_clean(slices);
4580
4581 _ephysics_body_face_evas_object_del(body, face_obj,
4582 _ephysics_body_ellipsoid_face_obj_resize_cb);
4583}
4584
4585static void
4586_ephysics_body_ellipsoid_face_evas_object_set(EPhysics_Body *body, EPhysics_Body_Face face, Evas_Object *evas_obj, Eina_Bool use_obj_pos)
4587{
4588 int obj_x, obj_y, obj_w, obj_h, bz, bd;
4589 double rate;
4590 EPhysics_Body_Face_Slice *face_slice = NULL;
4591 EPhysics_Body_Face_Obj *face_obj;
4592
4593 if ((face < EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_FRONT) ||
4594 (face > EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_BACK))
4595 {
4596 ERR("Can't set evas object to body, face is invalid.");
4597 return;
4598 }
4599
4600 if (!body)
4601 {
4602 ERR("Can't set evas object to body, the last wasn't provided.");
4603 return;
4604 }
4605
4606 if (!evas_obj)
4607 {
4608 ERR("Can't set evas object to body, the first wasn't provided.");
4609 return;
4610 }
4611
4612 face_slice = _ephysics_body_face_slice_get(body, face);
4613 if (!face_slice)
4614 {
4615 ERR("Could not find pre initialized face slice for the wanted face.");
4616 return;
4617 }
4618
4619 face_obj = _ephysics_body_face_evas_object_get(body, face);
4620
4621 if (face_obj)
4622 _ephysics_body_ellipsoid_face_evas_object_clean(body, face_obj,
4623 face_slice->slices);
4624
4625 _ephysics_body_face_evas_object_add(body, face, evas_obj,
4626 _ephysics_body_ellipsoid_face_obj_resize_cb);
4627
4628 evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_DEL,
4629 _ephysics_body_ellipsoid_face_evas_object_del_cb, face_slice);
4630
4631 evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_RESTACK,
4632 _ephysics_body_soft_body_evas_restack_cb,
4633 body);
4634
4635 _ephysics_body_soft_body_slices_init(body, evas_obj, face_slice->slices);
4636
4637 if (!use_obj_pos)
4638 return;
4639
4640 rate = ephysics_world_rate_get(body->world);
4641 evas_object_geometry_get(evas_obj, &obj_x, &obj_y, &obj_w, &obj_h);
4642 ephysics_body_geometry_get(body, NULL, NULL, &bz, NULL, NULL, &bd);
4643
4644 ephysics_world_lock_take(body->world);
4645 _ephysics_body_geometry_set(body, obj_x, obj_y, bz, obj_w, obj_h, bd, rate);
4646 ephysics_world_lock_release(body->world);
4647 evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_RESIZE,
4648 _ephysics_body_evas_obj_resize_cb, body);
4649 DBG("Ellipsoid face evas object set.");
4650}
4651
4652static Evas_Object *
4653_ephysics_body_ellipsoid_face_evas_object_get(const EPhysics_Body *body, EPhysics_Body_Face face)
4654{
4655 EPhysics_Body_Face_Obj *face_obj = NULL;
4656
4657 if ((face < EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_FRONT) ||
4658 (face > EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_BACK))
4659 {
4660 ERR("Can't get evas object from body, face is invalid.");
4661 return NULL;
4662 }
4663
4664 face_obj = _ephysics_body_face_evas_object_get((EPhysics_Body *)body, face);
4665 if (face_obj) return face_obj->obj;
4666
4667 ERR("Couldn't find an object associated to face %i.", face);
4668 return NULL;
4669}
4670
4671static Evas_Object *
4672_ephysics_body_ellipsoid_face_evas_object_unset(EPhysics_Body *body, EPhysics_Body_Face face)
4673{
4674 EPhysics_Body_Face_Slice *face_slice;
4675 EPhysics_Body_Face_Obj *face_obj = NULL;
4676 Evas_Object *obj;
4677
4678 if ((face < EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_FRONT) ||
4679 (face > EPHYSICS_BODY_SOFT_ELLIPSOID_FACE_BACK))
4680 {
4681 ERR("Can't unset evas object from body, face is invalid.");
4682 return NULL;
4683 }
4684
4685 face_obj = _ephysics_body_face_evas_object_get(body, face);
4686
4687 if (!face_obj) return NULL;
4688
4689 obj = face_obj->obj;
4690 face_slice = _ephysics_body_face_slice_get(body, face);
4691 _ephysics_body_ellipsoid_face_evas_object_clean(body, face_obj,
4692 face_slice->slices);
4693
4694 DBG("EPhysics Body face unset.");
4695 return obj;
4696}
4697
4306EAPI void 4698EAPI void
4307ephysics_body_face_evas_object_set(EPhysics_Body *body, EPhysics_Body_Face face, Evas_Object *evas_obj, Eina_Bool use_obj_pos) 4699ephysics_body_face_evas_object_set(EPhysics_Body *body, EPhysics_Body_Face face, Evas_Object *evas_obj, Eina_Bool use_obj_pos)
4308{ 4700{
@@ -4327,6 +4719,9 @@ ephysics_body_face_evas_object_set(EPhysics_Body *body, EPhysics_Body_Face face,
4327 if (body->shape == EPHYSICS_BODY_SHAPE_BOX) 4719 if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
4328 return _ephysics_body_box_face_evas_object_set(body, face, evas_obj, 4720 return _ephysics_body_box_face_evas_object_set(body, face, evas_obj,
4329 use_obj_pos); 4721 use_obj_pos);
4722 if (body->shape == EPHYSICS_BODY_SHAPE_ELLIPSOID)
4723 return _ephysics_body_ellipsoid_face_evas_object_set(body, face, evas_obj,
4724 use_obj_pos);
4330 4725
4331 ERR("Can't handle body %p type.", body); 4726 ERR("Can't handle body %p type.", body);
4332} 4727}
@@ -4346,6 +4741,8 @@ ephysics_body_face_evas_object_get(const EPhysics_Body *body, EPhysics_Body_Face
4346 return _ephysics_body_cylinder_face_evas_object_get(body, face); 4741 return _ephysics_body_cylinder_face_evas_object_get(body, face);
4347 if (body->shape == EPHYSICS_BODY_SHAPE_BOX) 4742 if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
4348 return _ephysics_body_box_face_evas_object_get(body, face); 4743 return _ephysics_body_box_face_evas_object_get(body, face);
4744 if (body->shape == EPHYSICS_BODY_SHAPE_ELLIPSOID)
4745 return _ephysics_body_ellipsoid_face_evas_object_get(body, face);
4349 4746
4350 ERR("Can't handle body %p type.", body); 4747 ERR("Can't handle body %p type.", body);
4351 return NULL; 4748 return NULL;
@@ -4366,6 +4763,8 @@ ephysics_body_face_evas_object_unset(EPhysics_Body *body, EPhysics_Body_Face fac
4366 return _ephysics_body_cylinder_face_evas_object_unset(body, face); 4763 return _ephysics_body_cylinder_face_evas_object_unset(body, face);
4367 if (body->shape == EPHYSICS_BODY_SHAPE_BOX) 4764 if (body->shape == EPHYSICS_BODY_SHAPE_BOX)
4368 return _ephysics_body_box_face_evas_object_unset(body, face); 4765 return _ephysics_body_box_face_evas_object_unset(body, face);
4766 if (body->shape == EPHYSICS_BODY_SHAPE_ELLIPSOID)
4767 return _ephysics_body_ellipsoid_face_evas_object_unset(body, face);
4369 4768
4370 ERR("Can't handle body %p type.", body); 4769 ERR("Can't handle body %p type.", body);
4371 return NULL; 4770 return NULL;
diff --git a/legacy/ephysics/src/lib/ephysics_private.h b/legacy/ephysics/src/lib/ephysics_private.h
index 8d5df70754..141edee503 100644
--- a/legacy/ephysics/src/lib/ephysics_private.h
+++ b/legacy/ephysics/src/lib/ephysics_private.h
@@ -60,6 +60,7 @@ typedef enum _EPhysics_Body_Shape
60 EPHYSICS_BODY_SHAPE_BOX, 60 EPHYSICS_BODY_SHAPE_BOX,
61 EPHYSICS_BODY_SHAPE_CUSTOM, 61 EPHYSICS_BODY_SHAPE_CUSTOM,
62 EPHYSICS_BODY_SHAPE_CYLINDER, 62 EPHYSICS_BODY_SHAPE_CYLINDER,
63 EPHYSICS_BODY_SHAPE_ELLIPSOID,
63 EPHYSICS_BODY_SHAPE_LAST, 64 EPHYSICS_BODY_SHAPE_LAST,
64} EPhysics_Body_Shape; 65} EPhysics_Body_Shape;
65 66
@@ -116,6 +117,7 @@ struct _EPhysics_Body_Size {
116}; 117};
117 118
118struct _EPhysics_Body_Face_Slice { 119struct _EPhysics_Body_Face_Slice {
120 EPhysics_Body *body;
119 EPhysics_Body_Face face; 121 EPhysics_Body_Face face;
120 int slices_cnt; 122 int slices_cnt;
121 int *points_deform; 123 int *points_deform;