From 57c3be0b9f4eb52967baa94f62dbfdaf4f8e8f6d Mon Sep 17 00:00:00 2001 From: Sergey Krivohatskiy Date: Tue, 23 Mar 2021 14:24:41 +0300 Subject: [PATCH 1/7] Added axisAngle tests Signed-off-by: Sergey Krivohatskiy --- test/gtx/gtx_matrix_interpolation.cpp | 60 ++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/test/gtx/gtx_matrix_interpolation.cpp b/test/gtx/gtx_matrix_interpolation.cpp index 38f0ce5d..d505bee3 100644 --- a/test/gtx/gtx_matrix_interpolation.cpp +++ b/test/gtx/gtx_matrix_interpolation.cpp @@ -1,8 +1,11 @@ #define GLM_ENABLE_EXPERIMENTAL #include +#include #include #include +#include + static int test_axisAngle() { @@ -34,6 +37,60 @@ static int test_axisAngle() return Error; } +template +int testForAxisAngle(glm::tvec3 const axisTrue, T const angleTrue) +{ + T const eps = sqrt(std::numeric_limits::epsilon()); + + glm::tmat4x4 const matTrue = glm::axisAngleMatrix(axisTrue, angleTrue); + + glm::tvec3 axis; + T angle; + glm::axisAngle(matTrue, axis, angle); + glm::tmat4x4 const matRebuilt = glm::axisAngleMatrix(axis, angle); + + glm::tmat4x4 const errMat = matTrue - matRebuilt; + T const maxErr = glm::compMax(glm::tvec4( + glm::compMax(glm::abs(errMat[0])), + glm::compMax(glm::abs(errMat[1])), + glm::compMax(glm::abs(errMat[2])), + glm::compMax(glm::abs(errMat[3])) + )); + + return maxErr < eps ? 0 : 1; +} + +static int test_axisAngle2() +{ + int Error = 0; + + Error += testForAxisAngle(glm::vec3(0.0f, 1.0f, 0.0f), 0.0f); + Error += testForAxisAngle(glm::vec3(0.358f, 0.0716f, 0.9309f), 0.00001f); + Error += testForAxisAngle(glm::vec3(1.0f, 0.0f, 0.0f), 0.0001f); + Error += testForAxisAngle(glm::vec3(0.0f, 0.0f, 1.0f), 0.001f); + Error += testForAxisAngle(glm::vec3(0.0f, 0.0f, 1.0f), 0.001f); + Error += testForAxisAngle(glm::vec3(0.0f, 1.0f, 0.0f), 0.005f); + Error += testForAxisAngle(glm::vec3(0.0f, 0.0f, 1.0f), 0.005f); + Error += testForAxisAngle(glm::vec3(0.358f, 0.0716f, 0.9309f), 0.03f); + Error += testForAxisAngle(glm::vec3(0.358f, 0.0716f, 0.9309f), 0.0003f); + Error += testForAxisAngle(glm::vec3(0.0f, 0.0f, 1.0f), 0.01f); + Error += testForAxisAngle(glm::dvec3(0.0f, 1.0f, 0.0f), 0.00005); + Error += testForAxisAngle(glm::dvec3(-1.0f, 0.0f, 0.0f), 0.000001); + Error += testForAxisAngle(glm::dvec3(0.7071f, 0.7071f, 0.0f), 0.5); + Error += testForAxisAngle(glm::dvec3(0.7071f, 0.0f, 0.7071f), 0.0002); + Error += testForAxisAngle(glm::dvec3(0.7071f, 0.0f, 0.7071f), 0.00002); + Error += testForAxisAngle(glm::dvec3(0.7071f, 0.0f, 0.7071f), 0.000002); + Error += testForAxisAngle(glm::dvec3(0.7071f, 0.0f, 0.7071f), 0.0000002); + Error += testForAxisAngle(glm::vec3(0.0f, 0.7071f, 0.7071f), 1.3f); + Error += testForAxisAngle(glm::vec3(0.0f, 0.7071f, 0.7071f), 6.3f); + Error += testForAxisAngle(glm::vec3(1.0f, 0.0f, 0.0f), -0.23456f); + Error += testForAxisAngle(glm::vec3(1.0f, 0.0f, 0.0f), glm::pi()); + Error += testForAxisAngle(glm::vec3(0.0f, 1.0f, 0.0f), -glm::pi()); + Error += testForAxisAngle(glm::vec3(0.358f, 0.0716f, 0.9309f), -glm::pi()); + + return Error; +} + static int test_rotate() { glm::mat4 m2(1.0); @@ -49,8 +106,9 @@ static int test_rotate() int main() { int Error = 0; - + Error += test_axisAngle(); + Error += test_axisAngle2(); Error += test_rotate(); return Error; From c9c656ce31efbd71dca1e3f0e959e80f0c37ca8a Mon Sep 17 00:00:00 2001 From: Sergey Krivohatskiy Date: Tue, 23 Mar 2021 14:27:00 +0300 Subject: [PATCH 2/7] axisAngle refactoring Signed-off-by: Sergey Krivohatskiy --- glm/gtx/matrix_interpolation.inl | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/glm/gtx/matrix_interpolation.inl b/glm/gtx/matrix_interpolation.inl index 28c3e816..10972974 100644 --- a/glm/gtx/matrix_interpolation.inl +++ b/glm/gtx/matrix_interpolation.inl @@ -1,11 +1,11 @@ /// @ref gtx_matrix_interpolation -#include "../gtc/constants.hpp" +#include "../ext/scalar_constants.hpp" namespace glm { template - GLM_FUNC_QUALIFIER void axisAngle(mat<4, 4, T, Q> const& m, vec<3, T, Q> & axis, T& angle) + GLM_FUNC_QUALIFIER void axisAngle(mat<4, 4, T, Q> const& m, vec<3, T, Q>& axis, T& angle) { T epsilon = static_cast(0.01); T epsilon2 = static_cast(0.1); @@ -15,12 +15,11 @@ namespace glm if ((abs(m[1][0] + m[0][1]) < epsilon2) && (abs(m[2][0] + m[0][2]) < epsilon2) && (abs(m[2][1] + m[1][2]) < epsilon2) && (abs(m[0][0] + m[1][1] + m[2][2] - static_cast(3.0)) < epsilon2)) { angle = static_cast(0.0); - axis.x = static_cast(1.0); - axis.y = static_cast(0.0); - axis.z = static_cast(0.0); + axis = vec<3, T, Q>( + static_cast(1.0), static_cast(0.0), static_cast(0.0)); return; } - angle = static_cast(3.1415926535897932384626433832795); + angle = pi(); T xx = (m[0][0] + static_cast(1.0)) * static_cast(0.5); T yy = (m[1][1] + static_cast(1.0)) * static_cast(0.5); T zz = (m[2][2] + static_cast(1.0)) * static_cast(0.5); @@ -74,9 +73,7 @@ namespace glm } return; } - T s = sqrt((m[2][1] - m[1][2]) * (m[2][1] - m[1][2]) + (m[2][0] - m[0][2]) * (m[2][0] - m[0][2]) + (m[1][0] - m[0][1]) * (m[1][0] - m[0][1])); - if (glm::abs(s) < T(0.001)) - s = static_cast(1); + T const angleCos = (m[0][0] + m[1][1] + m[2][2] - static_cast(1)) * static_cast(0.5); if(angleCos >= static_cast(1.0)) { @@ -90,9 +87,9 @@ namespace glm { angle = acos(angleCos); } - axis.x = (m[1][2] - m[2][1]) / s; - axis.y = (m[2][0] - m[0][2]) / s; - axis.z = (m[0][1] - m[1][0]) / s; + + axis = glm::normalize(glm::vec<3, T, Q>( + m[1][2] - m[2][1], m[2][0] - m[0][2], m[0][1] - m[1][0])); } template From df7b5bda7c174e073f56ccacd4de522f6e88cca8 Mon Sep 17 00:00:00 2001 From: Sergey Krivohatskiy Date: Tue, 23 Mar 2021 14:28:36 +0300 Subject: [PATCH 3/7] axisAngle epsilon changed to work as expected on small angles also small refactoring also single epsilon is used also passes new axisAngle tests now Signed-off-by: Sergey Krivohatskiy --- glm/gtx/matrix_interpolation.inl | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/glm/gtx/matrix_interpolation.inl b/glm/gtx/matrix_interpolation.inl index 10972974..f4ba3a6f 100644 --- a/glm/gtx/matrix_interpolation.inl +++ b/glm/gtx/matrix_interpolation.inl @@ -2,17 +2,29 @@ #include "../ext/scalar_constants.hpp" +#include + namespace glm { template GLM_FUNC_QUALIFIER void axisAngle(mat<4, 4, T, Q> const& m, vec<3, T, Q>& axis, T& angle) { - T epsilon = static_cast(0.01); - T epsilon2 = static_cast(0.1); + T const epsilon = + std::numeric_limits::epsilon() * static_cast(1e2); - if((abs(m[1][0] - m[0][1]) < epsilon) && (abs(m[2][0] - m[0][2]) < epsilon) && (abs(m[2][1] - m[1][2]) < epsilon)) + bool const nearSymmetrical = + abs(m[1][0] - m[0][1]) < epsilon && + abs(m[2][0] - m[0][2]) < epsilon && + abs(m[2][1] - m[1][2]) < epsilon; + + if(nearSymmetrical) { - if ((abs(m[1][0] + m[0][1]) < epsilon2) && (abs(m[2][0] + m[0][2]) < epsilon2) && (abs(m[2][1] + m[1][2]) < epsilon2) && (abs(m[0][0] + m[1][1] + m[2][2] - static_cast(3.0)) < epsilon2)) + bool const nearIdentity = + abs(m[1][0] + m[0][1]) < epsilon && + abs(m[2][0] + m[0][2]) < epsilon && + abs(m[2][1] + m[1][2]) < epsilon && + abs(m[0][0] + m[1][1] + m[2][2] - T(3.0)) < epsilon; + if (nearIdentity) { angle = static_cast(0.0); axis = vec<3, T, Q>( From 2b766d53034ced3b4e3412c3edb88775cf8d43e3 Mon Sep 17 00:00:00 2001 From: Sergey Krivohatskiy Date: Tue, 23 Mar 2021 14:30:52 +0300 Subject: [PATCH 4/7] a few more tests for axisAngle Signed-off-by: Sergey Krivohatskiy --- test/gtx/gtx_matrix_interpolation.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/gtx/gtx_matrix_interpolation.cpp b/test/gtx/gtx_matrix_interpolation.cpp index d505bee3..8d3a073e 100644 --- a/test/gtx/gtx_matrix_interpolation.cpp +++ b/test/gtx/gtx_matrix_interpolation.cpp @@ -87,6 +87,10 @@ static int test_axisAngle2() Error += testForAxisAngle(glm::vec3(1.0f, 0.0f, 0.0f), glm::pi()); Error += testForAxisAngle(glm::vec3(0.0f, 1.0f, 0.0f), -glm::pi()); Error += testForAxisAngle(glm::vec3(0.358f, 0.0716f, 0.9309f), -glm::pi()); + Error += testForAxisAngle(glm::vec3(1.0f, 0.0f, 0.0f), glm::pi() + 2e-6f); + Error += testForAxisAngle(glm::vec3(1.0f, 0.0f, 0.0f), glm::pi() + 1e-4f); + Error += testForAxisAngle(glm::vec3(0.0f, 1.0f, 0.0f), -glm::pi() + 1e-3f); + Error += testForAxisAngle(glm::vec3(0.358f, 0.0716f, 0.9309f), -glm::pi() + 5e-3f); return Error; } From 2010c883d543d2a1392503463ce1c451f0e93850 Mon Sep 17 00:00:00 2001 From: Sergey Krivohatskiy Date: Tue, 23 Mar 2021 14:33:11 +0300 Subject: [PATCH 5/7] formatting fix Signed-off-by: Sergey Krivohatskiy --- test/gtx/gtx_matrix_interpolation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/gtx/gtx_matrix_interpolation.cpp b/test/gtx/gtx_matrix_interpolation.cpp index 8d3a073e..4e51dd19 100644 --- a/test/gtx/gtx_matrix_interpolation.cpp +++ b/test/gtx/gtx_matrix_interpolation.cpp @@ -110,7 +110,7 @@ static int test_rotate() int main() { int Error = 0; - + Error += test_axisAngle(); Error += test_axisAngle2(); Error += test_rotate(); From e81a9c4baa620f5addf4515d491c85c7a6480cda Mon Sep 17 00:00:00 2001 From: Sergey Krivohatskiy Date: Tue, 23 Mar 2021 15:03:38 +0300 Subject: [PATCH 6/7] compilation fixes Signed-off-by: Sergey Krivohatskiy --- test/gtx/gtx_matrix_interpolation.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/gtx/gtx_matrix_interpolation.cpp b/test/gtx/gtx_matrix_interpolation.cpp index 4e51dd19..4ff1de8a 100644 --- a/test/gtx/gtx_matrix_interpolation.cpp +++ b/test/gtx/gtx_matrix_interpolation.cpp @@ -38,19 +38,19 @@ static int test_axisAngle() } template -int testForAxisAngle(glm::tvec3 const axisTrue, T const angleTrue) +int testForAxisAngle(glm::vec<3, T, glm::defaultp> const axisTrue, T const angleTrue) { T const eps = sqrt(std::numeric_limits::epsilon()); - glm::tmat4x4 const matTrue = glm::axisAngleMatrix(axisTrue, angleTrue); + glm::mat<4, 4, T, glm::defaultp> const matTrue = glm::axisAngleMatrix(axisTrue, angleTrue); - glm::tvec3 axis; + glm::vec<3, T, glm::defaultp> axis; T angle; glm::axisAngle(matTrue, axis, angle); - glm::tmat4x4 const matRebuilt = glm::axisAngleMatrix(axis, angle); + glm::mat<4, 4, T, glm::defaultp> const matRebuilt = glm::axisAngleMatrix(axis, angle); - glm::tmat4x4 const errMat = matTrue - matRebuilt; - T const maxErr = glm::compMax(glm::tvec4( + glm::mat<4, 4, T, glm::defaultp> const errMat = matTrue - matRebuilt; + T const maxErr = glm::compMax(glm::vec<4, T, glm::defaultp>( glm::compMax(glm::abs(errMat[0])), glm::compMax(glm::abs(errMat[1])), glm::compMax(glm::abs(errMat[2])), From b5d4757580fd1039d09585ec80e5c4440e6c1a75 Mon Sep 17 00:00:00 2001 From: Sergey Krivohatskiy Date: Tue, 23 Mar 2021 15:22:16 +0300 Subject: [PATCH 7/7] compilation fix Signed-off-by: Sergey Krivohatskiy --- test/gtx/gtx_matrix_interpolation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/gtx/gtx_matrix_interpolation.cpp b/test/gtx/gtx_matrix_interpolation.cpp index 4ff1de8a..108f02e9 100644 --- a/test/gtx/gtx_matrix_interpolation.cpp +++ b/test/gtx/gtx_matrix_interpolation.cpp @@ -5,6 +5,7 @@ #include #include +#include static int test_axisAngle() @@ -40,7 +41,7 @@ static int test_axisAngle() template int testForAxisAngle(glm::vec<3, T, glm::defaultp> const axisTrue, T const angleTrue) { - T const eps = sqrt(std::numeric_limits::epsilon()); + T const eps = std::sqrt(std::numeric_limits::epsilon()); glm::mat<4, 4, T, glm::defaultp> const matTrue = glm::axisAngleMatrix(axisTrue, angleTrue);