aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
}