diff --git a/legacy/ephysics/src/bin/ephysics_sandbox.c b/legacy/ephysics/src/bin/ephysics_sandbox.c index 5d29238568..7bb0db2a6a 100644 --- a/legacy/ephysics/src/bin/ephysics_sandbox.c +++ b/legacy/ephysics/src/bin/ephysics_sandbox.c @@ -118,14 +118,14 @@ _type_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) double mass, friction, restitution, lin_damping, ang_damping; double lin_sleeping, ang_sleeping; EPhysics_Body_Material material; - EPhysics_Quaternion *rotation; + EPhysics_Quaternion rotation; Evas_Object *body_image; EPhysics_World *world; Body_Data *bd = data; EPhysics_Body *body = bd->body; mass = ephysics_body_mass_get(body); - rotation = ephysics_body_rotation_get(body); + ephysics_body_rotation_get(body, &rotation); friction = ephysics_body_friction_get(body); restitution = ephysics_body_restitution_get(body); ephysics_body_damping_get(body, &lin_damping, &ang_damping); @@ -152,7 +152,7 @@ _type_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) ephysics_body_evas_object_set(body, body_image, EINA_TRUE); ephysics_body_mass_set(body, mass); - ephysics_body_rotation_set(body, rotation); + ephysics_body_rotation_set(body, &rotation); ephysics_body_friction_set(body, friction); ephysics_body_restitution_set(body, restitution); ephysics_body_damping_set(body, lin_damping, ang_damping); @@ -168,7 +168,6 @@ _type_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) elm_slider_value_get(bd->controls.force.torque)); bd->body = body; - free(rotation); } static void @@ -229,13 +228,10 @@ _density_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) static void _rotation_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) { - EPhysics_Quaternion *quat; + EPhysics_Quaternion quat; Body_Data *bd = data; - - quat = ephysics_quaternion_new(0, 0, 0, 0); - ephysics_quaternion_euler_set(quat, 0, 0, elm_slider_value_get(obj)); - ephysics_body_rotation_set(bd->body, quat); - free(quat); + ephysics_quaternion_euler_set(&quat, 0, 0, elm_slider_value_get(obj)); + ephysics_body_rotation_set(bd->body, &quat); } static void diff --git a/legacy/ephysics/src/bin/test_bouncing_3d.c b/legacy/ephysics/src/bin/test_bouncing_3d.c index e239ab699f..cfd3747b7e 100644 --- a/legacy/ephysics/src/bin/test_bouncing_3d.c +++ b/legacy/ephysics/src/bin/test_bouncing_3d.c @@ -7,18 +7,14 @@ static void _pos_print_cb(void *data __UNUSED__, EPhysics_Body *body, void *event_info __UNUSED__) { - EPhysics_Quaternion *quat; - double rx, ry, rz, rw; + EPhysics_Quaternion quat; Evas_Coord x, y, z; ephysics_body_geometry_get(body, &x, &y, &z, NULL, NULL, NULL); - - quat = ephysics_body_rotation_get(body); - ephysics_quaternion_get(quat, &rx, &ry, &rz, &rw); - free(quat); + ephysics_body_rotation_get(body, &quat); printf("Position X:%i Y:%i Z:%i\n", x, y, z); - printf("Rotation X:%lf Y:%lf Z:%lf W:%lf\n", rx, ry, rz, rw); + printf("Rotation X:%lf Y:%lf Z:%lf W:%lf\n", quat.x, quat.y, quat.z, quat.w); } static Eina_Bool diff --git a/legacy/ephysics/src/bin/test_cube_3d.c b/legacy/ephysics/src/bin/test_cube_3d.c index cf107299b7..cf7156ee1c 100644 --- a/legacy/ephysics/src/bin/test_cube_3d.c +++ b/legacy/ephysics/src/bin/test_cube_3d.c @@ -9,7 +9,7 @@ static void _mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) { - EPhysics_Quaternion *quat_prev, *quat_delta, *quat; + EPhysics_Quaternion quat_prev, quat_delta, quat; Evas_Event_Mouse_Move *mmove = event_info; EPhysics_Body *body = data; double rx, ry; @@ -19,15 +19,10 @@ _mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void rx = mmove->cur.output.y - mmove->prev.output.y; ry = mmove->cur.output.x - mmove->prev.output.x; - quat_prev = ephysics_body_rotation_get(body); - quat_delta = ephysics_quaternion_new(0, 0, 0, 0); - ephysics_quaternion_euler_set(quat_delta, -ry * 0.06, - rx * 0.04, 0); - quat = ephysics_quaternion_multiply(quat_prev, quat_delta); - ephysics_body_rotation_set(body, quat); - - free(quat_prev); - free(quat_delta); - free(quat); + ephysics_body_rotation_get(body, &quat_prev); + ephysics_quaternion_euler_set(&quat_delta, -ry * 0.06, - rx * 0.04, 0); + ephysics_quaternion_multiply(&quat_prev, &quat_delta, &quat); + ephysics_body_rotation_set(body, &quat); } static void diff --git a/legacy/ephysics/src/bin/test_rotating_forever.c b/legacy/ephysics/src/bin/test_rotating_forever.c index d0be41f939..f0445887bd 100644 --- a/legacy/ephysics/src/bin/test_rotating_forever.c +++ b/legacy/ephysics/src/bin/test_rotating_forever.c @@ -7,19 +7,15 @@ static Eina_Bool _rotate_cb(void *data) { - EPhysics_Quaternion *quat_prev, *quat_delta, *quat; + EPhysics_Quaternion *quat_prev, quat_delta, quat; EPhysics_Body *body = data; - quat_prev = ephysics_body_rotation_get(body); - quat_delta = ephysics_quaternion_new(0, 0, -0.15, 0.98); - ephysics_quaternion_normalize(quat_delta); - quat = ephysics_quaternion_multiply(quat_delta, quat_prev); - - ephysics_body_rotation_set(body, quat); - + quat_prev = ephysics_body_rotation_get(body, NULL); + ephysics_quaternion_set(&quat_delta, 0, 0, -0.15, 0.98); + ephysics_quaternion_normalize(&quat_delta); + ephysics_body_rotation_set( + body, ephysics_quaternion_multiply(&quat_delta, quat_prev, &quat)); free(quat_prev); - free(quat_delta); - free(quat); return EINA_TRUE; } @@ -74,14 +70,13 @@ static void _update_object_cb(void *data __UNUSED__, EPhysics_Body *body, void *event_info __UNUSED__) { double rx, ry, rz, rw, vrot, torque; - EPhysics_Quaternion *quat; + EPhysics_Quaternion quat; ephysics_body_angular_velocity_get(body, NULL, NULL, &vrot); ephysics_body_torques_get(body, NULL, NULL, &torque); - quat = ephysics_body_rotation_get(body); - ephysics_quaternion_get(quat, &rx, &ry, &rz, &rw); - free(quat); + ephysics_body_rotation_get(body, &quat); + ephysics_quaternion_get(&quat, &rx, &ry, &rz, &rw); ephysics_body_evas_object_update(body); diff --git a/legacy/ephysics/src/lib/EPhysics.h b/legacy/ephysics/src/lib/EPhysics.h index 5a9279693a..04179df1ad 100644 --- a/legacy/ephysics/src/lib/EPhysics.h +++ b/legacy/ephysics/src/lib/EPhysics.h @@ -157,20 +157,30 @@ EAPI int ephysics_shutdown(void); */ typedef struct _EPhysics_Quaternion EPhysics_Quaternion; +/** + * @struct _EPhysics_Quaternion + * + * Quaternion coordinates and rotation (w, x, y, z) + */ +struct _EPhysics_Quaternion +{ + double w; /**< rotation */ + double x; /**< x coordinate */ + double y; /**< y coordinate */ + double z; /**< z coordinate */ +}; + /** * @brief * Create a new quaternion. * - * @note It should be deleted with free() after usage is concluded. - * + * By default a quaternion is created as identity (w = 1, x = 0, y = 0, z = 0). * This values can be modified later by quaternion operations or set directly. * - * @param x The x coordinate. - * @param y The y coordinate. - * @param z The z coordinate. - * @param w The rotation. * @return The created quaternion or @c NULL on error. * + * @note It should be deleted with free() after usage is concluded. + * * @see ephysics_quaternion_set(); * @see ephysics_quaternion_axis_angle_set(); * @see ephysics_quaternion_euler_set(); @@ -179,7 +189,7 @@ typedef struct _EPhysics_Quaternion EPhysics_Quaternion; * * @ingroup EPhysics_Quaternion */ -EAPI EPhysics_Quaternion *ephysics_quaternion_new(double x, double y, double z, double w); +EAPI EPhysics_Quaternion *ephysics_quaternion_new(void); /** * @brief @@ -325,13 +335,13 @@ EAPI void ephysics_quaternion_inverse_scale(EPhysics_Quaternion *quat, double sc * * @param quat1 First quaternion to sum. * @param quat2 Second quaternion to sum. + * @param result Quaternion used to store the result. If it's @c NULL, a new + * quaternion will be allocated (and should be freed after usage). * @return The sum quaternion or @c NULL on error. * - * @note It should be freed after usage. - * * @ingroup EPhysics_Quaternion */ -EAPI EPhysics_Quaternion *ephysics_quaternion_sum(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2); +EAPI EPhysics_Quaternion *ephysics_quaternion_sum(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2, EPhysics_Quaternion *result); /** * @brief @@ -339,13 +349,13 @@ EAPI EPhysics_Quaternion *ephysics_quaternion_sum(const EPhysics_Quaternion *qua * * @param quat1 First quaternion. * @param quat2 Second quaternion. + * @param result Quaternion used to store the result. If it's @c NULL, a new + * quaternion will be allocated (and should be freed after usage). * @return The difference between @p quat1 and @p quat2, or @c NULL on error. * - * @note It should be freed after usage. - * * @ingroup EPhysics_Quaternion */ -EAPI EPhysics_Quaternion *ephysics_quaternion_diff(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2); +EAPI EPhysics_Quaternion *ephysics_quaternion_diff(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2, EPhysics_Quaternion *result); /** * @brief @@ -353,14 +363,14 @@ EAPI EPhysics_Quaternion *ephysics_quaternion_diff(const EPhysics_Quaternion *qu * * @param quat1 First quaternion. * @param quat2 Second quaternion. + * @param result Quaternion used to store the result. If it's @c NULL, a new + * quaternion will be allocated (and should be freed after usage). * @return The @p quat1 multiplied by @p quat2 on the right, or @c NULL * on error. * - * @note It should be freed after usage. - * * @ingroup EPhysics_Quaternion */ -EAPI EPhysics_Quaternion *ephysics_quaternion_multiply(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2); +EAPI EPhysics_Quaternion *ephysics_quaternion_multiply(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2, EPhysics_Quaternion *result); /** * @brief @@ -374,14 +384,14 @@ EAPI EPhysics_Quaternion *ephysics_quaternion_multiply(const EPhysics_Quaternion * @param ratio The ratio between @p quat1 and @p quat2 to interpolate. If * @p ratio = 0, the result is @p quat1, if @p ratio = 1, the result is * @p quat2. + * @param result Quaternion used to store the result. If it's @c NULL, a new + * quaternion will be allocated (and should be freed after usage). * @return The result of slerp between @p quat1 and @p quat2, or @c NULL * on error. * - * @note It should be freed after usage. - * * @ingroup EPhysics_Quaternion */ -EAPI EPhysics_Quaternion *ephysics_quaternion_slerp(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2, double ratio); +EAPI EPhysics_Quaternion *ephysics_quaternion_slerp(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2, double ratio, EPhysics_Quaternion *result); /** * @brief @@ -3738,18 +3748,19 @@ EAPI void ephysics_body_linear_movement_enable_get(const EPhysics_Body *body, Ei * @brief * Get body's rotation quaternion. * - * By default rotation is 0 degree on all axes. + * By default rotation is 0 degree on all axes (1, 0, 0, 0). * * @param body The physics body. - * @return A quaternion or @c NULL on error. It should be freed with free() - * after usage. + * @param rotation Quaternion used to store the result. If it's @c NULL, a new + * quaternion will be allocated (and should be freed after usage). + * @return A quaternion or @c NULL on error. * * @see ephysics_body_rotation_set() * @see ephysics_quaternion_get() * * @ingroup EPhysics_Body */ -EAPI EPhysics_Quaternion *ephysics_body_rotation_get(const EPhysics_Body *body); +EAPI EPhysics_Quaternion *ephysics_body_rotation_get(const EPhysics_Body *body, EPhysics_Quaternion *rotation); /** * @brief diff --git a/legacy/ephysics/src/lib/ephysics_body.cpp b/legacy/ephysics/src/lib/ephysics_body.cpp index 2054e49528..5ad3fdb482 100644 --- a/legacy/ephysics/src/lib/ephysics_body.cpp +++ b/legacy/ephysics/src/lib/ephysics_body.cpp @@ -3268,7 +3268,7 @@ ephysics_body_angular_movement_enable_get(const EPhysics_Body *body, Eina_Bool * } EAPI EPhysics_Quaternion * -ephysics_body_rotation_get(const EPhysics_Body *body) +ephysics_body_rotation_get(const EPhysics_Body *body, EPhysics_Quaternion *rotation) { EPhysics_Quaternion *quat; btTransform trans; @@ -3279,11 +3279,20 @@ ephysics_body_rotation_get(const EPhysics_Body *body) return NULL; } + if (!rotation) + { + quat = ephysics_quaternion_new(); + if (!quat) return NULL; + } + else + quat = rotation; + trans = _ephysics_body_transform_get(body); - quat = ephysics_quaternion_new(trans.getRotation().x(), - trans.getRotation().y(), - trans.getRotation().z(), - trans.getRotation().getW()); + quat->x = trans.getRotation().x(); + quat->y = trans.getRotation().y(); + quat->z = trans.getRotation().z(); + quat->w = trans.getRotation().getW(); + return quat; } diff --git a/legacy/ephysics/src/lib/ephysics_quaternion.cpp b/legacy/ephysics/src/lib/ephysics_quaternion.cpp index f008769839..c5abcd0753 100644 --- a/legacy/ephysics/src/lib/ephysics_quaternion.cpp +++ b/legacy/ephysics/src/lib/ephysics_quaternion.cpp @@ -8,13 +8,6 @@ extern "C" { #endif -struct _EPhysics_Quaternion { - double x; - double y; - double z; - double w; -}; - static void _ephysics_quaternion_update(EPhysics_Quaternion *quat, btQuaternion *bt_quat) { @@ -24,8 +17,23 @@ _ephysics_quaternion_update(EPhysics_Quaternion *quat, btQuaternion *bt_quat) quat->w = bt_quat->getW(); } +static EPhysics_Quaternion * +_ephysics_quaternion_params_check(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2, EPhysics_Quaternion *result) +{ + if ((!quat1) || (!quat2)) + { + ERR("Can't operate over null quaternions."); + return NULL; + } + + if (result) + return result; + + return ephysics_quaternion_new(); +} + EAPI EPhysics_Quaternion * -ephysics_quaternion_new(double x, double y, double z, double w) +ephysics_quaternion_new(void) { EPhysics_Quaternion *quat; @@ -37,11 +45,7 @@ ephysics_quaternion_new(double x, double y, double z, double w) return NULL; } - quat->x = x; - quat->y = y; - quat->z = z; - quat->w = w; - + quat->w = 1; return quat; } @@ -192,79 +196,71 @@ ephysics_quaternion_inverse_scale(EPhysics_Quaternion *quat, double scale) } EAPI EPhysics_Quaternion * -ephysics_quaternion_sum(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2) +ephysics_quaternion_sum(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2, EPhysics_Quaternion *result) { btQuaternion bt_quat1, bt_quat2, bt_quat; + EPhysics_Quaternion *quat; - if ((!quat1) || (!quat2)) - { - ERR("Can't operate over null quaternions."); - return NULL; - } + quat = _ephysics_quaternion_params_check(quat1, quat2, result); + if (!quat) return NULL; bt_quat1 = btQuaternion(quat1->x, quat1->y, quat1->z, quat1->w); bt_quat2 = btQuaternion(quat2->x, quat2->y, quat2->z, quat2->w); bt_quat = bt_quat1 + bt_quat2; - return ephysics_quaternion_new(bt_quat.x(), bt_quat.y(), bt_quat.z(), - bt_quat.getW()); + _ephysics_quaternion_update(quat, &bt_quat); + return quat; } EAPI EPhysics_Quaternion * -ephysics_quaternion_diff(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2) +ephysics_quaternion_diff(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2, EPhysics_Quaternion *result) { btQuaternion bt_quat1, bt_quat2, bt_quat; + EPhysics_Quaternion *quat; - if ((!quat1) || (!quat2)) - { - ERR("Can't operate over null quaternions."); - return NULL; - } + quat = _ephysics_quaternion_params_check(quat1, quat2, result); + if (!quat) return NULL; bt_quat1 = btQuaternion(quat1->x, quat1->y, quat1->z, quat1->w); bt_quat2 = btQuaternion(quat2->x, quat2->y, quat2->z, quat2->w); bt_quat = bt_quat1 - bt_quat2; - return ephysics_quaternion_new(bt_quat.x(), bt_quat.y(), bt_quat.z(), - bt_quat.getW()); + _ephysics_quaternion_update(quat, &bt_quat); + return quat; } EAPI EPhysics_Quaternion * -ephysics_quaternion_multiply(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2) +ephysics_quaternion_multiply(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2, EPhysics_Quaternion *result) { btQuaternion bt_quat1, bt_quat2, bt_quat; + EPhysics_Quaternion *quat; - if ((!quat1) || (!quat2)) - { - ERR("Can't operate over null quaternions."); - return NULL; - } + quat = _ephysics_quaternion_params_check(quat1, quat2, result); + if (!quat) return NULL; bt_quat1 = btQuaternion(quat1->x, quat1->y, quat1->z, quat1->w); bt_quat2 = btQuaternion(quat2->x, quat2->y, quat2->z, quat2->w); bt_quat = bt_quat1 * bt_quat2; - return ephysics_quaternion_new(bt_quat.x(), bt_quat.y(), bt_quat.z(), - bt_quat.getW()); + _ephysics_quaternion_update(quat, &bt_quat); + return quat; } EAPI EPhysics_Quaternion * -ephysics_quaternion_slerp(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2, double ratio) +ephysics_quaternion_slerp(const EPhysics_Quaternion *quat1, const EPhysics_Quaternion *quat2, double ratio, EPhysics_Quaternion *result) { btQuaternion bt_quat1, bt_quat2; + EPhysics_Quaternion *quat; - if ((!quat1) || (!quat2)) - { - ERR("Can't operate over null quaternions."); - return NULL; - } + quat = _ephysics_quaternion_params_check(quat1, quat2, result); + if (!quat) return NULL; bt_quat1 = btQuaternion(quat1->x, quat1->y, quat1->z, quat1->w); bt_quat2 = btQuaternion(quat2->x, quat2->y, quat2->z, quat2->w); bt_quat1.slerp(bt_quat2, ratio); - return ephysics_quaternion_new(bt_quat1.x(), bt_quat1.y(), bt_quat1.z(), - bt_quat1.getW()); + _ephysics_quaternion_update(quat, &bt_quat1); + return quat; } EAPI double