Commit 6e54b394 authored by Nianchen Deng's avatar Nianchen Deng
Browse files

paper committed

parent 90553bac
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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 core
/// @file glm/detail/intrinsic_exponential.hpp
/// @date 2009-05-11 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "setup.hpp"
#if(!(GLM_ARCH & GLM_ARCH_SSE2))
# error "SSE2 instructions not supported or enabled"
#else
namespace glm{
namespace detail
{
/*
GLM_FUNC_QUALIFIER __m128 sse_rsqrt_nr_ss(__m128 const x)
{
__m128 recip = _mm_rsqrt_ss( x ); // "estimate" opcode
const static __m128 three = { 3, 3, 3, 3 }; // aligned consts for fast load
const static __m128 half = { 0.5,0.5,0.5,0.5 };
__m128 halfrecip = _mm_mul_ss( half, recip );
__m128 threeminus_xrr = _mm_sub_ss( three, _mm_mul_ss( x, _mm_mul_ss ( recip, recip ) ) );
return _mm_mul_ss( halfrecip, threeminus_xrr );
}
GLM_FUNC_QUALIFIER __m128 sse_normalize_fast_ps( float * RESTRICT vOut, float * RESTRICT vIn )
{
__m128 x = _mm_load_ss(&vIn[0]);
__m128 y = _mm_load_ss(&vIn[1]);
__m128 z = _mm_load_ss(&vIn[2]);
const __m128 l = // compute x*x + y*y + z*z
_mm_add_ss(
_mm_add_ss( _mm_mul_ss(x,x),
_mm_mul_ss(y,y)
),
_mm_mul_ss( z, z )
);
const __m128 rsqt = _mm_rsqrt_nr_ss( l );
_mm_store_ss( &vOut[0] , _mm_mul_ss( rsqt, x ) );
_mm_store_ss( &vOut[1] , _mm_mul_ss( rsqt, y ) );
_mm_store_ss( &vOut[2] , _mm_mul_ss( rsqt, z ) );
return _mm_mul_ss( l , rsqt );
}
*/
}//namespace detail
}//namespace glm
#endif//GLM_ARCH
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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 core
/// @file glm/detail/intrinsic_exponential.inl
/// @date 2011-06-15 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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 core
/// @file glm/detail/intrinsic_geometric.hpp
/// @date 2009-05-08 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "setup.hpp"
#if(!(GLM_ARCH & GLM_ARCH_SSE2))
# error "SSE2 instructions not supported or enabled"
#else
#include "intrinsic_common.hpp"
namespace glm{
namespace detail
{
//length
__m128 sse_len_ps(__m128 x);
//distance
__m128 sse_dst_ps(__m128 p0, __m128 p1);
//dot
__m128 sse_dot_ps(__m128 v1, __m128 v2);
// SSE1
__m128 sse_dot_ss(__m128 v1, __m128 v2);
//cross
__m128 sse_xpd_ps(__m128 v1, __m128 v2);
//normalize
__m128 sse_nrm_ps(__m128 v);
//faceforward
__m128 sse_ffd_ps(__m128 N, __m128 I, __m128 Nref);
//reflect
__m128 sse_rfe_ps(__m128 I, __m128 N);
//refract
__m128 sse_rfa_ps(__m128 I, __m128 N, __m128 eta);
}//namespace detail
}//namespace glm
#include "intrinsic_geometric.inl"
#endif//GLM_ARCH
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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 core
/// @file glm/detail/intrinsic_geometric.inl
/// @date 2009-05-08 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
namespace glm{
namespace detail{
//length
GLM_FUNC_QUALIFIER __m128 sse_len_ps(__m128 x)
{
__m128 dot0 = sse_dot_ps(x, x);
__m128 sqt0 = _mm_sqrt_ps(dot0);
return sqt0;
}
//distance
GLM_FUNC_QUALIFIER __m128 sse_dst_ps(__m128 p0, __m128 p1)
{
__m128 sub0 = _mm_sub_ps(p0, p1);
__m128 len0 = sse_len_ps(sub0);
return len0;
}
//dot
GLM_FUNC_QUALIFIER __m128 sse_dot_ps(__m128 v1, __m128 v2)
{
# if(GLM_ARCH & GLM_ARCH_AVX)
return _mm_dp_ps(v1, v2, 0xff);
# else
__m128 mul0 = _mm_mul_ps(v1, v2);
__m128 swp0 = _mm_shuffle_ps(mul0, mul0, _MM_SHUFFLE(2, 3, 0, 1));
__m128 add0 = _mm_add_ps(mul0, swp0);
__m128 swp1 = _mm_shuffle_ps(add0, add0, _MM_SHUFFLE(0, 1, 2, 3));
__m128 add1 = _mm_add_ps(add0, swp1);
return add1;
# endif
}
// SSE1
GLM_FUNC_QUALIFIER __m128 sse_dot_ss(__m128 v1, __m128 v2)
{
__m128 mul0 = _mm_mul_ps(v1, v2);
__m128 mov0 = _mm_movehl_ps(mul0, mul0);
__m128 add0 = _mm_add_ps(mov0, mul0);
__m128 swp1 = _mm_shuffle_ps(add0, add0, 1);
__m128 add1 = _mm_add_ss(add0, swp1);
return add1;
}
//cross
GLM_FUNC_QUALIFIER __m128 sse_xpd_ps(__m128 v1, __m128 v2)
{
__m128 swp0 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 0, 2, 1));
__m128 swp1 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 1, 0, 2));
__m128 swp2 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 0, 2, 1));
__m128 swp3 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 1, 0, 2));
__m128 mul0 = _mm_mul_ps(swp0, swp3);
__m128 mul1 = _mm_mul_ps(swp1, swp2);
__m128 sub0 = _mm_sub_ps(mul0, mul1);
return sub0;
}
//normalize
GLM_FUNC_QUALIFIER __m128 sse_nrm_ps(__m128 v)
{
__m128 dot0 = sse_dot_ps(v, v);
__m128 isr0 = _mm_rsqrt_ps(dot0);
__m128 mul0 = _mm_mul_ps(v, isr0);
return mul0;
}
//faceforward
GLM_FUNC_QUALIFIER __m128 sse_ffd_ps(__m128 N, __m128 I, __m128 Nref)
{
//__m128 dot0 = _mm_dot_ps(v, v);
//__m128 neg0 = _mm_neg_ps(N);
//__m128 sgn0 = _mm_sgn_ps(dot0);
//__m128 mix0 = _mm_mix_ps(N, neg0, sgn0);
//return mix0;
__m128 dot0 = sse_dot_ps(Nref, I);
__m128 sgn0 = sse_sgn_ps(dot0);
__m128 mul0 = _mm_mul_ps(sgn0, glm::detail::minus_one);
__m128 mul1 = _mm_mul_ps(N, mul0);
return mul1;
}
//reflect
GLM_FUNC_QUALIFIER __m128 sse_rfe_ps(__m128 I, __m128 N)
{
__m128 dot0 = sse_dot_ps(N, I);
__m128 mul0 = _mm_mul_ps(N, dot0);
__m128 mul1 = _mm_mul_ps(mul0, glm::detail::two);
__m128 sub0 = _mm_sub_ps(I, mul1);
return sub0;
}
//refract
GLM_FUNC_QUALIFIER __m128 sse_rfa_ps(__m128 I, __m128 N, __m128 eta)
{
__m128 dot0 = sse_dot_ps(N, I);
__m128 mul0 = _mm_mul_ps(eta, eta);
__m128 mul1 = _mm_mul_ps(dot0, dot0);
__m128 sub0 = _mm_sub_ps(glm::detail::one, mul0);
__m128 sub1 = _mm_sub_ps(glm::detail::one, mul1);
__m128 mul2 = _mm_mul_ps(sub0, sub1);
if(_mm_movemask_ps(_mm_cmplt_ss(mul2, glm::detail::zero)) == 0)
return glm::detail::zero;
__m128 sqt0 = _mm_sqrt_ps(mul2);
__m128 mul3 = _mm_mul_ps(eta, dot0);
__m128 add0 = _mm_add_ps(mul3, sqt0);
__m128 mul4 = _mm_mul_ps(add0, N);
__m128 mul5 = _mm_mul_ps(eta, I);
__m128 sub2 = _mm_sub_ps(mul5, mul4);
return sub2;
}
}//namespace detail
}//namespace glm
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2012 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 core
/// @file glm/detail/intrinsic_integer.hpp
/// @date 2009-05-11 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "glm/glm.hpp"
#if(!(GLM_ARCH & GLM_ARCH_SSE2))
# error "SSE2 instructions not supported or enabled"
#else
namespace glm{
namespace detail
{
__m128i _mm_bit_interleave_si128(__m128i x);
__m128i _mm_bit_interleave_si128(__m128i x, __m128i y);
}//namespace detail
}//namespace glm
#include "intrinsic_integer.inl"
#endif//GLM_ARCH
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2012 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 core
/// @file glm/detail/intrinsic_integer.inl
/// @date 2009-05-08 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
namespace glm{
namespace detail
{
inline __m128i _mm_bit_interleave_si128(__m128i x)
{
__m128i const Mask4 = _mm_set1_epi32(0x0000FFFF);
__m128i const Mask3 = _mm_set1_epi32(0x00FF00FF);
__m128i const Mask2 = _mm_set1_epi32(0x0F0F0F0F);
__m128i const Mask1 = _mm_set1_epi32(0x33333333);
__m128i const Mask0 = _mm_set1_epi32(0x55555555);
__m128i Reg1;
__m128i Reg2;
// REG1 = x;
// REG2 = y;
//Reg1 = _mm_unpacklo_epi64(x, y);
Reg1 = x;
//REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF);
//REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF);
Reg2 = _mm_slli_si128(Reg1, 2);
Reg1 = _mm_or_si128(Reg2, Reg1);
Reg1 = _mm_and_si128(Reg1, Mask4);
//REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF);
//REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF);
Reg2 = _mm_slli_si128(Reg1, 1);
Reg1 = _mm_or_si128(Reg2, Reg1);
Reg1 = _mm_and_si128(Reg1, Mask3);
//REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F);
//REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F);
Reg2 = _mm_slli_epi32(Reg1, 4);
Reg1 = _mm_or_si128(Reg2, Reg1);
Reg1 = _mm_and_si128(Reg1, Mask2);
//REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333);
//REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333);
Reg2 = _mm_slli_epi32(Reg1, 2);
Reg1 = _mm_or_si128(Reg2, Reg1);
Reg1 = _mm_and_si128(Reg1, Mask1);
//REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555);
//REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555);
Reg2 = _mm_slli_epi32(Reg1, 1);
Reg1 = _mm_or_si128(Reg2, Reg1);
Reg1 = _mm_and_si128(Reg1, Mask0);
//return REG1 | (REG2 << 1);
Reg2 = _mm_slli_epi32(Reg1, 1);
Reg2 = _mm_srli_si128(Reg2, 8);
Reg1 = _mm_or_si128(Reg1, Reg2);
return Reg1;
}
inline __m128i _mm_bit_interleave_si128(__m128i x, __m128i y)
{
__m128i const Mask4 = _mm_set1_epi32(0x0000FFFF);
__m128i const Mask3 = _mm_set1_epi32(0x00FF00FF);
__m128i const Mask2 = _mm_set1_epi32(0x0F0F0F0F);
__m128i const Mask1 = _mm_set1_epi32(0x33333333);
__m128i const Mask0 = _mm_set1_epi32(0x55555555);
__m128i Reg1;
__m128i Reg2;
// REG1 = x;
// REG2 = y;
Reg1 = _mm_unpacklo_epi64(x, y);
//REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF);
//REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF);
Reg2 = _mm_slli_si128(Reg1, 2);
Reg1 = _mm_or_si128(Reg2, Reg1);
Reg1 = _mm_and_si128(Reg1, Mask4);
//REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF);
//REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF);
Reg2 = _mm_slli_si128(Reg1, 1);
Reg1 = _mm_or_si128(Reg2, Reg1);
Reg1 = _mm_and_si128(Reg1, Mask3);
//REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F);
//REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F);
Reg2 = _mm_slli_epi32(Reg1, 4);
Reg1 = _mm_or_si128(Reg2, Reg1);
Reg1 = _mm_and_si128(Reg1, Mask2);
//REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333);
//REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333);
Reg2 = _mm_slli_epi32(Reg1, 2);
Reg1 = _mm_or_si128(Reg2, Reg1);
Reg1 = _mm_and_si128(Reg1, Mask1);
//REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555);
//REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555);
Reg2 = _mm_slli_epi32(Reg1, 1);
Reg1 = _mm_or_si128(Reg2, Reg1);
Reg1 = _mm_and_si128(Reg1, Mask0);
//return REG1 | (REG2 << 1);
Reg2 = _mm_slli_epi32(Reg1, 1);
Reg2 = _mm_srli_si128(Reg2, 8);
Reg1 = _mm_or_si128(Reg1, Reg2);
return Reg1;
}
}//namespace detail
}//namespace glms
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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 core
/// @file glm/detail/intrinsic_common.hpp
/// @date 2009-06-05 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "setup.hpp"
#if(!(GLM_ARCH & GLM_ARCH_SSE2))
# error "SSE2 instructions not supported or enabled"
#else
#include "intrinsic_geometric.hpp"
namespace glm{
namespace detail
{
void sse_add_ps(__m128 in1[4], __m128 in2[4], __m128 out[4]);
void sse_sub_ps(__m128 in1[4], __m128 in2[4], __m128 out[4]);
__m128 sse_mul_ps(__m128 m[4], __m128 v);
__m128 sse_mul_ps(__m128 v, __m128 m[4]);
void sse_mul_ps(__m128 const in1[4], __m128 const in2[4], __m128 out[4]);
void sse_transpose_ps(__m128 const in[4], __m128 out[4]);
void sse_inverse_ps(__m128 const in[4], __m128 out[4]);
void sse_rotate_ps(__m128 const in[4], float Angle, float const v[3], __m128 out[4]);
__m128 sse_det_ps(__m128 const m[4]);
__m128 sse_slow_det_ps(__m128 const m[4]);
}//namespace detail
}//namespace glm
#include "intrinsic_matrix.inl"
#endif//GLM_ARCH
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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 core
/// @file glm/detail/intrinsic_common.inl
/// @date 2009-06-05 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
namespace glm{
namespace detail{
static const __m128 GLM_VAR_USED _m128_rad_ps = _mm_set_ps1(3.141592653589793238462643383279f / 180.f);
static const __m128 GLM_VAR_USED _m128_deg_ps = _mm_set_ps1(180.f / 3.141592653589793238462643383279f);
template <typename matType>
GLM_FUNC_QUALIFIER matType sse_comp_mul_ps
(
__m128 const in1[4],
__m128 const in2[4],
__m128 out[4]
)
{
out[0] = _mm_mul_ps(in1[0], in2[0]);
out[1] = _mm_mul_ps(in1[1], in2[1]);
out[2] = _mm_mul_ps(in1[2], in2[2]);
out[3] = _mm_mul_ps(in1[3], in2[3]);
}
GLM_FUNC_QUALIFIER void sse_add_ps(__m128 const in1[4], __m128 const in2[4], __m128 out[4])
{
{
out[0] = _mm_add_ps(in1[0], in2[0]);
out[1] = _mm_add_ps(in1[1], in2[1]);
out[2] = _mm_add_ps(in1[2], in2[2]);
out[3] = _mm_add_ps(in1[3], in2[3]);
}
}
GLM_FUNC_QUALIFIER void sse_sub_ps(__m128 const in1[4], __m128 const in2[4], __m128 out[4])
{
{
out[0] = _mm_sub_ps(in1[0], in2[0]);
out[1] = _mm_sub_ps(in1[1], in2[1]);
out[2] = _mm_sub_ps(in1[2], in2[2]);
out[3] = _mm_sub_ps(in1[3], in2[3]);
}
}
GLM_FUNC_QUALIFIER __m128 sse_mul_ps(__m128 const m[4], __m128 v)
{
__m128 v0 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
__m128 v1 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
__m128 v2 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
__m128 v3 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 3, 3, 3));
__m128 m0 = _mm_mul_ps(m[0], v0);
__m128 m1 = _mm_mul_ps(m[1], v1);
__m128 m2 = _mm_mul_ps(m[2], v2);
__m128 m3 = _mm_mul_ps(m[3], v3);
__m128 a0 = _mm_add_ps(m0, m1);
__m128 a1 = _mm_add_ps(m2, m3);
__m128 a2 = _mm_add_ps(a0, a1);
return a2;
}
GLM_FUNC_QUALIFIER __m128 sse_mul_ps(__m128 v, __m128 const m[4])
{
__m128 i0 = m[0];
__m128 i1 = m[1];
__m128 i2 = m[2];
__m128 i3 = m[3];
__m128 m0 = _mm_mul_ps(v, i0);
__m128 m1 = _mm_mul_ps(v, i1);
__m128 m2 = _mm_mul_ps(v, i2);
__m128 m3 = _mm_mul_ps(v, i3);
__m128 u0 = _mm_unpacklo_ps(m0, m1);
__m128 u1 = _mm_unpackhi_ps(m0, m1);
__m128 a0 = _mm_add_ps(u0, u1);
__m128 u2 = _mm_unpacklo_ps(m2, m3);
__m128 u3 = _mm_unpackhi_ps(m2, m3);
__m128 a1 = _mm_add_ps(u2, u3);
__m128 f0 = _mm_movelh_ps(a0, a1);
__m128 f1 = _mm_movehl_ps(a1, a0);
__m128 f2 = _mm_add_ps(f0, f1);
return f2;
}
GLM_FUNC_QUALIFIER void sse_mul_ps(__m128 const in1[4], __m128 const in2[4], __m128 out[4])
{
{
__m128 e0 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(0, 0, 0, 0));
__m128 e1 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(1, 1, 1, 1));
__m128 e2 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(2, 2, 2, 2));
__m128 e3 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(3, 3, 3, 3));
__m128 m0 = _mm_mul_ps(in1[0], e0);
__m128 m1 = _mm_mul_ps(in1[1], e1);
__m128 m2 = _mm_mul_ps(in1[2], e2);
__m128 m3 = _mm_mul_ps(in1[3], e3);
__m128 a0 = _mm_add_ps(m0, m1);
__m128 a1 = _mm_add_ps(m2, m3);
__m128 a2 = _mm_add_ps(a0, a1);
out[0] = a2;
}
{
__m128 e0 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(0, 0, 0, 0));
__m128 e1 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(1, 1, 1, 1));
__m128 e2 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(2, 2, 2, 2));
__m128 e3 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(3, 3, 3, 3));
__m128 m0 = _mm_mul_ps(in1[0], e0);
__m128 m1 = _mm_mul_ps(in1[1], e1);
__m128 m2 = _mm_mul_ps(in1[2], e2);
__m128 m3 = _mm_mul_ps(in1[3], e3);
__m128 a0 = _mm_add_ps(m0, m1);
__m128 a1 = _mm_add_ps(m2, m3);
__m128 a2 = _mm_add_ps(a0, a1);
out[1] = a2;
}
{
__m128 e0 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(0, 0, 0, 0));
__m128 e1 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(1, 1, 1, 1));
__m128 e2 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(2, 2, 2, 2));
__m128 e3 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(3, 3, 3, 3));
__m128 m0 = _mm_mul_ps(in1[0], e0);
__m128 m1 = _mm_mul_ps(in1[1], e1);
__m128 m2 = _mm_mul_ps(in1[2], e2);
__m128 m3 = _mm_mul_ps(in1[3], e3);
__m128 a0 = _mm_add_ps(m0, m1);
__m128 a1 = _mm_add_ps(m2, m3);
__m128 a2 = _mm_add_ps(a0, a1);
out[2] = a2;
}
{
//(__m128&)_mm_shuffle_epi32(__m128i&)in2[0], _MM_SHUFFLE(3, 3, 3, 3))
__m128 e0 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(0, 0, 0, 0));
__m128 e1 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(1, 1, 1, 1));
__m128 e2 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(2, 2, 2, 2));
__m128 e3 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(3, 3, 3, 3));
__m128 m0 = _mm_mul_ps(in1[0], e0);
__m128 m1 = _mm_mul_ps(in1[1], e1);
__m128 m2 = _mm_mul_ps(in1[2], e2);
__m128 m3 = _mm_mul_ps(in1[3], e3);
__m128 a0 = _mm_add_ps(m0, m1);
__m128 a1 = _mm_add_ps(m2, m3);
__m128 a2 = _mm_add_ps(a0, a1);
out[3] = a2;
}
}
GLM_FUNC_QUALIFIER void sse_transpose_ps(__m128 const in[4], __m128 out[4])
{
__m128 tmp0 = _mm_shuffle_ps(in[0], in[1], 0x44);
__m128 tmp2 = _mm_shuffle_ps(in[0], in[1], 0xEE);
__m128 tmp1 = _mm_shuffle_ps(in[2], in[3], 0x44);
__m128 tmp3 = _mm_shuffle_ps(in[2], in[3], 0xEE);
out[0] = _mm_shuffle_ps(tmp0, tmp1, 0x88);
out[1] = _mm_shuffle_ps(tmp0, tmp1, 0xDD);
out[2] = _mm_shuffle_ps(tmp2, tmp3, 0x88);
out[3] = _mm_shuffle_ps(tmp2, tmp3, 0xDD);
}
GLM_FUNC_QUALIFIER __m128 sse_slow_det_ps(__m128 const in[4])
{
__m128 Fac0;
{
// valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
// valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
// valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
// valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac0 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac1;
{
// valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
// valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
// valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
// valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac1 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac2;
{
// valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
// valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
// valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
// valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac2 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac3;
{
// valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
// valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
// valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
// valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac3 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac4;
{
// valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
// valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
// valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
// valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac4 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac5;
{
// valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
// valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
// valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
// valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac5 = _mm_sub_ps(Mul00, Mul01);
}
__m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f);
__m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f);
// m[1][0]
// m[0][0]
// m[0][0]
// m[0][0]
__m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0));
// m[1][1]
// m[0][1]
// m[0][1]
// m[0][1]
__m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0));
// m[1][2]
// m[0][2]
// m[0][2]
// m[0][2]
__m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0));
// m[1][3]
// m[0][3]
// m[0][3]
// m[0][3]
__m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0));
// col0
// + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]),
// - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]),
// + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]),
// - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]),
__m128 Mul00 = _mm_mul_ps(Vec1, Fac0);
__m128 Mul01 = _mm_mul_ps(Vec2, Fac1);
__m128 Mul02 = _mm_mul_ps(Vec3, Fac2);
__m128 Sub00 = _mm_sub_ps(Mul00, Mul01);
__m128 Add00 = _mm_add_ps(Sub00, Mul02);
__m128 Inv0 = _mm_mul_ps(SignB, Add00);
// col1
// - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]),
// + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]),
// - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]),
// + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]),
__m128 Mul03 = _mm_mul_ps(Vec0, Fac0);
__m128 Mul04 = _mm_mul_ps(Vec2, Fac3);
__m128 Mul05 = _mm_mul_ps(Vec3, Fac4);
__m128 Sub01 = _mm_sub_ps(Mul03, Mul04);
__m128 Add01 = _mm_add_ps(Sub01, Mul05);
__m128 Inv1 = _mm_mul_ps(SignA, Add01);
// col2
// + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]),
// - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]),
// + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]),
// - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]),
__m128 Mul06 = _mm_mul_ps(Vec0, Fac1);
__m128 Mul07 = _mm_mul_ps(Vec1, Fac3);
__m128 Mul08 = _mm_mul_ps(Vec3, Fac5);
__m128 Sub02 = _mm_sub_ps(Mul06, Mul07);
__m128 Add02 = _mm_add_ps(Sub02, Mul08);
__m128 Inv2 = _mm_mul_ps(SignB, Add02);
// col3
// - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]),
// + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]),
// - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]),
// + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3]));
__m128 Mul09 = _mm_mul_ps(Vec0, Fac2);
__m128 Mul10 = _mm_mul_ps(Vec1, Fac4);
__m128 Mul11 = _mm_mul_ps(Vec2, Fac5);
__m128 Sub03 = _mm_sub_ps(Mul09, Mul10);
__m128 Add03 = _mm_add_ps(Sub03, Mul11);
__m128 Inv3 = _mm_mul_ps(SignA, Add03);
__m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0));
__m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0));
__m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0));
// valType Determinant = m[0][0] * Inverse[0][0]
// + m[0][1] * Inverse[1][0]
// + m[0][2] * Inverse[2][0]
// + m[0][3] * Inverse[3][0];
__m128 Det0 = sse_dot_ps(in[0], Row2);
return Det0;
}
GLM_FUNC_QUALIFIER __m128 sse_detd_ps
(
__m128 const m[4]
)
{
// _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(
//T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
//T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
//T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
//T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
//T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
//T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
// First 2 columns
__m128 Swp2A = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(0, 1, 1, 2)));
__m128 Swp3A = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(3, 2, 3, 3)));
__m128 MulA = _mm_mul_ps(Swp2A, Swp3A);
// Second 2 columns
__m128 Swp2B = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(3, 2, 3, 3)));
__m128 Swp3B = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(0, 1, 1, 2)));
__m128 MulB = _mm_mul_ps(Swp2B, Swp3B);
// Columns subtraction
__m128 SubE = _mm_sub_ps(MulA, MulB);
// Last 2 rows
__m128 Swp2C = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(0, 0, 1, 2)));
__m128 Swp3C = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(1, 2, 0, 0)));
__m128 MulC = _mm_mul_ps(Swp2C, Swp3C);
__m128 SubF = _mm_sub_ps(_mm_movehl_ps(MulC, MulC), MulC);
//tvec4<T, P> DetCof(
// + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02),
// - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04),
// + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05),
// - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05));
__m128 SubFacA = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubE), _MM_SHUFFLE(2, 1, 0, 0)));
__m128 SwpFacA = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(0, 0, 0, 1)));
__m128 MulFacA = _mm_mul_ps(SwpFacA, SubFacA);
__m128 SubTmpB = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(0, 0, 3, 1));
__m128 SubFacB = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubTmpB), _MM_SHUFFLE(3, 1, 1, 0)));//SubF[0], SubE[3], SubE[3], SubE[1];
__m128 SwpFacB = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(1, 1, 2, 2)));
__m128 MulFacB = _mm_mul_ps(SwpFacB, SubFacB);
__m128 SubRes = _mm_sub_ps(MulFacA, MulFacB);
__m128 SubTmpC = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(1, 0, 2, 2));
__m128 SubFacC = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubTmpC), _MM_SHUFFLE(3, 3, 2, 0)));
__m128 SwpFacC = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(2, 3, 3, 3)));
__m128 MulFacC = _mm_mul_ps(SwpFacC, SubFacC);
__m128 AddRes = _mm_add_ps(SubRes, MulFacC);
__m128 DetCof = _mm_mul_ps(AddRes, _mm_setr_ps( 1.0f,-1.0f, 1.0f,-1.0f));
//return m[0][0] * DetCof[0]
// + m[0][1] * DetCof[1]
// + m[0][2] * DetCof[2]
// + m[0][3] * DetCof[3];
return sse_dot_ps(m[0], DetCof);
}
GLM_FUNC_QUALIFIER __m128 sse_det_ps
(
__m128 const m[4]
)
{
// _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(add)
//T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
//T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
//T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
//T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
//T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
//T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
// First 2 columns
__m128 Swp2A = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(0, 1, 1, 2));
__m128 Swp3A = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(3, 2, 3, 3));
__m128 MulA = _mm_mul_ps(Swp2A, Swp3A);
// Second 2 columns
__m128 Swp2B = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(3, 2, 3, 3));
__m128 Swp3B = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(0, 1, 1, 2));
__m128 MulB = _mm_mul_ps(Swp2B, Swp3B);
// Columns subtraction
__m128 SubE = _mm_sub_ps(MulA, MulB);
// Last 2 rows
__m128 Swp2C = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(0, 0, 1, 2));
__m128 Swp3C = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(1, 2, 0, 0));
__m128 MulC = _mm_mul_ps(Swp2C, Swp3C);
__m128 SubF = _mm_sub_ps(_mm_movehl_ps(MulC, MulC), MulC);
//tvec4<T, P> DetCof(
// + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02),
// - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04),
// + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05),
// - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05));
__m128 SubFacA = _mm_shuffle_ps(SubE, SubE, _MM_SHUFFLE(2, 1, 0, 0));
__m128 SwpFacA = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(0, 0, 0, 1));
__m128 MulFacA = _mm_mul_ps(SwpFacA, SubFacA);
__m128 SubTmpB = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(0, 0, 3, 1));
__m128 SubFacB = _mm_shuffle_ps(SubTmpB, SubTmpB, _MM_SHUFFLE(3, 1, 1, 0));//SubF[0], SubE[3], SubE[3], SubE[1];
__m128 SwpFacB = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(1, 1, 2, 2));
__m128 MulFacB = _mm_mul_ps(SwpFacB, SubFacB);
__m128 SubRes = _mm_sub_ps(MulFacA, MulFacB);
__m128 SubTmpC = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(1, 0, 2, 2));
__m128 SubFacC = _mm_shuffle_ps(SubTmpC, SubTmpC, _MM_SHUFFLE(3, 3, 2, 0));
__m128 SwpFacC = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(2, 3, 3, 3));
__m128 MulFacC = _mm_mul_ps(SwpFacC, SubFacC);
__m128 AddRes = _mm_add_ps(SubRes, MulFacC);
__m128 DetCof = _mm_mul_ps(AddRes, _mm_setr_ps( 1.0f,-1.0f, 1.0f,-1.0f));
//return m[0][0] * DetCof[0]
// + m[0][1] * DetCof[1]
// + m[0][2] * DetCof[2]
// + m[0][3] * DetCof[3];
return sse_dot_ps(m[0], DetCof);
}
GLM_FUNC_QUALIFIER void sse_inverse_ps(__m128 const in[4], __m128 out[4])
{
__m128 Fac0;
{
// valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
// valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
// valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
// valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac0 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac1;
{
// valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
// valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
// valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
// valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac1 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac2;
{
// valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
// valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
// valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
// valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac2 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac3;
{
// valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
// valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
// valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
// valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac3 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac4;
{
// valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
// valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
// valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
// valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac4 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac5;
{
// valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
// valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
// valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
// valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac5 = _mm_sub_ps(Mul00, Mul01);
}
__m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f);
__m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f);
// m[1][0]
// m[0][0]
// m[0][0]
// m[0][0]
__m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0));
// m[1][1]
// m[0][1]
// m[0][1]
// m[0][1]
__m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0));
// m[1][2]
// m[0][2]
// m[0][2]
// m[0][2]
__m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0));
// m[1][3]
// m[0][3]
// m[0][3]
// m[0][3]
__m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0));
// col0
// + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]),
// - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]),
// + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]),
// - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]),
__m128 Mul00 = _mm_mul_ps(Vec1, Fac0);
__m128 Mul01 = _mm_mul_ps(Vec2, Fac1);
__m128 Mul02 = _mm_mul_ps(Vec3, Fac2);
__m128 Sub00 = _mm_sub_ps(Mul00, Mul01);
__m128 Add00 = _mm_add_ps(Sub00, Mul02);
__m128 Inv0 = _mm_mul_ps(SignB, Add00);
// col1
// - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]),
// + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]),
// - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]),
// + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]),
__m128 Mul03 = _mm_mul_ps(Vec0, Fac0);
__m128 Mul04 = _mm_mul_ps(Vec2, Fac3);
__m128 Mul05 = _mm_mul_ps(Vec3, Fac4);
__m128 Sub01 = _mm_sub_ps(Mul03, Mul04);
__m128 Add01 = _mm_add_ps(Sub01, Mul05);
__m128 Inv1 = _mm_mul_ps(SignA, Add01);
// col2
// + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]),
// - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]),
// + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]),
// - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]),
__m128 Mul06 = _mm_mul_ps(Vec0, Fac1);
__m128 Mul07 = _mm_mul_ps(Vec1, Fac3);
__m128 Mul08 = _mm_mul_ps(Vec3, Fac5);
__m128 Sub02 = _mm_sub_ps(Mul06, Mul07);
__m128 Add02 = _mm_add_ps(Sub02, Mul08);
__m128 Inv2 = _mm_mul_ps(SignB, Add02);
// col3
// - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]),
// + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]),
// - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]),
// + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3]));
__m128 Mul09 = _mm_mul_ps(Vec0, Fac2);
__m128 Mul10 = _mm_mul_ps(Vec1, Fac4);
__m128 Mul11 = _mm_mul_ps(Vec2, Fac5);
__m128 Sub03 = _mm_sub_ps(Mul09, Mul10);
__m128 Add03 = _mm_add_ps(Sub03, Mul11);
__m128 Inv3 = _mm_mul_ps(SignA, Add03);
__m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0));
__m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0));
__m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0));
// valType Determinant = m[0][0] * Inverse[0][0]
// + m[0][1] * Inverse[1][0]
// + m[0][2] * Inverse[2][0]
// + m[0][3] * Inverse[3][0];
__m128 Det0 = sse_dot_ps(in[0], Row2);
__m128 Rcp0 = _mm_div_ps(one, Det0);
//__m128 Rcp0 = _mm_rcp_ps(Det0);
// Inverse /= Determinant;
out[0] = _mm_mul_ps(Inv0, Rcp0);
out[1] = _mm_mul_ps(Inv1, Rcp0);
out[2] = _mm_mul_ps(Inv2, Rcp0);
out[3] = _mm_mul_ps(Inv3, Rcp0);
}
GLM_FUNC_QUALIFIER void sse_inverse_fast_ps(__m128 const in[4], __m128 out[4])
{
__m128 Fac0;
{
// valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
// valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
// valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
// valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac0 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac1;
{
// valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
// valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
// valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
// valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac1 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac2;
{
// valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
// valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
// valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
// valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac2 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac3;
{
// valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
// valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
// valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
// valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac3 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac4;
{
// valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
// valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
// valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
// valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac4 = _mm_sub_ps(Mul00, Mul01);
}
__m128 Fac5;
{
// valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
// valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
// valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
// valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
__m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0));
__m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Mul00 = _mm_mul_ps(Swp00, Swp01);
__m128 Mul01 = _mm_mul_ps(Swp02, Swp03);
Fac5 = _mm_sub_ps(Mul00, Mul01);
}
__m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f);
__m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f);
// m[1][0]
// m[0][0]
// m[0][0]
// m[0][0]
__m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0));
__m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0));
// m[1][1]
// m[0][1]
// m[0][1]
// m[0][1]
__m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1));
__m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0));
// m[1][2]
// m[0][2]
// m[0][2]
// m[0][2]
__m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2));
__m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0));
// m[1][3]
// m[0][3]
// m[0][3]
// m[0][3]
__m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3));
__m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0));
// col0
// + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]),
// - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]),
// + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]),
// - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]),
__m128 Mul00 = _mm_mul_ps(Vec1, Fac0);
__m128 Mul01 = _mm_mul_ps(Vec2, Fac1);
__m128 Mul02 = _mm_mul_ps(Vec3, Fac2);
__m128 Sub00 = _mm_sub_ps(Mul00, Mul01);
__m128 Add00 = _mm_add_ps(Sub00, Mul02);
__m128 Inv0 = _mm_mul_ps(SignB, Add00);
// col1
// - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]),
// + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]),
// - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]),
// + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]),
__m128 Mul03 = _mm_mul_ps(Vec0, Fac0);
__m128 Mul04 = _mm_mul_ps(Vec2, Fac3);
__m128 Mul05 = _mm_mul_ps(Vec3, Fac4);
__m128 Sub01 = _mm_sub_ps(Mul03, Mul04);
__m128 Add01 = _mm_add_ps(Sub01, Mul05);
__m128 Inv1 = _mm_mul_ps(SignA, Add01);
// col2
// + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]),
// - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]),
// + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]),
// - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]),
__m128 Mul06 = _mm_mul_ps(Vec0, Fac1);
__m128 Mul07 = _mm_mul_ps(Vec1, Fac3);
__m128 Mul08 = _mm_mul_ps(Vec3, Fac5);
__m128 Sub02 = _mm_sub_ps(Mul06, Mul07);
__m128 Add02 = _mm_add_ps(Sub02, Mul08);
__m128 Inv2 = _mm_mul_ps(SignB, Add02);
// col3
// - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]),
// + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]),
// - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]),
// + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3]));
__m128 Mul09 = _mm_mul_ps(Vec0, Fac2);
__m128 Mul10 = _mm_mul_ps(Vec1, Fac4);
__m128 Mul11 = _mm_mul_ps(Vec2, Fac5);
__m128 Sub03 = _mm_sub_ps(Mul09, Mul10);
__m128 Add03 = _mm_add_ps(Sub03, Mul11);
__m128 Inv3 = _mm_mul_ps(SignA, Add03);
__m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0));
__m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0));
__m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0));
// valType Determinant = m[0][0] * Inverse[0][0]
// + m[0][1] * Inverse[1][0]
// + m[0][2] * Inverse[2][0]
// + m[0][3] * Inverse[3][0];
__m128 Det0 = sse_dot_ps(in[0], Row2);
__m128 Rcp0 = _mm_rcp_ps(Det0);
//__m128 Rcp0 = _mm_div_ps(one, Det0);
// Inverse /= Determinant;
out[0] = _mm_mul_ps(Inv0, Rcp0);
out[1] = _mm_mul_ps(Inv1, Rcp0);
out[2] = _mm_mul_ps(Inv2, Rcp0);
out[3] = _mm_mul_ps(Inv3, Rcp0);
}
/*
GLM_FUNC_QUALIFIER void sse_rotate_ps(__m128 const in[4], float Angle, float const v[3], __m128 out[4])
{
float a = glm::radians(Angle);
float c = cos(a);
float s = sin(a);
glm::vec4 AxisA(v[0], v[1], v[2], float(0));
__m128 AxisB = _mm_set_ps(AxisA.w, AxisA.z, AxisA.y, AxisA.x);
__m128 AxisC = detail::sse_nrm_ps(AxisB);
__m128 Cos0 = _mm_set_ss(c);
__m128 CosA = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(0, 0, 0, 0));
__m128 Sin0 = _mm_set_ss(s);
__m128 SinA = _mm_shuffle_ps(Sin0, Sin0, _MM_SHUFFLE(0, 0, 0, 0));
// tvec3<T, P> temp = (valType(1) - c) * axis;
__m128 Temp0 = _mm_sub_ps(one, CosA);
__m128 Temp1 = _mm_mul_ps(Temp0, AxisC);
//Rotate[0][0] = c + temp[0] * axis[0];
//Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2];
//Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1];
__m128 Axis0 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(0, 0, 0, 0));
__m128 TmpA0 = _mm_mul_ps(Axis0, AxisC);
__m128 CosA0 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 1, 1, 0));
__m128 TmpA1 = _mm_add_ps(CosA0, TmpA0);
__m128 SinA0 = SinA;//_mm_set_ps(0.0f, s, -s, 0.0f);
__m128 TmpA2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 1, 2, 3));
__m128 TmpA3 = _mm_mul_ps(SinA0, TmpA2);
__m128 TmpA4 = _mm_add_ps(TmpA1, TmpA3);
//Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2];
//Rotate[1][1] = c + temp[1] * axis[1];
//Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0];
__m128 Axis1 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(1, 1, 1, 1));
__m128 TmpB0 = _mm_mul_ps(Axis1, AxisC);
__m128 CosA1 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 1, 0, 1));
__m128 TmpB1 = _mm_add_ps(CosA1, TmpB0);
__m128 SinB0 = SinA;//_mm_set_ps(-s, 0.0f, s, 0.0f);
__m128 TmpB2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 0, 3, 2));
__m128 TmpB3 = _mm_mul_ps(SinA0, TmpB2);
__m128 TmpB4 = _mm_add_ps(TmpB1, TmpB3);
//Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1];
//Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0];
//Rotate[2][2] = c + temp[2] * axis[2];
__m128 Axis2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(2, 2, 2, 2));
__m128 TmpC0 = _mm_mul_ps(Axis2, AxisC);
__m128 CosA2 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 0, 1, 1));
__m128 TmpC1 = _mm_add_ps(CosA2, TmpC0);
__m128 SinC0 = SinA;//_mm_set_ps(s, -s, 0.0f, 0.0f);
__m128 TmpC2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 3, 0, 1));
__m128 TmpC3 = _mm_mul_ps(SinA0, TmpC2);
__m128 TmpC4 = _mm_add_ps(TmpC1, TmpC3);
__m128 Result[4];
Result[0] = TmpA4;
Result[1] = TmpB4;
Result[2] = TmpC4;
Result[3] = _mm_set_ps(1, 0, 0, 0);
//tmat4x4<valType> Result(uninitialize);
//Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2];
//Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2];
//Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2];
//Result[3] = m[3];
//return Result;
sse_mul_ps(in, Result, out);
}
*/
GLM_FUNC_QUALIFIER void sse_outer_ps(__m128 const & c, __m128 const & r, __m128 out[4])
{
out[0] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(0, 0, 0, 0)));
out[1] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(1, 1, 1, 1)));
out[2] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(2, 2, 2, 2)));
out[3] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(3, 3, 3, 3)));
}
}//namespace detail
}//namespace glm
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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 core
/// @file glm/detail/intrinsic_trigonometric.hpp
/// @date 2009-06-09 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "setup.hpp"
#if(!(GLM_ARCH & GLM_ARCH_SSE2))
# error "SSE2 instructions not supported or enabled"
#else
namespace glm{
namespace detail
{
}//namespace detail
}//namespace glm
#include "intrinsic_trigonometric.inl"
#endif//GLM_ARCH
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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 core
/// @file glm/detail/intrinsic_trigonometric.inl
/// @date 2011-06-15 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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 core
/// @file glm/detail/intrinsic_vector_relational.hpp
/// @date 2009-06-09 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "setup.hpp"
#if(!(GLM_ARCH & GLM_ARCH_SSE2))
# error "SSE2 instructions not supported or enabled"
#else
namespace glm{
namespace detail
{
}//namespace detail
}//namespace glm
#include "intrinsic_vector_relational.inl"
#endif//GLM_ARCH
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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 core
/// @file glm/detail/intrinsic_vector_relational.inl
/// @date 2009-06-09 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
//
//// lessThan
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec2<T, P>::bool_type lessThan
//(
// tvec2<T, P> const & x,
// tvec2<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec2<bool>::bool_type(x.x < y.x, x.y < y.y);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec3<T, P>::bool_type lessThan
//(
// tvec3<T, P> const & x,
// tvec3<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec3<bool>::bool_type(x.x < y.x, x.y < y.y, x.z < y.z);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec4<T, P>::bool_type lessThan
//(
// tvec4<T, P> const & x,
// tvec4<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec4<bool>::bool_type(x.x < y.x, x.y < y.y, x.z < y.z, x.w < y.w);
//}
//
//// lessThanEqual
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec2<T, P>::bool_type lessThanEqual
//(
// tvec2<T, P> const & x,
// tvec2<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec2<bool>::bool_type(x.x <= y.x, x.y <= y.y);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec3<T, P>::bool_type lessThanEqual
//(
// tvec3<T, P> const & x,
// tvec3<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec3<bool>::bool_type(x.x <= y.x, x.y <= y.y, x.z <= y.z);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec4<T, P>::bool_type lessThanEqual
//(
// tvec4<T, P> const & x,
// tvec4<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec4<bool>::bool_type(x.x <= y.x, x.y <= y.y, x.z <= y.z, x.w <= y.w);
//}
//
//// greaterThan
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec2<T, P>::bool_type greaterThan
//(
// tvec2<T, P> const & x,
// tvec2<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec2<bool>::bool_type(x.x > y.x, x.y > y.y);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec3<T, P>::bool_type greaterThan
//(
// tvec3<T, P> const & x,
// tvec3<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec3<bool>::bool_type(x.x > y.x, x.y > y.y, x.z > y.z);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec4<T, P>::bool_type greaterThan
//(
// tvec4<T, P> const & x,
// tvec4<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec4<bool>::bool_type(x.x > y.x, x.y > y.y, x.z > y.z, x.w > y.w);
//}
//
//// greaterThanEqual
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec2<T, P>::bool_type greaterThanEqual
//(
// tvec2<T, P> const & x,
// tvec2<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec2<bool>::bool_type(x.x >= y.x, x.y >= y.y);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec3<T, P>::bool_type greaterThanEqual
//(
// tvec3<T, P> const & x,
// tvec3<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec3<bool>::bool_type(x.x >= y.x, x.y >= y.y, x.z >= y.z);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec4<T, P>::bool_type greaterThanEqual
//(
// tvec4<T, P> const & x,
// tvec4<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint);
//
// return typename tvec4<bool>::bool_type(x.x >= y.x, x.y >= y.y, x.z >= y.z, x.w >= y.w);
//}
//
//// equal
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec2<T, P>::bool_type equal
//(
// tvec2<T, P> const & x,
// tvec2<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint ||
// detail::type<valType>::is_bool);
//
// return typename tvec2<T, P>::bool_type(x.x == y.x, x.y == y.y);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec3<T, P>::bool_type equal
//(
// tvec3<T, P> const & x,
// tvec3<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint ||
// detail::type<valType>::is_bool);
//
// return typename tvec3<T, P>::bool_type(x.x == y.x, x.y == y.y, x.z == y.z);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec4<T, P>::bool_type equal
//(
// tvec4<T, P> const & x,
// tvec4<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint ||
// detail::type<valType>::is_bool);
//
// return typename tvec4<T, P>::bool_type(x.x == y.x, x.y == y.y, x.z == y.z, x.w == y.w);
//}
//
//// notEqual
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec2<T, P>::bool_type notEqual
//(
// tvec2<T, P> const & x,
// tvec2<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint ||
// detail::type<valType>::is_bool);
//
// return typename tvec2<T, P>::bool_type(x.x != y.x, x.y != y.y);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec3<T, P>::bool_type notEqual
//(
// tvec3<T, P> const & x,
// tvec3<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint ||
// detail::type<valType>::is_bool);
//
// return typename tvec3<T, P>::bool_type(x.x != y.x, x.y != y.y, x.z != y.z);
//}
//
//template <typename valType>
//GLM_FUNC_QUALIFIER typename tvec4<T, P>::bool_type notEqual
//(
// tvec4<T, P> const & x,
// tvec4<T, P> const & y
//)
//{
// GLM_STATIC_ASSERT(
// detail::type<valType>::is_float ||
// detail::type<valType>::is_int ||
// detail::type<valType>::is_uint ||
// detail::type<valType>::is_bool);
//
// return typename tvec4<T, P>::bool_type(x.x != y.x, x.y != y.y, x.z != y.z, x.w != y.w);
//}
//
//// any
//GLM_FUNC_QUALIFIER bool any(tvec2<bool> const & x)
//{
// return x.x || x.y;
//}
//
//GLM_FUNC_QUALIFIER bool any(tvec3<bool> const & x)
//{
// return x.x || x.y || x.z;
//}
//
//GLM_FUNC_QUALIFIER bool any(tvec4<bool> const & x)
//{
// return x.x || x.y || x.z || x.w;
//}
//
//// all
//GLM_FUNC_QUALIFIER bool all(const tvec2<bool>& x)
//{
// return x.x && x.y;
//}
//
//GLM_FUNC_QUALIFIER bool all(const tvec3<bool>& x)
//{
// return x.x && x.y && x.z;
//}
//
//GLM_FUNC_QUALIFIER bool all(const tvec4<bool>& x)
//{
// return x.x && x.y && x.z && x.w;
//}
//
//// not
//GLM_FUNC_QUALIFIER tvec2<bool>::bool_type not_
//(
// tvec2<bool> const & v
//)
//{
// return tvec2<bool>::bool_type(!v.x, !v.y);
//}
//
//GLM_FUNC_QUALIFIER tvec3<bool>::bool_type not_
//(
// tvec3<bool> const & v
//)
//{
// return tvec3<bool>::bool_type(!v.x, !v.y, !v.z);
//}
//
//GLM_FUNC_QUALIFIER tvec4<bool>::bool_type not_
//(
// tvec4<bool> const & v
//)
//{
// return tvec4<bool>::bool_type(!v.x, !v.y, !v.z, !v.w);
//}
\ No newline at end of file
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// 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 core
/// @file glm/detail/precision.hpp
/// @date 2013-04-01 / 2013-04-01
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
namespace glm
{
enum precision
{
highp,
mediump,
lowp,
defaultp = highp
};
}//namespace glm
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// 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 core
/// @file glm/detail/setup.hpp
/// @date 2006-11-13 / 2014-10-05
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <cassert>
#include <cstddef>
///////////////////////////////////////////////////////////////////////////////////
// Version
#define GLM_VERSION 96
#define GLM_VERSION_MAJOR 0
#define GLM_VERSION_MINOR 9
#define GLM_VERSION_PATCH 6
#define GLM_VERSION_REVISION 3
#if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_VERSION_DISPLAYED))
# define GLM_MESSAGE_VERSION_DISPLAYED
# pragma message ("GLM: version 0.9.6.3")
#endif//GLM_MESSAGE
///////////////////////////////////////////////////////////////////////////////////
// Platform
#define GLM_PLATFORM_UNKNOWN 0x00000000
#define GLM_PLATFORM_WINDOWS 0x00010000
#define GLM_PLATFORM_LINUX 0x00020000
#define GLM_PLATFORM_APPLE 0x00040000
//#define GLM_PLATFORM_IOS 0x00080000
#define GLM_PLATFORM_ANDROID 0x00100000
#define GLM_PLATFORM_CHROME_NACL 0x00200000
#define GLM_PLATFORM_UNIX 0x00400000
#define GLM_PLATFORM_QNXNTO 0x00800000
#define GLM_PLATFORM_WINCE 0x01000000
#ifdef GLM_FORCE_PLATFORM_UNKNOWN
# define GLM_PLATFORM GLM_PLATFORM_UNKNOWN
#elif defined(__QNXNTO__)
# define GLM_PLATFORM GLM_PLATFORM_QNXNTO
#elif defined(__APPLE__)
# define GLM_PLATFORM GLM_PLATFORM_APPLE
#elif defined(WINCE)
# define GLM_PLATFORM GLM_PLATFORM_WINCE
#elif defined(_WIN32)
# define GLM_PLATFORM GLM_PLATFORM_WINDOWS
#elif defined(__native_client__)
# define GLM_PLATFORM GLM_PLATFORM_CHROME_NACL
#elif defined(__ANDROID__)
# define GLM_PLATFORM GLM_PLATFORM_ANDROID
#elif defined(__linux)
# define GLM_PLATFORM GLM_PLATFORM_LINUX
#elif defined(__unix)
# define GLM_PLATFORM GLM_PLATFORM_UNIX
#else
# define GLM_PLATFORM GLM_PLATFORM_UNKNOWN
#endif//
// Report platform detection
#if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_PLATFORM_DISPLAYED))
# define GLM_MESSAGE_PLATFORM_DISPLAYED
# if(GLM_PLATFORM & GLM_PLATFORM_QNXNTO)
# pragma message("GLM: QNX platform detected")
//# elif(GLM_PLATFORM & GLM_PLATFORM_IOS)
//# pragma message("GLM: iOS platform detected")
# elif(GLM_PLATFORM & GLM_PLATFORM_APPLE)
# pragma message("GLM: Apple platform detected")
# elif(GLM_PLATFORM & GLM_PLATFORM_WINCE)
# pragma message("GLM: WinCE platform detected")
# elif(GLM_PLATFORM & GLM_PLATFORM_WINDOWS)
# pragma message("GLM: Windows platform detected")
# elif(GLM_PLATFORM & GLM_PLATFORM_CHROME_NACL)
# pragma message("GLM: Native Client detected")
# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID)
# pragma message("GLM: Android platform detected")
# elif(GLM_PLATFORM & GLM_PLATFORM_LINUX)
# pragma message("GLM: Linux platform detected")
# elif(GLM_PLATFORM & GLM_PLATFORM_UNIX)
# pragma message("GLM: UNIX platform detected")
# elif(GLM_PLATFORM & GLM_PLATFORM_UNKNOWN)
# pragma message("GLM: platform unknown")
# else
# pragma message("GLM: platform not detected")
# endif
#endif//GLM_MESSAGE
///////////////////////////////////////////////////////////////////////////////////
// Compiler
// User defines: GLM_FORCE_COMPILER_UNKNOWN
// TODO ? __llvm__
#define GLM_COMPILER_UNKNOWN 0x00000000
// Intel
#define GLM_COMPILER_INTEL 0x00100000
#define GLM_COMPILER_INTEL12 0x00100010
#define GLM_COMPILER_INTEL12_1 0x00100020
#define GLM_COMPILER_INTEL13 0x00100030
#define GLM_COMPILER_INTEL14 0x00100040
#define GLM_COMPILER_INTEL15 0x00100050
// Visual C++ defines
#define GLM_COMPILER_VC 0x01000000
#define GLM_COMPILER_VC2010 0x01000090
#define GLM_COMPILER_VC2012 0x010000A0
#define GLM_COMPILER_VC2013 0x010000B0
#define GLM_COMPILER_VC2015 0x010000C0
// GCC defines
#define GLM_COMPILER_GCC 0x02000000
#define GLM_COMPILER_GCC44 0x020000B0
#define GLM_COMPILER_GCC45 0x020000C0
#define GLM_COMPILER_GCC46 0x020000D0
#define GLM_COMPILER_GCC47 0x020000E0
#define GLM_COMPILER_GCC48 0x020000F0
#define GLM_COMPILER_GCC49 0x02000100
#define GLM_COMPILER_GCC50 0x02000200
// CUDA
#define GLM_COMPILER_CUDA 0x10000000
#define GLM_COMPILER_CUDA40 0x10000040
#define GLM_COMPILER_CUDA41 0x10000050
#define GLM_COMPILER_CUDA42 0x10000060
#define GLM_COMPILER_CUDA50 0x10000070
#define GLM_COMPILER_CUDA60 0x10000080
#define GLM_COMPILER_CUDA65 0x10000090
// LLVM
#define GLM_COMPILER_LLVM 0x20000000
#define GLM_COMPILER_LLVM32 0x20000030
#define GLM_COMPILER_LLVM33 0x20000040
#define GLM_COMPILER_LLVM34 0x20000050
#define GLM_COMPILER_LLVM35 0x20000060
// Apple Clang
#define GLM_COMPILER_APPLE_CLANG 0x40000000
#define GLM_COMPILER_APPLE_CLANG40 0x40000010
#define GLM_COMPILER_APPLE_CLANG41 0x40000020
#define GLM_COMPILER_APPLE_CLANG42 0x40000030
#define GLM_COMPILER_APPLE_CLANG50 0x40000040
#define GLM_COMPILER_APPLE_CLANG51 0x40000050
#define GLM_COMPILER_APPLE_CLANG60 0x40000060
// Build model
#define GLM_MODEL_32 0x00000010
#define GLM_MODEL_64 0x00000020
// Force generic C++ compiler
#ifdef GLM_FORCE_COMPILER_UNKNOWN
# define GLM_COMPILER GLM_COMPILER_UNKNOWN
#elif defined(__INTEL_COMPILER)
# if __INTEL_COMPILER == 1200
# define GLM_COMPILER GLM_COMPILER_INTEL12
# elif __INTEL_COMPILER == 1210
# define GLM_COMPILER GLM_COMPILER_INTEL12_1
# elif __INTEL_COMPILER == 1300
# define GLM_COMPILER GLM_COMPILER_INTEL13
# elif __INTEL_COMPILER == 1400
# define GLM_COMPILER GLM_COMPILER_INTEL14
# elif __INTEL_COMPILER >= 1500
# define GLM_COMPILER GLM_COMPILER_INTEL15
# else
# define GLM_COMPILER GLM_COMPILER_INTEL
# endif
// CUDA
#elif defined(__CUDACC__)
# if !defined(CUDA_VERSION) && !defined(GLM_FORCE_CUDA)
# include <cuda.h> // make sure version is defined since nvcc does not define it itself!
# endif
# if CUDA_VERSION < 3000
# error "GLM requires CUDA 3.0 or higher"
# else
# define GLM_COMPILER GLM_COMPILER_CUDA
# endif
// Visual C++
#elif defined(_MSC_VER)
# if _MSC_VER < 1600
# error "GLM requires Visual C++ 2010 or higher"
# elif _MSC_VER == 1600
# define GLM_COMPILER GLM_COMPILER_VC2010
# elif _MSC_VER == 1700
# define GLM_COMPILER GLM_COMPILER_VC2012
# elif _MSC_VER == 1800
# define GLM_COMPILER GLM_COMPILER_VC2013
# elif _MSC_VER >= 1900
# define GLM_COMPILER GLM_COMPILER_VC2015
# else//_MSC_VER
# define GLM_COMPILER GLM_COMPILER_VC
# endif//_MSC_VER
// Clang
#elif defined(__clang__)
# if GLM_PLATFORM & GLM_PLATFORM_APPLE
# if __clang_major__ == 4 && __clang_minor__ == 0
# define GLM_COMPILER GLM_COMPILER_APPLE_CLANG40
# elif __clang_major__ == 4 && __clang_minor__ == 1
# define GLM_COMPILER GLM_COMPILER_APPLE_CLANG41
# elif __clang_major__ == 4 && __clang_minor__ == 2
# define GLM_COMPILER GLM_COMPILER_APPLE_CLANG42
# elif __clang_major__ == 5 && __clang_minor__ == 0
# define GLM_COMPILER GLM_COMPILER_APPLE_CLANG50
# elif __clang_major__ == 5 && __clang_minor__ == 1
# define GLM_COMPILER GLM_COMPILER_APPLE_CLANG51
# elif __clang_major__ >= 6
# define GLM_COMPILER GLM_COMPILER_APPLE_CLANG60
# endif
# else
# if __clang_major__ == 3 && __clang_minor__ == 0
# define GLM_COMPILER GLM_COMPILER_LLVM30
# elif __clang_major__ == 3 && __clang_minor__ == 1
# define GLM_COMPILER GLM_COMPILER_LLVM31
# elif __clang_major__ == 3 && __clang_minor__ == 2
# define GLM_COMPILER GLM_COMPILER_LLVM32
# elif __clang_major__ == 3 && __clang_minor__ == 3
# define GLM_COMPILER GLM_COMPILER_LLVM33
# elif __clang_major__ == 3 && __clang_minor__ == 4
# define GLM_COMPILER GLM_COMPILER_LLVM34
# elif __clang_major__ == 3 && __clang_minor__ == 5
# define GLM_COMPILER GLM_COMPILER_LLVM35
# else
# define GLM_COMPILER GLM_COMPILER_LLVM35
# endif
# endif
// G++
#elif defined(__GNUC__) || defined(__MINGW32__)
# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
# define GLM_COMPILER (GLM_COMPILER_GCC42)
# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
# define GLM_COMPILER (GLM_COMPILER_GCC43)
# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 4)
# define GLM_COMPILER (GLM_COMPILER_GCC44)
# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 5)
# define GLM_COMPILER (GLM_COMPILER_GCC45)
# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 6)
# define GLM_COMPILER (GLM_COMPILER_GCC46)
# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 7)
# define GLM_COMPILER (GLM_COMPILER_GCC47)
# elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
# define GLM_COMPILER (GLM_COMPILER_GCC48)
# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)
# define GLM_COMPILER (GLM_COMPILER_GCC49)
# elif (__GNUC__ > 4 )
# define GLM_COMPILER (GLM_COMPILER_GCC50)
# else
# define GLM_COMPILER (GLM_COMPILER_GCC)
# endif
#else
# define GLM_COMPILER GLM_COMPILER_UNKNOWN
#endif
#ifndef GLM_COMPILER
#error "GLM_COMPILER undefined, your compiler may not be supported by GLM. Add #define GLM_COMPILER 0 to ignore this message."
#endif//GLM_COMPILER
// Report compiler detection
#if defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_COMPILER_DISPLAYED)
# define GLM_MESSAGE_COMPILER_DISPLAYED
# if GLM_COMPILER & GLM_COMPILER_CUDA
# pragma message("GLM: CUDA compiler detected")
# elif GLM_COMPILER & GLM_COMPILER_VC
# pragma message("GLM: Visual C++ compiler detected")
# elif GLM_COMPILER & GLM_COMPILER_APPLE_CLANG
# pragma message("GLM: Clang compiler detected")
# elif GLM_COMPILER & GLM_COMPILER_LLVM
# pragma message("GLM: LLVM compiler detected")
# elif GLM_COMPILER & GLM_COMPILER_INTEL
# pragma message("GLM: Intel Compiler detected")
# elif GLM_COMPILER & GLM_COMPILER_GCC
# pragma message("GLM: GCC compiler detected")
# else
# pragma message("GLM: Compiler not detected")
# endif
#endif//GLM_MESSAGE
///////////////////////////////////////////////////////////////////////////////////
// Build model
#if defined(__arch64__) || defined(__LP64__) || defined(_M_X64) || defined(__ppc64__) || defined(__x86_64__)
# define GLM_MODEL GLM_MODEL_64
#elif defined(__i386__) || defined(__ppc__)
# define GLM_MODEL GLM_MODEL_32
#else
# define GLM_MODEL GLM_MODEL_32
#endif//
#if !defined(GLM_MODEL) && GLM_COMPILER != 0
# error "GLM_MODEL undefined, your compiler may not be supported by GLM. Add #define GLM_MODEL 0 to ignore this message."
#endif//GLM_MODEL
#if defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_MODEL_DISPLAYED)
# define GLM_MESSAGE_MODEL_DISPLAYED
# if(GLM_MODEL == GLM_MODEL_64)
# pragma message("GLM: 64 bits model")
# elif(GLM_MODEL == GLM_MODEL_32)
# pragma message("GLM: 32 bits model")
# endif//GLM_MODEL
#endif//GLM_MESSAGE
///////////////////////////////////////////////////////////////////////////////////
// C++ Version
// User defines: GLM_FORCE_CXX98, GLM_FORCE_CXX03, GLM_FORCE_CXX11, GLM_FORCE_CXX14
#define GLM_LANG_CXX98_FLAG (1 << 1)
#define GLM_LANG_CXX03_FLAG (1 << 2)
#define GLM_LANG_CXX0X_FLAG (1 << 3)
#define GLM_LANG_CXX11_FLAG (1 << 4)
#define GLM_LANG_CXX1Y_FLAG (1 << 5)
#define GLM_LANG_CXX14_FLAG (1 << 6)
#define GLM_LANG_CXX1Z_FLAG (1 << 7)
#define GLM_LANG_CXXMS_FLAG (1 << 8)
#define GLM_LANG_CXXGNU_FLAG (1 << 9)
#define GLM_LANG_CXX98 GLM_LANG_CXX98_FLAG
#define GLM_LANG_CXX03 (GLM_LANG_CXX98 | GLM_LANG_CXX03_FLAG)
#define GLM_LANG_CXX0X (GLM_LANG_CXX03 | GLM_LANG_CXX0X_FLAG)
#define GLM_LANG_CXX11 (GLM_LANG_CXX0X | GLM_LANG_CXX11_FLAG)
#define GLM_LANG_CXX1Y (GLM_LANG_CXX11 | GLM_LANG_CXX1Y_FLAG)
#define GLM_LANG_CXX14 (GLM_LANG_CXX1Y | GLM_LANG_CXX14_FLAG)
#define GLM_LANG_CXX1Z (GLM_LANG_CXX14 | GLM_LANG_CXX1Z_FLAG)
#define GLM_LANG_CXXMS GLM_LANG_CXXMS_FLAG
#define GLM_LANG_CXXGNU GLM_LANG_CXXGNU_FLAG
#if defined(GLM_FORCE_CXX14)
# undef GLM_FORCE_CXX11
# undef GLM_FORCE_CXX03
# undef GLM_FORCE_CXX98
# define GLM_LANG GLM_LANG_CXX14
#elif defined(GLM_FORCE_CXX11)
# undef GLM_FORCE_CXX03
# undef GLM_FORCE_CXX98
# define GLM_LANG GLM_LANG_CXX11
#elif defined(GLM_FORCE_CXX03)
# undef GLM_FORCE_CXX98
# define GLM_LANG GLM_LANG_CXX03
#elif defined(GLM_FORCE_CXX98)
# define GLM_LANG GLM_LANG_CXX98
#else
# if GLM_COMPILER & (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM)
# if __cplusplus >= 201402L // GLM_COMPILER_LLVM34 + -std=c++14
# define GLM_LANG GLM_LANG_CXX14
# elif __has_feature(cxx_decltype_auto) && __has_feature(cxx_aggregate_nsdmi) // GLM_COMPILER_LLVM33 + -std=c++1y
# define GLM_LANG GLM_LANG_CXX1Y
# elif __cplusplus >= 201103L // GLM_COMPILER_LLVM33 + -std=c++11
# define GLM_LANG GLM_LANG_CXX11
# elif __has_feature(cxx_static_assert) // GLM_COMPILER_LLVM29 + -std=c++11
# define GLM_LANG GLM_LANG_CXX0X
# elif __cplusplus >= 199711L
# define GLM_LANG GLM_LANG_CXX98
# else
# define GLM_LANG GLM_LANG_CXX
# endif
# elif GLM_COMPILER & GLM_COMPILER_GCC
# if __cplusplus >= 201402L
# define GLM_LANG GLM_LANG_CXX14
# elif __cplusplus >= 201103L
# define GLM_LANG GLM_LANG_CXX11
# elif defined(__GXX_EXPERIMENTAL_CXX0X__)
# define GLM_LANG GLM_LANG_CXX0X
# else
# define GLM_LANG GLM_LANG_CXX98
# endif
# elif GLM_COMPILER & GLM_COMPILER_VC
# ifdef _MSC_EXTENSIONS
# if __cplusplus >= 201402L
# define GLM_LANG (GLM_LANG_CXX14 | GLM_LANG_CXXMS_FLAG)
//# elif GLM_COMPILER >= GLM_COMPILER_VC2015
//# define GLM_LANG (GLM_LANG_CXX1Y | GLM_LANG_CXXMS_FLAG)
# elif __cplusplus >= 201103L
# define GLM_LANG (GLM_LANG_CXX11 | GLM_LANG_CXXMS_FLAG)
# elif GLM_COMPILER >= GLM_COMPILER_VC2010
# define GLM_LANG (GLM_LANG_CXX0X | GLM_LANG_CXXMS_FLAG)
# elif __cplusplus >= 199711L
# define GLM_LANG (GLM_LANG_CXX98 | GLM_LANG_CXXMS_FLAG)
# else
# define GLM_LANG (GLM_LANG_CXX | GLM_LANG_CXXMS_FLAG)
# endif
# else
# if __cplusplus >= 201402L
# define GLM_LANG GLM_LANG_CXX14
//# elif GLM_COMPILER >= GLM_COMPILER_VC2015
//# define GLM_LANG GLM_LANG_CXX1Y
# elif __cplusplus >= 201103L
# define GLM_LANG GLM_LANG_CXX11
# elif GLM_COMPILER >= GLM_COMPILER_VC2010
# define GLM_LANG GLM_LANG_CXX0X
# elif __cplusplus >= 199711L
# define GLM_LANG GLM_LANG_CXX98
# else
# define GLM_LANG GLM_LANG_CXX
# endif
# endif
# elif GLM_COMPILER & GLM_COMPILER_INTEL
# ifdef _MSC_EXTENSIONS
# if __cplusplus >= 201402L
# define GLM_LANG (GLM_LANG_CXX14 | GLM_LANG_CXXMS_FLAG)
# elif __cplusplus >= 201103L
# define GLM_LANG (GLM_LANG_CXX11 | GLM_LANG_CXXMS_FLAG)
# elif GLM_COMPILER >= GLM_COMPILER_INTEL13
# define GLM_LANG (GLM_LANG_CXX0X | GLM_LANG_CXXMS_FLAG)
# elif __cplusplus >= 199711L
# define GLM_LANG (GLM_LANG_CXX98 | GLM_LANG_CXXMS_FLAG)
# else
# define GLM_LANG (GLM_LANG_CXX | GLM_LANG_CXXMS_FLAG)
# endif
# else
# if __cplusplus >= 201402L
# define GLM_LANG (GLM_LANG_CXX14 | GLM_LANG_CXXMS_FLAG)
# elif __cplusplus >= 201103L
# define GLM_LANG (GLM_LANG_CXX11 | GLM_LANG_CXXMS_FLAG)
# elif GLM_COMPILER >= GLM_COMPILER_INTEL13
# define GLM_LANG (GLM_LANG_CXX0X | GLM_LANG_CXXMS_FLAG)
# elif __cplusplus >= 199711L
# define GLM_LANG (GLM_LANG_CXX98 | GLM_LANG_CXXMS_FLAG)
# else
# define GLM_LANG (GLM_LANG_CXX | GLM_LANG_CXXMS_FLAG)
# endif
# endif
# else // Unkown compiler
# if __cplusplus >= 201402L
# define GLM_LANG GLM_LANG_CXX14
# elif __cplusplus >= 201103L
# define GLM_LANG GLM_LANG_CXX11
# elif __cplusplus >= 199711L
# define GLM_LANG GLM_LANG_CXX98
# else
# define GLM_LANG GLM_LANG_CXX // Good luck with that!
# endif
# ifndef GLM_FORCE_PURE
# define GLM_FORCE_PURE
# endif
# endif
#endif
#if defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_LANG_DISPLAYED)
# define GLM_MESSAGE_LANG_DISPLAYED
# if GLM_LANG & GLM_LANG_CXX1Z_FLAG
# pragma message("GLM: C++1z")
# elif GLM_LANG & GLM_LANG_CXX14_FLAG
# pragma message("GLM: C++14")
# elif GLM_LANG & GLM_LANG_CXX1Y_FLAG
# pragma message("GLM: C++1y")
# elif GLM_LANG & GLM_LANG_CXX11_FLAG
# pragma message("GLM: C++11")
# elif GLM_LANG & GLM_LANG_CXX0X_FLAG
# pragma message("GLM: C++0x")
# elif GLM_LANG & GLM_LANG_CXX03_FLAG
# pragma message("GLM: C++03")
# elif GLM_LANG & GLM_LANG_CXX98_FLAG
# pragma message("GLM: C++98")
# else
# pragma message("GLM: C++ language undetected")
# endif//GLM_LANG
# if GLM_LANG & (GLM_LANG_CXXGNU_FLAG | GLM_LANG_CXXMS_FLAG)
# pragma message("GLM: Language extensions enabled")
# endif//GLM_LANG
#endif//GLM_MESSAGE
///////////////////////////////////////////////////////////////////////////////////
// Has of C++ features
// http://clang.llvm.org/cxx_status.html
// http://gcc.gnu.org/projects/cxx0x.html
// http://msdn.microsoft.com/en-us/library/vstudio/hh567368(v=vs.120).aspx
#if GLM_PLATFORM == GLM_PLATFORM_ANDROID
# define GLM_HAS_CXX11_STL 0
#elif GLM_COMPILER & (GLM_COMPILER_LLVM | GLM_COMPILER_APPLE_CLANG)
# define GLM_HAS_CXX11_STL __has_include(<__config>)
#else
# define GLM_HAS_CXX11_STL ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && \
((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC48)) || \
((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2013)))
#endif
// N1720
#if GLM_COMPILER & (GLM_COMPILER_LLVM | GLM_COMPILER_APPLE_CLANG)
# define GLM_HAS_STATIC_ASSERT __has_feature(cxx_static_assert)
#elif GLM_LANG & GLM_LANG_CXX11_FLAG
# define GLM_HAS_STATIC_ASSERT 1
#else
# define GLM_HAS_STATIC_ASSERT (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC43)) || \
((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2010)))
#endif
// N1988
#if GLM_LANG & GLM_LANG_CXX11_FLAG
# define GLM_HAS_EXTENDED_INTEGER_TYPE 1
#else
# define GLM_HAS_EXTENDED_INTEGER_TYPE (\
((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2012)) || \
((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC43)) || \
((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_LLVM) && (GLM_COMPILER >= GLM_COMPILER_LLVM30)) || \
((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_APPLE_CLANG) && (GLM_COMPILER >= GLM_COMPILER_APPLE_CLANG40)))
#endif
// N2235
#if GLM_COMPILER & (GLM_COMPILER_LLVM | GLM_COMPILER_APPLE_CLANG)
# define GLM_HAS_CONSTEXPR __has_feature(cxx_constexpr)
# define GLM_HAS_CONSTEXPR_PARTIAL GLM_HAS_CONSTEXPR
#elif GLM_LANG & GLM_LANG_CXX11_FLAG
# define GLM_HAS_CONSTEXPR 1
# define GLM_HAS_CONSTEXPR_PARTIAL GLM_HAS_CONSTEXPR
#else
# define GLM_HAS_CONSTEXPR (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC46)))
# define GLM_HAS_CONSTEXPR_PARTIAL GLM_HAS_CONSTEXPR || ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2015))
#endif
// N2672
#if GLM_COMPILER & (GLM_COMPILER_LLVM | GLM_COMPILER_APPLE_CLANG)
# define GLM_HAS_INITIALIZER_LISTS __has_feature(cxx_generalized_initializers)
#elif GLM_LANG & GLM_LANG_CXX11_FLAG
# define GLM_HAS_INITIALIZER_LISTS 1
#else
# define GLM_HAS_INITIALIZER_LISTS (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC44)) || \
((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2013)))
#endif
// N2544 Unrestricted unions
#if GLM_COMPILER & (GLM_COMPILER_LLVM | GLM_COMPILER_APPLE_CLANG)
# define GLM_HAS_UNRESTRICTED_UNIONS __has_feature(cxx_unrestricted_unions)
#elif GLM_LANG & (GLM_LANG_CXX11_FLAG | GLM_LANG_CXXMS_FLAG)
# define GLM_HAS_UNRESTRICTED_UNIONS 1
#else
# define GLM_HAS_UNRESTRICTED_UNIONS (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC46)))
#endif
// N2346
#if GLM_COMPILER & (GLM_COMPILER_LLVM | GLM_COMPILER_APPLE_CLANG)
# define GLM_HAS_DEFAULTED_FUNCTIONS __has_feature(cxx_defaulted_functions)
#elif GLM_LANG & GLM_LANG_CXX11_FLAG
# define GLM_HAS_DEFAULTED_FUNCTIONS 1
#else
# define GLM_HAS_DEFAULTED_FUNCTIONS (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC44)) || \
((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2013)))
#endif
// N2118
#if GLM_COMPILER & (GLM_COMPILER_LLVM | GLM_COMPILER_APPLE_CLANG)
# define GLM_HAS_RVALUE_REFERENCES __has_feature(cxx_rvalue_references)
#elif GLM_LANG & GLM_LANG_CXX11_FLAG
# define GLM_HAS_RVALUE_REFERENCES 1
#else
# define GLM_HAS_RVALUE_REFERENCES (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC43)) || \
((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2012)))
#endif
// N2437 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf
#if GLM_COMPILER & (GLM_COMPILER_LLVM | GLM_COMPILER_APPLE_CLANG)
# define GLM_HAS_EXPLICIT_CONVERSION_OPERATORS __has_feature(cxx_explicit_conversions)
#elif GLM_LANG & GLM_LANG_CXX11_FLAG
# define GLM_HAS_EXPLICIT_CONVERSION_OPERATORS 1
#else
# define GLM_HAS_EXPLICIT_CONVERSION_OPERATORS (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC45)) || \
((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL14)) || \
((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2013)))
#endif
// N2258 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf
#if GLM_COMPILER & (GLM_COMPILER_LLVM | GLM_COMPILER_APPLE_CLANG)
# define GLM_HAS_TEMPLATE_ALIASES __has_feature(cxx_alias_templates)
#elif GLM_LANG & GLM_LANG_CXX11_FLAG
# define GLM_HAS_TEMPLATE_ALIASES 1
#else
# define GLM_HAS_TEMPLATE_ALIASES (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL12_1)) || \
((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC47)) || \
((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2013)))
#endif
// N2930 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2930.html
#if GLM_COMPILER & (GLM_COMPILER_LLVM | GLM_COMPILER_APPLE_CLANG)
# define GLM_HAS_RANGE_FOR __has_feature(cxx_range_for)
#elif GLM_LANG & GLM_LANG_CXX11_FLAG
# define GLM_HAS_RANGE_FOR 1
#else
# define GLM_HAS_RANGE_FOR (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC46)) || \
((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL13)) || \
((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2012)))
#endif
//
#if GLM_LANG & GLM_LANG_CXX11_FLAG
# define GLM_HAS_ASSIGNABLE 1
#else
# define GLM_HAS_ASSIGNABLE (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC49)))
#endif
//
#define GLM_HAS_TRIVIAL_QUERIES 0//(
//((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2013)))
//
#if GLM_LANG & GLM_LANG_CXX11_FLAG
# define GLM_HAS_MAKE_SIGNED 1
#else
# define GLM_HAS_MAKE_SIGNED (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2013)))
#endif
//
#if GLM_ARCH == GLM_ARCH_PURE
# define GLM_HAS_BITSCAN_WINDOWS 0
#else
# define GLM_HAS_BITSCAN_WINDOWS (GLM_PLATFORM & GLM_PLATFORM_WINDOWS) && (\
(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_LLVM | GLM_COMPILER_INTEL))
#endif
// OpenMP
#ifdef _OPENMP
# if GLM_COMPILER & GLM_COMPILER_GCC
# if GLM_COMPILER >= GLM_COMPILER_GCC47
# define GLM_HAS_OPENMP 31
# elif GLM_COMPILER >= GLM_COMPILER_GCC44
# define GLM_HAS_OPENMP 30
# elif GLM_COMPILER >= GLM_COMPILER_GCC42
# define GLM_HAS_OPENMP 25
# endif
# endif// GLM_COMPILER & GLM_COMPILER_GCC
# if GLM_COMPILER & GLM_COMPILER_VC
# if GLM_COMPILER >= GLM_COMPILER_VC2010
# define GLM_HAS_OPENMP 20
# endif
# endif// GLM_COMPILER & GLM_COMPILER_VC
#endif
// Not standard
#define GLM_HAS_ANONYMOUS_UNION (GLM_LANG & GLM_LANG_CXXMS_FLAG)
///////////////////////////////////////////////////////////////////////////////////
// Platform
// User defines: GLM_FORCE_PURE GLM_FORCE_SSE2 GLM_FORCE_SSE3 GLM_FORCE_AVX GLM_FORCE_AVX2
#define GLM_ARCH_PURE 0x0000
#define GLM_ARCH_ARM 0x0001
#define GLM_ARCH_X86 0x0002
#define GLM_ARCH_SSE2 0x0004
#define GLM_ARCH_SSE3 0x0008
#define GLM_ARCH_SSE4 0x0010
#define GLM_ARCH_AVX 0x0020
#define GLM_ARCH_AVX2 0x0040
#if defined(GLM_FORCE_PURE)
# define GLM_ARCH GLM_ARCH_PURE
#elif defined(GLM_FORCE_AVX2)
# define GLM_ARCH (GLM_ARCH_AVX2 | GLM_ARCH_AVX | GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
#elif defined(GLM_FORCE_AVX)
# define GLM_ARCH (GLM_ARCH_AVX | GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
#elif defined(GLM_FORCE_SSE4)
# define GLM_ARCH (GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
#elif defined(GLM_FORCE_SSE3)
# define GLM_ARCH (GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
#elif defined(GLM_FORCE_SSE2)
# define GLM_ARCH (GLM_ARCH_SSE2)
#elif (GLM_COMPILER & (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM | GLM_COMPILER_GCC)) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_LINUX))
# if(__AVX2__)
# define GLM_ARCH (GLM_ARCH_AVX2 | GLM_ARCH_AVX | GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
# elif(__AVX__)
# define GLM_ARCH (GLM_ARCH_AVX | GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
# elif(__SSE3__)
# define GLM_ARCH (GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
# elif(__SSE2__)
# define GLM_ARCH (GLM_ARCH_SSE2)
# else
# define GLM_ARCH GLM_ARCH_PURE
# endif
#elif (GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))
# if defined(_M_ARM_FP)
# define GLM_ARCH (GLM_ARCH_ARM)
# elif defined(__AVX2__)
# define GLM_ARCH (GLM_ARCH_AVX2 | GLM_ARCH_AVX | GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
# elif defined(__AVX__)
# define GLM_ARCH (GLM_ARCH_AVX | GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
# elif _M_IX86_FP == 2
# define GLM_ARCH (GLM_ARCH_SSE2)
# else
# define GLM_ARCH (GLM_ARCH_PURE)
# endif
#elif (GLM_COMPILER & GLM_COMPILER_GCC) && (defined(__i386__) || defined(__x86_64__))
# if defined(__AVX2__)
# define GLM_ARCH (GLM_ARCH_AVX2 | GLM_ARCH_AVX | GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
# elif defined(__AVX__)
# define GLM_ARCH (GLM_ARCH_AVX | GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
# elif defined(__SSE4_1__ )
# define GLM_ARCH (GLM_ARCH_SSE4 | GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
# elif defined(__SSE3__)
# define GLM_ARCH (GLM_ARCH_SSE3 | GLM_ARCH_SSE2)
# elif defined(__SSE2__)
# define GLM_ARCH (GLM_ARCH_SSE2)
# else
# define GLM_ARCH (GLM_ARCH_PURE)
# endif
#else
# define GLM_ARCH GLM_ARCH_PURE
#endif
// With MinGW-W64, including intrinsic headers before intrin.h will produce some errors. The problem is
// that windows.h (and maybe other headers) will silently include intrin.h, which of course causes problems.
// To fix, we just explicitly include intrin.h here.
#if defined(__MINGW64__) && (GLM_ARCH != GLM_ARCH_PURE)
# include <intrin.h>
#endif
#if GLM_ARCH & GLM_ARCH_AVX2
# include <immintrin.h>
#endif//GLM_ARCH
#if GLM_ARCH & GLM_ARCH_AVX
# include <immintrin.h>
#endif//GLM_ARCH
#if GLM_ARCH & GLM_ARCH_SSE4
# include <smmintrin.h>
#endif//GLM_ARCH
#if GLM_ARCH & GLM_ARCH_SSE3
# include <pmmintrin.h>
#endif//GLM_ARCH
#if GLM_ARCH & GLM_ARCH_SSE2
# include <emmintrin.h>
# if(GLM_COMPILER == GLM_COMPILER_VC2005) // VC2005 is missing some intrinsics, workaround
inline float _mm_cvtss_f32(__m128 A) { return A.m128_f32[0]; }
inline __m128 _mm_castpd_ps(__m128d PD) { union { __m128 ps; __m128d pd; } c; c.pd = PD; return c.ps; }
inline __m128d _mm_castps_pd(__m128 PS) { union { __m128 ps; __m128d pd; } c; c.ps = PS; return c.pd; }
inline __m128i _mm_castps_si128(__m128 PS) { union { __m128 ps; __m128i pi; } c; c.ps = PS; return c.pi; }
inline __m128 _mm_castsi128_ps(__m128i PI) { union { __m128 ps; __m128i pi; } c; c.pi = PI; return c.ps; }
# endif
#endif//GLM_ARCH
#if defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_ARCH_DISPLAYED)
# define GLM_MESSAGE_ARCH_DISPLAYED
# if(GLM_ARCH == GLM_ARCH_PURE)
# pragma message("GLM: Platform independent code")
# elif(GLM_ARCH & GLM_ARCH_ARM)
# pragma message("GLM: ARM instruction set")
# elif(GLM_ARCH & GLM_ARCH_AVX2)
# pragma message("GLM: AVX2 instruction set")
# elif(GLM_ARCH & GLM_ARCH_AVX)
# pragma message("GLM: AVX instruction set")
# elif(GLM_ARCH & GLM_ARCH_SSE3)
# pragma message("GLM: SSE3 instruction set")
# elif(GLM_ARCH & GLM_ARCH_SSE2)
# pragma message("GLM: SSE2 instruction set")
# endif//GLM_ARCH
#endif//GLM_MESSAGE
///////////////////////////////////////////////////////////////////////////////////
// Static assert
#if GLM_HAS_STATIC_ASSERT
# define GLM_STATIC_ASSERT(x, message) static_assert(x, message)
#elif defined(BOOST_STATIC_ASSERT)
# define GLM_STATIC_ASSERT(x, message) BOOST_STATIC_ASSERT(x)
#elif GLM_COMPILER & GLM_COMPILER_VC
# define GLM_STATIC_ASSERT(x, message) typedef char __CASSERT__##__LINE__[(x) ? 1 : -1]
#else
# define GLM_STATIC_ASSERT(x, message)
# define GLM_STATIC_ASSERT_NULL
#endif//GLM_LANG
///////////////////////////////////////////////////////////////////////////////////
// Qualifiers
#if GLM_COMPILER & GLM_COMPILER_CUDA
# define GLM_CUDA_FUNC_DEF __device__ __host__
# define GLM_CUDA_FUNC_DECL __device__ __host__
#else
# define GLM_CUDA_FUNC_DEF
# define GLM_CUDA_FUNC_DECL
#endif
#if GLM_COMPILER & GLM_COMPILER_GCC
# define GLM_VAR_USED __attribute__ ((unused))
#else
# define GLM_VAR_USED
#endif
#if defined(GLM_FORCE_INLINE)
# if GLM_COMPILER & GLM_COMPILER_VC
# define GLM_INLINE __forceinline
# define GLM_NEVER_INLINE __declspec((noinline))
# elif GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM)
# define GLM_INLINE inline __attribute__((__always_inline__))
# define GLM_NEVER_INLINE __attribute__((__noinline__))
# else
# define GLM_INLINE inline
# define GLM_NEVER_INLINE
# endif//GLM_COMPILER
#else
# define GLM_INLINE inline
# define GLM_NEVER_INLINE
#endif//defined(GLM_FORCE_INLINE)
#define GLM_FUNC_DECL GLM_CUDA_FUNC_DECL
#define GLM_FUNC_QUALIFIER GLM_CUDA_FUNC_DEF GLM_INLINE
///////////////////////////////////////////////////////////////////////////////////
// Swizzle operators
// User defines: GLM_SWIZZLE
#if defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_SWIZZLE_DISPLAYED)
# define GLM_MESSAGE_SWIZZLE_DISPLAYED
# if defined(GLM_SWIZZLE)
# pragma message("GLM: Swizzling operators enabled")
# else
# pragma message("GLM: Swizzling operators disabled, #define GLM_SWIZZLE to enable swizzle operators")
# endif
#endif//GLM_MESSAGE
///////////////////////////////////////////////////////////////////////////////////
// Qualifiers
#if (GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))
# define GLM_DEPRECATED __declspec(deprecated)
# define GLM_ALIGN(x) __declspec(align(x))
# define GLM_ALIGNED_STRUCT(x) struct __declspec(align(x))
# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef __declspec(align(alignment)) type name
# define GLM_RESTRICT __declspec(restrict)
# define GLM_RESTRICT_VAR __restrict
#elif GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM | GLM_COMPILER_CUDA | GLM_COMPILER_INTEL)
# define GLM_DEPRECATED __attribute__((__deprecated__))
# define GLM_ALIGN(x) __attribute__((aligned(x)))
# define GLM_ALIGNED_STRUCT(x) struct __attribute__((aligned(x)))
# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name __attribute__((aligned(alignment)))
# define GLM_RESTRICT __restrict__
# define GLM_RESTRICT_VAR __restrict__
#else
# define GLM_DEPRECATED
# define GLM_ALIGN
# define GLM_ALIGNED_STRUCT(x) struct
# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name
# define GLM_RESTRICT
# define GLM_RESTRICT_VAR
#endif//GLM_COMPILER
#if GLM_HAS_CONSTEXPR
# define GLM_CONSTEXPR constexpr
#else
# define GLM_CONSTEXPR
#endif
///////////////////////////////////////////////////////////////////////////////////
// Length type
// User defines: GLM_FORCE_SIZE_T_LENGTH GLM_FORCE_SIZE_FUNC
namespace glm
{
using std::size_t;
# if defined(GLM_FORCE_SIZE_T_LENGTH) || defined(GLM_FORCE_SIZE_FUNC)
typedef size_t length_t;
# else
typedef int length_t;
# endif
namespace detail
{
# ifdef GLM_FORCE_SIZE_FUNC
typedef size_t component_count_t;
# else
typedef length_t component_count_t;
# endif
template <typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR component_count_t component_count(genType const & m)
{
# ifdef GLM_FORCE_SIZE_FUNC
return m.size();
# else
return m.length();
# endif
}
}//namespace detail
}//namespace glm
#if defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_FORCE_SIZE_T_LENGTH)
# define GLM_MESSAGE_FORCE_SIZE_T_LENGTH
# if defined GLM_FORCE_SIZE_FUNC
# pragma message("GLM: .length() is replaced by .size() and returns a std::size_t")
# elif defined GLM_FORCE_SIZE_T_LENGTH
# pragma message("GLM: .length() returns glm::length_t, a typedef of std::size_t")
# else
# pragma message("GLM: .length() returns glm::length_t, a typedef of int following the GLSL specification")
# endif
#endif//GLM_MESSAGE
///////////////////////////////////////////////////////////////////////////////////
// countof
#ifndef __has_feature
# define __has_feature(x) 0 // Compatibility with non-clang compilers.
#endif
#if GLM_HAS_CONSTEXPR_PARTIAL
namespace glm
{
template <typename T, std::size_t N>
constexpr std::size_t countof(T const (&)[N])
{
return N;
}
}//namespace glm
# define GLM_COUNTOF(arr) glm::countof(arr)
#elif _MSC_VER
# define GLM_COUNTOF(arr) _countof(arr)
#else
# define GLM_COUNTOF(arr) sizeof(arr) / sizeof(arr[0])
#endif
///////////////////////////////////////////////////////////////////////////////////
// Uninitialize constructors
namespace glm
{
enum ctor{uninitialize};
}//namespace glm
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// 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 core
/// @file glm/detail/type_float.hpp
/// @date 2008-08-22 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "setup.hpp"
namespace glm{
namespace detail
{
typedef float float32;
typedef double float64;
}//namespace detail
typedef float lowp_float_t;
typedef float mediump_float_t;
typedef double highp_float_t;
/// @addtogroup core_precision
/// @{
/// Low precision floating-point numbers.
/// There is no guarantee on the actual precision.
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.4 Floats</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier</a>
typedef lowp_float_t lowp_float;
/// Medium precision floating-point numbers.
/// There is no guarantee on the actual precision.
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.4 Floats</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier</a>
typedef mediump_float_t mediump_float;
/// High precision floating-point numbers.
/// There is no guarantee on the actual precision.
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.4 Floats</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier</a>
typedef highp_float_t highp_float;
#if(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
typedef mediump_float float_t;
#elif(defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
typedef highp_float float_t;
#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
typedef mediump_float float_t;
#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && defined(GLM_PRECISION_LOWP_FLOAT))
typedef lowp_float float_t;
#else
# error "GLM error: multiple default precision requested for floating-point types"
#endif
typedef float float32;
typedef double float64;
////////////////////
// check type sizes
#ifndef GLM_STATIC_ASSERT_NULL
GLM_STATIC_ASSERT(sizeof(glm::float32) == 4, "float32 size isn't 4 bytes on this platform");
GLM_STATIC_ASSERT(sizeof(glm::float64) == 8, "float64 size isn't 8 bytes on this platform");
#endif//GLM_STATIC_ASSERT_NULL
/// @}
}//namespace glm
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// 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 core
/// @file glm/detail/type_gentype.hpp
/// @date 2008-10-05 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
namespace glm
{
enum profile
{
nice,
fast,
simd
};
typedef std::size_t sizeType;
namespace detail
{
template
<
typename VALTYPE,
template <typename> class TYPE
>
struct genType
{
public:
enum ctor{null};
typedef VALTYPE value_type;
typedef VALTYPE & value_reference;
typedef VALTYPE * value_pointer;
typedef VALTYPE const * value_const_pointer;
typedef TYPE<bool> bool_type;
typedef sizeType size_type;
static bool is_vector();
static bool is_matrix();
typedef TYPE<VALTYPE> type;
typedef TYPE<VALTYPE> * pointer;
typedef TYPE<VALTYPE> const * const_pointer;
typedef TYPE<VALTYPE> const * const const_pointer_const;
typedef TYPE<VALTYPE> * const pointer_const;
typedef TYPE<VALTYPE> & reference;
typedef TYPE<VALTYPE> const & const_reference;
typedef TYPE<VALTYPE> const & param_type;
//////////////////////////////////////
// Address (Implementation details)
value_const_pointer value_address() const{return value_pointer(this);}
value_pointer value_address(){return value_pointer(this);}
//protected:
// enum kind
// {
// GEN_TYPE,
// VEC_TYPE,
// MAT_TYPE
// };
// typedef typename TYPE::kind kind;
};
template
<
typename VALTYPE,
template <typename> class TYPE
>
bool genType<VALTYPE, TYPE>::is_vector()
{
return true;
}
/*
template <typename valTypeT, unsigned int colT, unsigned int rowT, profile proT = nice>
class base
{
public:
//////////////////////////////////////
// Traits
typedef sizeType size_type;
typedef valTypeT value_type;
typedef base<value_type, colT, rowT> class_type;
typedef base<bool, colT, rowT> bool_type;
typedef base<value_type, rowT, 1> col_type;
typedef base<value_type, colT, 1> row_type;
typedef base<value_type, rowT, colT> transpose_type;
static size_type col_size();
static size_type row_size();
static size_type value_size();
static bool is_scalar();
static bool is_vector();
static bool is_matrix();
private:
// Data
col_type value[colT];
public:
//////////////////////////////////////
// Constructors
base();
base(class_type const & m);
explicit base(T const & x);
explicit base(value_type const * const x);
explicit base(col_type const * const x);
//////////////////////////////////////
// Conversions
template <typename vU, uint cU, uint rU, profile pU>
explicit base(base<vU, cU, rU, pU> const & m);
//////////////////////////////////////
// Accesses
col_type& operator[](size_type i);
col_type const & operator[](size_type i) const;
//////////////////////////////////////
// Unary updatable operators
class_type& operator= (class_type const & x);
class_type& operator+= (T const & x);
class_type& operator+= (class_type const & x);
class_type& operator-= (T const & x);
class_type& operator-= (class_type const & x);
class_type& operator*= (T const & x);
class_type& operator*= (class_type const & x);
class_type& operator/= (T const & x);
class_type& operator/= (class_type const & x);
class_type& operator++ ();
class_type& operator-- ();
};
*/
//template <typename T>
//struct traits
//{
// static const bool is_signed = false;
// static const bool is_float = false;
// static const bool is_vector = false;
// static const bool is_matrix = false;
// static const bool is_genType = false;
// static const bool is_genIType = false;
// static const bool is_genUType = false;
//};
//template <>
//struct traits<half>
//{
// static const bool is_float = true;
// static const bool is_genType = true;
//};
//template <>
//struct traits<float>
//{
// static const bool is_float = true;
// static const bool is_genType = true;
//};
//template <>
//struct traits<double>
//{
// static const bool is_float = true;
// static const bool is_genType = true;
//};
//template <typename genType>
//struct desc
//{
// typedef genType type;
// typedef genType * pointer;
// typedef genType const* const_pointer;
// typedef genType const *const const_pointer_const;
// typedef genType *const pointer_const;
// typedef genType & reference;
// typedef genType const& const_reference;
// typedef genType const& param_type;
// typedef typename genType::value_type value_type;
// typedef typename genType::size_type size_type;
// static const typename size_type value_size;
//};
//template <typename genType>
//const typename desc<genType>::size_type desc<genType>::value_size = genType::value_size();
}//namespace detail
}//namespace glm
//#include "type_gentype.inl"
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// 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 core
/// @file glm/detail/type_gentype.inl
/// @date 2008-10-05 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
namespace glm{
namespace detail{
/////////////////////////////////
// Static functions
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::size_type base<vT, cT, rT, pT>::col_size()
{
return cT;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::size_type base<vT, cT, rT, pT>::row_size()
{
return rT;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::size_type base<vT, cT, rT, pT>::value_size()
{
return rT * cT;
}
template <typename vT, uint cT, uint rT, profile pT>
bool base<vT, cT, rT, pT>::is_scalar()
{
return rT == 1 && cT == 1;
}
template <typename vT, uint cT, uint rT, profile pT>
bool base<vT, cT, rT, pT>::is_vector()
{
return rT == 1;
}
template <typename vT, uint cT, uint rT, profile pT>
bool base<vT, cT, rT, pT>::is_matrix()
{
return rT != 1;
}
/////////////////////////////////
// Constructor
template <typename vT, uint cT, uint rT, profile pT>
base<vT, cT, rT, pT>::base()
{
memset(&this->value, 0, cT * rT * sizeof(vT));
}
template <typename vT, uint cT, uint rT, profile pT>
base<vT, cT, rT, pT>::base
(
typename base<vT, cT, rT, pT>::class_type const & m
)
{
for
(
typename genType<vT, cT, rT, pT>::size_type i = typename base<vT, cT, rT, pT>::size_type(0);
i < base<vT, cT, rT, pT>::col_size();
++i
)
{
this->value[i] = m[i];
}
}
template <typename vT, uint cT, uint rT, profile pT>
base<vT, cT, rT, pT>::base
(
typename base<vT, cT, rT, pT>::T const & x
)
{
if(rT == 1) // vector
{
for
(
typename base<vT, cT, rT, pT>::size_type i = typename base<vT, cT, rT, pT>::size_type(0);
i < base<vT, cT, rT, pT>::col_size();
++i
)
{
this->value[i][rT] = x;
}
}
else // matrix
{
memset(&this->value, 0, cT * rT * sizeof(vT));
typename base<vT, cT, rT, pT>::size_type stop = cT < rT ? cT : rT;
for
(
typename base<vT, cT, rT, pT>::size_type i = typename base<vT, cT, rT, pT>::size_type(0);
i < stop;
++i
)
{
this->value[i][i] = x;
}
}
}
template <typename vT, uint cT, uint rT, profile pT>
base<vT, cT, rT, pT>::base
(
typename base<vT, cT, rT, pT>::value_type const * const x
)
{
memcpy(&this->value, &x.value, cT * rT * sizeof(vT));
}
template <typename vT, uint cT, uint rT, profile pT>
base<vT, cT, rT, pT>::base
(
typename base<vT, cT, rT, pT>::col_type const * const x
)
{
for
(
typename base<vT, cT, rT, pT>::size_type i = typename base<vT, cT, rT, pT>::size_type(0);
i < base<vT, cT, rT, pT>::col_size();
++i
)
{
this->value[i] = x[i];
}
}
template <typename vT, uint cT, uint rT, profile pT>
template <typename vU, uint cU, uint rU, profile pU>
base<vT, cT, rT, pT>::base
(
base<vU, cU, rU, pU> const & m
)
{
for
(
typename base<vT, cT, rT, pT>::size_type i = typename base<vT, cT, rT, pT>::size_type(0);
i < base<vT, cT, rT, pT>::col_size();
++i
)
{
this->value[i] = base<vT, cT, rT, pT>(m[i]);
}
}
//////////////////////////////////////
// Accesses
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::col_type& base<vT, cT, rT, pT>::operator[]
(
typename base<vT, cT, rT, pT>::size_type i
)
{
return this->value[i];
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::col_type const & base<vT, cT, rT, pT>::operator[]
(
typename base<vT, cT, rT, pT>::size_type i
) const
{
return this->value[i];
}
//////////////////////////////////////
// Unary updatable operators
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator=
(
typename base<vT, cT, rT, pT>::class_type const & x
)
{
memcpy(&this->value, &x.value, cT * rT * sizeof(vT));
return *this;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator+=
(
typename base<vT, cT, rT, pT>::T const & x
)
{
typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
this->value[j][i] += x;
return *this;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator+=
(
typename base<vT, cT, rT, pT>::class_type const & x
)
{
typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
this->value[j][i] += x[j][i];
return *this;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator-=
(
typename base<vT, cT, rT, pT>::T const & x
)
{
typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
this->value[j][i] -= x;
return *this;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator-=
(
typename base<vT, cT, rT, pT>::class_type const & x
)
{
typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
this->value[j][i] -= x[j][i];
return *this;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator*=
(
typename base<vT, cT, rT, pT>::T const & x
)
{
typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
this->value[j][i] *= x;
return *this;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator*=
(
typename base<vT, cT, rT, pT>::class_type const & x
)
{
typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
this->value[j][i] *= x[j][i];
return *this;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator/=
(
typename base<vT, cT, rT, pT>::T const & x
)
{
typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
this->value[j][i] /= x;
return *this;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator/=
(
typename base<vT, cT, rT, pT>::class_type const & x
)
{
typename base<vT, cT, rT, pT>::size_type stop_col = x.col_size();
typename base<vT, cT, rT, pT>::size_type stop_row = x.row_size();
for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
this->value[j][i] /= x[j][i];
return *this;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator++ ()
{
typename base<vT, cT, rT, pT>::size_type stop_col = col_size();
typename base<vT, cT, rT, pT>::size_type stop_row = row_size();
for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
++this->value[j][i];
return *this;
}
template <typename vT, uint cT, uint rT, profile pT>
typename base<vT, cT, rT, pT>::class_type& base<vT, cT, rT, pT>::operator-- ()
{
typename base<vT, cT, rT, pT>::size_type stop_col = col_size();
typename base<vT, cT, rT, pT>::size_type stop_row = row_size();
for(typename base<vT, cT, rT, pT>::size_type j = 0; j < stop_col; ++j)
for(typename base<vT, cT, rT, pT>::size_type i = 0; i < stop_row; ++i)
--this->value[j][i];
return *this;
}
} //namespace detail
} //namespace glm
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// 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 core
/// @file glm/detail/type_half.hpp
/// @date 2008-08-17 / 2011-09-20
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "setup.hpp"
namespace glm{
namespace detail
{
typedef short hdata;
GLM_FUNC_DECL float toFloat32(hdata value);
GLM_FUNC_DECL hdata toFloat16(float const & value);
}//namespace detail
}//namespace glm
#include "type_half.inl"
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 G-Truc Creation (www.g-truc.net)
///
/// This half implementation is based on OpenEXR which is Copyright (c) 2002,
/// Industrial Light & Magic, a division of Lucas Digital Ltd. LLC
///
/// 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.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// 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 core
/// @file glm/detail/type_half.inl
/// @date 2008-08-17 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
namespace glm{
namespace detail
{
GLM_FUNC_QUALIFIER float overflow()
{
volatile float f = 1e10;
for(int i = 0; i < 10; ++i)
f *= f; // this will overflow before the for loop terminates
return f;
}
union uif32
{
GLM_FUNC_QUALIFIER uif32() :
i(0)
{}
GLM_FUNC_QUALIFIER uif32(float f) :
f(f)
{}
GLM_FUNC_QUALIFIER uif32(uint32 i) :
i(i)
{}
float f;
uint32 i;
};
GLM_FUNC_QUALIFIER float toFloat32(hdata value)
{
int s = (value >> 15) & 0x00000001;
int e = (value >> 10) & 0x0000001f;
int m = value & 0x000003ff;
if(e == 0)
{
if(m == 0)
{
//
// Plus or minus zero
//
detail::uif32 result;
result.i = (unsigned int)(s << 31);
return result.f;
}
else
{
//
// Denormalized number -- renormalize it
//
while(!(m & 0x00000400))
{
m <<= 1;
e -= 1;
}
e += 1;
m &= ~0x00000400;
}
}
else if(e == 31)
{
if(m == 0)
{
//
// Positive or negative infinity
//
uif32 result;
result.i = (unsigned int)((s << 31) | 0x7f800000);
return result.f;
}
else
{
//
// Nan -- preserve sign and significand bits
//
uif32 result;
result.i = (unsigned int)((s << 31) | 0x7f800000 | (m << 13));
return result.f;
}
}
//
// Normalized number
//
e = e + (127 - 15);
m = m << 13;
//
// Assemble s, e and m.
//
uif32 Result;
Result.i = (unsigned int)((s << 31) | (e << 23) | m);
return Result.f;
}
GLM_FUNC_QUALIFIER hdata toFloat16(float const & f)
{
uif32 Entry;
Entry.f = f;
int i = (int)Entry.i;
//
// Our floating point number, f, is represented by the bit
// pattern in integer i. Disassemble that bit pattern into
// the sign, s, the exponent, e, and the significand, m.
// Shift s into the position where it will go in in the
// resulting half number.
// Adjust e, accounting for the different exponent bias
// of float and half (127 versus 15).
//
int s = (i >> 16) & 0x00008000;
int e = ((i >> 23) & 0x000000ff) - (127 - 15);
int m = i & 0x007fffff;
//
// Now reassemble s, e and m into a half:
//
if(e <= 0)
{
if(e < -10)
{
//
// E is less than -10. The absolute value of f is
// less than half_MIN (f may be a small normalized
// float, a denormalized float or a zero).
//
// We convert f to a half zero.
//
return hdata(s);
}
//
// E is between -10 and 0. F is a normalized float,
// whose magnitude is less than __half_NRM_MIN.
//
// We convert f to a denormalized half.
//
m = (m | 0x00800000) >> (1 - e);
//
// Round to nearest, round "0.5" up.
//
// Rounding may cause the significand to overflow and make
// our number normalized. Because of the way a half's bits
// are laid out, we don't have to treat this case separately;
// the code below will handle it correctly.
//
if(m & 0x00001000)
m += 0x00002000;
//
// Assemble the half from s, e (zero) and m.
//
return hdata(s | (m >> 13));
}
else if(e == 0xff - (127 - 15))
{
if(m == 0)
{
//
// F is an infinity; convert f to a half
// infinity with the same sign as f.
//
return hdata(s | 0x7c00);
}
else
{
//
// F is a NAN; we produce a half NAN that preserves
// the sign bit and the 10 leftmost bits of the
// significand of f, with one exception: If the 10
// leftmost bits are all zero, the NAN would turn
// into an infinity, so we have to set at least one
// bit in the significand.
//
m >>= 13;
return hdata(s | 0x7c00 | m | (m == 0));
}
}
else
{
//
// E is greater than zero. F is a normalized float.
// We try to convert f to a normalized half.
//
//
// Round to nearest, round "0.5" up
//
if(m & 0x00001000)
{
m += 0x00002000;
if(m & 0x00800000)
{
m = 0; // overflow in significand,
e += 1; // adjust exponent
}
}
//
// Handle exponent overflow
//
if (e > 30)
{
overflow(); // Cause a hardware floating point overflow;
return hdata(s | 0x7c00);
// if this returns, the half becomes an
} // infinity with the same sign as f.
//
// Assemble the half from s, e and m.
//
return hdata(s | (e << 10) | (m >> 13));
}
}
}//namespace detail
}//namespace glm
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 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.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// 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 core
/// @file glm/detail/type_int.hpp
/// @date 2008-08-22 / 2013-03-30
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "setup.hpp"
#if GLM_HAS_MAKE_SIGNED
# include <type_traits>
#endif
#if GLM_HAS_EXTENDED_INTEGER_TYPE
# include <cstdint>
#endif
namespace glm{
namespace detail
{
# if GLM_HAS_EXTENDED_INTEGER_TYPE
typedef std::int8_t int8;
typedef std::int16_t int16;
typedef std::int32_t int32;
typedef std::int64_t int64;
typedef std::uint8_t uint8;
typedef std::uint16_t uint16;
typedef std::uint32_t uint32;
typedef std::uint64_t uint64;
# else
# if(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) // C99 detected, 64 bit types available
typedef int64_t sint64;
typedef uint64_t uint64;
# elif GLM_COMPILER & GLM_COMPILER_VC
typedef signed __int64 sint64;
typedef unsigned __int64 uint64;
# elif GLM_COMPILER & GLM_COMPILER_GCC
__extension__ typedef signed long long sint64;
__extension__ typedef unsigned long long uint64;
# else//unknown compiler
typedef signed long long sint64;
typedef unsigned long long uint64;
# endif//GLM_COMPILER
typedef signed char int8;
typedef signed short int16;
typedef signed int int32;
typedef sint64 int64;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef uint64 uint64;
#endif//
typedef signed int lowp_int_t;
typedef signed int mediump_int_t;
typedef signed int highp_int_t;
typedef unsigned int lowp_uint_t;
typedef unsigned int mediump_uint_t;
typedef unsigned int highp_uint_t;
# if GLM_HAS_MAKE_SIGNED
using std::make_signed;
using std::make_unsigned;
# else//GLM_HAS_MAKE_SIGNED
template <typename genType>
struct make_signed
{};
template <>
struct make_signed<char>
{
typedef char type;
};
template <>
struct make_signed<short>
{
typedef short type;
};
template <>
struct make_signed<int>
{
typedef int type;
};
template <>
struct make_signed<long>
{
typedef long type;
};
template <>
struct make_signed<long long>
{
typedef long long type;
};
template <>
struct make_signed<unsigned char>
{
typedef char type;
};
template <>
struct make_signed<unsigned short>
{
typedef short type;
};
template <>
struct make_signed<unsigned int>
{
typedef int type;
};
template <>
struct make_signed<unsigned long>
{
typedef long type;
};
template <>
struct make_signed<unsigned long long>
{
typedef long long type;
};
template <typename genType>
struct make_unsigned
{};
template <>
struct make_unsigned<char>
{
typedef unsigned char type;
};
template <>
struct make_unsigned<short>
{
typedef unsigned short type;
};
template <>
struct make_unsigned<int>
{
typedef unsigned int type;
};
template <>
struct make_unsigned<long>
{
typedef unsigned long type;
};
template <>
struct make_unsigned<long long>
{
typedef unsigned long long type;
};
template <>
struct make_unsigned<unsigned char>
{
typedef unsigned char type;
};
template <>
struct make_unsigned<unsigned short>
{
typedef unsigned short type;
};
template <>
struct make_unsigned<unsigned int>
{
typedef unsigned int type;
};
template <>
struct make_unsigned<unsigned long>
{
typedef unsigned long type;
};
template <>
struct make_unsigned<unsigned long long>
{
typedef unsigned long long type;
};
# endif//GLM_HAS_MAKE_SIGNED
}//namespace detail
typedef detail::int8 int8;
typedef detail::int16 int16;
typedef detail::int32 int32;
typedef detail::int64 int64;
typedef detail::uint8 uint8;
typedef detail::uint16 uint16;
typedef detail::uint32 uint32;
typedef detail::uint64 uint64;
/// @addtogroup core_precision
/// @{
/// Low precision signed integer.
/// There is no guarantee on the actual precision.
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.3 Integers</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier</a>
typedef detail::lowp_int_t lowp_int;
/// Medium precision signed integer.
/// There is no guarantee on the actual precision.
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.3 Integers</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier</a>
typedef detail::mediump_int_t mediump_int;
/// High precision signed integer.
/// There is no guarantee on the actual precision.
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.3 Integers</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier</a>
typedef detail::highp_int_t highp_int;
/// Low precision unsigned integer.
/// There is no guarantee on the actual precision.
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.3 Integers</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier</a>
typedef detail::lowp_uint_t lowp_uint;
/// Medium precision unsigned integer.
/// There is no guarantee on the actual precision.
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.3 Integers</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier</a>
typedef detail::mediump_uint_t mediump_uint;
/// High precision unsigned integer.
/// There is no guarantee on the actual precision.
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.3 Integers</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier</a>
typedef detail::highp_uint_t highp_uint;
#if(!defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
typedef mediump_int int_t;
#elif(defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
typedef highp_int int_t;
#elif(!defined(GLM_PRECISION_HIGHP_INT) && defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
typedef mediump_int int_t;
#elif(!defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && defined(GLM_PRECISION_LOWP_INT))
typedef lowp_int int_t;
#else
# error "GLM error: multiple default precision requested for signed interger types"
#endif
#if(!defined(GLM_PRECISION_HIGHP_UINT) && !defined(GLM_PRECISION_MEDIUMP_UINT) && !defined(GLM_PRECISION_LOWP_UINT))
typedef mediump_uint uint_t;
#elif(defined(GLM_PRECISION_HIGHP_UINT) && !defined(GLM_PRECISION_MEDIUMP_UINT) && !defined(GLM_PRECISION_LOWP_UINT))
typedef highp_uint uint_t;
#elif(!defined(GLM_PRECISION_HIGHP_UINT) && defined(GLM_PRECISION_MEDIUMP_UINT) && !defined(GLM_PRECISION_LOWP_UINT))
typedef mediump_uint uint_t;
#elif(!defined(GLM_PRECISION_HIGHP_UINT) && !defined(GLM_PRECISION_MEDIUMP_UINT) && defined(GLM_PRECISION_LOWP_UINT))
typedef lowp_uint uint_t;
#else
# error "GLM error: multiple default precision requested for unsigned interger types"
#endif
/// Unsigned integer type.
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.3 Integers</a>
typedef unsigned int uint;
/// @}
////////////////////
// check type sizes
#ifndef GLM_STATIC_ASSERT_NULL
GLM_STATIC_ASSERT(sizeof(glm::int8) == 1, "int8 size isn't 1 byte on this platform");
GLM_STATIC_ASSERT(sizeof(glm::int16) == 2, "int16 size isn't 2 bytes on this platform");
GLM_STATIC_ASSERT(sizeof(glm::int32) == 4, "int32 size isn't 4 bytes on this platform");
GLM_STATIC_ASSERT(sizeof(glm::int64) == 8, "int64 size isn't 8 bytes on this platform");
GLM_STATIC_ASSERT(sizeof(glm::uint8) == 1, "uint8 size isn't 1 byte on this platform");
GLM_STATIC_ASSERT(sizeof(glm::uint16) == 2, "uint16 size isn't 2 bytes on this platform");
GLM_STATIC_ASSERT(sizeof(glm::uint32) == 4, "uint32 size isn't 4 bytes on this platform");
GLM_STATIC_ASSERT(sizeof(glm::uint64) == 8, "uint64 size isn't 8 bytes on this platform");
#endif//GLM_STATIC_ASSERT_NULL
}//namespace glm
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment