From a74cd55d8d60f3fc895e694c9258923ac13d83f6 Mon Sep 17 00:00:00 2001 From: Vitali Parkhomenko Date: Fri, 23 Mar 2018 14:27:35 +0300 Subject: [PATCH] #744 Added tests --- test/gtx/gtx_euler_angle.cpp | 210 +++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) diff --git a/test/gtx/gtx_euler_angle.cpp b/test/gtx/gtx_euler_angle.cpp index 98ed343e..348f5818 100644 --- a/test/gtx/gtx_euler_angle.cpp +++ b/test/gtx/gtx_euler_angle.cpp @@ -2,10 +2,14 @@ #define GLM_ENABLE_EXPERIMENTAL #include +#include +#include #include #include #include #include +#include +#include namespace test_eulerAngleX { @@ -136,6 +140,62 @@ namespace test_eulerAngleZ } }//namespace test_eulerAngleZ +namespace test_derivedEulerAngles +{ + bool epsilonEqual(glm::mat4 const& mat1, glm::mat4 const& mat2, glm::mat4::value_type const& epsilon) + { + return glm::all(glm::epsilonEqual(mat1[0], mat2[0], epsilon)) ? + ( + glm::all(glm::epsilonEqual(mat1[1], mat2[1], epsilon)) ? + ( + glm::all(glm::epsilonEqual(mat1[2], mat2[2], epsilon)) ? + ( + glm::all(glm::epsilonEqual(mat1[3], mat2[3], epsilon)) ? true : false + ) : false + ) : false + ) : false; + } + + template + int test(RotationFunc rotationFunc, TestDerivedFunc testDerivedFunc, const glm::vec3& basis) + { + int Error = 0; + + typedef glm::vec3::value_type value; + value const zeroAngle(0.0f); + value const Angle(glm::pi() * 0.75f); + value const negativeAngle(-Angle); + value const zeroAngleVelocity(0.0f); + value const AngleVelocity(glm::pi() * 0.27f); + value const negativeAngleVelocity(-AngleVelocity); + + typedef std::pair AngleAndAngleVelocity; + std::vector testPairs; + testPairs.push_back(AngleAndAngleVelocity(zeroAngle, zeroAngleVelocity)); + testPairs.push_back(AngleAndAngleVelocity(zeroAngle, AngleVelocity)); + testPairs.push_back(AngleAndAngleVelocity(zeroAngle, negativeAngleVelocity)); + testPairs.push_back(AngleAndAngleVelocity(Angle, zeroAngleVelocity)); + testPairs.push_back(AngleAndAngleVelocity(Angle, AngleVelocity)); + testPairs.push_back(AngleAndAngleVelocity(Angle, negativeAngleVelocity)); + testPairs.push_back(AngleAndAngleVelocity(negativeAngle, zeroAngleVelocity)); + testPairs.push_back(AngleAndAngleVelocity(negativeAngle, AngleVelocity)); + testPairs.push_back(AngleAndAngleVelocity(negativeAngle, negativeAngleVelocity)); + + for (size_t i = 0, size = testPairs.size(); i < size; ++i) + { + AngleAndAngleVelocity const& pair = testPairs.at(i); + + glm::mat4 const W = glm::matrixCross4(basis * pair.second); + glm::mat4 const rotMt = glm::transpose(rotationFunc(pair.first)); + glm::mat4 const derivedRotM = testDerivedFunc(pair.first, pair.second); + + Error += epsilonEqual(W, derivedRotM * rotMt, 0.00001f) ? 0 : 1; + } + + return Error; + } +}//namespace test_derivedEulerAngles + namespace test_eulerAngleXY { int test() @@ -310,13 +370,140 @@ namespace test_eulerAngleYXZ } }//namespace eulerAngleYXZ +namespace test_eulerAngles +{ + template + int test(TestRotationFunc testRotationFunc, glm::vec3 const& I, glm::vec3 const& J, glm::vec3 const& K) + { + int Error = 0; + + typedef glm::mat4::value_type value; + value const minAngle(-glm::pi()); + value const maxAngle(glm::pi()); + value const maxAngleWithDelta(maxAngle - 0.0000001f); + value const minMidAngle(-glm::pi() * 0.5f); + value const maxMidAngle(glm::pi() * 0.5f); + + std::vector testEulerAngles; + testEulerAngles.push_back(glm::vec3(1.046f, 0.52f, -0.785f)); + testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, minMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, minMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(minAngle, 0.0f, minAngle)); + testEulerAngles.push_back(glm::vec3(minAngle, 0.0f, maxAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, maxAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, maxAngle, maxAngle)); + + for (size_t i = 0, size = testEulerAngles.size(); i < size; ++i) + { + glm::vec3 const& angles = testEulerAngles.at(i); + glm::mat4 const rotationEuler = testRotationFunc(angles.x, angles.y, angles.z); + + glm::mat4 rotationDumb = glm::diagonal4x4(glm::mat4::col_type(1.0f)); + rotationDumb = glm::rotate(rotationDumb, angles.x, I); + rotationDumb = glm::rotate(rotationDumb, angles.y, J); + rotationDumb = glm::rotate(rotationDumb, angles.z, K); + + glm::vec4 const V(1.0f,1.0f,1.0f,1.0f); + glm::vec4 const V1 = rotationEuler * V; + glm::vec4 const V2 = rotationDumb * V; + + Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1; + } + + return Error; + } +}//namespace test_extractsEulerAngles + +namespace test_extractsEulerAngles +{ + template + int test(RotationFunc rotationFunc, TestExtractionFunc testExtractionFunc) + { + int Error = 0; + + typedef glm::mat4::value_type value; + value const minAngle(-glm::pi()); + value const maxAngle(glm::pi()); + value const maxAngleWithDelta(maxAngle - 0.0000001f); + value const minMidAngle(-glm::pi() * 0.5f); + value const maxMidAngle(glm::pi() * 0.5f); + + std::vector testEulerAngles; + testEulerAngles.push_back(glm::vec3(1.046f, 0.52f, -0.785f)); + testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(minAngle, minMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(minAngle, maxMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, minMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, minMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, minMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, maxMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, maxAngle)); + testEulerAngles.push_back(glm::vec3(maxAngleWithDelta, maxMidAngle, maxAngleWithDelta)); + testEulerAngles.push_back(glm::vec3(minAngle, 0.0f, minAngle)); + testEulerAngles.push_back(glm::vec3(minAngle, 0.0f, maxAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, maxAngle, minAngle)); + testEulerAngles.push_back(glm::vec3(maxAngle, maxAngle, maxAngle)); + + for (size_t i = 0, size = testEulerAngles.size(); i < size; ++i) + { + glm::vec3 const& angles = testEulerAngles.at(i); + glm::mat4 const rotation = rotationFunc(angles.x, angles.y, angles.z); + + glm::vec3 extractedEulerAngles(0.0f); + testExtractionFunc(rotation, extractedEulerAngles.x, extractedEulerAngles.y, extractedEulerAngles.z); + glm::mat4 const extractedRotation = rotationFunc(extractedEulerAngles.x, extractedEulerAngles.y, extractedEulerAngles.z); + + glm::vec4 const V(1.0f,1.0f,1.0f,1.0f); + glm::vec4 const V1 = rotation * V; + glm::vec4 const V2 = extractedRotation * V; + + Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1; + } + + return Error; + } +}//namespace test_extractsEulerAngles + int main() { int Error = 0; + typedef glm::mat4::value_type value; + glm::vec3 const X(1.0f, 0.0f, 0.0f); + glm::vec3 const Y(0.0f, 1.0f, 0.0f); + glm::vec3 const Z(0.0f, 0.0f, 1.0f); + Error += test_eulerAngleX::test(); Error += test_eulerAngleY::test(); Error += test_eulerAngleZ::test(); + + Error += test_derivedEulerAngles::test(glm::eulerAngleX, glm::derivedEulerAngleX, X); + Error += test_derivedEulerAngles::test(glm::eulerAngleY, glm::derivedEulerAngleY, Y); + Error += test_derivedEulerAngles::test(glm::eulerAngleZ, glm::derivedEulerAngleZ, Z); + Error += test_eulerAngleXY::test(); Error += test_eulerAngleYX::test(); Error += test_eulerAngleXZ::test(); @@ -325,5 +512,28 @@ int main() Error += test_eulerAngleZY::test(); Error += test_eulerAngleYXZ::test(); + Error += test_eulerAngles::test(glm::eulerAngleXZX, X, Z, X); + Error += test_eulerAngles::test(glm::eulerAngleXYX, X, Y, X); + Error += test_eulerAngles::test(glm::eulerAngleYXY, Y, X, Y); + Error += test_eulerAngles::test(glm::eulerAngleYZY, Y, Z, Y); + Error += test_eulerAngles::test(glm::eulerAngleZYZ, Z, Y, Z); + Error += test_eulerAngles::test(glm::eulerAngleZXZ, Z, X, Z); + Error += test_eulerAngles::test(glm::eulerAngleXZY, X, Z, Y); + Error += test_eulerAngles::test(glm::eulerAngleYZX, Y, Z, X); + Error += test_eulerAngles::test(glm::eulerAngleZYX, Z, Y, X); + Error += test_eulerAngles::test(glm::eulerAngleZXY, Z, X, Y); + + Error += test_extractsEulerAngles::test(glm::eulerAngleYXZ, glm::extractEulerAngleYXZ); + Error += test_extractsEulerAngles::test(glm::eulerAngleXZX, glm::extractEulerAngleXZX); + Error += test_extractsEulerAngles::test(glm::eulerAngleXYX, glm::extractEulerAngleXYX); + Error += test_extractsEulerAngles::test(glm::eulerAngleYXY, glm::extractEulerAngleYXY); + Error += test_extractsEulerAngles::test(glm::eulerAngleYZY, glm::extractEulerAngleYZY); + Error += test_extractsEulerAngles::test(glm::eulerAngleZYZ, glm::extractEulerAngleZYZ); + Error += test_extractsEulerAngles::test(glm::eulerAngleZXZ, glm::extractEulerAngleZXZ); + Error += test_extractsEulerAngles::test(glm::eulerAngleXZY, glm::extractEulerAngleXZY); + Error += test_extractsEulerAngles::test(glm::eulerAngleYZX, glm::extractEulerAngleYZX); + Error += test_extractsEulerAngles::test(glm::eulerAngleZYX, glm::extractEulerAngleZYX); + Error += test_extractsEulerAngles::test(glm::eulerAngleZXY, glm::extractEulerAngleZXY); + return Error; }