mirror of
https://github.com/g-truc/glm.git
synced 2024-11-26 02:04:35 +00:00
Merge branch 'master' of https://github.com/amc522/glm into 0.9.8-align
This commit is contained in:
commit
4175505a83
@ -5,7 +5,7 @@ if (NOT CMAKE_VERSION VERSION_LESS "3.1")
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(glm)
|
project(glm)
|
||||||
set(GLM_VERSION "0.9.8")
|
set(GLM_VERSION "0.9.9")
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
@ -317,6 +317,10 @@ namespace detail
|
|||||||
template <typename T, glm::precision P, template <typename, glm::precision> class vecType>
|
template <typename T, glm::precision P, template <typename, glm::precision> class vecType>
|
||||||
GLM_FUNC_QUALIFIER vecType<int, P> bitCount(vecType<T, P> const & v)
|
GLM_FUNC_QUALIFIER vecType<int, P> bitCount(vecType<T, P> const & v)
|
||||||
{
|
{
|
||||||
|
#if GLM_COMPILER & GLM_COMPILER_VC
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4310) //cast truncates constant value
|
||||||
|
#endif
|
||||||
vecType<typename detail::make_unsigned<T>::type, P> x(*reinterpret_cast<vecType<typename detail::make_unsigned<T>::type, P> const *>(&v));
|
vecType<typename detail::make_unsigned<T>::type, P> x(*reinterpret_cast<vecType<typename detail::make_unsigned<T>::type, P> const *>(&v));
|
||||||
x = detail::compute_bitfieldBitCountStep<typename detail::make_unsigned<T>::type, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 2>::call(x, typename detail::make_unsigned<T>::type(0x5555555555555555ull), typename detail::make_unsigned<T>::type( 1));
|
x = detail::compute_bitfieldBitCountStep<typename detail::make_unsigned<T>::type, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 2>::call(x, typename detail::make_unsigned<T>::type(0x5555555555555555ull), typename detail::make_unsigned<T>::type( 1));
|
||||||
x = detail::compute_bitfieldBitCountStep<typename detail::make_unsigned<T>::type, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 4>::call(x, typename detail::make_unsigned<T>::type(0x3333333333333333ull), typename detail::make_unsigned<T>::type( 2));
|
x = detail::compute_bitfieldBitCountStep<typename detail::make_unsigned<T>::type, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 4>::call(x, typename detail::make_unsigned<T>::type(0x3333333333333333ull), typename detail::make_unsigned<T>::type( 2));
|
||||||
@ -325,6 +329,9 @@ namespace detail
|
|||||||
x = detail::compute_bitfieldBitCountStep<typename detail::make_unsigned<T>::type, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 32>::call(x, typename detail::make_unsigned<T>::type(0x0000FFFF0000FFFFull), typename detail::make_unsigned<T>::type(16));
|
x = detail::compute_bitfieldBitCountStep<typename detail::make_unsigned<T>::type, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 32>::call(x, typename detail::make_unsigned<T>::type(0x0000FFFF0000FFFFull), typename detail::make_unsigned<T>::type(16));
|
||||||
x = detail::compute_bitfieldBitCountStep<typename detail::make_unsigned<T>::type, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 64>::call(x, typename detail::make_unsigned<T>::type(0x00000000FFFFFFFFull), typename detail::make_unsigned<T>::type(32));
|
x = detail::compute_bitfieldBitCountStep<typename detail::make_unsigned<T>::type, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 64>::call(x, typename detail::make_unsigned<T>::type(0x00000000FFFFFFFFull), typename detail::make_unsigned<T>::type(32));
|
||||||
return vecType<int, P>(x);
|
return vecType<int, P>(x);
|
||||||
|
#if GLM_COMPILER & GLM_COMPILER_VC
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// findLSB
|
// findLSB
|
||||||
|
@ -3,25 +3,19 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if (defined(GLM_FORCE_SWIZZLE) || defined(GLM_SWIZZLE)) && defined(GLM_FORCE_UNRESTRICTED_GENTYPE)
|
#if defined(GLM_FORCE_SWIZZLE) && defined(GLM_FORCE_UNRESTRICTED_GENTYPE)
|
||||||
# error "Both GLM_FORCE_SWIZZLE and GLM_FORCE_UNRESTRICTED_GENTYPE can't be defined at the same time"
|
# error "Both GLM_FORCE_SWIZZLE and GLM_FORCE_UNRESTRICTED_GENTYPE can't be defined at the same time"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Messages
|
// Messages
|
||||||
|
|
||||||
#ifdef GLM_MESSAGES
|
|
||||||
# pragma message("GLM: GLM_MESSAGES is deprecated, use GLM_FORCE_MESSAGES instead")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GLM_MESSAGES_ENABLED 1
|
#define GLM_MESSAGES_ENABLED 1
|
||||||
#define GLM_MESSAGES_DISABLE 0
|
#define GLM_MESSAGES_DISABLE 0
|
||||||
|
|
||||||
#if defined(GLM_FORCE_MESSAGES) || defined(GLM_MESSAGES)
|
#if defined(GLM_FORCE_MESSAGES)
|
||||||
# undef GLM_MESSAGES
|
|
||||||
# define GLM_MESSAGES GLM_MESSAGES_ENABLED
|
# define GLM_MESSAGES GLM_MESSAGES_ENABLED
|
||||||
#else
|
#else
|
||||||
# undef GLM_MESSAGES
|
|
||||||
# define GLM_MESSAGES GLM_MESSAGES_DISABLE
|
# define GLM_MESSAGES GLM_MESSAGES_DISABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -32,15 +26,15 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Version
|
// Version
|
||||||
|
|
||||||
#define GLM_VERSION 98
|
#define GLM_VERSION 99
|
||||||
#define GLM_VERSION_MAJOR 0
|
#define GLM_VERSION_MAJOR 0
|
||||||
#define GLM_VERSION_MINOR 9
|
#define GLM_VERSION_MINOR 9
|
||||||
#define GLM_VERSION_PATCH 8
|
#define GLM_VERSION_PATCH 9
|
||||||
#define GLM_VERSION_REVISION 1
|
#define GLM_VERSION_REVISION 0
|
||||||
|
|
||||||
#if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_MESSAGE_VERSION_DISPLAYED)
|
#if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_MESSAGE_VERSION_DISPLAYED)
|
||||||
# define GLM_MESSAGE_VERSION_DISPLAYED
|
# define GLM_MESSAGE_VERSION_DISPLAYED
|
||||||
# pragma message ("GLM: version 0.9.8.0")
|
# pragma message ("GLM: version 0.9.9.0")
|
||||||
#endif//GLM_MESSAGES
|
#endif//GLM_MESSAGES
|
||||||
|
|
||||||
// Report compiler detection
|
// Report compiler detection
|
||||||
@ -550,18 +544,12 @@
|
|||||||
|
|
||||||
// User defines: GLM_FORCE_SWIZZLE
|
// User defines: GLM_FORCE_SWIZZLE
|
||||||
|
|
||||||
#ifdef GLM_SWIZZLE
|
|
||||||
# pragma message("GLM: GLM_SWIZZLE is deprecated, use GLM_FORCE_SWIZZLE instead")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GLM_SWIZZLE_ENABLED 1
|
#define GLM_SWIZZLE_ENABLED 1
|
||||||
#define GLM_SWIZZLE_DISABLE 0
|
#define GLM_SWIZZLE_DISABLE 0
|
||||||
|
|
||||||
#if defined(GLM_FORCE_SWIZZLE) || defined(GLM_SWIZZLE)
|
#if defined(GLM_FORCE_SWIZZLE)
|
||||||
# undef GLM_SWIZZLE
|
|
||||||
# define GLM_SWIZZLE GLM_SWIZZLE_ENABLED
|
# define GLM_SWIZZLE GLM_SWIZZLE_ENABLED
|
||||||
#else
|
#else
|
||||||
# undef GLM_SWIZZLE
|
|
||||||
# define GLM_SWIZZLE GLM_SWIZZLE_DISABLE
|
# define GLM_SWIZZLE GLM_SWIZZLE_DISABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -589,10 +577,6 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Clip control
|
// Clip control
|
||||||
|
|
||||||
#ifdef GLM_DEPTH_ZERO_TO_ONE // Legacy 0.9.8 development
|
|
||||||
# error Define GLM_FORCE_DEPTH_ZERO_TO_ONE instead of GLM_DEPTH_ZERO_TO_ONE to use 0 to 1 clip space.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GLM_DEPTH_ZERO_TO_ONE 0x00000001
|
#define GLM_DEPTH_ZERO_TO_ONE 0x00000001
|
||||||
#define GLM_DEPTH_NEGATIVE_ONE_TO_ONE 0x00000002
|
#define GLM_DEPTH_NEGATIVE_ONE_TO_ONE 0x00000002
|
||||||
|
|
||||||
@ -615,10 +599,6 @@
|
|||||||
// Coordinate system, define GLM_FORCE_LEFT_HANDED before including GLM
|
// Coordinate system, define GLM_FORCE_LEFT_HANDED before including GLM
|
||||||
// to use left handed coordinate system by default.
|
// to use left handed coordinate system by default.
|
||||||
|
|
||||||
#ifdef GLM_LEFT_HANDED // Legacy 0.9.8 development
|
|
||||||
# error Define GLM_FORCE_LEFT_HANDED instead of GLM_LEFT_HANDED left handed coordinate system by default.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GLM_LEFT_HANDED 0x00000001 // For DirectX, Metal, Vulkan
|
#define GLM_LEFT_HANDED 0x00000001 // For DirectX, Metal, Vulkan
|
||||||
#define GLM_RIGHT_HANDED 0x00000002 // For OpenGL, default in GLM
|
#define GLM_RIGHT_HANDED 0x00000002 // For OpenGL, default in GLM
|
||||||
|
|
||||||
|
@ -9,15 +9,6 @@
|
|||||||
namespace glm{
|
namespace glm{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<std::size_t N> struct aligned {};
|
|
||||||
template<> GLM_ALIGNED_STRUCT(1) aligned<1>{};
|
|
||||||
template<> GLM_ALIGNED_STRUCT(2) aligned<2>{};
|
|
||||||
template<> GLM_ALIGNED_STRUCT(4) aligned<4>{};
|
|
||||||
template<> GLM_ALIGNED_STRUCT(8) aligned<8>{};
|
|
||||||
template<> GLM_ALIGNED_STRUCT(16) aligned<16>{};
|
|
||||||
template<> GLM_ALIGNED_STRUCT(32) aligned<32>{};
|
|
||||||
template<> GLM_ALIGNED_STRUCT(64) aligned<64>{};
|
|
||||||
|
|
||||||
template <typename T, std::size_t size, bool aligned>
|
template <typename T, std::size_t size, bool aligned>
|
||||||
struct storage
|
struct storage
|
||||||
{
|
{
|
||||||
@ -26,15 +17,22 @@ namespace detail
|
|||||||
} type;
|
} type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, std::size_t size>
|
#define GLM_ALIGNED_STORAGE_TYPE_STRUCT(x) \
|
||||||
struct storage<T, size, true>
|
template <typename T> \
|
||||||
{
|
struct storage<T, x, true> { \
|
||||||
struct type : aligned<size>
|
GLM_ALIGNED_STRUCT(x) type { \
|
||||||
{
|
uint8_t data[x]; \
|
||||||
uint8 data[size];
|
}; \
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
GLM_ALIGNED_STORAGE_TYPE_STRUCT(1)
|
||||||
|
GLM_ALIGNED_STORAGE_TYPE_STRUCT(2)
|
||||||
|
GLM_ALIGNED_STORAGE_TYPE_STRUCT(4)
|
||||||
|
GLM_ALIGNED_STORAGE_TYPE_STRUCT(8)
|
||||||
|
GLM_ALIGNED_STORAGE_TYPE_STRUCT(16)
|
||||||
|
GLM_ALIGNED_STORAGE_TYPE_STRUCT(32)
|
||||||
|
GLM_ALIGNED_STORAGE_TYPE_STRUCT(64)
|
||||||
|
|
||||||
# if GLM_ARCH & GLM_ARCH_SSE2_BIT
|
# if GLM_ARCH & GLM_ARCH_SSE2_BIT
|
||||||
template <>
|
template <>
|
||||||
struct storage<float, 16, true>
|
struct storage<float, 16, true>
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#endif//GLM_MESSAGES
|
#endif//GLM_MESSAGES
|
||||||
|
|
||||||
#include "./gtc/bitfield.hpp"
|
#include "./gtc/bitfield.hpp"
|
||||||
|
#include "./gtc/color_encoding.hpp"
|
||||||
#include "./gtc/color_space.hpp"
|
#include "./gtc/color_space.hpp"
|
||||||
#include "./gtc/constants.hpp"
|
#include "./gtc/constants.hpp"
|
||||||
#include "./gtc/epsilon.hpp"
|
#include "./gtc/epsilon.hpp"
|
||||||
|
50
glm/gtc/color_encoding.hpp
Normal file
50
glm/gtc/color_encoding.hpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/// @ref gtc_color_encoding
|
||||||
|
/// @file glm/gtc/color_encoding.hpp
|
||||||
|
///
|
||||||
|
/// @see core (dependence)
|
||||||
|
/// @see gtc_color_encoding (dependence)
|
||||||
|
///
|
||||||
|
/// @defgroup gtc_color_encoding GLM_GTC_color_encoding
|
||||||
|
/// @ingroup gtc
|
||||||
|
///
|
||||||
|
/// @brief Allow to perform bit operations on integer values
|
||||||
|
///
|
||||||
|
/// <glm/gtc/color_encoding.hpp> need to be included to use these functionalities.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Dependencies
|
||||||
|
#include "../detail/setup.hpp"
|
||||||
|
#include "../detail/precision.hpp"
|
||||||
|
#include "../vec3.hpp"
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_EXT_INCLUDED)
|
||||||
|
# pragma message("GLM: GLM_GTC_color_encoding extension included")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace glm
|
||||||
|
{
|
||||||
|
/// @addtogroup gtc_color_encoding
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/// Convert a linear sRGB color to D65 YUV.
|
||||||
|
template <typename T, precision P>
|
||||||
|
GLM_FUNC_DECL tvec3<T, P> convertLinearSRGBToD65XYZ(tvec3<T, P> const& ColorLinearSRGB);
|
||||||
|
|
||||||
|
/// Convert a D65 YUV color to linear sRGB.
|
||||||
|
template <typename T, precision P>
|
||||||
|
GLM_FUNC_DECL tvec3<T, P> convertD65XYZToLinearSRGB(tvec3<T, P> const& ColorD65XYZ);
|
||||||
|
|
||||||
|
/// Convert a D50 YUV color to D65 YUV.
|
||||||
|
template <typename T, precision P>
|
||||||
|
GLM_FUNC_DECL tvec3<T, P> convertD50XYZToD65XYZ(tvec3<T, P> const& ColorD50XYZ);
|
||||||
|
|
||||||
|
/// Convert a D65 YUV color to D50 YUV.
|
||||||
|
template <typename T, precision P>
|
||||||
|
GLM_FUNC_DECL tvec3<T, P> convertD65XYZToD50XYZ(tvec3<T, P> const& ColorD65XYZ);
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
} //namespace glm
|
||||||
|
|
||||||
|
#include "color_encoding.inl"
|
@ -40,7 +40,7 @@ namespace glm
|
|||||||
tvec3<T, P> const N();
|
tvec3<T, P> const N();
|
||||||
tvec3<T, P> const O();
|
tvec3<T, P> const O();
|
||||||
|
|
||||||
return M * ColorD65XYZ + N * ColorD65XYZ + O * ColorD65XYZ;
|
return M * ColorD50XYZ + N * ColorD50XYZ + O * ColorD50XYZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, precision P>
|
template <typename T, precision P>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
///
|
///
|
||||||
/// @brief Allow to perform bit operations on integer values
|
/// @brief Allow to perform bit operations on integer values
|
||||||
///
|
///
|
||||||
/// <glm/gtc/color.hpp> need to be included to use these functionalities.
|
/// <glm/gtc/color_space.hpp> need to be included to use these functionalities.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@ -31,22 +31,22 @@ namespace glm
|
|||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// Convert a linear color to sRGB color using a standard gamma correction.
|
/// Convert a linear color to sRGB color using a standard gamma correction.
|
||||||
/// IEC 61966-2-1:1999 specification https://www.w3.org/Graphics/Color/srgb
|
/// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb
|
||||||
template <typename T, precision P, template <typename, precision> class vecType>
|
template <typename T, precision P, template <typename, precision> class vecType>
|
||||||
GLM_FUNC_DECL vecType<T, P> convertLinearToSRGB(vecType<T, P> const & ColorLinear);
|
GLM_FUNC_DECL vecType<T, P> convertLinearToSRGB(vecType<T, P> const & ColorLinear);
|
||||||
|
|
||||||
/// Convert a linear color to sRGB color using a custom gamma correction.
|
/// Convert a linear color to sRGB color using a custom gamma correction.
|
||||||
/// IEC 61966-2-1:1999 specification https://www.w3.org/Graphics/Color/srgb
|
/// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb
|
||||||
template <typename T, precision P, template <typename, precision> class vecType>
|
template <typename T, precision P, template <typename, precision> class vecType>
|
||||||
GLM_FUNC_DECL vecType<T, P> convertLinearToSRGB(vecType<T, P> const & ColorLinear, T Gamma);
|
GLM_FUNC_DECL vecType<T, P> convertLinearToSRGB(vecType<T, P> const & ColorLinear, T Gamma);
|
||||||
|
|
||||||
/// Convert a sRGB color to linear color using a standard gamma correction.
|
/// Convert a sRGB color to linear color using a standard gamma correction.
|
||||||
/// IEC 61966-2-1:1999 specification https://www.w3.org/Graphics/Color/srgb
|
/// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb
|
||||||
template <typename T, precision P, template <typename, precision> class vecType>
|
template <typename T, precision P, template <typename, precision> class vecType>
|
||||||
GLM_FUNC_DECL vecType<T, P> convertSRGBToLinear(vecType<T, P> const & ColorSRGB);
|
GLM_FUNC_DECL vecType<T, P> convertSRGBToLinear(vecType<T, P> const & ColorSRGB);
|
||||||
|
|
||||||
/// Convert a sRGB color to linear color using a custom gamma correction.
|
/// Convert a sRGB color to linear color using a custom gamma correction.
|
||||||
// IEC 61966-2-1:1999 specification https://www.w3.org/Graphics/Color/srgb
|
// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb
|
||||||
template <typename T, precision P, template <typename, precision> class vecType>
|
template <typename T, precision P, template <typename, precision> class vecType>
|
||||||
GLM_FUNC_DECL vecType<T, P> convertSRGBToLinear(vecType<T, P> const & ColorSRGB, T Gamma);
|
GLM_FUNC_DECL vecType<T, P> convertSRGBToLinear(vecType<T, P> const & ColorSRGB, T Gamma);
|
||||||
|
|
||||||
|
@ -1,182 +0,0 @@
|
|||||||
/// @ref gtx_simd_mat4
|
|
||||||
/// @file glm/gtx/simd_mat4.hpp
|
|
||||||
///
|
|
||||||
/// @see core (dependence)
|
|
||||||
///
|
|
||||||
/// @defgroup gtx_simd_mat4 GLM_GTX_simd_mat4
|
|
||||||
/// @ingroup gtx
|
|
||||||
///
|
|
||||||
/// @brief SIMD implementation of mat4 type.
|
|
||||||
///
|
|
||||||
/// <glm/gtx/simd_mat4.hpp> need to be included to use these functionalities.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// Dependencies
|
|
||||||
#include "../detail/setup.hpp"
|
|
||||||
|
|
||||||
#if(GLM_ARCH != GLM_ARCH_PURE)
|
|
||||||
|
|
||||||
#if(GLM_ARCH & GLM_ARCH_SSE2_BIT)
|
|
||||||
# include "../detail/intrinsic_matrix.hpp"
|
|
||||||
# include "../gtx/simd_vec4.hpp"
|
|
||||||
#else
|
|
||||||
# error "GLM: GLM_GTX_simd_mat4 requires compiler support of SSE2 through intrinsics"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_EXT_INCLUDED)
|
|
||||||
# pragma message("GLM: GLM_GTX_simd_mat4 extension included")
|
|
||||||
# pragma message("GLM: GLM_GTX_simd_mat4 extension is deprecated and will be removed in GLM 0.9.9. Use mat4 instead and use compiler SIMD arguments.")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace glm{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
/// 4x4 Matrix implemented using SIMD SEE intrinsics.
|
|
||||||
/// \ingroup gtx_simd_mat4
|
|
||||||
GLM_ALIGNED_STRUCT(16) fmat4x4SIMD
|
|
||||||
{
|
|
||||||
typedef float value_type;
|
|
||||||
typedef fvec4SIMD col_type;
|
|
||||||
typedef fvec4SIMD row_type;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
typedef fmat4x4SIMD type;
|
|
||||||
typedef fmat4x4SIMD transpose_type;
|
|
||||||
|
|
||||||
typedef tmat4x4<float, defaultp> pure_type;
|
|
||||||
typedef tvec4<float, defaultp> pure_row_type;
|
|
||||||
typedef tvec4<float, defaultp> pure_col_type;
|
|
||||||
typedef tmat4x4<float, defaultp> pure_transpose_type;
|
|
||||||
|
|
||||||
GLM_FUNC_DECL length_t length() const;
|
|
||||||
|
|
||||||
fvec4SIMD Data[4];
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
fmat4x4SIMD() GLM_DEFAULT_CTOR;
|
|
||||||
explicit fmat4x4SIMD(float const & s);
|
|
||||||
explicit fmat4x4SIMD(
|
|
||||||
float const & x0, float const & y0, float const & z0, float const & w0,
|
|
||||||
float const & x1, float const & y1, float const & z1, float const & w1,
|
|
||||||
float const & x2, float const & y2, float const & z2, float const & w2,
|
|
||||||
float const & x3, float const & y3, float const & z3, float const & w3);
|
|
||||||
explicit fmat4x4SIMD(
|
|
||||||
fvec4SIMD const & v0,
|
|
||||||
fvec4SIMD const & v1,
|
|
||||||
fvec4SIMD const & v2,
|
|
||||||
fvec4SIMD const & v3);
|
|
||||||
explicit fmat4x4SIMD(
|
|
||||||
mat4x4 const & m);
|
|
||||||
explicit fmat4x4SIMD(
|
|
||||||
__m128 const in[4]);
|
|
||||||
|
|
||||||
// Conversions
|
|
||||||
//template <typename U>
|
|
||||||
//explicit tmat4x4(tmat4x4<U> const & m);
|
|
||||||
|
|
||||||
//explicit tmat4x4(tmat2x2<T> const & x);
|
|
||||||
//explicit tmat4x4(tmat3x3<T> const & x);
|
|
||||||
//explicit tmat4x4(tmat2x3<T> const & x);
|
|
||||||
//explicit tmat4x4(tmat3x2<T> const & x);
|
|
||||||
//explicit tmat4x4(tmat2x4<T> const & x);
|
|
||||||
//explicit tmat4x4(tmat4x2<T> const & x);
|
|
||||||
//explicit tmat4x4(tmat3x4<T> const & x);
|
|
||||||
//explicit tmat4x4(tmat4x3<T> const & x);
|
|
||||||
|
|
||||||
// Accesses
|
|
||||||
fvec4SIMD & operator[](length_t i);
|
|
||||||
fvec4SIMD const & operator[](length_t i) const;
|
|
||||||
|
|
||||||
// Unary updatable operators
|
|
||||||
fmat4x4SIMD & operator= (fmat4x4SIMD const & m) GLM_DEFAULT;
|
|
||||||
fmat4x4SIMD & operator+= (float const & s);
|
|
||||||
fmat4x4SIMD & operator+= (fmat4x4SIMD const & m);
|
|
||||||
fmat4x4SIMD & operator-= (float const & s);
|
|
||||||
fmat4x4SIMD & operator-= (fmat4x4SIMD const & m);
|
|
||||||
fmat4x4SIMD & operator*= (float const & s);
|
|
||||||
fmat4x4SIMD & operator*= (fmat4x4SIMD const & m);
|
|
||||||
fmat4x4SIMD & operator/= (float const & s);
|
|
||||||
fmat4x4SIMD & operator/= (fmat4x4SIMD const & m);
|
|
||||||
fmat4x4SIMD & operator++ ();
|
|
||||||
fmat4x4SIMD & operator-- ();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Binary operators
|
|
||||||
fmat4x4SIMD operator+ (fmat4x4SIMD const & m, float const & s);
|
|
||||||
fmat4x4SIMD operator+ (float const & s, fmat4x4SIMD const & m);
|
|
||||||
fmat4x4SIMD operator+ (fmat4x4SIMD const & m1, fmat4x4SIMD const & m2);
|
|
||||||
|
|
||||||
fmat4x4SIMD operator- (fmat4x4SIMD const & m, float const & s);
|
|
||||||
fmat4x4SIMD operator- (float const & s, fmat4x4SIMD const & m);
|
|
||||||
fmat4x4SIMD operator- (fmat4x4SIMD const & m1, fmat4x4SIMD const & m2);
|
|
||||||
|
|
||||||
fmat4x4SIMD operator* (fmat4x4SIMD const & m, float const & s);
|
|
||||||
fmat4x4SIMD operator* (float const & s, fmat4x4SIMD const & m);
|
|
||||||
|
|
||||||
fvec4SIMD operator* (fmat4x4SIMD const & m, fvec4SIMD const & v);
|
|
||||||
fvec4SIMD operator* (fvec4SIMD const & v, fmat4x4SIMD const & m);
|
|
||||||
|
|
||||||
fmat4x4SIMD operator* (fmat4x4SIMD const & m1, fmat4x4SIMD const & m2);
|
|
||||||
|
|
||||||
fmat4x4SIMD operator/ (fmat4x4SIMD const & m, float const & s);
|
|
||||||
fmat4x4SIMD operator/ (float const & s, fmat4x4SIMD const & m);
|
|
||||||
|
|
||||||
fvec4SIMD operator/ (fmat4x4SIMD const & m, fvec4SIMD const & v);
|
|
||||||
fvec4SIMD operator/ (fvec4SIMD const & v, fmat4x4SIMD const & m);
|
|
||||||
|
|
||||||
fmat4x4SIMD operator/ (fmat4x4SIMD const & m1, fmat4x4SIMD const & m2);
|
|
||||||
|
|
||||||
// Unary constant operators
|
|
||||||
fmat4x4SIMD const operator- (fmat4x4SIMD const & m);
|
|
||||||
fmat4x4SIMD const operator-- (fmat4x4SIMD const & m, int);
|
|
||||||
fmat4x4SIMD const operator++ (fmat4x4SIMD const & m, int);
|
|
||||||
}//namespace detail
|
|
||||||
|
|
||||||
typedef detail::fmat4x4SIMD simdMat4;
|
|
||||||
|
|
||||||
/// @addtogroup gtx_simd_mat4
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
//! Convert a simdMat4 to a mat4.
|
|
||||||
//! (From GLM_GTX_simd_mat4 extension)
|
|
||||||
mat4 mat4_cast(
|
|
||||||
detail::fmat4x4SIMD const & x);
|
|
||||||
|
|
||||||
//! Multiply matrix x by matrix y component-wise, i.e.,
|
|
||||||
//! result[i][j] is the scalar product of x[i][j] and y[i][j].
|
|
||||||
//! (From GLM_GTX_simd_mat4 extension).
|
|
||||||
detail::fmat4x4SIMD matrixCompMult(
|
|
||||||
detail::fmat4x4SIMD const & x,
|
|
||||||
detail::fmat4x4SIMD const & y);
|
|
||||||
|
|
||||||
//! Treats the first parameter c as a column vector
|
|
||||||
//! and the second parameter r as a row vector
|
|
||||||
//! and does a linear algebraic matrix multiply c * r.
|
|
||||||
//! (From GLM_GTX_simd_mat4 extension).
|
|
||||||
detail::fmat4x4SIMD outerProduct(
|
|
||||||
detail::fvec4SIMD const & c,
|
|
||||||
detail::fvec4SIMD const & r);
|
|
||||||
|
|
||||||
//! Returns the transposed matrix of x
|
|
||||||
//! (From GLM_GTX_simd_mat4 extension).
|
|
||||||
detail::fmat4x4SIMD transpose(
|
|
||||||
detail::fmat4x4SIMD const & x);
|
|
||||||
|
|
||||||
//! Return the determinant of a mat4 matrix.
|
|
||||||
//! (From GLM_GTX_simd_mat4 extension).
|
|
||||||
float determinant(
|
|
||||||
detail::fmat4x4SIMD const & m);
|
|
||||||
|
|
||||||
//! Return the inverse of a mat4 matrix.
|
|
||||||
//! (From GLM_GTX_simd_mat4 extension).
|
|
||||||
detail::fmat4x4SIMD inverse(
|
|
||||||
detail::fmat4x4SIMD const & m);
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
}// namespace glm
|
|
||||||
|
|
||||||
#include "simd_mat4.inl"
|
|
||||||
|
|
||||||
#endif//(GLM_ARCH != GLM_ARCH_PURE)
|
|
@ -1,577 +0,0 @@
|
|||||||
/// @ref gtx_simd_mat4
|
|
||||||
/// @file glm/gtx/simd_mat4.inl
|
|
||||||
|
|
||||||
namespace glm{
|
|
||||||
namespace detail{
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER length_t fmat4x4SIMD::length() const
|
|
||||||
{
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Accesses
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD & fmat4x4SIMD::operator[]
|
|
||||||
(
|
|
||||||
length_t i
|
|
||||||
)
|
|
||||||
{
|
|
||||||
assert(i < this->length());
|
|
||||||
|
|
||||||
return this->Data[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD const & fmat4x4SIMD::operator[]
|
|
||||||
(
|
|
||||||
length_t i
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
assert(i < this->length());
|
|
||||||
|
|
||||||
return this->Data[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
#if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD()
|
|
||||||
{
|
|
||||||
# ifndef GLM_FORCE_NO_CTOR_INIT
|
|
||||||
this->Data[0] = fvec4SIMD(1, 0, 0, 0);
|
|
||||||
this->Data[1] = fvec4SIMD(0, 1, 0, 0);
|
|
||||||
this->Data[2] = fvec4SIMD(0, 0, 1, 0);
|
|
||||||
this->Data[3] = fvec4SIMD(0, 0, 0, 1);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
# endif//!GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD(float const & s)
|
|
||||||
{
|
|
||||||
this->Data[0] = fvec4SIMD(s, 0, 0, 0);
|
|
||||||
this->Data[1] = fvec4SIMD(0, s, 0, 0);
|
|
||||||
this->Data[2] = fvec4SIMD(0, 0, s, 0);
|
|
||||||
this->Data[3] = fvec4SIMD(0, 0, 0, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
float const & x0, float const & y0, float const & z0, float const & w0,
|
|
||||||
float const & x1, float const & y1, float const & z1, float const & w1,
|
|
||||||
float const & x2, float const & y2, float const & z2, float const & w2,
|
|
||||||
float const & x3, float const & y3, float const & z3, float const & w3
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this->Data[0] = fvec4SIMD(x0, y0, z0, w0);
|
|
||||||
this->Data[1] = fvec4SIMD(x1, y1, z1, w1);
|
|
||||||
this->Data[2] = fvec4SIMD(x2, y2, z2, w2);
|
|
||||||
this->Data[3] = fvec4SIMD(x3, y3, z3, w3);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
fvec4SIMD const & v0,
|
|
||||||
fvec4SIMD const & v1,
|
|
||||||
fvec4SIMD const & v2,
|
|
||||||
fvec4SIMD const & v3
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this->Data[0] = v0;
|
|
||||||
this->Data[1] = v1;
|
|
||||||
this->Data[2] = v2;
|
|
||||||
this->Data[3] = v3;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
mat4 const & m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this->Data[0] = fvec4SIMD(m[0]);
|
|
||||||
this->Data[1] = fvec4SIMD(m[1]);
|
|
||||||
this->Data[2] = fvec4SIMD(m[2]);
|
|
||||||
this->Data[3] = fvec4SIMD(m[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
__m128 const in[4]
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this->Data[0] = in[0];
|
|
||||||
this->Data[1] = in[1];
|
|
||||||
this->Data[2] = in[2];
|
|
||||||
this->Data[3] = in[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
// mat4 operators
|
|
||||||
|
|
||||||
#if !GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD& fmat4x4SIMD::operator=
|
|
||||||
(
|
|
||||||
fmat4x4SIMD const & m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this->Data[0] = m[0];
|
|
||||||
this->Data[1] = m[1];
|
|
||||||
this->Data[2] = m[2];
|
|
||||||
this->Data[3] = m[3];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif//!GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
|
|
||||||
(
|
|
||||||
fmat4x4SIMD const & m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this->Data[0].Data = _mm_add_ps(this->Data[0].Data, m[0].Data);
|
|
||||||
this->Data[1].Data = _mm_add_ps(this->Data[1].Data, m[1].Data);
|
|
||||||
this->Data[2].Data = _mm_add_ps(this->Data[2].Data, m[2].Data);
|
|
||||||
this->Data[3].Data = _mm_add_ps(this->Data[3].Data, m[3].Data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
|
|
||||||
(
|
|
||||||
fmat4x4SIMD const & m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, m[0].Data);
|
|
||||||
this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, m[1].Data);
|
|
||||||
this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, m[2].Data);
|
|
||||||
this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, m[3].Data);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
|
|
||||||
(
|
|
||||||
fmat4x4SIMD const & m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
sse_mul_ps(&this->Data[0].Data, &m.Data[0].Data, &this->Data[0].Data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
|
|
||||||
(
|
|
||||||
fmat4x4SIMD const & m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 Inv[4];
|
|
||||||
sse_inverse_ps(&m.Data[0].Data, Inv);
|
|
||||||
sse_mul_ps(&this->Data[0].Data, Inv, &this->Data[0].Data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
|
|
||||||
(
|
|
||||||
float const & s
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 Operand = _mm_set_ps1(s);
|
|
||||||
this->Data[0].Data = _mm_add_ps(this->Data[0].Data, Operand);
|
|
||||||
this->Data[1].Data = _mm_add_ps(this->Data[1].Data, Operand);
|
|
||||||
this->Data[2].Data = _mm_add_ps(this->Data[2].Data, Operand);
|
|
||||||
this->Data[3].Data = _mm_add_ps(this->Data[3].Data, Operand);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
|
|
||||||
(
|
|
||||||
float const & s
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 Operand = _mm_set_ps1(s);
|
|
||||||
this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, Operand);
|
|
||||||
this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, Operand);
|
|
||||||
this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, Operand);
|
|
||||||
this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, Operand);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
|
|
||||||
(
|
|
||||||
float const & s
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 Operand = _mm_set_ps1(s);
|
|
||||||
this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
|
|
||||||
this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
|
|
||||||
this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
|
|
||||||
this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
|
|
||||||
(
|
|
||||||
float const & s
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 Operand = _mm_div_ps(one, _mm_set_ps1(s));
|
|
||||||
this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
|
|
||||||
this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
|
|
||||||
this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
|
|
||||||
this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator++ ()
|
|
||||||
{
|
|
||||||
this->Data[0].Data = _mm_add_ps(this->Data[0].Data, one);
|
|
||||||
this->Data[1].Data = _mm_add_ps(this->Data[1].Data, one);
|
|
||||||
this->Data[2].Data = _mm_add_ps(this->Data[2].Data, one);
|
|
||||||
this->Data[3].Data = _mm_add_ps(this->Data[3].Data, one);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-- ()
|
|
||||||
{
|
|
||||||
this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, one);
|
|
||||||
this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, one);
|
|
||||||
this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, one);
|
|
||||||
this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, one);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
// Binary operators
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator+
|
|
||||||
(
|
|
||||||
const fmat4x4SIMD &m,
|
|
||||||
float const & s
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
m[0] + s,
|
|
||||||
m[1] + s,
|
|
||||||
m[2] + s,
|
|
||||||
m[3] + s
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator+
|
|
||||||
(
|
|
||||||
float const & s,
|
|
||||||
const fmat4x4SIMD &m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
m[0] + s,
|
|
||||||
m[1] + s,
|
|
||||||
m[2] + s,
|
|
||||||
m[3] + s
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator+
|
|
||||||
(
|
|
||||||
const fmat4x4SIMD &m1,
|
|
||||||
const fmat4x4SIMD &m2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
m1[0] + m2[0],
|
|
||||||
m1[1] + m2[1],
|
|
||||||
m1[2] + m2[2],
|
|
||||||
m1[3] + m2[3]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator-
|
|
||||||
(
|
|
||||||
const fmat4x4SIMD &m,
|
|
||||||
float const & s
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
m[0] - s,
|
|
||||||
m[1] - s,
|
|
||||||
m[2] - s,
|
|
||||||
m[3] - s
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator-
|
|
||||||
(
|
|
||||||
float const & s,
|
|
||||||
const fmat4x4SIMD &m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
s - m[0],
|
|
||||||
s - m[1],
|
|
||||||
s - m[2],
|
|
||||||
s - m[3]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator-
|
|
||||||
(
|
|
||||||
const fmat4x4SIMD &m1,
|
|
||||||
const fmat4x4SIMD &m2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
m1[0] - m2[0],
|
|
||||||
m1[1] - m2[1],
|
|
||||||
m1[2] - m2[2],
|
|
||||||
m1[3] - m2[3]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator*
|
|
||||||
(
|
|
||||||
const fmat4x4SIMD &m,
|
|
||||||
float const & s
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
m[0] * s,
|
|
||||||
m[1] * s,
|
|
||||||
m[2] * s,
|
|
||||||
m[3] * s
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator*
|
|
||||||
(
|
|
||||||
float const & s,
|
|
||||||
const fmat4x4SIMD &m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
m[0] * s,
|
|
||||||
m[1] * s,
|
|
||||||
m[2] * s,
|
|
||||||
m[3] * s
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator*
|
|
||||||
(
|
|
||||||
const fmat4x4SIMD &m,
|
|
||||||
fvec4SIMD const & v
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return sse_mul_ps(&m.Data[0].Data, v.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator*
|
|
||||||
(
|
|
||||||
fvec4SIMD const & v,
|
|
||||||
const fmat4x4SIMD &m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return sse_mul_ps(v.Data, &m.Data[0].Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator*
|
|
||||||
(
|
|
||||||
const fmat4x4SIMD &m1,
|
|
||||||
const fmat4x4SIMD &m2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
fmat4x4SIMD result;
|
|
||||||
sse_mul_ps(&m1.Data[0].Data, &m2.Data[0].Data, &result.Data[0].Data);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator/
|
|
||||||
(
|
|
||||||
const fmat4x4SIMD &m,
|
|
||||||
float const & s
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
m[0] / s,
|
|
||||||
m[1] / s,
|
|
||||||
m[2] / s,
|
|
||||||
m[3] / s
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator/
|
|
||||||
(
|
|
||||||
float const & s,
|
|
||||||
const fmat4x4SIMD &m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
s / m[0],
|
|
||||||
s / m[1],
|
|
||||||
s / m[2],
|
|
||||||
s / m[3]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fmat4x4SIMD inverse(detail::fmat4x4SIMD const & m)
|
|
||||||
{
|
|
||||||
detail::fmat4x4SIMD result;
|
|
||||||
detail::sse_inverse_ps(&m[0].Data, &result[0].Data);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator/
|
|
||||||
(
|
|
||||||
const fmat4x4SIMD & m,
|
|
||||||
fvec4SIMD const & v
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return inverse(m) * v;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator/
|
|
||||||
(
|
|
||||||
fvec4SIMD const & v,
|
|
||||||
const fmat4x4SIMD &m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return v * inverse(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD operator/
|
|
||||||
(
|
|
||||||
const fmat4x4SIMD &m1,
|
|
||||||
const fmat4x4SIMD &m2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 result[4];
|
|
||||||
__m128 inv[4];
|
|
||||||
|
|
||||||
sse_inverse_ps(&m2.Data[0].Data, inv);
|
|
||||||
sse_mul_ps(&m1.Data[0].Data, inv, result);
|
|
||||||
|
|
||||||
return fmat4x4SIMD(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
// Unary constant operators
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD const operator-
|
|
||||||
(
|
|
||||||
fmat4x4SIMD const & m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
-m[0],
|
|
||||||
-m[1],
|
|
||||||
-m[2],
|
|
||||||
-m[3]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD const operator--
|
|
||||||
(
|
|
||||||
fmat4x4SIMD const & m,
|
|
||||||
int
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
m[0] - 1.0f,
|
|
||||||
m[1] - 1.0f,
|
|
||||||
m[2] - 1.0f,
|
|
||||||
m[3] - 1.0f
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fmat4x4SIMD const operator++
|
|
||||||
(
|
|
||||||
fmat4x4SIMD const & m,
|
|
||||||
int
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fmat4x4SIMD
|
|
||||||
(
|
|
||||||
m[0] + 1.0f,
|
|
||||||
m[1] + 1.0f,
|
|
||||||
m[2] + 1.0f,
|
|
||||||
m[3] + 1.0f
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}//namespace detail
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER mat4 mat4_cast
|
|
||||||
(
|
|
||||||
detail::fmat4x4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GLM_ALIGN(16) mat4 Result;
|
|
||||||
_mm_store_ps(&Result[0][0], x.Data[0].Data);
|
|
||||||
_mm_store_ps(&Result[1][0], x.Data[1].Data);
|
|
||||||
_mm_store_ps(&Result[2][0], x.Data[2].Data);
|
|
||||||
_mm_store_ps(&Result[3][0], x.Data[3].Data);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fmat4x4SIMD matrixCompMult
|
|
||||||
(
|
|
||||||
detail::fmat4x4SIMD const & x,
|
|
||||||
detail::fmat4x4SIMD const & y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
detail::fmat4x4SIMD result;
|
|
||||||
result[0] = x[0] * y[0];
|
|
||||||
result[1] = x[1] * y[1];
|
|
||||||
result[2] = x[2] * y[2];
|
|
||||||
result[3] = x[3] * y[3];
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fmat4x4SIMD outerProduct
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & c,
|
|
||||||
detail::fvec4SIMD const & r
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 Shu0 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(0, 0, 0, 0));
|
|
||||||
__m128 Shu1 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(1, 1, 1, 1));
|
|
||||||
__m128 Shu2 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(2, 2, 2, 2));
|
|
||||||
__m128 Shu3 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(3, 3, 3, 3));
|
|
||||||
|
|
||||||
detail::fmat4x4SIMD result(uninitialize);
|
|
||||||
result[0].Data = _mm_mul_ps(c.Data, Shu0);
|
|
||||||
result[1].Data = _mm_mul_ps(c.Data, Shu1);
|
|
||||||
result[2].Data = _mm_mul_ps(c.Data, Shu2);
|
|
||||||
result[3].Data = _mm_mul_ps(c.Data, Shu3);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fmat4x4SIMD transpose(detail::fmat4x4SIMD const & m)
|
|
||||||
{
|
|
||||||
detail::fmat4x4SIMD result;
|
|
||||||
glm_mat4_transpose(&m[0].Data, &result[0].Data);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER float determinant(detail::fmat4x4SIMD const & m)
|
|
||||||
{
|
|
||||||
float Result;
|
|
||||||
_mm_store_ss(&Result, glm_mat4_determinant(&m[0].Data));
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}//namespace glm
|
|
@ -1,307 +0,0 @@
|
|||||||
/// @ref gtx_simd_quat
|
|
||||||
/// @file glm/gtx/simd_quat.hpp
|
|
||||||
///
|
|
||||||
/// @see core (dependence)
|
|
||||||
///
|
|
||||||
/// @defgroup gtx_simd_quat GLM_GTX_simd_quat
|
|
||||||
/// @ingroup gtx
|
|
||||||
///
|
|
||||||
/// @brief SIMD implementation of quat type.
|
|
||||||
///
|
|
||||||
/// <glm/gtx/simd_quat.hpp> need to be included to use these functionalities.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// Dependency:
|
|
||||||
#include "../glm.hpp"
|
|
||||||
#include "../gtc/quaternion.hpp"
|
|
||||||
#include "../gtx/fast_trigonometry.hpp"
|
|
||||||
|
|
||||||
#if GLM_ARCH != GLM_ARCH_PURE
|
|
||||||
|
|
||||||
#if GLM_ARCH & GLM_ARCH_SSE2_BIT
|
|
||||||
# include "../gtx/simd_mat4.hpp"
|
|
||||||
#else
|
|
||||||
# error "GLM: GLM_GTX_simd_quat requires compiler support of SSE2 through intrinsics"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_EXT_INCLUDED)
|
|
||||||
# pragma message("GLM: GLM_GTX_simd_quat extension included")
|
|
||||||
# pragma message("GLM: GLM_GTX_simd_quat extension is deprecated and will be removed in GLM 0.9.9. Use GLM_GTC_quaternion instead and use compiler SIMD arguments.")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Warning silencer for nameless struct/union.
|
|
||||||
#if (GLM_COMPILER & GLM_COMPILER_VC)
|
|
||||||
# pragma warning(push)
|
|
||||||
# pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace glm{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
GLM_ALIGNED_STRUCT(16) fquatSIMD
|
|
||||||
{
|
|
||||||
typedef float value_type;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
|
|
||||||
typedef fquatSIMD type;
|
|
||||||
typedef tquat<bool, defaultp> bool_type;
|
|
||||||
typedef tquat<float, defaultp> pure_type;
|
|
||||||
|
|
||||||
#ifdef GLM_SIMD_ENABLE_XYZW_UNION
|
|
||||||
union
|
|
||||||
{
|
|
||||||
__m128 Data;
|
|
||||||
struct {float x, y, z, w;};
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
__m128 Data;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Implicit basic constructors
|
|
||||||
|
|
||||||
fquatSIMD() GLM_DEFAULT_CTOR;
|
|
||||||
fquatSIMD(fquatSIMD const & q) GLM_DEFAULT;
|
|
||||||
fquatSIMD(__m128 const & Data);
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Explicit basic constructors
|
|
||||||
|
|
||||||
explicit fquatSIMD(
|
|
||||||
ctor);
|
|
||||||
explicit fquatSIMD(
|
|
||||||
float const & w,
|
|
||||||
float const & x,
|
|
||||||
float const & y,
|
|
||||||
float const & z);
|
|
||||||
explicit fquatSIMD(
|
|
||||||
quat const & v);
|
|
||||||
explicit fquatSIMD(
|
|
||||||
vec3 const & eulerAngles);
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Unary arithmetic operators
|
|
||||||
|
|
||||||
fquatSIMD& operator= (fquatSIMD const & q) GLM_DEFAULT;
|
|
||||||
fquatSIMD& operator*=(float const & s);
|
|
||||||
fquatSIMD& operator/=(float const & s);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Arithmetic operators
|
|
||||||
|
|
||||||
detail::fquatSIMD operator- (
|
|
||||||
detail::fquatSIMD const & q);
|
|
||||||
|
|
||||||
detail::fquatSIMD operator+ (
|
|
||||||
detail::fquatSIMD const & q,
|
|
||||||
detail::fquatSIMD const & p);
|
|
||||||
|
|
||||||
detail::fquatSIMD operator* (
|
|
||||||
detail::fquatSIMD const & q,
|
|
||||||
detail::fquatSIMD const & p);
|
|
||||||
|
|
||||||
detail::fvec4SIMD operator* (
|
|
||||||
detail::fquatSIMD const & q,
|
|
||||||
detail::fvec4SIMD const & v);
|
|
||||||
|
|
||||||
detail::fvec4SIMD operator* (
|
|
||||||
detail::fvec4SIMD const & v,
|
|
||||||
detail::fquatSIMD const & q);
|
|
||||||
|
|
||||||
detail::fquatSIMD operator* (
|
|
||||||
detail::fquatSIMD const & q,
|
|
||||||
float s);
|
|
||||||
|
|
||||||
detail::fquatSIMD operator* (
|
|
||||||
float s,
|
|
||||||
detail::fquatSIMD const & q);
|
|
||||||
|
|
||||||
detail::fquatSIMD operator/ (
|
|
||||||
detail::fquatSIMD const & q,
|
|
||||||
float s);
|
|
||||||
|
|
||||||
}//namespace detail
|
|
||||||
|
|
||||||
/// @addtogroup gtx_simd_quat
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
typedef glm::detail::fquatSIMD simdQuat;
|
|
||||||
|
|
||||||
//! Convert a simdQuat to a quat.
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
quat quat_cast(
|
|
||||||
detail::fquatSIMD const & x);
|
|
||||||
|
|
||||||
//! Convert a simdMat4 to a simdQuat.
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
detail::fquatSIMD quatSIMD_cast(
|
|
||||||
detail::fmat4x4SIMD const & m);
|
|
||||||
|
|
||||||
//! Converts a mat4 to a simdQuat.
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
template <typename T, precision P>
|
|
||||||
detail::fquatSIMD quatSIMD_cast(
|
|
||||||
tmat4x4<T, P> const & m);
|
|
||||||
|
|
||||||
//! Converts a mat3 to a simdQuat.
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
template <typename T, precision P>
|
|
||||||
detail::fquatSIMD quatSIMD_cast(
|
|
||||||
tmat3x3<T, P> const & m);
|
|
||||||
|
|
||||||
//! Convert a simdQuat to a simdMat4
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
detail::fmat4x4SIMD mat4SIMD_cast(
|
|
||||||
detail::fquatSIMD const & q);
|
|
||||||
|
|
||||||
//! Converts a simdQuat to a standard mat4.
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
mat4 mat4_cast(
|
|
||||||
detail::fquatSIMD const & q);
|
|
||||||
|
|
||||||
|
|
||||||
/// Returns the length of the quaternion.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
float length(
|
|
||||||
detail::fquatSIMD const & x);
|
|
||||||
|
|
||||||
/// Returns the normalized quaternion.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
detail::fquatSIMD normalize(
|
|
||||||
detail::fquatSIMD const & x);
|
|
||||||
|
|
||||||
/// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ...
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
float dot(
|
|
||||||
detail::fquatSIMD const & q1,
|
|
||||||
detail::fquatSIMD const & q2);
|
|
||||||
|
|
||||||
/// Spherical linear interpolation of two quaternions.
|
|
||||||
/// The interpolation is oriented and the rotation is performed at constant speed.
|
|
||||||
/// For short path spherical linear interpolation, use the slerp function.
|
|
||||||
///
|
|
||||||
/// @param x A quaternion
|
|
||||||
/// @param y A quaternion
|
|
||||||
/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
|
|
||||||
/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
/// @see - slerp(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a)
|
|
||||||
detail::fquatSIMD mix(
|
|
||||||
detail::fquatSIMD const & x,
|
|
||||||
detail::fquatSIMD const & y,
|
|
||||||
float const & a);
|
|
||||||
|
|
||||||
/// Linear interpolation of two quaternions.
|
|
||||||
/// The interpolation is oriented.
|
|
||||||
///
|
|
||||||
/// @param x A quaternion
|
|
||||||
/// @param y A quaternion
|
|
||||||
/// @param a Interpolation factor. The interpolation is defined in the range [0, 1].
|
|
||||||
/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
detail::fquatSIMD lerp(
|
|
||||||
detail::fquatSIMD const & x,
|
|
||||||
detail::fquatSIMD const & y,
|
|
||||||
float const & a);
|
|
||||||
|
|
||||||
/// Spherical linear interpolation of two quaternions.
|
|
||||||
/// The interpolation always take the short path and the rotation is performed at constant speed.
|
|
||||||
///
|
|
||||||
/// @param x A quaternion
|
|
||||||
/// @param y A quaternion
|
|
||||||
/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
|
|
||||||
/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
detail::fquatSIMD slerp(
|
|
||||||
detail::fquatSIMD const & x,
|
|
||||||
detail::fquatSIMD const & y,
|
|
||||||
float const & a);
|
|
||||||
|
|
||||||
|
|
||||||
/// Faster spherical linear interpolation of two unit length quaternions.
|
|
||||||
///
|
|
||||||
/// This is the same as mix(), except for two rules:
|
|
||||||
/// 1) The two quaternions must be unit length.
|
|
||||||
/// 2) The interpolation factor (a) must be in the range [0, 1].
|
|
||||||
///
|
|
||||||
/// This will use the equivalent to fastAcos() and fastSin().
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
/// @see - mix(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a)
|
|
||||||
detail::fquatSIMD fastMix(
|
|
||||||
detail::fquatSIMD const & x,
|
|
||||||
detail::fquatSIMD const & y,
|
|
||||||
float const & a);
|
|
||||||
|
|
||||||
/// Identical to fastMix() except takes the shortest path.
|
|
||||||
///
|
|
||||||
/// The same rules apply here as those in fastMix(). Both quaternions must be unit length and 'a' must be
|
|
||||||
/// in the range [0, 1].
|
|
||||||
///
|
|
||||||
/// @see - fastMix(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a)
|
|
||||||
/// @see - slerp(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a)
|
|
||||||
detail::fquatSIMD fastSlerp(
|
|
||||||
detail::fquatSIMD const & x,
|
|
||||||
detail::fquatSIMD const & y,
|
|
||||||
float const & a);
|
|
||||||
|
|
||||||
|
|
||||||
/// Returns the q conjugate.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
detail::fquatSIMD conjugate(
|
|
||||||
detail::fquatSIMD const & q);
|
|
||||||
|
|
||||||
/// Returns the q inverse.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
detail::fquatSIMD inverse(
|
|
||||||
detail::fquatSIMD const & q);
|
|
||||||
|
|
||||||
/// Build a quaternion from an angle and a normalized axis.
|
|
||||||
///
|
|
||||||
/// @param angle Angle expressed in radians.
|
|
||||||
/// @param axis Axis of the quaternion, must be normalized.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
detail::fquatSIMD angleAxisSIMD(
|
|
||||||
float const & angle,
|
|
||||||
vec3 const & axis);
|
|
||||||
|
|
||||||
/// Build a quaternion from an angle and a normalized axis.
|
|
||||||
///
|
|
||||||
/// @param angle Angle expressed in radians.
|
|
||||||
/// @param x x component of the x-axis, x, y, z must be a normalized axis
|
|
||||||
/// @param y y component of the y-axis, x, y, z must be a normalized axis
|
|
||||||
/// @param z z component of the z-axis, x, y, z must be a normalized axis
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_quat
|
|
||||||
detail::fquatSIMD angleAxisSIMD(
|
|
||||||
float const & angle,
|
|
||||||
float const & x,
|
|
||||||
float const & y,
|
|
||||||
float const & z);
|
|
||||||
|
|
||||||
// TODO: Move this to somewhere more appropriate. Used with fastMix() and fastSlerp().
|
|
||||||
/// Performs the equivalent of glm::fastSin() on each component of the given __m128.
|
|
||||||
__m128 fastSin(__m128 x);
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
}//namespace glm
|
|
||||||
|
|
||||||
#include "simd_quat.inl"
|
|
||||||
|
|
||||||
|
|
||||||
#if (GLM_COMPILER & GLM_COMPILER_VC)
|
|
||||||
# pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif//(GLM_ARCH != GLM_ARCH_PURE)
|
|
@ -1,620 +0,0 @@
|
|||||||
/// @ref gtx_simd_quat
|
|
||||||
/// @file glm/gtx/simd_quat.inl
|
|
||||||
|
|
||||||
namespace glm{
|
|
||||||
namespace detail{
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Debugging
|
|
||||||
#if 0
|
|
||||||
void print(__m128 v)
|
|
||||||
{
|
|
||||||
GLM_ALIGN(16) float result[4];
|
|
||||||
_mm_store_ps(result, v);
|
|
||||||
|
|
||||||
printf("__m128: %f %f %f %f\n", result[0], result[1], result[2], result[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print(const fvec4SIMD &v)
|
|
||||||
{
|
|
||||||
printf("fvec4SIMD: %f %f %f %f\n", v.x, v.y, v.z, v.w);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Implicit basic constructors
|
|
||||||
|
|
||||||
# if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD::fquatSIMD()
|
|
||||||
# ifdef GLM_FORCE_NO_CTOR_INIT
|
|
||||||
: Data(_mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f))
|
|
||||||
# endif
|
|
||||||
{}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if !GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD::fquatSIMD(fquatSIMD const & q) :
|
|
||||||
Data(q.Data)
|
|
||||||
{}
|
|
||||||
# endif//!GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD::fquatSIMD(__m128 const & Data) :
|
|
||||||
Data(Data)
|
|
||||||
{}
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Explicit basic constructors
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD::fquatSIMD(float const & w, float const & x, float const & y, float const & z) :
|
|
||||||
Data(_mm_set_ps(w, z, y, x))
|
|
||||||
{}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD::fquatSIMD(quat const & q) :
|
|
||||||
Data(_mm_set_ps(q.w, q.z, q.y, q.x))
|
|
||||||
{}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD::fquatSIMD(vec3 const & eulerAngles)
|
|
||||||
{
|
|
||||||
vec3 c = glm::cos(eulerAngles * 0.5f);
|
|
||||||
vec3 s = glm::sin(eulerAngles * 0.5f);
|
|
||||||
|
|
||||||
Data = _mm_set_ps(
|
|
||||||
(c.x * c.y * c.z) + (s.x * s.y * s.z),
|
|
||||||
(c.x * c.y * s.z) - (s.x * s.y * c.z),
|
|
||||||
(c.x * s.y * c.z) + (s.x * c.y * s.z),
|
|
||||||
(s.x * c.y * c.z) - (c.x * s.y * s.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Unary arithmetic operators
|
|
||||||
|
|
||||||
#if !GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD& fquatSIMD::operator=(fquatSIMD const & q)
|
|
||||||
{
|
|
||||||
this->Data = q.Data;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif//!GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD& fquatSIMD::operator*=(float const & s)
|
|
||||||
{
|
|
||||||
this->Data = _mm_mul_ps(this->Data, _mm_set_ps1(s));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD& fquatSIMD::operator/=(float const & s)
|
|
||||||
{
|
|
||||||
this->Data = _mm_div_ps(Data, _mm_set1_ps(s));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// negate operator
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD operator- (fquatSIMD const & q)
|
|
||||||
{
|
|
||||||
return fquatSIMD(_mm_mul_ps(q.Data, _mm_set_ps(-1.0f, -1.0f, -1.0f, -1.0f)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// operator+
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD operator+ (fquatSIMD const & q1, fquatSIMD const & q2)
|
|
||||||
{
|
|
||||||
return fquatSIMD(_mm_add_ps(q1.Data, q2.Data));
|
|
||||||
}
|
|
||||||
|
|
||||||
//operator*
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD operator* (fquatSIMD const & q1, fquatSIMD const & q2)
|
|
||||||
{
|
|
||||||
// SSE2 STATS:
|
|
||||||
// 11 shuffle
|
|
||||||
// 8 mul
|
|
||||||
// 8 add
|
|
||||||
|
|
||||||
// SSE4 STATS:
|
|
||||||
// 3 shuffle
|
|
||||||
// 4 mul
|
|
||||||
// 4 dpps
|
|
||||||
|
|
||||||
__m128 mul0 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(0, 1, 2, 3)));
|
|
||||||
__m128 mul1 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(1, 0, 3, 2)));
|
|
||||||
__m128 mul2 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(2, 3, 0, 1)));
|
|
||||||
__m128 mul3 = _mm_mul_ps(q1.Data, q2.Data);
|
|
||||||
|
|
||||||
# if(GLM_ARCH & GLM_ARCH_SSE41_BIT)
|
|
||||||
__m128 add0 = _mm_dp_ps(mul0, _mm_set_ps(1.0f, -1.0f, 1.0f, 1.0f), 0xff);
|
|
||||||
__m128 add1 = _mm_dp_ps(mul1, _mm_set_ps(1.0f, 1.0f, 1.0f, -1.0f), 0xff);
|
|
||||||
__m128 add2 = _mm_dp_ps(mul2, _mm_set_ps(1.0f, 1.0f, -1.0f, 1.0f), 0xff);
|
|
||||||
__m128 add3 = _mm_dp_ps(mul3, _mm_set_ps(1.0f, -1.0f, -1.0f, -1.0f), 0xff);
|
|
||||||
# else
|
|
||||||
mul0 = _mm_mul_ps(mul0, _mm_set_ps(1.0f, -1.0f, 1.0f, 1.0f));
|
|
||||||
__m128 add0 = _mm_add_ps(mul0, _mm_movehl_ps(mul0, mul0));
|
|
||||||
add0 = _mm_add_ss(add0, _mm_shuffle_ps(add0, add0, 1));
|
|
||||||
|
|
||||||
mul1 = _mm_mul_ps(mul1, _mm_set_ps(1.0f, 1.0f, 1.0f, -1.0f));
|
|
||||||
__m128 add1 = _mm_add_ps(mul1, _mm_movehl_ps(mul1, mul1));
|
|
||||||
add1 = _mm_add_ss(add1, _mm_shuffle_ps(add1, add1, 1));
|
|
||||||
|
|
||||||
mul2 = _mm_mul_ps(mul2, _mm_set_ps(1.0f, 1.0f, -1.0f, 1.0f));
|
|
||||||
__m128 add2 = _mm_add_ps(mul2, _mm_movehl_ps(mul2, mul2));
|
|
||||||
add2 = _mm_add_ss(add2, _mm_shuffle_ps(add2, add2, 1));
|
|
||||||
|
|
||||||
mul3 = _mm_mul_ps(mul3, _mm_set_ps(1.0f, -1.0f, -1.0f, -1.0f));
|
|
||||||
__m128 add3 = _mm_add_ps(mul3, _mm_movehl_ps(mul3, mul3));
|
|
||||||
add3 = _mm_add_ss(add3, _mm_shuffle_ps(add3, add3, 1));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// This SIMD code is a politically correct way of doing this, but in every test I've tried it has been slower than
|
|
||||||
// the final code below. I'll keep this here for reference - maybe somebody else can do something better...
|
|
||||||
//
|
|
||||||
//__m128 xxyy = _mm_shuffle_ps(add0, add1, _MM_SHUFFLE(0, 0, 0, 0));
|
|
||||||
//__m128 zzww = _mm_shuffle_ps(add2, add3, _MM_SHUFFLE(0, 0, 0, 0));
|
|
||||||
//
|
|
||||||
//return _mm_shuffle_ps(xxyy, zzww, _MM_SHUFFLE(2, 0, 2, 0));
|
|
||||||
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
float w;
|
|
||||||
|
|
||||||
_mm_store_ss(&x, add0);
|
|
||||||
_mm_store_ss(&y, add1);
|
|
||||||
_mm_store_ss(&z, add2);
|
|
||||||
_mm_store_ss(&w, add3);
|
|
||||||
|
|
||||||
return detail::fquatSIMD(w, x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator* (fquatSIMD const & q, fvec4SIMD const & v)
|
|
||||||
{
|
|
||||||
static const __m128 two = _mm_set1_ps(2.0f);
|
|
||||||
|
|
||||||
__m128 q_wwww = _mm_shuffle_ps(q.Data, q.Data, _MM_SHUFFLE(3, 3, 3, 3));
|
|
||||||
__m128 q_swp0 = _mm_shuffle_ps(q.Data, q.Data, _MM_SHUFFLE(3, 0, 2, 1));
|
|
||||||
__m128 q_swp1 = _mm_shuffle_ps(q.Data, q.Data, _MM_SHUFFLE(3, 1, 0, 2));
|
|
||||||
__m128 v_swp0 = _mm_shuffle_ps(v.Data, v.Data, _MM_SHUFFLE(3, 0, 2, 1));
|
|
||||||
__m128 v_swp1 = _mm_shuffle_ps(v.Data, v.Data, _MM_SHUFFLE(3, 1, 0, 2));
|
|
||||||
|
|
||||||
__m128 uv = _mm_sub_ps(_mm_mul_ps(q_swp0, v_swp1), _mm_mul_ps(q_swp1, v_swp0));
|
|
||||||
__m128 uv_swp0 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 0, 2, 1));
|
|
||||||
__m128 uv_swp1 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 1, 0, 2));
|
|
||||||
__m128 uuv = _mm_sub_ps(_mm_mul_ps(q_swp0, uv_swp1), _mm_mul_ps(q_swp1, uv_swp0));
|
|
||||||
|
|
||||||
|
|
||||||
uv = _mm_mul_ps(uv, _mm_mul_ps(q_wwww, two));
|
|
||||||
uuv = _mm_mul_ps(uuv, two);
|
|
||||||
|
|
||||||
return _mm_add_ps(v.Data, _mm_add_ps(uv, uuv));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator* (fvec4SIMD const & v, fquatSIMD const & q)
|
|
||||||
{
|
|
||||||
return glm::inverse(q) * v;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD operator* (fquatSIMD const & q, float s)
|
|
||||||
{
|
|
||||||
return fquatSIMD(_mm_mul_ps(q.Data, _mm_set1_ps(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD operator* (float s, fquatSIMD const & q)
|
|
||||||
{
|
|
||||||
return fquatSIMD(_mm_mul_ps(_mm_set1_ps(s), q.Data));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//operator/
|
|
||||||
GLM_FUNC_QUALIFIER fquatSIMD operator/ (fquatSIMD const & q, float s)
|
|
||||||
{
|
|
||||||
return fquatSIMD(_mm_div_ps(q.Data, _mm_set1_ps(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}//namespace detail
|
|
||||||
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER quat quat_cast
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GLM_ALIGN(16) quat Result;
|
|
||||||
_mm_store_ps(&Result[0], x.Data);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD quatSIMD_cast_impl(const T m0[], const T m1[], const T m2[])
|
|
||||||
{
|
|
||||||
T trace = m0[0] + m1[1] + m2[2] + T(1.0);
|
|
||||||
if (trace > T(0))
|
|
||||||
{
|
|
||||||
T s = static_cast<T>(0.5) / sqrt(trace);
|
|
||||||
|
|
||||||
return _mm_set_ps(
|
|
||||||
static_cast<float>(T(0.25) / s),
|
|
||||||
static_cast<float>((m0[1] - m1[0]) * s),
|
|
||||||
static_cast<float>((m2[0] - m0[2]) * s),
|
|
||||||
static_cast<float>((m1[2] - m2[1]) * s));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m0[0] > m1[1])
|
|
||||||
{
|
|
||||||
if (m0[0] > m2[2])
|
|
||||||
{
|
|
||||||
// X is biggest.
|
|
||||||
T s = sqrt(m0[0] - m1[1] - m2[2] + T(1.0)) * T(0.5);
|
|
||||||
|
|
||||||
return _mm_set_ps(
|
|
||||||
static_cast<float>((m1[2] - m2[1]) * s),
|
|
||||||
static_cast<float>((m2[0] + m0[2]) * s),
|
|
||||||
static_cast<float>((m0[1] + m1[0]) * s),
|
|
||||||
static_cast<float>(T(0.5) * s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m1[1] > m2[2])
|
|
||||||
{
|
|
||||||
// Y is biggest.
|
|
||||||
T s = sqrt(m1[1] - m0[0] - m2[2] + T(1.0)) * T(0.5);
|
|
||||||
|
|
||||||
return _mm_set_ps(
|
|
||||||
static_cast<float>((m2[0] - m0[2]) * s),
|
|
||||||
static_cast<float>((m1[2] + m2[1]) * s),
|
|
||||||
static_cast<float>(T(0.5) * s),
|
|
||||||
static_cast<float>((m0[1] + m1[0]) * s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Z is biggest.
|
|
||||||
T s = sqrt(m2[2] - m0[0] - m1[1] + T(1.0)) * T(0.5);
|
|
||||||
|
|
||||||
return _mm_set_ps(
|
|
||||||
static_cast<float>((m0[1] - m1[0]) * s),
|
|
||||||
static_cast<float>(T(0.5) * s),
|
|
||||||
static_cast<float>((m1[2] + m2[1]) * s),
|
|
||||||
static_cast<float>((m2[0] + m0[2]) * s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD quatSIMD_cast
|
|
||||||
(
|
|
||||||
detail::fmat4x4SIMD const & m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Scalar implementation for now.
|
|
||||||
GLM_ALIGN(16) float m0[4];
|
|
||||||
GLM_ALIGN(16) float m1[4];
|
|
||||||
GLM_ALIGN(16) float m2[4];
|
|
||||||
|
|
||||||
_mm_store_ps(m0, m[0].Data);
|
|
||||||
_mm_store_ps(m1, m[1].Data);
|
|
||||||
_mm_store_ps(m2, m[2].Data);
|
|
||||||
|
|
||||||
return quatSIMD_cast_impl(m0, m1, m2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, precision P>
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD quatSIMD_cast
|
|
||||||
(
|
|
||||||
tmat4x4<T, P> const & m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return quatSIMD_cast_impl(&m[0][0], &m[1][0], &m[2][0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, precision P>
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD quatSIMD_cast
|
|
||||||
(
|
|
||||||
tmat3x3<T, P> const & m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return quatSIMD_cast_impl(&m[0][0], &m[1][0], &m[2][0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fmat4x4SIMD mat4SIMD_cast
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & q
|
|
||||||
)
|
|
||||||
{
|
|
||||||
detail::fmat4x4SIMD result;
|
|
||||||
|
|
||||||
__m128 _wwww = _mm_shuffle_ps(q.Data, q.Data, _MM_SHUFFLE(3, 3, 3, 3));
|
|
||||||
__m128 _xyzw = q.Data;
|
|
||||||
__m128 _zxyw = _mm_shuffle_ps(q.Data, q.Data, _MM_SHUFFLE(3, 1, 0, 2));
|
|
||||||
__m128 _yzxw = _mm_shuffle_ps(q.Data, q.Data, _MM_SHUFFLE(3, 0, 2, 1));
|
|
||||||
|
|
||||||
__m128 _xyzw2 = _mm_add_ps(_xyzw, _xyzw);
|
|
||||||
__m128 _zxyw2 = _mm_shuffle_ps(_xyzw2, _xyzw2, _MM_SHUFFLE(3, 1, 0, 2));
|
|
||||||
__m128 _yzxw2 = _mm_shuffle_ps(_xyzw2, _xyzw2, _MM_SHUFFLE(3, 0, 2, 1));
|
|
||||||
|
|
||||||
__m128 _tmp0 = _mm_sub_ps(_mm_set1_ps(1.0f), _mm_mul_ps(_yzxw2, _yzxw));
|
|
||||||
_tmp0 = _mm_sub_ps(_tmp0, _mm_mul_ps(_zxyw2, _zxyw));
|
|
||||||
|
|
||||||
__m128 _tmp1 = _mm_mul_ps(_yzxw2, _xyzw);
|
|
||||||
_tmp1 = _mm_add_ps(_tmp1, _mm_mul_ps(_zxyw2, _wwww));
|
|
||||||
|
|
||||||
__m128 _tmp2 = _mm_mul_ps(_zxyw2, _xyzw);
|
|
||||||
_tmp2 = _mm_sub_ps(_tmp2, _mm_mul_ps(_yzxw2, _wwww));
|
|
||||||
|
|
||||||
|
|
||||||
// There's probably a better, more politically correct way of doing this...
|
|
||||||
result[0].Data = _mm_set_ps(
|
|
||||||
0.0f,
|
|
||||||
reinterpret_cast<float*>(&_tmp2)[0],
|
|
||||||
reinterpret_cast<float*>(&_tmp1)[0],
|
|
||||||
reinterpret_cast<float*>(&_tmp0)[0]);
|
|
||||||
|
|
||||||
result[1].Data = _mm_set_ps(
|
|
||||||
0.0f,
|
|
||||||
reinterpret_cast<float*>(&_tmp1)[1],
|
|
||||||
reinterpret_cast<float*>(&_tmp0)[1],
|
|
||||||
reinterpret_cast<float*>(&_tmp2)[1]);
|
|
||||||
|
|
||||||
result[2].Data = _mm_set_ps(
|
|
||||||
0.0f,
|
|
||||||
reinterpret_cast<float*>(&_tmp0)[2],
|
|
||||||
reinterpret_cast<float*>(&_tmp2)[2],
|
|
||||||
reinterpret_cast<float*>(&_tmp1)[2]);
|
|
||||||
|
|
||||||
result[3].Data = _mm_set_ps(
|
|
||||||
1.0f,
|
|
||||||
0.0f,
|
|
||||||
0.0f,
|
|
||||||
0.0f);
|
|
||||||
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER mat4 mat4_cast
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & q
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return mat4_cast(mat4SIMD_cast(q));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER float length
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & q
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return glm::sqrt(dot(q, q));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD normalize
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & q
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _mm_mul_ps(q.Data, _mm_set1_ps(1.0f / length(q)));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER float dot
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & q1,
|
|
||||||
detail::fquatSIMD const & q2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
float result;
|
|
||||||
_mm_store_ss(&result, detail::sse_dot_ps(q1.Data, q2.Data));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD mix
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & x,
|
|
||||||
detail::fquatSIMD const & y,
|
|
||||||
float const & a
|
|
||||||
)
|
|
||||||
{
|
|
||||||
float cosTheta = dot(x, y);
|
|
||||||
|
|
||||||
if (cosTheta > 1.0f - glm::epsilon<float>())
|
|
||||||
{
|
|
||||||
return _mm_add_ps(x.Data, _mm_mul_ps(_mm_set1_ps(a), _mm_sub_ps(y.Data, x.Data)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float angle = glm::acos(cosTheta);
|
|
||||||
|
|
||||||
|
|
||||||
float s0 = glm::sin((1.0f - a) * angle);
|
|
||||||
float s1 = glm::sin(a * angle);
|
|
||||||
float d = 1.0f / glm::sin(angle);
|
|
||||||
|
|
||||||
return (s0 * x + s1 * y) * d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD lerp
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & x,
|
|
||||||
detail::fquatSIMD const & y,
|
|
||||||
float const & a
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Lerp is only defined in [0, 1]
|
|
||||||
assert(a >= 0.0f);
|
|
||||||
assert(a <= 1.0f);
|
|
||||||
|
|
||||||
return _mm_add_ps(x.Data, _mm_mul_ps(_mm_set1_ps(a), _mm_sub_ps(y.Data, x.Data)));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD slerp
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & x,
|
|
||||||
detail::fquatSIMD const & y,
|
|
||||||
float const & a
|
|
||||||
)
|
|
||||||
{
|
|
||||||
detail::fquatSIMD z = y;
|
|
||||||
|
|
||||||
float cosTheta = dot(x, y);
|
|
||||||
|
|
||||||
// If cosTheta < 0, the interpolation will take the long way around the sphere.
|
|
||||||
// To fix this, one quat must be negated.
|
|
||||||
if (cosTheta < 0.0f)
|
|
||||||
{
|
|
||||||
z = -y;
|
|
||||||
cosTheta = -cosTheta;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator
|
|
||||||
if(cosTheta > 1.0f - epsilon<float>())
|
|
||||||
{
|
|
||||||
return _mm_add_ps(x.Data, _mm_mul_ps(_mm_set1_ps(a), _mm_sub_ps(y.Data, x.Data)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float angle = glm::acos(cosTheta);
|
|
||||||
|
|
||||||
|
|
||||||
float s0 = glm::sin((1.0f - a) * angle);
|
|
||||||
float s1 = glm::sin(a * angle);
|
|
||||||
float d = 1.0f / glm::sin(angle);
|
|
||||||
|
|
||||||
return (s0 * x + s1 * y) * d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD fastMix
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & x,
|
|
||||||
detail::fquatSIMD const & y,
|
|
||||||
float const & a
|
|
||||||
)
|
|
||||||
{
|
|
||||||
float cosTheta = dot(x, y);
|
|
||||||
|
|
||||||
if (cosTheta > 1.0f - glm::epsilon<float>())
|
|
||||||
{
|
|
||||||
return _mm_add_ps(x.Data, _mm_mul_ps(_mm_set1_ps(a), _mm_sub_ps(y.Data, x.Data)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float angle = glm::fastAcos(cosTheta);
|
|
||||||
|
|
||||||
|
|
||||||
__m128 s = glm::fastSin(_mm_set_ps((1.0f - a) * angle, a * angle, angle, 0.0f));
|
|
||||||
|
|
||||||
__m128 s0 = _mm_shuffle_ps(s, s, _MM_SHUFFLE(3, 3, 3, 3));
|
|
||||||
__m128 s1 = _mm_shuffle_ps(s, s, _MM_SHUFFLE(2, 2, 2, 2));
|
|
||||||
__m128 d = _mm_div_ps(_mm_set1_ps(1.0f), _mm_shuffle_ps(s, s, _MM_SHUFFLE(1, 1, 1, 1)));
|
|
||||||
|
|
||||||
return _mm_mul_ps(_mm_add_ps(_mm_mul_ps(s0, x.Data), _mm_mul_ps(s1, y.Data)), d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD fastSlerp
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & x,
|
|
||||||
detail::fquatSIMD const & y,
|
|
||||||
float const & a
|
|
||||||
)
|
|
||||||
{
|
|
||||||
detail::fquatSIMD z = y;
|
|
||||||
|
|
||||||
float cosTheta = dot(x, y);
|
|
||||||
if (cosTheta < 0.0f)
|
|
||||||
{
|
|
||||||
z = -y;
|
|
||||||
cosTheta = -cosTheta;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(cosTheta > 1.0f - epsilon<float>())
|
|
||||||
{
|
|
||||||
return _mm_add_ps(x.Data, _mm_mul_ps(_mm_set1_ps(a), _mm_sub_ps(y.Data, x.Data)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float angle = glm::fastAcos(cosTheta);
|
|
||||||
|
|
||||||
|
|
||||||
__m128 s = glm::fastSin(_mm_set_ps((1.0f - a) * angle, a * angle, angle, 0.0f));
|
|
||||||
|
|
||||||
__m128 s0 = _mm_shuffle_ps(s, s, _MM_SHUFFLE(3, 3, 3, 3));
|
|
||||||
__m128 s1 = _mm_shuffle_ps(s, s, _MM_SHUFFLE(2, 2, 2, 2));
|
|
||||||
__m128 d = _mm_div_ps(_mm_set1_ps(1.0f), _mm_shuffle_ps(s, s, _MM_SHUFFLE(1, 1, 1, 1)));
|
|
||||||
|
|
||||||
return _mm_mul_ps(_mm_add_ps(_mm_mul_ps(s0, x.Data), _mm_mul_ps(s1, y.Data)), d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD conjugate
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & q
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::fquatSIMD(_mm_mul_ps(q.Data, _mm_set_ps(1.0f, -1.0f, -1.0f, -1.0f)));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD inverse
|
|
||||||
(
|
|
||||||
detail::fquatSIMD const & q
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return conjugate(q) / dot(q, q);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD angleAxisSIMD
|
|
||||||
(
|
|
||||||
float const & angle,
|
|
||||||
vec3 const & v
|
|
||||||
)
|
|
||||||
{
|
|
||||||
float s = glm::sin(angle * 0.5f);
|
|
||||||
|
|
||||||
return _mm_set_ps(
|
|
||||||
glm::cos(angle * 0.5f),
|
|
||||||
v.z * s,
|
|
||||||
v.y * s,
|
|
||||||
v.x * s);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fquatSIMD angleAxisSIMD
|
|
||||||
(
|
|
||||||
float const & angle,
|
|
||||||
float const & x,
|
|
||||||
float const & y,
|
|
||||||
float const & z
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return angleAxisSIMD(angle, vec3(x, y, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER __m128 fastSin(__m128 x)
|
|
||||||
{
|
|
||||||
static const __m128 c0 = _mm_set1_ps(0.16666666666666666666666666666667f);
|
|
||||||
static const __m128 c1 = _mm_set1_ps(0.00833333333333333333333333333333f);
|
|
||||||
static const __m128 c2 = _mm_set1_ps(0.00019841269841269841269841269841f);
|
|
||||||
|
|
||||||
__m128 x3 = _mm_mul_ps(x, _mm_mul_ps(x, x));
|
|
||||||
__m128 x5 = _mm_mul_ps(x3, _mm_mul_ps(x, x));
|
|
||||||
__m128 x7 = _mm_mul_ps(x5, _mm_mul_ps(x, x));
|
|
||||||
|
|
||||||
__m128 y0 = _mm_mul_ps(x3, c0);
|
|
||||||
__m128 y1 = _mm_mul_ps(x5, c1);
|
|
||||||
__m128 y2 = _mm_mul_ps(x7, c2);
|
|
||||||
|
|
||||||
return _mm_sub_ps(_mm_add_ps(_mm_sub_ps(x, y0), y1), y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}//namespace glm
|
|
@ -1,546 +0,0 @@
|
|||||||
/// @ref gtx_simd_vec4
|
|
||||||
/// @file glm/gtx/simd_vec4.hpp
|
|
||||||
///
|
|
||||||
/// @see core (dependence)
|
|
||||||
///
|
|
||||||
/// @defgroup gtx_simd_vec4 GLM_GTX_simd_vec4
|
|
||||||
/// @ingroup gtx
|
|
||||||
///
|
|
||||||
/// @brief SIMD implementation of vec4 type.
|
|
||||||
///
|
|
||||||
/// <glm/gtx/simd_vec4.hpp> need to be included to use these functionalities.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// Dependency:
|
|
||||||
#include "../glm.hpp"
|
|
||||||
|
|
||||||
#if(GLM_ARCH != GLM_ARCH_PURE)
|
|
||||||
|
|
||||||
#if(GLM_ARCH & GLM_ARCH_SSE2_BIT)
|
|
||||||
# include "../detail/intrinsic_common.hpp"
|
|
||||||
# include "../detail/intrinsic_geometric.hpp"
|
|
||||||
# include "../detail/intrinsic_integer.hpp"
|
|
||||||
#else
|
|
||||||
# error "GLM: GLM_GTX_simd_vec4 requires compiler support of SSE2 through intrinsics"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_EXT_INCLUDED)
|
|
||||||
# pragma message("GLM: GLM_GTX_simd_vec4 extension included")
|
|
||||||
# pragma message("GLM: GLM_GTX_simd_vec4 extension is deprecated and will be removed in GLM 0.9.9. Use *vec4 types instead and use compiler SIMD arguments.")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Warning silencer for nameless struct/union.
|
|
||||||
#if (GLM_COMPILER & GLM_COMPILER_VC)
|
|
||||||
# pragma warning(push)
|
|
||||||
# pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace glm
|
|
||||||
{
|
|
||||||
enum comp
|
|
||||||
{
|
|
||||||
X = 0,
|
|
||||||
R = 0,
|
|
||||||
S = 0,
|
|
||||||
Y = 1,
|
|
||||||
G = 1,
|
|
||||||
T = 1,
|
|
||||||
Z = 2,
|
|
||||||
B = 2,
|
|
||||||
P = 2,
|
|
||||||
W = 3,
|
|
||||||
A = 3,
|
|
||||||
Q = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
}//namespace glm
|
|
||||||
|
|
||||||
namespace glm{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
/// 4-dimensional vector implemented using SIMD SEE intrinsics.
|
|
||||||
/// \ingroup gtx_simd_vec4
|
|
||||||
GLM_ALIGNED_STRUCT(16) fvec4SIMD
|
|
||||||
{
|
|
||||||
typedef float value_type;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
|
|
||||||
typedef fvec4SIMD type;
|
|
||||||
typedef tvec4<float, defaultp> pure_type;
|
|
||||||
typedef tvec4<bool, highp> bool_type;
|
|
||||||
|
|
||||||
#ifdef GLM_SIMD_ENABLE_XYZW_UNION
|
|
||||||
union
|
|
||||||
{
|
|
||||||
__m128 Data;
|
|
||||||
struct {float x, y, z, w;};
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
__m128 Data;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Implicit basic constructors
|
|
||||||
|
|
||||||
fvec4SIMD() GLM_DEFAULT_CTOR;
|
|
||||||
fvec4SIMD(fvec4SIMD const & v) GLM_DEFAULT;
|
|
||||||
fvec4SIMD(__m128 const & Data);
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Explicit basic constructors
|
|
||||||
|
|
||||||
explicit fvec4SIMD(
|
|
||||||
ctor);
|
|
||||||
explicit fvec4SIMD(
|
|
||||||
float const & s);
|
|
||||||
explicit fvec4SIMD(
|
|
||||||
float const & x,
|
|
||||||
float const & y,
|
|
||||||
float const & z,
|
|
||||||
float const & w);
|
|
||||||
explicit fvec4SIMD(
|
|
||||||
vec4 const & v);
|
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
//// Conversion vector constructors
|
|
||||||
|
|
||||||
fvec4SIMD(vec2 const & v, float const & s1, float const & s2);
|
|
||||||
fvec4SIMD(float const & s1, vec2 const & v, float const & s2);
|
|
||||||
fvec4SIMD(float const & s1, float const & s2, vec2 const & v);
|
|
||||||
fvec4SIMD(vec3 const & v, float const & s);
|
|
||||||
fvec4SIMD(float const & s, vec3 const & v);
|
|
||||||
fvec4SIMD(vec2 const & v1, vec2 const & v2);
|
|
||||||
//fvec4SIMD(ivec4SIMD const & v);
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Unary arithmetic operators
|
|
||||||
|
|
||||||
fvec4SIMD& operator= (fvec4SIMD const & v) GLM_DEFAULT;
|
|
||||||
fvec4SIMD& operator+=(fvec4SIMD const & v);
|
|
||||||
fvec4SIMD& operator-=(fvec4SIMD const & v);
|
|
||||||
fvec4SIMD& operator*=(fvec4SIMD const & v);
|
|
||||||
fvec4SIMD& operator/=(fvec4SIMD const & v);
|
|
||||||
|
|
||||||
fvec4SIMD& operator+=(float const & s);
|
|
||||||
fvec4SIMD& operator-=(float const & s);
|
|
||||||
fvec4SIMD& operator*=(float const & s);
|
|
||||||
fvec4SIMD& operator/=(float const & s);
|
|
||||||
|
|
||||||
fvec4SIMD& operator++();
|
|
||||||
fvec4SIMD& operator--();
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Swizzle operators
|
|
||||||
|
|
||||||
template <comp X_, comp Y_, comp Z_, comp W_>
|
|
||||||
fvec4SIMD& swizzle();
|
|
||||||
template <comp X_, comp Y_, comp Z_, comp W_>
|
|
||||||
fvec4SIMD swizzle() const;
|
|
||||||
template <comp X_, comp Y_, comp Z_>
|
|
||||||
fvec4SIMD swizzle() const;
|
|
||||||
template <comp X_, comp Y_>
|
|
||||||
fvec4SIMD swizzle() const;
|
|
||||||
template <comp X_>
|
|
||||||
fvec4SIMD swizzle() const;
|
|
||||||
};
|
|
||||||
}//namespace detail
|
|
||||||
|
|
||||||
typedef glm::detail::fvec4SIMD simdVec4;
|
|
||||||
|
|
||||||
/// @addtogroup gtx_simd_vec4
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
//! Convert a simdVec4 to a vec4.
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
vec4 vec4_cast(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns x if x >= 0; otherwise, it returns -x.
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD abs(detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns 1.0 if x > 0, 0.0 if x = 0, or -1.0 if x < 0.
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD sign(detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns a value equal to the nearest integer that is less then or equal to x.
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD floor(detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns a value equal to the nearest integer to x
|
|
||||||
//! whose absolute value is not larger than the absolute value of x.
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD trunc(detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns a value equal to the nearest integer to x.
|
|
||||||
//! The fraction 0.5 will round in a direction chosen by the
|
|
||||||
//! implementation, presumably the direction that is fastest.
|
|
||||||
//! This includes the possibility that round(x) returns the
|
|
||||||
//! same value as roundEven(x) for all values of x.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD round(detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns a value equal to the nearest integer to x.
|
|
||||||
//! A fractional part of 0.5 will round toward the nearest even
|
|
||||||
//! integer. (Both 3.5 and 4.5 for x will return 4.0.)
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
//detail::fvec4SIMD roundEven(detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns a value equal to the nearest integer
|
|
||||||
//! that is greater than or equal to x.
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD ceil(detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Return x - floor(x).
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD fract(detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Modulus. Returns x - y * floor(x / y)
|
|
||||||
//! for each component in x using the floating point value y.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD mod(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y);
|
|
||||||
|
|
||||||
//! Modulus. Returns x - y * floor(x / y)
|
|
||||||
//! for each component in x using the floating point value y.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD mod(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
float const & y);
|
|
||||||
|
|
||||||
//! Returns the fractional part of x and sets i to the integer
|
|
||||||
//! part (as a whole number floating point value). Both the
|
|
||||||
//! return value and the output parameter will have the same
|
|
||||||
//! sign as x.
|
|
||||||
//! (From GLM_GTX_simd_vec4 extension, common function)
|
|
||||||
//detail::fvec4SIMD modf(
|
|
||||||
// detail::fvec4SIMD const & x,
|
|
||||||
// detail::fvec4SIMD & i);
|
|
||||||
|
|
||||||
//! Returns y if y < x; otherwise, it returns x.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD min(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y);
|
|
||||||
|
|
||||||
detail::fvec4SIMD min(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
float const & y);
|
|
||||||
|
|
||||||
//! Returns y if x < y; otherwise, it returns x.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD max(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y);
|
|
||||||
|
|
||||||
detail::fvec4SIMD max(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
float const & y);
|
|
||||||
|
|
||||||
//! Returns min(max(x, minVal), maxVal) for each component in x
|
|
||||||
//! using the floating-point values minVal and maxVal.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD clamp(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & minVal,
|
|
||||||
detail::fvec4SIMD const & maxVal);
|
|
||||||
|
|
||||||
detail::fvec4SIMD clamp(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
float const & minVal,
|
|
||||||
float const & maxVal);
|
|
||||||
|
|
||||||
//! \return If genTypeU is a floating scalar or vector:
|
|
||||||
//! Returns x * (1.0 - a) + y * a, i.e., the linear blend of
|
|
||||||
//! x and y using the floating-point value a.
|
|
||||||
//! The value for a is not restricted to the range [0, 1].
|
|
||||||
//!
|
|
||||||
//! \return If genTypeU is a boolean scalar or vector:
|
|
||||||
//! Selects which vector each returned component comes
|
|
||||||
//! from. For a component of a that is false, the
|
|
||||||
//! corresponding component of x is returned. For a
|
|
||||||
//! component of a that is true, the corresponding
|
|
||||||
//! component of y is returned. Components of x and y that
|
|
||||||
//! are not selected are allowed to be invalid floating point
|
|
||||||
//! values and will have no effect on the results. Thus, this
|
|
||||||
//! provides different functionality than
|
|
||||||
//! genType mix(genType x, genType y, genType(a))
|
|
||||||
//! where a is a Boolean vector.
|
|
||||||
//!
|
|
||||||
//! From GLSL 1.30.08 specification, section 8.3
|
|
||||||
//!
|
|
||||||
//! \param[in] x Floating point scalar or vector.
|
|
||||||
//! \param[in] y Floating point scalar or vector.
|
|
||||||
//! \param[in] a Floating point or boolean scalar or vector.
|
|
||||||
//!
|
|
||||||
/// \todo Test when 'a' is a boolean.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD mix(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y,
|
|
||||||
detail::fvec4SIMD const & a);
|
|
||||||
|
|
||||||
//! Returns 0.0 if x < edge, otherwise it returns 1.0.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD step(
|
|
||||||
detail::fvec4SIMD const & edge,
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
detail::fvec4SIMD step(
|
|
||||||
float const & edge,
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
|
|
||||||
//! performs smooth Hermite interpolation between 0 and 1
|
|
||||||
//! when edge0 < x < edge1. This is useful in cases where
|
|
||||||
//! you would want a threshold function with a smooth
|
|
||||||
//! transition. This is equivalent to:
|
|
||||||
//! genType t;
|
|
||||||
//! t = clamp ((x - edge0) / (edge1 - edge0), 0, 1);
|
|
||||||
//! return t * t * (3 - 2 * t);
|
|
||||||
//! Results are undefined if edge0 >= edge1.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD smoothstep(
|
|
||||||
detail::fvec4SIMD const & edge0,
|
|
||||||
detail::fvec4SIMD const & edge1,
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
detail::fvec4SIMD smoothstep(
|
|
||||||
float const & edge0,
|
|
||||||
float const & edge1,
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns true if x holds a NaN (not a number)
|
|
||||||
//! representation in the underlying implementation's set of
|
|
||||||
//! floating point representations. Returns false otherwise,
|
|
||||||
//! including for implementations with no NaN
|
|
||||||
//! representations.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
//bvec4 isnan(detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns true if x holds a positive infinity or negative
|
|
||||||
//! infinity representation in the underlying implementation's
|
|
||||||
//! set of floating point representations. Returns false
|
|
||||||
//! otherwise, including for implementations with no infinity
|
|
||||||
//! representations.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
//bvec4 isinf(detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns a signed or unsigned integer value representing
|
|
||||||
//! the encoding of a floating-point value. The floatingpoint
|
|
||||||
//! value's bit-level representation is preserved.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
//detail::ivec4SIMD floatBitsToInt(detail::fvec4SIMD const & value);
|
|
||||||
|
|
||||||
//! Returns a floating-point value corresponding to a signed
|
|
||||||
//! or unsigned integer encoding of a floating-point value.
|
|
||||||
//! If an inf or NaN is passed in, it will not signal, and the
|
|
||||||
//! resulting floating point value is unspecified. Otherwise,
|
|
||||||
//! the bit-level representation is preserved.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
//detail::fvec4SIMD intBitsToFloat(detail::ivec4SIMD const & value);
|
|
||||||
|
|
||||||
//! Computes and returns a * b + c.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD fma(
|
|
||||||
detail::fvec4SIMD const & a,
|
|
||||||
detail::fvec4SIMD const & b,
|
|
||||||
detail::fvec4SIMD const & c);
|
|
||||||
|
|
||||||
//! Splits x into a floating-point significand in the range
|
|
||||||
//! [0.5, 1.0) and an integral exponent of two, such that:
|
|
||||||
//! x = significand * exp(2, exponent)
|
|
||||||
//! The significand is returned by the function and the
|
|
||||||
//! exponent is returned in the parameter exp. For a
|
|
||||||
//! floating-point value of zero, the significant and exponent
|
|
||||||
//! are both zero. For a floating-point value that is an
|
|
||||||
//! infinity or is not a number, the results are undefined.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
//detail::fvec4SIMD frexp(detail::fvec4SIMD const & x, detail::ivec4SIMD & exp);
|
|
||||||
|
|
||||||
//! Builds a floating-point number from x and the
|
|
||||||
//! corresponding integral exponent of two in exp, returning:
|
|
||||||
//! significand * exp(2, exponent)
|
|
||||||
//! If this product is too large to be represented in the
|
|
||||||
//! floating-point type, the result is undefined.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
//detail::fvec4SIMD ldexp(detail::fvec4SIMD const & x, detail::ivec4SIMD const & exp);
|
|
||||||
|
|
||||||
//! Returns the length of x, i.e., sqrt(x * x).
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
float length(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns the length of x, i.e., sqrt(x * x).
|
|
||||||
//! Less accurate but much faster than simdLength.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
float fastLength(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns the length of x, i.e., sqrt(x * x).
|
|
||||||
//! Slightly more accurate but much slower than simdLength.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
float niceLength(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns the length of x, i.e., sqrt(x * x).
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD length4(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns the length of x, i.e., sqrt(x * x).
|
|
||||||
//! Less accurate but much faster than simdLength4.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD fastLength4(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns the length of x, i.e., sqrt(x * x).
|
|
||||||
//! Slightly more accurate but much slower than simdLength4.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD niceLength4(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
float distance(
|
|
||||||
detail::fvec4SIMD const & p0,
|
|
||||||
detail::fvec4SIMD const & p1);
|
|
||||||
|
|
||||||
//! Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD distance4(
|
|
||||||
detail::fvec4SIMD const & p0,
|
|
||||||
detail::fvec4SIMD const & p1);
|
|
||||||
|
|
||||||
//! Returns the dot product of x and y, i.e., result = x * y.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
float simdDot(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y);
|
|
||||||
|
|
||||||
//! Returns the dot product of x and y, i.e., result = x * y.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD dot4(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y);
|
|
||||||
|
|
||||||
//! Returns the cross product of x and y.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD cross(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y);
|
|
||||||
|
|
||||||
//! Returns a vector in the same direction as x but with length of 1.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD normalize(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns a vector in the same direction as x but with length of 1.
|
|
||||||
//! Less accurate but much faster than simdNormalize.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD fastNormalize(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! If dot(Nref, I) < 0.0, return N, otherwise, return -N.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD simdFaceforward(
|
|
||||||
detail::fvec4SIMD const & N,
|
|
||||||
detail::fvec4SIMD const & I,
|
|
||||||
detail::fvec4SIMD const & Nref);
|
|
||||||
|
|
||||||
//! For the incident vector I and surface orientation N,
|
|
||||||
//! returns the reflection direction : result = I - 2.0 * dot(N, I) * N.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD reflect(
|
|
||||||
detail::fvec4SIMD const & I,
|
|
||||||
detail::fvec4SIMD const & N);
|
|
||||||
|
|
||||||
//! For the incident vector I and surface normal N,
|
|
||||||
//! and the ratio of indices of refraction eta,
|
|
||||||
//! return the refraction vector.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD refract(
|
|
||||||
detail::fvec4SIMD const & I,
|
|
||||||
detail::fvec4SIMD const & N,
|
|
||||||
float const & eta);
|
|
||||||
|
|
||||||
//! Returns the positive square root of x.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD sqrt(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns the positive square root of x with the nicest quality but very slow.
|
|
||||||
//! Slightly more accurate but much slower than simdSqrt.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD niceSqrt(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns the positive square root of x
|
|
||||||
//! Less accurate but much faster than sqrt.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD fastSqrt(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns the reciprocal of the positive square root of x.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD inversesqrt(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
//! Returns the reciprocal of the positive square root of x.
|
|
||||||
//! Faster than inversesqrt but less accurate.
|
|
||||||
///
|
|
||||||
/// @see gtx_simd_vec4
|
|
||||||
detail::fvec4SIMD fastInversesqrt(
|
|
||||||
detail::fvec4SIMD const & x);
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
}//namespace glm
|
|
||||||
|
|
||||||
#include "simd_vec4.inl"
|
|
||||||
|
|
||||||
#if (GLM_COMPILER & GLM_COMPILER_VC)
|
|
||||||
# pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif//(GLM_ARCH != GLM_ARCH_PURE)
|
|
@ -1,721 +0,0 @@
|
|||||||
/// @ref gtx_simd_vec4
|
|
||||||
/// @file glm/gtx/simd_vec4.inl
|
|
||||||
|
|
||||||
namespace glm{
|
|
||||||
namespace detail{
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Implicit basic constructors
|
|
||||||
|
|
||||||
#if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD()
|
|
||||||
# ifdef GLM_FORCE_NO_CTOR_INIT
|
|
||||||
: Data(_mm_set_ps(0.0f, 0.0f, 0.0f, 0.0f))
|
|
||||||
# endif
|
|
||||||
{}
|
|
||||||
#endif//!GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
|
|
||||||
#if !GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(fvec4SIMD const & v) :
|
|
||||||
Data(v.Data)
|
|
||||||
{}
|
|
||||||
#endif//!GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(__m128 const & Data) :
|
|
||||||
Data(Data)
|
|
||||||
{}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(vec4 const & v) :
|
|
||||||
Data(_mm_set_ps(v.w, v.z, v.y, v.x))
|
|
||||||
{}
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Explicit basic constructors
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const & s) :
|
|
||||||
Data(_mm_set1_ps(s))
|
|
||||||
{}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const & x, float const & y, float const & z, float const & w) :
|
|
||||||
// Data(_mm_setr_ps(x, y, z, w))
|
|
||||||
Data(_mm_set_ps(w, z, y, x))
|
|
||||||
{}
|
|
||||||
/*
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const v[4]) :
|
|
||||||
Data(_mm_load_ps(v))
|
|
||||||
{}
|
|
||||||
*/
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Swizzle constructors
|
|
||||||
|
|
||||||
//fvec4SIMD(ref4<float> const & r);
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Conversion vector constructors
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(vec2 const & v, float const & s1, float const & s2) :
|
|
||||||
Data(_mm_set_ps(s2, s1, v.y, v.x))
|
|
||||||
{}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const & s1, vec2 const & v, float const & s2) :
|
|
||||||
Data(_mm_set_ps(s2, v.y, v.x, s1))
|
|
||||||
{}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const & s1, float const & s2, vec2 const & v) :
|
|
||||||
Data(_mm_set_ps(v.y, v.x, s2, s1))
|
|
||||||
{}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(vec3 const & v, float const & s) :
|
|
||||||
Data(_mm_set_ps(s, v.z, v.y, v.x))
|
|
||||||
{}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(float const & s, vec3 const & v) :
|
|
||||||
Data(_mm_set_ps(v.z, v.y, v.x, s))
|
|
||||||
{}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(vec2 const & v1, vec2 const & v2) :
|
|
||||||
Data(_mm_set_ps(v2.y, v2.x, v1.y, v1.x))
|
|
||||||
{}
|
|
||||||
|
|
||||||
//GLM_FUNC_QUALIFIER fvec4SIMD::fvec4SIMD(ivec4SIMD const & v) :
|
|
||||||
// Data(_mm_cvtepi32_ps(v.Data))
|
|
||||||
//{}
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Unary arithmetic operators
|
|
||||||
|
|
||||||
#if !GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator=(fvec4SIMD const & v)
|
|
||||||
{
|
|
||||||
this->Data = v.Data;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif//!GLM_HAS_DEFAULTED_FUNCTIONS
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator+=(float const & s)
|
|
||||||
{
|
|
||||||
this->Data = _mm_add_ps(Data, _mm_set_ps1(s));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator+=(fvec4SIMD const & v)
|
|
||||||
{
|
|
||||||
this->Data = _mm_add_ps(this->Data , v.Data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator-=(float const & s)
|
|
||||||
{
|
|
||||||
this->Data = _mm_sub_ps(Data, _mm_set_ps1(s));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator-=(fvec4SIMD const & v)
|
|
||||||
{
|
|
||||||
this->Data = _mm_sub_ps(this->Data , v.Data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator*=(float const & s)
|
|
||||||
{
|
|
||||||
this->Data = _mm_mul_ps(this->Data, _mm_set_ps1(s));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator*=(fvec4SIMD const & v)
|
|
||||||
{
|
|
||||||
this->Data = _mm_mul_ps(this->Data , v.Data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator/=(float const & s)
|
|
||||||
{
|
|
||||||
this->Data = _mm_div_ps(Data, _mm_set1_ps(s));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator/=(fvec4SIMD const & v)
|
|
||||||
{
|
|
||||||
this->Data = _mm_div_ps(this->Data , v.Data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator++()
|
|
||||||
{
|
|
||||||
this->Data = _mm_add_ps(this->Data , glm::detail::one);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::operator--()
|
|
||||||
{
|
|
||||||
this->Data = _mm_sub_ps(this->Data, glm::detail::one);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Swizzle operators
|
|
||||||
|
|
||||||
template <comp X_, comp Y_, comp Z_, comp W_>
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD fvec4SIMD::swizzle() const
|
|
||||||
{
|
|
||||||
__m128 Data = _mm_shuffle_ps(
|
|
||||||
this->Data, this->Data,
|
|
||||||
shuffle_mask<(W_ << 6) | (Z_ << 4) | (Y_ << 2) | (X_ << 0)>::value);
|
|
||||||
return fvec4SIMD(Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <comp X_, comp Y_, comp Z_, comp W_>
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD& fvec4SIMD::swizzle()
|
|
||||||
{
|
|
||||||
this->Data = _mm_shuffle_ps(
|
|
||||||
this->Data, this->Data,
|
|
||||||
shuffle_mask<(W_ << 6) | (Z_ << 4) | (Y_ << 2) | (X_ << 0)>::value);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// operator+
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator+ (fvec4SIMD const & v, float s)
|
|
||||||
{
|
|
||||||
return fvec4SIMD(_mm_add_ps(v.Data, _mm_set1_ps(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator+ (float s, fvec4SIMD const & v)
|
|
||||||
{
|
|
||||||
return fvec4SIMD(_mm_add_ps(_mm_set1_ps(s), v.Data));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator+ (fvec4SIMD const & v1, fvec4SIMD const & v2)
|
|
||||||
{
|
|
||||||
return fvec4SIMD(_mm_add_ps(v1.Data, v2.Data));
|
|
||||||
}
|
|
||||||
|
|
||||||
//operator-
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator- (fvec4SIMD const & v, float s)
|
|
||||||
{
|
|
||||||
return fvec4SIMD(_mm_sub_ps(v.Data, _mm_set1_ps(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator- (float s, fvec4SIMD const & v)
|
|
||||||
{
|
|
||||||
return fvec4SIMD(_mm_sub_ps(_mm_set1_ps(s), v.Data));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator- (fvec4SIMD const & v1, fvec4SIMD const & v2)
|
|
||||||
{
|
|
||||||
return fvec4SIMD(_mm_sub_ps(v1.Data, v2.Data));
|
|
||||||
}
|
|
||||||
|
|
||||||
//operator*
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator* (fvec4SIMD const & v, float s)
|
|
||||||
{
|
|
||||||
__m128 par0 = v.Data;
|
|
||||||
__m128 par1 = _mm_set1_ps(s);
|
|
||||||
return fvec4SIMD(_mm_mul_ps(par0, par1));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator* (float s, fvec4SIMD const & v)
|
|
||||||
{
|
|
||||||
__m128 par0 = _mm_set1_ps(s);
|
|
||||||
__m128 par1 = v.Data;
|
|
||||||
return fvec4SIMD(_mm_mul_ps(par0, par1));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator* (fvec4SIMD const & v1, fvec4SIMD const & v2)
|
|
||||||
{
|
|
||||||
return fvec4SIMD(_mm_mul_ps(v1.Data, v2.Data));
|
|
||||||
}
|
|
||||||
|
|
||||||
//operator/
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator/ (fvec4SIMD const & v, float s)
|
|
||||||
{
|
|
||||||
__m128 par0 = v.Data;
|
|
||||||
__m128 par1 = _mm_set1_ps(s);
|
|
||||||
return fvec4SIMD(_mm_div_ps(par0, par1));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator/ (float s, fvec4SIMD const & v)
|
|
||||||
{
|
|
||||||
__m128 par0 = _mm_set1_ps(s);
|
|
||||||
__m128 par1 = v.Data;
|
|
||||||
return fvec4SIMD(_mm_div_ps(par0, par1));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator/ (fvec4SIMD const & v1, fvec4SIMD const & v2)
|
|
||||||
{
|
|
||||||
return fvec4SIMD(_mm_div_ps(v1.Data, v2.Data));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unary constant operators
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator- (fvec4SIMD const & v)
|
|
||||||
{
|
|
||||||
return fvec4SIMD(_mm_sub_ps(_mm_setzero_ps(), v.Data));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator++ (fvec4SIMD const & v, int)
|
|
||||||
{
|
|
||||||
return fvec4SIMD(_mm_add_ps(v.Data, glm::detail::one));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER fvec4SIMD operator-- (fvec4SIMD const & v, int)
|
|
||||||
{
|
|
||||||
return fvec4SIMD(_mm_sub_ps(v.Data, glm::detail::one));
|
|
||||||
}
|
|
||||||
|
|
||||||
}//namespace detail
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER vec4 vec4_cast
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GLM_ALIGN(16) vec4 Result;
|
|
||||||
_mm_store_ps(&Result[0], x.Data);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other possible implementation
|
|
||||||
//float abs(float a)
|
|
||||||
//{
|
|
||||||
// return max(-a, a);
|
|
||||||
//}
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD abs
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_abs_ps(x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD sign
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_sgn_ps(x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD floor
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_flr_ps(x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD trunc
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//return x < 0 ? -floor(-x) : floor(x);
|
|
||||||
|
|
||||||
__m128 Flr0 = detail::sse_flr_ps(_mm_sub_ps(_mm_setzero_ps(), x.Data));
|
|
||||||
__m128 Sub0 = _mm_sub_ps(Flr0, x.Data);
|
|
||||||
__m128 Flr1 = detail::sse_flr_ps(x.Data);
|
|
||||||
|
|
||||||
__m128 Cmp0 = _mm_cmplt_ps(x.Data, glm::detail::zero);
|
|
||||||
__m128 Cmp1 = _mm_cmpnlt_ps(x.Data, glm::detail::zero);
|
|
||||||
|
|
||||||
__m128 And0 = _mm_and_ps(Sub0, Cmp0);
|
|
||||||
__m128 And1 = _mm_and_ps(Flr1, Cmp1);
|
|
||||||
|
|
||||||
return _mm_or_ps(And0, And1);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD round
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_rnd_ps(x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//GLM_FUNC_QUALIFIER detail::fvec4SIMD roundEven
|
|
||||||
//(
|
|
||||||
// detail::fvec4SIMD const & x
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD ceil
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_ceil_ps(x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD fract
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_frc_ps(x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD mod
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_mod_ps(x.Data, y.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD mod
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
float const & y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_mod_ps(x.Data, _mm_set1_ps(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
//GLM_FUNC_QUALIFIER detail::fvec4SIMD modf
|
|
||||||
//(
|
|
||||||
// detail::fvec4SIMD const & x,
|
|
||||||
// detail::fvec4SIMD & i
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD min
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _mm_min_ps(x.Data, y.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD min
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
float const & y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _mm_min_ps(x.Data, _mm_set1_ps(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD max
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _mm_max_ps(x.Data, y.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD max
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
float const & y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _mm_max_ps(x.Data, _mm_set1_ps(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD clamp
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & minVal,
|
|
||||||
detail::fvec4SIMD const & maxVal
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_clp_ps(x.Data, minVal.Data, maxVal.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD clamp
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
float const & minVal,
|
|
||||||
float const & maxVal
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_clp_ps(x.Data, _mm_set1_ps(minVal), _mm_set1_ps(maxVal));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD mix
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y,
|
|
||||||
detail::fvec4SIMD const & a
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 Sub0 = _mm_sub_ps(y.Data, x.Data);
|
|
||||||
__m128 Mul0 = _mm_mul_ps(a.Data, Sub0);
|
|
||||||
return _mm_add_ps(x.Data, Mul0);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD step
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & edge,
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 cmp0 = _mm_cmpngt_ps(x.Data, edge.Data);
|
|
||||||
return _mm_max_ps(_mm_min_ps(cmp0, _mm_setzero_ps()), detail::one);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD step
|
|
||||||
(
|
|
||||||
float const & edge,
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 cmp0 = _mm_cmpngt_ps(x.Data, _mm_set1_ps(edge));
|
|
||||||
return _mm_max_ps(_mm_min_ps(cmp0, _mm_setzero_ps()), detail::one);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD smoothstep
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & edge0,
|
|
||||||
detail::fvec4SIMD const & edge1,
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_ssp_ps(edge0.Data, edge1.Data, x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD smoothstep
|
|
||||||
(
|
|
||||||
float const & edge0,
|
|
||||||
float const & edge1,
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_ssp_ps(_mm_set1_ps(edge0), _mm_set1_ps(edge1), x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//GLM_FUNC_QUALIFIER bvec4 isnan(detail::fvec4SIMD const & x)
|
|
||||||
//{
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//GLM_FUNC_QUALIFIER bvec4 isinf(detail::fvec4SIMD const & x)
|
|
||||||
//{
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//GLM_FUNC_QUALIFIER detail::ivec4SIMD floatBitsToInt
|
|
||||||
//(
|
|
||||||
// detail::fvec4SIMD const & value
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//GLM_FUNC_QUALIFIER detail::fvec4SIMD intBitsToFloat
|
|
||||||
//(
|
|
||||||
// detail::ivec4SIMD const & value
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD fma
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & a,
|
|
||||||
detail::fvec4SIMD const & b,
|
|
||||||
detail::fvec4SIMD const & c
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _mm_add_ps(_mm_mul_ps(a.Data, b.Data), c.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER float length
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
detail::fvec4SIMD dot0 = detail::sse_dot_ss(x.Data, x.Data);
|
|
||||||
detail::fvec4SIMD sqt0 = sqrt(dot0);
|
|
||||||
float Result = 0;
|
|
||||||
_mm_store_ss(&Result, sqt0.Data);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER float fastLength
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
detail::fvec4SIMD dot0 = detail::sse_dot_ss(x.Data, x.Data);
|
|
||||||
detail::fvec4SIMD sqt0 = fastSqrt(dot0);
|
|
||||||
float Result = 0;
|
|
||||||
_mm_store_ss(&Result, sqt0.Data);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER float niceLength
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
detail::fvec4SIMD dot0 = detail::sse_dot_ss(x.Data, x.Data);
|
|
||||||
detail::fvec4SIMD sqt0 = niceSqrt(dot0);
|
|
||||||
float Result = 0;
|
|
||||||
_mm_store_ss(&Result, sqt0.Data);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD length4
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return sqrt(dot4(x, x));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD fastLength4
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return fastSqrt(dot4(x, x));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD niceLength4
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return niceSqrt(dot4(x, x));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER float distance
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & p0,
|
|
||||||
detail::fvec4SIMD const & p1
|
|
||||||
)
|
|
||||||
{
|
|
||||||
float Result = 0;
|
|
||||||
_mm_store_ss(&Result, detail::sse_dst_ps(p0.Data, p1.Data));
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD distance4
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & p0,
|
|
||||||
detail::fvec4SIMD const & p1
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_dst_ps(p0.Data, p1.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER float dot
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
float Result = 0;
|
|
||||||
_mm_store_ss(&Result, detail::sse_dot_ss(x.Data, y.Data));
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD dot4
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_dot_ps(x.Data, y.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD cross
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x,
|
|
||||||
detail::fvec4SIMD const & y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_xpd_ps(x.Data, y.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD normalize
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 dot0 = detail::sse_dot_ps(x.Data, x.Data);
|
|
||||||
__m128 isr0 = inversesqrt(detail::fvec4SIMD(dot0)).Data;
|
|
||||||
__m128 mul0 = _mm_mul_ps(x.Data, isr0);
|
|
||||||
return mul0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD fastNormalize
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & x
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__m128 dot0 = detail::sse_dot_ps(x.Data, x.Data);
|
|
||||||
__m128 isr0 = fastInversesqrt(dot0).Data;
|
|
||||||
__m128 mul0 = _mm_mul_ps(x.Data, isr0);
|
|
||||||
return mul0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD faceforward
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & N,
|
|
||||||
detail::fvec4SIMD const & I,
|
|
||||||
detail::fvec4SIMD const & Nref
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_ffd_ps(N.Data, I.Data, Nref.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD reflect
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & I,
|
|
||||||
detail::fvec4SIMD const & N
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_rfe_ps(I.Data, N.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD refract
|
|
||||||
(
|
|
||||||
detail::fvec4SIMD const & I,
|
|
||||||
detail::fvec4SIMD const & N,
|
|
||||||
float const & eta
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return detail::sse_rfa_ps(I.Data, N.Data, _mm_set1_ps(eta));
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD sqrt(detail::fvec4SIMD const & x)
|
|
||||||
{
|
|
||||||
return _mm_mul_ps(inversesqrt(x).Data, x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD niceSqrt(detail::fvec4SIMD const & x)
|
|
||||||
{
|
|
||||||
return _mm_sqrt_ps(x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD fastSqrt(detail::fvec4SIMD const & x)
|
|
||||||
{
|
|
||||||
return _mm_mul_ps(fastInversesqrt(x.Data).Data, x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SSE scalar reciprocal sqrt using rsqrt op, plus one Newton-Rhaphson iteration
|
|
||||||
// By Elan Ruskin, http://assemblyrequired.crashworks.org/
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD inversesqrt(detail::fvec4SIMD const & x)
|
|
||||||
{
|
|
||||||
GLM_ALIGN(4) static const __m128 three = {3, 3, 3, 3}; // aligned consts for fast load
|
|
||||||
GLM_ALIGN(4) static const __m128 half = {0.5,0.5,0.5,0.5};
|
|
||||||
|
|
||||||
__m128 recip = _mm_rsqrt_ps(x.Data); // "estimate" opcode
|
|
||||||
__m128 halfrecip = _mm_mul_ps(half, recip);
|
|
||||||
__m128 threeminus_xrr = _mm_sub_ps(three, _mm_mul_ps(x.Data, _mm_mul_ps(recip, recip)));
|
|
||||||
return _mm_mul_ps(halfrecip, threeminus_xrr);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER detail::fvec4SIMD fastInversesqrt(detail::fvec4SIMD const & x)
|
|
||||||
{
|
|
||||||
return _mm_rsqrt_ps(x.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
}//namespace glm
|
|
19
readme.md
19
readme.md
@ -51,6 +51,23 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate)
|
|||||||
|
|
||||||
## Release notes
|
## Release notes
|
||||||
|
|
||||||
|
#### [GLM 0.9.9.0](https://github.com/g-truc/glm/releases/latest) - 2017-XX-XX
|
||||||
|
##### Features:
|
||||||
|
- Added GTC_color_encoding extension
|
||||||
|
|
||||||
|
##### Improvements:
|
||||||
|
|
||||||
|
##### Fixes:
|
||||||
|
|
||||||
|
##### Deprecation:
|
||||||
|
- Removed GLM_GTX_simd_vec4 extension
|
||||||
|
- Removed GLM_GTX_simd_mat4 extension
|
||||||
|
- Removed GLM_GTX_simd_quat extension
|
||||||
|
- Removed GLM_SWIZZLE, use GLM_FORCE_SWIZZLE instead
|
||||||
|
- Removed GLM_MESSAGES, use GLM_FORCE_MESSAGES instead
|
||||||
|
- Removed GLM_DEPTH_ZERO_TO_ONE, use GLM_FORCE_DEPTH_ZERO_TO_ONE instead
|
||||||
|
- Removed GLM_LEFT_HANDED, use GLM_FORCE_LEFT_HANDED instead
|
||||||
|
|
||||||
#### [GLM 0.9.8.1](https://github.com/g-truc/glm/tree/0.9.8) - 2016-XX-XX
|
#### [GLM 0.9.8.1](https://github.com/g-truc/glm/tree/0.9.8) - 2016-XX-XX
|
||||||
##### Fixes:
|
##### Fixes:
|
||||||
- Fixed GCC warning filtering, replaced -pedantic by -Wpedantic
|
- Fixed GCC warning filtering, replaced -pedantic by -Wpedantic
|
||||||
@ -101,7 +118,7 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate)
|
|||||||
- Fixed missing vec1 overload to length2 and distance2 functions #431
|
- Fixed missing vec1 overload to length2 and distance2 functions #431
|
||||||
- Fixed GLM test '/fp:fast' and '/Za' command-line options are incompatible
|
- Fixed GLM test '/fp:fast' and '/Za' command-line options are incompatible
|
||||||
- Fixed quaterion to mat3 cast function mat3_cast from GTC_quaternion #542
|
- Fixed quaterion to mat3 cast function mat3_cast from GTC_quaternion #542
|
||||||
- Fixed GLM_GTX_io for Cuda #547 #546
|
- Fixed GTX_io for Cuda #547 #546
|
||||||
|
|
||||||
##### Deprecation:
|
##### Deprecation:
|
||||||
- Removed GLM_FORCE_SIZE_FUNC define
|
- Removed GLM_FORCE_SIZE_FUNC define
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
glmCreateTestGTC(gtc_bitfield)
|
glmCreateTestGTC(gtc_bitfield)
|
||||||
|
glmCreateTestGTC(gtc_color_encoding)
|
||||||
glmCreateTestGTC(gtc_color_space)
|
glmCreateTestGTC(gtc_color_space)
|
||||||
glmCreateTestGTC(gtc_constants)
|
glmCreateTestGTC(gtc_constants)
|
||||||
glmCreateTestGTC(gtc_epsilon)
|
glmCreateTestGTC(gtc_epsilon)
|
||||||
|
51
test/gtc/gtc_color_encoding.cpp
Normal file
51
test/gtc/gtc_color_encoding.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include <glm/gtc/color_encoding.hpp>
|
||||||
|
#include <glm/gtc/color_space.hpp>
|
||||||
|
#include <glm/gtc/epsilon.hpp>
|
||||||
|
#include <glm/gtc/constants.hpp>
|
||||||
|
|
||||||
|
namespace srgb
|
||||||
|
{
|
||||||
|
int test()
|
||||||
|
{
|
||||||
|
int Error(0);
|
||||||
|
|
||||||
|
glm::vec3 const ColorSourceRGB(1.0, 0.5, 0.0);
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
glm::vec3 const ColorSRGB = glm::convertLinearSRGBToD65XYZ(ColorSourceRGB);
|
||||||
|
glm::vec3 const ColorRGB = glm::convertD65XYZToLinearSRGB(ColorSRGB);
|
||||||
|
Error += glm::all(glm::epsilonEqual(ColorSourceRGB, ColorRGB, 0.00001f)) ? 0 : 1;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
glm::vec3 const ColorSRGB = glm::convertLinearToSRGB(ColorSourceRGB, 2.8f);
|
||||||
|
glm::vec3 const ColorRGB = glm::convertSRGBToLinear(ColorSRGB, 2.8f);
|
||||||
|
Error += glm::all(glm::epsilonEqual(ColorSourceRGB, ColorRGB, 0.00001f)) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec4 const ColorSourceRGBA(1.0, 0.5, 0.0, 1.0);
|
||||||
|
|
||||||
|
{
|
||||||
|
glm::vec4 const ColorSRGB = glm::convertLinearToSRGB(ColorSourceRGBA);
|
||||||
|
glm::vec4 const ColorRGB = glm::convertSRGBToLinear(ColorSRGB);
|
||||||
|
Error += glm::all(glm::epsilonEqual(ColorSourceRGBA, ColorRGB, 0.00001f)) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
glm::vec4 const ColorSRGB = glm::convertLinearToSRGB(ColorSourceRGBA, 2.8f);
|
||||||
|
glm::vec4 const ColorRGB = glm::convertSRGBToLinear(ColorSRGB, 2.8f);
|
||||||
|
Error += glm::all(glm::epsilonEqual(ColorSourceRGBA, ColorRGB, 0.00001f)) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
}//namespace srgb
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int Error(0);
|
||||||
|
|
||||||
|
Error += srgb::test();
|
||||||
|
|
||||||
|
return Error;
|
||||||
|
}
|
@ -40,8 +40,6 @@ glmCreateTestGTC(gtx_rotate_normalized_axis)
|
|||||||
glmCreateTestGTC(gtx_rotate_vector)
|
glmCreateTestGTC(gtx_rotate_vector)
|
||||||
glmCreateTestGTC(gtx_scalar_multiplication)
|
glmCreateTestGTC(gtx_scalar_multiplication)
|
||||||
glmCreateTestGTC(gtx_scalar_relational)
|
glmCreateTestGTC(gtx_scalar_relational)
|
||||||
#glmCreateTestGTC(gtx_simd_vec4)
|
|
||||||
#glmCreateTestGTC(gtx_simd_mat4)
|
|
||||||
glmCreateTestGTC(gtx_spline)
|
glmCreateTestGTC(gtx_spline)
|
||||||
glmCreateTestGTC(gtx_string_cast)
|
glmCreateTestGTC(gtx_string_cast)
|
||||||
glmCreateTestGTC(gtx_type_aligned)
|
glmCreateTestGTC(gtx_type_aligned)
|
||||||
|
Loading…
Reference in New Issue
Block a user