summaryrefslogtreecommitdiff
path: root/legacy
diff options
context:
space:
mode:
authorLeandro Dorileo <dorileo@profusion.mobi>2012-08-22 20:04:39 +0000
committerBruno Dilly <bdilly@profusion.mobi>2012-08-22 20:04:39 +0000
commit18743b72ad47766450af22a5896f77f2e5fc6eea (patch)
tree9958da74334faabb40e27472d8086d9753d38ab3 /legacy
parent0ef94e328ed10c3af6679630920cd00b481589e2 (diff)
EPhysics: soft body implementation
Introduces soft body dynamics and calls to create soft circles and boxes. Patch by: Leandro Dorileo <dorileo@profusion.mobi> SVN revision: 75564
Diffstat (limited to 'legacy')
-rw-r--r--legacy/ephysics/src/bin/Makefile.am3
-rw-r--r--legacy/ephysics/src/bin/test.c2
-rw-r--r--legacy/ephysics/src/bin/test_soft_body.c160
-rw-r--r--legacy/ephysics/src/lib/EPhysics.h47
-rw-r--r--legacy/ephysics/src/lib/ephysics_body.cpp299
-rw-r--r--legacy/ephysics/src/lib/ephysics_private.h10
-rw-r--r--legacy/ephysics/src/lib/ephysics_trimesh.h292
-rw-r--r--legacy/ephysics/src/lib/ephysics_world.cpp98
8 files changed, 884 insertions, 27 deletions
diff --git a/legacy/ephysics/src/bin/Makefile.am b/legacy/ephysics/src/bin/Makefile.am
index 5f846ba06d..723a78e989 100644
--- a/legacy/ephysics/src/bin/Makefile.am
+++ b/legacy/ephysics/src/bin/Makefile.am
@@ -37,7 +37,8 @@ test_velocity.c \
37test_shapes.c \ 37test_shapes.c \
38test_sleeping_threshold.c \ 38test_sleeping_threshold.c \
39test_slider.c \ 39test_slider.c \
40test_win_resize.c 40test_win_resize.c \
41test_soft_body.c
41 42
42ephysics_logo_SOURCES = \ 43ephysics_logo_SOURCES = \
43ephysics_logo.c 44ephysics_logo.c
diff --git a/legacy/ephysics/src/bin/test.c b/legacy/ephysics/src/bin/test.c
index 0c35888609..2aabdcab3b 100644
--- a/legacy/ephysics/src/bin/test.c
+++ b/legacy/ephysics/src/bin/test.c
@@ -37,6 +37,7 @@ void test_shapes(void *data, Evas_Object *obj, void *event_info);
37void test_sleeping(void *data, Evas_Object *obj, void *event_info); 37void test_sleeping(void *data, Evas_Object *obj, void *event_info);
38void test_slider(void *data, Evas_Object *obj, void *event_info); 38void test_slider(void *data, Evas_Object *obj, void *event_info);
39void test_win_resize(void *data, Evas_Object *obj, void *event_info); 39void test_win_resize(void *data, Evas_Object *obj, void *event_info);
40void test_soft_body(void *data, Evas_Object *obj, void *event_info);
40 41
41static const EPhysics_Test tests[] = { 42static const EPhysics_Test tests[] = {
42 {"Bouncing Ball", test_bouncing_ball}, 43 {"Bouncing Ball", test_bouncing_ball},
@@ -61,6 +62,7 @@ static const EPhysics_Test tests[] = {
61 {"Sleeping Threshold", test_sleeping}, 62 {"Sleeping Threshold", test_sleeping},
62 {"Slider", test_slider}, 63 {"Slider", test_slider},
63 {"Win Resize", test_win_resize}, 64 {"Win Resize", test_win_resize},
65 {"Soft Body", test_soft_body},
64}; 66};
65 67
66static void 68static void
diff --git a/legacy/ephysics/src/bin/test_soft_body.c b/legacy/ephysics/src/bin/test_soft_body.c
new file mode 100644
index 0000000000..edd08f6092
--- /dev/null
+++ b/legacy/ephysics/src/bin/test_soft_body.c
@@ -0,0 +1,160 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ephysics_test.h"
6
7static void
8_world_populate(Test_Data *test_data)
9{
10 Evas_Object *evas_obj, *shadow;
11 EPhysics_Body *fall_body;
12
13 shadow = elm_layout_add(test_data->win);
14 elm_layout_file_set(
15 shadow, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "shadow-ball");
16 evas_object_move(shadow, WIDTH / 3, FLOOR_Y);
17 evas_object_resize(shadow, 70, 3);
18 evas_object_show(shadow);
19 test_data->evas_objs = eina_list_append(test_data->evas_objs, shadow);
20
21 evas_obj = elm_image_add(test_data->win);
22 elm_image_file_set(
23 evas_obj, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "big-red-ball");
24 evas_object_move(evas_obj, WIDTH / 3, HEIGHT / 2);
25 evas_object_resize(evas_obj, 70, 70);
26 evas_object_show(evas_obj);
27 test_data->evas_objs = eina_list_append(test_data->evas_objs, evas_obj);
28
29 fall_body = ephysics_body_soft_circle_add(test_data->world);
30 ephysics_body_evas_object_set(fall_body, evas_obj, EINA_TRUE);
31 ephysics_body_restitution_set(fall_body, 0.95);
32 ephysics_body_friction_set(fall_body, 0.1);
33 ephysics_body_event_callback_add(fall_body, EPHYSICS_CALLBACK_BODY_UPDATE,
34 update_object_cb, shadow);
35 test_data->bodies = eina_list_append(test_data->bodies, fall_body);
36
37 shadow = elm_layout_add(test_data->win);
38 elm_layout_file_set(
39 shadow, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "shadow-ball");
40 evas_object_move(shadow, WIDTH / 3, FLOOR_Y);
41 evas_object_resize(shadow, 70, 3);
42 evas_object_show(shadow);
43 test_data->evas_objs = eina_list_append(test_data->evas_objs, shadow);
44
45 evas_obj = elm_image_add(test_data->win);
46 elm_image_file_set(
47 evas_obj, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "big-blue-ball");
48 evas_object_move(evas_obj, WIDTH / 3, HEIGHT / 4);
49 evas_object_resize(evas_obj, 70, 70);
50 evas_object_show(evas_obj);
51 test_data->evas_objs = eina_list_append(test_data->evas_objs, evas_obj);
52
53 fall_body = ephysics_body_circle_add(test_data->world);
54 ephysics_body_evas_object_set(fall_body, evas_obj, EINA_TRUE);
55 ephysics_body_mass_set(fall_body, 1200);
56 ephysics_body_restitution_set(fall_body, 0.95);
57 ephysics_body_friction_set(fall_body, 0.1);
58 ephysics_body_event_callback_add(fall_body, EPHYSICS_CALLBACK_BODY_UPDATE,
59 update_object_cb, shadow);
60 test_data->bodies = eina_list_append(test_data->bodies, fall_body);
61
62 shadow = elm_layout_add(test_data->win);
63 elm_layout_file_set(
64 shadow, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "shadow-ball");
65 evas_object_move(shadow, WIDTH / 4, FLOOR_Y);
66 evas_object_resize(shadow, 70, 3);
67 evas_object_show(shadow);
68 test_data->evas_objs = eina_list_append(test_data->evas_objs, shadow);
69
70 evas_obj = elm_image_add(test_data->win);
71 elm_image_file_set(
72 evas_obj, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "big-blue-ball");
73 evas_object_move(evas_obj, WIDTH / 4, HEIGHT / 4);
74 evas_object_resize(evas_obj, 70, 70);
75 evas_object_show(evas_obj);
76 test_data->evas_objs = eina_list_append(test_data->evas_objs, evas_obj);
77
78 fall_body = ephysics_body_circle_add(test_data->world);
79 ephysics_body_evas_object_set(fall_body, evas_obj, EINA_TRUE);
80 ephysics_body_mass_set(fall_body, 600);
81 ephysics_body_restitution_set(fall_body, 0.95);
82 ephysics_body_friction_set(fall_body, 0.1);
83 ephysics_body_central_impulse_apply(fall_body, 500, 150);
84 ephysics_body_event_callback_add(fall_body, EPHYSICS_CALLBACK_BODY_UPDATE,
85 update_object_cb, shadow);
86 test_data->bodies = eina_list_append(test_data->bodies, fall_body);
87
88 shadow = elm_layout_add(test_data->win);
89 elm_layout_file_set(
90 shadow, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "shadow-cube");
91 evas_object_move(shadow, WIDTH / 6 + 60, FLOOR_Y);
92 evas_object_resize(shadow, 70, 3);
93 evas_object_show(shadow);
94 test_data->evas_objs = eina_list_append(test_data->evas_objs, shadow);
95
96 evas_obj = elm_image_add(test_data->win);
97 elm_image_file_set(
98 evas_obj, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "purple-cube");
99 evas_object_move(evas_obj, WIDTH / 6 + 60, HEIGHT / 8);
100 evas_object_resize(evas_obj, 70, 70);
101 evas_object_show(evas_obj);
102 test_data->evas_objs = eina_list_append(test_data->evas_objs, evas_obj);
103
104 fall_body = ephysics_body_soft_box_add(test_data->world);
105 ephysics_body_evas_object_set(fall_body, evas_obj, EINA_TRUE);
106 ephysics_body_event_callback_add(fall_body, EPHYSICS_CALLBACK_BODY_UPDATE,
107 update_object_cb, shadow);
108 ephysics_body_restitution_set(fall_body, 0.5);
109 ephysics_body_friction_set(fall_body, 0.1);
110 test_data->bodies = eina_list_append(test_data->bodies, fall_body);
111}
112
113static void
114_restart(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
115{
116 Test_Data *test_data = data;
117
118 DBG("Restart pressed");
119 test_clean(test_data);
120 _world_populate(test_data);
121}
122
123void
124test_soft_body(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
125{
126 EPhysics_Body *boundary;
127 EPhysics_World *world;
128 Test_Data *test_data;
129
130 if (!ephysics_init())
131 return;
132
133 test_data = test_data_new();
134 test_win_add(test_data, "Soft Body", EINA_TRUE);
135
136 elm_layout_signal_callback_add(test_data->layout, "restart", "test-theme",
137 _restart, test_data);
138 elm_object_signal_emit(test_data->layout, "borders,show", "ephysics_test");
139 elm_object_signal_emit(test_data->layout, "arrows,show", "ephysics_test");
140
141 world = ephysics_world_new();
142 ephysics_world_render_geometry_set(world, 50, 40, WIDTH - 100, FLOOR_Y - 40);
143 test_data->world = world;
144
145 boundary = ephysics_body_bottom_boundary_add(test_data->world);
146 ephysics_body_restitution_set(boundary, 0.65);
147 ephysics_body_friction_set(boundary, 4);
148
149 boundary = ephysics_body_right_boundary_add(test_data->world);
150 ephysics_body_restitution_set(boundary, 0.4);
151 ephysics_body_friction_set(boundary, 3);
152
153 boundary = ephysics_body_left_boundary_add(test_data->world);
154 ephysics_body_restitution_set(boundary, 0.4);
155 ephysics_body_friction_set(boundary, 3);
156
157 ephysics_body_top_boundary_add(test_data->world);
158
159 _world_populate(test_data);
160}
diff --git a/legacy/ephysics/src/lib/EPhysics.h b/legacy/ephysics/src/lib/EPhysics.h
index 4494881de4..da9f61c63f 100644
--- a/legacy/ephysics/src/lib/EPhysics.h
+++ b/legacy/ephysics/src/lib/EPhysics.h
@@ -1282,8 +1282,8 @@ typedef void (*EPhysics_Body_Event_Cb)(void *data, EPhysics_Body *body, void *ev
1282 * Create a new circle physics body. 1282 * Create a new circle physics body.
1283 * 1283 *
1284 * Its collision shape will be a circle of diameter 1. To change it's size 1284 * Its collision shape will be a circle of diameter 1. To change it's size
1285 * @ref ephysics_body_geometry_set() should be used, so it can be deformed 1285 * @ref ephysics_body_geometry_set() should be used.
1286 * on x and y axises. 1286 *
1287 * Any evas object can be associated to it with 1287 * Any evas object can be associated to it with
1288 * @ref ephysics_body_evas_object_set(), 1288 * @ref ephysics_body_evas_object_set(),
1289 * and it will collide as a circle (even if you have an evas rectangle). 1289 * and it will collide as a circle (even if you have an evas rectangle).
@@ -1302,11 +1302,33 @@ EAPI EPhysics_Body *ephysics_body_circle_add(EPhysics_World *world);
1302 1302
1303/** 1303/**
1304 * @brief 1304 * @brief
1305 * Create a new deformable circle physics body.
1306 *
1307 * Its collision shape will be a circle of diameter 1. To change it's size
1308 * @ref ephysics_body_geometry_set() should be used.
1309 *
1310 * Any evas object can be associated to it with
1311 * @ref ephysics_body_evas_object_set(),
1312 * and it will collide as a circle (even if you have an evas rectangle).
1313 *
1314 * Actually, since we're using a 3D backend, it will be a cylinder on
1315 * z axis.
1316 *
1317 * @param world The world this body will belongs to.
1318 * @return a new body or @c NULL, on errors.
1319 *
1320 * @see ephysics_body_del().
1321 *
1322 * @ingroup EPhysics_Body
1323 */
1324EAPI EPhysics_Body *ephysics_body_soft_circle_add(EPhysics_World *world);
1325
1326/**
1327 * @brief
1305 * Create a new box physics body. 1328 * Create a new box physics body.
1306 * 1329 *
1307 * Its collision shape will be a box of dimensions 1 on all the axises. 1330 * Its collision shape will be a box of dimensions 1 on all the axises.
1308 * To change it's size @ref ephysics_body_geometry_set() should be used, 1331 * To change it's size @ref ephysics_body_geometry_set() should be used.
1309 * so it can be deformed on x and y axises.
1310 * 1332 *
1311 * @param world The world this body will belongs to. 1333 * @param world The world this body will belongs to.
1312 * @return a new body or @c NULL, on errors. 1334 * @return a new body or @c NULL, on errors.
@@ -1320,6 +1342,23 @@ EAPI EPhysics_Body *ephysics_body_box_add(EPhysics_World *world);
1320 1342
1321/** 1343/**
1322 * @brief 1344 * @brief
1345 * Create a new deformable box physics body.
1346 *
1347 * Its collision shape will be a box of dimensions 1 on all the axises.
1348 * To change it's size @ref ephysics_body_geometry_set() should be used.
1349 *
1350 * @param world The world this body will belongs to.
1351 * @return a new body or @c NULL, on errors.
1352 *
1353 * @see ephysics_body_del().
1354 * @see ephysics_body_evas_object_set().
1355 *
1356 * @ingroup EPhysics_Body
1357 */
1358EAPI EPhysics_Body *ephysics_body_soft_box_add(EPhysics_World *world);
1359
1360/**
1361 * @brief
1323 * Create a new physics body using a custom shape. 1362 * Create a new physics body using a custom shape.
1324 * 1363 *
1325 * Its collision shape will be a convex shape that has all the points 1364 * Its collision shape will be a convex shape that has all the points
diff --git a/legacy/ephysics/src/lib/ephysics_body.cpp b/legacy/ephysics/src/lib/ephysics_body.cpp
index 287ab605ed..505dfe6534 100644
--- a/legacy/ephysics/src/lib/ephysics_body.cpp
+++ b/legacy/ephysics/src/lib/ephysics_body.cpp
@@ -4,7 +4,10 @@
4 4
5#include <Evas.h> 5#include <Evas.h>
6 6
7#include <math.h>
8
7#include "ephysics_private.h" 9#include "ephysics_private.h"
10#include "ephysics_trimesh.h"
8 11
9#ifdef __cplusplus 12#ifdef __cplusplus
10extern "C" { 13extern "C" {
@@ -236,6 +239,7 @@ _ephysics_body_add(EPhysics_World *world, btCollisionShape *collision_shape, con
236 goto err_rigid_body; 239 goto err_rigid_body;
237 } 240 }
238 241
242 body->soft_body = NULL;
239 body->collision_groups = NULL; 243 body->collision_groups = NULL;
240 body->collision_shape = collision_shape; 244 body->collision_shape = collision_shape;
241 body->rigid_body = rigid_body; 245 body->rigid_body = rigid_body;
@@ -278,6 +282,32 @@ _ephysics_body_evas_obj_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj
278} 282}
279 283
280static void 284static void
285_ephysics_body_soft_body_points_distance_get(const EPhysics_Body *body, double distances[4][3])
286{
287 btVector3 center;
288 btScalar raius;
289
290 body->soft_body->getCollisionShape()->getBoundingSphere(center, raius);
291
292 for (int m = 0; m < 4; m++)
293 {
294 for (int n = 0; n < 3; n++)
295 {
296 btVector3 node;
297 double distance;
298
299 node = body->soft_body->
300 m_faces[body->points_deform[m][n]].m_n[1]->m_x;
301
302 distance = sqrt(pow(center.x() - node.x(), 2) +
303 pow(center.y() - node.y(), 2));
304
305 distances[m][n] = distance;
306 }
307 }
308}
309
310static void
281_ephysics_body_resize(EPhysics_Body *body, Evas_Coord w, Evas_Coord h) 311_ephysics_body_resize(EPhysics_Body *body, Evas_Coord w, Evas_Coord h)
282{ 312{
283 double rate, sx, sy; 313 double rate, sx, sy;
@@ -286,10 +316,23 @@ _ephysics_body_resize(EPhysics_Body *body, Evas_Coord w, Evas_Coord h)
286 sx = w / rate; 316 sx = w / rate;
287 sy = h / rate; 317 sy = h / rate;
288 318
289 body->collision_shape->setLocalScaling(btVector3(sx, sy, 1)); 319 if (body->soft_body)
320 {
321 body->soft_body->m_anchors.resize(0);
322 body->soft_body->scale(btVector3(sx, sy, 1));
323
324 for (int i = 0; i < body->soft_body->m_nodes.size(); i++)
325 body->soft_body->appendAnchor(i, body->rigid_body);
326
327 _ephysics_body_soft_body_points_distance_get(body, body->distances);
328 }
329 else
330 {
331 body->collision_shape->setLocalScaling(btVector3(sx, sy, 1));
290 332
291 if(!body->rigid_body->isStaticObject()) 333 if(!body->rigid_body->isStaticObject())
292 ephysics_body_mass_set(body, ephysics_body_mass_get(body)); 334 ephysics_body_mass_set(body, ephysics_body_mass_get(body));
335 }
293 336
294 body->w = w; 337 body->w = w;
295 body->h = h; 338 body->h = h;
@@ -305,6 +348,7 @@ _ephysics_body_move(EPhysics_Body *body, Evas_Coord x, Evas_Coord y)
305 double rate, mx, my; 348 double rate, mx, my;
306 btTransform trans; 349 btTransform trans;
307 int wy, height; 350 int wy, height;
351 btVector3 body_scale;
308 352
309 rate = ephysics_world_rate_get(body->world); 353 rate = ephysics_world_rate_get(body->world);
310 ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, &height); 354 ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, &height);
@@ -329,6 +373,7 @@ _ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Eva
329 double mx, my, sx, sy; 373 double mx, my, sx, sy;
330 btTransform trans; 374 btTransform trans;
331 int wy, height; 375 int wy, height;
376 btVector3 body_scale;
332 377
333 ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, &height); 378 ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, &height);
334 height += wy; 379 height += wy;
@@ -340,12 +385,28 @@ _ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Eva
340 385
341 body->rigid_body->getMotionState()->getWorldTransform(trans); 386 body->rigid_body->getMotionState()->getWorldTransform(trans);
342 trans.setOrigin(btVector3(mx, my, 0)); 387 trans.setOrigin(btVector3(mx, my, 0));
343 body->rigid_body->proceedToTransform(trans);
344 388
345 body->collision_shape->setLocalScaling(btVector3(sx, sy, 1)); 389 body_scale = btVector3(sx, sy, 1);
390 if (body->soft_body)
391 {
392 body->soft_body->m_anchors.resize(0);
393 body->soft_body->scale(btVector3(sx, sy, 1));
394 body->rigid_body->proceedToTransform(trans);
395 body->soft_body->transform(trans);
346 396
347 if(!body->rigid_body->isStaticObject()) 397 for (int i = 0; i < body->soft_body->m_nodes.size(); i++)
348 ephysics_body_mass_set(body, ephysics_body_mass_get(body)); 398 body->soft_body->appendAnchor(i, body->rigid_body);
399
400 _ephysics_body_soft_body_points_distance_get(body, body->distances);
401 }
402 else
403 {
404 body->collision_shape->setLocalScaling(body_scale);
405 body->rigid_body->proceedToTransform(trans);
406
407 if (!body->rigid_body->isStaticObject())
408 ephysics_body_mass_set(body, ephysics_body_mass_get(body));
409 }
349 410
350 body->rigid_body->getMotionState()->setWorldTransform(trans); 411 body->rigid_body->getMotionState()->setWorldTransform(trans);
351 412
@@ -359,6 +420,32 @@ _ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Eva
359} 420}
360 421
361static void 422static void
423_ephysics_body_soft_body_deform(EPhysics_Body *body, double rate, Evas_Map *map)
424{
425 double curr_distances[4][3];
426
427 _ephysics_body_soft_body_points_distance_get(body, curr_distances);
428
429 for (int m = 0; m < 4; m++)
430 {
431 Evas_Coord px, py, pz;
432 double dx = 0, dy = 0;
433
434 evas_map_point_coord_get(map, m, &px, &py, &pz);
435
436 for (int n = 0; n < 3; n++)
437 {
438 double diff = (curr_distances[m][n] - body->distances[m][n]);
439 dx += diff;
440 dy += diff;
441 }
442
443 evas_map_point_coord_set(map, m, px - (dx * rate), py - (dy * rate),
444 pz);
445 }
446}
447
448static void
362_ephysics_body_evas_obj_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) 449_ephysics_body_evas_obj_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
363{ 450{
364 EPhysics_Body *body = (EPhysics_Body *) data; 451 EPhysics_Body *body = (EPhysics_Body *) data;
@@ -400,6 +487,7 @@ _ephysics_body_del(EPhysics_Body *body)
400 delete body->rigid_body->getMotionState(); 487 delete body->rigid_body->getMotionState();
401 delete body->collision_shape; 488 delete body->collision_shape;
402 delete body->rigid_body; 489 delete body->rigid_body;
490 delete body->soft_body;
403 491
404 free(body); 492 free(body);
405} 493}
@@ -443,6 +531,10 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
443 531
444 map = evas_map_new(4); 532 map = evas_map_new(4);
445 evas_map_util_points_populate_from_object(map, body->evas_obj); 533 evas_map_util_points_populate_from_object(map, body->evas_obj);
534
535 if (body->soft_body)
536 _ephysics_body_soft_body_deform(body, rate, map);
537
446 evas_map_util_rotate(map, rot, x + (w / 2), y + (h / 2)); 538 evas_map_util_rotate(map, rot, x + (w / 2), y + (h / 2));
447 evas_object_map_set(body->evas_obj, map); 539 evas_object_map_set(body->evas_obj, map);
448 evas_object_map_enable_set(body->evas_obj, EINA_TRUE); 540 evas_object_map_enable_set(body->evas_obj, EINA_TRUE);
@@ -586,6 +678,117 @@ ephysics_body_rigid_body_get(const EPhysics_Body *body)
586 return body->rigid_body; 678 return body->rigid_body;
587} 679}
588 680
681btSoftBody *
682ephysics_body_soft_body_get(const EPhysics_Body *body)
683{
684 return body->soft_body;
685}
686
687static EPhysics_Body *
688_ephysics_body_soft_add(EPhysics_World *world, btCollisionShape *collision_shape, btSoftBody *soft_body, const char *type)
689{
690 EPhysics_Body *body;
691 btSoftBody::AJoint::Specs angular_joint;
692 btSoftBody::LJoint::Specs linear_joint;
693
694 body = _ephysics_body_add(world, collision_shape, "soft box");
695 if (!body)
696 {
697 ephysics_body_del(body);
698 return NULL;
699 }
700
701 body->soft_body = soft_body;
702 body->soft_body->setUserPointer(body);
703
704 body->soft_body->getCollisionShape()->setMargin(0.22);
705
706 soft_body->m_materials[0]->m_kLST = 0.35;
707 soft_body->setPose(true, false);
708
709 body->soft_body->m_cfg.collisions += btSoftBody::fCollision::SDF_RS;
710 body->soft_body->m_cfg.collisions += btSoftBody::fCollision::CL_SS;
711
712 body->soft_body->generateClusters(body->soft_body->m_nodes.size());
713
714 angular_joint.erp = 0.;
715 angular_joint.cfm = 0.;
716 angular_joint.axis = btVector3(0, 0, 1);
717 body->soft_body->appendAngularJoint(angular_joint);
718
719 linear_joint.erp = 0.;
720 linear_joint.cfm = 0.;
721 linear_joint.position = btVector3(0, 0, 0);
722 body->soft_body->appendLinearJoint(linear_joint, body->rigid_body);
723
724 for (int i = 0; i < body->soft_body->m_nodes.size(); i++)
725 body->soft_body->appendAnchor(i, body->rigid_body);
726
727 ephysics_world_soft_body_add(world, body);
728 return body;
729}
730
731EAPI EPhysics_Body *
732ephysics_body_soft_circle_add(EPhysics_World *world)
733{
734 EPhysics_Body *body;
735 btCollisionShape *shape;
736 btSoftBodyWorldInfo *world_info;
737 btSoftBody *soft_body;
738
739 if (!world)
740 {
741 ERR("Can't add circle, world is null.");
742 return NULL;
743 }
744
745 shape = new btCylinderShapeZ(btVector3(0.25, 0.25, 0.25));
746 if (!shape)
747 {
748 ERR("Couldn't create a new cylinder shape.");
749 goto no_collision_shape;
750 }
751
752 world_info = ephysics_world_info_get(world);
753 soft_body = btSoftBodyHelpers::CreateFromTriMesh(*world_info,
754 cylinder_vertices, &cylinder_indices[0][0],
755 CYLINDER_NUM_TRIANGLES);
756 if (!soft_body)
757 {
758 ERR("Couldn't create a new soft body.");
759 goto no_soft_body;
760 }
761
762 body = _ephysics_body_soft_add(world, shape, soft_body, "soft circle");
763 if (!body)
764 goto no_body;
765
766 body->points_deform[0][0] = 72;
767 body->points_deform[0][1] = 6;
768 body->points_deform[0][2] = 65;
769
770 body->points_deform[1][0] = 72;
771 body->points_deform[1][1] = 69;
772 body->points_deform[1][2] = 3;
773
774 body->points_deform[2][0] = 57;
775 body->points_deform[2][1] = 3;
776 body->points_deform[2][2] = 76;
777
778 body->points_deform[3][0] = 54;
779 body->points_deform[3][1] = 47;
780 body->points_deform[3][2] = 65;
781
782 return body;
783
784no_body:
785 delete soft_body;
786no_soft_body:
787 delete shape;
788no_collision_shape:
789 return NULL;
790}
791
589EAPI EPhysics_Body * 792EAPI EPhysics_Body *
590ephysics_body_circle_add(EPhysics_World *world) 793ephysics_body_circle_add(EPhysics_World *world)
591{ 794{
@@ -598,11 +801,77 @@ ephysics_body_circle_add(EPhysics_World *world)
598 } 801 }
599 802
600 collision_shape = new btCylinderShapeZ(btVector3(0.5, 0.5, 0.5)); 803 collision_shape = new btCylinderShapeZ(btVector3(0.5, 0.5, 0.5));
804 if (!collision_shape)
805 {
806 ERR("Couldn't create a new cylinder shape.");
807 return NULL;
808 }
601 809
602 return _ephysics_body_add(world, collision_shape, "circle"); 810 return _ephysics_body_add(world, collision_shape, "circle");
603} 811}
604 812
605EAPI EPhysics_Body * 813EAPI EPhysics_Body *
814ephysics_body_soft_box_add(EPhysics_World *world)
815{
816 EPhysics_Body *body;
817 btCollisionShape *shape;
818 btSoftBodyWorldInfo *world_info;
819 btSoftBody *soft_body;
820
821 if (!world)
822 {
823 ERR("Can't add circle, world is null.");
824 return NULL;
825 }
826
827 shape = new btBoxShape(btVector3(0.25, 0.25, 0.25));
828 if (!shape)
829 {
830 ERR("Couldn't create a new box shape.");
831 goto no_collision_shape;
832 }
833
834 world_info = ephysics_world_info_get(world);
835 soft_body = btSoftBodyHelpers::CreateFromTriMesh(*world_info,
836 cube_vertices, &cube_indices[0][0],
837 CUBE_NUM_TRIANGLES);
838 if (!soft_body)
839 {
840 ERR("Couldn't create a new soft body.");
841 goto no_soft_body;
842 }
843
844 body = _ephysics_body_soft_add(world, shape, soft_body, "soft box");
845 if (!body)
846 goto no_body;
847
848 body->points_deform[0][0] = 27;
849 body->points_deform[0][1] = 80;
850 body->points_deform[0][2] = 69;
851
852 body->points_deform[1][0] = 85;
853 body->points_deform[1][1] = 12;
854 body->points_deform[1][2] = 30;
855
856 body->points_deform[2][0] = 18;
857 body->points_deform[2][1] = 62;
858 body->points_deform[2][2] = 8;
859
860 body->points_deform[3][0] = 50;
861 body->points_deform[3][1] = 40;
862 body->points_deform[3][2] = 60;
863
864 return body;
865
866no_body:
867 delete soft_body;
868no_soft_body:
869 delete shape;
870no_collision_shape:
871 return NULL;
872}
873
874EAPI EPhysics_Body *
606ephysics_body_box_add(EPhysics_World *world) 875ephysics_body_box_add(EPhysics_World *world)
607{ 876{
608 btCollisionShape *collision_shape; 877 btCollisionShape *collision_shape;
@@ -796,6 +1065,7 @@ ephysics_body_evas_object_set(EPhysics_Body *body, Evas_Object *evas_obj, Eina_B
796 } 1065 }
797 1066
798 body->evas_obj = evas_obj; 1067 body->evas_obj = evas_obj;
1068
799 evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_DEL, 1069 evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_DEL,
800 _ephysics_body_evas_obj_del_cb, body); 1070 _ephysics_body_evas_obj_del_cb, body);
801 1071
@@ -932,9 +1202,14 @@ ephysics_body_mass_set(EPhysics_Body *body, double mass)
932 } 1202 }
933 1203
934 btVector3 inertia(0, 0, 0); 1204 btVector3 inertia(0, 0, 0);
935 body->collision_shape->calculateLocalInertia(mass, inertia); 1205 if (body->soft_body)
936 body->rigid_body->setMassProps(mass, inertia); 1206 body->soft_body->setTotalMass(mass);
937 body->rigid_body->updateInertiaTensor(); 1207 else
1208 {
1209 body->collision_shape->calculateLocalInertia(mass, inertia);
1210 body->rigid_body->setMassProps(mass, inertia);
1211 body->rigid_body->updateInertiaTensor();
1212 }
938 body->mass = mass; 1213 body->mass = mass;
939 1214
940 DBG("Body %p mass changed to %lf.", body, mass); 1215 DBG("Body %p mass changed to %lf.", body, mass);
@@ -1380,6 +1655,10 @@ ephysics_body_rotation_set(EPhysics_Body *body, double rotation)
1380 body->rigid_body->getMotionState()->getWorldTransform(trans); 1655 body->rigid_body->getMotionState()->getWorldTransform(trans);
1381 quat.setEuler(0, 0, -rotation / RAD_TO_DEG); 1656 quat.setEuler(0, 0, -rotation / RAD_TO_DEG);
1382 trans.setRotation(quat); 1657 trans.setRotation(quat);
1658
1659 if (body->soft_body)
1660 body->soft_body->transform(trans);
1661
1383 body->rigid_body->proceedToTransform(trans); 1662 body->rigid_body->proceedToTransform(trans);
1384 body->rigid_body->getMotionState()->setWorldTransform(trans); 1663 body->rigid_body->getMotionState()->setWorldTransform(trans);
1385 1664
diff --git a/legacy/ephysics/src/lib/ephysics_private.h b/legacy/ephysics/src/lib/ephysics_private.h
index 3a3dad4736..1cd491e125 100644
--- a/legacy/ephysics/src/lib/ephysics_private.h
+++ b/legacy/ephysics/src/lib/ephysics_private.h
@@ -5,6 +5,10 @@
5# include <Evil.h> 5# include <Evil.h>
6#endif 6#endif
7 7
8#include <BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h>
9#include <BulletSoftBody/btDefaultSoftBodySolver.h>
10#include <BulletSoftBody/btSoftRigidDynamicsWorld.h>
11#include <BulletSoftBody/btSoftBodyHelpers.h>
8#include <btBulletDynamicsCommon.h> 12#include <btBulletDynamicsCommon.h>
9#include "EPhysics.h" 13#include "EPhysics.h"
10 14
@@ -65,6 +69,7 @@ struct _EPhysics_Body {
65 EINA_INLIST; 69 EINA_INLIST;
66 btCollisionShape *collision_shape; 70 btCollisionShape *collision_shape;
67 btRigidBody *rigid_body; 71 btRigidBody *rigid_body;
72 btSoftBody *soft_body;
68 Evas_Object *evas_obj; 73 Evas_Object *evas_obj;
69 EPhysics_World *world; 74 EPhysics_World *world;
70 int walking; 75 int walking;
@@ -82,6 +87,8 @@ struct _EPhysics_Body {
82 } force; 87 } force;
83 Eina_Bool active:1; 88 Eina_Bool active:1;
84 Eina_Bool deleted:1; 89 Eina_Bool deleted:1;
90 double distances[4][3];
91 int points_deform[4][3];
85}; 92};
86 93
87extern int _ephysics_log_dom; 94extern int _ephysics_log_dom;
@@ -91,12 +98,14 @@ int ephysics_world_init(void);
91int ephysics_world_shutdown(void); 98int ephysics_world_shutdown(void);
92Eina_Bool ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body); 99Eina_Bool ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body);
93Eina_Bool ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body); 100Eina_Bool ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body);
101Eina_Bool ephysics_world_soft_body_add(EPhysics_World *world, EPhysics_Body *body);
94void ephysics_world_constraint_add(EPhysics_World *world, EPhysics_Constraint *constraint, btTypedConstraint *bt_constraint); 102void ephysics_world_constraint_add(EPhysics_World *world, EPhysics_Constraint *constraint, btTypedConstraint *bt_constraint);
95void ephysics_world_constraint_del(EPhysics_World *world, EPhysics_Constraint *constraint, btTypedConstraint *bt_constraint); 103void ephysics_world_constraint_del(EPhysics_World *world, EPhysics_Constraint *constraint, btTypedConstraint *bt_constraint);
96void ephysics_body_world_boundaries_resize(EPhysics_World *world); 104void ephysics_body_world_boundaries_resize(EPhysics_World *world);
97void ephysics_world_boundary_set(EPhysics_World *world, EPhysics_World_Boundary boundary, EPhysics_Body *body); 105void ephysics_world_boundary_set(EPhysics_World *world, EPhysics_World_Boundary boundary, EPhysics_Body *body);
98EPhysics_Body *ephysics_world_boundary_get(const EPhysics_World *world, EPhysics_World_Boundary boundary); 106EPhysics_Body *ephysics_world_boundary_get(const EPhysics_World *world, EPhysics_World_Boundary boundary);
99Eina_Bool ephysics_world_bodies_outside_autodel_get(const EPhysics_World *world); 107Eina_Bool ephysics_world_bodies_outside_autodel_get(const EPhysics_World *world);
108btSoftBodyWorldInfo *ephysics_world_info_get(const EPhysics_World *world);
100 109
101/* Body */ 110/* Body */
102Eina_Bool ephysics_body_filter_collision(EPhysics_Body *body0, EPhysics_Body *body1); 111Eina_Bool ephysics_body_filter_collision(EPhysics_Body *body0, EPhysics_Body *body1);
@@ -104,6 +113,7 @@ void ephysics_body_evas_object_update_select(EPhysics_Body *body);
104void ephysics_orphan_body_del(EPhysics_Body *body); 113void ephysics_orphan_body_del(EPhysics_Body *body);
105void ephysics_body_contact_processed(EPhysics_Body *body, EPhysics_Body *contact_body, btVector3 position); 114void ephysics_body_contact_processed(EPhysics_Body *body, EPhysics_Body *contact_body, btVector3 position);
106btRigidBody *ephysics_body_rigid_body_get(const EPhysics_Body *body); 115btRigidBody *ephysics_body_rigid_body_get(const EPhysics_Body *body);
116btSoftBody *ephysics_body_soft_body_get(const EPhysics_Body *body);
107void ephysics_body_active_set(EPhysics_Body *body, Eina_Bool active); 117void ephysics_body_active_set(EPhysics_Body *body, Eina_Bool active);
108void ephysics_body_recalc(EPhysics_Body *body, double rate); 118void ephysics_body_recalc(EPhysics_Body *body, double rate);
109void ephysics_body_forces_apply(EPhysics_Body *body); 119void ephysics_body_forces_apply(EPhysics_Body *body);
diff --git a/legacy/ephysics/src/lib/ephysics_trimesh.h b/legacy/ephysics/src/lib/ephysics_trimesh.h
new file mode 100644
index 0000000000..3d17c40a1c
--- /dev/null
+++ b/legacy/ephysics/src/lib/ephysics_trimesh.h
@@ -0,0 +1,292 @@
1#ifndef EPHYSICS_TRIMESH_H
2#define EPHYSICS_TRIMESH_H
3
4#define CYLINDER_NUM_VERTICES 46
5#define CYLINDER_NUM_TRIANGLES 80
6
7static btScalar cylinder_vertices[CYLINDER_NUM_VERTICES * 3] = {
8 btScalar(0.378791), btScalar(-0.156900), btScalar(0.410000),
9 btScalar(0.381661), btScalar(0.142468), btScalar(0.410000),
10 btScalar(0.205276), btScalar(0.346467), btScalar(0.410000),
11 btScalar(-0.062845), btScalar(0.397499), btScalar(0.410000),
12 btScalar(-0.312196), btScalar(0.256566), btScalar(0.410000),
13 btScalar(-0.409345), btScalar(0.003295), btScalar(0.410000),
14 btScalar(-0.315929), btScalar(-0.250980), btScalar(0.410000),
15 btScalar(-0.085737), btScalar(-0.392946), btScalar(0.410000),
16 btScalar(0.181088), btScalar(-0.362629), btScalar(0.410000),
17 btScalar(0.378791), btScalar(-0.156900), btScalar(-0.410000),
18 btScalar(0.183474), btScalar(-0.361035), btScalar(-0.410000),
19 btScalar(-0.085737), btScalar(-0.392946), btScalar(-0.410000),
20 btScalar(-0.315929), btScalar(-0.250980), btScalar(-0.410000),
21 btScalar(-0.409345), btScalar(0.003295), btScalar(-0.410000),
22 btScalar(-0.312196), btScalar(0.256566), btScalar(-0.410000),
23 btScalar(-0.062845), btScalar(0.397499), btScalar(-0.410000),
24 btScalar(0.204218), btScalar(0.347174), btScalar(-0.410000),
25 btScalar(0.381661), btScalar(0.142468), btScalar(-0.410000),
26 btScalar(0.197462), btScalar(0.068348), btScalar(0.410000),
27 btScalar(-0.036961), btScalar(0.150675), btScalar(0.410000),
28 btScalar(0.067713), btScalar(-0.147128), btScalar(0.410000),
29 btScalar(-0.178972), btScalar(-0.060078), btScalar(0.410000),
30 btScalar(0.120907), btScalar(-0.105917), btScalar(-0.410000),
31 btScalar(-0.151098), btScalar(-0.043779), btScalar(-0.410000),
32 btScalar(0.039171), btScalar(0.161620), btScalar(-0.410000),
33 btScalar(0.311630), btScalar(-0.257414), btScalar(0.203297),
34 btScalar(-0.392051), btScalar(0.090235), btScalar(0.134737),
35 btScalar(-0.360756), btScalar(-0.183891), btScalar(0.144512),
36 btScalar(-0.141439), btScalar(-0.381866), btScalar(0.155320),
37 btScalar(0.110283), btScalar(-0.388063), btScalar(0.161516),
38 btScalar(0.320615), btScalar(-0.243966), btScalar(-0.082931),
39 btScalar(0.043971), btScalar(-0.401254), btScalar(-0.106715),
40 btScalar(-0.237476), btScalar(-0.324952), btScalar(-0.131440),
41 btScalar(-0.392954), btScalar(-0.085698), btScalar(-0.130760),
42 btScalar(-0.355705), btScalar(0.191451), btScalar(-0.132884),
43 btScalar(-0.115651), btScalar(0.386996), btScalar(-0.130213),
44 btScalar(0.169937), btScalar(0.370080), btScalar(-0.151207),
45 btScalar(0.388128), btScalar(0.109959), btScalar(-0.173023),
46 btScalar(0.401935), btScalar(-0.040547), btScalar(0.142301),
47 btScalar(0.319544), btScalar(0.245570), btScalar(0.129082),
48 btScalar(0.058047), btScalar(0.398454), btScalar(0.125903),
49 btScalar(-0.223604), btScalar(0.334221), btScalar(0.131019),
50 btScalar(-0.118588), btScalar(-0.126284), btScalar(-0.116393),
51 btScalar(0.107303), btScalar(0.062176), btScalar(0.066999),
52 btScalar(-0.052534), btScalar(0.162121), btScalar(-0.154024),
53 btScalar(-0.027084), btScalar(-0.147475), btScalar(0.173698),
54};
55
56static int cylinder_indices[CYLINDER_NUM_TRIANGLES][3] = {
57 {0, 1, 18},
58 {1, 2, 18},
59 {2, 3, 19},
60 {18, 2, 19},
61 {3, 4, 19},
62 {8, 0, 20},
63 {7, 8, 20},
64 {0, 18, 20},
65 {4, 5, 21},
66 {19, 4, 21},
67 {5, 6, 21},
68 {6, 7, 21},
69 {7, 20, 21},
70 {18, 19, 20},
71 {20, 19, 21},
72 {9, 10, 22},
73 {10, 11, 22},
74 {11, 12, 23},
75 {22, 11, 23},
76 {12, 13, 23},
77 {17, 9, 22},
78 {13, 14, 23},
79 {14, 15, 24},
80 {23, 14, 24},
81 {15, 16, 24},
82 {16, 17, 24},
83 {17, 22, 24},
84 {23, 24, 22},
85 {0, 8, 25},
86 {5, 4, 26},
87 {6, 5, 27},
88 {5, 26, 27},
89 {7, 6, 28},
90 {6, 27, 28},
91 {8, 7, 29},
92 {25, 8, 29},
93 {7, 28, 29},
94 {10, 9, 30},
95 {11, 10, 31},
96 {10, 30, 31},
97 {12, 11, 32},
98 {11, 31, 32},
99 {13, 12, 33},
100 {12, 32, 33},
101 {14, 13, 34},
102 {13, 33, 34},
103 {15, 14, 35},
104 {14, 34, 35},
105 {16, 15, 36},
106 {15, 35, 36},
107 {17, 16, 37},
108 {16, 36, 37},
109 {1, 0, 38},
110 {2, 1, 39},
111 {3, 2, 40},
112 {4, 3, 41},
113 {26, 4, 41},
114 {3, 40, 41},
115 {1, 38, 39},
116 {17, 37, 9},
117 {38, 0, 25},
118 {30, 9, 37},
119 {40, 2, 39},
120 {39, 38, 37},
121 {28, 27, 32},
122 {31, 30, 29},
123 {32, 31, 28},
124 {33, 32, 27},
125 {34, 33, 26},
126 {36, 35, 40},
127 {37, 36, 39},
128 {30, 37, 38},
129 {34, 26, 41},
130 {27, 26, 33},
131 {40, 39, 36},
132 {28, 31, 29},
133 {40, 35, 41},
134 {30, 38, 25},
135 {25, 29, 30},
136 {41, 35, 34},
137};
138
139#define CUBE_NUM_VERTICES 54
140#define CUBE_NUM_TRIANGLES 90
141
142static btScalar cube_vertices[CUBE_NUM_VERTICES * 3] = {
143 btScalar(0.400000), btScalar(-0.400000), btScalar(-0.400000),
144 btScalar(0.400000), btScalar(-0.400000), btScalar(-0.129695),
145 btScalar(0.400000), btScalar(-0.400000), btScalar(0.157468),
146 btScalar(0.400000), btScalar(-0.400000), btScalar(0.400000),
147 btScalar(-0.400000), btScalar(-0.400000), btScalar(-0.400000),
148 btScalar(-0.137266), btScalar(-0.400000), btScalar(-0.400000),
149 btScalar(0.142832), btScalar(-0.400000), btScalar(-0.400000),
150 btScalar(-0.400000), btScalar(-0.400000), btScalar(0.400000),
151 btScalar(-0.400000), btScalar(-0.400000), btScalar(0.144537),
152 btScalar(-0.400000), btScalar(-0.400000), btScalar(-0.132810),
153 btScalar(0.147946), btScalar(-0.400000), btScalar(0.400000),
154 btScalar(-0.127038), btScalar(-0.400000), btScalar(0.400000),
155 btScalar(0.400000), btScalar(-0.156914), btScalar(-0.400000),
156 btScalar(0.400000), btScalar(0.110878), btScalar(-0.400000),
157 btScalar(0.400000), btScalar(0.400000), btScalar(-0.400000),
158 btScalar(0.400000), btScalar(0.400000), btScalar(0.400000),
159 btScalar(0.400000), btScalar(0.143565), btScalar(0.400000),
160 btScalar(0.400000), btScalar(-0.142881), btScalar(0.400000),
161 btScalar(0.400000), btScalar(0.400000), btScalar(-0.142285),
162 btScalar(0.400000), btScalar(0.400000), btScalar(0.142285),
163 btScalar(-0.400000), btScalar(-0.155504), btScalar(-0.400000),
164 btScalar(-0.400000), btScalar(0.143304), btScalar(-0.400000),
165 btScalar(-0.400000), btScalar(0.400000), btScalar(-0.400000),
166 btScalar(-0.137266), btScalar(0.400000), btScalar(-0.400000),
167 btScalar(0.142832), btScalar(0.400000), btScalar(-0.400000),
168 btScalar(-0.400000), btScalar(0.400000), btScalar(0.400000),
169 btScalar(-0.400000), btScalar(0.123157), btScalar(0.400000),
170 btScalar(-0.400000), btScalar(-0.151643), btScalar(0.400000),
171 btScalar(0.147946), btScalar(0.400000), btScalar(0.400000),
172 btScalar(-0.127038), btScalar(0.400000), btScalar(0.400000),
173 btScalar(-0.400000), btScalar(0.400000), btScalar(-0.145673),
174 btScalar(-0.400000), btScalar(0.400000), btScalar(0.145673),
175 btScalar(0.149457), btScalar(-0.400000), btScalar(0.029476),
176 btScalar(-0.118651), btScalar(-0.400000), btScalar(-0.091520),
177 btScalar(-0.116729), btScalar(-0.400000), btScalar(0.185444),
178 btScalar(0.400000), btScalar(-0.030750), btScalar(0.108353),
179 btScalar(0.400000), btScalar(-0.017128), btScalar(-0.173998),
180 btScalar(-0.098445), btScalar(-0.123516), btScalar(-0.400000),
181 btScalar(0.189421), btScalar(-0.129196), btScalar(-0.400000),
182 btScalar(0.028300), btScalar(0.131810), btScalar(-0.400000),
183 btScalar(-0.121334), btScalar(-0.101441), btScalar(0.400000),
184 btScalar(0.149876), btScalar(0.018849), btScalar(0.400000),
185 btScalar(-0.114236), btScalar(0.180350), btScalar(0.400000),
186 btScalar(0.140128), btScalar(0.400000), btScalar(0.051515),
187 btScalar(-0.119461), btScalar(0.400000), btScalar(-0.055704),
188 btScalar(-0.400000), btScalar(-0.140426), btScalar(-0.044838),
189 btScalar(-0.400000), btScalar(0.123997), btScalar(0.045044),
190 btScalar(-0.157858), btScalar(-0.190293), btScalar(0.146609),
191 btScalar(0.104141), btScalar(-0.199541), btScalar(0.222140),
192 btScalar(-0.207788), btScalar(0.065226), btScalar(0.172945),
193 btScalar(0.103299), btScalar(-0.168979), btScalar(-0.094225),
194 btScalar(0.130475), btScalar(0.068676), btScalar(-0.129420),
195 btScalar(0.065630), btScalar(0.075409), btScalar(0.150963),
196 btScalar(-0.172328), btScalar(0.041173), btScalar(-0.142551),
197};
198
199static int cube_indices[CUBE_NUM_TRIANGLES][3] = {
200 {0, 1, 6},
201 {1, 2, 32},
202 {2, 3, 10},
203 {4, 5, 9},
204 {5, 6, 33},
205 {9, 5, 33},
206 {8, 34, 7},
207 {8, 9, 33},
208 {10, 11, 34},
209 {11, 7, 34},
210 {2, 10, 32},
211 {6, 1, 32},
212 {34, 8, 33},
213 {6, 32, 33},
214 {10, 34, 32},
215 {32, 34, 33},
216 {36, 1, 12},
217 {2, 1, 35},
218 {3, 2, 17},
219 {12, 13, 36},
220 {13, 14, 18},
221 {15, 16, 19},
222 {19, 16, 35},
223 {16, 17, 35},
224 {18, 19, 35},
225 {17, 2, 35},
226 {0, 12, 1},
227 {13, 18, 36},
228 {35, 1, 36},
229 {36, 18, 35},
230 {6, 38, 0},
231 {5, 4, 20},
232 {6, 5, 37},
233 {5, 20, 37},
234 {13, 12, 38},
235 {14, 13, 24},
236 {20, 21, 37},
237 {21, 22, 23},
238 {23, 24, 39},
239 {21, 23, 39},
240 {24, 13, 39},
241 {12, 0, 38},
242 {13, 38, 39},
243 {37, 21, 39},
244 {39, 38, 37},
245 {6, 37, 38},
246 {10, 3, 17},
247 {7, 11, 27},
248 {27, 11, 40},
249 {11, 10, 40},
250 {16, 15, 28},
251 {17, 16, 41},
252 {26, 42, 25},
253 {26, 27, 40},
254 {28, 29, 42},
255 {29, 25, 42},
256 {16, 28, 41},
257 {10, 17, 41},
258 {10, 41, 40},
259 {26, 40, 42},
260 {42, 40, 41},
261 {28, 42, 41},
262 {18, 14, 24},
263 {15, 19, 28},
264 {19, 18, 43},
265 {28, 19, 43},
266 {23, 22, 30},
267 {24, 23, 44},
268 {25, 29, 31},
269 {29, 28, 43},
270 {23, 30, 44},
271 {44, 30, 31},
272 {43, 44, 29},
273 {18, 24, 43},
274 {31, 29, 44},
275 {24, 44, 43},
276 {4, 9, 20},
277 {8, 7, 27},
278 {9, 8, 45},
279 {8, 27, 45},
280 {22, 21, 30},
281 {26, 25, 31},
282 {26, 31, 46},
283 {27, 26, 46},
284 {31, 30, 46},
285 {20, 9, 45},
286 {30, 21, 46},
287 {45, 27, 46},
288 {46, 21, 45},
289 {21, 20, 45},
290};
291
292#endif
diff --git a/legacy/ephysics/src/lib/ephysics_world.cpp b/legacy/ephysics/src/lib/ephysics_world.cpp
index d8314cac4e..157cd219b8 100644
--- a/legacy/ephysics/src/lib/ephysics_world.cpp
+++ b/legacy/ephysics/src/lib/ephysics_world.cpp
@@ -10,6 +10,8 @@
10extern "C" { 10extern "C" {
11#endif 11#endif
12 12
13#define DEFAULT_GRAVITY btVector3(0, -9.8, 0)
14
13typedef struct _EPhysics_World_Callback EPhysics_World_Callback; 15typedef struct _EPhysics_World_Callback EPhysics_World_Callback;
14 16
15struct _EPhysics_World_Callback { 17struct _EPhysics_World_Callback {
@@ -26,7 +28,9 @@ struct _EPhysics_World {
26 btDefaultCollisionConfiguration* collision; 28 btDefaultCollisionConfiguration* collision;
27 btCollisionDispatcher* dispatcher; 29 btCollisionDispatcher* dispatcher;
28 btSequentialImpulseConstraintSolver* solver; 30 btSequentialImpulseConstraintSolver* solver;
29 btDiscreteDynamicsWorld* dynamics_world; 31 btSoftRigidDynamicsWorld* dynamics_world;
32 btSoftBodyWorldInfo* world_info;
33 btSoftBodySolver* soft_solver;
30 34
31 EPhysics_Body *boundaries[4]; 35 EPhysics_Body *boundaries[4];
32 EPhysics_Camera *camera; 36 EPhysics_Camera *camera;
@@ -39,6 +43,7 @@ struct _EPhysics_World {
39 int max_sub_steps; 43 int max_sub_steps;
40 int walking; 44 int walking;
41 int cb_walking; 45 int cb_walking;
46 int soft_body_ref;
42 double last_update; 47 double last_update;
43 double rate; 48 double rate;
44 double fixed_time_step; 49 double fixed_time_step;
@@ -60,6 +65,12 @@ static Eina_List *_worlds_to_delete = NULL;
60static Ecore_Animator *_anim_simulate = NULL; 65static Ecore_Animator *_anim_simulate = NULL;
61static int _worlds_walking = 0; 66static int _worlds_walking = 0;
62 67
68btSoftBodyWorldInfo *
69ephysics_world_info_get(const EPhysics_World *world)
70{
71 return world->world_info;
72}
73
63struct _ephysics_world_ovelap_filter_cb : public btOverlapFilterCallback 74struct _ephysics_world_ovelap_filter_cb : public btOverlapFilterCallback
64{ 75{
65 virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0, 76 virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,
@@ -81,7 +92,11 @@ struct _ephysics_world_ovelap_filter_cb : public btOverlapFilterCallback
81static inline void 92static inline void
82_ephysics_world_gravity_set(EPhysics_World *world, double gx, double gy, double rate) 93_ephysics_world_gravity_set(EPhysics_World *world, double gx, double gy, double rate)
83{ 94{
84 world->dynamics_world->setGravity(btVector3(gx / rate, -gy / rate, 0)); 95 btVector3 gravity;
96
97 gravity = btVector3(gx / rate, -gy / rate, 0);
98 world->dynamics_world->setGravity(gravity);
99 world->world_info->m_gravity = gravity;
85} 100}
86 101
87static void 102static void
@@ -226,6 +241,8 @@ _ephysics_world_free(EPhysics_World *world)
226 delete world->broadphase; 241 delete world->broadphase;
227 delete world->dispatcher; 242 delete world->dispatcher;
228 delete world->collision; 243 delete world->collision;
244 delete world->soft_solver;
245 delete world->world_info;
229 */ 246 */
230 247
231 free(world); 248 free(world);
@@ -259,8 +276,15 @@ _simulate_worlds(void *data __UNUSED__)
259 world->last_update = time_now; 276 world->last_update = time_now;
260 277
261 gDeactivationTime = world->max_sleeping_time; 278 gDeactivationTime = world->max_sleeping_time;
262 world->dynamics_world->stepSimulation(delta, world->max_sub_steps, 279
280 if (world->soft_body_ref)
281 world->dynamics_world->stepSimulation(delta, world->max_sub_steps,
263 world->fixed_time_step); 282 world->fixed_time_step);
283 else
284 ((btDiscreteDynamicsWorld *)world->dynamics_world)->stepSimulation(
285 delta, world->max_sub_steps,
286 world->fixed_time_step);
287
264 world->walking--; 288 world->walking--;
265 289
266 if (!world->walking) 290 if (!world->walking)
@@ -322,8 +346,9 @@ _ephysics_world_boundary_del_cb(void *data, EPhysics_Body *body, void *event_inf
322Eina_Bool 346Eina_Bool
323ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body) 347ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body)
324{ 348{
325 world->bodies = eina_inlist_append(world->bodies, 349 if (!eina_inlist_find(world->bodies, EINA_INLIST_GET(body)))
326 EINA_INLIST_GET(body)); 350 world->bodies = eina_inlist_append(world->bodies, EINA_INLIST_GET(body));
351
327 if (eina_error_get()) 352 if (eina_error_get())
328 { 353 {
329 ERR("Couldn't add body to bodies list."); 354 ERR("Couldn't add body to bodies list.");
@@ -331,13 +356,14 @@ ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body)
331 } 356 }
332 357
333 world->dynamics_world->addRigidBody(ephysics_body_rigid_body_get(body)); 358 world->dynamics_world->addRigidBody(ephysics_body_rigid_body_get(body));
334
335 return EINA_TRUE; 359 return EINA_TRUE;
336} 360}
337 361
338Eina_Bool 362Eina_Bool
339ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body) 363ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body)
340{ 364{
365 btSoftBody *soft_body;
366
341 if (world->walking) 367 if (world->walking)
342 { 368 {
343 world->to_delete = eina_list_append(world->to_delete, body); 369 world->to_delete = eina_list_append(world->to_delete, body);
@@ -345,13 +371,37 @@ ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body)
345 } 371 }
346 372
347 world->dynamics_world->removeRigidBody(ephysics_body_rigid_body_get(body)); 373 world->dynamics_world->removeRigidBody(ephysics_body_rigid_body_get(body));
348 world->bodies = eina_inlist_remove(world->bodies, 374
349 EINA_INLIST_GET(body)); 375 soft_body = ephysics_body_soft_body_get(body);
376 if (soft_body)
377 {
378 world->dynamics_world->removeSoftBody(soft_body);
379 --world->soft_body_ref;
380 }
381
382 world->bodies = eina_inlist_remove(world->bodies, EINA_INLIST_GET(body));
350 ephysics_orphan_body_del(body); 383 ephysics_orphan_body_del(body);
351 384
352 return EINA_TRUE; 385 return EINA_TRUE;
353} 386}
354 387
388Eina_Bool
389ephysics_world_soft_body_add(EPhysics_World *world, EPhysics_Body *body)
390{
391 if (!eina_inlist_find(world->bodies, EINA_INLIST_GET(body)))
392 world->bodies = eina_inlist_append(world->bodies, EINA_INLIST_GET(body));
393
394 if (eina_error_get())
395 {
396 ERR("Couldn't add body to bodies list.");
397 return EINA_FALSE;
398 }
399
400 ++world->soft_body_ref;
401 world->dynamics_world->addSoftBody(ephysics_body_soft_body_get(body));
402 return EINA_TRUE;
403}
404
355void 405void
356ephysics_world_constraint_add(EPhysics_World *world, EPhysics_Constraint *constraint, btTypedConstraint *bt_constraint) 406ephysics_world_constraint_add(EPhysics_World *world, EPhysics_Constraint *constraint, btTypedConstraint *bt_constraint)
357{ 407{
@@ -446,7 +496,7 @@ ephysics_world_new(void)
446 goto no_broadphase; 496 goto no_broadphase;
447 } 497 }
448 498
449 world->collision = new btDefaultCollisionConfiguration(); 499 world->collision = new btSoftBodyRigidBodyCollisionConfiguration();
450 if (!world->collision) 500 if (!world->collision)
451 { 501 {
452 ERR("Couldn't configure collision."); 502 ERR("Couldn't configure collision.");
@@ -467,15 +517,34 @@ ephysics_world_new(void)
467 goto no_solver; 517 goto no_solver;
468 } 518 }
469 519
470 world->dynamics_world = new btDiscreteDynamicsWorld( 520 world->soft_solver = new btDefaultSoftBodySolver();
521 if (!world->soft_solver)
522 {
523 ERR("Couldn't create soft body solver.");
524 goto no_soft_solver;
525 }
526
527 world->dynamics_world = new btSoftRigidDynamicsWorld(
471 world->dispatcher, world->broadphase, world->solver, 528 world->dispatcher, world->broadphase, world->solver,
472 world->collision); 529 world->collision, world->soft_solver);
473 if (!world->dynamics_world) 530 if (!world->dynamics_world)
474 { 531 {
475 ERR("Couldn't create dynamic world."); 532 ERR("Couldn't create dynamic world.");
476 goto no_world; 533 goto no_world;
477 } 534 }
478 535
536 world->world_info = new btSoftBodyWorldInfo();
537 if (!world->world_info)
538 {
539 ERR("Couldn't create soft body world info.");
540 goto no_world_info;
541 }
542
543 world->world_info->m_gravity = DEFAULT_GRAVITY;
544 world->world_info->m_broadphase = world->broadphase;
545 world->world_info->m_dispatcher = world->dispatcher;
546 world->world_info->m_sparsesdf.Initialize();
547
479 _worlds = eina_inlist_append(_worlds, EINA_INLIST_GET(world)); 548 _worlds = eina_inlist_append(_worlds, EINA_INLIST_GET(world));
480 if (eina_error_get()) 549 if (eina_error_get())
481 { 550 {
@@ -485,7 +554,7 @@ ephysics_world_new(void)
485 554
486 world->dynamics_world->getSolverInfo().m_solverMode ^= 555 world->dynamics_world->getSolverInfo().m_solverMode ^=
487 EPHYSICS_WORLD_SOLVER_SIMD; 556 EPHYSICS_WORLD_SOLVER_SIMD;
488 world->dynamics_world->setGravity(btVector3(0, -9.8, 0)); 557 world->dynamics_world->setGravity(DEFAULT_GRAVITY);
489 558
490 filter_cb = new _ephysics_world_ovelap_filter_cb(); 559 filter_cb = new _ephysics_world_ovelap_filter_cb();
491 if (!filter_cb) 560 if (!filter_cb)
@@ -493,6 +562,7 @@ ephysics_world_new(void)
493 else 562 else
494 world->dynamics_world->getPairCache()->setOverlapFilterCallback(filter_cb); 563 world->dynamics_world->getPairCache()->setOverlapFilterCallback(filter_cb);
495 564
565 world->soft_body_ref = 0;
496 world->rate = 30; 566 world->rate = 30;
497 world->max_sub_steps = 3; 567 world->max_sub_steps = 3;
498 world->fixed_time_step = 1/60.f; 568 world->fixed_time_step = 1/60.f;
@@ -510,8 +580,12 @@ ephysics_world_new(void)
510 return world; 580 return world;
511 581
512no_list: 582no_list:
583 delete world->world_info;
584no_world_info:
513 delete world->dynamics_world; 585 delete world->dynamics_world;
514no_world: 586no_world:
587 delete world->soft_solver;
588no_soft_solver:
515 delete world->solver; 589 delete world->solver;
516no_solver: 590no_solver:
517 delete world->dispatcher; 591 delete world->dispatcher;