From 1d05f79eb8ab82058251cbd7b42c58dc4a7b6f46 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sat, 24 Sep 2011 23:25:09 +0100 Subject: [PATCH 01/32] C++11 tests --- CMakeLists.txt | 4 +++- glm/core/type_vec2.hpp | 8 ++++---- glm/core/type_vec4.hpp | 20 ++++++++++---------- glm/gtc/half_float.hpp | 2 +- glm/gtc/half_float.inl | 2 +- test/core/core_type_vec3.cpp | 3 +++ 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 35ea2cc5..93d9325b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,9 @@ if(CMAKE_COMPILER_IS_GNUCXX) #add_definitions(-S) #add_definitions(-s) add_definitions(-msse2) - add_definitions(-std=c++0x ) + add_definitions(-std=c++0x) + add_definitions(-fms-extensions) + add_definitions(-D_MSC_EXTENSIONS) #add_definitions(-m32) #add_definitions(-mfpmath=387) #add_definitions(-ffast-math) diff --git a/glm/core/type_vec2.hpp b/glm/core/type_vec2.hpp index e1256bb6..928c9122 100644 --- a/glm/core/type_vec2.hpp +++ b/glm/core/type_vec2.hpp @@ -62,9 +62,9 @@ namespace detail ////////////////////////////////////// // Data -# if(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW) +# if(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW) value_type x, y; -# elif(GLM_COMPONENT == GLM_COMPONENT_MS_EXT) +# elif(GLM_COMPONENT == GLM_COMPONENT_MS_EXT || GLM_LANG == GLM_LANG_CXX0X) union { _GLM_SWIZZLE2_2_MEMBERS(value_type,glm::detail::tvec2,x,y) @@ -81,10 +81,10 @@ namespace detail struct{value_type s, t;}; struct{value_type x, y;}; }; -# else//(GLM_COMPONENT == GLM_COMPONENT_GLSL_NAMES) +# else//(GLM_COMPONENT == GLM_COMPONENT_GLSL_NAMES) union {value_type x, r, s;}; union {value_type y, g, t;}; -# endif//GLM_COMPONENT +# endif//GLM_COMPONENT ////////////////////////////////////// // Accesses diff --git a/glm/core/type_vec4.hpp b/glm/core/type_vec4.hpp index bf34fb31..737607aa 100644 --- a/glm/core/type_vec4.hpp +++ b/glm/core/type_vec4.hpp @@ -64,18 +64,18 @@ namespace detail # if(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW) value_type x, y, z, w; -# elif(GLM_COMPONENT == GLM_COMPONENT_MS_EXT) +# elif(GLM_COMPONENT == GLM_COMPONENT_MS_EXT || GLM_LANG == GLM_LANG_CXX0X) union { - _GLM_SWIZZLE4_2_MEMBERS(value_type,glm::detail::tvec2,x,y,z,w) - _GLM_SWIZZLE4_2_MEMBERS(value_type,glm::detail::tvec2,r,g,b,a) - _GLM_SWIZZLE4_2_MEMBERS(value_type,glm::detail::tvec2,s,t,p,q) - _GLM_SWIZZLE4_3_MEMBERS(value_type,glm::detail::tvec3,x,y,z,w) - _GLM_SWIZZLE4_3_MEMBERS(value_type,glm::detail::tvec3,r,g,b,a) - _GLM_SWIZZLE4_3_MEMBERS(value_type,glm::detail::tvec3,s,t,p,q) - _GLM_SWIZZLE4_4_MEMBERS(value_type,glm::detail::tvec4,x,y,z,w) - _GLM_SWIZZLE4_4_MEMBERS(value_type,glm::detail::tvec4,r,g,b,a) - _GLM_SWIZZLE4_4_MEMBERS(value_type,glm::detail::tvec4,s,t,p,q) + _GLM_SWIZZLE4_2_MEMBERS(value_type,glm::detail::tvec2,x,y,z,w) + _GLM_SWIZZLE4_2_MEMBERS(value_type,glm::detail::tvec2,r,g,b,a) + _GLM_SWIZZLE4_2_MEMBERS(value_type,glm::detail::tvec2,s,t,p,q) + _GLM_SWIZZLE4_3_MEMBERS(value_type,glm::detail::tvec3,x,y,z,w) + _GLM_SWIZZLE4_3_MEMBERS(value_type,glm::detail::tvec3,r,g,b,a) + _GLM_SWIZZLE4_3_MEMBERS(value_type,glm::detail::tvec3,s,t,p,q) + _GLM_SWIZZLE4_4_MEMBERS(value_type,glm::detail::tvec4,x,y,z,w) + _GLM_SWIZZLE4_4_MEMBERS(value_type,glm::detail::tvec4,r,g,b,a) + _GLM_SWIZZLE4_4_MEMBERS(value_type,glm::detail::tvec4,s,t,p,q) struct{value_type r, g, b, a;}; struct{value_type s, t, p, q;}; diff --git a/glm/gtc/half_float.hpp b/glm/gtc/half_float.hpp index 8cb6689d..8c8896de 100644 --- a/glm/gtc/half_float.hpp +++ b/glm/gtc/half_float.hpp @@ -47,7 +47,7 @@ namespace glm{ namespace detail { -#ifndef _MSC_EXTENSIONS +#if 0 //ndef _MSC_EXTENSIONS template <> struct tvec2 { diff --git a/glm/gtc/half_float.inl b/glm/gtc/half_float.inl index 2d20f8a0..624bc6ee 100644 --- a/glm/gtc/half_float.inl +++ b/glm/gtc/half_float.inl @@ -29,7 +29,7 @@ namespace glm{ namespace detail{ -#ifndef _MSC_EXTENSIONS +#if 0//ndef _MSC_EXTENSIONS ////////////////////////////////////// // hvec2 diff --git a/test/core/core_type_vec3.cpp b/test/core/core_type_vec3.cpp index 0e5c4636..b39c6d67 100644 --- a/test/core/core_type_vec3.cpp +++ b/test/core/core_type_vec3.cpp @@ -9,6 +9,7 @@ #include #include +#include static int test_vec3_operators() { @@ -251,5 +252,7 @@ int main() Error += test_vec3_swizzle_operators(); Error += test_vec3_swizzle_functions(); + printf("Errors: %d\n", Error); + return Error; } From a4724afb2c670c16d6166b2533013f6f4fc1d047 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sun, 25 Sep 2011 14:21:36 +0100 Subject: [PATCH 02/32] Added vec2 operators tests --- test/core/core_type_vec2.cpp | 112 +++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/test/core/core_type_vec2.cpp b/test/core/core_type_vec2.cpp index 0e513cd3..18b4a15e 100644 --- a/test/core/core_type_vec2.cpp +++ b/test/core/core_type_vec2.cpp @@ -71,6 +71,118 @@ int test_vec2_operators() Error += A.x == C.x && A.y == C.y ? 0 : 1; } + { + glm::vec2 A(1.0f, 2.0f); + glm::vec2 B(4.0f, 5.0f); + + glm::vec2 C = A + B; + Error += C == glm::vec2(5, 7) ? 0 : 1; + + glm::vec2 D = B - A; + Error += D == glm::vec2(3, 3) ? 0 : 1; + + glm::vec2 E = A * B; + Error += E == glm::vec2(4, 10) ? 0 : 1; + + glm::vec2 F = B / A; + Error += F == glm::vec2(4, 2.5) ? 0 : 1; + + glm::vec2 G = A + 1.0f; + Error += G == glm::vec2(2, 3) ? 0 : 1; + + glm::vec2 H = B - 1.0f; + Error += H == glm::vec2(3, 4) ? 0 : 1; + + glm::vec2 I = A * 2.0f; + Error += I == glm::vec2(2, 4) ? 0 : 1; + + glm::vec2 J = B / 2.0f; + Error += J == glm::vec2(2, 2.5) ? 0 : 1; + + glm::vec2 K = 1.0f + A; + Error += K == glm::vec2(2, 3) ? 0 : 1; + + glm::vec2 L = 1.0f - B; + Error += L == glm::vec2(-3, -4) ? 0 : 1; + + glm::vec2 M = 2.0f * A; + Error += M == glm::vec2(2, 4) ? 0 : 1; + + glm::vec2 N = 2.0f / B; + Error += N == glm::vec2(0.5, 2.0 / 5.0) ? 0 : 1; + } + + { + glm::vec2 A(1.0f, 2.0f); + glm::vec2 B(4.0f, 5.0f); + + A += B; + Error += A == glm::vec2(5, 7) ? 0 : 1; + + A += 1.0f; + Error += A == glm::vec2(6, 8) ? 0 : 1; + } + { + glm::vec2 A(1.0f, 2.0f); + glm::vec2 B(4.0f, 5.0f); + + B -= A; + Error += B == glm::vec2(3, 3) ? 0 : 1; + + B -= 1.0f; + Error += B == glm::vec2(2, 2) ? 0 : 1; + } + { + glm::vec2 A(1.0f, 2.0f); + glm::vec2 B(4.0f, 5.0f); + + A *= B; + Error += A == glm::vec2(4, 10) ? 0 : 1; + + A *= 2.0f; + Error += A == glm::vec2(8, 20) ? 0 : 1; + } + { + glm::vec2 A(1.0f, 2.0f); + glm::vec2 B(4.0f, 5.0f); + + B /= A; + Error += B == glm::vec2(4, 2.5) ? 0 : 1; + + B /= 2.0f; + Error += B == glm::vec2(2, 1.25) ? 0 : 1; + } + + { + glm::vec3 A(1.0f, 2.0f); + glm::vec3 B = -A; + Error += B == glm::vec2(-1.0f, -2.0f) ? 0 : 1; + } + + { + glm::vec2 A(1.0f, 2.0f); + glm::vec2 B = --A; + Error += B == glm::vec2(0.0f, 1.0f) ? 0 : 1; + } + + { + glm::vec2 A(1.0f, 2.0f); + glm::vec2 B = A--; + Error += B == glm::vec2(0.0f, 1.0f) ? 0 : 1; + } + + { + glm::vec2 A(1.0f, 2.0f); + glm::vec2 B = ++A; + Error += B == glm::vec2(2.0f, 3.0f) ? 0 : 1; + } + + { + glm::vec2 A(1.0f, 2.0f); + glm::vec2 B = A++; + Error += B == glm::vec2(2.0f, 3.0f) ? 0 : 1; + } + return Error; } From 88bd9ab6ae7edd7daedeaa7e307fc8da7669c3ac Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sun, 25 Sep 2011 15:18:10 +0100 Subject: [PATCH 03/32] Fixed typo --- doc/pages.doxy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pages.doxy b/doc/pages.doxy index 1115d6ab..d30242e2 100644 --- a/doc/pages.doxy +++ b/doc/pages.doxy @@ -265,7 +265,7 @@ void foo() \section advanced_inline Force Inline - GLM's functions are defined in headers, so they are defined with C++'s "inline" delcaration. + GLM's functions are defined in headers, so they are defined with C++'s "inline" declaration. This does not require the compiler to inline them, however. To force the compiler to inline the function, using whatever capabilities that the compiler provides to do so, GLM_FORCE_INLINE can be defined before any inclusion of . From 8876a7f7f4fc42213132f54ce5effc74262b0863 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sun, 25 Sep 2011 17:11:21 +0100 Subject: [PATCH 04/32] Fixed build --- test/core/core_type_vec2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/core/core_type_vec2.cpp b/test/core/core_type_vec2.cpp index 18b4a15e..f9b97577 100644 --- a/test/core/core_type_vec2.cpp +++ b/test/core/core_type_vec2.cpp @@ -154,8 +154,8 @@ int test_vec2_operators() } { - glm::vec3 A(1.0f, 2.0f); - glm::vec3 B = -A; + glm::vec2 A(1.0f, 2.0f); + glm::vec2 B = -A; Error += B == glm::vec2(-1.0f, -2.0f) ? 0 : 1; } From 0abdaee9b4d4459f6f98db6a7d239eac4d434693 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Mon, 26 Sep 2011 02:20:23 +0100 Subject: [PATCH 05/32] typo --- glm/gtx/noise.inl | 2 +- test/gtx/gtx_noise.cpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/glm/gtx/noise.inl b/glm/gtx/noise.inl index 938a0ef8..8bd1ef2c 100644 --- a/glm/gtx/noise.inl +++ b/glm/gtx/noise.inl @@ -760,7 +760,7 @@ GLM_FUNC_QUALIFIER T simplex(detail::tvec3 const & v) // Mix final noise value detail::tvec4 m = max(T(0.6) - detail::tvec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), T(0)); m = m * m; - return T(42) * dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3))); + return T(42) * dot(m * m, detail::tvec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3))); } template diff --git a/test/gtx/gtx_noise.cpp b/test/gtx/gtx_noise.cpp index 16f3de22..d82273b4 100644 --- a/test/gtx/gtx_noise.cpp +++ b/test/gtx/gtx_noise.cpp @@ -23,7 +23,7 @@ int test_simplex() for(std::size_t y = 0; y < Size; ++y) for(std::size_t x = 0; x < Size; ++x) { - ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::simplex(glm::vec2(x / 32.f, y / 32.f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::simplex(glm::vec2(x / 64.f, y / 64.f)) * 128.f + 127.f); ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; } @@ -40,7 +40,7 @@ int test_simplex() for(std::size_t y = 0; y < Size; ++y) for(std::size_t x = 0; x < Size; ++x) { - ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::simplex(glm::vec3(x / 32.f, y / 32.f, 0.5f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::simplex(glm::vec3(x / 64.f, y / 64.f, 0.5f)) * 128.f + 127.f); ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; } @@ -57,7 +57,7 @@ int test_simplex() for(std::size_t y = 0; y < Size; ++y) for(std::size_t x = 0; x < Size; ++x) { - ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::simplex(glm::vec4(x / 32.f, y / 32.f, 0.5f, 0.5f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::simplex(glm::vec4(x / 64.f, y / 64.f, 0.5f, 0.5f)) * 128.f + 127.f); ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; } @@ -81,7 +81,7 @@ int test_perlin() for(std::size_t y = 0; y < Size; ++y) for(std::size_t x = 0; x < Size; ++x) { - ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec2(x / 16.f, y / 16.f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec2(x / 64.f, y / 64.f)) * 128.f + 127.f); ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; } @@ -98,7 +98,7 @@ int test_perlin() for(std::size_t y = 0; y < Size; ++y) for(std::size_t x = 0; x < Size; ++x) { - ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec3(x / 16.f, y / 16.f, 0.5f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec3(x / 64.f, y / 64.f, 0.5f)) * 128.f + 127.f); ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; } @@ -115,7 +115,7 @@ int test_perlin() for(std::size_t y = 0; y < Size; ++y) for(std::size_t x = 0; x < Size; ++x) { - ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec4(x / 16.f, y / 16.f, 0.5f, 0.5f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec4(x / 64.f, y / 64.f, 0.5f, 0.5f)) * 128.f + 127.f); ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; } @@ -139,7 +139,7 @@ int test_perlin_pedioric() for(std::size_t y = 0; y < Size; ++y) for(std::size_t x = 0; x < Size; ++x) { - ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec2(x / 16.f, y / 16.f), glm::vec2(2.0f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec2(x / 64.f, y / 64.f), glm::vec2(2.0f)) * 128.f + 127.f); ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; } @@ -156,7 +156,7 @@ int test_perlin_pedioric() for(std::size_t y = 0; y < Size; ++y) for(std::size_t x = 0; x < Size; ++x) { - ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec3(x / 16.f, y / 16.f, 0.5f), glm::vec3(2.0f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec3(x / 64.f, y / 64.f, 0.5f), glm::vec3(2.0f)) * 128.f + 127.f); ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; } @@ -173,7 +173,7 @@ int test_perlin_pedioric() for(std::size_t y = 0; y < Size; ++y) for(std::size_t x = 0; x < Size; ++x) { - ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec4(x / 16.f, y / 16.f, 0.5f, 0.5f), glm::vec4(2.0f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec4(x / 64.f, y / 64.f, 0.5f, 0.5f), glm::vec4(2.0f)) * 128.f + 127.f); ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; } From 9c8930e63011d9f16f6d98d510a86245e1eebbbd Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Tue, 27 Sep 2011 10:22:29 +0100 Subject: [PATCH 06/32] Promoted noise extension to GTC --- glm/gtc/noise.hpp | 81 ++++ glm/gtc/noise.inl | 852 +++++++++++++++++++++++++++++++++++ glm/gtx/noise.hpp | 20 +- glm/gtx/noise.inl | 832 ---------------------------------- test/core/core_type_vec3.cpp | 27 ++ test/core/core_type_vec4.cpp | 31 ++ test/gtc/CMakeLists.txt | 1 + test/gtc/gtc_noise.cpp | 199 ++++++++ 8 files changed, 1192 insertions(+), 851 deletions(-) create mode 100644 glm/gtc/noise.hpp create mode 100644 glm/gtc/noise.inl create mode 100644 test/gtc/gtc_noise.cpp diff --git a/glm/gtc/noise.hpp b/glm/gtc/noise.hpp new file mode 100644 index 00000000..29a7c121 --- /dev/null +++ b/glm/gtc/noise.hpp @@ -0,0 +1,81 @@ +/////////////////////////////////////////////////////////////////////////////////// +/// OpenGL Mathematics (glm.g-truc.net) +/// +/// Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net) +/// Permission is hereby granted, free of charge, to any person obtaining a copy +/// of this software and associated documentation files (the "Software"), to deal +/// in the Software without restriction, including without limitation the rights +/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/// copies of the Software, and to permit persons to whom the Software is +/// furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +/// THE SOFTWARE. +/// +/// @ref gtc_noise +/// @file glm/gtc/noise.hpp +/// @date 2011-04-21 / 2011-09-27 +/// @author Christophe Riccio +/// +/// @see core (dependence) +/// +/// @defgroup gtx_noise GLM_GTX_noise: Procedural noise functions +/// @ingroup gtx +/// +/// Defines 2D, 3D and 4D procedural noise functions +/// Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise": +/// https://github.com/ashima/webgl-noise +/// Following Stefan Gustavson's paper "Simplex noise demystified": +/// http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf +/// Defines the half-precision floating-point type, along with various typedefs for vectors and matrices. +/// need to be included to use these functionalities. +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef GLM_GTC_noise +#define GLM_GTC_noise GLM_VERSION + +// Dependency: +#include "../glm.hpp" + +#if(defined(GLM_MESSAGES) && !defined(glm_ext)) +# pragma message("GLM: GLM_GTC_noise extension included") +#endif + +namespace glm +{ + /// @addtogroup gtx_noise + /// @{ + + /// Classic perlin noise. + /// From GLM_GTC_noise extension. + template class vecType> + T perlin( + vecType const & p); + + /// Periodic perlin noise. + /// From GLM_GTC_noise extension. + template class vecType> + T perlin( + vecType const & p, + vecType const & rep); + + /// Simplex noise. + /// From GLM_GTC_noise extension. + template class vecType> + T simplex( + vecType const & p); + + /// @} +}//namespace glm + +#include "noise.inl" + +#endif//GLM_GTC_noise diff --git a/glm/gtc/noise.inl b/glm/gtc/noise.inl new file mode 100644 index 00000000..1fbc3f37 --- /dev/null +++ b/glm/gtc/noise.inl @@ -0,0 +1,852 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////// +// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net) +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise": +// https://github.com/ashima/webgl-noise +// Following Stefan Gustavson's paper "Simplex noise demystified": +// http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Created : 2011-04-21 +// Updated : 2011-09-27 +// Licence : This source is under MIT License +// File : glm/gtc/noise.inl +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Dependency: +// - GLM core +/////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace glm{ + +template +GLM_FUNC_QUALIFIER T mod289(T const & x) +{ + return x - floor(x * T(1.0 / 289.0)) * T(289.0); +} + +template +GLM_FUNC_QUALIFIER T permute(T const & x) +{ + return mod289(((x * T(34)) + T(1)) * x); +} + +template class vecType> +GLM_FUNC_QUALIFIER vecType permute(vecType const & x) +{ + return mod289(((x * T(34)) + T(1)) * x); +} + +template +GLM_FUNC_QUALIFIER T taylorInvSqrt(T const & r) +{ + return T(1.79284291400159) - T(0.85373472095314) * r; +} + +template class vecType> +GLM_FUNC_QUALIFIER vecType taylorInvSqrt(vecType const & r) +{ + return T(1.79284291400159) - T(0.85373472095314) * r; +} + +template class vecType> +GLM_FUNC_QUALIFIER vecType fade(vecType const & t) +{ + return t * t * t * (t * (t * T(6) - T(15)) + T(10)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 grad4(T const & j, detail::tvec4 const & ip) +{ + detail::tvec3 pXYZ = floor(fract(detail::tvec3(j) * detail::tvec3(ip)) * T(7)) * ip[2] - T(1); + T pW = T(1.5) - dot(abs(pXYZ), detail::tvec3(1)); + detail::tvec4 s = detail::tvec4(lessThan(detail::tvec4(pXYZ, pW), detail::tvec4(0.0))); + pXYZ = pXYZ + (detail::tvec3(s) * T(2) - T(1)) * s.w; + return detail::tvec4(pXYZ, pW); +} + +// Classic Perlin noise +template +GLM_FUNC_QUALIFIER T perlin(detail::tvec2 const & P) +{ + detail::tvec4 Pi = glm::floor(detail::tvec4(P.x, P.y, P.x, P.y)) + detail::tvec4(0.0, 0.0, 1.0, 1.0); + detail::tvec4 Pf = glm::fract(detail::tvec4(P.x, P.y, P.x, P.y)) - detail::tvec4(0.0, 0.0, 1.0, 1.0); + Pi = mod(Pi, T(289)); // To avoid truncation effects in permutation + detail::tvec4 ix(Pi.x, Pi.z, Pi.x, Pi.z); + detail::tvec4 iy(Pi.y, Pi.y, Pi.w, Pi.w); + detail::tvec4 fx(Pf.x, Pf.z, Pf.x, Pf.z); + detail::tvec4 fy(Pf.y, Pf.y, Pf.w, Pf.w); + + detail::tvec4 i = glm::permute(glm::permute(ix) + iy); + + detail::tvec4 gx = T(2) * glm::fract(i / T(41)) - T(1); + detail::tvec4 gy = glm::abs(gx) - T(0.5); + detail::tvec4 tx = glm::floor(gx + T(0.5)); + gx = gx - tx; + + detail::tvec2 g00(gx.x, gy.x); + detail::tvec2 g10(gx.y, gy.y); + detail::tvec2 g01(gx.z, gy.z); + detail::tvec2 g11(gx.w, gy.w); + + detail::tvec4 norm = taylorInvSqrt(detail::tvec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); + g00 *= norm.x; + g01 *= norm.y; + g10 *= norm.z; + g11 *= norm.w; + + T n00 = dot(g00, detail::tvec2(fx.x, fy.x)); + T n10 = dot(g10, detail::tvec2(fx.y, fy.y)); + T n01 = dot(g01, detail::tvec2(fx.z, fy.z)); + T n11 = dot(g11, detail::tvec2(fx.w, fy.w)); + + detail::tvec2 fade_xy = fade(detail::tvec2(Pf.x, Pf.y)); + detail::tvec2 n_x = mix(detail::tvec2(n00, n01), detail::tvec2(n10, n11), fade_xy.x); + T n_xy = mix(n_x.x, n_x.y, fade_xy.y); + return T(2.3) * n_xy; +} + +// Classic Perlin noise +template +GLM_FUNC_QUALIFIER T perlin(detail::tvec3 const & P) +{ + detail::tvec3 Pi0 = floor(P); // Integer part for indexing + detail::tvec3 Pi1 = Pi0 + T(1); // Integer part + 1 + Pi0 = mod289(Pi0); + Pi1 = mod289(Pi1); + detail::tvec3 Pf0 = fract(P); // Fractional part for interpolation + detail::tvec3 Pf1 = Pf0 - T(1); // Fractional part - 1.0 + detail::tvec4 ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + detail::tvec4 iy = detail::tvec4(detail::tvec2(Pi0.y), detail::tvec2(Pi1.y)); + detail::tvec4 iz0(Pi0.z); + detail::tvec4 iz1(Pi1.z); + + detail::tvec4 ixy = permute(permute(ix) + iy); + detail::tvec4 ixy0 = permute(ixy + iz0); + detail::tvec4 ixy1 = permute(ixy + iz1); + + detail::tvec4 gx0 = ixy0 * T(1.0 / 7.0); + detail::tvec4 gy0 = fract(floor(gx0) * T(1.0 / 7.0)) - T(0.5); + gx0 = fract(gx0); + detail::tvec4 gz0 = detail::tvec4(0.5) - abs(gx0) - abs(gy0); + detail::tvec4 sz0 = step(gz0, detail::tvec4(0.0)); + gx0 -= sz0 * (step(T(0), gx0) - T(0.5)); + gy0 -= sz0 * (step(T(0), gy0) - T(0.5)); + + detail::tvec4 gx1 = ixy1 * T(1.0 / 7.0); + detail::tvec4 gy1 = fract(floor(gx1) * T(1.0 / 7.0)) - T(0.5); + gx1 = fract(gx1); + detail::tvec4 gz1 = detail::tvec4(0.5) - abs(gx1) - abs(gy1); + detail::tvec4 sz1 = step(gz1, detail::tvec4(0.0)); + gx1 -= sz1 * (step(T(0), gx1) - T(0.5)); + gy1 -= sz1 * (step(T(0), gy1) - T(0.5)); + + detail::tvec3 g000(gx0.x, gy0.x, gz0.x); + detail::tvec3 g100(gx0.y, gy0.y, gz0.y); + detail::tvec3 g010(gx0.z, gy0.z, gz0.z); + detail::tvec3 g110(gx0.w, gy0.w, gz0.w); + detail::tvec3 g001(gx1.x, gy1.x, gz1.x); + detail::tvec3 g101(gx1.y, gy1.y, gz1.y); + detail::tvec3 g011(gx1.z, gy1.z, gz1.z); + detail::tvec3 g111(gx1.w, gy1.w, gz1.w); + + detail::tvec4 norm0 = taylorInvSqrt(detail::tvec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + detail::tvec4 norm1 = taylorInvSqrt(detail::tvec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + T n000 = dot(g000, Pf0); + T n100 = dot(g100, detail::tvec3(Pf1.x, Pf0.y, Pf0.z)); + T n010 = dot(g010, detail::tvec3(Pf0.x, Pf1.y, Pf0.z)); + T n110 = dot(g110, detail::tvec3(Pf1.x, Pf1.y, Pf0.z)); + T n001 = dot(g001, detail::tvec3(Pf0.x, Pf0.y, Pf1.z)); + T n101 = dot(g101, detail::tvec3(Pf1.x, Pf0.y, Pf1.z)); + T n011 = dot(g011, detail::tvec3(Pf0.x, Pf1.y, Pf1.z)); + T n111 = dot(g111, Pf1); + + detail::tvec3 fade_xyz = fade(Pf0); + detail::tvec4 n_z = mix(detail::tvec4(n000, n100, n010, n110), detail::tvec4(n001, n101, n011, n111), fade_xyz.z); + detail::tvec2 n_yz = mix(detail::tvec2(n_z.x, n_z.y), detail::tvec2(n_z.z, n_z.w), fade_xyz.y); + T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return T(2.2) * n_xyz; +} +/* +// Classic Perlin noise +template +GLM_FUNC_QUALIFIER T perlin(detail::tvec3 const & P) +{ + detail::tvec3 Pi0 = floor(P); // Integer part for indexing + detail::tvec3 Pi1 = Pi0 + T(1); // Integer part + 1 + Pi0 = mod(Pi0, T(289)); + Pi1 = mod(Pi1, T(289)); + detail::tvec3 Pf0 = fract(P); // Fractional part for interpolation + detail::tvec3 Pf1 = Pf0 - T(1); // Fractional part - 1.0 + detail::tvec4 ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + detail::tvec4 iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + detail::tvec4 iz0(Pi0.z); + detail::tvec4 iz1(Pi1.z); + + detail::tvec4 ixy = permute(permute(ix) + iy); + detail::tvec4 ixy0 = permute(ixy + iz0); + detail::tvec4 ixy1 = permute(ixy + iz1); + + detail::tvec4 gx0 = ixy0 / T(7); + detail::tvec4 gy0 = fract(floor(gx0) / T(7)) - T(0.5); + gx0 = fract(gx0); + detail::tvec4 gz0 = detail::tvec4(0.5) - abs(gx0) - abs(gy0); + detail::tvec4 sz0 = step(gz0, detail::tvec4(0.0)); + gx0 -= sz0 * (step(0.0, gx0) - T(0.5)); + gy0 -= sz0 * (step(0.0, gy0) - T(0.5)); + + detail::tvec4 gx1 = ixy1 / T(7); + detail::tvec4 gy1 = fract(floor(gx1) / T(7)) - T(0.5); + gx1 = fract(gx1); + detail::tvec4 gz1 = detail::tvec4(0.5) - abs(gx1) - abs(gy1); + detail::tvec4 sz1 = step(gz1, detail::tvec4(0.0)); + gx1 -= sz1 * (step(T(0), gx1) - T(0.5)); + gy1 -= sz1 * (step(T(0), gy1) - T(0.5)); + + detail::tvec3 g000(gx0.x, gy0.x, gz0.x); + detail::tvec3 g100(gx0.y, gy0.y, gz0.y); + detail::tvec3 g010(gx0.z, gy0.z, gz0.z); + detail::tvec3 g110(gx0.w, gy0.w, gz0.w); + detail::tvec3 g001(gx1.x, gy1.x, gz1.x); + detail::tvec3 g101(gx1.y, gy1.y, gz1.y); + detail::tvec3 g011(gx1.z, gy1.z, gz1.z); + detail::tvec3 g111(gx1.w, gy1.w, gz1.w); + + detail::tvec4 norm0 = taylorInvSqrt(detail::tvec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + detail::tvec4 norm1 = taylorInvSqrt(detail::tvec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + T n000 = dot(g000, Pf0); + T n100 = dot(g100, detail::tvec3(Pf1.x, Pf0.y, Pf0.z)); + T n010 = dot(g010, detail::tvec3(Pf0.x, Pf1.y, Pf0.z)); + T n110 = dot(g110, detail::tvec3(Pf1.x, Pf1.y, Pf0.z)); + T n001 = dot(g001, detail::tvec3(Pf0.x, Pf0.y, Pf1.z)); + T n101 = dot(g101, detail::tvec3(Pf1.x, Pf0.y, Pf1.z)); + T n011 = dot(g011, detail::tvec3(Pf0.x, Pf1.y, Pf1.z)); + T n111 = dot(g111, Pf1); + + detail::tvec3 fade_xyz = fade(Pf0); + detail::tvec4 n_z = mix(detail::tvec4(n000, n100, n010, n110), detail::tvec4(n001, n101, n011, n111), fade_xyz.z); + detail::tvec2 n_yz = mix( + detail::tvec2(n_z.x, n_z.y), + detail::tvec2(n_z.z, n_z.w), fade_xyz.y); + T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return T(2.2) * n_xyz; +} +*/ +// Classic Perlin noise +template +GLM_FUNC_QUALIFIER T perlin(detail::tvec4 const & P) +{ + detail::tvec4 Pi0 = floor(P); // Integer part for indexing + detail::tvec4 Pi1 = Pi0 + T(1); // Integer part + 1 + Pi0 = mod(Pi0, T(289)); + Pi1 = mod(Pi1, T(289)); + detail::tvec4 Pf0 = fract(P); // Fractional part for interpolation + detail::tvec4 Pf1 = Pf0 - T(1); // Fractional part - 1.0 + detail::tvec4 ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + detail::tvec4 iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + detail::tvec4 iz0(Pi0.z); + detail::tvec4 iz1(Pi1.z); + detail::tvec4 iw0(Pi0.w); + detail::tvec4 iw1(Pi1.w); + + detail::tvec4 ixy = permute(permute(ix) + iy); + detail::tvec4 ixy0 = permute(ixy + iz0); + detail::tvec4 ixy1 = permute(ixy + iz1); + detail::tvec4 ixy00 = permute(ixy0 + iw0); + detail::tvec4 ixy01 = permute(ixy0 + iw1); + detail::tvec4 ixy10 = permute(ixy1 + iw0); + detail::tvec4 ixy11 = permute(ixy1 + iw1); + + detail::tvec4 gx00 = ixy00 / T(7); + detail::tvec4 gy00 = floor(gx00) / T(7); + detail::tvec4 gz00 = floor(gy00) / T(6); + gx00 = fract(gx00) - T(0.5); + gy00 = fract(gy00) - T(0.5); + gz00 = fract(gz00) - T(0.5); + detail::tvec4 gw00 = detail::tvec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00); + detail::tvec4 sw00 = step(gw00, detail::tvec4(0.0)); + gx00 -= sw00 * (step(T(0), gx00) - T(0.5)); + gy00 -= sw00 * (step(T(0), gy00) - T(0.5)); + + detail::tvec4 gx01 = ixy01 / T(7); + detail::tvec4 gy01 = floor(gx01) / T(7); + detail::tvec4 gz01 = floor(gy01) / T(6); + gx01 = fract(gx01) - T(0.5); + gy01 = fract(gy01) - T(0.5); + gz01 = fract(gz01) - T(0.5); + detail::tvec4 gw01 = detail::tvec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01); + detail::tvec4 sw01 = step(gw01, detail::tvec4(0.0)); + gx01 -= sw01 * (step(T(0), gx01) - T(0.5)); + gy01 -= sw01 * (step(T(0), gy01) - T(0.5)); + + detail::tvec4 gx10 = ixy10 / T(7); + detail::tvec4 gy10 = floor(gx10) / T(7); + detail::tvec4 gz10 = floor(gy10) / T(6); + gx10 = fract(gx10) - T(0.5); + gy10 = fract(gy10) - T(0.5); + gz10 = fract(gz10) - T(0.5); + detail::tvec4 gw10 = detail::tvec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10); + detail::tvec4 sw10 = step(gw10, detail::tvec4(0)); + gx10 -= sw10 * (step(T(0), gx10) - T(0.5)); + gy10 -= sw10 * (step(T(0), gy10) - T(0.5)); + + detail::tvec4 gx11 = ixy11 / T(7); + detail::tvec4 gy11 = floor(gx11) / T(7); + detail::tvec4 gz11 = floor(gy11) / T(6); + gx11 = fract(gx11) - T(0.5); + gy11 = fract(gy11) - T(0.5); + gz11 = fract(gz11) - T(0.5); + detail::tvec4 gw11 = detail::tvec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11); + detail::tvec4 sw11 = step(gw11, detail::tvec4(0.0)); + gx11 -= sw11 * (step(T(0), gx11) - T(0.5)); + gy11 -= sw11 * (step(T(0), gy11) - T(0.5)); + + detail::tvec4 g0000(gx00.x, gy00.x, gz00.x, gw00.x); + detail::tvec4 g1000(gx00.y, gy00.y, gz00.y, gw00.y); + detail::tvec4 g0100(gx00.z, gy00.z, gz00.z, gw00.z); + detail::tvec4 g1100(gx00.w, gy00.w, gz00.w, gw00.w); + detail::tvec4 g0010(gx10.x, gy10.x, gz10.x, gw10.x); + detail::tvec4 g1010(gx10.y, gy10.y, gz10.y, gw10.y); + detail::tvec4 g0110(gx10.z, gy10.z, gz10.z, gw10.z); + detail::tvec4 g1110(gx10.w, gy10.w, gz10.w, gw10.w); + detail::tvec4 g0001(gx01.x, gy01.x, gz01.x, gw01.x); + detail::tvec4 g1001(gx01.y, gy01.y, gz01.y, gw01.y); + detail::tvec4 g0101(gx01.z, gy01.z, gz01.z, gw01.z); + detail::tvec4 g1101(gx01.w, gy01.w, gz01.w, gw01.w); + detail::tvec4 g0011(gx11.x, gy11.x, gz11.x, gw11.x); + detail::tvec4 g1011(gx11.y, gy11.y, gz11.y, gw11.y); + detail::tvec4 g0111(gx11.z, gy11.z, gz11.z, gw11.z); + detail::tvec4 g1111(gx11.w, gy11.w, gz11.w, gw11.w); + + detail::tvec4 norm00 = taylorInvSqrt(detail::tvec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); + g0000 *= norm00.x; + g0100 *= norm00.y; + g1000 *= norm00.z; + g1100 *= norm00.w; + + detail::tvec4 norm01 = taylorInvSqrt(detail::tvec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); + g0001 *= norm01.x; + g0101 *= norm01.y; + g1001 *= norm01.z; + g1101 *= norm01.w; + + detail::tvec4 norm10 = taylorInvSqrt(detail::tvec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); + g0010 *= norm10.x; + g0110 *= norm10.y; + g1010 *= norm10.z; + g1110 *= norm10.w; + + detail::tvec4 norm11 = taylorInvSqrt(detail::tvec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); + g0011 *= norm11.x; + g0111 *= norm11.y; + g1011 *= norm11.z; + g1111 *= norm11.w; + + T n0000 = dot(g0000, Pf0); + T n1000 = dot(g1000, detail::tvec4(Pf1.x, Pf0.y, Pf0.z, Pf0.w)); + T n0100 = dot(g0100, detail::tvec4(Pf0.x, Pf1.y, Pf0.z, Pf0.w)); + T n1100 = dot(g1100, detail::tvec4(Pf1.x, Pf1.y, Pf0.z, Pf0.w)); + T n0010 = dot(g0010, detail::tvec4(Pf0.x, Pf0.y, Pf1.z, Pf0.w)); + T n1010 = dot(g1010, detail::tvec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); + T n0110 = dot(g0110, detail::tvec4(Pf0.x, Pf1.y, Pf1.z, Pf0.w)); + T n1110 = dot(g1110, detail::tvec4(Pf1.x, Pf1.y, Pf1.z, Pf0.w)); + T n0001 = dot(g0001, detail::tvec4(Pf0.x, Pf0.y, Pf0.z, Pf1.w)); + T n1001 = dot(g1001, detail::tvec4(Pf1.x, Pf0.y, Pf0.z, Pf1.w)); + T n0101 = dot(g0101, detail::tvec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); + T n1101 = dot(g1101, detail::tvec4(Pf1.x, Pf1.y, Pf0.z, Pf1.w)); + T n0011 = dot(g0011, detail::tvec4(Pf0.x, Pf0.y, Pf1.z, Pf1.w)); + T n1011 = dot(g1011, detail::tvec4(Pf1.x, Pf0.y, Pf1.z, Pf1.w)); + T n0111 = dot(g0111, detail::tvec4(Pf0.x, Pf1.y, Pf1.z, Pf1.w)); + T n1111 = dot(g1111, Pf1); + + detail::tvec4 fade_xyzw = fade(Pf0); + detail::tvec4 n_0w = mix(detail::tvec4(n0000, n1000, n0100, n1100), detail::tvec4(n0001, n1001, n0101, n1101), fade_xyzw.w); + detail::tvec4 n_1w = mix(detail::tvec4(n0010, n1010, n0110, n1110), detail::tvec4(n0011, n1011, n0111, n1111), fade_xyzw.w); + detail::tvec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z); + detail::tvec2 n_yzw = mix(detail::tvec2(n_zw.x, n_zw.y), detail::tvec2(n_zw.z, n_zw.w), fade_xyzw.y); + T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); + return T(2.2) * n_xyzw; +} + +// Classic Perlin noise, periodic variant +template +GLM_FUNC_QUALIFIER T perlin(detail::tvec2 const & P, detail::tvec2 const & rep) +{ + detail::tvec4 Pi = floor(detail::tvec4(P.x, P.y, P.x, P.y)) + detail::tvec4(0.0, 0.0, 1.0, 1.0); + detail::tvec4 Pf = fract(detail::tvec4(P.x, P.y, P.x, P.y)) - detail::tvec4(0.0, 0.0, 1.0, 1.0); + Pi = mod(Pi, detail::tvec4(rep.x, rep.y, rep.x, rep.y)); // To create noise with explicit period + Pi = mod(Pi, T(289)); // To avoid truncation effects in permutation + detail::tvec4 ix(Pi.x, Pi.z, Pi.x, Pi.z); + detail::tvec4 iy(Pi.y, Pi.y, Pi.w, Pi.w); + detail::tvec4 fx(Pf.x, Pf.z, Pf.x, Pf.z); + detail::tvec4 fy(Pf.y, Pf.y, Pf.w, Pf.w); + + detail::tvec4 i = permute(permute(ix) + iy); + + detail::tvec4 gx = T(2) * fract(i / T(41)) - T(1); + detail::tvec4 gy = abs(gx) - T(0.5); + detail::tvec4 tx = floor(gx + T(0.5)); + gx = gx - tx; + + detail::tvec2 g00(gx.x, gy.x); + detail::tvec2 g10(gx.y, gy.y); + detail::tvec2 g01(gx.z, gy.z); + detail::tvec2 g11(gx.w, gy.w); + + detail::tvec4 norm = taylorInvSqrt(detail::tvec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); + g00 *= norm.x; + g01 *= norm.y; + g10 *= norm.z; + g11 *= norm.w; + + T n00 = dot(g00, detail::tvec2(fx.x, fy.x)); + T n10 = dot(g10, detail::tvec2(fx.y, fy.y)); + T n01 = dot(g01, detail::tvec2(fx.z, fy.z)); + T n11 = dot(g11, detail::tvec2(fx.w, fy.w)); + + detail::tvec2 fade_xy = fade(detail::tvec2(Pf.x, Pf.y)); + detail::tvec2 n_x = mix(detail::tvec2(n00, n01), detail::tvec2(n10, n11), fade_xy.x); + T n_xy = mix(n_x.x, n_x.y, fade_xy.y); + return T(2.3) * n_xy; +} + +// Classic Perlin noise, periodic variant +template +GLM_FUNC_QUALIFIER T perlin(detail::tvec3 const & P, detail::tvec3 const & rep) +{ + detail::tvec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period + detail::tvec3 Pi1 = mod(Pi0 + detail::tvec3(1.0), rep); // Integer part + 1, mod period + Pi0 = mod(Pi0, T(289)); + Pi1 = mod(Pi1, T(289)); + detail::tvec3 Pf0 = fract(P); // Fractional part for interpolation + detail::tvec3 Pf1 = Pf0 - detail::tvec3(1.0); // Fractional part - 1.0 + detail::tvec4 ix = detail::tvec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + detail::tvec4 iy = detail::tvec4(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + detail::tvec4 iz0(Pi0.z); + detail::tvec4 iz1(Pi1.z); + + detail::tvec4 ixy = permute(permute(ix) + iy); + detail::tvec4 ixy0 = permute(ixy + iz0); + detail::tvec4 ixy1 = permute(ixy + iz1); + + detail::tvec4 gx0 = ixy0 / T(7); + detail::tvec4 gy0 = fract(floor(gx0) / T(7)) - T(0.5); + gx0 = fract(gx0); + detail::tvec4 gz0 = detail::tvec4(0.5) - abs(gx0) - abs(gy0); + detail::tvec4 sz0 = step(gz0, detail::tvec4(0)); + gx0 -= sz0 * (step(0.0, gx0) - T(0.5)); + gy0 -= sz0 * (step(0.0, gy0) - T(0.5)); + + detail::tvec4 gx1 = ixy1 / T(7); + detail::tvec4 gy1 = fract(floor(gx1) / T(7)) - T(0.5); + gx1 = fract(gx1); + detail::tvec4 gz1 = detail::tvec4(0.5) - abs(gx1) - abs(gy1); + detail::tvec4 sz1 = step(gz1, detail::tvec4(0.0)); + gx1 -= sz1 * (step(0.0, gx1) - T(0.5)); + gy1 -= sz1 * (step(0.0, gy1) - T(0.5)); + + detail::tvec3 g000 = detail::tvec3(gx0.x, gy0.x, gz0.x); + detail::tvec3 g100 = detail::tvec3(gx0.y, gy0.y, gz0.y); + detail::tvec3 g010 = detail::tvec3(gx0.z, gy0.z, gz0.z); + detail::tvec3 g110 = detail::tvec3(gx0.w, gy0.w, gz0.w); + detail::tvec3 g001 = detail::tvec3(gx1.x, gy1.x, gz1.x); + detail::tvec3 g101 = detail::tvec3(gx1.y, gy1.y, gz1.y); + detail::tvec3 g011 = detail::tvec3(gx1.z, gy1.z, gz1.z); + detail::tvec3 g111 = detail::tvec3(gx1.w, gy1.w, gz1.w); + + detail::tvec4 norm0 = taylorInvSqrt(detail::tvec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + detail::tvec4 norm1 = taylorInvSqrt(detail::tvec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + T n000 = dot(g000, Pf0); + T n100 = dot(g100, detail::tvec3(Pf1.x, Pf0.y, Pf0.z)); + T n010 = dot(g010, detail::tvec3(Pf0.x, Pf1.y, Pf0.z)); + T n110 = dot(g110, detail::tvec3(Pf1.x, Pf1.y, Pf0.z)); + T n001 = dot(g001, detail::tvec3(Pf0.x, Pf0.y, Pf1.z)); + T n101 = dot(g101, detail::tvec3(Pf1.x, Pf0.y, Pf1.z)); + T n011 = dot(g011, detail::tvec3(Pf0.x, Pf1.y, Pf1.z)); + T n111 = dot(g111, Pf1); + + detail::tvec3 fade_xyz = fade(Pf0); + detail::tvec4 n_z = mix(detail::tvec4(n000, n100, n010, n110), detail::tvec4(n001, n101, n011, n111), fade_xyz.z); + detail::tvec2 n_yz = mix(detail::tvec2(n_z.x, n_z.y), detail::tvec2(n_z.z, n_z.w), fade_xyz.y); + T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return T(2.2) * n_xyz; +} + +// Classic Perlin noise, periodic version +template +GLM_FUNC_QUALIFIER T perlin(detail::tvec4 const & P, detail::tvec4 const & rep) +{ + detail::tvec4 Pi0 = mod(floor(P), rep); // Integer part modulo rep + detail::tvec4 Pi1 = mod(Pi0 + T(1), rep); // Integer part + 1 mod rep + detail::tvec4 Pf0 = fract(P); // Fractional part for interpolation + detail::tvec4 Pf1 = Pf0 - T(1); // Fractional part - 1.0 + detail::tvec4 ix = detail::tvec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + detail::tvec4 iy = detail::tvec4(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + detail::tvec4 iz0(Pi0.z); + detail::tvec4 iz1(Pi1.z); + detail::tvec4 iw0(Pi0.w); + detail::tvec4 iw1(Pi1.w); + + detail::tvec4 ixy = permute(permute(ix) + iy); + detail::tvec4 ixy0 = permute(ixy + iz0); + detail::tvec4 ixy1 = permute(ixy + iz1); + detail::tvec4 ixy00 = permute(ixy0 + iw0); + detail::tvec4 ixy01 = permute(ixy0 + iw1); + detail::tvec4 ixy10 = permute(ixy1 + iw0); + detail::tvec4 ixy11 = permute(ixy1 + iw1); + + detail::tvec4 gx00 = ixy00 / T(7); + detail::tvec4 gy00 = floor(gx00) / T(7); + detail::tvec4 gz00 = floor(gy00) / T(6); + gx00 = fract(gx00) - T(0.5); + gy00 = fract(gy00) - T(0.5); + gz00 = fract(gz00) - T(0.5); + detail::tvec4 gw00 = detail::tvec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00); + detail::tvec4 sw00 = step(gw00, detail::tvec4(0)); + gx00 -= sw00 * (step(0.0, gx00) - T(0.5)); + gy00 -= sw00 * (step(0.0, gy00) - T(0.5)); + + detail::tvec4 gx01 = ixy01 / T(7); + detail::tvec4 gy01 = floor(gx01) / T(7); + detail::tvec4 gz01 = floor(gy01) / T(6); + gx01 = fract(gx01) - T(0.5); + gy01 = fract(gy01) - T(0.5); + gz01 = fract(gz01) - T(0.5); + detail::tvec4 gw01 = detail::tvec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01); + detail::tvec4 sw01 = step(gw01, detail::tvec4(0.0)); + gx01 -= sw01 * (step(0.0, gx01) - T(0.5)); + gy01 -= sw01 * (step(0.0, gy01) - T(0.5)); + + detail::tvec4 gx10 = ixy10 / T(7); + detail::tvec4 gy10 = floor(gx10) / T(7); + detail::tvec4 gz10 = floor(gy10) / T(6); + gx10 = fract(gx10) - T(0.5); + gy10 = fract(gy10) - T(0.5); + gz10 = fract(gz10) - T(0.5); + detail::tvec4 gw10 = detail::tvec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10); + detail::tvec4 sw10 = step(gw10, detail::tvec4(0.0)); + gx10 -= sw10 * (step(0.0, gx10) - T(0.5)); + gy10 -= sw10 * (step(0.0, gy10) - T(0.5)); + + detail::tvec4 gx11 = ixy11 / T(7); + detail::tvec4 gy11 = floor(gx11) / T(7); + detail::tvec4 gz11 = floor(gy11) / T(6); + gx11 = fract(gx11) - T(0.5); + gy11 = fract(gy11) - T(0.5); + gz11 = fract(gz11) - T(0.5); + detail::tvec4 gw11 = detail::tvec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11); + detail::tvec4 sw11 = step(gw11, detail::tvec4(0.0)); + gx11 -= sw11 * (step(0.0, gx11) - T(0.5)); + gy11 -= sw11 * (step(0.0, gy11) - T(0.5)); + + detail::tvec4 g0000(gx00.x, gy00.x, gz00.x, gw00.x); + detail::tvec4 g1000(gx00.y, gy00.y, gz00.y, gw00.y); + detail::tvec4 g0100(gx00.z, gy00.z, gz00.z, gw00.z); + detail::tvec4 g1100(gx00.w, gy00.w, gz00.w, gw00.w); + detail::tvec4 g0010(gx10.x, gy10.x, gz10.x, gw10.x); + detail::tvec4 g1010(gx10.y, gy10.y, gz10.y, gw10.y); + detail::tvec4 g0110(gx10.z, gy10.z, gz10.z, gw10.z); + detail::tvec4 g1110(gx10.w, gy10.w, gz10.w, gw10.w); + detail::tvec4 g0001(gx01.x, gy01.x, gz01.x, gw01.x); + detail::tvec4 g1001(gx01.y, gy01.y, gz01.y, gw01.y); + detail::tvec4 g0101(gx01.z, gy01.z, gz01.z, gw01.z); + detail::tvec4 g1101(gx01.w, gy01.w, gz01.w, gw01.w); + detail::tvec4 g0011(gx11.x, gy11.x, gz11.x, gw11.x); + detail::tvec4 g1011(gx11.y, gy11.y, gz11.y, gw11.y); + detail::tvec4 g0111(gx11.z, gy11.z, gz11.z, gw11.z); + detail::tvec4 g1111(gx11.w, gy11.w, gz11.w, gw11.w); + + detail::tvec4 norm00 = taylorInvSqrt(detail::tvec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); + g0000 *= norm00.x; + g0100 *= norm00.y; + g1000 *= norm00.z; + g1100 *= norm00.w; + + detail::tvec4 norm01 = taylorInvSqrt(detail::tvec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); + g0001 *= norm01.x; + g0101 *= norm01.y; + g1001 *= norm01.z; + g1101 *= norm01.w; + + detail::tvec4 norm10 = taylorInvSqrt(detail::tvec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); + g0010 *= norm10.x; + g0110 *= norm10.y; + g1010 *= norm10.z; + g1110 *= norm10.w; + + detail::tvec4 norm11 = taylorInvSqrt(detail::tvec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); + g0011 *= norm11.x; + g0111 *= norm11.y; + g1011 *= norm11.z; + g1111 *= norm11.w; + + T n0000 = dot(g0000, Pf0); + T n1000 = dot(g1000, detail::tvec4(Pf1.x, Pf0.y, Pf0.z, Pf0.w)); + T n0100 = dot(g0100, detail::tvec4(Pf0.x, Pf1.y, Pf0.z, Pf0.w)); + T n1100 = dot(g1100, detail::tvec4(Pf1.x, Pf1.y, Pf0.z, Pf0.w)); + T n0010 = dot(g0010, detail::tvec4(Pf0.x, Pf0.y, Pf1.z, Pf0.w)); + T n1010 = dot(g1010, detail::tvec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); + T n0110 = dot(g0110, detail::tvec4(Pf0.x, Pf1.y, Pf1.z, Pf0.w)); + T n1110 = dot(g1110, detail::tvec4(Pf1.x, Pf1.y, Pf1.z, Pf0.w)); + T n0001 = dot(g0001, detail::tvec4(Pf0.x, Pf0.y, Pf0.z, Pf1.w)); + T n1001 = dot(g1001, detail::tvec4(Pf1.x, Pf0.y, Pf0.z, Pf1.w)); + T n0101 = dot(g0101, detail::tvec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); + T n1101 = dot(g1101, detail::tvec4(Pf1.x, Pf1.y, Pf0.z, Pf1.w)); + T n0011 = dot(g0011, detail::tvec4(Pf0.x, Pf0.y, Pf1.z, Pf1.w)); + T n1011 = dot(g1011, detail::tvec4(Pf1.x, Pf0.y, Pf1.z, Pf1.w)); + T n0111 = dot(g0111, detail::tvec4(Pf0.x, Pf1.y, Pf1.z, Pf1.w)); + T n1111 = dot(g1111, Pf1); + + detail::tvec4 fade_xyzw = fade(Pf0); + detail::tvec4 n_0w = mix(detail::tvec4(n0000, n1000, n0100, n1100), detail::tvec4(n0001, n1001, n0101, n1101), fade_xyzw.w); + detail::tvec4 n_1w = mix(detail::tvec4(n0010, n1010, n0110, n1110), detail::tvec4(n0011, n1011, n0111, n1111), fade_xyzw.w); + detail::tvec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z); + detail::tvec2 n_yzw = mix(detail::tvec2(n_zw.x, n_zw.y), detail::tvec2(n_zw.z, n_zw.w), fade_xyzw.y); + T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); + return T(2.2) * n_xyzw; +} + +template +GLM_FUNC_QUALIFIER T simplex(glm::detail::tvec2 const & v) +{ + detail::tvec4 const C = detail::tvec4( + T( 0.211324865405187), // (3.0 - sqrt(3.0)) / 6.0 + T( 0.366025403784439), // 0.5 * (sqrt(3.0) - 1.0) + T(-0.577350269189626), // -1.0 + 2.0 * C.x + T( 0.024390243902439)); // 1.0 / 41.0 + + // First corner + detail::tvec2 i = floor(v + dot(v, detail::tvec2(C[1]))); + detail::tvec2 x0 = v - i + dot(i, detail::tvec2(C[0])); + + // Other corners + //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 + //i1.y = 1.0 - i1.x; + detail::tvec2 i1 = (x0.x > x0.y) ? detail::tvec2(1, 0) : detail::tvec2(0, 1); + // x0 = x0 - 0.0 + 0.0 * C.xx ; + // x1 = x0 - i1 + 1.0 * C.xx ; + // x2 = x0 - 1.0 + 2.0 * C.xx ; + detail::tvec4 x12 = detail::tvec4(x0.x, x0.y, x0.x, x0.y) + detail::tvec4(C.x, C.x, C.z, C.z); + x12 = detail::tvec4(detail::tvec2(x12) - i1, x12.z, x12.w); + + // Permutations + i = mod(i, T(289)); // Avoid truncation effects in permutation + detail::tvec3 p = permute( + permute(i.y + detail::tvec3(T(0), i1.y, T(1))) + + i.x + detail::tvec3(T(0), i1.x, T(1))); + + detail::tvec3 m = max(T(0.5) - detail::tvec3( + dot(x0, x0), + dot(detail::tvec2(x12.x, x12.y), detail::tvec2(x12.x, x12.y)), + dot(detail::tvec2(x12.z, x12.w), detail::tvec2(x12.z, x12.w))), T(0)); + m = m * m ; + m = m * m ; + + // Gradients: 41 points uniformly over a line, mapped onto a diamond. + // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) + + detail::tvec3 x = T(2) * fract(p * C.w) - T(1); + detail::tvec3 h = abs(x) - T(0.5); + detail::tvec3 ox = floor(x + T(0.5)); + detail::tvec3 a0 = x - ox; + + // Normalise gradients implicitly by scaling m + // Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h ); + m *= T(1.79284291400159) - T(0.85373472095314) * (a0 * a0 + h * h); + + // Compute final noise value at P + detail::tvec3 g; + g.x = a0.x * x0.x + h.x * x0.y; + //g.yz = a0.yz * x12.xz + h.yz * x12.yw; + g.y = a0.y * x12.x + h.y * x12.y; + g.z = a0.z * x12.z + h.z * x12.w; + return T(130) * dot(m, g); +} + +template +GLM_FUNC_QUALIFIER T simplex(detail::tvec3 const & v) +{ + detail::tvec2 const C(1.0 / 6.0, 1.0 / 3.0); + detail::tvec4 const D(0.0, 0.5, 1.0, 2.0); + + // First corner + detail::tvec3 i(floor(v + dot(v, detail::tvec3(C.y)))); + detail::tvec3 x0(v - i + dot(i, detail::tvec3(C.x))); + + // Other corners + detail::tvec3 g(step(detail::tvec3(x0.y, x0.z, x0.x), x0)); + detail::tvec3 l(T(1) - g); + detail::tvec3 i1(min(g, detail::tvec3(l.z, l.x, l.y))); + detail::tvec3 i2(max(g, detail::tvec3(l.z, l.x, l.y))); + + // x0 = x0 - 0.0 + 0.0 * C.xxx; + // x1 = x0 - i1 + 1.0 * C.xxx; + // x2 = x0 - i2 + 2.0 * C.xxx; + // x3 = x0 - 1.0 + 3.0 * C.xxx; + detail::tvec3 x1(x0 - i1 + C.x); + detail::tvec3 x2(x0 - i2 + C.y); // 2.0*C.x = 1/3 = C.y + detail::tvec3 x3(x0 - D.y); // -1.0+3.0*C.x = -0.5 = -D.y + + // Permutations + i = mod289(i); + detail::tvec4 p(permute(permute(permute( + i.z + detail::tvec4(T(0), i1.z, i2.z, T(1))) + + i.y + detail::tvec4(T(0), i1.y, i2.y, T(1))) + + i.x + detail::tvec4(T(0), i1.x, i2.x, T(1)))); + + // Gradients: 7x7 points over a square, mapped onto an octahedron. + // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) + T n_ = T(0.142857142857); // 1.0/7.0 + detail::tvec3 ns(n_ * detail::tvec3(D.w, D.y, D.z) - detail::tvec3(D.x, D.z, D.x)); + + detail::tvec4 j(p - T(49) * floor(p * ns.z * ns.z)); // mod(p,7*7) + + detail::tvec4 x_(floor(j * ns.z)); + detail::tvec4 y_(floor(j - T(7) * x_)); // mod(j,N) + + detail::tvec4 x(x_ * ns.x + ns.y); + detail::tvec4 y(y_ * ns.x + ns.y); + detail::tvec4 h(T(1) - abs(x) - abs(y)); + + detail::tvec4 b0(x.x, x.y, y.x, y.y); + detail::tvec4 b1(x.z, x.w, y.z, y.w); + + // vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; + // vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; + detail::tvec4 s0(floor(b0) * T(2) + T(1)); + detail::tvec4 s1(floor(b1) * T(2) + T(1)); + detail::tvec4 sh(-step(h, detail::tvec4(0.0))); + + detail::tvec4 a0 = detail::tvec4(b0.x, b0.z, b0.y, b0.w) + detail::tvec4(s0.x, s0.z, s0.y, s0.w) * detail::tvec4(sh.x, sh.x, sh.y, sh.y); + detail::tvec4 a1 = detail::tvec4(b1.x, b1.z, b1.y, b1.w) + detail::tvec4(s1.x, s1.z, s1.y, s1.w) * detail::tvec4(sh.z, sh.z, sh.w, sh.w); + + detail::tvec3 p0(a0.x, a0.y, h.x); + detail::tvec3 p1(a0.z, a0.w, h.y); + detail::tvec3 p2(a1.x, a1.y, h.z); + detail::tvec3 p3(a1.z, a1.w, h.w); + + // Normalise gradients + detail::tvec4 norm = taylorInvSqrt(detail::tvec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + + // Mix final noise value + detail::tvec4 m = max(T(0.6) - detail::tvec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), T(0)); + m = m * m; + return T(42) * dot(m * m, detail::tvec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3))); +} + +template +GLM_FUNC_QUALIFIER T simplex(detail::tvec4 const & v) +{ + detail::tvec4 const C( + 0.138196601125011, // (5 - sqrt(5))/20 G4 + 0.276393202250021, // 2 * G4 + 0.414589803375032, // 3 * G4 + -0.447213595499958); // -1 + 4 * G4 + + // (sqrt(5) - 1)/4 = F4, used once below + T const F4 = T(0.309016994374947451); + + // First corner + detail::tvec4 i = floor(v + dot(v, vec4(F4))); + detail::tvec4 x0 = v - i + dot(i, vec4(C.x)); + + // Other corners + + // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) + detail::tvec4 i0; + detail::tvec3 isX = step(detail::tvec3(x0.y, x0.z, x0.w), detail::tvec3(x0.x)); + detail::tvec3 isYZ = step(detail::tvec3(x0.z, x0.w, x0.w), detail::tvec3(x0.y, x0.y, x0.z)); + // i0.x = dot(isX, vec3(1.0)); + //i0.x = isX.x + isX.y + isX.z; + //i0.yzw = T(1) - isX; + i0 = detail::tvec4(isX.x + isX.y + isX.z, T(1) - isX); + // i0.y += dot(isYZ.xy, vec2(1.0)); + i0.y += isYZ.x + isYZ.y; + //i0.zw += 1.0 - detail::tvec2(isYZ.x, isYZ.y); + i0.z += T(1) - isYZ.x; + i0.w += T(1) - isYZ.y; + i0.z += isYZ.z; + i0.w += T(1) - isYZ.z; + + // i0 now contains the unique values 0,1,2,3 in each channel + detail::tvec4 i3 = clamp(i0, 0.0, 1.0); + detail::tvec4 i2 = clamp(i0 - 1.0, 0.0, 1.0); + detail::tvec4 i1 = clamp(i0 - 2.0, 0.0, 1.0); + + // x0 = x0 - 0.0 + 0.0 * C.xxxx + // x1 = x0 - i1 + 0.0 * C.xxxx + // x2 = x0 - i2 + 0.0 * C.xxxx + // x3 = x0 - i3 + 0.0 * C.xxxx + // x4 = x0 - 1.0 + 4.0 * C.xxxx + detail::tvec4 x1 = x0 - i1 + C.x; + detail::tvec4 x2 = x0 - i2 + C.y; + detail::tvec4 x3 = x0 - i3 + C.z; + detail::tvec4 x4 = x0 + C.w; + + // Permutations + i = mod(i, T(289)); + T j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x); + detail::tvec4 j1 = permute(permute(permute(permute( + i.w + detail::tvec4(i1.w, i2.w, i3.w, T(1))) + + i.z + detail::tvec4(i1.z, i2.z, i3.z, T(1))) + + i.y + detail::tvec4(i1.y, i2.y, i3.y, T(1))) + + i.x + detail::tvec4(i1.x, i2.x, i3.x, T(1))); + + // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope + // 7*7*6 = 294, which is close to the ring size 17*17 = 289. + detail::tvec4 ip = detail::tvec4(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0)); + + detail::tvec4 p0 = grad4(j0, ip); + detail::tvec4 p1 = grad4(j1.x, ip); + detail::tvec4 p2 = grad4(j1.y, ip); + detail::tvec4 p3 = grad4(j1.z, ip); + detail::tvec4 p4 = grad4(j1.w, ip); + + // Normalise gradients + detail::tvec4 norm = taylorInvSqrt(detail::tvec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + p4 *= taylorInvSqrt(dot(p4, p4)); + + // Mix contributions from the five corners + detail::tvec3 m0 = max(T(0.6) - detail::tvec3(dot(x0, x0), dot(x1, x1), dot(x2, x2)), T(0)); + detail::tvec2 m1 = max(T(0.6) - detail::tvec2(dot(x3, x3), dot(x4, x4) ), T(0)); + m0 = m0 * m0; + m1 = m1 * m1; + return T(49) * + (dot(m0 * m0, detail::tvec3(dot(p0, x0), dot(p1, x1), dot(p2, x2))) + + dot(m1 * m1, detail::tvec2(dot(p3, x3), dot(p4, x4)))); +} + +}//namespace glm diff --git a/glm/gtx/noise.hpp b/glm/gtx/noise.hpp index 48ecac01..c417eb65 100644 --- a/glm/gtx/noise.hpp +++ b/glm/gtx/noise.hpp @@ -44,6 +44,7 @@ // Dependency: #include "../glm.hpp" +#include "../gtc/noise.hpp" #if(defined(GLM_MESSAGES) && !defined(glm_ext)) # pragma message("GLM: GLM_GTX_noise extension included") @@ -54,25 +55,6 @@ namespace glm /// @addtogroup gtx_noise /// @{ - //! Classic perlin noise. - //! From GLM_GTX_noise extension. - template class vecType> - T perlin( - vecType const & p); - - //! Periodic perlin noise. - //! From GLM_GTX_noise extension. - template class vecType> - T perlin( - vecType const & p, - vecType const & rep); - - //! Simplex noise. - //! From GLM_GTX_noise extension. - template class vecType> - T simplex( - vecType const & p); - /// @} }//namespace glm diff --git a/glm/gtx/noise.inl b/glm/gtx/noise.inl index 8bd1ef2c..389e4800 100644 --- a/glm/gtx/noise.inl +++ b/glm/gtx/noise.inl @@ -17,836 +17,4 @@ namespace glm{ -template -GLM_FUNC_QUALIFIER T mod289(T const & x) -{ - return x - floor(x * T(1.0 / 289.0)) * T(289.0); -} - -template -GLM_FUNC_QUALIFIER T permute(T const & x) -{ - return mod289(((x * T(34)) + T(1)) * x); -} - -template class vecType> -GLM_FUNC_QUALIFIER vecType permute(vecType const & x) -{ - return mod289(((x * T(34)) + T(1)) * x); -} - -template -GLM_FUNC_QUALIFIER T taylorInvSqrt(T const & r) -{ - return T(1.79284291400159) - T(0.85373472095314) * r; -} - -template class vecType> -GLM_FUNC_QUALIFIER vecType taylorInvSqrt(vecType const & r) -{ - return T(1.79284291400159) - T(0.85373472095314) * r; -} - -template class vecType> -GLM_FUNC_QUALIFIER vecType fade(vecType const & t) -{ - return t * t * t * (t * (t * T(6) - T(15)) + T(10)); -} - -template -GLM_FUNC_QUALIFIER detail::tvec4 grad4(T const & j, detail::tvec4 const & ip) -{ - detail::tvec3 pXYZ = floor(fract(detail::tvec3(j) * detail::tvec3(ip)) * T(7)) * ip[2] - T(1); - T pW = T(1.5) - dot(abs(pXYZ), detail::tvec3(1)); - detail::tvec4 s = detail::tvec4(lessThan(detail::tvec4(pXYZ, pW), detail::tvec4(0.0))); - pXYZ = pXYZ + (detail::tvec3(s) * T(2) - T(1)) * s.w; - return detail::tvec4(pXYZ, pW); -} - -// Classic Perlin noise -template -GLM_FUNC_QUALIFIER T perlin(detail::tvec2 const & P) -{ - detail::tvec4 Pi = glm::floor(detail::tvec4(P.x, P.y, P.x, P.y)) + detail::tvec4(0.0, 0.0, 1.0, 1.0); - detail::tvec4 Pf = glm::fract(detail::tvec4(P.x, P.y, P.x, P.y)) - detail::tvec4(0.0, 0.0, 1.0, 1.0); - Pi = mod(Pi, T(289)); // To avoid truncation effects in permutation - detail::tvec4 ix(Pi.x, Pi.z, Pi.x, Pi.z); - detail::tvec4 iy(Pi.y, Pi.y, Pi.w, Pi.w); - detail::tvec4 fx(Pf.x, Pf.z, Pf.x, Pf.z); - detail::tvec4 fy(Pf.y, Pf.y, Pf.w, Pf.w); - - detail::tvec4 i = glm::permute(glm::permute(ix) + iy); - - detail::tvec4 gx = T(2) * glm::fract(i / T(41)) - T(1); - detail::tvec4 gy = glm::abs(gx) - T(0.5); - detail::tvec4 tx = glm::floor(gx + T(0.5)); - gx = gx - tx; - - detail::tvec2 g00(gx.x, gy.x); - detail::tvec2 g10(gx.y, gy.y); - detail::tvec2 g01(gx.z, gy.z); - detail::tvec2 g11(gx.w, gy.w); - - detail::tvec4 norm = taylorInvSqrt(detail::tvec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); - g00 *= norm.x; - g01 *= norm.y; - g10 *= norm.z; - g11 *= norm.w; - - T n00 = dot(g00, detail::tvec2(fx.x, fy.x)); - T n10 = dot(g10, detail::tvec2(fx.y, fy.y)); - T n01 = dot(g01, detail::tvec2(fx.z, fy.z)); - T n11 = dot(g11, detail::tvec2(fx.w, fy.w)); - - detail::tvec2 fade_xy = fade(detail::tvec2(Pf.x, Pf.y)); - detail::tvec2 n_x = mix(detail::tvec2(n00, n01), detail::tvec2(n10, n11), fade_xy.x); - T n_xy = mix(n_x.x, n_x.y, fade_xy.y); - return T(2.3) * n_xy; -} - -// Classic Perlin noise -template -GLM_FUNC_QUALIFIER T perlin(detail::tvec3 const & P) -{ - detail::tvec3 Pi0 = floor(P); // Integer part for indexing - detail::tvec3 Pi1 = Pi0 + T(1); // Integer part + 1 - Pi0 = mod289(Pi0); - Pi1 = mod289(Pi1); - detail::tvec3 Pf0 = fract(P); // Fractional part for interpolation - detail::tvec3 Pf1 = Pf0 - T(1); // Fractional part - 1.0 - detail::tvec4 ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); - detail::tvec4 iy = detail::tvec4(detail::tvec2(Pi0.y), detail::tvec2(Pi1.y)); - detail::tvec4 iz0(Pi0.z); - detail::tvec4 iz1(Pi1.z); - - detail::tvec4 ixy = permute(permute(ix) + iy); - detail::tvec4 ixy0 = permute(ixy + iz0); - detail::tvec4 ixy1 = permute(ixy + iz1); - - detail::tvec4 gx0 = ixy0 * T(1.0 / 7.0); - detail::tvec4 gy0 = fract(floor(gx0) * T(1.0 / 7.0)) - T(0.5); - gx0 = fract(gx0); - detail::tvec4 gz0 = detail::tvec4(0.5) - abs(gx0) - abs(gy0); - detail::tvec4 sz0 = step(gz0, detail::tvec4(0.0)); - gx0 -= sz0 * (step(T(0), gx0) - T(0.5)); - gy0 -= sz0 * (step(T(0), gy0) - T(0.5)); - - detail::tvec4 gx1 = ixy1 * T(1.0 / 7.0); - detail::tvec4 gy1 = fract(floor(gx1) * T(1.0 / 7.0)) - T(0.5); - gx1 = fract(gx1); - detail::tvec4 gz1 = detail::tvec4(0.5) - abs(gx1) - abs(gy1); - detail::tvec4 sz1 = step(gz1, detail::tvec4(0.0)); - gx1 -= sz1 * (step(T(0), gx1) - T(0.5)); - gy1 -= sz1 * (step(T(0), gy1) - T(0.5)); - - detail::tvec3 g000(gx0.x, gy0.x, gz0.x); - detail::tvec3 g100(gx0.y, gy0.y, gz0.y); - detail::tvec3 g010(gx0.z, gy0.z, gz0.z); - detail::tvec3 g110(gx0.w, gy0.w, gz0.w); - detail::tvec3 g001(gx1.x, gy1.x, gz1.x); - detail::tvec3 g101(gx1.y, gy1.y, gz1.y); - detail::tvec3 g011(gx1.z, gy1.z, gz1.z); - detail::tvec3 g111(gx1.w, gy1.w, gz1.w); - - detail::tvec4 norm0 = taylorInvSqrt(detail::tvec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); - g000 *= norm0.x; - g010 *= norm0.y; - g100 *= norm0.z; - g110 *= norm0.w; - detail::tvec4 norm1 = taylorInvSqrt(detail::tvec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); - g001 *= norm1.x; - g011 *= norm1.y; - g101 *= norm1.z; - g111 *= norm1.w; - - T n000 = dot(g000, Pf0); - T n100 = dot(g100, detail::tvec3(Pf1.x, Pf0.y, Pf0.z)); - T n010 = dot(g010, detail::tvec3(Pf0.x, Pf1.y, Pf0.z)); - T n110 = dot(g110, detail::tvec3(Pf1.x, Pf1.y, Pf0.z)); - T n001 = dot(g001, detail::tvec3(Pf0.x, Pf0.y, Pf1.z)); - T n101 = dot(g101, detail::tvec3(Pf1.x, Pf0.y, Pf1.z)); - T n011 = dot(g011, detail::tvec3(Pf0.x, Pf1.y, Pf1.z)); - T n111 = dot(g111, Pf1); - - detail::tvec3 fade_xyz = fade(Pf0); - detail::tvec4 n_z = mix(detail::tvec4(n000, n100, n010, n110), detail::tvec4(n001, n101, n011, n111), fade_xyz.z); - detail::tvec2 n_yz = mix(detail::tvec2(n_z.x, n_z.y), detail::tvec2(n_z.z, n_z.w), fade_xyz.y); - T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); - return T(2.2) * n_xyz; -} -/* -// Classic Perlin noise -template -GLM_FUNC_QUALIFIER T perlin(detail::tvec3 const & P) -{ - detail::tvec3 Pi0 = floor(P); // Integer part for indexing - detail::tvec3 Pi1 = Pi0 + T(1); // Integer part + 1 - Pi0 = mod(Pi0, T(289)); - Pi1 = mod(Pi1, T(289)); - detail::tvec3 Pf0 = fract(P); // Fractional part for interpolation - detail::tvec3 Pf1 = Pf0 - T(1); // Fractional part - 1.0 - detail::tvec4 ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); - detail::tvec4 iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y); - detail::tvec4 iz0(Pi0.z); - detail::tvec4 iz1(Pi1.z); - - detail::tvec4 ixy = permute(permute(ix) + iy); - detail::tvec4 ixy0 = permute(ixy + iz0); - detail::tvec4 ixy1 = permute(ixy + iz1); - - detail::tvec4 gx0 = ixy0 / T(7); - detail::tvec4 gy0 = fract(floor(gx0) / T(7)) - T(0.5); - gx0 = fract(gx0); - detail::tvec4 gz0 = detail::tvec4(0.5) - abs(gx0) - abs(gy0); - detail::tvec4 sz0 = step(gz0, detail::tvec4(0.0)); - gx0 -= sz0 * (step(0.0, gx0) - T(0.5)); - gy0 -= sz0 * (step(0.0, gy0) - T(0.5)); - - detail::tvec4 gx1 = ixy1 / T(7); - detail::tvec4 gy1 = fract(floor(gx1) / T(7)) - T(0.5); - gx1 = fract(gx1); - detail::tvec4 gz1 = detail::tvec4(0.5) - abs(gx1) - abs(gy1); - detail::tvec4 sz1 = step(gz1, detail::tvec4(0.0)); - gx1 -= sz1 * (step(T(0), gx1) - T(0.5)); - gy1 -= sz1 * (step(T(0), gy1) - T(0.5)); - - detail::tvec3 g000(gx0.x, gy0.x, gz0.x); - detail::tvec3 g100(gx0.y, gy0.y, gz0.y); - detail::tvec3 g010(gx0.z, gy0.z, gz0.z); - detail::tvec3 g110(gx0.w, gy0.w, gz0.w); - detail::tvec3 g001(gx1.x, gy1.x, gz1.x); - detail::tvec3 g101(gx1.y, gy1.y, gz1.y); - detail::tvec3 g011(gx1.z, gy1.z, gz1.z); - detail::tvec3 g111(gx1.w, gy1.w, gz1.w); - - detail::tvec4 norm0 = taylorInvSqrt(detail::tvec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); - g000 *= norm0.x; - g010 *= norm0.y; - g100 *= norm0.z; - g110 *= norm0.w; - detail::tvec4 norm1 = taylorInvSqrt(detail::tvec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); - g001 *= norm1.x; - g011 *= norm1.y; - g101 *= norm1.z; - g111 *= norm1.w; - - T n000 = dot(g000, Pf0); - T n100 = dot(g100, detail::tvec3(Pf1.x, Pf0.y, Pf0.z)); - T n010 = dot(g010, detail::tvec3(Pf0.x, Pf1.y, Pf0.z)); - T n110 = dot(g110, detail::tvec3(Pf1.x, Pf1.y, Pf0.z)); - T n001 = dot(g001, detail::tvec3(Pf0.x, Pf0.y, Pf1.z)); - T n101 = dot(g101, detail::tvec3(Pf1.x, Pf0.y, Pf1.z)); - T n011 = dot(g011, detail::tvec3(Pf0.x, Pf1.y, Pf1.z)); - T n111 = dot(g111, Pf1); - - detail::tvec3 fade_xyz = fade(Pf0); - detail::tvec4 n_z = mix(detail::tvec4(n000, n100, n010, n110), detail::tvec4(n001, n101, n011, n111), fade_xyz.z); - detail::tvec2 n_yz = mix( - detail::tvec2(n_z.x, n_z.y), - detail::tvec2(n_z.z, n_z.w), fade_xyz.y); - T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); - return T(2.2) * n_xyz; -} -*/ -// Classic Perlin noise -template -GLM_FUNC_QUALIFIER T perlin(detail::tvec4 const & P) -{ - detail::tvec4 Pi0 = floor(P); // Integer part for indexing - detail::tvec4 Pi1 = Pi0 + T(1); // Integer part + 1 - Pi0 = mod(Pi0, T(289)); - Pi1 = mod(Pi1, T(289)); - detail::tvec4 Pf0 = fract(P); // Fractional part for interpolation - detail::tvec4 Pf1 = Pf0 - T(1); // Fractional part - 1.0 - detail::tvec4 ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); - detail::tvec4 iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y); - detail::tvec4 iz0(Pi0.z); - detail::tvec4 iz1(Pi1.z); - detail::tvec4 iw0(Pi0.w); - detail::tvec4 iw1(Pi1.w); - - detail::tvec4 ixy = permute(permute(ix) + iy); - detail::tvec4 ixy0 = permute(ixy + iz0); - detail::tvec4 ixy1 = permute(ixy + iz1); - detail::tvec4 ixy00 = permute(ixy0 + iw0); - detail::tvec4 ixy01 = permute(ixy0 + iw1); - detail::tvec4 ixy10 = permute(ixy1 + iw0); - detail::tvec4 ixy11 = permute(ixy1 + iw1); - - detail::tvec4 gx00 = ixy00 / T(7); - detail::tvec4 gy00 = floor(gx00) / T(7); - detail::tvec4 gz00 = floor(gy00) / T(6); - gx00 = fract(gx00) - T(0.5); - gy00 = fract(gy00) - T(0.5); - gz00 = fract(gz00) - T(0.5); - detail::tvec4 gw00 = detail::tvec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00); - detail::tvec4 sw00 = step(gw00, detail::tvec4(0.0)); - gx00 -= sw00 * (step(T(0), gx00) - T(0.5)); - gy00 -= sw00 * (step(T(0), gy00) - T(0.5)); - - detail::tvec4 gx01 = ixy01 / T(7); - detail::tvec4 gy01 = floor(gx01) / T(7); - detail::tvec4 gz01 = floor(gy01) / T(6); - gx01 = fract(gx01) - T(0.5); - gy01 = fract(gy01) - T(0.5); - gz01 = fract(gz01) - T(0.5); - detail::tvec4 gw01 = detail::tvec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01); - detail::tvec4 sw01 = step(gw01, detail::tvec4(0.0)); - gx01 -= sw01 * (step(T(0), gx01) - T(0.5)); - gy01 -= sw01 * (step(T(0), gy01) - T(0.5)); - - detail::tvec4 gx10 = ixy10 / T(7); - detail::tvec4 gy10 = floor(gx10) / T(7); - detail::tvec4 gz10 = floor(gy10) / T(6); - gx10 = fract(gx10) - T(0.5); - gy10 = fract(gy10) - T(0.5); - gz10 = fract(gz10) - T(0.5); - detail::tvec4 gw10 = detail::tvec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10); - detail::tvec4 sw10 = step(gw10, detail::tvec4(0)); - gx10 -= sw10 * (step(T(0), gx10) - T(0.5)); - gy10 -= sw10 * (step(T(0), gy10) - T(0.5)); - - detail::tvec4 gx11 = ixy11 / T(7); - detail::tvec4 gy11 = floor(gx11) / T(7); - detail::tvec4 gz11 = floor(gy11) / T(6); - gx11 = fract(gx11) - T(0.5); - gy11 = fract(gy11) - T(0.5); - gz11 = fract(gz11) - T(0.5); - detail::tvec4 gw11 = detail::tvec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11); - detail::tvec4 sw11 = step(gw11, detail::tvec4(0.0)); - gx11 -= sw11 * (step(T(0), gx11) - T(0.5)); - gy11 -= sw11 * (step(T(0), gy11) - T(0.5)); - - detail::tvec4 g0000(gx00.x, gy00.x, gz00.x, gw00.x); - detail::tvec4 g1000(gx00.y, gy00.y, gz00.y, gw00.y); - detail::tvec4 g0100(gx00.z, gy00.z, gz00.z, gw00.z); - detail::tvec4 g1100(gx00.w, gy00.w, gz00.w, gw00.w); - detail::tvec4 g0010(gx10.x, gy10.x, gz10.x, gw10.x); - detail::tvec4 g1010(gx10.y, gy10.y, gz10.y, gw10.y); - detail::tvec4 g0110(gx10.z, gy10.z, gz10.z, gw10.z); - detail::tvec4 g1110(gx10.w, gy10.w, gz10.w, gw10.w); - detail::tvec4 g0001(gx01.x, gy01.x, gz01.x, gw01.x); - detail::tvec4 g1001(gx01.y, gy01.y, gz01.y, gw01.y); - detail::tvec4 g0101(gx01.z, gy01.z, gz01.z, gw01.z); - detail::tvec4 g1101(gx01.w, gy01.w, gz01.w, gw01.w); - detail::tvec4 g0011(gx11.x, gy11.x, gz11.x, gw11.x); - detail::tvec4 g1011(gx11.y, gy11.y, gz11.y, gw11.y); - detail::tvec4 g0111(gx11.z, gy11.z, gz11.z, gw11.z); - detail::tvec4 g1111(gx11.w, gy11.w, gz11.w, gw11.w); - - detail::tvec4 norm00 = taylorInvSqrt(detail::tvec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); - g0000 *= norm00.x; - g0100 *= norm00.y; - g1000 *= norm00.z; - g1100 *= norm00.w; - - detail::tvec4 norm01 = taylorInvSqrt(detail::tvec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); - g0001 *= norm01.x; - g0101 *= norm01.y; - g1001 *= norm01.z; - g1101 *= norm01.w; - - detail::tvec4 norm10 = taylorInvSqrt(detail::tvec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); - g0010 *= norm10.x; - g0110 *= norm10.y; - g1010 *= norm10.z; - g1110 *= norm10.w; - - detail::tvec4 norm11 = taylorInvSqrt(detail::tvec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); - g0011 *= norm11.x; - g0111 *= norm11.y; - g1011 *= norm11.z; - g1111 *= norm11.w; - - T n0000 = dot(g0000, Pf0); - T n1000 = dot(g1000, detail::tvec4(Pf1.x, Pf0.y, Pf0.z, Pf0.w)); - T n0100 = dot(g0100, detail::tvec4(Pf0.x, Pf1.y, Pf0.z, Pf0.w)); - T n1100 = dot(g1100, detail::tvec4(Pf1.x, Pf1.y, Pf0.z, Pf0.w)); - T n0010 = dot(g0010, detail::tvec4(Pf0.x, Pf0.y, Pf1.z, Pf0.w)); - T n1010 = dot(g1010, detail::tvec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); - T n0110 = dot(g0110, detail::tvec4(Pf0.x, Pf1.y, Pf1.z, Pf0.w)); - T n1110 = dot(g1110, detail::tvec4(Pf1.x, Pf1.y, Pf1.z, Pf0.w)); - T n0001 = dot(g0001, detail::tvec4(Pf0.x, Pf0.y, Pf0.z, Pf1.w)); - T n1001 = dot(g1001, detail::tvec4(Pf1.x, Pf0.y, Pf0.z, Pf1.w)); - T n0101 = dot(g0101, detail::tvec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); - T n1101 = dot(g1101, detail::tvec4(Pf1.x, Pf1.y, Pf0.z, Pf1.w)); - T n0011 = dot(g0011, detail::tvec4(Pf0.x, Pf0.y, Pf1.z, Pf1.w)); - T n1011 = dot(g1011, detail::tvec4(Pf1.x, Pf0.y, Pf1.z, Pf1.w)); - T n0111 = dot(g0111, detail::tvec4(Pf0.x, Pf1.y, Pf1.z, Pf1.w)); - T n1111 = dot(g1111, Pf1); - - detail::tvec4 fade_xyzw = fade(Pf0); - detail::tvec4 n_0w = mix(detail::tvec4(n0000, n1000, n0100, n1100), detail::tvec4(n0001, n1001, n0101, n1101), fade_xyzw.w); - detail::tvec4 n_1w = mix(detail::tvec4(n0010, n1010, n0110, n1110), detail::tvec4(n0011, n1011, n0111, n1111), fade_xyzw.w); - detail::tvec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z); - detail::tvec2 n_yzw = mix(detail::tvec2(n_zw.x, n_zw.y), detail::tvec2(n_zw.z, n_zw.w), fade_xyzw.y); - T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); - return T(2.2) * n_xyzw; -} - -// Classic Perlin noise, periodic variant -template -GLM_FUNC_QUALIFIER T perlin(detail::tvec2 const & P, detail::tvec2 const & rep) -{ - detail::tvec4 Pi = floor(detail::tvec4(P.x, P.y, P.x, P.y)) + detail::tvec4(0.0, 0.0, 1.0, 1.0); - detail::tvec4 Pf = fract(detail::tvec4(P.x, P.y, P.x, P.y)) - detail::tvec4(0.0, 0.0, 1.0, 1.0); - Pi = mod(Pi, detail::tvec4(rep.x, rep.y, rep.x, rep.y)); // To create noise with explicit period - Pi = mod(Pi, T(289)); // To avoid truncation effects in permutation - detail::tvec4 ix(Pi.x, Pi.z, Pi.x, Pi.z); - detail::tvec4 iy(Pi.y, Pi.y, Pi.w, Pi.w); - detail::tvec4 fx(Pf.x, Pf.z, Pf.x, Pf.z); - detail::tvec4 fy(Pf.y, Pf.y, Pf.w, Pf.w); - - detail::tvec4 i = permute(permute(ix) + iy); - - detail::tvec4 gx = T(2) * fract(i / T(41)) - T(1); - detail::tvec4 gy = abs(gx) - T(0.5); - detail::tvec4 tx = floor(gx + T(0.5)); - gx = gx - tx; - - detail::tvec2 g00(gx.x, gy.x); - detail::tvec2 g10(gx.y, gy.y); - detail::tvec2 g01(gx.z, gy.z); - detail::tvec2 g11(gx.w, gy.w); - - detail::tvec4 norm = taylorInvSqrt(detail::tvec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); - g00 *= norm.x; - g01 *= norm.y; - g10 *= norm.z; - g11 *= norm.w; - - T n00 = dot(g00, detail::tvec2(fx.x, fy.x)); - T n10 = dot(g10, detail::tvec2(fx.y, fy.y)); - T n01 = dot(g01, detail::tvec2(fx.z, fy.z)); - T n11 = dot(g11, detail::tvec2(fx.w, fy.w)); - - detail::tvec2 fade_xy = fade(detail::tvec2(Pf.x, Pf.y)); - detail::tvec2 n_x = mix(detail::tvec2(n00, n01), detail::tvec2(n10, n11), fade_xy.x); - T n_xy = mix(n_x.x, n_x.y, fade_xy.y); - return T(2.3) * n_xy; -} - -// Classic Perlin noise, periodic variant -template -GLM_FUNC_QUALIFIER T perlin(detail::tvec3 const & P, detail::tvec3 const & rep) -{ - detail::tvec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period - detail::tvec3 Pi1 = mod(Pi0 + detail::tvec3(1.0), rep); // Integer part + 1, mod period - Pi0 = mod(Pi0, T(289)); - Pi1 = mod(Pi1, T(289)); - detail::tvec3 Pf0 = fract(P); // Fractional part for interpolation - detail::tvec3 Pf1 = Pf0 - detail::tvec3(1.0); // Fractional part - 1.0 - detail::tvec4 ix = detail::tvec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); - detail::tvec4 iy = detail::tvec4(Pi0.y, Pi0.y, Pi1.y, Pi1.y); - detail::tvec4 iz0(Pi0.z); - detail::tvec4 iz1(Pi1.z); - - detail::tvec4 ixy = permute(permute(ix) + iy); - detail::tvec4 ixy0 = permute(ixy + iz0); - detail::tvec4 ixy1 = permute(ixy + iz1); - - detail::tvec4 gx0 = ixy0 / T(7); - detail::tvec4 gy0 = fract(floor(gx0) / T(7)) - T(0.5); - gx0 = fract(gx0); - detail::tvec4 gz0 = detail::tvec4(0.5) - abs(gx0) - abs(gy0); - detail::tvec4 sz0 = step(gz0, detail::tvec4(0)); - gx0 -= sz0 * (step(0.0, gx0) - T(0.5)); - gy0 -= sz0 * (step(0.0, gy0) - T(0.5)); - - detail::tvec4 gx1 = ixy1 / T(7); - detail::tvec4 gy1 = fract(floor(gx1) / T(7)) - T(0.5); - gx1 = fract(gx1); - detail::tvec4 gz1 = detail::tvec4(0.5) - abs(gx1) - abs(gy1); - detail::tvec4 sz1 = step(gz1, detail::tvec4(0.0)); - gx1 -= sz1 * (step(0.0, gx1) - T(0.5)); - gy1 -= sz1 * (step(0.0, gy1) - T(0.5)); - - detail::tvec3 g000 = detail::tvec3(gx0.x, gy0.x, gz0.x); - detail::tvec3 g100 = detail::tvec3(gx0.y, gy0.y, gz0.y); - detail::tvec3 g010 = detail::tvec3(gx0.z, gy0.z, gz0.z); - detail::tvec3 g110 = detail::tvec3(gx0.w, gy0.w, gz0.w); - detail::tvec3 g001 = detail::tvec3(gx1.x, gy1.x, gz1.x); - detail::tvec3 g101 = detail::tvec3(gx1.y, gy1.y, gz1.y); - detail::tvec3 g011 = detail::tvec3(gx1.z, gy1.z, gz1.z); - detail::tvec3 g111 = detail::tvec3(gx1.w, gy1.w, gz1.w); - - detail::tvec4 norm0 = taylorInvSqrt(detail::tvec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); - g000 *= norm0.x; - g010 *= norm0.y; - g100 *= norm0.z; - g110 *= norm0.w; - detail::tvec4 norm1 = taylorInvSqrt(detail::tvec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); - g001 *= norm1.x; - g011 *= norm1.y; - g101 *= norm1.z; - g111 *= norm1.w; - - T n000 = dot(g000, Pf0); - T n100 = dot(g100, detail::tvec3(Pf1.x, Pf0.y, Pf0.z)); - T n010 = dot(g010, detail::tvec3(Pf0.x, Pf1.y, Pf0.z)); - T n110 = dot(g110, detail::tvec3(Pf1.x, Pf1.y, Pf0.z)); - T n001 = dot(g001, detail::tvec3(Pf0.x, Pf0.y, Pf1.z)); - T n101 = dot(g101, detail::tvec3(Pf1.x, Pf0.y, Pf1.z)); - T n011 = dot(g011, detail::tvec3(Pf0.x, Pf1.y, Pf1.z)); - T n111 = dot(g111, Pf1); - - detail::tvec3 fade_xyz = fade(Pf0); - detail::tvec4 n_z = mix(detail::tvec4(n000, n100, n010, n110), detail::tvec4(n001, n101, n011, n111), fade_xyz.z); - detail::tvec2 n_yz = mix(detail::tvec2(n_z.x, n_z.y), detail::tvec2(n_z.z, n_z.w), fade_xyz.y); - T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); - return T(2.2) * n_xyz; -} - -// Classic Perlin noise, periodic version -template -GLM_FUNC_QUALIFIER T perlin(detail::tvec4 const & P, detail::tvec4 const & rep) -{ - detail::tvec4 Pi0 = mod(floor(P), rep); // Integer part modulo rep - detail::tvec4 Pi1 = mod(Pi0 + T(1), rep); // Integer part + 1 mod rep - detail::tvec4 Pf0 = fract(P); // Fractional part for interpolation - detail::tvec4 Pf1 = Pf0 - T(1); // Fractional part - 1.0 - detail::tvec4 ix = detail::tvec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); - detail::tvec4 iy = detail::tvec4(Pi0.y, Pi0.y, Pi1.y, Pi1.y); - detail::tvec4 iz0(Pi0.z); - detail::tvec4 iz1(Pi1.z); - detail::tvec4 iw0(Pi0.w); - detail::tvec4 iw1(Pi1.w); - - detail::tvec4 ixy = permute(permute(ix) + iy); - detail::tvec4 ixy0 = permute(ixy + iz0); - detail::tvec4 ixy1 = permute(ixy + iz1); - detail::tvec4 ixy00 = permute(ixy0 + iw0); - detail::tvec4 ixy01 = permute(ixy0 + iw1); - detail::tvec4 ixy10 = permute(ixy1 + iw0); - detail::tvec4 ixy11 = permute(ixy1 + iw1); - - detail::tvec4 gx00 = ixy00 / T(7); - detail::tvec4 gy00 = floor(gx00) / T(7); - detail::tvec4 gz00 = floor(gy00) / T(6); - gx00 = fract(gx00) - T(0.5); - gy00 = fract(gy00) - T(0.5); - gz00 = fract(gz00) - T(0.5); - detail::tvec4 gw00 = detail::tvec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00); - detail::tvec4 sw00 = step(gw00, detail::tvec4(0)); - gx00 -= sw00 * (step(0.0, gx00) - T(0.5)); - gy00 -= sw00 * (step(0.0, gy00) - T(0.5)); - - detail::tvec4 gx01 = ixy01 / T(7); - detail::tvec4 gy01 = floor(gx01) / T(7); - detail::tvec4 gz01 = floor(gy01) / T(6); - gx01 = fract(gx01) - T(0.5); - gy01 = fract(gy01) - T(0.5); - gz01 = fract(gz01) - T(0.5); - detail::tvec4 gw01 = detail::tvec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01); - detail::tvec4 sw01 = step(gw01, detail::tvec4(0.0)); - gx01 -= sw01 * (step(0.0, gx01) - T(0.5)); - gy01 -= sw01 * (step(0.0, gy01) - T(0.5)); - - detail::tvec4 gx10 = ixy10 / T(7); - detail::tvec4 gy10 = floor(gx10) / T(7); - detail::tvec4 gz10 = floor(gy10) / T(6); - gx10 = fract(gx10) - T(0.5); - gy10 = fract(gy10) - T(0.5); - gz10 = fract(gz10) - T(0.5); - detail::tvec4 gw10 = detail::tvec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10); - detail::tvec4 sw10 = step(gw10, detail::tvec4(0.0)); - gx10 -= sw10 * (step(0.0, gx10) - T(0.5)); - gy10 -= sw10 * (step(0.0, gy10) - T(0.5)); - - detail::tvec4 gx11 = ixy11 / T(7); - detail::tvec4 gy11 = floor(gx11) / T(7); - detail::tvec4 gz11 = floor(gy11) / T(6); - gx11 = fract(gx11) - T(0.5); - gy11 = fract(gy11) - T(0.5); - gz11 = fract(gz11) - T(0.5); - detail::tvec4 gw11 = detail::tvec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11); - detail::tvec4 sw11 = step(gw11, detail::tvec4(0.0)); - gx11 -= sw11 * (step(0.0, gx11) - T(0.5)); - gy11 -= sw11 * (step(0.0, gy11) - T(0.5)); - - detail::tvec4 g0000(gx00.x, gy00.x, gz00.x, gw00.x); - detail::tvec4 g1000(gx00.y, gy00.y, gz00.y, gw00.y); - detail::tvec4 g0100(gx00.z, gy00.z, gz00.z, gw00.z); - detail::tvec4 g1100(gx00.w, gy00.w, gz00.w, gw00.w); - detail::tvec4 g0010(gx10.x, gy10.x, gz10.x, gw10.x); - detail::tvec4 g1010(gx10.y, gy10.y, gz10.y, gw10.y); - detail::tvec4 g0110(gx10.z, gy10.z, gz10.z, gw10.z); - detail::tvec4 g1110(gx10.w, gy10.w, gz10.w, gw10.w); - detail::tvec4 g0001(gx01.x, gy01.x, gz01.x, gw01.x); - detail::tvec4 g1001(gx01.y, gy01.y, gz01.y, gw01.y); - detail::tvec4 g0101(gx01.z, gy01.z, gz01.z, gw01.z); - detail::tvec4 g1101(gx01.w, gy01.w, gz01.w, gw01.w); - detail::tvec4 g0011(gx11.x, gy11.x, gz11.x, gw11.x); - detail::tvec4 g1011(gx11.y, gy11.y, gz11.y, gw11.y); - detail::tvec4 g0111(gx11.z, gy11.z, gz11.z, gw11.z); - detail::tvec4 g1111(gx11.w, gy11.w, gz11.w, gw11.w); - - detail::tvec4 norm00 = taylorInvSqrt(detail::tvec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); - g0000 *= norm00.x; - g0100 *= norm00.y; - g1000 *= norm00.z; - g1100 *= norm00.w; - - detail::tvec4 norm01 = taylorInvSqrt(detail::tvec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); - g0001 *= norm01.x; - g0101 *= norm01.y; - g1001 *= norm01.z; - g1101 *= norm01.w; - - detail::tvec4 norm10 = taylorInvSqrt(detail::tvec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); - g0010 *= norm10.x; - g0110 *= norm10.y; - g1010 *= norm10.z; - g1110 *= norm10.w; - - detail::tvec4 norm11 = taylorInvSqrt(detail::tvec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); - g0011 *= norm11.x; - g0111 *= norm11.y; - g1011 *= norm11.z; - g1111 *= norm11.w; - - T n0000 = dot(g0000, Pf0); - T n1000 = dot(g1000, detail::tvec4(Pf1.x, Pf0.y, Pf0.z, Pf0.w)); - T n0100 = dot(g0100, detail::tvec4(Pf0.x, Pf1.y, Pf0.z, Pf0.w)); - T n1100 = dot(g1100, detail::tvec4(Pf1.x, Pf1.y, Pf0.z, Pf0.w)); - T n0010 = dot(g0010, detail::tvec4(Pf0.x, Pf0.y, Pf1.z, Pf0.w)); - T n1010 = dot(g1010, detail::tvec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); - T n0110 = dot(g0110, detail::tvec4(Pf0.x, Pf1.y, Pf1.z, Pf0.w)); - T n1110 = dot(g1110, detail::tvec4(Pf1.x, Pf1.y, Pf1.z, Pf0.w)); - T n0001 = dot(g0001, detail::tvec4(Pf0.x, Pf0.y, Pf0.z, Pf1.w)); - T n1001 = dot(g1001, detail::tvec4(Pf1.x, Pf0.y, Pf0.z, Pf1.w)); - T n0101 = dot(g0101, detail::tvec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); - T n1101 = dot(g1101, detail::tvec4(Pf1.x, Pf1.y, Pf0.z, Pf1.w)); - T n0011 = dot(g0011, detail::tvec4(Pf0.x, Pf0.y, Pf1.z, Pf1.w)); - T n1011 = dot(g1011, detail::tvec4(Pf1.x, Pf0.y, Pf1.z, Pf1.w)); - T n0111 = dot(g0111, detail::tvec4(Pf0.x, Pf1.y, Pf1.z, Pf1.w)); - T n1111 = dot(g1111, Pf1); - - detail::tvec4 fade_xyzw = fade(Pf0); - detail::tvec4 n_0w = mix(detail::tvec4(n0000, n1000, n0100, n1100), detail::tvec4(n0001, n1001, n0101, n1101), fade_xyzw.w); - detail::tvec4 n_1w = mix(detail::tvec4(n0010, n1010, n0110, n1110), detail::tvec4(n0011, n1011, n0111, n1111), fade_xyzw.w); - detail::tvec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z); - detail::tvec2 n_yzw = mix(detail::tvec2(n_zw.x, n_zw.y), detail::tvec2(n_zw.z, n_zw.w), fade_xyzw.y); - T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); - return T(2.2) * n_xyzw; -} - -template -GLM_FUNC_QUALIFIER T simplex(glm::detail::tvec2 const & v) -{ - detail::tvec4 const C = detail::tvec4( - T( 0.211324865405187), // (3.0 - sqrt(3.0)) / 6.0 - T( 0.366025403784439), // 0.5 * (sqrt(3.0) - 1.0) - T(-0.577350269189626), // -1.0 + 2.0 * C.x - T( 0.024390243902439)); // 1.0 / 41.0 - - // First corner - detail::tvec2 i = floor(v + dot(v, detail::tvec2(C[1]))); - detail::tvec2 x0 = v - i + dot(i, detail::tvec2(C[0])); - - // Other corners - //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 - //i1.y = 1.0 - i1.x; - detail::tvec2 i1 = (x0.x > x0.y) ? detail::tvec2(1, 0) : detail::tvec2(0, 1); - // x0 = x0 - 0.0 + 0.0 * C.xx ; - // x1 = x0 - i1 + 1.0 * C.xx ; - // x2 = x0 - 1.0 + 2.0 * C.xx ; - detail::tvec4 x12 = detail::tvec4(x0.x, x0.y, x0.x, x0.y) + detail::tvec4(C.x, C.x, C.z, C.z); - x12 = detail::tvec4(detail::tvec2(x12) - i1, x12.z, x12.w); - - // Permutations - i = mod(i, T(289)); // Avoid truncation effects in permutation - detail::tvec3 p = permute( - permute(i.y + detail::tvec3(T(0), i1.y, T(1))) - + i.x + detail::tvec3(T(0), i1.x, T(1))); - - detail::tvec3 m = max(T(0.5) - detail::tvec3( - dot(x0, x0), - dot(detail::tvec2(x12.x, x12.y), detail::tvec2(x12.x, x12.y)), - dot(detail::tvec2(x12.z, x12.w), detail::tvec2(x12.z, x12.w))), T(0)); - m = m * m ; - m = m * m ; - - // Gradients: 41 points uniformly over a line, mapped onto a diamond. - // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) - - detail::tvec3 x = T(2) * fract(p * C.w) - T(1); - detail::tvec3 h = abs(x) - T(0.5); - detail::tvec3 ox = floor(x + T(0.5)); - detail::tvec3 a0 = x - ox; - - // Normalise gradients implicitly by scaling m - // Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h ); - m *= T(1.79284291400159) - T(0.85373472095314) * (a0 * a0 + h * h); - - // Compute final noise value at P - detail::tvec3 g; - g.x = a0.x * x0.x + h.x * x0.y; - //g.yz = a0.yz * x12.xz + h.yz * x12.yw; - g.y = a0.y * x12.x + h.y * x12.y; - g.z = a0.z * x12.z + h.z * x12.w; - return T(130) * dot(m, g); -} - -template -GLM_FUNC_QUALIFIER T simplex(detail::tvec3 const & v) -{ - detail::tvec2 const C(1.0 / 6.0, 1.0 / 3.0); - detail::tvec4 const D(0.0, 0.5, 1.0, 2.0); - - // First corner - detail::tvec3 i(floor(v + dot(v, detail::tvec3(C.y)))); - detail::tvec3 x0(v - i + dot(i, detail::tvec3(C.x))); - - // Other corners - detail::tvec3 g(step(detail::tvec3(x0.y, x0.z, x0.x), x0)); - detail::tvec3 l(T(1) - g); - detail::tvec3 i1(min(g, detail::tvec3(l.z, l.x, l.y))); - detail::tvec3 i2(max(g, detail::tvec3(l.z, l.x, l.y))); - - // x0 = x0 - 0.0 + 0.0 * C.xxx; - // x1 = x0 - i1 + 1.0 * C.xxx; - // x2 = x0 - i2 + 2.0 * C.xxx; - // x3 = x0 - 1.0 + 3.0 * C.xxx; - detail::tvec3 x1(x0 - i1 + C.x); - detail::tvec3 x2(x0 - i2 + C.y); // 2.0*C.x = 1/3 = C.y - detail::tvec3 x3(x0 - D.y); // -1.0+3.0*C.x = -0.5 = -D.y - - // Permutations - i = mod289(i); - detail::tvec4 p(permute(permute(permute( - i.z + detail::tvec4(T(0), i1.z, i2.z, T(1))) + - i.y + detail::tvec4(T(0), i1.y, i2.y, T(1))) + - i.x + detail::tvec4(T(0), i1.x, i2.x, T(1)))); - - // Gradients: 7x7 points over a square, mapped onto an octahedron. - // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) - T n_ = T(0.142857142857); // 1.0/7.0 - detail::tvec3 ns(n_ * detail::tvec3(D.w, D.y, D.z) - detail::tvec3(D.x, D.z, D.x)); - - detail::tvec4 j(p - T(49) * floor(p * ns.z * ns.z)); // mod(p,7*7) - - detail::tvec4 x_(floor(j * ns.z)); - detail::tvec4 y_(floor(j - T(7) * x_)); // mod(j,N) - - detail::tvec4 x(x_ * ns.x + ns.y); - detail::tvec4 y(y_ * ns.x + ns.y); - detail::tvec4 h(T(1) - abs(x) - abs(y)); - - detail::tvec4 b0(x.x, x.y, y.x, y.y); - detail::tvec4 b1(x.z, x.w, y.z, y.w); - - // vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; - // vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; - detail::tvec4 s0(floor(b0) * T(2) + T(1)); - detail::tvec4 s1(floor(b1) * T(2) + T(1)); - detail::tvec4 sh(-step(h, detail::tvec4(0.0))); - - detail::tvec4 a0 = detail::tvec4(b0.x, b0.z, b0.y, b0.w) + detail::tvec4(s0.x, s0.z, s0.y, s0.w) * detail::tvec4(sh.x, sh.x, sh.y, sh.y); - detail::tvec4 a1 = detail::tvec4(b1.x, b1.z, b1.y, b1.w) + detail::tvec4(s1.x, s1.z, s1.y, s1.w) * detail::tvec4(sh.z, sh.z, sh.w, sh.w); - - detail::tvec3 p0(a0.x, a0.y, h.x); - detail::tvec3 p1(a0.z, a0.w, h.y); - detail::tvec3 p2(a1.x, a1.y, h.z); - detail::tvec3 p3(a1.z, a1.w, h.w); - - // Normalise gradients - detail::tvec4 norm = taylorInvSqrt(detail::tvec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); - p0 *= norm.x; - p1 *= norm.y; - p2 *= norm.z; - p3 *= norm.w; - - // Mix final noise value - detail::tvec4 m = max(T(0.6) - detail::tvec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), T(0)); - m = m * m; - return T(42) * dot(m * m, detail::tvec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3))); -} - -template -GLM_FUNC_QUALIFIER T simplex(detail::tvec4 const & v) -{ - detail::tvec4 const C( - 0.138196601125011, // (5 - sqrt(5))/20 G4 - 0.276393202250021, // 2 * G4 - 0.414589803375032, // 3 * G4 - -0.447213595499958); // -1 + 4 * G4 - - // (sqrt(5) - 1)/4 = F4, used once below - T const F4 = T(0.309016994374947451); - - // First corner - detail::tvec4 i = floor(v + dot(v, vec4(F4))); - detail::tvec4 x0 = v - i + dot(i, vec4(C.x)); - - // Other corners - - // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) - detail::tvec4 i0; - detail::tvec3 isX = step(detail::tvec3(x0.y, x0.z, x0.w), detail::tvec3(x0.x)); - detail::tvec3 isYZ = step(detail::tvec3(x0.z, x0.w, x0.w), detail::tvec3(x0.y, x0.y, x0.z)); - // i0.x = dot(isX, vec3(1.0)); - //i0.x = isX.x + isX.y + isX.z; - //i0.yzw = T(1) - isX; - i0 = detail::tvec4(isX.x + isX.y + isX.z, T(1) - isX); - // i0.y += dot(isYZ.xy, vec2(1.0)); - i0.y += isYZ.x + isYZ.y; - //i0.zw += 1.0 - detail::tvec2(isYZ.x, isYZ.y); - i0.z += T(1) - isYZ.x; - i0.w += T(1) - isYZ.y; - i0.z += isYZ.z; - i0.w += T(1) - isYZ.z; - - // i0 now contains the unique values 0,1,2,3 in each channel - detail::tvec4 i3 = clamp(i0, 0.0, 1.0); - detail::tvec4 i2 = clamp(i0 - 1.0, 0.0, 1.0); - detail::tvec4 i1 = clamp(i0 - 2.0, 0.0, 1.0); - - // x0 = x0 - 0.0 + 0.0 * C.xxxx - // x1 = x0 - i1 + 0.0 * C.xxxx - // x2 = x0 - i2 + 0.0 * C.xxxx - // x3 = x0 - i3 + 0.0 * C.xxxx - // x4 = x0 - 1.0 + 4.0 * C.xxxx - detail::tvec4 x1 = x0 - i1 + C.x; - detail::tvec4 x2 = x0 - i2 + C.y; - detail::tvec4 x3 = x0 - i3 + C.z; - detail::tvec4 x4 = x0 + C.w; - - // Permutations - i = mod(i, T(289)); - T j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x); - detail::tvec4 j1 = permute(permute(permute(permute( - i.w + detail::tvec4(i1.w, i2.w, i3.w, T(1))) - + i.z + detail::tvec4(i1.z, i2.z, i3.z, T(1))) - + i.y + detail::tvec4(i1.y, i2.y, i3.y, T(1))) - + i.x + detail::tvec4(i1.x, i2.x, i3.x, T(1))); - - // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope - // 7*7*6 = 294, which is close to the ring size 17*17 = 289. - detail::tvec4 ip = detail::tvec4(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0)); - - detail::tvec4 p0 = grad4(j0, ip); - detail::tvec4 p1 = grad4(j1.x, ip); - detail::tvec4 p2 = grad4(j1.y, ip); - detail::tvec4 p3 = grad4(j1.z, ip); - detail::tvec4 p4 = grad4(j1.w, ip); - - // Normalise gradients - detail::tvec4 norm = taylorInvSqrt(detail::tvec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); - p0 *= norm.x; - p1 *= norm.y; - p2 *= norm.z; - p3 *= norm.w; - p4 *= taylorInvSqrt(dot(p4, p4)); - - // Mix contributions from the five corners - detail::tvec3 m0 = max(T(0.6) - detail::tvec3(dot(x0, x0), dot(x1, x1), dot(x2, x2)), T(0)); - detail::tvec2 m1 = max(T(0.6) - detail::tvec2(dot(x3, x3), dot(x4, x4) ), T(0)); - m0 = m0 * m0; - m1 = m1 * m1; - return T(49) * - (dot(m0 * m0, detail::tvec3(dot(p0, x0), dot(p1, x1), dot(p2, x2))) + - dot(m1 * m1, detail::tvec2(dot(p3, x3), dot(p4, x4)))); -} - }//namespace glm diff --git a/test/core/core_type_vec3.cpp b/test/core/core_type_vec3.cpp index dd2cb63a..4127174b 100644 --- a/test/core/core_type_vec3.cpp +++ b/test/core/core_type_vec3.cpp @@ -8,6 +8,32 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// #include +#include + +int test_vec3_ctor() +{ + int Error = 0; + + { + glm::vec3 A(1); + glm::vec3 B(1, 1, 1); + + Error += A == B ? 0 : 1; + } + + { + std::vector Tests; + Tests.push_back(glm::vec3(glm::vec2(1, 2), 3)); + Tests.push_back(glm::vec3(1, glm::vec2(2, 3))); + Tests.push_back(glm::vec3(1, 2, 3)); + Tests.push_back(glm::vec3(glm::vec4(1, 2, 3, 4))); + + for(std::size_t i = 0; i < Tests.size(); ++i) + Error += Tests[i] == glm::vec3(1, 2, 3) ? 0 : 1; + } + + return Error; +} int test_vec3_operators() { @@ -155,6 +181,7 @@ int main() { int Error = 0; + Error += test_vec3_ctor(); Error += test_vec3_operators(); Error += test_vec3_size(); diff --git a/test/core/core_type_vec4.cpp b/test/core/core_type_vec4.cpp index fda101d3..99410fa0 100644 --- a/test/core/core_type_vec4.cpp +++ b/test/core/core_type_vec4.cpp @@ -9,6 +9,7 @@ #include #include +#include template struct mask @@ -41,6 +42,35 @@ int test_hvec4() return 0; } +int test_vec4_ctor() +{ + int Error = 0; + + { + glm::vec4 A(1); + glm::vec4 B(1, 1, 1, 1); + + Error += A == B ? 0 : 1; + } + + { + std::vector Tests; + Tests.push_back(glm::vec4(glm::vec2(1, 2), 3, 4)); + Tests.push_back(glm::vec4(1, glm::vec2(2, 3), 4)); + Tests.push_back(glm::vec4(1, 2, glm::vec2(3, 4))); + Tests.push_back(glm::vec4(glm::vec3(1, 2, 3), 4)); + Tests.push_back(glm::vec4(1, glm::vec3(2, 3, 4))); + Tests.push_back(glm::vec4(glm::vec2(1, 2), glm::vec2(3, 4))); + Tests.push_back(glm::vec4(1, 2, 3, 4)); + Tests.push_back(glm::vec4(glm::vec4(1, 2, 3, 4))); + + for(std::size_t i = 0; i < Tests.size(); ++i) + Error += Tests[i] == glm::vec4(1, 2, 3, 4) ? 0 : 1; + } + + return Error; +} + int test_vec4_operators() { int Error = 0; @@ -189,6 +219,7 @@ int main() //__m128 DataB = swizzle(glm::vec4(1.0f, 2.0f, 3.0f, 4.0f)); int Error = 0; + Error += test_vec4_ctor(); Error += test_vec4_size(); Error += test_vec4_operators(); Error += test_hvec4(); diff --git a/test/gtc/CMakeLists.txt b/test/gtc/CMakeLists.txt index 9bbfea59..dbb92d83 100644 --- a/test/gtc/CMakeLists.txt +++ b/test/gtc/CMakeLists.txt @@ -3,6 +3,7 @@ glmCreateTestGTC(gtc_matrix_access) glmCreateTestGTC(gtc_matrix_integer) glmCreateTestGTC(gtc_matrix_inverse) glmCreateTestGTC(gtc_matrix_transform) +glmCreateTestGTC(gtc_noise) glmCreateTestGTC(gtc_quaternion) glmCreateTestGTC(gtc_random) glmCreateTestGTC(gtc_swizzle) diff --git a/test/gtc/gtc_noise.cpp b/test/gtc/gtc_noise.cpp new file mode 100644 index 00000000..d82273b4 --- /dev/null +++ b/test/gtc/gtc_noise.cpp @@ -0,0 +1,199 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////// +// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net) +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Created : 2011-04-21 +// Updated : 2011-04-26 +// Licence : This source is under MIT licence +// File : test/gtx/noise.cpp +/////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +int test_simplex() +{ + std::size_t const Size = 256; + + { + std::vector ImageData(Size * Size * 3); + + for(std::size_t y = 0; y < Size; ++y) + for(std::size_t x = 0; x < Size; ++x) + { + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::simplex(glm::vec2(x / 64.f, y / 64.f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; + ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; + } + + gli::texture2D Texture(1); + Texture[0] = gli::image2D(glm::uvec2(Size), gli::RGB8U); + memcpy(Texture[0].data(), &ImageData[0], ImageData.size()); + gli::saveDDS9(Texture, "texture_simplex2d_256.dds"); + } + + { + std::vector ImageData(Size * Size * 3); + + for(std::size_t y = 0; y < Size; ++y) + for(std::size_t x = 0; x < Size; ++x) + { + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::simplex(glm::vec3(x / 64.f, y / 64.f, 0.5f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; + ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; + } + + gli::texture2D Texture(1); + Texture[0] = gli::image2D(glm::uvec2(Size), gli::RGB8U); + memcpy(Texture[0].data(), &ImageData[0], ImageData.size()); + gli::saveDDS9(Texture, "texture_simplex3d_256.dds"); + } + + { + std::vector ImageData(Size * Size * 3); + + for(std::size_t y = 0; y < Size; ++y) + for(std::size_t x = 0; x < Size; ++x) + { + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::simplex(glm::vec4(x / 64.f, y / 64.f, 0.5f, 0.5f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; + ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; + } + + gli::texture2D Texture(1); + Texture[0] = gli::image2D(glm::uvec2(Size), gli::RGB8U); + memcpy(Texture[0].data(), &ImageData[0], ImageData.size()); + gli::saveDDS9(Texture, "texture_simplex4d_256.dds"); + } + + return 0; +} + +int test_perlin() +{ + std::size_t const Size = 256; + + { + std::vector ImageData(Size * Size * 3); + + for(std::size_t y = 0; y < Size; ++y) + for(std::size_t x = 0; x < Size; ++x) + { + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec2(x / 64.f, y / 64.f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; + ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; + } + + gli::texture2D Texture(1); + Texture[0] = gli::image2D(glm::uvec2(Size), gli::RGB8U); + memcpy(Texture[0].data(), &ImageData[0], ImageData.size()); + gli::saveDDS9(Texture, "texture_perlin2d_256.dds"); + } + + { + std::vector ImageData(Size * Size * 3); + + for(std::size_t y = 0; y < Size; ++y) + for(std::size_t x = 0; x < Size; ++x) + { + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec3(x / 64.f, y / 64.f, 0.5f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; + ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; + } + + gli::texture2D Texture(1); + Texture[0] = gli::image2D(glm::uvec2(Size), gli::RGB8U); + memcpy(Texture[0].data(), &ImageData[0], ImageData.size()); + gli::saveDDS9(Texture, "texture_perlin3d_256.dds"); + } + + { + std::vector ImageData(Size * Size * 3); + + for(std::size_t y = 0; y < Size; ++y) + for(std::size_t x = 0; x < Size; ++x) + { + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec4(x / 64.f, y / 64.f, 0.5f, 0.5f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; + ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; + } + + gli::texture2D Texture(1); + Texture[0] = gli::image2D(glm::uvec2(Size), gli::RGB8U); + memcpy(Texture[0].data(), &ImageData[0], ImageData.size()); + gli::saveDDS9(Texture, "texture_perlin4d_256.dds"); + } + + return 0; +} + +int test_perlin_pedioric() +{ + std::size_t const Size = 256; + + { + std::vector ImageData(Size * Size * 3); + + for(std::size_t y = 0; y < Size; ++y) + for(std::size_t x = 0; x < Size; ++x) + { + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec2(x / 64.f, y / 64.f), glm::vec2(2.0f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; + ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; + } + + gli::texture2D Texture(1); + Texture[0] = gli::image2D(glm::uvec2(Size), gli::RGB8U); + memcpy(Texture[0].data(), &ImageData[0], ImageData.size()); + gli::saveDDS9(Texture, "texture_perlin_pedioric_2d_256.dds"); + } + + { + std::vector ImageData(Size * Size * 3); + + for(std::size_t y = 0; y < Size; ++y) + for(std::size_t x = 0; x < Size; ++x) + { + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec3(x / 64.f, y / 64.f, 0.5f), glm::vec3(2.0f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; + ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; + } + + gli::texture2D Texture(1); + Texture[0] = gli::image2D(glm::uvec2(Size), gli::RGB8U); + memcpy(Texture[0].data(), &ImageData[0], ImageData.size()); + gli::saveDDS9(Texture, "texture_perlin_pedioric_3d_256.dds"); + } + + { + std::vector ImageData(Size * Size * 3); + + for(std::size_t y = 0; y < Size; ++y) + for(std::size_t x = 0; x < Size; ++x) + { + ImageData[(x + y * Size) * 3 + 0] = glm::byte(glm::perlin(glm::vec4(x / 64.f, y / 64.f, 0.5f, 0.5f), glm::vec4(2.0f)) * 128.f + 127.f); + ImageData[(x + y * Size) * 3 + 1] = ImageData[(x + y * Size) * 3 + 0]; + ImageData[(x + y * Size) * 3 + 2] = ImageData[(x + y * Size) * 3 + 0]; + } + + gli::texture2D Texture(1); + Texture[0] = gli::image2D(glm::uvec2(Size), gli::RGB8U); + memcpy(Texture[0].data(), &ImageData[0], ImageData.size()); + gli::saveDDS9(Texture, "texture_perlin_pedioric_4d_256.dds"); + } + + return 0; +} + +int main() +{ + int Error = 0; + + Error += test_simplex(); + Error += test_perlin(); + Error += test_perlin_pedioric(); + + return Error; +} From 9cdf63331ef58e5834c7b69026a129bd3e491358 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Wed, 28 Sep 2011 10:27:43 +0100 Subject: [PATCH 07/32] Added noise2, noise3 and noise4 draft implementation --- glm/core/func_noise.inl | 336 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 334 insertions(+), 2 deletions(-) diff --git a/glm/core/func_noise.inl b/glm/core/func_noise.inl index d53fb299..91e0eb3d 100644 --- a/glm/core/func_noise.inl +++ b/glm/core/func_noise.inl @@ -22,11 +22,343 @@ /// /// @ref core /// @file glm/core/func_noise.inl -/// @date 2008-08-01 / 2011-06-15 +/// @date 2008-08-01 / 2011-09-27 /// @author Christophe Riccio /////////////////////////////////////////////////////////////////////////////////// namespace glm -{ +{ + template + GLM_FUNC_QUALIFIER T noise1(T const & x) + { + return noise1(glm::detail::tvec2(x, T(0))); + } + template + GLM_FUNC_QUALIFIER glm::detail::tvec2 noise2(T const & x) + { + return glm::detail::tvec2( + noise1(x + T(0.0)), + noise1(x + T(1.0))); + } + + template + GLM_FUNC_QUALIFIER glm::detail::tvec3 noise3(T const & x) + { + return glm::detail::tvec3( + noise1(x - T(1.0)), + noise1(x + T(0.0)), + noise1(x + T(1.0))); + } + + template + GLM_FUNC_QUALIFIER glm::detail::tvec4 noise4(T const & x) + { + return glm::detail::tvec4( + noise1(x - T(1.0)), + noise1(x + T(0.0)), + noise1(x + T(1.0)), + noise1(x + T(2.0))); + } + + template + GLM_FUNC_QUALIFIER T noise1(glm::detail::tvec2 const & v) + { + detail::tvec4 const C = detail::tvec4( + T( 0.211324865405187), // (3.0 - sqrt(3.0)) / 6.0 + T( 0.366025403784439), // 0.5 * (sqrt(3.0) - 1.0) + T(-0.577350269189626), // -1.0 + 2.0 * C.x + T( 0.024390243902439)); // 1.0 / 41.0 + + // First corner + detail::tvec2 i = floor(v + dot(v, detail::tvec2(C[1]))); + detail::tvec2 x0 = v - i + dot(i, detail::tvec2(C[0])); + + // Other corners + //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 + //i1.y = 1.0 - i1.x; + detail::tvec2 i1 = (x0.x > x0.y) ? detail::tvec2(1, 0) : detail::tvec2(0, 1); + // x0 = x0 - 0.0 + 0.0 * C.xx ; + // x1 = x0 - i1 + 1.0 * C.xx ; + // x2 = x0 - 1.0 + 2.0 * C.xx ; + detail::tvec4 x12 = detail::tvec4(x0.x, x0.y, x0.x, x0.y) + detail::tvec4(C.x, C.x, C.z, C.z); + x12 = detail::tvec4(detail::tvec2(x12) - i1, x12.z, x12.w); + + // Permutations + i = mod(i, T(289)); // Avoid truncation effects in permutation + detail::tvec3 p = permute( + permute(i.y + detail::tvec3(T(0), i1.y, T(1))) + + i.x + detail::tvec3(T(0), i1.x, T(1))); + + detail::tvec3 m = max(T(0.5) - detail::tvec3( + dot(x0, x0), + dot(detail::tvec2(x12.x, x12.y), detail::tvec2(x12.x, x12.y)), + dot(detail::tvec2(x12.z, x12.w), detail::tvec2(x12.z, x12.w))), T(0)); + m = m * m ; + m = m * m ; + + // Gradients: 41 points uniformly over a line, mapped onto a diamond. + // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) + + detail::tvec3 x = T(2) * fract(p * C.w) - T(1); + detail::tvec3 h = abs(x) - T(0.5); + detail::tvec3 ox = floor(x + T(0.5)); + detail::tvec3 a0 = x - ox; + + // Normalise gradients implicitly by scaling m + // Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h ); + m *= T(1.79284291400159) - T(0.85373472095314) * (a0 * a0 + h * h); + + // Compute final noise value at P + detail::tvec3 g; + g.x = a0.x * x0.x + h.x * x0.y; + //g.yz = a0.yz * x12.xz + h.yz * x12.yw; + g.y = a0.y * x12.x + h.y * x12.y; + g.z = a0.z * x12.z + h.z * x12.w; + return T(130) * dot(m, g); + } + + template + GLM_FUNC_QUALIFIER T noise1(detail::tvec3 const & v) + { + detail::tvec2 const C(1.0 / 6.0, 1.0 / 3.0); + detail::tvec4 const D(0.0, 0.5, 1.0, 2.0); + + // First corner + detail::tvec3 i(floor(v + dot(v, detail::tvec3(C.y)))); + detail::tvec3 x0(v - i + dot(i, detail::tvec3(C.x))); + + // Other corners + detail::tvec3 g(step(detail::tvec3(x0.y, x0.z, x0.x), x0)); + detail::tvec3 l(T(1) - g); + detail::tvec3 i1(min(g, detail::tvec3(l.z, l.x, l.y))); + detail::tvec3 i2(max(g, detail::tvec3(l.z, l.x, l.y))); + + // x0 = x0 - 0.0 + 0.0 * C.xxx; + // x1 = x0 - i1 + 1.0 * C.xxx; + // x2 = x0 - i2 + 2.0 * C.xxx; + // x3 = x0 - 1.0 + 3.0 * C.xxx; + detail::tvec3 x1(x0 - i1 + C.x); + detail::tvec3 x2(x0 - i2 + C.y); // 2.0*C.x = 1/3 = C.y + detail::tvec3 x3(x0 - D.y); // -1.0+3.0*C.x = -0.5 = -D.y + + // Permutations + i = mod289(i); + detail::tvec4 p(permute(permute(permute( + i.z + detail::tvec4(T(0), i1.z, i2.z, T(1))) + + i.y + detail::tvec4(T(0), i1.y, i2.y, T(1))) + + i.x + detail::tvec4(T(0), i1.x, i2.x, T(1)))); + + // Gradients: 7x7 points over a square, mapped onto an octahedron. + // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) + T n_ = T(0.142857142857); // 1.0/7.0 + detail::tvec3 ns(n_ * detail::tvec3(D.w, D.y, D.z) - detail::tvec3(D.x, D.z, D.x)); + + detail::tvec4 j(p - T(49) * floor(p * ns.z * ns.z)); // mod(p,7*7) + + detail::tvec4 x_(floor(j * ns.z)); + detail::tvec4 y_(floor(j - T(7) * x_)); // mod(j,N) + + detail::tvec4 x(x_ * ns.x + ns.y); + detail::tvec4 y(y_ * ns.x + ns.y); + detail::tvec4 h(T(1) - abs(x) - abs(y)); + + detail::tvec4 b0(x.x, x.y, y.x, y.y); + detail::tvec4 b1(x.z, x.w, y.z, y.w); + + // vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; + // vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; + detail::tvec4 s0(floor(b0) * T(2) + T(1)); + detail::tvec4 s1(floor(b1) * T(2) + T(1)); + detail::tvec4 sh(-step(h, detail::tvec4(0.0))); + + detail::tvec4 a0 = detail::tvec4(b0.x, b0.z, b0.y, b0.w) + detail::tvec4(s0.x, s0.z, s0.y, s0.w) * detail::tvec4(sh.x, sh.x, sh.y, sh.y); + detail::tvec4 a1 = detail::tvec4(b1.x, b1.z, b1.y, b1.w) + detail::tvec4(s1.x, s1.z, s1.y, s1.w) * detail::tvec4(sh.z, sh.z, sh.w, sh.w); + + detail::tvec3 p0(a0.x, a0.y, h.x); + detail::tvec3 p1(a0.z, a0.w, h.y); + detail::tvec3 p2(a1.x, a1.y, h.z); + detail::tvec3 p3(a1.z, a1.w, h.w); + + // Normalise gradients + detail::tvec4 norm = taylorInvSqrt(detail::tvec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + + // Mix final noise value + detail::tvec4 m = max(T(0.6) - detail::tvec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), T(0)); + m = m * m; + return T(42) * dot(m * m, detail::tvec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3))); + } + + template + GLM_FUNC_QUALIFIER T noise1(detail::tvec4 const & v) + { + detail::tvec4 const C( + 0.138196601125011, // (5 - sqrt(5))/20 G4 + 0.276393202250021, // 2 * G4 + 0.414589803375032, // 3 * G4 + -0.447213595499958); // -1 + 4 * G4 + + // (sqrt(5) - 1)/4 = F4, used once below + T const F4 = T(0.309016994374947451); + + // First corner + detail::tvec4 i = floor(v + dot(v, vec4(F4))); + detail::tvec4 x0 = v - i + dot(i, vec4(C.x)); + + // Other corners + + // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) + detail::tvec4 i0; + detail::tvec3 isX = step(detail::tvec3(x0.y, x0.z, x0.w), detail::tvec3(x0.x)); + detail::tvec3 isYZ = step(detail::tvec3(x0.z, x0.w, x0.w), detail::tvec3(x0.y, x0.y, x0.z)); + // i0.x = dot(isX, vec3(1.0)); + //i0.x = isX.x + isX.y + isX.z; + //i0.yzw = T(1) - isX; + i0 = detail::tvec4(isX.x + isX.y + isX.z, T(1) - isX); + // i0.y += dot(isYZ.xy, vec2(1.0)); + i0.y += isYZ.x + isYZ.y; + //i0.zw += 1.0 - detail::tvec2(isYZ.x, isYZ.y); + i0.z += T(1) - isYZ.x; + i0.w += T(1) - isYZ.y; + i0.z += isYZ.z; + i0.w += T(1) - isYZ.z; + + // i0 now contains the unique values 0,1,2,3 in each channel + detail::tvec4 i3 = clamp(i0, 0.0, 1.0); + detail::tvec4 i2 = clamp(i0 - 1.0, 0.0, 1.0); + detail::tvec4 i1 = clamp(i0 - 2.0, 0.0, 1.0); + + // x0 = x0 - 0.0 + 0.0 * C.xxxx + // x1 = x0 - i1 + 0.0 * C.xxxx + // x2 = x0 - i2 + 0.0 * C.xxxx + // x3 = x0 - i3 + 0.0 * C.xxxx + // x4 = x0 - 1.0 + 4.0 * C.xxxx + detail::tvec4 x1 = x0 - i1 + C.x; + detail::tvec4 x2 = x0 - i2 + C.y; + detail::tvec4 x3 = x0 - i3 + C.z; + detail::tvec4 x4 = x0 + C.w; + + // Permutations + i = mod(i, T(289)); + T j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x); + detail::tvec4 j1 = permute(permute(permute(permute( + i.w + detail::tvec4(i1.w, i2.w, i3.w, T(1))) + + i.z + detail::tvec4(i1.z, i2.z, i3.z, T(1))) + + i.y + detail::tvec4(i1.y, i2.y, i3.y, T(1))) + + i.x + detail::tvec4(i1.x, i2.x, i3.x, T(1))); + + // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope + // 7*7*6 = 294, which is close to the ring size 17*17 = 289. + detail::tvec4 ip = detail::tvec4(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0)); + + detail::tvec4 p0 = grad4(j0, ip); + detail::tvec4 p1 = grad4(j1.x, ip); + detail::tvec4 p2 = grad4(j1.y, ip); + detail::tvec4 p3 = grad4(j1.z, ip); + detail::tvec4 p4 = grad4(j1.w, ip); + + // Normalise gradients + detail::tvec4 norm = taylorInvSqrt(detail::tvec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + p4 *= taylorInvSqrt(dot(p4, p4)); + + // Mix contributions from the five corners + detail::tvec3 m0 = max(T(0.6) - detail::tvec3(dot(x0, x0), dot(x1, x1), dot(x2, x2)), T(0)); + detail::tvec2 m1 = max(T(0.6) - detail::tvec2(dot(x3, x3), dot(x4, x4) ), T(0)); + m0 = m0 * m0; + m1 = m1 * m1; + return T(49) * + (dot(m0 * m0, detail::tvec3(dot(p0, x0), dot(p1, x1), dot(p2, x2))) + + dot(m1 * m1, detail::tvec2(dot(p3, x3), dot(p4, x4)))); + } + + template + GLM_FUNC_QUALIFIER glm::detail::tvec2 noise2(glm::detail::tvec2 const & x) + { + return glm::detail::tvec2( + noise1(x + glm::detail::tvec2(0.0)), + noise1(glm::detail::tvec2(0.0) - x)); + } + + template + GLM_FUNC_QUALIFIER glm::detail::tvec2 noise2(glm::detail::tvec3 const & x) + { + return glm::detail::tvec2( + noise1(x + glm::detail::tvec3(0.0)), + noise1(glm::detail::tvec3(0.0) - x)); + } + + template + GLM_FUNC_QUALIFIER glm::detail::tvec2 noise2(glm::detail::tvec4 const & x) + { + return glm::detail::tvec2( + noise1(x + glm::detail::tvec4(0.0)), + noise1(glm::detail::tvec4(0.0) - x)); + } + + template + GLM_FUNC_QUALIFIER glm::detail::tvec3 noise3(glm::detail::tvec2 const & x) + { + return glm::detail::tvec3( + noise1(x - glm::detail::tvec2(1.0)), + noise1(x + glm::detail::tvec2(0.0)), + noise1(x + glm::detail::tvec2(1.0))); + } + + template + GLM_FUNC_QUALIFIER glm::detail::tvec3 noise3(glm::detail::tvec3 const & x) + { + return glm::detail::tvec3( + noise1(x - glm::detail::tvec3(1.0)), + noise1(x + glm::detail::tvec3(0.0)), + noise1(x + glm::detail::tvec3(1.0))); + } + + template + GLM_FUNC_QUALIFIER glm::detail::tvec3 noise3(glm::detail::tvec4 const & x) + { + return glm::detail::tvec3( + noise1(x - glm::detail::tvec4(1.0)), + noise1(x + glm::detail::tvec4(0.0)), + noise1(x + glm::detail::tvec4(1.0))); + } + + template + GLM_FUNC_QUALIFIER glm::detail::tvec4 noise4(glm::detail::tvec2 const & x) + { + return glm::detail::tvec4( + noise1(x - glm::detail::tvec2(1.0)), + noise1(x + glm::detail::tvec2(0.0)), + noise1(x + glm::detail::tvec2(1.0)), + noise1(x + glm::detail::tvec2(2.0))); + } + + + template + GLM_FUNC_QUALIFIER glm::detail::tvec4 noise4(glm::detail::tvec3 const & x) + { + return glm::detail::tvec4( + noise1(x - glm::detail::tvec3(1.0)), + noise1(x + glm::detail::tvec3(0.0)), + noise1(x + glm::detail::tvec3(1.0)), + noise1(x + glm::detail::tvec3(2.0))); + } + + template + GLM_FUNC_QUALIFIER glm::detail::tvec4 noise4(glm::detail::tvec4 const & x) + { + return glm::detail::tvec4( + noise1(x - glm::detail::tvec4(1.0)), + noise1(x + glm::detail::tvec4(0.0)), + noise1(x + glm::detail::tvec4(1.0)), + noise1(x + glm::detail::tvec4(2.0))); + } + }//namespace glm From 5431212c55b846fff8d2b95bbd31ab3454ad4c3b Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Thu, 29 Sep 2011 16:49:50 +0100 Subject: [PATCH 08/32] Fixed /W4 warnings --- glm/core/func_packing.inl | 2 +- glm/core/intrinsic_common.inl | 22 ++++++++++++---------- glm/gtc/half_float.inl | 7 +++---- glm/gtx/ulp.inl | 4 ++-- test/core/core_type_half.cpp | 6 +++--- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/glm/core/func_packing.inl b/glm/core/func_packing.inl index 1e6ce6fa..303bde95 100644 --- a/glm/core/func_packing.inl +++ b/glm/core/func_packing.inl @@ -128,7 +128,7 @@ GLM_FUNC_QUALIFIER detail::tvec2 unpackDouble2x32(double const & v) return *(detail::tvec2*)&v; } -GLM_FUNC_QUALIFIER uint packHalf2x16(vec2 const & v) +GLM_FUNC_QUALIFIER uint packHalf2x16(detail::tvec2 const & v) { detail::tvec2 Pack(detail::toFloat16(v.x), detail::toFloat16(v.y)); return *(uint*)&Pack; diff --git a/glm/core/intrinsic_common.inl b/glm/core/intrinsic_common.inl index 8080bb35..471769fa 100644 --- a/glm/core/intrinsic_common.inl +++ b/glm/core/intrinsic_common.inl @@ -205,11 +205,13 @@ GLM_FUNC_QUALIFIER __m128 sse_mod_ps(__m128 x, __m128 y) } /// TODO +/* GLM_FUNC_QUALIFIER __m128 sse_modf_ps(__m128 x, __m128i & i) { __m128 empty; return empty; } +*/ //GLM_FUNC_QUALIFIER __m128 _mm_min_ps(__m128 x, __m128 y) @@ -254,18 +256,18 @@ GLM_FUNC_QUALIFIER __m128 sse_ssp_ps(__m128 edge0, __m128 edge1, __m128 x) } /// \todo -GLM_FUNC_QUALIFIER __m128 sse_nan_ps(__m128 x) -{ - __m128 empty; - return empty; -} +//GLM_FUNC_QUALIFIER __m128 sse_nan_ps(__m128 x) +//{ +// __m128 empty; +// return empty; +//} /// \todo -GLM_FUNC_QUALIFIER __m128 sse_inf_ps(__m128 x) -{ - __m128 empty; - return empty; -} +//GLM_FUNC_QUALIFIER __m128 sse_inf_ps(__m128 x) +//{ +// __m128 empty; +// return empty; +//} // SSE scalar reciprocal sqrt using rsqrt op, plus one Newton-Rhaphson iteration // By Elan Ruskin, http://assemblyrequired.crashworks.org/ diff --git a/glm/gtc/half_float.inl b/glm/gtc/half_float.inl index 32e1a341..92cb2fc5 100644 --- a/glm/gtc/half_float.inl +++ b/glm/gtc/half_float.inl @@ -20,7 +20,7 @@ GLM_FUNC_QUALIFIER tvec2::size_type tvec2::value_size() return 2; } -GLM_FUNC_QUALIFIER typename tvec2::size_type tvec2::length() const +GLM_FUNC_QUALIFIER tvec2::size_type tvec2::length() const { return 2; } @@ -293,7 +293,7 @@ GLM_FUNC_QUALIFIER tvec3::size_type tvec3::value_size() return 3; } -GLM_FUNC_QUALIFIER typename tvec3::size_type tvec3::length() const +GLM_FUNC_QUALIFIER tvec3::size_type tvec3::length() const { return 3; } @@ -610,8 +610,7 @@ GLM_FUNC_QUALIFIER tvec4::size_type tvec4::value_size() return 4; } - -GLM_FUNC_QUALIFIER typename tvec4::size_type tvec4::length() const +GLM_FUNC_QUALIFIER tvec4::size_type tvec4::length() const { return 4; } diff --git a/glm/gtx/ulp.inl b/glm/gtx/ulp.inl index 08d886a5..41a4bd9b 100644 --- a/glm/gtx/ulp.inl +++ b/glm/gtx/ulp.inl @@ -76,8 +76,8 @@ namespace detail volatile float t; glm::detail::int32 hx, hy, ix, iy; - GLM_GET_FLOAT_WORD(hx,x); - GLM_GET_FLOAT_WORD(hy,y); + GLM_GET_FLOAT_WORD(hx, x); + GLM_GET_FLOAT_WORD(hy, y); ix = hx&0x7fffffff; // |x| iy = hy&0x7fffffff; // |y| diff --git a/test/core/core_type_half.cpp b/test/core/core_type_half.cpp index 3468f357..37f59fde 100644 --- a/test/core/core_type_half.cpp +++ b/test/core/core_type_half.cpp @@ -18,13 +18,13 @@ int main() glm::half B(2.0f); glm::half C = A + B; glm::half D(C); - float E = D; - int F = float(C); + float E(D); + int F(float(C)); glm::half G = B * C; glm::half H = G / C; H += glm::half(1.0f); double J = H; - int I = float(H); + int I(float(H)); Result = Result && J == 3.0; From 35b352168afecf52efc36104bd457350f3d0663c Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Fri, 30 Sep 2011 13:47:38 +0100 Subject: [PATCH 09/32] Fixed revision number --- glm/core/setup.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glm/core/setup.hpp b/glm/core/setup.hpp index e3a569ec..5babcd95 100644 --- a/glm/core/setup.hpp +++ b/glm/core/setup.hpp @@ -17,7 +17,7 @@ #define GLM_VERSION_MAJOR 0 #define GLM_VERSION_MINOR 9 #define GLM_VERSION_PATCH 2 -#define GLM_VERSION_REVISION 3 +#define GLM_VERSION_REVISION 6 /////////////////////////////////////////////////////////////////////////////////////////////////// // Compiler From 2438ec04b1b922b1cd161ea0d798aedf7d4a59fd Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Fri, 30 Sep 2011 13:57:09 +0100 Subject: [PATCH 10/32] Ticket #129, fixed -Wsign-conversion warnings --- glm/core/type_half.inl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/glm/core/type_half.inl b/glm/core/type_half.inl index 8166a75e..c6f90301 100644 --- a/glm/core/type_half.inl +++ b/glm/core/type_half.inl @@ -41,7 +41,7 @@ namespace detail // detail::uif result; - result.i = s << 31; + result.i = (unsigned int)(s << 31); return result.f; } else @@ -69,7 +69,7 @@ namespace detail // uif result; - result.i = (s << 31) | 0x7f800000; + result.i = (unsigned int)((s << 31) | 0x7f800000); return result.f; } else @@ -79,7 +79,7 @@ namespace detail // uif result; - result.i = (s << 31) | 0x7f800000 | (m << 13); + result.i = (unsigned int)((s << 31) | 0x7f800000 | (m << 13)); return result.f; } } @@ -96,7 +96,7 @@ namespace detail // uif Result; - Result.i = (s << 31) | (e << 23) | m; + Result.i = (unsigned int)((s << 31) | (e << 23) | m); return Result.f; } @@ -104,7 +104,7 @@ namespace detail { uif Entry; Entry.f = f; - int i = Entry.i; + int i = (int)Entry.i; // // Our floating point number, f, is represented by the bit From 3def64b49b76ca474034b64980797f3e59f18ed4 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Fri, 30 Sep 2011 14:14:21 +0100 Subject: [PATCH 11/32] Fixed matrix division --- glm/gtx/simd_mat4.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glm/gtx/simd_mat4.inl b/glm/gtx/simd_mat4.inl index 84771b65..3bbadf13 100644 --- a/glm/gtx/simd_mat4.inl +++ b/glm/gtx/simd_mat4.inl @@ -157,7 +157,7 @@ namespace detail ) { __m128 Inv[4]; - sse_inverse_ps(&this->Data[0].Data, Inv); + sse_inverse_ps(&m.Data[0].Data, Inv); sse_mul_ps(&this->Data[0].Data, Inv, &this->Data[0].Data); return *this; } From ac8552d2967f6acb8fc9d429394b69a1a4c109cd Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Fri, 30 Sep 2011 14:37:49 +0100 Subject: [PATCH 12/32] Fixed /W4 VC warnings --- glm/core/intrinsic_common.inl | 5 +++++ glm/gtx/ulp.inl | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/glm/core/intrinsic_common.inl b/glm/core/intrinsic_common.inl index 471769fa..12c9023f 100644 --- a/glm/core/intrinsic_common.inl +++ b/glm/core/intrinsic_common.inl @@ -10,6 +10,9 @@ namespace glm{ namespace detail{ +#pragma warning(push) +#pragma warning(disable : 4510 4512 4610) + union ieee754_QNAN { const float f; @@ -21,6 +24,8 @@ namespace detail{ ieee754_QNAN() : f(0.0)/*, mantissa(0x7FFFFF), exp(0xFF), sign(0x0)*/ {} }; +#pragma warning(pop) + static const __m128 GLM_VAR_USED zero = _mm_setzero_ps(); static const __m128 GLM_VAR_USED one = _mm_set_ps1(1.0f); static const __m128 GLM_VAR_USED minus_one = _mm_set_ps1(-1.0f); diff --git a/glm/gtx/ulp.inl b/glm/gtx/ulp.inl index 41a4bd9b..a0c53bef 100644 --- a/glm/gtx/ulp.inl +++ b/glm/gtx/ulp.inl @@ -21,6 +21,9 @@ * ==================================================== */ +#pragma warning(push) +#pragma warning(disable : 4127) + typedef union { float value; @@ -168,6 +171,8 @@ namespace detail }//namespace detail }//namespace glm +#pragma warning(pop) + #if(GLM_COMPILER & GLM_COMPILER_VC) # define GLM_NEXT_AFTER_FLT(x, toward) glm::detail::nextafterf((x), (toward)) # define GLM_NEXT_AFTER_DBL(x, toward) _nextafter((x), (toward)) From 21942860b96d362384ebf3ed862abe6f6b450cbb Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Fri, 30 Sep 2011 14:52:27 +0100 Subject: [PATCH 13/32] updated readme for release --- readme.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/readme.txt b/readme.txt index a0497392..69019670 100644 --- a/readme.txt +++ b/readme.txt @@ -36,6 +36,12 @@ GLM is a header only library, there is nothing to build, just include it. More informations in GLM manual: http://glm.g-truc.net/glm-0.9.2.pdf +================================================================================ +GLM 0.9.2.6: 2011-10-01 +-------------------------------------------------------------------------------- +- Fixed half based type build on old GCC +- Fixed /W4 warnings on Visual C++ + ================================================================================ GLM 0.9.2.5: 2011-09-20 -------------------------------------------------------------------------------- From b7c11b1e6aad0cfdeffb00f24ff727a9e96a8aad Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Fri, 30 Sep 2011 15:36:55 +0100 Subject: [PATCH 14/32] Added GLM_GTX_constants extension --- glm/gtx/constants.hpp | 177 ++++++++++ glm/gtx/constants.inl | 792 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 969 insertions(+) create mode 100644 glm/gtx/constants.hpp create mode 100644 glm/gtx/constants.inl diff --git a/glm/gtx/constants.hpp b/glm/gtx/constants.hpp new file mode 100644 index 00000000..d8ea4f05 --- /dev/null +++ b/glm/gtx/constants.hpp @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////////////////////////////////// +/// OpenGL Mathematics (glm.g-truc.net) +/// +/// Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net) +/// Permission is hereby granted, free of charge, to any person obtaining a copy +/// of this software and associated documentation files (the "Software"), to deal +/// in the Software without restriction, including without limitation the rights +/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/// copies of the Software, and to permit persons to whom the Software is +/// furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +/// THE SOFTWARE. +/// +/// @ref constants +/// @file glm/gtx/constants.hpp +/// @date 2011-09-30 / 2011-09-30 +/// @author Christophe Riccio +/// +/// @see core (dependence) +/// @see gtc_half_float (dependence) +/// +/// @defgroup gtx_constants GLM_GTX_constants: Provide build-in constants +/// @ingroup gtx +/// +/// @brief Allow to perform bit operations on integer values +/// +/// need to be included to use these functionalities. +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef GLM_GTX_constants +#define GLM_GTX_constants GLM_VERSION + +// Dependency: +#include "../glm.hpp" +#include "../gtc/half_float.hpp" + +#if(defined(GLM_MESSAGES) && !defined(glm_ext)) +# pragma message("GLM: GLM_GTX_constants extension included") +#endif + +namespace glm +{ + /// @addtogroup gtx_constants + /// @{ + + template + T pi(); + + template + GLM_FUNC_QUALIFIER T pi() + { + return T(3.14159265358979323846264338327950288); + } + + template + GLM_FUNC_QUALIFIER T root_pi() + { + return T(1.772453850905516027); + } + + template + GLM_FUNC_QUALIFIER T half_pi() + { + return T(1.57079632679489661923132169163975144); + } + + template + GLM_FUNC_QUALIFIER T quarter_pi() + { + return T(0.785398163397448309615660845819875721); + } + + template + GLM_FUNC_QUALIFIER T one_over_pi() + { + return T(0.318309886183790671537767526745028724); + } + + template + GLM_FUNC_QUALIFIER T two_over_pi() + { + return T(0.636619772367581343075535053490057448); + } + + template + GLM_FUNC_QUALIFIER T two_over_root_pi() + { + return T(1.12837916709551257389615890312154517); + } + + template + GLM_FUNC_QUALIFIER T one_over_root_two() + { + return T(0.707106781186547524400844362104849039); + } + + template + GLM_FUNC_QUALIFIER T root_half_pi() + { + return T(1.253314137315500251); + } + + template + GLM_FUNC_QUALIFIER T root_two_pi() + { + return T(2.506628274631000502); + } + + template + GLM_FUNC_QUALIFIER T root_ln_four() + { + return T(1.17741002251547469); + } + + template + GLM_FUNC_QUALIFIER T e() + { + return T(2.71828182845904523536); + } + + template + GLM_FUNC_QUALIFIER T euler() + { + return T(0.577215664901532860606); + } + + template + GLM_FUNC_QUALIFIER T root_two() + { + return T(1.41421356237309504880168872420969808); + } + + template + GLM_FUNC_QUALIFIER T ln_two() + { + return T(0.693147180559945309417232121458176568); + } + + template + GLM_FUNC_QUALIFIER T ln_ten(2.30258509299404568401799145468436421) + { + return T(); + } + + template + GLM_FUNC_QUALIFIER T ln_ln_two() + { + return T(-0.3665129205816643); + } + + template + GLM_FUNC_QUALIFIER T third() + { + return T(0.333333333333333333); + } + + template + GLM_FUNC_QUALIFIER T twothirds() + { + return T(0.666666666666666666); + } + + /// @} +} //namespace glm + +#include "constants.inl" + +#endif//GLM_GTX_constants diff --git a/glm/gtx/constants.inl b/glm/gtx/constants.inl new file mode 100644 index 00000000..885c66af --- /dev/null +++ b/glm/gtx/constants.inl @@ -0,0 +1,792 @@ +/////////////////////////////////////////////////////////////////////////////////// +/// OpenGL Mathematics (glm.g-truc.net) +/// +/// Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net) +/// Permission is hereby granted, free of charge, to any person obtaining a copy +/// of this software and associated documentation files (the "Software"), to deal +/// in the Software without restriction, including without limitation the rights +/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/// copies of the Software, and to permit persons to whom the Software is +/// furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +/// THE SOFTWARE. +/// +/// @ref gtc_half_float +/// @file glm/gtc/half_float.inl +/// @date 2009-04-29 / 2011-06-05 +/// @author Christophe Riccio +/////////////////////////////////////////////////////////////////////////////////// + +#include "../core/_detail.hpp" + +namespace glm{ + +template +GLM_FUNC_QUALIFIER genIType mask +( + genIType const & count +) +{ + return ((genIType(1) << (count)) - genIType(1)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 mask +( + detail::tvec2 const & count +) +{ + return detail::tvec2( + mask(count[0]), + mask(count[1])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 mask +( + detail::tvec3 const & count +) +{ + return detail::tvec3( + mask(count[0]), + mask(count[1]), + mask(count[2])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 mask +( + detail::tvec4 const & count +) +{ + return detail::tvec4( + mask(count[0]), + mask(count[1]), + mask(count[2]), + mask(count[3])); +} + +// extractField +template +GLM_FUNC_QUALIFIER genIType extractField +( + half const & value, + genIType const & first, + genIType const & count +) +{ + assert(first + count < sizeof(half)); + return (value._data() << first) >> ((sizeof(half) << 3) - count); +} + +template +GLM_FUNC_QUALIFIER genIType extractField +( + float const & value, + genIType const & first, + genIType const & count +) +{ + assert(first + count < sizeof(float)); + return (detail::uif32(value).i << first) >> ((sizeof(float) << 3) - count); +} + +template +GLM_FUNC_QUALIFIER genIType extractField +( + double const & value, + genIType const & first, + genIType const & count +) +{ + assert(first + count < sizeof(double)); + return (detail::uif64(value).i << first) >> ((sizeof(double) << genIType(3)) - count); +} + +template +GLM_FUNC_QUALIFIER genIUType extractField +( + genIUType const & Value, + sizeType const & First, + sizeType const & Count +) +{ + sizeType GenSize = sizeof(genIUType) << 3; + + assert(First + Count <= GenSize); + + genIUType ShiftLeft = Count ? Value << (GenSize - (Count + First)) : 0; + genIUType ShiftBack = ShiftLeft >> genIUType(GenSize - Count); + + return ShiftBack; +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 extractField +( + detail::tvec2 const & value, + sizeType const & first, + sizeType const & count +) +{ + return detail::tvec2( + extractField(value[0], first, count), + extractField(value[1], first, count)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 extractField +( + detail::tvec3 const & value, + sizeType const & first, + sizeType const & count +) +{ + return detail::tvec3( + extractField(value[0], first, count), + extractField(value[1], first, count), + extractField(value[2], first, count)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 extractField +( + detail::tvec4 const & value, + sizeType const & first, + sizeType const & count +) +{ + return detail::tvec4( + extractField(value[0], first, count), + extractField(value[1], first, count), + extractField(value[2], first, count), + extractField(value[3], first, count)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 extractField +( + detail::tvec2 const & value, + detail::tvec2 const & first, + detail::tvec2 const & count +) +{ + return detail::tvec2( + extractField(value[0], first[0], count[0]), + extractField(value[1], first[1], count[1])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 extractField +( + detail::tvec3 const & value, + detail::tvec3 const & first, + detail::tvec3 const & count +) +{ + return detail::tvec3( + extractField(value[0], first[0], count[0]), + extractField(value[1], first[1], count[1]), + extractField(value[2], first[2], count[2])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 extractField +( + detail::tvec4 const & value, + detail::tvec4 const & first, + detail::tvec4 const & count +) +{ + return detail::tvec4( + extractField(value[0], first[0], count[0]), + extractField(value[1], first[1], count[1]), + extractField(value[2], first[2], count[2]), + extractField(value[3], first[3], count[3])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 extractField +( + genIUType const & value, + detail::tvec2 const & first, + detail::tvec2 const & count +) +{ + return detail::tvec2( + extractField(value, first[0], count[0]), + extractField(value, first[1], count[1])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 extractField +( + genIUType const & value, + detail::tvec3 const & first, + detail::tvec3 const & count +) +{ + return detail::tvec3( + extractField(value, first[0], count[0]), + extractField(value, first[1], count[1]), + extractField(value, first[2], count[2])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 extractField +( + genIUType const & value, + detail::tvec4 const & first, + detail::tvec4 const & count +) +{ + return detail::tvec4( + extractField(value, first[0], count[0]), + extractField(value, first[1], count[1]), + extractField(value, first[2], count[2]), + extractField(value, first[3], count[3])); +} + +// lowestBit +template +GLM_FUNC_QUALIFIER int lowestBit +( + genType const & Value +) +{ + assert(Value != genType(0)); // not valid call + + genType Bit; + for(Bit = genType(0); !(Value & (1 << Bit)); ++Bit){} + return Bit; +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 lowestBit +( + detail::tvec2 const & value +) +{ + return detail::tvec2( + lowestBit(value[0]), + lowestBit(value[1])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 lowestBit +( + detail::tvec3 const & value +) +{ + return detail::tvec3( + lowestBit(value[0]), + lowestBit(value[1]), + lowestBit(value[2])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 lowestBit +( + detail::tvec4 const & value +) +{ + return detail::tvec4( + lowestBit(value[0]), + lowestBit(value[1]), + lowestBit(value[2]), + lowestBit(value[3])); +} + +// highestBit +template +GLM_FUNC_QUALIFIER int highestBit +( + genType const & value +) +{ + assert(value != genType(0)); // not valid call + + genType bit = genType(-1); + for(genType tmp = value; tmp; tmp >>= 1, ++bit){} + return bit; +} + +//template <> +//GLM_FUNC_QUALIFIER int highestBit +//( +// int value +//) +//{ +// int bit = -1; +// for(int tmp = value; tmp; tmp >>= 1, ++bit); +// return bit; +//} + +template +GLM_FUNC_QUALIFIER detail::tvec2 highestBit +( + detail::tvec2 const & value +) +{ + return detail::tvec2( + highestBit(value[0]), + highestBit(value[1])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 highestBit +( + detail::tvec3 const & value +) +{ + return detail::tvec3( + highestBit(value[0]), + highestBit(value[1]), + highestBit(value[2])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 highestBit +( + detail::tvec4 const & value +) +{ + return detail::tvec4( + highestBit(value[0]), + highestBit(value[1]), + highestBit(value[2]), + highestBit(value[3])); +} + +// highestBitValue +template +GLM_FUNC_QUALIFIER genType highestBitValue +( + genType const & value +) +{ + genType tmp = value; + genType result = genType(0); + while(tmp) + { + result = (tmp & (~tmp + 1)); // grab lowest bit + tmp &= ~result; // clear lowest bit + } + return result; +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 highestBitValue +( + detail::tvec2 const & value +) +{ + return detail::tvec2( + highestBitValue(value[0]), + highestBitValue(value[1])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 highestBitValue +( + detail::tvec3 const & value +) +{ + return detail::tvec3( + highestBitValue(value[0]), + highestBitValue(value[1]), + highestBitValue(value[2])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 highestBitValue +( + detail::tvec4 const & value +) +{ + return detail::tvec4( + highestBitValue(value[0]), + highestBitValue(value[1]), + highestBitValue(value[2]), + highestBitValue(value[3])); +} + +// isPowerOfTwo +template +GLM_FUNC_QUALIFIER bool isPowerOfTwo(genType const & Value) +{ + //detail::If::is_signed>::apply(abs, Value); + //return !(Value & (Value - 1)); + + // For old complier? + genType Result = Value; + if(std::numeric_limits::is_signed) + Result = abs(Result); + return !(Result & (Result - 1)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 isPowerOfTwo +( + detail::tvec2 const & value +) +{ + return detail::tvec2( + isPowerOfTwo(value[0]), + isPowerOfTwo(value[1])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 isPowerOfTwo +( + detail::tvec3 const & value +) +{ + return detail::tvec3( + isPowerOfTwo(value[0]), + isPowerOfTwo(value[1]), + isPowerOfTwo(value[2])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 isPowerOfTwo +( + detail::tvec4 const & value +) +{ + return detail::tvec4( + isPowerOfTwo(value[0]), + isPowerOfTwo(value[1]), + isPowerOfTwo(value[2]), + isPowerOfTwo(value[3])); +} + +// powerOfTwoAbove +template +GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType const & value) +{ + return isPowerOfTwo(value) ? value : highestBitValue(value) << 1; +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 powerOfTwoAbove +( + detail::tvec2 const & value +) +{ + return detail::tvec2( + powerOfTwoAbove(value[0]), + powerOfTwoAbove(value[1])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 powerOfTwoAbove +( + detail::tvec3 const & value +) +{ + return detail::tvec3( + powerOfTwoAbove(value[0]), + powerOfTwoAbove(value[1]), + powerOfTwoAbove(value[2])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 powerOfTwoAbove +( + detail::tvec4 const & value +) +{ + return detail::tvec4( + powerOfTwoAbove(value[0]), + powerOfTwoAbove(value[1]), + powerOfTwoAbove(value[2]), + powerOfTwoAbove(value[3])); +} + +// powerOfTwoBelow +template +GLM_FUNC_QUALIFIER genType powerOfTwoBelow +( + genType const & value +) +{ + return isPowerOfTwo(value) ? value : highestBitValue(value); +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 powerOfTwoBelow +( + detail::tvec2 const & value +) +{ + return detail::tvec2( + powerOfTwoBelow(value[0]), + powerOfTwoBelow(value[1])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 powerOfTwoBelow +( + detail::tvec3 const & value +) +{ + return detail::tvec3( + powerOfTwoBelow(value[0]), + powerOfTwoBelow(value[1]), + powerOfTwoBelow(value[2])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 powerOfTwoBelow +( + detail::tvec4 const & value +) +{ + return detail::tvec4( + powerOfTwoBelow(value[0]), + powerOfTwoBelow(value[1]), + powerOfTwoBelow(value[2]), + powerOfTwoBelow(value[3])); +} + +// powerOfTwoNearest +template +GLM_FUNC_QUALIFIER genType powerOfTwoNearest +( + genType const & value +) +{ + if(isPowerOfTwo(value)) + return value; + + genType prev = highestBitValue(value); + genType next = prev << 1; + return (next - value) < (value - prev) ? next : prev; +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 powerOfTwoNearest +( + detail::tvec2 const & value +) +{ + return detail::tvec2( + powerOfTwoNearest(value[0]), + powerOfTwoNearest(value[1])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 powerOfTwoNearest +( + detail::tvec3 const & value +) +{ + return detail::tvec3( + powerOfTwoNearest(value[0]), + powerOfTwoNearest(value[1]), + powerOfTwoNearest(value[2])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 powerOfTwoNearest +( + detail::tvec4 const & value +) +{ + return detail::tvec4( + powerOfTwoNearest(value[0]), + powerOfTwoNearest(value[1]), + powerOfTwoNearest(value[2]), + powerOfTwoNearest(value[3])); +} + +template +GLM_FUNC_QUALIFIER genType bitRevert(genType const & In) +{ + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitRevert' only accept integer values"); + + genType Out = 0; + std::size_t BitSize = sizeof(genType) * 8; + for(std::size_t i = 0; i < BitSize; ++i) + if(In & (genType(1) << i)) + Out |= genType(1) << (BitSize - 1 - i); + return Out; +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 bitRevert +( + detail::tvec2 const & Value +) +{ + return detail::tvec2( + bitRevert(Value[0]), + bitRevert(Value[1])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 bitRevert +( + detail::tvec3 const & Value +) +{ + return detail::tvec3( + bitRevert(Value[0]), + bitRevert(Value[1]), + bitRevert(Value[2])); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 bitRevert +( + detail::tvec4 const & Value +) +{ + return detail::tvec4( + bitRevert(Value[0]), + bitRevert(Value[1]), + bitRevert(Value[2]), + bitRevert(Value[3])); +} + +template +GLM_FUNC_QUALIFIER genType bitRotateRight(genType const & In, std::size_t Shift) +{ + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitRotateRight' only accept integer values"); + + std::size_t BitSize = sizeof(genType) * 8; + return (In << Shift) | (In >> (BitSize - Shift)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 bitRotateRight +( + detail::tvec2 const & Value, + std::size_t Shift +) +{ + return detail::tvec2( + bitRotateRight(Value[0], Shift), + bitRotateRight(Value[1], Shift)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 bitRotateRight +( + detail::tvec3 const & Value, + std::size_t Shift +) +{ + return detail::tvec3( + bitRotateRight(Value[0], Shift), + bitRotateRight(Value[1], Shift), + bitRotateRight(Value[2], Shift)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 bitRotateRight +( + detail::tvec4 const & Value, + std::size_t Shift +) +{ + return detail::tvec4( + bitRotateRight(Value[0], Shift), + bitRotateRight(Value[1], Shift), + bitRotateRight(Value[2], Shift), + bitRotateRight(Value[3], Shift)); +} + +template +GLM_FUNC_QUALIFIER genType bitRotateLeft(genType const & In, std::size_t Shift) +{ + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitRotateLeft' only accept integer values"); + + std::size_t BitSize = sizeof(genType) * 8; + return (In >> Shift) | (In << (BitSize - Shift)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 bitRotateLeft +( + detail::tvec2 const & Value, + std::size_t Shift +) +{ + return detail::tvec2( + bitRotateLeft(Value[0], Shift), + bitRotateLeft(Value[1], Shift)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 bitRotateLeft +( + detail::tvec3 const & Value, + std::size_t Shift +) +{ + return detail::tvec3( + bitRotateLeft(Value[0], Shift), + bitRotateLeft(Value[1], Shift), + bitRotateLeft(Value[2], Shift)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 bitRotateLeft +( + detail::tvec4 const & Value, + std::size_t Shift +) +{ + return detail::tvec4( + bitRotateLeft(Value[0], Shift), + bitRotateLeft(Value[1], Shift), + bitRotateLeft(Value[2], Shift), + bitRotateLeft(Value[3], Shift)); +} + +template +GLM_FUNC_QUALIFIER genIUType fillBitfieldWithOne +( + genIUType const & Value, + int const & FromBit, + int const & ToBit +) +{ + assert(FromBit <= ToBit); + assert(ToBit <= sizeof(genIUType) * std::size_t(8)); + + genIUType Result = Value; + for(std::size_t i = 0; i <= ToBit; ++i) + Result |= (1 << i); + return Result; +} + +template +GLM_FUNC_QUALIFIER genIUType fillBitfieldWithZero +( + genIUType const & Value, + int const & FromBit, + int const & ToBit +) +{ + assert(FromBit <= ToBit); + assert(ToBit <= sizeof(genIUType) * std::size_t(8)); + + genIUType Result = Value; + for(std::size_t i = 0; i <= ToBit; ++i) + Result &= ~(1 << i); + return Result; +} + +}//namespace glm From 7f6387f213e2f2af3d638ae6d9b55de607de02f0 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Fri, 30 Sep 2011 16:06:22 +0100 Subject: [PATCH 15/32] Updated GLM 0.9.3 feature lsit --- readme.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readme.txt b/readme.txt index 907d45dd..d0305ae4 100644 --- a/readme.txt +++ b/readme.txt @@ -40,6 +40,10 @@ http://glm.g-truc.net/glm-0.9.3.pdf GLM 0.9.3.0: 2011-XX-XX -------------------------------------------------------------------------------- - Improved doxygen documentation +- Promoted GLM_GTC_noise extension: simplex, perlin, periodic noise functions +- Promoted GLM_GTC_random extension: linear, gaussian and various random number +generation distribution. +- Added GLM_GTX_constants: provides usefull constants - Added extension versioning - Removed many unused namespaces - Fixed half based type contructors From d75db9b8e4be6358e1e0b74a589d9de03bfa0a53 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Fri, 30 Sep 2011 16:16:55 +0100 Subject: [PATCH 16/32] Fixed ticket #111, missing swizzle operations --- glm/core/type_vec3.hpp | 1 + glm/core/type_vec3.inl | 12 ++++++++++++ glm/core/type_vec4.hpp | 2 ++ glm/core/type_vec4.inl | 26 ++++++++++++++++++++++++++ 4 files changed, 41 insertions(+) diff --git a/glm/core/type_vec3.hpp b/glm/core/type_vec3.hpp index 1afb844f..281809dd 100644 --- a/glm/core/type_vec3.hpp +++ b/glm/core/type_vec3.hpp @@ -178,6 +178,7 @@ namespace detail GLM_FUNC_DECL tvec2 swizzle(comp X, comp Y) const; GLM_FUNC_DECL tvec3 swizzle(comp X, comp Y, comp Z) const; GLM_FUNC_DECL tvec4 swizzle(comp X, comp Y, comp Z, comp W) const; + GLM_FUNC_DECL tref2 swizzle(comp X, comp Y); GLM_FUNC_DECL tref3 swizzle(comp X, comp Y, comp Z); }; diff --git a/glm/core/type_vec3.inl b/glm/core/type_vec3.inl index f06d541f..f112a4ad 100644 --- a/glm/core/type_vec3.inl +++ b/glm/core/type_vec3.inl @@ -575,6 +575,18 @@ namespace detail (*this)[w]); } + template + GLM_FUNC_QUALIFIER tref2 tvec3::swizzle + ( + comp x, + comp y + ) + { + return tref2( + (*this)[x], + (*this)[y]); + } + template GLM_FUNC_QUALIFIER tref3 tvec3::swizzle ( diff --git a/glm/core/type_vec4.hpp b/glm/core/type_vec4.hpp index 9ea08606..4ec85c05 100644 --- a/glm/core/type_vec4.hpp +++ b/glm/core/type_vec4.hpp @@ -190,6 +190,8 @@ namespace detail GLM_FUNC_DECL tvec2 swizzle(comp X, comp Y) const; GLM_FUNC_DECL tvec3 swizzle(comp X, comp Y, comp Z) const; GLM_FUNC_DECL tvec4 swizzle(comp X, comp Y, comp Z, comp W) const; + GLM_FUNC_DECL tref2 swizzle(comp X, comp Y); + GLM_FUNC_DECL tref3 swizzle(comp X, comp Y, comp Z); GLM_FUNC_DECL tref4 swizzle(comp X, comp Y, comp Z, comp W); }; diff --git a/glm/core/type_vec4.inl b/glm/core/type_vec4.inl index 6750beae..567be01c 100644 --- a/glm/core/type_vec4.inl +++ b/glm/core/type_vec4.inl @@ -632,6 +632,32 @@ namespace detail (*this)[w]); } + template + GLM_FUNC_QUALIFIER tref2 tvec4::swizzle + ( + comp x, + comp y + ) + { + return tref2( + (*this)[x], + (*this)[y]); + } + + template + GLM_FUNC_QUALIFIER tref3 tvec4::swizzle + ( + comp x, + comp y, + comp z + ) + { + return tref3( + (*this)[x], + (*this)[y], + (*this)[z]); + } + template GLM_FUNC_QUALIFIER tref4 tvec4::swizzle ( From b7ae077826cd160dfaf1e1d0729ba18d54f263c3 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Fri, 30 Sep 2011 16:38:29 +0100 Subject: [PATCH 17/32] Updated GLM 0.9.2.6 release note --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index 69019670..8e196bac 100644 --- a/readme.txt +++ b/readme.txt @@ -41,6 +41,7 @@ GLM 0.9.2.6: 2011-10-01 -------------------------------------------------------------------------------- - Fixed half based type build on old GCC - Fixed /W4 warnings on Visual C++ +- Fixed some missing l-value swizzle operators ================================================================================ GLM 0.9.2.5: 2011-09-20 From f1975617c09e2ecf38e92d07a1c055d5301243e4 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sat, 1 Oct 2011 11:52:10 +0100 Subject: [PATCH 18/32] Release GLM 0.9.2.6 --- doc/about.html | 4 ++-- doc/code.html | 4 ++-- doc/download.html | 16 +++++++++++----- doc/goodies.html | 4 ++-- doc/index.html | 16 ++++++++++++---- doc/src/data.xml | 15 +++++++++++++++ 6 files changed, 44 insertions(+), 15 deletions(-) diff --git a/doc/about.html b/doc/about.html index 8add18d7..2fc28148 100644 --- a/doc/about.html +++ b/doc/about.html @@ -11,8 +11,8 @@ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); -
OpenGL Mathematics
GLSL + Optional features = OpenGL Mathematics (GLM)
A C++ mathematics library for graphics programming


+
OpenGL Mathematics
GLSL + Optional features = OpenGL Mathematics (GLM)
A C++ mathematics library for graphics programming


OpenGL Mathematics (GLM) is a header only C++ mathematics library for graphics software based on the OpenGL Shading Language (GLSL) specification.

diff --git a/doc/code.html b/doc/code.html index d5764b86..ff7c3b75 100644 --- a/doc/code.html +++ b/doc/code.html @@ -11,8 +11,8 @@ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); -
OpenGL Mathematics
GLSL + Optional features = OpenGL Mathematics (GLM)
A C++ mathematics library for graphics programming


Compute a triangle normal: