aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeandro Dorileo <dorileo@profusion.mobi>2012-10-04 22:40:16 +0000
committerBruno Dilly <bdilly@profusion.mobi>2012-10-04 22:40:16 +0000
commit252643a33b65af308f3084ddc407459221e96677 (patch)
tree279e243b0dd91f133c020878033791f3053c74a6
parentEPhysics: multi point deformation (diff)
downloadefl-252643a33b65af308f3084ddc407459221e96677.tar.gz
EPhysics: add cloth support
This patch introduces the cloth support. Auxiliary API's for setting full anchors, cloth nodes anchors and so on is also introduced. Few other issues concerning soft body and cloth transform, has been worked to fit the cloth support needs. Patch by: Leandro Dorileo <dorileo@profusion.mobi> SVN revision: 77467
-rw-r--r--legacy/ephysics/data/themes/Makefile.am4
-rw-r--r--legacy/ephysics/data/themes/ephysics_test.edc1
-rw-r--r--legacy/ephysics/data/themes/images/brown-pole.pngbin0 -> 1507 bytes
-rw-r--r--legacy/ephysics/data/themes/images/green-flag.pngbin0 -> 2093 bytes
-rw-r--r--legacy/ephysics/data/themes/others.edc42
-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_flag.c94
-rw-r--r--legacy/ephysics/src/lib/EPhysics.h118
-rw-r--r--legacy/ephysics/src/lib/ephysics_body.cpp443
-rw-r--r--legacy/ephysics/src/lib/ephysics_constraints.cpp17
-rw-r--r--legacy/ephysics/src/lib/ephysics_private.h16
-rw-r--r--legacy/ephysics/src/lib/ephysics_world.cpp20
13 files changed, 677 insertions, 83 deletions
diff --git a/legacy/ephysics/data/themes/Makefile.am b/legacy/ephysics/data/themes/Makefile.am
index c7e2001a44..0973a55d1f 100644
--- a/legacy/ephysics/data/themes/Makefile.am
+++ b/legacy/ephysics/data/themes/Makefile.am
@@ -55,7 +55,9 @@ EXTRA_DIST = \
images/spinner_bt_left_pressed.png \
images/spinner_bt_right.png \
images/spinner_bt_right_pressed.png \
- images/star.png
+ images/star.png \
+ images/green-flag.png \
+ images/brown-pole.png
ephysics_test.edj: Makefile $(EXTRA_DIST)
$(EDJE_CC) $(EDJE_FLAGS) \
diff --git a/legacy/ephysics/data/themes/ephysics_test.edc b/legacy/ephysics/data/themes/ephysics_test.edc
index 4d7a02be0e..2e1f427604 100644
--- a/legacy/ephysics/data/themes/ephysics_test.edc
+++ b/legacy/ephysics/data/themes/ephysics_test.edc
@@ -12,4 +12,5 @@ collections {
#include "shadows.edc"
#include "shapes.edc"
#include "spinner.edc"
+#include "others.edc"
}
diff --git a/legacy/ephysics/data/themes/images/brown-pole.png b/legacy/ephysics/data/themes/images/brown-pole.png
new file mode 100644
index 0000000000..d0e24d996e
--- /dev/null
+++ b/legacy/ephysics/data/themes/images/brown-pole.png
Binary files differ
diff --git a/legacy/ephysics/data/themes/images/green-flag.png b/legacy/ephysics/data/themes/images/green-flag.png
new file mode 100644
index 0000000000..7b331916d1
--- /dev/null
+++ b/legacy/ephysics/data/themes/images/green-flag.png
Binary files differ
diff --git a/legacy/ephysics/data/themes/others.edc b/legacy/ephysics/data/themes/others.edc
new file mode 100644
index 0000000000..4c436a13ac
--- /dev/null
+++ b/legacy/ephysics/data/themes/others.edc
@@ -0,0 +1,42 @@
+ images {
+ image: "green-flag.png" COMP;
+ image: "brown-pole.png" COMP;
+ }
+
+ group {
+ name: "green-flag";
+
+ parts {
+
+ part {
+ name: "flag";
+ mouse_events: 0;
+ type: IMAGE;
+ description {
+ state: "default" 0.0;
+ image.normal: "green-flag.png";
+ }
+ }
+
+ }
+
+ }
+
+ group {
+ name: "brown-pole";
+
+ parts {
+
+ part {
+ name: "pole";
+ mouse_events: 0;
+ type: IMAGE;
+ description {
+ state: "default" 0.0;
+ image.normal: "brown-pole.png";
+ }
+ }
+
+ }
+
+ } \ No newline at end of file
diff --git a/legacy/ephysics/src/bin/Makefile.am b/legacy/ephysics/src/bin/Makefile.am
index 1dc99669c4..9bd4eb9876 100644
--- a/legacy/ephysics/src/bin/Makefile.am
+++ b/legacy/ephysics/src/bin/Makefile.am
@@ -39,7 +39,8 @@ test_shapes.c \
test_sleeping_threshold.c \
test_slider.c \
test_soft_body.c \
-test_win_resize.c
+test_win_resize.c \
+test_flag.c
ephysics_logo_SOURCES = \
ephysics_logo.c
diff --git a/legacy/ephysics/src/bin/test.c b/legacy/ephysics/src/bin/test.c
index 7a60961884..f512356254 100644
--- a/legacy/ephysics/src/bin/test.c
+++ b/legacy/ephysics/src/bin/test.c
@@ -26,6 +26,7 @@ void test_collision_speed(void *data, Evas_Object *obj, void *event_info);
void test_constraint(void *data, Evas_Object *obj, void *event_info);
void test_delete(void *data, Evas_Object *obj, void *event_info);
void test_falling_letters(void *data, Evas_Object *obj, void *event_info);
+void test_flag(void *data, Evas_Object *obj, void *event_info);
void test_forces(void *data, Evas_Object *obj, void *event_info);
void test_growing_balls(void *data, Evas_Object *obj, void *event_info);
void test_jumping_balls(void *data, Evas_Object *obj, void *event_info);
@@ -52,6 +53,7 @@ static const EPhysics_Test tests[] = {
{"Constraint", test_constraint},
{"Delete Body", test_delete},
{"Falling Letters", test_falling_letters},
+ {"Flag - Cloth", test_flag},
{"Forces", test_forces},
{"Growing Balls", test_growing_balls},
{"Jumping Balls", test_jumping_balls},
diff --git a/legacy/ephysics/src/bin/test_flag.c b/legacy/ephysics/src/bin/test_flag.c
new file mode 100644
index 0000000000..85fd728086
--- /dev/null
+++ b/legacy/ephysics/src/bin/test_flag.c
@@ -0,0 +1,94 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ephysics_test.h"
+
+static void
+_world_populate(Test_Data *test_data)
+{
+ Evas_Object *evas_obj;
+ EPhysics_Body *flag_body, *pole_body;
+
+ evas_obj = elm_image_add(test_data->win);
+ elm_image_file_set(
+ evas_obj, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "brown-pole");
+ evas_object_move(evas_obj, 150, FLOOR_Y - 280);
+ evas_object_resize(evas_obj, 17, 280);
+ evas_object_show(evas_obj);
+ test_data->evas_objs = eina_list_append(test_data->evas_objs, evas_obj);
+
+ pole_body = ephysics_body_box_add(test_data->world);
+ ephysics_body_mass_set(pole_body, 0);
+ ephysics_body_evas_object_set(pole_body, evas_obj, EINA_TRUE);
+ ephysics_body_restitution_set(pole_body, 0.5);
+ ephysics_body_friction_set(pole_body, 0.1);
+ test_data->bodies = eina_list_append(test_data->bodies, pole_body);
+
+ evas_obj = elm_image_add(test_data->win);
+ elm_image_file_set(
+ evas_obj, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "green-flag");
+ evas_object_move(evas_obj, 150 + 17, FLOOR_Y - 280 + 14);
+ evas_object_resize(evas_obj, 180, 126);
+ evas_object_show(evas_obj);
+ test_data->evas_objs = eina_list_append(test_data->evas_objs, evas_obj);
+
+ flag_body = ephysics_body_cloth_add(test_data->world, 0);
+ ephysics_body_mass_set(flag_body, 10);
+ ephysics_body_soft_body_hardness_set(flag_body, 1);
+ evas_obj = ephysics_body_evas_object_set(flag_body, evas_obj, EINA_TRUE);
+ ephysics_body_restitution_set(flag_body, 0.5);
+ ephysics_body_friction_set(flag_body, 0.1);
+ test_data->evas_objs = eina_list_append(test_data->evas_objs, evas_obj);
+ test_data->bodies = eina_list_append(test_data->bodies, flag_body);
+ ephysics_body_cloth_anchor_full_add(flag_body, pole_body,
+ EPHYSICS_BODY_CLOTH_ANCHOR_SIDE_LEFT);
+}
+
+static void
+_restart(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+ Test_Data *test_data = data;
+
+ DBG("Restart pressed");
+ test_clean(test_data);
+ _world_populate(test_data);
+}
+
+void
+test_flag(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ EPhysics_Body *boundary;
+ EPhysics_World *world;
+ Test_Data *test_data;
+
+ if (!ephysics_init())
+ return;
+
+ test_data = test_data_new();
+ test_win_add(test_data, "Flag", EINA_TRUE);
+
+ elm_layout_signal_callback_add(test_data->layout, "restart", "test-theme",
+ _restart, test_data);
+ elm_object_signal_emit(test_data->layout, "borders,show", "ephysics_test");
+
+ world = ephysics_world_new();
+ ephysics_world_simulation_set(world, 1/160.f, 10);
+ ephysics_world_render_geometry_set(world, 50, 40, WIDTH - 100, FLOOR_Y - 40);
+ test_data->world = world;
+
+ boundary = ephysics_body_bottom_boundary_add(test_data->world);
+ ephysics_body_restitution_set(boundary, 0.65);
+ ephysics_body_friction_set(boundary, 4);
+
+ boundary = ephysics_body_right_boundary_add(test_data->world);
+ ephysics_body_restitution_set(boundary, 0.4);
+ ephysics_body_friction_set(boundary, 3);
+
+ boundary = ephysics_body_left_boundary_add(test_data->world);
+ ephysics_body_restitution_set(boundary, 0.4);
+ ephysics_body_friction_set(boundary, 3);
+
+ ephysics_body_top_boundary_add(test_data->world);
+ _world_populate(test_data);
+}
diff --git a/legacy/ephysics/src/lib/EPhysics.h b/legacy/ephysics/src/lib/EPhysics.h
index 5e1809bb1f..5533b5761f 100644
--- a/legacy/ephysics/src/lib/EPhysics.h
+++ b/legacy/ephysics/src/lib/EPhysics.h
@@ -1427,6 +1427,24 @@ EAPI void ephysics_world_simulation_get(const EPhysics_World *world, double *fix
#define EPHYSICS_BODY_RESTITUTION_PLASTIC (0.6)
/**
+ * @enum _EPhysics_Body_Cloth_Anchor_Side
+ * @typedef EPhysics_Body_Cloth_Anchor_Side
+ *
+ * Identifier of cloth anchor sides.
+ *
+ * @see ephysics_body_cloth_anchor_full_add()
+ *
+ * @ingroup EPhysics_Body
+ */
+typedef enum _EPhysics_Body_Cloth_Anchor_Side
+{
+ EPHYSICS_BODY_CLOTH_ANCHOR_SIDE_LEFT,
+ EPHYSICS_BODY_CLOTH_ANCHOR_SIDE_RIGHT,
+ EPHYSICS_BODY_CLOTH_ANCHOR_SIDE_TOP,
+ EPHYSICS_BODY_CLOTH_ANCHOR_SIDE_BOTTOM,
+} EPhysics_Body_Cloth_Anchor_Side;
+
+/**
* @typedef EPhysics_Body_Collision
*
* Body collision wraps collision informations.
@@ -1628,8 +1646,8 @@ EAPI EPhysics_Body *ephysics_body_box_add(EPhysics_World *world);
*
* For a rigid circle, check @ref ephysics_body_circle_add().
*
- * @param world The world this body will belongs to.
- * @return a new body or @c NULL, on errors.
+ * @param world The world this body will belong to.
+ * @return a new body or @c NULL on errors.
*
* @see ephysics_body_del().
* @see ephysics_body_evas_object_set().
@@ -1641,6 +1659,102 @@ EAPI EPhysics_Body *ephysics_body_soft_box_add(EPhysics_World *world);
/**
* @brief
+ * Create a new deformable cloth physics body.
+ *
+ * A cloth has its points of deformation conceptually split into rows and columns
+ * where every square is also split into two triangles - afore named nodes. To
+ * fine tune the deformation one can increase this granularity by increasing the
+ * @p granularity parameter.
+ *
+ * The number of rows is always proportional to the number of columns, for
+ * example passing @p granularity of 20 will create a cloth with 20 rows and 20
+ * columns.
+ *
+ * By default EPhysics creates a cloth with 10 rows and 10 columns, these default
+ * values will generally fit the most common scenarios.
+ *
+ * If the informed @p granularity is of 0 then the default value - of 10 - is
+ * assumed.
+ *
+ * @param world The world this body will belong to.
+ * @granularity Define - proportionally - the number of rows and columns, if 0
+ * the default value - of 10 - is assumed.
+ * @return a bew body or @c NULL on erros.
+ *
+ * @see ephysics_body_del().
+ * @see ephysics_body_evas_object_set().
+ * @see ephysics_world_simulation_set().
+ * @see ephysics_body_cloth_anchor_add().
+ * @see ephysics_body_cloth_anchor_full_add().
+ *
+ * @ingroup EPhysics_Body
+ */
+EAPI EPhysics_Body *ephysics_body_cloth_add(EPhysics_World *world, unsigned short granularity);
+
+/**
+ * @brief
+ * Anchors a cloth with a rigid body.
+ *
+ * All the informed @p side of @p body1 will be anchored to @p body1 wherever
+ * it's in time of anchoring. That is, all the nodes in the informed "edge".
+ *
+ * An anchor assumes the @p body1 positions, if it's 20px far from @p body2 then
+ * this distance is always kept, moving @p body1 or @p body2 will respect a 20px
+ * difference.
+ *
+ * @param body1 The cloth body to be anchored.
+ * @param body2 The body to be anchored to.
+ * @param side The side to be anchored.
+ *
+ * @see ephysics_body_cloth_anchor_add().
+ * @see ephysics_body_cloth_anchor_del().
+ * @see ephysics_body_cloth_add() to know more about the cloth physics
+ * representation.
+ * @ingroup EPhysics_Body
+ */
+EAPI void ephysics_body_cloth_anchor_full_add(EPhysics_Body *body1, EPhysics_Body *body2, EPhysics_Body_Cloth_Anchor_Side side);
+
+/**
+ * @brief
+ * Anchors an arbitrary cloth's node with a rigid body.
+ *
+ * The informed @p node of @p body1 will be anchored to @p body2 wherever it's
+ * in time of anchoring.
+ *
+ * @see ephysics_body_cloth_add() to know more about the cloth physics
+ * representation, nodes and so on.
+ *
+ * An anchor assumes the @p body1 positions, if it's 20px far from @p body2 then
+ * this distance is always kept, moving @p body1 or @p body2 will respect a 20px
+ * difference.
+ *
+ * @param body1 The cloth body to be anchored.
+ * @param body2 The body to be anchored to.
+ * @param node The node index to be anchored.
+ *
+ * @see ephysics_body_cloth_anchor_full_add().
+ * @see ephysics_body_cloth_anchor_del().
+
+ *
+ * @ingroup EPhysics_Body
+ */
+EAPI void ephysics_body_cloth_anchor_add(EPhysics_Body *body1, EPhysics_Body *body2, int node);
+
+/**
+ * @brief
+ * Removes the anchors in a cloth body.
+ *
+ * @param body The body to delete anchors from.
+ *
+ * @see ephysics_body_cloth_anchor_full_add().
+ * @see ephysics_body_cloth_anchor_add().
+ *
+ * @ingroup EPhysics_Body
+ */
+EAPI void ephysics_body_cloth_anchor_del(EPhysics_Body *body);
+
+/**
+ * @brief
* Create a new physics body using a custom shape.
*
* 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 954c951f40..4fd499ae15 100644
--- a/legacy/ephysics/src/lib/ephysics_body.cpp
+++ b/legacy/ephysics/src/lib/ephysics_body.cpp
@@ -68,13 +68,14 @@ _ephysics_body_soft_body_slices_apply(Evas_Object *obj)
double rate;
void *data;
Eina_List *l;
- Evas_Coord x, y, h, wy, wh, y0, y1, y2, x0, x1, x2;
+ Evas_Coord x, y, h, wy, wh, y0, y1, y2, x0, x1, x2, z0, z1, z2;
Evas_Map *map;
btVector3 p0, p1, p2;
btSoftBody::tFaceArray faces;
EPhysics_Body_Soft_Body_Slice *slice;
EPhysics_Body_Soft_Body_Smart_Data *smart_data;
EPhysics_Body *body;
+ short z_factor;
EPHYSICS_BODY_SOFT_BODY_SMART_DATA_GET(obj, smart_data);
body = smart_data->body;
@@ -98,19 +99,28 @@ _ephysics_body_soft_body_slices_apply(Evas_Object *obj)
x1 = p1.x() * rate;
x2 = p2.x() * rate;
+ z0 = p0.z() * rate;
+ z1 = p1.z() * rate;
+ z2 = p2.z() * rate;
+
+ z_factor = p0.z() + p1.z() + p2.z();
+ z_factor = (z_factor < 0) ? -z_factor : z_factor;
+
+ evas_object_layer_set(slice->evas_obj, z_factor);
evas_object_map_enable_set(slice->evas_obj, EINA_FALSE);
map = (Evas_Map *)evas_object_map_get((const Evas_Object *)
slice->evas_obj);
evas_object_image_smooth_scale_set(slice->evas_obj, EINA_TRUE);
- evas_map_point_coord_set(map, 0, x0, y0, 0);
- evas_map_point_coord_set(map, 1, x1, y1, 0);
- evas_map_point_coord_set(map, 2, x2, y2, 0);
- evas_map_point_coord_set(map, 3, x2, y2, 0);
+ evas_map_point_coord_set(map, 0, x0, y0, z0);
+ evas_map_point_coord_set(map, 1, x1, y1, z1);
+ evas_map_point_coord_set(map, 2, x2, y2, z2);
+ evas_map_point_coord_set(map, 3, x2, y2, z2);
evas_object_map_set(slice->evas_obj, map);
evas_object_map_enable_set(slice->evas_obj, EINA_TRUE);
+ evas_object_show(slice->evas_obj);
}
}
@@ -136,7 +146,7 @@ static Eina_Bool
_ephysics_body_soft_body_slices_init(EPhysics_Body *body, Evas_Object *obj)
{
double rate;
- Evas_Coord x, y, w, h, wy, wh, y0, y1, y2, x0, x1, x2;
+ Evas_Coord x, y, w, h, wy, wh, y0, y1, y2, x0, x1, x2, z0, z1, z2;
Evas_Map *map;
Evas *evas;
EPhysics_Body_Soft_Body_Smart_Data *smart_data;
@@ -177,6 +187,10 @@ _ephysics_body_soft_body_slices_init(EPhysics_Body *body, Evas_Object *obj)
x1 = p1.x() * rate;
x2 = p2.x() * rate;
+ z0 = p0.z() * rate;
+ z1 = p1.z() * rate;
+ z2 = p2.z() * rate;
+
map = evas_map_new(4);
evas_map_util_points_populate_from_object(map, slice->evas_obj);
@@ -185,17 +199,16 @@ _ephysics_body_soft_body_slices_init(EPhysics_Body *body, Evas_Object *obj)
evas_map_point_image_uv_set(map, 2, x2 - x, y2 - y);
evas_map_point_image_uv_set(map, 3, x2 - x, y2 - y);
- evas_map_point_coord_set(map, 0, x0, y0, 0);
- evas_map_point_coord_set(map, 1, x1, y1, 0);
- evas_map_point_coord_set(map, 2, x2, y2, 0);
- evas_map_point_coord_set(map, 3, x2, y2, 0);
+ evas_map_point_coord_set(map, 0, x0, y0, z0);
+ evas_map_point_coord_set(map, 1, x1, y1, z1);
+ evas_map_point_coord_set(map, 2, x2, y2, z2);
+ evas_map_point_coord_set(map, 3, x2, y2, z2);
evas_object_map_set(slice->evas_obj, map);
evas_object_map_enable_set(slice->evas_obj, EINA_TRUE);
evas_map_free(map);
smart_data->slices = eina_list_append(smart_data->slices, slice);
- evas_object_smart_member_add(slice->evas_obj, obj);
}
return EINA_TRUE;
@@ -349,6 +362,63 @@ _ephysics_body_soft_body_evas_add(EPhysics_Body *body)
return obj;
}
+static btTransform
+_ephysics_body_transform_get(const EPhysics_Body *body)
+{
+ btTransform trans;
+ btVector3 center;
+ btScalar radius;
+
+ if (body->type == EPHYSICS_BODY_TYPE_RIGID)
+ {
+ body->rigid_body->getMotionState()->getWorldTransform(trans);
+ return trans;
+ }
+
+ body->soft_body->getCollisionShape()->getBoundingSphere(center, radius);
+ trans.setIdentity();
+ trans.setOrigin(center);
+ return trans;
+}
+
+static void
+_ephysics_body_transform_set(EPhysics_Body *body, btTransform trans)
+{
+ btTransform origin;
+ btTransform dest;
+
+ if (body->type == EPHYSICS_BODY_TYPE_CLOTH)
+ {
+ origin = _ephysics_body_transform_get(body);
+ dest.setIdentity();
+ dest.setOrigin(trans.getOrigin() / origin.getOrigin());
+ body->soft_body->translate(trans.getOrigin() - origin.getOrigin());
+ return;
+ }
+ body->rigid_body->getMotionState()->setWorldTransform(trans);
+}
+
+static btVector3
+_ephysics_body_scale_get(const EPhysics_Body *body)
+{
+ if (body->type == EPHYSICS_BODY_TYPE_RIGID)
+ return body->collision_shape->getLocalScaling();
+
+ return body->soft_body->getCollisionShape()->getLocalScaling();
+}
+
+void
+ephysics_body_activate(const EPhysics_Body *body, Eina_Bool activate)
+{
+ if (body->type == EPHYSICS_BODY_TYPE_RIGID)
+ {
+ body->rigid_body->activate(activate);
+ return;
+ }
+
+ body->soft_body->activate(activate);
+}
+
static void
_ephysics_body_forces_update(EPhysics_Body *body)
{
@@ -515,7 +585,27 @@ ephysics_body_collision_group_list_get(const EPhysics_Body *body)
}
static EPhysics_Body *
-_ephysics_body_add(EPhysics_World *world, btCollisionShape *collision_shape, const char *type, double cm_x, double cm_y)
+_ephysics_body_new(EPhysics_World *world, btScalar mass, double cm_x, double cm_y)
+{
+ EPhysics_Body *body;
+
+ body = (EPhysics_Body *) calloc(1, sizeof(EPhysics_Body));
+ if (!body)
+ {
+ ERR("Couldn't create a new body instance.");
+ return NULL;
+ }
+
+ body->mass = mass;
+ body->world = world;
+ body->cm.x = cm_x;
+ body->cm.y = cm_y;
+
+ return body;
+}
+
+static EPhysics_Body *
+_ephysics_body_rigid_body_add(EPhysics_World *world, btCollisionShape *collision_shape, const char *type, double cm_x, double cm_y)
{
btRigidBody::btRigidBodyConstructionInfo *rigid_body_ci;
btDefaultMotionState *motion_state;
@@ -530,7 +620,7 @@ _ephysics_body_add(EPhysics_World *world, btCollisionShape *collision_shape, con
return NULL;
}
- body = (EPhysics_Body *) calloc(1, sizeof(EPhysics_Body));
+ body = _ephysics_body_new(world, mass, cm_x, cm_y);
if (!body)
{
ERR("Couldn't create a new body instance.");
@@ -562,12 +652,9 @@ _ephysics_body_add(EPhysics_World *world, btCollisionShape *collision_shape, con
goto err_rigid_body;
}
+ body->type = EPHYSICS_BODY_TYPE_RIGID;
body->collision_shape = collision_shape;
body->rigid_body = rigid_body;
- body->mass = mass;
- body->world = world;
- body->cm.x = cm_x;
- body->cm.y = cm_y;
body->rigid_body->setUserPointer(body);
body->rigid_body->setLinearFactor(btVector3(1, 1, 0));
body->rigid_body->setAngularFactor(btVector3(0, 0, 1));
@@ -618,6 +705,37 @@ _ephysics_body_soft_body_anchors_rebuild(int node, btRigidBody *rigid_body, btSo
}
static void
+_ephysics_body_cloth_constraints_rebuild(EPhysics_Body *body)
+{
+ btRigidBody *rigid_body;
+ btSoftBody *soft_body;
+ btSoftBody::Node *node;
+ btSoftBody::Anchor anchor;
+ int anchors_size = body->soft_body->m_anchors.size();
+
+ soft_body = body->soft_body;
+
+ if (anchors_size)
+ {
+ rigid_body = soft_body->m_anchors[0].m_body;
+ for (int m = 0; m < anchors_size; m++)
+ {
+ anchor = soft_body->m_anchors[m];
+ node = anchor.m_node;
+ for (int n = 0; n < soft_body->m_nodes.size(); n++)
+ {
+ if (node == &soft_body->m_nodes[n])
+ _ephysics_body_soft_body_anchors_rebuild(n, rigid_body,
+ soft_body);
+ }
+ }
+ }
+
+ soft_body->generateClusters(0);
+ soft_body->generateBendingConstraints(2, soft_body->m_materials[0]);
+}
+
+static void
_ephysics_body_soft_body_constraints_rebuild(EPhysics_Body *body)
{
btSoftBody *soft_body = body->soft_body;
@@ -691,7 +809,7 @@ _ephysics_body_resize(EPhysics_Body *body, Evas_Coord w, Evas_Coord h)
body->w = w;
body->h = h;
- body->rigid_body->activate(1);
+ ephysics_body_activate(body, EINA_TRUE);
DBG("Body %p scale changed to %lf, %lf.", body, sx, sy);
}
@@ -711,12 +829,12 @@ _ephysics_body_move(EPhysics_Body *body, Evas_Coord x, Evas_Coord y)
mx = (x + body->w * body->cm.x) / rate;
my = (height - (y + body->h * body->cm.y)) / rate;
- body->rigid_body->getMotionState()->getWorldTransform(trans);
+ trans = _ephysics_body_transform_get(body);
trans.setOrigin(btVector3(mx, my, 0));
body->rigid_body->proceedToTransform(trans);
body->rigid_body->getMotionState()->setWorldTransform(trans);
- body->rigid_body->activate(1);
+ ephysics_body_activate(body, EINA_TRUE);
DBG("Body %p position changed to %lf, %lf.", body, mx, my);
}
@@ -737,17 +855,23 @@ _ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Eva
sx = w / rate;
sy = h / rate;
- body->rigid_body->getMotionState()->getWorldTransform(trans);
- trans.setOrigin(btVector3(mx, my, 0));
-
+ trans = _ephysics_body_transform_get(body);
+ trans.setOrigin(btVector3(mx, my, trans.getOrigin().z()));
body_scale = btVector3(sx, sy, 1);
- if (body->soft_body)
+
+ if (body->type == EPHYSICS_BODY_TYPE_SOFT)
{
- body->soft_body->scale(btVector3(sx, sy, 1));
+ body->soft_body->scale(body_scale);
body->rigid_body->proceedToTransform(trans);
body->soft_body->transform(trans);
_ephysics_body_soft_body_constraints_rebuild(body);
}
+ else if (body->type == EPHYSICS_BODY_TYPE_CLOTH)
+ {
+ body->soft_body->scale(body_scale);
+ _ephysics_body_transform_set(body, trans);
+ _ephysics_body_cloth_constraints_rebuild(body);
+ }
else
{
body->collision_shape->setLocalScaling(body_scale);
@@ -757,13 +881,12 @@ _ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Eva
_ephysics_body_mass_set(body, ephysics_body_mass_get(body));
}
- body->rigid_body->getMotionState()->setWorldTransform(trans);
+ _ephysics_body_transform_set(body, trans);
+ ephysics_body_activate(body, EINA_TRUE);
body->w = w;
body->h = h;
- body->rigid_body->activate(1);
-
DBG("Body %p position changed to %lf, %lf.", body, mx, my);
DBG("Body %p scale changed to %lf, %lf.", body, sx, sy);
}
@@ -811,9 +934,13 @@ _ephysics_body_del(EPhysics_Body *body)
free(body->points_deform);
- delete body->rigid_body->getMotionState();
- delete body->collision_shape;
- delete body->rigid_body;
+ if (body->rigid_body)
+ {
+ delete body->rigid_body->getMotionState();
+ delete body->collision_shape;
+ delete body->rigid_body;
+ }
+
delete body->soft_body;
free(body);
@@ -831,9 +958,8 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
if (!body->evas_obj)
return;
- body->rigid_body->getMotionState()->getWorldTransform(trans);
+ trans = _ephysics_body_transform_get(body);
ephysics_world_render_geometry_get(body->world, &wx, &wy, NULL, &wh);
-
camera = ephysics_world_camera_get(body->world);
ephysics_camera_position_get(camera, &cx, &cy);
cx -= wx;
@@ -853,7 +979,7 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
return;
}
- if (body->soft_body)
+ if (body->type != EPHYSICS_BODY_TYPE_RIGID)
return;
rot = - trans.getRotation().getAngle() * RAD_TO_DEG *
@@ -901,7 +1027,7 @@ ephysics_body_forces_apply(EPhysics_Body *body)
return;
rate = ephysics_world_rate_get(body->world);
- body->rigid_body->activate(1);
+ ephysics_body_activate(body, EINA_TRUE);
body->rigid_body->applyCentralForce(btVector3(body->force.x / rate,
body->force.y / rate, 0));
body->rigid_body->applyTorque(btVector3(0, 0, body->force.torque));
@@ -1015,7 +1141,7 @@ static void
_ephysics_body_soft_body_hardness_set(EPhysics_Body *body, double hardness)
{
btSoftBody *soft_body = body->soft_body;
- soft_body->m_cfg.kAHR = (hardness / 1000) * 0.6;
+ soft_body->m_cfg.kAHR = (hardness / body->anchor_prop) * 0.6;
soft_body->m_materials[0]->m_kVST = (hardness / 1000);
soft_body->m_materials[0]->m_kLST = (hardness / 1000);
soft_body->m_materials[0]->m_kAST = (hardness / 1000);
@@ -1066,12 +1192,27 @@ ephysics_body_soft_body_hardness_get(const EPhysics_Body *body)
return (body->soft_body->m_materials[0]->m_kVST * 100);
}
+static void
+_ephysics_body_soft_body_default_config(EPhysics_Body *body, btSoftBody *soft_body)
+{
+ body->soft_body = soft_body;
+ body->soft_body->getCollisionShape()->setMargin(btScalar(0.02));
+ body->soft_body->setUserPointer(body);
+ body->soft_body->setTotalMass(body->mass);
+
+ body->soft_body->m_cfg.collisions += btSoftBody::fCollision::SDF_RS;
+ body->soft_body->m_cfg.collisions += btSoftBody::fCollision::VF_SS;
+
+ _ephysics_body_soft_body_hardness_set(body, 100);
+}
+
static EPhysics_Body *
_ephysics_body_soft_body_add(EPhysics_World *world, btCollisionShape *collision_shape, btSoftBody *soft_body)
{
EPhysics_Body *body;
- body = _ephysics_body_add(world, collision_shape, "soft box", 0.5, 0.5);
+ body = _ephysics_body_rigid_body_add(world, collision_shape, "soft box", 0.5,
+ 0.5);
if (!body)
{
if (body->deleted) return NULL;
@@ -1079,16 +1220,11 @@ _ephysics_body_soft_body_add(EPhysics_World *world, btCollisionShape *collision_
ephysics_world_body_del(body->world, body);
return NULL;
}
- body->soft_body = soft_body;
- body->soft_body->getCollisionShape()->setMargin(btScalar(0.02));
- body->soft_body->setUserPointer(body);
- body->soft_body->setTotalMass(body->mass);
+ body->anchor_prop = 1000;
+ body->type = EPHYSICS_BODY_TYPE_SOFT;
+ _ephysics_body_soft_body_default_config(body, soft_body);
- body->soft_body->m_cfg.collisions += btSoftBody::fCollision::SDF_RS;
- body->soft_body->m_cfg.collisions += btSoftBody::fCollision::VF_SS;
-
- _ephysics_body_soft_body_hardness_set(body, 100);
body->rigid_body->setCollisionFlags(
btCollisionObject::CF_NO_CONTACT_RESPONSE);
@@ -1097,6 +1233,157 @@ _ephysics_body_soft_body_add(EPhysics_World *world, btCollisionShape *collision_
return body;
}
+EAPI void
+ephysics_body_cloth_anchor_full_add(EPhysics_Body *body1, EPhysics_Body *body2, EPhysics_Body_Cloth_Anchor_Side side)
+{
+ int rows;
+ int columns;
+
+ if (!body1 || !body2)
+ {
+ ERR("Could not add anchors, body1 or body2 is null");
+ return;
+ }
+
+ if (body1->type != EPHYSICS_BODY_TYPE_CLOTH ||
+ body2->type != EPHYSICS_BODY_TYPE_RIGID)
+ {
+ ERR("Cloth anchors are allowed only between cloth and rigid body.");
+ return;
+ }
+
+ rows = body1->cloth_rows;
+ columns = body1->cloth_columns;
+
+ if (side == EPHYSICS_BODY_CLOTH_ANCHOR_SIDE_LEFT)
+ {
+ for (int i = 0; i < rows; i++)
+ body1->soft_body->appendAnchor(i, body2->rigid_body);
+ return;
+ }
+
+ if (side == EPHYSICS_BODY_CLOTH_ANCHOR_SIDE_RIGHT)
+ {
+ for (int i = 1; i <= rows; i++)
+ body1->soft_body->appendAnchor((rows * columns) - i,
+ body2->rigid_body);
+ return;
+ }
+
+ if (side == EPHYSICS_BODY_CLOTH_ANCHOR_SIDE_TOP)
+ {
+ for (int i = 0; i <= rows; i++)
+ body1->soft_body->appendAnchor(i * rows, body2->rigid_body);
+ return;
+ }
+
+ if (side == EPHYSICS_BODY_CLOTH_ANCHOR_SIDE_BOTTOM)
+ {
+ for (int i = 0; i < columns; i++)
+ body1->soft_body->appendAnchor((rows - 1) + rows * i,
+ body2->rigid_body);
+ }
+}
+
+EAPI void
+ephysics_body_cloth_anchor_add(EPhysics_Body *body1, EPhysics_Body *body2, int node)
+{
+ if (!body1 || !body2)
+ {
+ ERR("Could not add anchors, body1 or body2 is null");
+ return;
+ }
+
+ if (body1->type != EPHYSICS_BODY_TYPE_CLOTH ||
+ body2->type != EPHYSICS_BODY_TYPE_RIGID)
+ {
+ ERR("Cloth anchors are allowed only between cloth and rigid body.");
+ return;
+ }
+
+ body1->soft_body->appendAnchor(node, body2->rigid_body);
+}
+
+EAPI void
+ephysics_body_cloth_anchor_del(EPhysics_Body *body)
+{
+ if (!body)
+ {
+ ERR("Could not delete anchor, body is null.");
+ return;
+ }
+
+ if (body->type != EPHYSICS_BODY_TYPE_CLOTH)
+ {
+ ERR("Could not delete anchors, body is not a cloth.");
+ return;
+ }
+
+ body->soft_body->m_anchors.resize(0);
+}
+
+EAPI EPhysics_Body *
+ephysics_body_cloth_add(EPhysics_World *world, unsigned short granularity)
+{
+ EPhysics_Body *body;
+ btSoftBodyWorldInfo *world_info;
+ btSoftBody *soft_body;
+ const int rows = (!granularity) ? 10 : granularity;
+ const int columns = (!granularity) ? 10 : granularity;
+
+ if (!world)
+ {
+ ERR("Can't add circle, world is null.");
+ return NULL;
+ }
+
+ world_info = ephysics_world_info_get(world);
+ soft_body = btSoftBodyHelpers::CreatePatch(*world_info,
+ btVector3(1, 2, 0.5),
+ btVector3(1, 1, 0.5),
+ btVector3(2, 2, 0.5),
+ btVector3(2, 1, 0.5),
+ rows, columns, 0, false);
+ if (!soft_body)
+ {
+ ERR("Couldn't create a new soft body.");
+ return NULL;
+ }
+
+ body = _ephysics_body_new(world, 1, 0.5, 0.5);
+ if (!body)
+ goto no_body;
+
+ _ephysics_body_soft_body_default_config(body, soft_body);
+ soft_body->m_cfg.piterations = 10;
+ _ephysics_body_cloth_constraints_rebuild(body);
+
+ body->slices = soft_body->m_faces.size();
+ body->points_deform = (int *)malloc(body->slices * sizeof(int));
+ if (!body->points_deform)
+ {
+ ERR("Couldn't create points of deformation.");
+ goto no_deform;
+ }
+
+ for (int i = 0; i < body->slices; i++)
+ body->points_deform[i] = i;
+
+ body->cloth_columns = columns;
+ body->cloth_rows = rows;
+ body->anchor_prop = 100;
+ body->type = EPHYSICS_BODY_TYPE_CLOTH;
+
+ ephysics_world_soft_body_add(world, body);
+ return body;
+
+no_deform:
+ free(body);
+no_body:
+ delete soft_body;
+ return NULL;
+}
+
EAPI EPhysics_Body *
ephysics_body_soft_circle_add(EPhysics_World *world)
{
@@ -1181,7 +1468,8 @@ ephysics_body_circle_add(EPhysics_World *world)
}
ephysics_world_lock_take(world);
- body = _ephysics_body_add(world, collision_shape, "circle", 0.5, 0.5);
+ body = _ephysics_body_rigid_body_add(world, collision_shape, "circle", 0.5,
+ 0.5);
ephysics_world_lock_release(world);
return body;
}
@@ -1265,7 +1553,7 @@ ephysics_body_box_add(EPhysics_World *world)
collision_shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
ephysics_world_lock_take(world);
- body = _ephysics_body_add(world, collision_shape, "box", 0.5, 0.5);
+ body = _ephysics_body_rigid_body_add(world, collision_shape, "box", 0.5, 0.5);
ephysics_world_lock_release(world);
return body;
}
@@ -1380,9 +1668,10 @@ ephysics_body_shape_add(EPhysics_World *world, EPhysics_Shape *shape)
}
ephysics_world_lock_take(world);
- body = _ephysics_body_add(world, (btCollisionShape *)simplified_shape,
- "generic", (cm_x - min_x) / range_x,
- 1 - (cm_y - min_y) / range_y);
+ body = _ephysics_body_rigid_body_add(world,
+ (btCollisionShape *)simplified_shape,
+ "generic", (cm_x - min_x) / range_x,
+ 1 - (cm_y - min_y) / range_y);
ephysics_world_lock_release(world);
return body;
}
@@ -1552,9 +1841,12 @@ ephysics_body_evas_object_set(EPhysics_Body *body, Evas_Object *evas_obj, Eina_B
if (body->soft_body)
{
- body->evas_obj = _ephysics_body_soft_body_evas_add(body);
evas_object_event_callback_del(evas_obj, EVAS_CALLBACK_DEL,
_ephysics_body_evas_obj_del_cb);
+
+ evas_obj = _ephysics_body_soft_body_evas_add(body);
+ body->evas_obj = evas_obj;
+
evas_object_event_callback_add(body->evas_obj, EVAS_CALLBACK_DEL,
_ephysics_body_evas_obj_del_cb, body);
}
@@ -1661,7 +1953,7 @@ EAPI void
ephysics_body_geometry_get(const EPhysics_Body *body, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
{
btTransform trans;
- btVector3 vector;
+ btVector3 scale;
double rate;
int wy, height;
@@ -1671,15 +1963,15 @@ ephysics_body_geometry_get(const EPhysics_Body *body, Evas_Coord *x, Evas_Coord
return;
}
- body->rigid_body->getMotionState()->getWorldTransform(trans);
- vector = body->collision_shape->getLocalScaling();
+ trans = _ephysics_body_transform_get(body);
+ scale = _ephysics_body_scale_get(body);
rate = ephysics_world_rate_get(body->world);
ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, &height);
height += wy;
- if (x) *x = round((trans.getOrigin().getX() - vector.x() / 2) * rate);
- if (y) *y = height - round((trans.getOrigin().getY() + vector.y() / 2)
+ if (x) *x = round((trans.getOrigin().getX() - scale.x() / 2) * rate);
+ if (y) *y = height - round((trans.getOrigin().getY() + scale.y() / 2)
* rate);
if (w) *w = body->w;
if (h) *h = body->h;
@@ -1960,7 +2252,13 @@ ephysics_body_event_callback_del_full(EPhysics_Body *body, EPhysics_Callback_Bod
static void
_ephysics_body_restitution_set(EPhysics_Body *body, double restitution)
{
- body->rigid_body->setRestitution(btScalar(restitution));
+ if (body->type == EPHYSICS_BODY_TYPE_RIGID)
+ {
+ body->rigid_body->setRestitution(btScalar(restitution));
+ return;
+ }
+
+ body->soft_body->setRestitution(btScalar(restitution));
DBG("Body %p restitution set to %lf", body, restitution);
}
@@ -1988,13 +2286,22 @@ ephysics_body_restitution_get(const EPhysics_Body *body)
return 0;
}
- return body->rigid_body->getRestitution();
+ if (body->type == EPHYSICS_BODY_TYPE_RIGID)
+ return body->rigid_body->getRestitution();
+
+ return body->soft_body->getRestitution();
}
static void
_ephysics_body_friction_set(EPhysics_Body *body, double friction)
{
- body->rigid_body->setFriction(btScalar(friction));
+ if (body->type == EPHYSICS_BODY_TYPE_RIGID)
+ {
+ body->rigid_body->setFriction(btScalar(friction));
+ return;
+ }
+
+ body->soft_body->setFriction(btScalar(friction));
DBG("Body %p friction set to %lf", body, friction);
}
@@ -2022,7 +2329,10 @@ ephysics_body_friction_get(const EPhysics_Body *body)
return 0;
}
- return body->rigid_body->getFriction();
+ if (body->type == EPHYSICS_BODY_TYPE_RIGID)
+ return body->rigid_body->getFriction();
+
+ return body->soft_body->getFriction();
}
EAPI EPhysics_World *
@@ -2051,7 +2361,7 @@ ephysics_body_central_impulse_apply(EPhysics_Body *body, double x, double y)
rate = ephysics_world_rate_get(body->world);
ephysics_world_lock_take(body->world);
- body->rigid_body->activate(1);
+ ephysics_body_activate(body, EINA_TRUE);
body->rigid_body->applyCentralImpulse(btVector3(x / rate, - y / rate, 0));
ephysics_world_lock_release(body->world);
}
@@ -2070,7 +2380,7 @@ ephysics_body_impulse_apply(EPhysics_Body *body, double x, double y, Evas_Coord
rate = ephysics_world_rate_get(body->world);
ephysics_world_lock_take(body->world);
- body->rigid_body->activate(1);
+ ephysics_body_activate(body, EINA_TRUE);
body->rigid_body->applyImpulse(btVector3(x / rate, - y / rate, 0),
btVector3((double) pos_x / rate,
(double) pos_y / rate, 0));
@@ -2114,7 +2424,7 @@ ephysics_body_torque_impulse_apply(EPhysics_Body *body, double roll)
}
ephysics_world_lock_take(body->world);
- body->rigid_body->activate(1);
+ ephysics_body_activate(body, EINA_TRUE);
body->rigid_body->applyTorqueImpulse(btVector3(0, 0, -roll));
ephysics_world_lock_release(body->world);
}
@@ -2160,7 +2470,7 @@ ephysics_body_rotation_get(const EPhysics_Body *body)
return 0;
}
- body->rigid_body->getMotionState()->getWorldTransform(trans);
+ trans = _ephysics_body_transform_get(body);
rot = - trans.getRotation().getAngle() * RAD_TO_DEG *
trans.getRotation().getAxis().getZ();
@@ -2180,8 +2490,9 @@ ephysics_body_rotation_set(EPhysics_Body *body, double rotation)
}
ephysics_world_lock_take(body->world);
- body->rigid_body->activate(1);
- body->rigid_body->getMotionState()->getWorldTransform(trans);
+ ephysics_body_activate(body, EINA_TRUE);
+ trans = _ephysics_body_transform_get(body);
+
quat.setEuler(0, 0, -rotation / RAD_TO_DEG);
trans.setRotation(quat);
diff --git a/legacy/ephysics/src/lib/ephysics_constraints.cpp b/legacy/ephysics/src/lib/ephysics_constraints.cpp
index 834d923a2b..ed5c5c8411 100644
--- a/legacy/ephysics/src/lib/ephysics_constraints.cpp
+++ b/legacy/ephysics/src/lib/ephysics_constraints.cpp
@@ -119,6 +119,13 @@ ephysics_constraint_slider_add(EPhysics_Body *body)
return NULL;
}
+ if (body->type == EPHYSICS_BODY_TYPE_CLOTH)
+ {
+ ERR("Constraints are allowed only between rigid -> rigid bodies or "
+ "rigid -> soft bodies");
+ return NULL;
+ }
+
constraint = (EPhysics_Constraint *) calloc(1, sizeof(EPhysics_Constraint));
if (!constraint)
{
@@ -277,11 +284,19 @@ ephysics_constraint_p2p_add(EPhysics_Body *body1, EPhysics_Body *body2, Evas_Coo
if ((body2) &&
(ephysics_body_world_get(body1) != ephysics_body_world_get(body2)))
{
- ERR("To create a constraint both bodies must to belong to the same"
+ ERR("To create a constraint both bodies must belong to the same"
"world.");
return NULL;
}
+ if (body1->type == EPHYSICS_BODY_TYPE_CLOTH ||
+ body2->type == EPHYSICS_BODY_TYPE_CLOTH)
+ {
+ ERR("Constraints are allowed only between rigid -> rigid bodies or"
+ "rigid -> soft bodies");
+ return NULL;
+ }
+
constraint = (EPhysics_Constraint *) calloc(1, sizeof(EPhysics_Constraint));
if (!constraint)
{
diff --git a/legacy/ephysics/src/lib/ephysics_private.h b/legacy/ephysics/src/lib/ephysics_private.h
index 91e4de84ce..5fd51d54ea 100644
--- a/legacy/ephysics/src/lib/ephysics_private.h
+++ b/legacy/ephysics/src/lib/ephysics_private.h
@@ -65,6 +65,13 @@ struct _EPhysics_Point {
double y;
};
+typedef enum _EPhysics_Body_Type
+{
+ EPHYSICS_BODY_TYPE_RIGID,
+ EPHYSICS_BODY_TYPE_SOFT,
+ EPHYSICS_BODY_TYPE_CLOTH,
+} EPhysics_Body_Type;
+
struct _EPhysics_Body {
EINA_INLIST;
btCollisionShape *collision_shape;
@@ -95,6 +102,10 @@ struct _EPhysics_Body {
Eina_Bool deleted:1;
int slices;
int *points_deform;
+ EPhysics_Body_Type type;
+ int cloth_columns;
+ int cloth_rows;
+ int anchor_prop;
};
extern int _ephysics_log_dom;
@@ -116,6 +127,8 @@ void ephysics_world_boundary_set(EPhysics_World *world, EPhysics_World_Boundary
EPhysics_Body *ephysics_world_boundary_get(const EPhysics_World *world, EPhysics_World_Boundary boundary);
Eina_Bool ephysics_world_bodies_outside_autodel_get(const EPhysics_World *world);
btSoftBodyWorldInfo *ephysics_world_info_get(const EPhysics_World *world);
+void ephysics_world_lock_take(EPhysics_World *world);
+void ephysics_world_lock_release(EPhysics_World *world);
/* Body */
Eina_Bool ephysics_body_filter_collision(EPhysics_Body *body0, EPhysics_Body *body1);
@@ -127,8 +140,7 @@ btSoftBody *ephysics_body_soft_body_get(const EPhysics_Body *body);
void ephysics_body_active_set(EPhysics_Body *body, Eina_Bool active);
void ephysics_body_recalc(EPhysics_Body *body, double rate);
void ephysics_body_forces_apply(EPhysics_Body *body);
-void ephysics_world_lock_take(EPhysics_World *world);
-void ephysics_world_lock_release(EPhysics_World *world);
+void ephysics_body_activate(const EPhysics_Body *body, Eina_Bool activate);
/* Camera */
EPhysics_Camera *ephysics_camera_add(EPhysics_World *world);
diff --git a/legacy/ephysics/src/lib/ephysics_world.cpp b/legacy/ephysics/src/lib/ephysics_world.cpp
index fd7492804e..e7655588db 100644
--- a/legacy/ephysics/src/lib/ephysics_world.cpp
+++ b/legacy/ephysics/src/lib/ephysics_world.cpp
@@ -171,9 +171,10 @@ _ephysics_world_tick(btDynamicsWorld *dynamics_world)
{
Eina_Bool world_active, camera_moved, tx, ty;
btCollisionObjectArray objects;
- btRigidBody *rigid_body;
+ btCollisionObject *collision;
EPhysics_World *world;
EPhysics_Body *body;
+ btRigidBody *rigid_body;
world = (EPhysics_World *) dynamics_world->getWorldUserInfo();
@@ -192,12 +193,13 @@ _ephysics_world_tick(btDynamicsWorld *dynamics_world)
objects = dynamics_world->getCollisionObjectArray();
for (int i = 0; i < objects.size(); i++)
{
- btRigidBody *rigid_body = btRigidBody::upcast(objects[i]);
- if (!rigid_body)
+ collision = objects[i];
+
+ if (!collision)
continue;
- body = (EPhysics_Body *) rigid_body->getUserPointer();
- if (rigid_body->isActive())
+ body = (EPhysics_Body *) collision->getUserPointer();
+ if (collision->isActive())
{
ephysics_body_active_set(body, EINA_TRUE);
ephysics_body_evas_object_update_select(body);
@@ -260,7 +262,8 @@ _ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body)
{
btSoftBody *soft_body;
- world->dynamics_world->removeRigidBody(ephysics_body_rigid_body_get(body));
+ if (ephysics_body_rigid_body_get(body))
+ world->dynamics_world->removeRigidBody(ephysics_body_rigid_body_get(body));
soft_body = ephysics_body_soft_body_get(body);
if (soft_body)
@@ -291,10 +294,7 @@ ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body)
and body 2 will stay freezed in the air. Gravity won't start to
act over it until it's activated again. */
EINA_INLIST_FOREACH(world->bodies, bd)
- {
- btRigidBody *rigid_body = ephysics_body_rigid_body_get(bd);
- rigid_body->activate(1);
- }
+ ephysics_body_activate(bd, EINA_TRUE);
return EINA_TRUE;
}