diff --git a/include/c3d/maths.h b/include/c3d/maths.h index 9113cf3..76e3bdd 100644 --- a/include/c3d/maths.h +++ b/include/c3d/maths.h @@ -624,10 +624,10 @@ void Mtx_FromQuat(C3D_Mtx* m, C3D_FQuat q); /** * @brief Get Quaternion equivalent to 4x4 matrix * @note If the matrix is orthogonal or special orthogonal, where determinant(matrix) = +1.0f, then the matrix can be converted. - * @param[out] q Output Quaternion * @param[in] m Input Matrix + * @return Generated Quaternion */ -void Quat_FromMtx(C3D_FQuat* q, C3D_Mtx m); +C3D_FQuat Quat_FromMtx(C3D_Mtx m); /** * @brief Identity Quaternion diff --git a/source/maths/quat_frommtx.c b/source/maths/quat_frommtx.c index eba7e96..f9ae941 100644 --- a/source/maths/quat_frommtx.c +++ b/source/maths/quat_frommtx.c @@ -1,6 +1,6 @@ #include -void Quat_FromMtx(C3D_FQuat* q, C3D_Mtx m) +C3D_FQuat Quat_FromMtx(C3D_Mtx m) { //Taken from Gamasutra: //http://www.gamasutra.com/view/feature/131686/rotating_objects_using_quaternions.php @@ -9,6 +9,7 @@ void Quat_FromMtx(C3D_FQuat* q, C3D_Mtx m) //Variables we need. float trace, sqrtTrace; + C3D_FQuat q; //Check the main diagonal of the passed-in matrix for positive/negative signs. trace = m.r[0].c[0] + m.r[1].c[1] + m.r[2].c[2]; @@ -16,11 +17,11 @@ void Quat_FromMtx(C3D_FQuat* q, C3D_Mtx m) { //Diagonal is positive. sqrtTrace = sqrtf(trace + 1.0f); - q->w = sqrtTrace / 2.0f; + q.w = sqrtTrace / 2.0f; sqrtTrace = 0.5 / sqrtTrace; - q->x = (m.r[1].c[2] - m.r[2].c[1]) * sqrtTrace; - q->y = (m.r[2].c[0] - m.r[0].c[2]) * sqrtTrace; - q->z = (m.r[0].c[1] - m.r[1].c[0]) * sqrtTrace; + q.x = (m.r[1].c[2] - m.r[2].c[1]) * sqrtTrace; + q.y = (m.r[2].c[0] - m.r[0].c[2]) * sqrtTrace; + q.z = (m.r[0].c[1] - m.r[1].c[0]) * sqrtTrace; } else { @@ -28,26 +29,27 @@ void Quat_FromMtx(C3D_FQuat* q, C3D_Mtx m) if (m.r[0].c[0] > m.r[1].c[1] && m.r[0].c[0] > m.r[2].c[2]) { sqrtTrace = 2.0f * sqrtf(1.0f + m.r[0].c[0] - m.r[1].c[1] - m.r[2].c[2]); - q->w = (m.r[2].c[1] - m.r[1].c[2]) / sqrtTrace; - q->x = 0.25f * sqrtTrace; - q->y = (m.r[0].c[1] - m.r[1].c[0]) / sqrtTrace; - q->z = (m.r[0].c[2] - m.r[2].c[0]) / sqrtTrace; + q.w = (m.r[2].c[1] - m.r[1].c[2]) / sqrtTrace; + q.x = 0.25f * sqrtTrace; + q.y = (m.r[0].c[1] - m.r[1].c[0]) / sqrtTrace; + q.z = (m.r[0].c[2] - m.r[2].c[0]) / sqrtTrace; } else if (m.r[1].c[1] > m.r[2].c[2]) { sqrtTrace = 2.0f * sqrtf(1.0f + m.r[1].c[1] - m.r[0].c[0] - m.r[2].c[2]); - q->w = (m.r[0].c[2] - m.r[2].c[0]) / sqrtTrace; - q->x = (m.r[0].c[1] - m.r[1].c[0]) / sqrtTrace; - q->y = 0.25f * sqrtTrace; - q->z = (m.r[1].c[2] - m.r[2].c[1]) / sqrtTrace; + q.w = (m.r[0].c[2] - m.r[2].c[0]) / sqrtTrace; + q.x = (m.r[0].c[1] - m.r[1].c[0]) / sqrtTrace; + q.y = 0.25f * sqrtTrace; + q.z = (m.r[1].c[2] - m.r[2].c[1]) / sqrtTrace; } else { sqrtTrace = 2.0f * sqrtf(1.0f + m.r[2].c[2] - m.r[0].c[0] - m.r[1].c[1]); - q->w = (m.r[1].c[0] - m.r[0].c[1]) / sqrtTrace; - q->x = (m.r[0].c[2] - m.r[2].c[0]) / sqrtTrace; - q->y = (m.r[1].c[2] - m.r[2].c[1]) / sqrtTrace; - q->z = 0.25f * sqrtTrace; + q.w = (m.r[1].c[0] - m.r[0].c[1]) / sqrtTrace; + q.x = (m.r[0].c[2] - m.r[2].c[0]) / sqrtTrace; + q.y = (m.r[1].c[2] - m.r[2].c[1]) / sqrtTrace; + q.z = 0.25f * sqrtTrace; } } + return q; }