diff --git a/legacy/ephysics/src/bin/test_constraint.c b/legacy/ephysics/src/bin/test_constraint.c index 617b19e1f3..988ed7b415 100644 --- a/legacy/ephysics/src/bin/test_constraint.c +++ b/legacy/ephysics/src/bin/test_constraint.c @@ -4,12 +4,27 @@ #include "ephysics_test.h" +static void +_constraint_set(Test_Data *test_data, EPhysics_Body *body1, EPhysics_Body *body2) +{ + EPhysics_Constraint *constraint; + Evas_Coord b1x, b1y, b1z, b1w, b1h, b1d, b2x, b2y, b2z, b2w, b2h, b2d; + + ephysics_body_geometry_get(body1, &b1x, &b1y, &b1z, &b1w, &b1h, &b1d); + ephysics_body_geometry_get(body2, &b2x, &b2y, &b2z, &b2w, &b2h, &b2d); + + constraint = ephysics_constraint_linked_add(body1, body2); + + ephysics_constraint_anchor_set(constraint, b1x + b1w / 2, b1y + b1h / 2 + 100, + b1z, b2x + b2w / 2, b2y + b2h / 2, b2z); + test_data->constraints = eina_list_append(test_data->constraints, constraint); +} + static void _world_populate(Test_Data *test_data) { EPhysics_Body *box_body1, *box_body2; Evas_Object *box1, *box2, *sh1, *sh2; - EPhysics_Constraint *constraint; sh1 = elm_layout_add(test_data->win); elm_layout_file_set( @@ -52,18 +67,15 @@ _world_populate(Test_Data *test_data) test_data->evas_objs = eina_list_append(test_data->evas_objs, box2); box_body2 = ephysics_body_box_add(test_data->world); - ephysics_body_mass_set(box_body2, 5); ephysics_body_evas_object_set(box_body2, box2, EINA_TRUE); + ephysics_body_mass_set(box_body2, 5); 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_p2p_add(box_body1, box_body2, 0, 100, 0, - 0); - test_data->constraints = eina_list_append(test_data->constraints, - constraint); + _constraint_set(test_data, box_body1, box_body2); } static void diff --git a/legacy/ephysics/src/bin/test_slider.c b/legacy/ephysics/src/bin/test_slider.c index 6bb840e6a5..f17ca01d7f 100644 --- a/legacy/ephysics/src/bin/test_slider.c +++ b/legacy/ephysics/src/bin/test_slider.c @@ -60,10 +60,10 @@ _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_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); + constraint = ephysics_constraint_add(box_body2); + ephysics_constraint_linear_limit_set(constraint, 0, 0, 0, + HEIGHT - (HEIGHT / 8), 0, 0); + ephysics_constraint_angular_limit_set(constraint, 0, 0, 0, 0, 0, 45); test_data->constraints = eina_list_append(test_data->constraints, constraint); @@ -91,9 +91,8 @@ _world_populate(Test_Data *test_data) 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); + constraint = ephysics_constraint_add(box_body3); + ephysics_constraint_linear_limit_set(constraint, WIDTH - 120, 0, 0, 0, 0, 0); ephysics_body_central_impulse_apply(box_body3, -240, 0, 0); test_data->constraints = eina_list_append(test_data->constraints, constraint); @@ -122,8 +121,8 @@ _world_populate(Test_Data *test_data) 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); + constraint = ephysics_constraint_add(box_body4); + ephysics_constraint_linear_limit_set(constraint, WIDTH / 3, 0, 0, 0, 0, 0); ephysics_body_central_impulse_apply(box_body4, -600, 0, 0); test_data->constraints = eina_list_append(test_data->constraints, constraint); diff --git a/legacy/ephysics/src/lib/EPhysics.h b/legacy/ephysics/src/lib/EPhysics.h index f0c0b07e94..affac90c14 100644 --- a/legacy/ephysics/src/lib/EPhysics.h +++ b/legacy/ephysics/src/lib/EPhysics.h @@ -4397,123 +4397,192 @@ EAPI Eina_Bool ephysics_body_clockwise_get(const EPhysics_Body *body); * between bodies and the world. Constraints can limit movement angle, * translation, or work like a motor. * - * Constraints can be created with @ref ephysics_constraint_p2p_add() - * or @ref ephysics_constraint_slider_add() and removed + * Constraints can be created with @ref ephysics_constraint_linked_add() + * or @ref ephysics_constraint_add() and removed * with @ref ephysics_constraint_del(). * Can be applied between two bodies or between a body and the world. */ -typedef struct _EPhysics_Constraint EPhysics_Constraint; /**< Constraint handle, used to limit bodies movements. Created with @ref ephysics_constraint_p2p_add() or @ref ephysics_constraint_slider_add() and deleted with @ref ephysics_constraint_del(). */ +typedef struct _EPhysics_Constraint EPhysics_Constraint; /**< Constraint handle, used to limit bodies movements. Created with @ref ephysics_constraint_linked_add() or @ref ephysics_constraint_add() and deleted with @ref ephysics_constraint_del(). */ /** * @brief * 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. + * The constraint will join two bodies(@p body1 and @p body2) with angular and + * linear movements limited by calling ephysics_constraint_linear_limit_set() + * and ephysics_constraint_angular_limit_set(). Anchors values can be defined + * with ephysics_constraint_anchor_set(). * * @param body1 The first body to apply the constraint. * @param body2 The second body to apply the constraint. - * @param anchor_b1_x The first body X anchor. - * @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 p2p(point to point) constraint or @c NULL, on errors. + * @return A new linked(joining 2 bodies) constraint or @c NULL, on errors. * * @see ephysics_constraint_del(). * * @ingroup EPhysics_Constraint */ -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); +EAPI EPhysics_Constraint *ephysics_constraint_linked_add(EPhysics_Body *body1, EPhysics_Body *body2); /** * @brief - * Create a new slider constraint. + * Change the constraints anchors values on both constrained bodies. * - * The constraint will limit the linear and angular moving of a body. + * @note By default the anchors are in the middle of a body, if a body of 20, 20 + * is positioned at (10, 10) then its anchor is set to (20, 20). + * + * @note There`s no need to inform @p anchor_b2_x, @p anchor_b2_y and @p + * anchor_b2_z if the constraint has been created using + * ephysics_constraint_add(). + * + * @param constraint The constraint to be set. + * @param anchor_b1_x The first body X anchor. + * @param anchor_b1_y The first body Y anchor. + * @param anchor_b1_z The first body Z anchor. + * @param anchor_b2_x The second body X anchor. + * @param anchor_b2_y The second body Y anchor. + * @param anchor_b2_z The second body Z anchor. + * + * @see ephysics_constraint_anchor_get(). + * @see ephysics_constraint_linked_add(). + * + * @ingroup EPhysics_Constraint + */ +EAPI void ephysics_constraint_anchor_set(EPhysics_Constraint *constraint, Evas_Coord anchor_b1_x, Evas_Coord anchor_b1_y, Evas_Coord anchor_b1_z, Evas_Coord anchor_b2_x, Evas_Coord anchor_b2_y, Evas_Coord anchor_b2_z); + +/** + * @brief + * Get the constraints anchors values on both constrained bodies. + * + * @param constraint The constraint to get anchor values from. + * @param anchor_b1_x Pointer to an Evas_Coord in which to store the first body + * X anchor value. + * @param anchor_b1_y Pointer to an Evas_Coord in which to store the first body + * Y anchor value. + * @param anchor_b1_z Pointer to an Evas_Coord in which to store the first body + * Z anchor value. + * @param anchor_b2_x Pointer to an Evas_Coord in which to store the second body + * X anchor value. + * @param anchor_b2_y Pointer to an Evas_Coord in which to store the second body + * Y anchor value. + * @param anchor_b2_z Pointer to an Evas_Coord in which to store the second body + * Z anchor value. + * + * @see ephysics_constraint_anchor_set(). + * @see ephysics_constraint_linked_add(). + * + * @ingroup EPhysics_Constraint + */ +EAPI void ephysics_constraint_anchor_get(const EPhysics_Constraint *constraint, Evas_Coord *anchor_b1_x, Evas_Coord *anchor_b1_y, Evas_Coord *anchor_b1_z, Evas_Coord *anchor_b2_x, Evas_Coord *anchor_b2_y, Evas_Coord *anchor_b2_z); + +/** + * @brief + * Create a new constraint. + * + * The constraint will limit the linear and angular moving of a body. This simple + * constraint is designated to constraint a single body. * * @param body The body to apply the constraint. * - * @see ephysics_constraint_slider_linear_limit_set() for linear moving limit + * @see ephysics_constraint_linear_limit_set() for linear moving limit * configuration. - * @see ephysics_constraint_slider_angular_limit_set() for angular moving limit + * @see ephysics_constraint_angular_limit_set() for angular moving limit * configuration. - * @return A new slider constraint or @c NULL on erros. + * @return A new constraint or @c NULL on erros. * * @see ephysics_constraint_del(). * * @ingroup EPhysics_Constraint */ -EAPI EPhysics_Constraint *ephysics_constraint_slider_add(EPhysics_Body *body); +EAPI EPhysics_Constraint *ephysics_constraint_add(EPhysics_Body *body); /** * @brief - * Define the linear moving limits of a slider @p constraint. + * Define the linear moving limits of a @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. + * want to limit the movements on X, Y and Z axis where lower == upper axis + * will be locked, lower > upper axis is free, lower < upper axis is limited to + * the range. + * + * 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. + * @param lower_x The lower linear moving limit on X axis. + * @param upper_x The upper linear moving limit on X axis. + * @param lower_y The lower linear moving limit on Y axis. + * @param upper_y The upper linear moving limit on Y axis. + * @param lower_z The lower linear moving limit on Z axis. + * @param upper_z The upper linear moving limit on Z axis. * - * @see ephysics_constraint_slider_linear_limit_get() + * + * @see ephysics_constraint_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); +EAPI void ephysics_constraint_linear_limit_set(EPhysics_Constraint *constraint, Evas_Coord lower_x, Evas_Coord upper_x, Evas_Coord lower_y, Evas_Coord upper_y, Evas_Coord lower_z, Evas_Coord upper_z); /** * @brief - * Get the linear moving limits of a slider constraint. + * Get the linear moving limits of a @p 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. + * @param lower_x Pointer to set with the lower limit to the X axis. + * @param upper_x Pointer to set with the upper limit to the X axis. + * @param lower_y Pointer to set with the lower limit to the Y axis. + * @param upper_y Pointer to set with the upper limit to the Y axis. + * @param lower_z Pointer to set with the lower limit to the Z axis. + * @param upper_z Pointer to set with the upper limit to the Z axis. * - * @see ephysics_constraint_slider_linear_limit_set() + * @see ephysics_constraint_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); +EAPI void ephysics_constraint_linear_limit_get(const EPhysics_Constraint *constraint, Evas_Coord *lower_x, Evas_Coord *upper_x, Evas_Coord *lower_y, Evas_Coord *upper_y, Evas_Coord *lower_z, Evas_Coord *upper_z); /** * @brief - * Set the angular moving limits of a slider @p constraint. + * Set the angular moving limits of a @p constraint. * * The angular moving limits is defined in degrees and will limit the moving on * Z axis - counter clockwise and clockwise directions. * * @param constraint The constraint to be set. + * @param counter_clock_x Amount of degrees from 0.0 to 360.0 to limit counter + * clockwise rotation on X axis. + * @param clock_wise_x Amount of degrees from 0.0 to 360.0 to limit clockwise + * rotation on X axis. + * @param counter_clock_y Amount of degrees from 0.0 to 360.0 to limit counter + * clockwise rotation o Y axis. + * @param clock_wise_y Amount of degrees from 0.0 to 360.0 to limit clockwise + * rotation on Y axis. * @param counter_clock_z Amount of degrees from 0.0 to 360.0 to limit - * counter clockwise rotation. + * counter clockwise rotation on Z axis. * @param clock_wise_z Amount of degrees from 0.0 to 360.0 to limit clockwise - * rotation. + * rotation on Z axis. * - * @see ephysics_constraint_slider_angular_limit_get() + * @see ephysics_constraint_angular_limit_get() * @ingroup EPhysics_Constraint */ -EAPI void ephysics_constraint_slider_angular_limit_set(EPhysics_Constraint *constraint, double counter_clock_z, double clock_wise_z); +EAPI void ephysics_constraint_angular_limit_set(EPhysics_Constraint *constraint, double counter_clock_x, double clock_wise_x, double counter_clock_y, double clock_wise_y, double counter_clock_z, double clock_wise_z); /** * @brief - * Get the angular moving limits of a slider @p constraint. + * Get the angular moving limits of a @p constraint. * * @param constraint The constraint to get the angular limits from. + * @param counter_clock_x Pointer to set with the counter clockwise limmit + * degrees on X axis. + * @param clock_wise_x Pointer to set with the clockwise limit degrees on X axis. + * @param counter_clock_y Pointer to set with the counter clockwise limit + * degrees on Y axis. + * @param clock_wise_y Pointer to set with the clockwise limit degrees on Y axis. * @param counter_clock_z Pointer to set with the counter clockwise limit - * degrees. - * @param clock_wise_z Pointer to set with the clockwise limit degrees. + * degrees on Z axis. + * @param clock_wise_z Pointer to set with the clockwise limit degrees on Z axis. * - * @see ephysics_constraint_slider_angular_limit_set() + * @see ephysics_constraint_angular_limit_set() * @ingroup EPhysics_Constraint */ -EAPI void ephysics_constraint_slider_angular_limit_get(const EPhysics_Constraint *constraint, double *counter_clock_z, double *clock_wise_z); +EAPI void ephysics_constraint_angular_limit_get(const EPhysics_Constraint *constraint, double *counter_clock_x, double *clock_wise_x, double *counter_clock_y, double *clock_wise_y, double *counter_clock_z, double *clock_wise_z); /** * @brief @@ -4521,7 +4590,7 @@ EAPI void ephysics_constraint_slider_angular_limit_get(const EPhysics_Constraint * * @param constraint The constraint to be deleted. * - * @see ephysics_constraint_p2p_add() for more details. + * @see ephysics_constraint_linked_add() for more details. * @see ephysics_constraint_slider_add() for more details. * * @ingroup EPhysics_Constraint diff --git a/legacy/ephysics/src/lib/ephysics_constraints.cpp b/legacy/ephysics/src/lib/ephysics_constraints.cpp index ed5c5c8411..f97af58659 100644 --- a/legacy/ephysics/src/lib/ephysics_constraints.cpp +++ b/legacy/ephysics/src/lib/ephysics_constraints.cpp @@ -8,107 +8,67 @@ extern "C" { #endif -typedef enum _EPhysics_Constraint_Type { - EPHYSICS_CONSTRAINT_P2P, - EPHYSICS_CONSTRAINT_SLIDER, -} EPhysics_Constraint_Type; - struct _EPhysics_Constraint { - btTypedConstraint *bt_constraint; + btGeneric6DofConstraint *bt_constraint; EPhysics_World *world; - EPhysics_Constraint_Type type; - struct { - 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; - } p2p; + EPhysics_Body *bodies[2]; }; -/* FIXME: it shouldn't be this way. - * All constraints should be generic and have all these options - * set after add(). - */ -static Eina_Bool -_ephysics_constraint_p2p_set(EPhysics_Constraint *constraint, double rate) +static void +_ephysics_constraint_linear_limit_get(const EPhysics_Constraint *constraint, Evas_Coord *lower_x, Evas_Coord *upper_x, Evas_Coord *lower_y, Evas_Coord *upper_y, Evas_Coord *lower_z, Evas_Coord *upper_z, double rate) { - if (!constraint->p2p.body2) - constraint->bt_constraint = new btPoint2PointConstraint( - *ephysics_body_rigid_body_get(constraint->p2p.body1), - btVector3(constraint->p2p.anchor_b1_x / rate, - constraint->p2p.anchor_b1_y / rate, 0)); - else - constraint->bt_constraint = new btPoint2PointConstraint( - *ephysics_body_rigid_body_get(constraint->p2p.body1), - *ephysics_body_rigid_body_get(constraint->p2p.body2), - btVector3(constraint->p2p.anchor_b1_x / rate, - constraint->p2p.anchor_b1_y / rate, 0), - btVector3(constraint->p2p.anchor_b2_x / rate, - constraint->p2p.anchor_b2_y / rate, 0)); + btVector3 linear_limit; - if (!constraint->bt_constraint) + if (lower_x || lower_y || lower_z) { - ERR("Failed to create a btConstraint"); - free(constraint); - return EINA_FALSE; + constraint->bt_constraint->getLinearLowerLimit(linear_limit); + + if (lower_x) *lower_x = linear_limit.getX() * rate; + if (lower_y) *lower_y = linear_limit.getY() * rate; + if (lower_z) *lower_z = linear_limit.getZ() * rate; } - constraint->type = EPHYSICS_CONSTRAINT_P2P; - ephysics_world_constraint_add(constraint->world, constraint, - constraint->bt_constraint); + if (upper_x || upper_y || upper_z) + { + constraint->bt_constraint->getLinearUpperLimit(linear_limit); - return EINA_TRUE; + if (upper_x) *upper_x = linear_limit.getX() * rate; + if (upper_y) *upper_y = linear_limit.getY() * rate; + if (upper_z) *upper_z = linear_limit.getZ() * rate; + } } static void -_ephysics_constraint_p2p_recalc(EPhysics_Constraint *constraint, double rate) +_ephysics_constraint_linear_limit_set(EPhysics_Constraint *constraint, Evas_Coord lower_x, Evas_Coord upper_x, Evas_Coord lower_y, Evas_Coord upper_y, Evas_Coord lower_z, Evas_Coord upper_z, double rate) { - ephysics_world_constraint_del(constraint->world, constraint, - constraint->bt_constraint); - delete constraint->bt_constraint; + lower_x = (lower_x) / rate; + upper_x = (upper_x) / rate; - _ephysics_constraint_p2p_set(constraint, rate); -} + lower_y = (lower_y) / rate; + upper_y = (upper_y) / rate; -static 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, double rate) -{ - btGeneric6DofConstraint *slider_constraint; + lower_z = (lower_z) / rate; + upper_z = (upper_z) / rate; - 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)); + constraint->bt_constraint->setLinearLowerLimit(btVector3(-lower_x, -upper_y, + -lower_z)); + constraint->bt_constraint->setLinearUpperLimit(btVector3(upper_x, upper_y, + upper_z)); } void ephysics_constraint_recalc(EPhysics_Constraint *constraint, double rate) { - Evas_Coord left_x, under_y, right_x, above_y; + Evas_Coord lower_x, upper_x, lower_y, upper_y, lower_z, upper_z; - if (constraint->type == EPHYSICS_CONSTRAINT_P2P) - { - _ephysics_constraint_p2p_recalc(constraint, rate); - return; - } - - ephysics_constraint_slider_linear_limit_get(constraint, &left_x, &under_y, - &right_x, &above_y); - _ephysics_constraint_slider_linear_limit_set(constraint, left_x, under_y, - right_x, above_y, rate); + _ephysics_constraint_linear_limit_get(constraint, &lower_x, &upper_x, + &lower_y, &upper_y, &lower_z, &upper_z, rate); + _ephysics_constraint_linear_limit_set(constraint, lower_x, upper_x, lower_y, + upper_y, lower_z, upper_z, rate); } EAPI EPhysics_Constraint * -ephysics_constraint_slider_add(EPhysics_Body *body) +ephysics_constraint_add(EPhysics_Body *body) { EPhysics_Constraint *constraint; btTransform trans; @@ -119,13 +79,6 @@ 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) { @@ -135,6 +88,7 @@ ephysics_constraint_slider_add(EPhysics_Body *body) ephysics_world_lock_take(ephysics_body_world_get(body)); trans.setIdentity(); + trans.setOrigin(btVector3(0, 0, 0)); constraint->bt_constraint = new btGeneric6DofConstraint(*ephysics_body_rigid_body_get(body), trans, false); @@ -146,7 +100,7 @@ ephysics_constraint_slider_add(EPhysics_Body *body) return NULL; } - constraint->type = EPHYSICS_CONSTRAINT_SLIDER; + constraint->bodies[0] = body; constraint->world = ephysics_body_world_get(body); ephysics_world_constraint_add(constraint->world, constraint, constraint->bt_constraint); @@ -157,32 +111,26 @@ ephysics_constraint_slider_add(EPhysics_Body *body) } 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) +ephysics_constraint_linear_limit_set(EPhysics_Constraint *constraint, Evas_Coord lower_x, Evas_Coord upper_x, Evas_Coord lower_y, Evas_Coord upper_y, Evas_Coord lower_z, Evas_Coord upper_z) { + double 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; - } - ephysics_world_lock_take(constraint->world); - _ephysics_constraint_slider_linear_limit_set( - constraint, left_x, under_y, right_x, above_y, - ephysics_world_rate_get(constraint->world)); + rate = ephysics_world_rate_get(constraint->world); + _ephysics_constraint_linear_limit_set(constraint, lower_x, upper_x, lower_y, + upper_y, lower_z, upper_z, rate); ephysics_world_lock_release(constraint->world); } 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) +ephysics_constraint_linear_limit_get(const EPhysics_Constraint *constraint, Evas_Coord *lower_x, Evas_Coord *upper_x, Evas_Coord *lower_y, Evas_Coord *upper_y, Evas_Coord *lower_z, Evas_Coord *upper_z) { - btGeneric6DofConstraint *slider_constraint; - btVector3 linear_limit; int rate; if (!constraint) @@ -191,31 +139,14 @@ ephysics_constraint_slider_linear_limit_get(const EPhysics_Constraint *constrain 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; + _ephysics_constraint_linear_limit_get(constraint, lower_x, upper_x, lower_y, + upper_y, lower_z, upper_z, rate); } EAPI void -ephysics_constraint_slider_angular_limit_set(EPhysics_Constraint *constraint, double counter_clock_z, double clock_wise_z) +ephysics_constraint_angular_limit_set(EPhysics_Constraint *constraint, double counter_clock_x, double clock_wise_x, double counter_clock_y, double clock_wise_y, double counter_clock_z, double clock_wise_z) { - btGeneric6DofConstraint *slider_constraint; if (!constraint) { @@ -223,25 +154,20 @@ ephysics_constraint_slider_angular_limit_set(EPhysics_Constraint *constraint, do return; } - if (constraint->type != EPHYSICS_CONSTRAINT_SLIDER) - { - ERR("Can't set angular limit, this is not an slider constraint."); - return; - } - ephysics_world_lock_take(constraint->world); - 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)); + + constraint->bt_constraint->setAngularLowerLimit(btVector3( + -counter_clock_x / RAD_TO_DEG, -counter_clock_y / RAD_TO_DEG, + -counter_clock_z/RAD_TO_DEG)); + constraint->bt_constraint->setAngularUpperLimit(btVector3( + clock_wise_x / RAD_TO_DEG, clock_wise_y / RAD_TO_DEG, + clock_wise_z/RAD_TO_DEG)); ephysics_world_lock_release(constraint->world); } EAPI void -ephysics_constraint_slider_angular_limit_get(const EPhysics_Constraint *constraint, double *counter_clock_z, double *clock_wise_z) +ephysics_constraint_angular_limit_get(const EPhysics_Constraint *constraint, double *counter_clock_x, double *clock_wise_x, double *counter_clock_y, double *clock_wise_y, double *counter_clock_z, double *clock_wise_z) { - btGeneric6DofConstraint *slider_constraint; btVector3 angular_limit; if (!constraint) @@ -250,39 +176,148 @@ ephysics_constraint_slider_angular_limit_get(const EPhysics_Constraint *constrai return; } - if (constraint->type != EPHYSICS_CONSTRAINT_SLIDER) + if (counter_clock_x) { - ERR("Can't get angular limit, this is not an slider constraint."); - return; + constraint->bt_constraint->getAngularLowerLimit(angular_limit); + *counter_clock_x = angular_limit.getX() * RAD_TO_DEG; + } + + if (clock_wise_x) + { + constraint->bt_constraint->getAngularUpperLimit(angular_limit); + *clock_wise_x = angular_limit.getX() * RAD_TO_DEG; + } + + if (counter_clock_y) + { + constraint->bt_constraint->getAngularLowerLimit(angular_limit); + *counter_clock_y = angular_limit.getY() * RAD_TO_DEG; + } + + if (clock_wise_y) + { + constraint->bt_constraint->getAngularUpperLimit(angular_limit); + *clock_wise_y = angular_limit.getY() * RAD_TO_DEG; } - slider_constraint = (btGeneric6DofConstraint *)constraint->bt_constraint; if (counter_clock_z) { - slider_constraint->getAngularLowerLimit(angular_limit); - *counter_clock_z = angular_limit.getZ(); + constraint->bt_constraint->getAngularLowerLimit(angular_limit); + *counter_clock_z = angular_limit.getZ() * RAD_TO_DEG; } if (clock_wise_z) { - slider_constraint->getAngularUpperLimit(angular_limit); - *clock_wise_z = angular_limit.getZ(); + constraint->bt_constraint->getAngularUpperLimit(angular_limit); + *clock_wise_z = angular_limit.getZ() * RAD_TO_DEG; } } +EAPI void +ephysics_constraint_anchor_set(EPhysics_Constraint *constraint, Evas_Coord anchor_b1_x, Evas_Coord anchor_b1_y, Evas_Coord anchor_b1_z, Evas_Coord anchor_b2_x, Evas_Coord anchor_b2_y, Evas_Coord anchor_b2_z) +{ + btTransform anchor_b1; + btTransform anchor_b2; + btTransform center_mass; + double rate; + Evas_Coord b1x, b1y, b1z, b1w, b1h, b1d, b2x, b2y, b2z, b2w, b2h, b2d, wx, wy, + wh; + btScalar ab1x, ab1y, ab1z, ab2x, ab2y, ab2z; + + if (!constraint) + { + ERR("Can't set constraint's anchors, constraint is null."); + return; + } + + ephysics_world_lock_take(constraint->world); + + ephysics_world_render_geometry_get(constraint->world, &wx, &wy, NULL, NULL, + &wh, NULL); + + ephysics_body_geometry_get(constraint->bodies[0], &b1x, &b1y, &b1z, &b1w, + &b1h, &b1d); + + rate = ephysics_world_rate_get(constraint->world); + + ab1x = (anchor_b1_x - (b1x + b1w / 2)) / rate; + ab1y = (anchor_b1_y - (b1y + b1h / 2)) / rate; + ab1z = (anchor_b1_z - (b1z + b1d / 2)) / rate; + DBG("body1 anchor set to: %lf, %lf, %lf", ab1x, ab1y, ab1z); + + anchor_b1.setIdentity(); + anchor_b1.setOrigin(btVector3(ab1x, ab1y, ab1z)); + + if (constraint->bodies[1]) + { + ephysics_body_geometry_get(constraint->bodies[1], &b2x, &b2y, &b2z, &b2w, + &b2h, &b2d); + + ab2x = (anchor_b2_x - (b2x + b2w / 2)) / rate; + ab2y = (anchor_b2_y - (b2y + b2h / 2)) / rate; + ab2z = (anchor_b2_z - (b2z + b2d / 2)) / rate; + + DBG("body2 anchor set to: %lf, %lf, %lf", ab2x, ab2y, ab2z); + + anchor_b2.setIdentity(); + anchor_b2.setOrigin(btVector3(ab2x, ab2y, ab2z)); + } + else + { + anchor_b2.setIdentity(); + anchor_b2.setOrigin(btVector3(anchor_b1.getOrigin().x(), + anchor_b1.getOrigin().y(), + anchor_b1.getOrigin().z())); + + center_mass = constraint->bodies[0]->rigid_body-> + getCenterOfMassTransform(); + + anchor_b1.setIdentity(); + anchor_b1 = center_mass * anchor_b2; + } + + constraint->bt_constraint->setFrames(anchor_b1, anchor_b2); + ephysics_world_lock_release(constraint->world); +} + +EAPI void +ephysics_constraint_anchor_get(const EPhysics_Constraint *constraint, Evas_Coord *anchor_b1_x, Evas_Coord *anchor_b1_y, Evas_Coord *anchor_b1_z, Evas_Coord *anchor_b2_x, Evas_Coord *anchor_b2_y, Evas_Coord *anchor_b2_z) +{ + btTransform anchor_b1; + btTransform anchor_b2; + double rate; + + if (!constraint) + { + ERR("Can't set constraint's anchors, constraint is null."); + return; + } + + rate = ephysics_world_rate_get(constraint->world); + + anchor_b1 = constraint->bt_constraint->getFrameOffsetA(); + anchor_b2 = constraint->bt_constraint->getFrameOffsetB(); + + if (anchor_b1_x) *anchor_b1_x = round(anchor_b1.getOrigin().x() * rate); + if (anchor_b1_y) *anchor_b1_y = round(anchor_b1.getOrigin().y() * rate); + if (anchor_b1_z) *anchor_b1_z = round(anchor_b1.getOrigin().z() * rate); + if (anchor_b2_x) *anchor_b2_x = round(anchor_b2.getOrigin().x() * rate); + if (anchor_b2_y) *anchor_b2_y = round(anchor_b2.getOrigin().y() * rate); + if (anchor_b2_z) *anchor_b2_z = round(anchor_b2.getOrigin().z() * rate); +} + 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_linked_add(EPhysics_Body *body1, EPhysics_Body *body2) { EPhysics_Constraint *constraint; - if (!body1) + if (!body1 || !body2) { - ERR("To create a constraint body1 must to be non null."); + ERR("To create a linked constraint body1 and bod2 must to be non null."); return NULL; } - if ((body2) && - (ephysics_body_world_get(body1) != ephysics_body_world_get(body2))) + if (ephysics_body_world_get(body1) != ephysics_body_world_get(body2)) { ERR("To create a constraint both bodies must belong to the same" "world."); @@ -305,23 +340,25 @@ ephysics_constraint_p2p_add(EPhysics_Body *body1, EPhysics_Body *body2, Evas_Coo } constraint->world = ephysics_body_world_get(body1); - constraint->p2p.body1 = body1; - constraint->p2p.body2 = body2; - constraint->p2p.anchor_b1_x = anchor_b1_x; - constraint->p2p.anchor_b1_y = anchor_b1_y; - constraint->p2p.anchor_b2_x = anchor_b2_x; - constraint->p2p.anchor_b2_y = anchor_b2_y; + constraint->bodies[0] = body1; + constraint->bodies[1] = body2; ephysics_world_lock_take(constraint->world); - if (!_ephysics_constraint_p2p_set( - constraint, ephysics_world_rate_get(ephysics_body_world_get( - constraint->p2p.body1)))) + + constraint->bt_constraint = new btGeneric6DofConstraint( + *ephysics_body_rigid_body_get(body1), *ephysics_body_rigid_body_get(body2), + btTransform(), btTransform(), false); + + if (!constraint->bt_constraint) { ephysics_world_lock_release(constraint->world); free(constraint); return NULL; } + ephysics_world_constraint_add(constraint->world, constraint, + constraint->bt_constraint); + ephysics_world_lock_release(constraint->world); INF("Constraint added."); return constraint; diff --git a/legacy/ephysics/src/lib/ephysics_private.h b/legacy/ephysics/src/lib/ephysics_private.h index 141edee503..818ec706b1 100644 --- a/legacy/ephysics/src/lib/ephysics_private.h +++ b/legacy/ephysics/src/lib/ephysics_private.h @@ -175,8 +175,8 @@ int ephysics_world_shutdown(void); Eina_Bool ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body); Eina_Bool ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body); Eina_Bool ephysics_world_soft_body_add(EPhysics_World *world, EPhysics_Body *body); -void ephysics_world_constraint_add(EPhysics_World *world, EPhysics_Constraint *constraint, btTypedConstraint *bt_constraint); -void ephysics_world_constraint_del(EPhysics_World *world, EPhysics_Constraint *constraint, btTypedConstraint *bt_constraint); +void ephysics_world_constraint_add(EPhysics_World *world, EPhysics_Constraint *constraint, btGeneric6DofConstraint *bt_constraint); +void ephysics_world_constraint_del(EPhysics_World *world, EPhysics_Constraint *constraint, btGeneric6DofConstraint *bt_constraint); void ephysics_body_world_boundaries_resize(EPhysics_World *world); void ephysics_world_boundary_set(EPhysics_World *world, EPhysics_World_Boundary boundary, EPhysics_Body *body); EPhysics_Body *ephysics_world_boundary_get(const EPhysics_World *world, EPhysics_World_Boundary boundary); diff --git a/legacy/ephysics/src/lib/ephysics_world.cpp b/legacy/ephysics/src/lib/ephysics_world.cpp index 8ee9481d5a..f1004bb3c8 100644 --- a/legacy/ephysics/src/lib/ephysics_world.cpp +++ b/legacy/ephysics/src/lib/ephysics_world.cpp @@ -500,14 +500,14 @@ ephysics_world_soft_body_add(EPhysics_World *world, EPhysics_Body *body) } void -ephysics_world_constraint_add(EPhysics_World *world, EPhysics_Constraint *constraint, btTypedConstraint *bt_constraint) +ephysics_world_constraint_add(EPhysics_World *world, EPhysics_Constraint *constraint, btGeneric6DofConstraint *bt_constraint) { - world->dynamics_world->addConstraint(bt_constraint); + world->dynamics_world->addConstraint(bt_constraint, true); world->constraints = eina_list_append(world->constraints, constraint); } void -ephysics_world_constraint_del(EPhysics_World *world, EPhysics_Constraint *constraint, btTypedConstraint *bt_constraint) +ephysics_world_constraint_del(EPhysics_World *world, EPhysics_Constraint *constraint, btGeneric6DofConstraint *bt_constraint) { world->dynamics_world->removeConstraint(bt_constraint); world->constraints = eina_list_remove(world->constraints, constraint);