From 658d7e278853afe106980bf2b8396ff130439ad1 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sun, 16 Mar 2014 03:08:56 +0100 Subject: [PATCH 01/11] Fixed strict aliasing warnings in GCC 4.8.1 / Android NDK 9c (#152) --- glm/detail/func_integer.inl | 6 ++++-- readme.txt | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/glm/detail/func_integer.inl b/glm/detail/func_integer.inl index 7bf3eb94..d6f6c7ce 100644 --- a/glm/detail/func_integer.inl +++ b/glm/detail/func_integer.inl @@ -171,7 +171,8 @@ namespace glm GLM_STATIC_ASSERT(sizeof(uint) == sizeof(uint32), "uint and uint32 size mismatch"); uint64 Value64 = static_cast(x) * static_cast(y); - msb = *(reinterpret_cast(&Value64) + 1); + uint32* PointerMSB = (reinterpret_cast(&Value64) + 1); + msb = *PointerMSB; lsb = reinterpret_cast(Value64); } @@ -230,7 +231,8 @@ namespace glm GLM_STATIC_ASSERT(sizeof(int) == sizeof(int32), "int and int32 size mismatch"); int64 Value64 = static_cast(x) * static_cast(y); - msb = *(reinterpret_cast(&Value64) + 1); + int32* PointerMSB = (reinterpret_cast(&Value64) + 1); + msb = *PointerMSB; lsb = reinterpret_cast(Value64); } diff --git a/readme.txt b/readme.txt index d47557b2..a6a95017 100644 --- a/readme.txt +++ b/readme.txt @@ -46,6 +46,7 @@ GLM 0.9.5.3: 2014-0X-XX - Added GLM_GTX_matrix_transform_2d extension (#178, #176) - Fixed CUDA issues (#169, #168, #183, #182) - Added support for all extensions but GTX_string_cast to CUDA +- Fixed strict aliasing warnings in GCC 4.8.1 / Android NDK 9c (#152) ================================================================================ GLM 0.9.5.2: 2014-02-08 From 0b73091c7fbd1939e9bf4e20afe8407cf42b16f2 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sun, 16 Mar 2014 11:15:56 +0100 Subject: [PATCH 02/11] Fixed aliasing warnings --- glm/detail/func_integer.inl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/glm/detail/func_integer.inl b/glm/detail/func_integer.inl index d6f6c7ce..ee010146 100644 --- a/glm/detail/func_integer.inl +++ b/glm/detail/func_integer.inl @@ -111,7 +111,7 @@ namespace glm Borrow = x >= y ? static_cast(0) : static_cast(1); if(x > y) - return static_cast(static_cast(x) -static_cast(y)); + return static_cast(static_cast(x) - static_cast(y)); else return static_cast((static_cast(1) << static_cast(32)) + static_cast(x) - static_cast(y)); } @@ -173,7 +173,8 @@ namespace glm uint64 Value64 = static_cast(x) * static_cast(y); uint32* PointerMSB = (reinterpret_cast(&Value64) + 1); msb = *PointerMSB; - lsb = reinterpret_cast(Value64); + uint32* PointerLSB = (reinterpret_cast(&Value64) + 0); + lsb = *PointerLSB; } template <> @@ -233,7 +234,8 @@ namespace glm int64 Value64 = static_cast(x) * static_cast(y); int32* PointerMSB = (reinterpret_cast(&Value64) + 1); msb = *PointerMSB; - lsb = reinterpret_cast(Value64); + int32* PointerLSB = (reinterpret_cast(&Value64)); + lsb = *PointerLSB; } template <> From 00e860eeeec3f3e8358049f84b1ef6725df3a283 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sun, 16 Mar 2014 11:53:58 +0100 Subject: [PATCH 03/11] Fixed missing bitfieldInterleave definisions --- glm/gtx/bit.inl | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ readme.txt | 1 + 2 files changed, 83 insertions(+) diff --git a/glm/gtx/bit.inl b/glm/gtx/bit.inl index 541ae7a8..e8ef509f 100644 --- a/glm/gtx/bit.inl +++ b/glm/gtx/bit.inl @@ -420,6 +420,62 @@ namespace glm return REG1 | (REG2 << 1); } + template <> + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z) + { + glm::uint32 REG1(x); + glm::uint32 REG2(y); + glm::uint32 REG3(z); + + REG1 = ((REG1 << 16) | REG1) & glm::uint32(0x00FF0000FF0000FF); + REG2 = ((REG2 << 16) | REG2) & glm::uint32(0x00FF0000FF0000FF); + REG3 = ((REG3 << 16) | REG3) & glm::uint32(0x00FF0000FF0000FF); + + REG1 = ((REG1 << 8) | REG1) & glm::uint32(0xF00F00F00F00F00F); + REG2 = ((REG2 << 8) | REG2) & glm::uint32(0xF00F00F00F00F00F); + REG3 = ((REG3 << 8) | REG3) & glm::uint32(0xF00F00F00F00F00F); + + REG1 = ((REG1 << 4) | REG1) & glm::uint32(0x30C30C30C30C30C3); + REG2 = ((REG2 << 4) | REG2) & glm::uint32(0x30C30C30C30C30C3); + REG3 = ((REG3 << 4) | REG3) & glm::uint32(0x30C30C30C30C30C3); + + REG1 = ((REG1 << 2) | REG1) & glm::uint32(0x9249249249249249); + REG2 = ((REG2 << 2) | REG2) & glm::uint32(0x9249249249249249); + REG3 = ((REG3 << 2) | REG3) & glm::uint32(0x9249249249249249); + + return REG1 | (REG2 << 1) | (REG3 << 2); + } + + template <> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + glm::uint64 REG3(z); + + REG1 = ((REG1 << 32) | REG1) & glm::uint64(0xFFFF00000000FFFF); + REG2 = ((REG2 << 32) | REG2) & glm::uint64(0xFFFF00000000FFFF); + REG3 = ((REG3 << 32) | REG3) & glm::uint64(0xFFFF00000000FFFF); + + REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x00FF0000FF0000FF); + REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x00FF0000FF0000FF); + REG3 = ((REG3 << 16) | REG3) & glm::uint64(0x00FF0000FF0000FF); + + REG1 = ((REG1 << 8) | REG1) & glm::uint64(0xF00F00F00F00F00F); + REG2 = ((REG2 << 8) | REG2) & glm::uint64(0xF00F00F00F00F00F); + REG3 = ((REG3 << 8) | REG3) & glm::uint64(0xF00F00F00F00F00F); + + REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x30C30C30C30C30C3); + REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x30C30C30C30C30C3); + REG3 = ((REG3 << 4) | REG3) & glm::uint64(0x30C30C30C30C30C3); + + REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x9249249249249249); + REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x9249249249249249); + REG3 = ((REG3 << 2) | REG3) & glm::uint64(0x9249249249249249); + + return REG1 | (REG2 << 1) | (REG3 << 2); + } + template <> GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y, glm::uint32 z) { @@ -450,6 +506,32 @@ namespace glm return REG1 | (REG2 << 1) | (REG3 << 2); } + template <> + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z, glm::uint8 w) + { + glm::uint32 REG1(x); + glm::uint32 REG2(y); + glm::uint32 REG3(z); + glm::uint32 REG4(w); + + REG1 = ((REG1 << 12) | REG1) & glm::uint32(0x000F000F000F000F); + REG2 = ((REG2 << 12) | REG2) & glm::uint32(0x000F000F000F000F); + REG3 = ((REG3 << 12) | REG3) & glm::uint32(0x000F000F000F000F); + REG4 = ((REG4 << 12) | REG4) & glm::uint32(0x000F000F000F000F); + + REG1 = ((REG1 << 6) | REG1) & glm::uint32(0x0303030303030303); + REG2 = ((REG2 << 6) | REG2) & glm::uint32(0x0303030303030303); + REG3 = ((REG3 << 6) | REG3) & glm::uint32(0x0303030303030303); + REG4 = ((REG4 << 6) | REG4) & glm::uint32(0x0303030303030303); + + REG1 = ((REG1 << 3) | REG1) & glm::uint32(0x1111111111111111); + REG2 = ((REG2 << 3) | REG2) & glm::uint32(0x1111111111111111); + REG3 = ((REG3 << 3) | REG3) & glm::uint32(0x1111111111111111); + REG4 = ((REG4 << 3) | REG4) & glm::uint32(0x1111111111111111); + + return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3); + } + template <> GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z, glm::uint16 w) { diff --git a/readme.txt b/readme.txt index a6a95017..0ec0e353 100644 --- a/readme.txt +++ b/readme.txt @@ -47,6 +47,7 @@ GLM 0.9.5.3: 2014-0X-XX - Fixed CUDA issues (#169, #168, #183, #182) - Added support for all extensions but GTX_string_cast to CUDA - Fixed strict aliasing warnings in GCC 4.8.1 / Android NDK 9c (#152) +- Fixed missing bitfieldInterleave definisions ================================================================================ GLM 0.9.5.2: 2014-02-08 From 3f327d5e7017c988198be506f0e33e1acb564121 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sun, 16 Mar 2014 12:33:00 +0100 Subject: [PATCH 04/11] Fixed usubBorrw --- glm/detail/func_integer.inl | 6 +++--- readme.txt | 1 + test/core/core_func_integer.cpp | 26 +++++++++++++++++++++----- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/glm/detail/func_integer.inl b/glm/detail/func_integer.inl index ee010146..e792461d 100644 --- a/glm/detail/func_integer.inl +++ b/glm/detail/func_integer.inl @@ -110,10 +110,10 @@ namespace glm GLM_STATIC_ASSERT(sizeof(uint) == sizeof(uint32), "uint and uint32 size mismatch"); Borrow = x >= y ? static_cast(0) : static_cast(1); - if(x > y) - return static_cast(static_cast(x) - static_cast(y)); + if(y >= x) + return y - x; else - return static_cast((static_cast(1) << static_cast(32)) + static_cast(x) - static_cast(y)); + return static_cast((static_cast(1) << static_cast(32)) + (static_cast(y) - static_cast(x))); } template <> diff --git a/readme.txt b/readme.txt index 0ec0e353..3ad50114 100644 --- a/readme.txt +++ b/readme.txt @@ -48,6 +48,7 @@ GLM 0.9.5.3: 2014-0X-XX - Added support for all extensions but GTX_string_cast to CUDA - Fixed strict aliasing warnings in GCC 4.8.1 / Android NDK 9c (#152) - Fixed missing bitfieldInterleave definisions +- Fixed usubBorrow (#171) ================================================================================ GLM 0.9.5.2: 2014-02-08 diff --git a/test/core/core_func_integer.cpp b/test/core/core_func_integer.cpp index d1fcec87..1380f4a3 100644 --- a/test/core/core_func_integer.cpp +++ b/test/core/core_func_integer.cpp @@ -197,14 +197,14 @@ namespace findLSB genType Value; genType Return; }; - + type const DataI32[] = { {0x00000001, 0}, - {0x00000003, 0}, - {0x00000002, 1} + {0x00000003, 0}, + {0x00000002, 1} }; - + int test() { int Error(0); @@ -215,11 +215,27 @@ namespace findLSB Error += DataI32[i].Return == Result ? 0 : 1; assert(!Error); } - + return Error; } }//findLSB +namespace usubBorrow +{ + int test() + { + int Error(0); + + glm::uint x = 16; + glm::uint y = 17; + glm::uint Borrow = 0; + glm::uint Result = glm::usubBorrow(x, y, Borrow); + + return Error; + } + +}//namespace usubBorrow + int main() { int Error = 0; From 04d9fa2d45de6ae3b31901bbb95d15f83c7273ef Mon Sep 17 00:00:00 2001 From: David Reid Date: Fri, 21 Mar 2014 18:49:27 +1000 Subject: [PATCH 05/11] Fix simd_quat build. --- glm/gtx/simd_quat.hpp | 2 -- glm/gtx/simd_quat.inl | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/glm/gtx/simd_quat.hpp b/glm/gtx/simd_quat.hpp index 80b3c726..1658cca4 100644 --- a/glm/gtx/simd_quat.hpp +++ b/glm/gtx/simd_quat.hpp @@ -46,8 +46,6 @@ #if(GLM_ARCH != GLM_ARCH_PURE) #if(GLM_ARCH & GLM_ARCH_SSE2) -# include "../core/intrinsic_common.hpp" -# include "../core/intrinsic_geometric.hpp" # include "../gtx/simd_mat4.hpp" #else # error "GLM: GLM_GTX_simd_quat requires compiler support of SSE2 through intrinsics" diff --git a/glm/gtx/simd_quat.inl b/glm/gtx/simd_quat.inl index 983c32a0..9bbc254d 100644 --- a/glm/gtx/simd_quat.inl +++ b/glm/gtx/simd_quat.inl @@ -194,7 +194,7 @@ GLM_FUNC_QUALIFIER fvec4SIMD operator* (fquatSIMD const & q, fvec4SIMD const & v GLM_FUNC_QUALIFIER fvec4SIMD operator* (fvec4SIMD const & v, fquatSIMD const & q) { - return inverse(q) * v; + return glm::inverse(q) * v; } GLM_FUNC_QUALIFIER fquatSIMD operator* (fquatSIMD const & q, float s) From 12cde2bf750469b9e2d8b6072e2d6a81e6c245f3 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Mon, 31 Mar 2014 02:00:51 +0200 Subject: [PATCH 06/11] Added eulerAnglesX tests --- test/gtx/gtx_euler_angle.cpp | 153 ++++++++++++++++++++++++++++++----- 1 file changed, 134 insertions(+), 19 deletions(-) diff --git a/test/gtx/gtx_euler_angle.cpp b/test/gtx/gtx_euler_angle.cpp index 16597809..fbe3115f 100644 --- a/test/gtx/gtx_euler_angle.cpp +++ b/test/gtx/gtx_euler_angle.cpp @@ -11,33 +11,148 @@ #define GLM_FORCE_RADIANS #include +#include #include #include #include -using namespace glm; +namespace test_eulerAngleX +{ + int test() + { + int Error = 0; -int main() -{ - f32 first = 1.046f; - f32 second = 0.52f; - f32 third = -0.785f; + float const Angle(glm::pi() * 0.5f); + glm::vec3 const X(1.0f, 0.0f, 0.0f); + + glm::vec4 const Y(0.0f, 1.0f, 0.0f, 1.0f); + glm::vec4 const Y1 = glm::rotate(glm::mat4(1.0f), Angle, X) * Y; + glm::vec4 const Y2 = glm::eulerAngleX(Angle) * Y; + glm::vec4 const Y3 = glm::eulerAngleXY(Angle, 0.0f) * Y; + glm::vec4 const Y4 = glm::eulerAngleYX(0.0f, Angle) * Y; + glm::vec4 const Y5 = glm::eulerAngleXZ(Angle, 0.0f) * Y; + glm::vec4 const Y6 = glm::eulerAngleZX(0.0f, Angle) * Y; + glm::vec4 const Y7 = glm::eulerAngleYXZ(0.0f, Angle, 0.0f) * Y; + Error += glm::all(glm::epsilonEqual(Y1, Y2, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Y1, Y3, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Y1, Y4, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Y1, Y5, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Y1, Y6, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Y1, Y7, 0.00001f)) ? 0 : 1; + + glm::vec4 const Z(0.0f, 0.0f, 1.0f, 1.0f); + glm::vec4 const Z1 = glm::rotate(glm::mat4(1.0f), Angle, X) * Z; + glm::vec4 const Z2 = glm::eulerAngleX(Angle) * Z; + glm::vec4 const Z3 = glm::eulerAngleXY(Angle, 0.0f) * Z; + glm::vec4 const Z4 = glm::eulerAngleYX(0.0f, Angle) * Z; + glm::vec4 const Z5 = glm::eulerAngleXZ(Angle, 0.0f) * Z; + glm::vec4 const Z6 = glm::eulerAngleZX(0.0f, Angle) * Z; + glm::vec4 const Z7 = glm::eulerAngleYXZ(0.0f, Angle, 0.0f) * Z; + Error += glm::all(glm::epsilonEqual(Z1, Z2, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z3, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z4, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z5, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z6, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z7, 0.00001f)) ? 0 : 1; + + return Error; + } +}//namespace test_eulerAngleX + +namespace test_eulerAngleY +{ + int test() + { + int Error = 0; + + float const Angle(glm::pi() * 0.5f); + glm::vec3 const Y(0.0f, 1.0f, 0.0f); + + glm::vec4 const X(1.0f, 0.0f, 0.0f, 1.0f); + glm::vec4 const X1 = glm::eulerAngleY(Angle) * X; + glm::vec4 const X2 = glm::rotate(glm::mat4(1.0f), Angle, Y) * X; + Error += glm::all(glm::epsilonEqual(X1, X2, 0.00001f)) ? 0 : 1; + + glm::vec4 const Z(1.0f, 0.0f, 0.0f, 1.0f); + glm::vec4 const Z1 = glm::eulerAngleY(Angle) * Z; + glm::vec4 const Z2 = glm::rotate(glm::mat4(1.0f), Angle, Y) * Z; + Error += glm::all(glm::epsilonEqual(Z1, Z2, 0.00001f)) ? 0 : 1; + + return Error; + } +}//namespace test_eulerAngleY + +namespace test_eulerAngleZ +{ + int test() + { + int Error = 0; + + float const Angle(glm::pi() * 0.5f); + glm::vec3 const Z(0.0f, 0.0f, 1.0f); - fmat4 rotationEuler = eulerAngleYXZ(first, second, third); + glm::vec4 const X(1.0f, 0.0f, 0.0f, 1.0f); + glm::vec4 const X1 = glm::eulerAngleZ(Angle) * X; + glm::vec4 const X2 = glm::rotate(glm::mat4(1.0f), Angle, Z) * X; + Error += glm::all(glm::epsilonEqual(X1, X2, 0.00001f)) ? 0 : 1; - fmat4 rotationInvertedY = eulerAngleY(-1.f*first) * eulerAngleX(second) * eulerAngleZ(third); - fmat4 rotationDumb = glm::fmat4(); - rotationDumb = rotate(rotationDumb, first, glm::fvec3(0,1,0)); - rotationDumb = rotate(rotationDumb, second, glm::fvec3(1,0,0)); - rotationDumb = rotate(rotationDumb, third, glm::fvec3(0,0,1)); + glm::vec4 const Y(1.0f, 0.0f, 0.0f, 1.0f); + glm::vec4 const Y1 = glm::eulerAngleZ(Angle) * Y; + glm::vec4 const Y2 = glm::rotate(glm::mat4(1.0f), Angle, Z) * Y; + Error += glm::all(glm::epsilonEqual(Y1, Y2, 0.00001f)) ? 0 : 1; + + return Error; + } +}//namespace test_eulerAngleZ - std::cout << glm::to_string(fmat3(rotationEuler)) << std::endl; - std::cout << glm::to_string(fmat3(rotationDumb)) << std::endl; - std::cout << glm::to_string(fmat3(rotationInvertedY )) << std::endl; +namespace test_eulerAngleXY +{ + int test() + { + + + + return 0; + } +}//namespace eulerAngleXY + +namespace test_eulerAngleYXZ +{ + int test() + { + glm::f32 first = 1.046f; + glm::f32 second = 0.52f; + glm::f32 third = -0.785f; + + glm::fmat4 rotationEuler = glm::eulerAngleYXZ(first, second, third); + + glm::fmat4 rotationInvertedY = glm::eulerAngleY(-1.f*first) * glm::eulerAngleX(second) * glm::eulerAngleZ(third); + glm::fmat4 rotationDumb = glm::fmat4(); + rotationDumb = glm::rotate(rotationDumb, first, glm::fvec3(0,1,0)); + rotationDumb = glm::rotate(rotationDumb, second, glm::fvec3(1,0,0)); + rotationDumb = glm::rotate(rotationDumb, third, glm::fvec3(0,0,1)); + + std::cout << glm::to_string(glm::fmat3(rotationEuler)) << std::endl; + std::cout << glm::to_string(glm::fmat3(rotationDumb)) << std::endl; + std::cout << glm::to_string(glm::fmat3(rotationInvertedY )) << std::endl; + + std::cout <<"\nRESIDUAL\n"; + std::cout << glm::to_string(glm::fmat3(rotationEuler-(rotationDumb))) << std::endl; + std::cout << glm::to_string(glm::fmat3(rotationEuler-(rotationInvertedY ))) << std::endl; + + return 0; + } +}//namespace eulerAngleYXZ + +int main() +{ + int Error = 0; - std::cout <<"\nRESIDUAL\n"; - std::cout << glm::to_string(fmat3(rotationEuler-(rotationDumb))) << std::endl; - std::cout << glm::to_string(fmat3(rotationEuler-(rotationInvertedY ))) << std::endl; + Error += test_eulerAngleX::test(); + Error += test_eulerAngleY::test(); + Error += test_eulerAngleZ::test(); + Error += test_eulerAngleXY::test(); + Error += test_eulerAngleYXZ::test(); - return 0; + return Error; } From e33136538dc60540426baf2e64b81162553c0d7d Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Mon, 31 Mar 2014 23:50:15 +0200 Subject: [PATCH 07/11] - Fixed eulerAngle*** not consistent for right-handed coordinate system (#173) --- glm/gtx/euler_angles.inl | 36 ++++-- readme.txt | 2 + test/gtx/gtx_euler_angle.cpp | 206 ++++++++++++++++++++++++++++++++--- 3 files changed, 223 insertions(+), 21 deletions(-) diff --git a/glm/gtx/euler_angles.inl b/glm/gtx/euler_angles.inl index 2ff391ab..b3102242 100644 --- a/glm/gtx/euler_angles.inl +++ b/glm/gtx/euler_angles.inl @@ -70,10 +70,10 @@ namespace glm T sinY = glm::sin(angleY); return detail::tmat4x4( - cosY, -sinX * sinY, cosX * sinY, T(0), - T(0), cosX, sinX, T(0), - -sinY, -sinX * cosY, cosX * cosY, T(0), - T(0), T(0), T(0), T(1)); + cosY, -sinX * -sinY, cosX * -sinY, T(0), + T(0), cosX, sinX, T(0), + sinY, -sinX * cosY, cosX * cosY, T(0), + T(0), T(0), T(0), T(1)); } template @@ -89,10 +89,10 @@ namespace glm T sinY = glm::sin(angleY); return detail::tmat4x4( - cosY, T(0), sinY, T(0), - -sinX * sinY, cosX, sinX * cosY, T(0), - -cosX * sinY, -sinX, cosX * cosY, T(0), - T(0), T(0), T(0), T(1)); + cosY, 0, -sinY, T(0), + sinY * sinX, cosX, cosY * sinX, T(0), + sinY * cosX, -sinX, cosY * cosX, T(0), + T(0), T(0), T(0), T(1)); } template @@ -115,6 +115,26 @@ namespace glm return eulerAngleZ(angleZ) * eulerAngleX(angleX); } + template + GLM_FUNC_QUALIFIER detail::tmat4x4 eulerAngleYZ + ( + T const & angleY, + T const & angleZ + ) + { + return eulerAngleY(angleY) * eulerAngleZ(angleZ); + } + + template + GLM_FUNC_QUALIFIER detail::tmat4x4 eulerAngleZY + ( + T const & angleZ, + T const & angleY + ) + { + return eulerAngleZ(angleZ) * eulerAngleY(angleY); + } + template GLM_FUNC_QUALIFIER detail::tmat4x4 eulerAngleYXZ ( diff --git a/readme.txt b/readme.txt index 3ad50114..300c82ff 100644 --- a/readme.txt +++ b/readme.txt @@ -49,6 +49,8 @@ GLM 0.9.5.3: 2014-0X-XX - Fixed strict aliasing warnings in GCC 4.8.1 / Android NDK 9c (#152) - Fixed missing bitfieldInterleave definisions - Fixed usubBorrow (#171) +- Fixed eulerAngle*** not consistent for right-handed coordinate system (#173) +- Added full tests for eulerAngle*** functions (#173) ================================================================================ GLM 0.9.5.2: 2014-02-08 diff --git a/test/gtx/gtx_euler_angle.cpp b/test/gtx/gtx_euler_angle.cpp index fbe3115f..28d53af6 100644 --- a/test/gtx/gtx_euler_angle.cpp +++ b/test/gtx/gtx_euler_angle.cpp @@ -69,15 +69,35 @@ namespace test_eulerAngleY glm::vec3 const Y(0.0f, 1.0f, 0.0f); glm::vec4 const X(1.0f, 0.0f, 0.0f, 1.0f); - glm::vec4 const X1 = glm::eulerAngleY(Angle) * X; - glm::vec4 const X2 = glm::rotate(glm::mat4(1.0f), Angle, Y) * X; + glm::vec4 const X1 = glm::rotate(glm::mat4(1.0f), Angle, Y) * X; + glm::vec4 const X2 = glm::eulerAngleY(Angle) * X; + glm::vec4 const X3 = glm::eulerAngleYX(Angle, 0.0f) * X; + glm::vec4 const X4 = glm::eulerAngleXY(0.0f, Angle) * X; + glm::vec4 const X5 = glm::eulerAngleYZ(Angle, 0.0f) * X; + glm::vec4 const X6 = glm::eulerAngleZY(0.0f, Angle) * X; + glm::vec4 const X7 = glm::eulerAngleYXZ(Angle, 0.0f, 0.0f) * X; Error += glm::all(glm::epsilonEqual(X1, X2, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(X1, X3, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(X1, X4, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(X1, X5, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(X1, X6, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(X1, X7, 0.00001f)) ? 0 : 1; - glm::vec4 const Z(1.0f, 0.0f, 0.0f, 1.0f); + glm::vec4 const Z(0.0f, 0.0f, 1.0f, 1.0f); glm::vec4 const Z1 = glm::eulerAngleY(Angle) * Z; glm::vec4 const Z2 = glm::rotate(glm::mat4(1.0f), Angle, Y) * Z; + glm::vec4 const Z3 = glm::eulerAngleYX(Angle, 0.0f) * Z; + glm::vec4 const Z4 = glm::eulerAngleXY(0.0f, Angle) * Z; + glm::vec4 const Z5 = glm::eulerAngleYZ(Angle, 0.0f) * Z; + glm::vec4 const Z6 = glm::eulerAngleZY(0.0f, Angle) * Z; + glm::vec4 const Z7 = glm::eulerAngleYXZ(Angle, 0.0f, 0.0f) * Z; Error += glm::all(glm::epsilonEqual(Z1, Z2, 0.00001f)) ? 0 : 1; - + Error += glm::all(glm::epsilonEqual(Z1, Z3, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z4, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z5, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z6, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z7, 0.00001f)) ? 0 : 1; + return Error; } }//namespace test_eulerAngleY @@ -92,15 +112,35 @@ namespace test_eulerAngleZ glm::vec3 const Z(0.0f, 0.0f, 1.0f); glm::vec4 const X(1.0f, 0.0f, 0.0f, 1.0f); - glm::vec4 const X1 = glm::eulerAngleZ(Angle) * X; - glm::vec4 const X2 = glm::rotate(glm::mat4(1.0f), Angle, Z) * X; + glm::vec4 const X1 = glm::rotate(glm::mat4(1.0f), Angle, Z) * X; + glm::vec4 const X2 = glm::eulerAngleZ(Angle) * X; + glm::vec4 const X3 = glm::eulerAngleZX(Angle, 0.0f) * X; + glm::vec4 const X4 = glm::eulerAngleXZ(0.0f, Angle) * X; + glm::vec4 const X5 = glm::eulerAngleZY(Angle, 0.0f) * X; + glm::vec4 const X6 = glm::eulerAngleYZ(0.0f, Angle) * X; + glm::vec4 const X7 = glm::eulerAngleYXZ(0.0f, 0.0f, Angle) * X; Error += glm::all(glm::epsilonEqual(X1, X2, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(X1, X3, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(X1, X4, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(X1, X5, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(X1, X6, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(X1, X7, 0.00001f)) ? 0 : 1; glm::vec4 const Y(1.0f, 0.0f, 0.0f, 1.0f); - glm::vec4 const Y1 = glm::eulerAngleZ(Angle) * Y; - glm::vec4 const Y2 = glm::rotate(glm::mat4(1.0f), Angle, Z) * Y; - Error += glm::all(glm::epsilonEqual(Y1, Y2, 0.00001f)) ? 0 : 1; - + glm::vec4 const Z1 = glm::rotate(glm::mat4(1.0f), Angle, Z) * Y; + glm::vec4 const Z2 = glm::eulerAngleZ(Angle) * Y; + glm::vec4 const Z3 = glm::eulerAngleZX(Angle, 0.0f) * Y; + glm::vec4 const Z4 = glm::eulerAngleXZ(0.0f, Angle) * Y; + glm::vec4 const Z5 = glm::eulerAngleZY(Angle, 0.0f) * Y; + glm::vec4 const Z6 = glm::eulerAngleYZ(0.0f, Angle) * Y; + glm::vec4 const Z7 = glm::eulerAngleYXZ(0.0f, 0.0f, Angle) * Y; + Error += glm::all(glm::epsilonEqual(Z1, Z2, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z3, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z4, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z5, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z6, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(Z1, Z7, 0.00001f)) ? 0 : 1; + return Error; } }//namespace test_eulerAngleZ @@ -109,12 +149,147 @@ namespace test_eulerAngleXY { int test() { - + int Error = 0; + glm::vec4 const V(1.0f); - return 0; + float const AngleX(glm::pi() * 0.5f); + float const AngleY(glm::pi() * 0.25f); + + glm::vec3 const axisX(1.0f, 0.0f, 0.0f); + glm::vec3 const axisY(0.0f, 1.0f, 0.0f); + + glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleX, axisX) * glm::rotate(glm::mat4(1.0f), AngleY, axisY)) * V; + glm::vec4 const V2 = glm::eulerAngleXY(AngleX, AngleY) * V; + glm::vec4 const V3 = glm::eulerAngleX(AngleX) * glm::eulerAngleY(AngleY) * V; + Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1; + + return Error; + } +}//namespace test_eulerAngleXY + +namespace test_eulerAngleYX +{ + int test() + { + int Error = 0; + + glm::vec4 const V(1.0f); + + float const AngleX(glm::pi() * 0.5f); + float const AngleY(glm::pi() * 0.25f); + + glm::vec3 const axisX(1.0f, 0.0f, 0.0f); + glm::vec3 const axisY(0.0f, 1.0f, 0.0f); + + glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleY, axisY) * glm::rotate(glm::mat4(1.0f), AngleX, axisX)) * V; + glm::vec4 const V2 = glm::eulerAngleYX(AngleY, AngleX) * V; + glm::vec4 const V3 = glm::eulerAngleY(AngleY) * glm::eulerAngleX(AngleX) * V; + Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1; + + return Error; + } +}//namespace test_eulerAngleYX + +namespace test_eulerAngleXZ +{ + int test() + { + int Error = 0; + + glm::vec4 const V(1.0f); + + float const AngleX(glm::pi() * 0.5f); + float const AngleZ(glm::pi() * 0.25f); + + glm::vec3 const axisX(1.0f, 0.0f, 0.0f); + glm::vec3 const axisZ(0.0f, 0.0f, 1.0f); + + glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleX, axisX) * glm::rotate(glm::mat4(1.0f), AngleZ, axisZ)) * V; + glm::vec4 const V2 = glm::eulerAngleXZ(AngleX, AngleZ) * V; + glm::vec4 const V3 = glm::eulerAngleX(AngleX) * glm::eulerAngleZ(AngleZ) * V; + Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1; + + return Error; + } +}//namespace test_eulerAngleXZ + +namespace test_eulerAngleZX +{ + int test() + { + int Error = 0; + + glm::vec4 const V(1.0f); + + float const AngleX(glm::pi() * 0.5f); + float const AngleZ(glm::pi() * 0.25f); + + glm::vec3 const axisX(1.0f, 0.0f, 0.0f); + glm::vec3 const axisZ(0.0f, 0.0f, 1.0f); + + glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleZ, axisZ) * glm::rotate(glm::mat4(1.0f), AngleX, axisX)) * V; + glm::vec4 const V2 = glm::eulerAngleZX(AngleZ, AngleX) * V; + glm::vec4 const V3 = glm::eulerAngleZ(AngleZ) * glm::eulerAngleX(AngleX) * V; + Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1; + + return Error; + } +}//namespace test_eulerAngleZX + +namespace test_eulerAngleYZ +{ + int test() + { + int Error = 0; + + glm::vec4 const V(1.0f); + + float const AngleY(glm::pi() * 0.5f); + float const AngleZ(glm::pi() * 0.25f); + + glm::vec3 const axisX(1.0f, 0.0f, 0.0f); + glm::vec3 const axisY(0.0f, 1.0f, 0.0f); + glm::vec3 const axisZ(0.0f, 0.0f, 1.0f); + + glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleY, axisY) * glm::rotate(glm::mat4(1.0f), AngleZ, axisZ)) * V; + glm::vec4 const V2 = glm::eulerAngleYZ(AngleY, AngleZ) * V; + glm::vec4 const V3 = glm::eulerAngleY(AngleY) * glm::eulerAngleZ(AngleZ) * V; + Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1; + + return Error; + } +}//namespace test_eulerAngleYZ + +namespace test_eulerAngleZY +{ + int test() + { + int Error = 0; + + glm::vec4 const V(1.0f); + + float const AngleY(glm::pi() * 0.5f); + float const AngleZ(glm::pi() * 0.25f); + + glm::vec3 const axisX(1.0f, 0.0f, 0.0f); + glm::vec3 const axisY(0.0f, 1.0f, 0.0f); + glm::vec3 const axisZ(0.0f, 0.0f, 1.0f); + + glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleZ, axisZ) * glm::rotate(glm::mat4(1.0f), AngleY, axisY)) * V; + glm::vec4 const V2 = glm::eulerAngleZY(AngleZ, AngleY) * V; + glm::vec4 const V3 = glm::eulerAngleZ(AngleZ) * glm::eulerAngleY(AngleY) * V; + Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1; + Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1; + + return Error; } -}//namespace eulerAngleXY +}//namespace test_eulerAngleZY namespace test_eulerAngleYXZ { @@ -152,6 +327,11 @@ int main() Error += test_eulerAngleY::test(); Error += test_eulerAngleZ::test(); Error += test_eulerAngleXY::test(); + Error += test_eulerAngleYX::test(); + Error += test_eulerAngleXZ::test(); + Error += test_eulerAngleZX::test(); + Error += test_eulerAngleYZ::test(); + Error += test_eulerAngleZY::test(); Error += test_eulerAngleYXZ::test(); return Error; From a5d2a63ef340597dedd34c1e7095c7e090d80706 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Tue, 1 Apr 2014 01:20:03 +0200 Subject: [PATCH 08/11] - Added workaround for a CUDA compiler bug (#186, #185) --- glm/detail/func_exponential.inl | 14 ++++++++++++-- glm/detail/func_geometric.inl | 7 ++++++- glm/gtx/fast_square_root.inl | 14 ++++++++++++-- readme.txt | 1 + 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/glm/detail/func_exponential.inl b/glm/detail/func_exponential.inl index 3a2f2379..767323f7 100644 --- a/glm/detail/func_exponential.inl +++ b/glm/detail/func_exponential.inl @@ -197,12 +197,22 @@ namespace detail // sqrt GLM_FUNC_QUALIFIER float sqrt(float x) { - return detail::compute_sqrt::call(x).x; +# ifdef __CUDACC__ // Wordaround for a CUDA compiler bug up to CUDA6 + detail::tvec1 tmp(detail::compute_sqrt::call(x)); + return tmp.x; +# else + return detail::compute_sqrt::call(x).x; +# endif } GLM_FUNC_QUALIFIER double sqrt(double x) { - return detail::compute_sqrt::call(x).x; +# ifdef __CUDACC__ // Wordaround for a CUDA compiler bug up to CUDA6 + detail::tvec1 tmp(detail::compute_sqrt::call(x)); + return tmp.x; +# else + return detail::compute_sqrt::call(x).x; +# endif } template class vecType> diff --git a/glm/detail/func_geometric.inl b/glm/detail/func_geometric.inl index 58aca38b..2f8691dd 100644 --- a/glm/detail/func_geometric.inl +++ b/glm/detail/func_geometric.inl @@ -43,7 +43,12 @@ namespace detail { GLM_FUNC_QUALIFIER static T call(detail::tvec1 const & x, detail::tvec1 const & y) { - return detail::tvec1(x * y).x; +# ifdef __CUDACC__ // Wordaround for a CUDA compiler bug up to CUDA6 + detail::tvec1 tmp(x * y); + return tmp.x; +# else + return detail::tvec1(x * y).x; +# endif } }; diff --git a/glm/gtx/fast_square_root.inl b/glm/gtx/fast_square_root.inl index b3f97957..a08bdbf2 100644 --- a/glm/gtx/fast_square_root.inl +++ b/glm/gtx/fast_square_root.inl @@ -27,13 +27,23 @@ namespace glm template <> GLM_FUNC_QUALIFIER float fastInverseSqrt(float const & x) { - return detail::compute_inversesqrt::call(detail::tvec1(x)).x; +# ifdef __CUDACC__ // Wordaround for a CUDA compiler bug up to CUDA6 + detail::tvec1 tmp(detail::compute_inversesqrt::call(detail::tvec1(x))); + return tmp.x; +# else + return detail::compute_inversesqrt::call(detail::tvec1(x)).x; +# endif } template <> GLM_FUNC_QUALIFIER double fastInverseSqrt(double const & x) { - return detail::compute_inversesqrt::call(detail::tvec1(x)).x; +# ifdef __CUDACC__ // Wordaround for a CUDA compiler bug up to CUDA6 + detail::tvec1 tmp(detail::compute_inversesqrt::call(detail::tvec1(x))); + return tmp.x; +# else + return detail::compute_inversesqrt::call(detail::tvec1(x)).x; +# endif } template