diff --git a/legacy/ephysics/src/bin/Makefile.am b/legacy/ephysics/src/bin/Makefile.am index 10c5e1f4de..66e5eb34e6 100644 --- a/legacy/ephysics/src/bin/Makefile.am +++ b/legacy/ephysics/src/bin/Makefile.am @@ -30,7 +30,8 @@ test_jumping_balls.c \ test_no_gravity.c \ test_rotate.c \ test_velocity.c \ -test_sleeping_threshold.c +test_sleeping_threshold.c \ +test_slider.c ephysics_logo_SOURCES = \ ephysics_logo.c diff --git a/legacy/ephysics/src/bin/test.c b/legacy/ephysics/src/bin/test.c index 53b675127d..07b3b48eb8 100644 --- a/legacy/ephysics/src/bin/test.c +++ b/legacy/ephysics/src/bin/test.c @@ -24,6 +24,7 @@ void test_no_gravity(void *data, Evas_Object *obj, void *event_info); void test_rotate(void *data, Evas_Object *obj, void *event_info); void test_velocity(void *data, Evas_Object *obj, void *event_info); void test_sleeping(void *data, Evas_Object *obj, void *event_info); +void test_slider(void *data, Evas_Object *obj, void *event_info); static void _win_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) @@ -166,6 +167,7 @@ _main_win_add(char *autorun __UNUSED__, Eina_Bool test_win_only __UNUSED__) ADD_TEST("ROTATE", test_rotate); ADD_TEST("VELOCITY", test_velocity); ADD_TEST("SLEEPING THRESHOLD", test_sleeping); + ADD_TEST("SLIDER", test_slider); elm_list_go(list); } diff --git a/legacy/ephysics/src/bin/test_constraint.c b/legacy/ephysics/src/bin/test_constraint.c index c5e7be3754..3a7d6c0c6e 100644 --- a/legacy/ephysics/src/bin/test_constraint.c +++ b/legacy/ephysics/src/bin/test_constraint.c @@ -60,7 +60,8 @@ _world_populate(Test_Data *test_data) ephysics_body_friction_set(box_body2, 0.1); test_data->bodies = eina_list_append(test_data->bodies, box_body2); - constraint = ephysics_constraint_add(box_body1, box_body2, 0, 100, 0, 0); + constraint = ephysics_constraint_p2p_add(box_body1, box_body2, 0, 100, 0, + 0); test_data->constraints = eina_list_append(test_data->constraints, constraint); } diff --git a/legacy/ephysics/src/bin/test_slider.c b/legacy/ephysics/src/bin/test_slider.c new file mode 100644 index 0000000000..56aae11392 --- /dev/null +++ b/legacy/ephysics/src/bin/test_slider.c @@ -0,0 +1,167 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "ephysics_test.h" + +static void +_world_populate(Test_Data *test_data) +{ + EPhysics_Body *box_body1, *box_body2, *box_body3, *box_body4; + Evas_Object *box1, *box2, *box3, *box4, *sh1, *sh2, *sh3, *sh4; + EPhysics_Constraint *constraint; + + sh1 = elm_layout_add(test_data->win); + elm_layout_file_set( + sh1, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "shadow-cube"); + evas_object_move(sh1, WIDTH / 6, FLOOR_Y); + evas_object_resize(sh1, 70, 3); + evas_object_show(sh1); + test_data->evas_objs = eina_list_append(test_data->evas_objs, sh1); + + box1 = elm_image_add(test_data->win); + elm_image_file_set( + box1, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "blue-cube"); + evas_object_move(box1, WIDTH / 6, FLOOR_Y - 70); + evas_object_resize(box1, 70, 70); + evas_object_show(box1); + test_data->evas_objs = eina_list_append(test_data->evas_objs, box1); + + box_body1 = ephysics_body_box_add(test_data->world); + ephysics_body_mass_set(box_body1, 0); + ephysics_body_evas_object_set(box_body1, box1, EINA_TRUE); + ephysics_body_event_callback_add(box_body1, EPHYSICS_CALLBACK_BODY_UPDATE, + update_object_cb, sh1); + ephysics_body_restitution_set(box_body1, 0.3); + ephysics_body_friction_set(box_body1, 0.1); + test_data->bodies = eina_list_append(test_data->bodies, box_body1); + + sh2 = elm_layout_add(test_data->win); + elm_layout_file_set( + sh2, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "shadow-cube"); + evas_object_move(sh2, WIDTH / 6 + 60, FLOOR_Y); + evas_object_resize(sh2, 70, 3); + evas_object_show(sh2); + test_data->evas_objs = eina_list_append(test_data->evas_objs, sh2); + + box2 = elm_image_add(test_data->win); + elm_image_file_set( + box2, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "purple-cube"); + evas_object_move(box2, WIDTH / 6 + 65, HEIGHT / 8); + evas_object_resize(box2, 70, 70); + evas_object_show(box2); + test_data->evas_objs = eina_list_append(test_data->evas_objs, box2); + + box_body2 = ephysics_body_box_add(test_data->world); + ephysics_body_evas_object_set(box_body2, box2, EINA_TRUE); + ephysics_body_event_callback_add(box_body2, EPHYSICS_CALLBACK_BODY_UPDATE, + update_object_cb, sh2); + ephysics_body_restitution_set(box_body2, 0.5); + ephysics_body_friction_set(box_body2, 0.1); + test_data->bodies = eina_list_append(test_data->bodies, box_body2); + + constraint = ephysics_constraint_slider_add(box_body2); + ephysics_constraint_slider_linear_limit_set(constraint, 0, + HEIGHT - (HEIGHT / 8), 0, 0); + ephysics_constraint_slider_angular_limit_set(constraint, 0, 45); + test_data->constraints = eina_list_append(test_data->constraints, + constraint); + + sh3 = elm_layout_add(test_data->win); + elm_layout_file_set( + sh3, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "shadow-cube"); + evas_object_move(sh3, WIDTH / 6 + 60, FLOOR_Y); + evas_object_resize(sh3, 70, 3); + evas_object_show(sh3); + test_data->evas_objs = eina_list_append(test_data->evas_objs, sh3); + + box3 = elm_image_add(test_data->win); + elm_image_file_set( + box3, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "blue-cube"); + evas_object_move(box3, WIDTH - 120, HEIGHT / 8); + evas_object_resize(box3, 70, 70); + evas_object_show(box3); + test_data->evas_objs = eina_list_append(test_data->evas_objs, box3); + + box_body3 = ephysics_body_box_add(test_data->world); + ephysics_body_evas_object_set(box_body3, box3, EINA_TRUE); + ephysics_body_event_callback_add(box_body3, EPHYSICS_CALLBACK_BODY_UPDATE, + update_object_cb, sh3); + ephysics_body_restitution_set(box_body3, 0.5); + ephysics_body_friction_set(box_body3, 0.1); + test_data->bodies = eina_list_append(test_data->bodies, box_body3); + + constraint = ephysics_constraint_slider_add(box_body3); + ephysics_constraint_slider_linear_limit_set(constraint, WIDTH - 120, 0, 0, + 0); + ephysics_body_central_impulse_apply(box_body3, -8, 0); + test_data->constraints = eina_list_append(test_data->constraints, + constraint); + + sh4 = elm_layout_add(test_data->win); + elm_layout_file_set( + sh4, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "shadow-cube"); + evas_object_move(sh4, WIDTH / 6 + 60, FLOOR_Y); + evas_object_resize(sh4, 70, 3); + evas_object_show(sh4); + test_data->evas_objs = eina_list_append(test_data->evas_objs, sh4); + + box4 = elm_image_add(test_data->win); + elm_image_file_set( + box4, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "purple-cube"); + evas_object_move(box4, WIDTH - 120, FLOOR_Y - 70); + evas_object_resize(box4, 70, 70); + evas_object_show(box4); + test_data->evas_objs = eina_list_append(test_data->evas_objs, box4); + + box_body4 = ephysics_body_box_add(test_data->world); + ephysics_body_evas_object_set(box_body4, box4, EINA_TRUE); + ephysics_body_event_callback_add(box_body4, EPHYSICS_CALLBACK_BODY_UPDATE, + update_object_cb, sh4); + ephysics_body_restitution_set(box_body4, 0.5); + ephysics_body_friction_set(box_body4, 0.1); + test_data->bodies = eina_list_append(test_data->bodies, box_body4); + + constraint = ephysics_constraint_slider_add(box_body4); + ephysics_constraint_slider_linear_limit_set(constraint, WIDTH / 3, 0, 0, 0); + ephysics_body_central_impulse_apply(box_body4, -20, 0); + test_data->constraints = eina_list_append(test_data->constraints, + constraint); + +} + +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_slider(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, "Slider", EINA_TRUE); + elm_layout_signal_callback_add(test_data->layout, "restart", "test-theme", + _restart, test_data); + + world = ephysics_world_new(); + 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, 3); + + _world_populate(test_data); +} diff --git a/legacy/ephysics/src/lib/EPhysics.h b/legacy/ephysics/src/lib/EPhysics.h index f4c8227299..49d3d20b57 100644 --- a/legacy/ephysics/src/lib/EPhysics.h +++ b/legacy/ephysics/src/lib/EPhysics.h @@ -2091,7 +2091,7 @@ typedef struct _EPhysics_Constraint EPhysics_Constraint; /**< Constraint handle, /** * @brief - * Create a new constraint between 2 bodies. + * Create a new constraint between 2 bodies(Point to Point constraint). * * The constraint will join two bodies(@p body1 and @p body2) limiting their * movements based on specified anchors. @@ -2102,13 +2102,101 @@ typedef struct _EPhysics_Constraint EPhysics_Constraint; /**< Constraint handle, * @param anchor_b1_y The fist body Y anchor. * @param anchor_b2_x The second body X anchor. * @param anchor_b2_y The second body Y anchor. - * @return A new constraint or @c NULL, on errors. + * @return A new p2p(point to point) constraint or @c NULL, on errors. * * @see ephysics_constraint_del(). * * @ingroup EPhysics_Constraint */ -EAPI EPhysics_Constraint *ephysics_constraint_add(EPhysics_Body *body1, EPhysics_Body *body2, Evas_Coord anchor_b1_x, Evas_Coord anchor_b1_y, Evas_Coord anchor_b2_x, Evas_Coord anchor_b2_y); +EAPI EPhysics_Constraint *ephysics_constraint_p2p_add(EPhysics_Body *body1, EPhysics_Body *body2, Evas_Coord anchor_b1_x, Evas_Coord anchor_b1_y, Evas_Coord anchor_b2_x, Evas_Coord anchor_b2_y); + +/** + * @brief + * Create a new slider constraint. + * + * The constraint will limit the linear and angular moving of a body. + * + * @param body The body to apply the constraint. + * + * @see ephysics_constraint_slider_linear_limit_set() for linear moving limit + * configuration. + * @see ephysics_constraint_slider_angular_limit_set() for angular moving limit + * configuration. + * @return A new slider constraint or @c NULL on erros. + * + * @see ephysics_constraint_del(). + * + * @ingroup EPhysics_Constraint + */ +EAPI EPhysics_Constraint *ephysics_constraint_slider_add(EPhysics_Body *body); + +/** + * @brief + * Define the linear moving limits of a slider @p constraint. + * + * The linear limits are defined from the body's position on. The user will + * want to limit the movements to the left, right, under and above the rigid + * body. The unit for every limits are defined on Evas coordinates. + * + * @param constraint The constraint to be set. + * @param left_x The moving limit to the left on X axis - from the body's + * position on. + * @param under_y The moving limit down on Y axis - from the body's position + * on. + * @param right_x The moving limit to the right on X axis - from the body's + * position on. + * @param above_y The moving limit up on Y axis - from the body's position on. + * + * @see ephysics_constraint_slider_linear_limit_get() + * @ingroup EPhysics_Constraint + */ +EAPI void ephysics_constraint_slider_linear_limit_set(EPhysics_Constraint *constraint, Evas_Coord left_x, Evas_Coord under_y, Evas_Coord right_x, Evas_Coord above_y); + +/** + * @brief + * Get the linear moving limits of a slider constraint. + * + * @param constraint The constraint to get linear limits from. + * @param left_x Pointer to set with the limit to the left on X axis. + * @param under_y Pointer to set with the limit down on Y axis. + * @param right_x Pointer to set with the limit to the right on X axis. + * @param above_y Pointer to set with the limit up on Y axis. + * + * @see ephysics_constraint_slider_linear_limit_set() + * @ingroup EPhysics_Constraint + */ +EAPI void ephysics_constraint_slider_linear_limit_get(const EPhysics_Constraint *constraint, Evas_Coord *left_x, Evas_Coord *under_y, Evas_Coord *right_x, Evas_Coord *above_y); + +/** + * @brief + * Set the angular moving limits of a slider @p constraint. + * + * The angular moving limits is defined in degrees and will limit the moving on + * Z axis - counter clock and clock wise directions. + * + * @param constraint The constraint to be set. + * @param counter_clock_z Amount of degrees from 0.0 to 360.0 to limit + * counter clock rotation. + * @param clock_wise_z Amount of degrees from 0.0 to 360.0 to limit clock wise + * rotation. + * + * @see ephysics_constraint_slider_angular_limit_get() + * @ingroup EPhysics_Constraint + */ +EAPI void ephysics_constraint_slider_angular_limit_set(EPhysics_Constraint *constraint, Evas_Coord counter_clock_z, Evas_Coord clock_wise_z); + +/** + * @brief + * Get the angular moving limits of a slider @p constraint. + * + * @param constraint The constraint to get the angular limits from. + * @param counter_clock_z Pointer to set with the counter clock limit degrees. + * @param clock_wise_z Pointer to set with the clock wise limit degrees. + * + * @see ephysics_constraint_slider_angular_limit_set() + * @ingroup EPhysics_Constraint + */ +EAPI void ephysics_constraint_slider_angular_limit_get(const EPhysics_Constraint *constraint, Evas_Coord *counter_clock_z, Evas_Coord *clock_wise_z); /** * @brief diff --git a/legacy/ephysics/src/lib/ephysics_body.cpp b/legacy/ephysics/src/lib/ephysics_body.cpp index 3c8c9c9371..993ad50996 100644 --- a/legacy/ephysics/src/lib/ephysics_body.cpp +++ b/legacy/ephysics/src/lib/ephysics_body.cpp @@ -10,8 +10,6 @@ extern "C" { #endif -#define RAD_TO_DEG 57.29582 /* 2 * pi radians == 360 degree */ - typedef struct _EPhysics_Body_Callback EPhysics_Body_Callback; struct _EPhysics_Body_Callback { diff --git a/legacy/ephysics/src/lib/ephysics_constraints.cpp b/legacy/ephysics/src/lib/ephysics_constraints.cpp index 125c698864..4c803769d8 100644 --- a/legacy/ephysics/src/lib/ephysics_constraints.cpp +++ b/legacy/ephysics/src/lib/ephysics_constraints.cpp @@ -8,13 +8,179 @@ extern "C" { #endif +typedef enum _EPhysics_Constraint_Type { + EPHYSICS_CONSTRAINT_P2P, + EPHYSICS_CONSTRAINT_SLIDER, +} EPhysics_Constraint_Type; + struct _EPhysics_Constraint { btTypedConstraint *bt_constraint; EPhysics_World *world; + EPhysics_Constraint_Type type; }; EAPI EPhysics_Constraint * -ephysics_constraint_add(EPhysics_Body *body1, EPhysics_Body *body2, Evas_Coord anchor_b1_x, Evas_Coord anchor_b1_y, Evas_Coord anchor_b2_x, Evas_Coord anchor_b2_y) +ephysics_constraint_slider_add(EPhysics_Body *body) +{ + EPhysics_Constraint *constraint; + btTransform trans; + + if (!body) + { + ERR("To create a constraint body must to be non null."); + return NULL; + } + + constraint = (EPhysics_Constraint *) calloc(1, sizeof(EPhysics_Constraint)); + if (!constraint) + { + ERR("Couldn't create a new constraint."); + return NULL; + } + + trans.setIdentity(); + constraint->bt_constraint = new + btGeneric6DofConstraint(*ephysics_body_rigid_body_get(body), trans, + false); + + if (!constraint->bt_constraint) + { + ERR("Failed to create a btConstraint"); + free(constraint); + return NULL; + } + + constraint->type = EPHYSICS_CONSTRAINT_SLIDER; + constraint->world = ephysics_body_world_get(body); + ephysics_world_constraint_add(constraint->world, constraint->bt_constraint); + + INF("Constraint added."); + return constraint; +} + +EAPI void +ephysics_constraint_slider_linear_limit_set(EPhysics_Constraint *constraint, Evas_Coord left_x, Evas_Coord under_y, Evas_Coord right_x, Evas_Coord above_y) +{ + btGeneric6DofConstraint *slider_constraint; + int rate; + + if (!constraint) + { + ERR("Can't set constraint's linear limit, constraint is null."); + return; + } + + if (constraint->type != EPHYSICS_CONSTRAINT_SLIDER) + { + ERR("Can't set linear limit, this is not an slider constraint."); + return; + } + + slider_constraint = (btGeneric6DofConstraint *)constraint->bt_constraint; + rate = ephysics_world_rate_get(constraint->world); + + left_x = (left_x) / rate; + right_x = (right_x) / rate; + + under_y = (under_y) / rate; + above_y = (above_y) / rate; + + slider_constraint->setLinearLowerLimit(btVector3(-left_x, -under_y, 0)); + slider_constraint->setLinearUpperLimit(btVector3(right_x, above_y, 0)); +} + +EAPI void +ephysics_constraint_slider_linear_limit_get(const EPhysics_Constraint *constraint, Evas_Coord *left_x, Evas_Coord *under_y, Evas_Coord *right_x, Evas_Coord *above_y) +{ + btGeneric6DofConstraint *slider_constraint; + btVector3 linear_limit; + int rate; + + if (!constraint) + { + ERR("Can't get constraint's linear limit, constraint is null."); + return; + } + + if (constraint->type != EPHYSICS_CONSTRAINT_SLIDER) + { + ERR("Can't get linear limit, this is not an slider constraint."); + return; + } + + rate = ephysics_world_rate_get(constraint->world); + slider_constraint = (btGeneric6DofConstraint *)constraint->bt_constraint; + if (left_x || under_y) + slider_constraint->getLinearLowerLimit(linear_limit); + + if (left_x) *left_x = linear_limit.getX() * rate; + if (under_y) *under_y = linear_limit.getY() * rate; + + if (right_x || above_y) + slider_constraint->getLinearUpperLimit(linear_limit); + + if (right_x) *right_x = linear_limit.getX() * rate; + if (above_y) *above_y = linear_limit.getY() * rate; +} + +EAPI void +ephysics_constraint_slider_angular_limit_set(EPhysics_Constraint *constraint, Evas_Coord counter_clock_z, Evas_Coord clock_wise_z) +{ + btGeneric6DofConstraint *slider_constraint; + + if (!constraint) + { + ERR("Can't set constraint's angular limit, constraint is null."); + return; + } + + if (constraint->type != EPHYSICS_CONSTRAINT_SLIDER) + { + ERR("Can't set angular limit, this is not an slider constraint."); + return; + } + + slider_constraint = (btGeneric6DofConstraint *)constraint->bt_constraint; + slider_constraint->setAngularLowerLimit(btVector3(0, 0, + -counter_clock_z/RAD_TO_DEG)); + slider_constraint->setAngularUpperLimit(btVector3(0, 0, + clock_wise_z/RAD_TO_DEG)); +} + +EAPI void +ephysics_constraint_slider_angular_limit_get(const EPhysics_Constraint *constraint, Evas_Coord *counter_clock_z, Evas_Coord *clock_wise_z) +{ + btGeneric6DofConstraint *slider_constraint; + btVector3 angular_limit; + + if (!constraint) + { + ERR("Can't get constraint's angular limit, constraint is null."); + return; + } + + if (constraint->type != EPHYSICS_CONSTRAINT_SLIDER) + { + ERR("Can't get angular limit, this is not an slider constraint."); + return; + } + + slider_constraint = (btGeneric6DofConstraint *)constraint->bt_constraint; + if (counter_clock_z) + { + slider_constraint->getAngularLowerLimit(angular_limit); + *counter_clock_z = angular_limit.getZ(); + } + + if (clock_wise_z) + { + slider_constraint->getAngularUpperLimit(angular_limit); + *clock_wise_z = angular_limit.getZ(); + } +} + +EAPI EPhysics_Constraint * +ephysics_constraint_p2p_add(EPhysics_Body *body1, EPhysics_Body *body2, Evas_Coord anchor_b1_x, Evas_Coord anchor_b1_y, Evas_Coord anchor_b2_x, Evas_Coord anchor_b2_y) { EPhysics_Constraint *constraint; int rate; @@ -60,6 +226,7 @@ ephysics_constraint_add(EPhysics_Body *body1, EPhysics_Body *body2, Evas_Coord a return NULL; } + constraint->type = EPHYSICS_CONSTRAINT_P2P; constraint->world = ephysics_body_world_get(body1); ephysics_world_constraint_add(constraint->world, constraint->bt_constraint); diff --git a/legacy/ephysics/src/lib/ephysics_private.h b/legacy/ephysics/src/lib/ephysics_private.h index 44b20d0e1e..be0679885e 100644 --- a/legacy/ephysics/src/lib/ephysics_private.h +++ b/legacy/ephysics/src/lib/ephysics_private.h @@ -42,6 +42,8 @@ extern "C" { #endif +#define RAD_TO_DEG 57.29582 /* 2 * pi radians == 360 degree */ + typedef enum _EPhysics_World_Boundary { EPHYSICS_WORLD_BOUNDARY_TOP,