aboutsummaryrefslogtreecommitdiffstats
path: root/legacy/ephysics/src/lib
diff options
context:
space:
mode:
authorBruno Dilly <bdilly@profusion.mobi>2012-11-14 20:01:20 +0000
committerBruno Dilly <bdilly@profusion.mobi>2012-11-14 20:01:20 +0000
commit52e0d5417466418af18254cf40a2099dc5c6e2f0 (patch)
tree12de11baf8744763656d2e58366823d7bd1bfc92 /legacy/ephysics/src/lib
parent8a7f6631687d9ee9d01c2f6eec33580e9384c20d (diff)
downloadefl-52e0d5417466418af18254cf40a2099dc5c6e2f0.tar.gz
efl-52e0d5417466418af18254cf40a2099dc5c6e2f0.tar.xz
efl-52e0d5417466418af18254cf40a2099dc5c6e2f0.zip
ephysics: change quaternion API to avoid many free calls
It was really annoying and error prone (easy to leak). SVN revision: 79299
Diffstat (limited to 'legacy/ephysics/src/lib')
-rw-r--r--legacy/ephysics/src/lib/EPhysics.h57
-rw-r--r--legacy/ephysics/src/lib/ephysics_body.cpp19
-rw-r--r--legacy/ephysics/src/lib/ephysics_quaternion.cpp86
3 files changed, 89 insertions, 73 deletions
diff --git a/legacy/ephysics/src/lib/EPhysics.h b/legacy/ephysics/src/lib/EPhysics.h
index 5a9279693..04179df1a 100644
--- a/legacy/ephysics/src/lib/EPhysics.h
+++ b/legacy/ephysics/src/lib/EPhysics.h
@@ -158,19 +158,29 @@ 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 2054e4952..5ad3fdb48 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 f00876983..c5abcd075 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