Rebuild trinity visualizer from bare SDL and OpenGL to using Raylib. Added Code for serial parsing on linux. Current functionality reads incoming quaternion packet data coming in over serial and displays the values and also visualizes with a cube, connect and disconnect is implemented. Essentially rebuild the functionality of the old version with added linux support.

This commit is contained in:
2026-09-13 19:44:26 +02:00
commit 62abf4d5d6
821 changed files with 239694 additions and 0 deletions
+266
View File
@@ -0,0 +1,266 @@
/// @ref gtc_bitfield
/// @file glm/gtc/bitfield.hpp
///
/// @see core (dependence)
/// @see gtc_bitfield (dependence)
///
/// @defgroup gtc_bitfield GLM_GTC_bitfield
/// @ingroup gtc
///
/// Include <glm/gtc/bitfield.hpp> to use the features of this extension.
///
/// Allow to perform bit operations on integer values
#include "../detail/setup.hpp"
#pragma once
// Dependencies
#include "../ext/scalar_int_sized.hpp"
#include "../ext/scalar_uint_sized.hpp"
#include "../detail/qualifier.hpp"
#include "../detail/_vectorize.hpp"
#include "type_precision.hpp"
#include <limits>
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_bitfield extension included")
#endif
namespace glm
{
/// @addtogroup gtc_bitfield
/// @{
/// Build a mask of 'count' bits
///
/// @see gtc_bitfield
template<typename genIUType>
GLM_FUNC_DECL genIUType mask(genIUType Bits);
/// Build a mask of 'count' bits
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Signed and unsigned integer scalar types
/// @tparam Q Value from qualifier enum
///
/// @see gtc_bitfield
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> mask(vec<L, T, Q> const& v);
/// Rotate all bits to the right. All the bits dropped in the right side are inserted back on the left side.
///
/// @see gtc_bitfield
template<typename genIUType>
GLM_FUNC_DECL genIUType bitfieldRotateRight(genIUType In, int Shift);
/// Rotate all bits to the right. All the bits dropped in the right side are inserted back on the left side.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Signed and unsigned integer scalar types
/// @tparam Q Value from qualifier enum
///
/// @see gtc_bitfield
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> bitfieldRotateRight(vec<L, T, Q> const& In, int Shift);
/// Rotate all bits to the left. All the bits dropped in the left side are inserted back on the right side.
///
/// @see gtc_bitfield
template<typename genIUType>
GLM_FUNC_DECL genIUType bitfieldRotateLeft(genIUType In, int Shift);
/// Rotate all bits to the left. All the bits dropped in the left side are inserted back on the right side.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Signed and unsigned integer scalar types
/// @tparam Q Value from qualifier enum
///
/// @see gtc_bitfield
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> bitfieldRotateLeft(vec<L, T, Q> const& In, int Shift);
/// Set to 1 a range of bits.
///
/// @see gtc_bitfield
template<typename genIUType>
GLM_FUNC_DECL genIUType bitfieldFillOne(genIUType Value, int FirstBit, int BitCount);
/// Set to 1 a range of bits.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Signed and unsigned integer scalar types
/// @tparam Q Value from qualifier enum
///
/// @see gtc_bitfield
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> bitfieldFillOne(vec<L, T, Q> const& Value, int FirstBit, int BitCount);
/// Set to 0 a range of bits.
///
/// @see gtc_bitfield
template<typename genIUType>
GLM_FUNC_DECL genIUType bitfieldFillZero(genIUType Value, int FirstBit, int BitCount);
/// Set to 0 a range of bits.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Signed and unsigned integer scalar types
/// @tparam Q Value from qualifier enum
///
/// @see gtc_bitfield
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> bitfieldFillZero(vec<L, T, Q> const& Value, int FirstBit, int BitCount);
/// Interleaves the bits of x and y.
/// The first bit is the first bit of x followed by the first bit of y.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL int16 bitfieldInterleave(int8 x, int8 y);
/// Interleaves the bits of x and y.
/// The first bit is the first bit of x followed by the first bit of y.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL uint16 bitfieldInterleave(uint8 x, uint8 y);
/// Interleaves the bits of x and y.
/// The first bit is the first bit of v.x followed by the first bit of v.y.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL uint16 bitfieldInterleave(u8vec2 const& v);
/// Deinterleaves the bits of x.
///
/// @see gtc_bitfield
GLM_FUNC_DECL glm::u8vec2 bitfieldDeinterleave(glm::uint16 x);
/// Interleaves the bits of x and y.
/// The first bit is the first bit of x followed by the first bit of y.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL int32 bitfieldInterleave(int16 x, int16 y);
/// Interleaves the bits of x and y.
/// The first bit is the first bit of x followed by the first bit of y.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL uint32 bitfieldInterleave(uint16 x, uint16 y);
/// Interleaves the bits of x and y.
/// The first bit is the first bit of v.x followed by the first bit of v.y.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL uint32 bitfieldInterleave(u16vec2 const& v);
/// Deinterleaves the bits of x.
///
/// @see gtc_bitfield
GLM_FUNC_DECL glm::u16vec2 bitfieldDeinterleave(glm::uint32 x);
/// Interleaves the bits of x and y.
/// The first bit is the first bit of x followed by the first bit of y.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL int64 bitfieldInterleave(int32 x, int32 y);
/// Interleaves the bits of x and y.
/// The first bit is the first bit of x followed by the first bit of y.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y);
/// Interleaves the bits of x and y.
/// The first bit is the first bit of v.x followed by the first bit of v.y.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL uint64 bitfieldInterleave(u32vec2 const& v);
/// Deinterleaves the bits of x.
///
/// @see gtc_bitfield
GLM_FUNC_DECL glm::u32vec2 bitfieldDeinterleave(glm::uint64 x);
/// Interleaves the bits of x, y and z.
/// The first bit is the first bit of x followed by the first bit of y and the first bit of z.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL int32 bitfieldInterleave(int8 x, int8 y, int8 z);
/// Interleaves the bits of x, y and z.
/// The first bit is the first bit of x followed by the first bit of y and the first bit of z.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z);
/// Interleaves the bits of x, y and z.
/// The first bit is the first bit of x followed by the first bit of y and the first bit of z.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL int64 bitfieldInterleave(int16 x, int16 y, int16 z);
/// Interleaves the bits of x, y and z.
/// The first bit is the first bit of x followed by the first bit of y and the first bit of z.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z);
/// Interleaves the bits of x, y and z.
/// The first bit is the first bit of x followed by the first bit of y and the first bit of z.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL int64 bitfieldInterleave(int32 x, int32 y, int32 z);
/// Interleaves the bits of x, y and z.
/// The first bit is the first bit of x followed by the first bit of y and the first bit of z.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z);
/// Interleaves the bits of x, y, z and w.
/// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w);
/// Interleaves the bits of x, y, z and w.
/// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w);
/// Interleaves the bits of x, y, z and w.
/// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w);
/// Interleaves the bits of x, y, z and w.
/// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w.
/// The other bits are interleaved following the previous sequence.
///
/// @see gtc_bitfield
GLM_FUNC_DECL uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w);
/// @}
} //namespace glm
#include "bitfield.inl"
+635
View File
@@ -0,0 +1,635 @@
/// @ref gtc_bitfield
#include "../simd/integer.h"
namespace glm{
namespace detail
{
template<typename PARAM, typename RET>
GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y);
template<typename PARAM, typename RET>
GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z);
template<typename PARAM, typename RET>
GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w);
template<>
GLM_FUNC_QUALIFIER glm::uint16 bitfieldInterleave(glm::uint8 x, glm::uint8 y)
{
glm::uint16 REG1(x);
glm::uint16 REG2(y);
REG1 = ((REG1 << 4) | REG1) & static_cast<glm::uint16>(0x0F0F);
REG2 = ((REG2 << 4) | REG2) & static_cast<glm::uint16>(0x0F0F);
REG1 = ((REG1 << 2) | REG1) & static_cast<glm::uint16>(0x3333);
REG2 = ((REG2 << 2) | REG2) & static_cast<glm::uint16>(0x3333);
REG1 = ((REG1 << 1) | REG1) & static_cast<glm::uint16>(0x5555);
REG2 = ((REG2 << 1) | REG2) & static_cast<glm::uint16>(0x5555);
return REG1 | static_cast<glm::uint16>(REG2 << 1);
}
template<>
GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint16 x, glm::uint16 y)
{
glm::uint32 REG1(x);
glm::uint32 REG2(y);
REG1 = ((REG1 << 8) | REG1) & static_cast<glm::uint32>(0x00FF00FF);
REG2 = ((REG2 << 8) | REG2) & static_cast<glm::uint32>(0x00FF00FF);
REG1 = ((REG1 << 4) | REG1) & static_cast<glm::uint32>(0x0F0F0F0F);
REG2 = ((REG2 << 4) | REG2) & static_cast<glm::uint32>(0x0F0F0F0F);
REG1 = ((REG1 << 2) | REG1) & static_cast<glm::uint32>(0x33333333);
REG2 = ((REG2 << 2) | REG2) & static_cast<glm::uint32>(0x33333333);
REG1 = ((REG1 << 1) | REG1) & static_cast<glm::uint32>(0x55555555);
REG2 = ((REG2 << 1) | REG2) & static_cast<glm::uint32>(0x55555555);
return REG1 | (REG2 << 1);
}
template<>
GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y)
{
glm::uint64 REG1(x);
glm::uint64 REG2(y);
REG1 = ((REG1 << 16) | REG1) & static_cast<glm::uint64>(0x0000FFFF0000FFFFull);
REG2 = ((REG2 << 16) | REG2) & static_cast<glm::uint64>(0x0000FFFF0000FFFFull);
REG1 = ((REG1 << 8) | REG1) & static_cast<glm::uint64>(0x00FF00FF00FF00FFull);
REG2 = ((REG2 << 8) | REG2) & static_cast<glm::uint64>(0x00FF00FF00FF00FFull);
REG1 = ((REG1 << 4) | REG1) & static_cast<glm::uint64>(0x0F0F0F0F0F0F0F0Full);
REG2 = ((REG2 << 4) | REG2) & static_cast<glm::uint64>(0x0F0F0F0F0F0F0F0Full);
REG1 = ((REG1 << 2) | REG1) & static_cast<glm::uint64>(0x3333333333333333ull);
REG2 = ((REG2 << 2) | REG2) & static_cast<glm::uint64>(0x3333333333333333ull);
REG1 = ((REG1 << 1) | REG1) & static_cast<glm::uint64>(0x5555555555555555ull);
REG2 = ((REG2 << 1) | REG2) & static_cast<glm::uint64>(0x5555555555555555ull);
return REG1 | (REG2 << 1);
}
template<>
GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z)
{
glm::uint32 REG1(x);
glm::uint32 REG2(y);
glm::uint32 REG3(z);
REG1 = ((REG1 << 16) | REG1) & static_cast<glm::uint32>(0xFF0000FFu);
REG2 = ((REG2 << 16) | REG2) & static_cast<glm::uint32>(0xFF0000FFu);
REG3 = ((REG3 << 16) | REG3) & static_cast<glm::uint32>(0xFF0000FFu);
REG1 = ((REG1 << 8) | REG1) & static_cast<glm::uint32>(0x0F00F00Fu);
REG2 = ((REG2 << 8) | REG2) & static_cast<glm::uint32>(0x0F00F00Fu);
REG3 = ((REG3 << 8) | REG3) & static_cast<glm::uint32>(0x0F00F00Fu);
REG1 = ((REG1 << 4) | REG1) & static_cast<glm::uint32>(0xC30C30C3u);
REG2 = ((REG2 << 4) | REG2) & static_cast<glm::uint32>(0xC30C30C3u);
REG3 = ((REG3 << 4) | REG3) & static_cast<glm::uint32>(0xC30C30C3u);
REG1 = ((REG1 << 2) | REG1) & static_cast<glm::uint32>(0x49249249u);
REG2 = ((REG2 << 2) | REG2) & static_cast<glm::uint32>(0x49249249u);
REG3 = ((REG3 << 2) | REG3) & static_cast<glm::uint32>(0x49249249u);
return REG1 | (REG2 << 1) | (REG3 << 2);
}
template<>
GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z)
{
glm::uint64 REG1(x);
glm::uint64 REG2(y);
glm::uint64 REG3(z);
REG1 = ((REG1 << 32) | REG1) & static_cast<glm::uint64>(0xFFFF00000000FFFFull);
REG2 = ((REG2 << 32) | REG2) & static_cast<glm::uint64>(0xFFFF00000000FFFFull);
REG3 = ((REG3 << 32) | REG3) & static_cast<glm::uint64>(0xFFFF00000000FFFFull);
REG1 = ((REG1 << 16) | REG1) & static_cast<glm::uint64>(0x00FF0000FF0000FFull);
REG2 = ((REG2 << 16) | REG2) & static_cast<glm::uint64>(0x00FF0000FF0000FFull);
REG3 = ((REG3 << 16) | REG3) & static_cast<glm::uint64>(0x00FF0000FF0000FFull);
REG1 = ((REG1 << 8) | REG1) & static_cast<glm::uint64>(0xF00F00F00F00F00Full);
REG2 = ((REG2 << 8) | REG2) & static_cast<glm::uint64>(0xF00F00F00F00F00Full);
REG3 = ((REG3 << 8) | REG3) & static_cast<glm::uint64>(0xF00F00F00F00F00Full);
REG1 = ((REG1 << 4) | REG1) & static_cast<glm::uint64>(0x30C30C30C30C30C3ull);
REG2 = ((REG2 << 4) | REG2) & static_cast<glm::uint64>(0x30C30C30C30C30C3ull);
REG3 = ((REG3 << 4) | REG3) & static_cast<glm::uint64>(0x30C30C30C30C30C3ull);
REG1 = ((REG1 << 2) | REG1) & static_cast<glm::uint64>(0x9249249249249249ull);
REG2 = ((REG2 << 2) | REG2) & static_cast<glm::uint64>(0x9249249249249249ull);
REG3 = ((REG3 << 2) | REG3) & static_cast<glm::uint64>(0x9249249249249249ull);
return REG1 | (REG2 << 1) | (REG3 << 2);
}
template<>
GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y, glm::uint32 z)
{
glm::uint64 REG1(x);
glm::uint64 REG2(y);
glm::uint64 REG3(z);
REG1 = ((REG1 << 32) | REG1) & static_cast<glm::uint64>(0xFFFF00000000FFFFull);
REG2 = ((REG2 << 32) | REG2) & static_cast<glm::uint64>(0xFFFF00000000FFFFull);
REG3 = ((REG3 << 32) | REG3) & static_cast<glm::uint64>(0xFFFF00000000FFFFull);
REG1 = ((REG1 << 16) | REG1) & static_cast<glm::uint64>(0x00FF0000FF0000FFull);
REG2 = ((REG2 << 16) | REG2) & static_cast<glm::uint64>(0x00FF0000FF0000FFull);
REG3 = ((REG3 << 16) | REG3) & static_cast<glm::uint64>(0x00FF0000FF0000FFull);
REG1 = ((REG1 << 8) | REG1) & static_cast<glm::uint64>(0xF00F00F00F00F00Full);
REG2 = ((REG2 << 8) | REG2) & static_cast<glm::uint64>(0xF00F00F00F00F00Full);
REG3 = ((REG3 << 8) | REG3) & static_cast<glm::uint64>(0xF00F00F00F00F00Full);
REG1 = ((REG1 << 4) | REG1) & static_cast<glm::uint64>(0x30C30C30C30C30C3ull);
REG2 = ((REG2 << 4) | REG2) & static_cast<glm::uint64>(0x30C30C30C30C30C3ull);
REG3 = ((REG3 << 4) | REG3) & static_cast<glm::uint64>(0x30C30C30C30C30C3ull);
REG1 = ((REG1 << 2) | REG1) & static_cast<glm::uint64>(0x9249249249249249ull);
REG2 = ((REG2 << 2) | REG2) & static_cast<glm::uint64>(0x9249249249249249ull);
REG3 = ((REG3 << 2) | REG3) & static_cast<glm::uint64>(0x9249249249249249ull);
return REG1 | (REG2 << 1) | (REG3 << 2);
}
template<>
GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z, glm::uint8 w)
{
glm::uint32 REG1(x);
glm::uint32 REG2(y);
glm::uint32 REG3(z);
glm::uint32 REG4(w);
REG1 = ((REG1 << 12) | REG1) & static_cast<glm::uint32>(0x000F000Fu);
REG2 = ((REG2 << 12) | REG2) & static_cast<glm::uint32>(0x000F000Fu);
REG3 = ((REG3 << 12) | REG3) & static_cast<glm::uint32>(0x000F000Fu);
REG4 = ((REG4 << 12) | REG4) & static_cast<glm::uint32>(0x000F000Fu);
REG1 = ((REG1 << 6) | REG1) & static_cast<glm::uint32>(0x03030303u);
REG2 = ((REG2 << 6) | REG2) & static_cast<glm::uint32>(0x03030303u);
REG3 = ((REG3 << 6) | REG3) & static_cast<glm::uint32>(0x03030303u);
REG4 = ((REG4 << 6) | REG4) & static_cast<glm::uint32>(0x03030303u);
REG1 = ((REG1 << 3) | REG1) & static_cast<glm::uint32>(0x11111111u);
REG2 = ((REG2 << 3) | REG2) & static_cast<glm::uint32>(0x11111111u);
REG3 = ((REG3 << 3) | REG3) & static_cast<glm::uint32>(0x11111111u);
REG4 = ((REG4 << 3) | REG4) & static_cast<glm::uint32>(0x11111111u);
return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3);
}
template<>
GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z, glm::uint16 w)
{
glm::uint64 REG1(x);
glm::uint64 REG2(y);
glm::uint64 REG3(z);
glm::uint64 REG4(w);
REG1 = ((REG1 << 24) | REG1) & static_cast<glm::uint64>(0x000000FF000000FFull);
REG2 = ((REG2 << 24) | REG2) & static_cast<glm::uint64>(0x000000FF000000FFull);
REG3 = ((REG3 << 24) | REG3) & static_cast<glm::uint64>(0x000000FF000000FFull);
REG4 = ((REG4 << 24) | REG4) & static_cast<glm::uint64>(0x000000FF000000FFull);
REG1 = ((REG1 << 12) | REG1) & static_cast<glm::uint64>(0x000F000F000F000Full);
REG2 = ((REG2 << 12) | REG2) & static_cast<glm::uint64>(0x000F000F000F000Full);
REG3 = ((REG3 << 12) | REG3) & static_cast<glm::uint64>(0x000F000F000F000Full);
REG4 = ((REG4 << 12) | REG4) & static_cast<glm::uint64>(0x000F000F000F000Full);
REG1 = ((REG1 << 6) | REG1) & static_cast<glm::uint64>(0x0303030303030303ull);
REG2 = ((REG2 << 6) | REG2) & static_cast<glm::uint64>(0x0303030303030303ull);
REG3 = ((REG3 << 6) | REG3) & static_cast<glm::uint64>(0x0303030303030303ull);
REG4 = ((REG4 << 6) | REG4) & static_cast<glm::uint64>(0x0303030303030303ull);
REG1 = ((REG1 << 3) | REG1) & static_cast<glm::uint64>(0x1111111111111111ull);
REG2 = ((REG2 << 3) | REG2) & static_cast<glm::uint64>(0x1111111111111111ull);
REG3 = ((REG3 << 3) | REG3) & static_cast<glm::uint64>(0x1111111111111111ull);
REG4 = ((REG4 << 3) | REG4) & static_cast<glm::uint64>(0x1111111111111111ull);
return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3);
}
}//namespace detail
#if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wsign-compare"
#endif
template<typename genIUType>
GLM_FUNC_QUALIFIER genIUType mask(genIUType Bits)
{
GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'mask' accepts only integer values");
return Bits >= static_cast<genIUType>(sizeof(genIUType) * 8) ? ~static_cast<genIUType>(0) : (static_cast<genIUType>(1) << Bits) - static_cast<genIUType>(1);
}
#if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic pop
#endif
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> mask(vec<L, T, Q> const& v)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'mask' accepts only integer values");
return detail::functor1<vec, L, T, T, Q>::call(mask, v);
}
template<typename genIType>
GLM_FUNC_QUALIFIER genIType bitfieldRotateRight(genIType In, int Shift)
{
GLM_STATIC_ASSERT(std::numeric_limits<genIType>::is_integer, "'bitfieldRotateRight' accepts only integer values");
int const BitSize = static_cast<genIType>(sizeof(genIType) * 8);
return (In << static_cast<genIType>(Shift)) | (In >> static_cast<genIType>(BitSize - Shift));
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> bitfieldRotateRight(vec<L, T, Q> const& In, int Shift)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitfieldRotateRight' accepts only integer values");
int const BitSize = static_cast<int>(sizeof(T) * 8);
return (In << static_cast<T>(Shift)) | (In >> static_cast<T>(BitSize - Shift));
}
template<typename genIType>
GLM_FUNC_QUALIFIER genIType bitfieldRotateLeft(genIType In, int Shift)
{
GLM_STATIC_ASSERT(std::numeric_limits<genIType>::is_integer, "'bitfieldRotateLeft' accepts only integer values");
int const BitSize = static_cast<genIType>(sizeof(genIType) * 8);
return (In >> static_cast<genIType>(Shift)) | (In << static_cast<genIType>(BitSize - Shift));
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> bitfieldRotateLeft(vec<L, T, Q> const& In, int Shift)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitfieldRotateLeft' accepts only integer values");
int const BitSize = static_cast<int>(sizeof(T) * 8);
return (In >> static_cast<T>(Shift)) | (In << static_cast<T>(BitSize - Shift));
}
template<typename genIUType>
GLM_FUNC_QUALIFIER genIUType bitfieldFillOne(genIUType Value, int FirstBit, int BitCount)
{
return Value | static_cast<genIUType>(mask(BitCount) << FirstBit);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> bitfieldFillOne(vec<L, T, Q> const& Value, int FirstBit, int BitCount)
{
return Value | static_cast<T>(mask(BitCount) << FirstBit);
}
template<typename genIUType>
GLM_FUNC_QUALIFIER genIUType bitfieldFillZero(genIUType Value, int FirstBit, int BitCount)
{
return Value & static_cast<genIUType>(~(mask(BitCount) << FirstBit));
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> bitfieldFillZero(vec<L, T, Q> const& Value, int FirstBit, int BitCount)
{
return Value & static_cast<T>(~(mask(BitCount) << FirstBit));
}
GLM_FUNC_QUALIFIER int16 bitfieldInterleave(int8 x, int8 y)
{
union sign8
{
int8 i;
uint8 u;
} sign_x, sign_y;
union sign16
{
int16 i;
uint16 u;
} result;
sign_x.i = x;
sign_y.i = y;
result.u = bitfieldInterleave(sign_x.u, sign_y.u);
return result.i;
}
GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(uint8 x, uint8 y)
{
return detail::bitfieldInterleave<uint8, uint16>(x, y);
}
GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(u8vec2 const& v)
{
return detail::bitfieldInterleave<uint8, uint16>(v.x, v.y);
}
GLM_FUNC_QUALIFIER u8vec2 bitfieldDeinterleave(glm::uint16 x)
{
uint16 REG1(x);
uint16 REG2(x >>= 1);
REG1 = REG1 & static_cast<uint16>(0x5555);
REG2 = REG2 & static_cast<uint16>(0x5555);
REG1 = ((REG1 >> 1) | REG1) & static_cast<uint16>(0x3333);
REG2 = ((REG2 >> 1) | REG2) & static_cast<uint16>(0x3333);
REG1 = ((REG1 >> 2) | REG1) & static_cast<uint16>(0x0F0F);
REG2 = ((REG2 >> 2) | REG2) & static_cast<uint16>(0x0F0F);
REG1 = ((REG1 >> 4) | REG1) & static_cast<uint16>(0x00FF);
REG2 = ((REG2 >> 4) | REG2) & static_cast<uint16>(0x00FF);
REG1 = ((REG1 >> 8) | REG1) & static_cast<uint16>(0xFFFF);
REG2 = ((REG2 >> 8) | REG2) & static_cast<uint16>(0xFFFF);
return glm::u8vec2(REG1, REG2);
}
GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int16 x, int16 y)
{
union sign16
{
int16 i;
uint16 u;
} sign_x, sign_y;
union sign32
{
int32 i;
uint32 u;
} result;
sign_x.i = x;
sign_y.i = y;
result.u = bitfieldInterleave(sign_x.u, sign_y.u);
return result.i;
}
GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint16 x, uint16 y)
{
return detail::bitfieldInterleave<uint16, uint32>(x, y);
}
GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(u16vec2 const& v)
{
return detail::bitfieldInterleave<uint16, uint32>(v.x, v.y);
}
GLM_FUNC_QUALIFIER glm::u16vec2 bitfieldDeinterleave(glm::uint32 x)
{
glm::uint32 REG1(x);
glm::uint32 REG2(x >>= 1);
REG1 = REG1 & static_cast<glm::uint32>(0x55555555);
REG2 = REG2 & static_cast<glm::uint32>(0x55555555);
REG1 = ((REG1 >> 1) | REG1) & static_cast<glm::uint32>(0x33333333);
REG2 = ((REG2 >> 1) | REG2) & static_cast<glm::uint32>(0x33333333);
REG1 = ((REG1 >> 2) | REG1) & static_cast<glm::uint32>(0x0F0F0F0F);
REG2 = ((REG2 >> 2) | REG2) & static_cast<glm::uint32>(0x0F0F0F0F);
REG1 = ((REG1 >> 4) | REG1) & static_cast<glm::uint32>(0x00FF00FF);
REG2 = ((REG2 >> 4) | REG2) & static_cast<glm::uint32>(0x00FF00FF);
REG1 = ((REG1 >> 8) | REG1) & static_cast<glm::uint32>(0x0000FFFF);
REG2 = ((REG2 >> 8) | REG2) & static_cast<glm::uint32>(0x0000FFFF);
return glm::u16vec2(REG1, REG2);
}
GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y)
{
union sign32
{
int32 i;
uint32 u;
} sign_x, sign_y;
union sign64
{
int64 i;
uint64 u;
} result;
sign_x.i = x;
sign_y.i = y;
result.u = bitfieldInterleave(sign_x.u, sign_y.u);
return result.i;
}
GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y)
{
return detail::bitfieldInterleave<uint32, uint64>(x, y);
}
GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(u32vec2 const& v)
{
return detail::bitfieldInterleave<uint32, uint64>(v.x, v.y);
}
GLM_FUNC_QUALIFIER glm::u32vec2 bitfieldDeinterleave(glm::uint64 x)
{
glm::uint64 REG1(x);
glm::uint64 REG2(x >>= 1);
REG1 = REG1 & static_cast<glm::uint64>(0x5555555555555555ull);
REG2 = REG2 & static_cast<glm::uint64>(0x5555555555555555ull);
REG1 = ((REG1 >> 1) | REG1) & static_cast<glm::uint64>(0x3333333333333333ull);
REG2 = ((REG2 >> 1) | REG2) & static_cast<glm::uint64>(0x3333333333333333ull);
REG1 = ((REG1 >> 2) | REG1) & static_cast<glm::uint64>(0x0F0F0F0F0F0F0F0Full);
REG2 = ((REG2 >> 2) | REG2) & static_cast<glm::uint64>(0x0F0F0F0F0F0F0F0Full);
REG1 = ((REG1 >> 4) | REG1) & static_cast<glm::uint64>(0x00FF00FF00FF00FFull);
REG2 = ((REG2 >> 4) | REG2) & static_cast<glm::uint64>(0x00FF00FF00FF00FFull);
REG1 = ((REG1 >> 8) | REG1) & static_cast<glm::uint64>(0x0000FFFF0000FFFFull);
REG2 = ((REG2 >> 8) | REG2) & static_cast<glm::uint64>(0x0000FFFF0000FFFFull);
REG1 = ((REG1 >> 16) | REG1) & static_cast<glm::uint64>(0x00000000FFFFFFFFull);
REG2 = ((REG2 >> 16) | REG2) & static_cast<glm::uint64>(0x00000000FFFFFFFFull);
return glm::u32vec2(REG1, REG2);
}
GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z)
{
union sign8
{
int8 i;
uint8 u;
} sign_x, sign_y, sign_z;
union sign32
{
int32 i;
uint32 u;
} result;
sign_x.i = x;
sign_y.i = y;
sign_z.i = z;
result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u);
return result.i;
}
GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z)
{
return detail::bitfieldInterleave<uint8, uint32>(x, y, z);
}
GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(u8vec3 const& v)
{
return detail::bitfieldInterleave<uint8, uint32>(v.x, v.y, v.z);
}
GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z)
{
union sign16
{
int16 i;
uint16 u;
} sign_x, sign_y, sign_z;
union sign64
{
int64 i;
uint64 u;
} result;
sign_x.i = x;
sign_y.i = y;
sign_z.i = z;
result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u);
return result.i;
}
GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z)
{
return detail::bitfieldInterleave<uint32, uint64>(x, y, z);
}
GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(u16vec3 const& v)
{
return detail::bitfieldInterleave<uint32, uint64>(v.x, v.y, v.z);
}
GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y, int32 z)
{
union sign16
{
int32 i;
uint32 u;
} sign_x, sign_y, sign_z;
union sign64
{
int64 i;
uint64 u;
} result;
sign_x.i = x;
sign_y.i = y;
sign_z.i = z;
result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u);
return result.i;
}
GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z)
{
return detail::bitfieldInterleave<uint32, uint64>(x, y, z);
}
GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(u32vec3 const& v)
{
return detail::bitfieldInterleave<uint32, uint64>(v.x, v.y, v.z);
}
GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w)
{
union sign8
{
int8 i;
uint8 u;
} sign_x, sign_y, sign_z, sign_w;
union sign32
{
int32 i;
uint32 u;
} result;
sign_x.i = x;
sign_y.i = y;
sign_z.i = z;
sign_w.i = w;
result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u);
return result.i;
}
GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w)
{
return detail::bitfieldInterleave<uint8, uint32>(x, y, z, w);
}
GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(u8vec4 const& v)
{
return detail::bitfieldInterleave<uint8, uint32>(v.x, v.y, v.z, v.w);
}
GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w)
{
union sign16
{
int16 i;
uint16 u;
} sign_x, sign_y, sign_z, sign_w;
union sign64
{
int64 i;
uint64 u;
} result;
sign_x.i = x;
sign_y.i = y;
sign_z.i = z;
sign_w.i = w;
result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u);
return result.i;
}
GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w)
{
return detail::bitfieldInterleave<uint16, uint64>(x, y, z, w);
}
GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(u16vec4 const& v)
{
return detail::bitfieldInterleave<uint16, uint64>(v.x, v.y, v.z, v.w);
}
}//namespace glm
+56
View File
@@ -0,0 +1,56 @@
/// @ref gtc_color_space
/// @file glm/gtc/color_space.hpp
///
/// @see core (dependence)
/// @see gtc_color_space (dependence)
///
/// @defgroup gtc_color_space GLM_GTC_color_space
/// @ingroup gtc
///
/// Include <glm/gtc/color_space.hpp> to use the features of this extension.
///
/// Allow to perform bit operations on integer values
#pragma once
// Dependencies
#include "../detail/setup.hpp"
#include "../detail/qualifier.hpp"
#include "../exponential.hpp"
#include "../vec3.hpp"
#include "../vec4.hpp"
#include <limits>
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_color_space extension included")
#endif
namespace glm
{
/// @addtogroup gtc_color_space
/// @{
/// Convert a linear color to sRGB color using a standard gamma correction.
/// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> convertLinearToSRGB(vec<L, T, Q> const& ColorLinear);
/// Convert a linear color to sRGB color using a custom gamma correction.
/// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> convertLinearToSRGB(vec<L, T, Q> const& ColorLinear, T Gamma);
/// Convert a sRGB color to linear color using a standard gamma correction.
/// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> convertSRGBToLinear(vec<L, T, Q> const& ColorSRGB);
/// Convert a sRGB color to linear color using a custom gamma correction.
// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> convertSRGBToLinear(vec<L, T, Q> const& ColorSRGB, T Gamma);
/// @}
} //namespace glm
#include "color_space.inl"
+84
View File
@@ -0,0 +1,84 @@
/// @ref gtc_color_space
namespace glm{
namespace detail
{
template<length_t L, typename T, qualifier Q>
struct compute_rgbToSrgb
{
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& ColorRGB, T GammaCorrection)
{
vec<L, T, Q> const ClampedColor(clamp(ColorRGB, static_cast<T>(0), static_cast<T>(1)));
return mix(
pow(ClampedColor, vec<L, T, Q>(GammaCorrection)) * static_cast<T>(1.055) - static_cast<T>(0.055),
ClampedColor * static_cast<T>(12.92),
lessThan(ClampedColor, vec<L, T, Q>(static_cast<T>(0.0031308))));
}
};
template<typename T, qualifier Q>
struct compute_rgbToSrgb<4, T, Q>
{
GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<4, T, Q> const& ColorRGB, T GammaCorrection)
{
return vec<4, T, Q>(compute_rgbToSrgb<3, T, Q>::call(vec<3, T, Q>(ColorRGB), GammaCorrection), ColorRGB.w);
}
};
template<length_t L, typename T, qualifier Q>
struct compute_srgbToRgb
{
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& ColorSRGB, T Gamma)
{
return mix(
pow((ColorSRGB + static_cast<T>(0.055)) * static_cast<T>(0.94786729857819905213270142180095), vec<L, T, Q>(Gamma)),
ColorSRGB * static_cast<T>(0.07739938080495356037151702786378),
lessThanEqual(ColorSRGB, vec<L, T, Q>(static_cast<T>(0.04045))));
}
};
template<typename T, qualifier Q>
struct compute_srgbToRgb<4, T, Q>
{
GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<4, T, Q> const& ColorSRGB, T Gamma)
{
return vec<4, T, Q>(compute_srgbToRgb<3, T, Q>::call(vec<3, T, Q>(ColorSRGB), Gamma), ColorSRGB.w);
}
};
}//namespace detail
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> convertLinearToSRGB(vec<L, T, Q> const& ColorLinear)
{
return detail::compute_rgbToSrgb<L, T, Q>::call(ColorLinear, static_cast<T>(0.41666));
}
// Based on Ian Taylor http://chilliant.blogspot.fr/2012/08/srgb-approximations-for-hlsl.html
template<>
GLM_FUNC_QUALIFIER vec<3, float, lowp> convertLinearToSRGB(vec<3, float, lowp> const& ColorLinear)
{
vec<3, float, lowp> S1 = sqrt(ColorLinear);
vec<3, float, lowp> S2 = sqrt(S1);
vec<3, float, lowp> S3 = sqrt(S2);
return 0.662002687f * S1 + 0.684122060f * S2 - 0.323583601f * S3 - 0.0225411470f * ColorLinear;
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> convertLinearToSRGB(vec<L, T, Q> const& ColorLinear, T Gamma)
{
return detail::compute_rgbToSrgb<L, T, Q>::call(ColorLinear, static_cast<T>(1) / Gamma);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> convertSRGBToLinear(vec<L, T, Q> const& ColorSRGB)
{
return detail::compute_srgbToRgb<L, T, Q>::call(ColorSRGB, static_cast<T>(2.4));
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> convertSRGBToLinear(vec<L, T, Q> const& ColorSRGB, T Gamma)
{
return detail::compute_srgbToRgb<L, T, Q>::call(ColorSRGB, Gamma);
}
}//namespace glm
+170
View File
@@ -0,0 +1,170 @@
/// @ref gtc_constants
/// @file glm/gtc/constants.hpp
///
/// @see core (dependence)
///
/// @defgroup gtc_constants GLM_GTC_constants
/// @ingroup gtc
///
/// Include <glm/gtc/constants.hpp> to use the features of this extension.
///
/// Provide a list of constants and precomputed useful values.
#pragma once
// Dependencies
#include "../ext/scalar_constants.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_constants extension included")
#endif
namespace glm
{
/// @addtogroup gtc_constants
/// @{
/// Return 0.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType zero();
/// Return 1.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType one();
/// Return pi * 2.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType two_pi();
/// Return unit-circle circumference, or pi * 2.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType tau();
/// Return square root of pi.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType root_pi();
/// Return pi / 2.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType half_pi();
/// Return pi / 2 * 3.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType three_over_two_pi();
/// Return pi / 4.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType quarter_pi();
/// Return 1 / pi.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType one_over_pi();
/// Return 1 / (pi * 2).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType one_over_two_pi();
/// Return 2 / pi.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType two_over_pi();
/// Return 4 / pi.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType four_over_pi();
/// Return 2 / sqrt(pi).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType two_over_root_pi();
/// Return 1 / sqrt(2).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType one_over_root_two();
/// Return sqrt(pi / 2).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType root_half_pi();
/// Return sqrt(2 * pi).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType root_two_pi();
/// Return sqrt(ln(4)).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType root_ln_four();
/// Return e constant.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType e();
/// Return Euler's constant.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType euler();
/// Return sqrt(2).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType root_two();
/// Return sqrt(3).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType root_three();
/// Return sqrt(5).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType root_five();
/// Return ln(2).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType ln_two();
/// Return ln(10).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType ln_ten();
/// Return ln(ln(2)).
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType ln_ln_two();
/// Return 1 / 3.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType third();
/// Return 2 / 3.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType two_thirds();
/// Return the golden ratio constant.
/// @see gtc_constants
template<typename genType>
GLM_FUNC_DECL GLM_CONSTEXPR genType golden_ratio();
/// @}
} //namespace glm
#include "constants.inl"
+173
View File
@@ -0,0 +1,173 @@
/// @ref gtc_constants
namespace glm
{
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType zero()
{
return genType(0);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one()
{
return genType(1);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_pi()
{
return genType(6.28318530717958647692528676655900576);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType tau()
{
return two_pi<genType>();
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_pi()
{
return genType(1.772453850905516027);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType half_pi()
{
return genType(1.57079632679489661923132169163975144);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType three_over_two_pi()
{
return genType(4.71238898038468985769396507491925432);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType quarter_pi()
{
return genType(0.785398163397448309615660845819875721);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one_over_pi()
{
return genType(0.318309886183790671537767526745028724);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one_over_two_pi()
{
return genType(0.159154943091895335768883763372514362);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_over_pi()
{
return genType(0.636619772367581343075535053490057448);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType four_over_pi()
{
return genType(1.273239544735162686151070106980114898);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_over_root_pi()
{
return genType(1.12837916709551257389615890312154517);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one_over_root_two()
{
return genType(0.707106781186547524400844362104849039);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_half_pi()
{
return genType(1.253314137315500251);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_two_pi()
{
return genType(2.506628274631000502);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_ln_four()
{
return genType(1.17741002251547469);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType e()
{
return genType(2.71828182845904523536);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType euler()
{
return genType(0.577215664901532860606);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_two()
{
return genType(1.41421356237309504880168872420969808);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_three()
{
return genType(1.73205080756887729352744634150587236);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_five()
{
return genType(2.23606797749978969640917366873127623);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType ln_two()
{
return genType(0.693147180559945309417232121458176568);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType ln_ten()
{
return genType(2.30258509299404568401799145468436421);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType ln_ln_two()
{
return genType(-0.3665129205816643);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType third()
{
return genType(0.3333333333333333333333333333333333333333);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_thirds()
{
return genType(0.666666666666666666666666666666666666667);
}
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType golden_ratio()
{
return genType(1.61803398874989484820458683436563811);
}
} //namespace glm
+60
View File
@@ -0,0 +1,60 @@
/// @ref gtc_epsilon
/// @file glm/gtc/epsilon.hpp
///
/// @see core (dependence)
/// @see gtc_quaternion (dependence)
///
/// @defgroup gtc_epsilon GLM_GTC_epsilon
/// @ingroup gtc
///
/// Include <glm/gtc/epsilon.hpp> to use the features of this extension.
///
/// Comparison functions for a user defined epsilon values.
#pragma once
// Dependencies
#include "../detail/setup.hpp"
#include "../detail/qualifier.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_epsilon extension included")
#endif
namespace glm
{
/// @addtogroup gtc_epsilon
/// @{
/// Returns the component-wise comparison of |x - y| < epsilon.
/// True if this expression is satisfied.
///
/// @see gtc_epsilon
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, bool, Q> epsilonEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, T const& epsilon);
/// Returns the component-wise comparison of |x - y| < epsilon.
/// True if this expression is satisfied.
///
/// @see gtc_epsilon
template<typename genType>
GLM_FUNC_DECL bool epsilonEqual(genType const& x, genType const& y, genType const& epsilon);
/// Returns the component-wise comparison of |x - y| < epsilon.
/// True if this expression is not satisfied.
///
/// @see gtc_epsilon
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, bool, Q> epsilonNotEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, T const& epsilon);
/// Returns the component-wise comparison of |x - y| >= epsilon.
/// True if this expression is not satisfied.
///
/// @see gtc_epsilon
template<typename genType>
GLM_FUNC_DECL bool epsilonNotEqual(genType const& x, genType const& y, genType const& epsilon);
/// @}
}//namespace glm
#include "epsilon.inl"
+80
View File
@@ -0,0 +1,80 @@
/// @ref gtc_epsilon
// Dependency:
#include "../vector_relational.hpp"
#include "../common.hpp"
namespace glm
{
template<>
GLM_FUNC_QUALIFIER bool epsilonEqual
(
float const& x,
float const& y,
float const& epsilon
)
{
return abs(x - y) < epsilon;
}
template<>
GLM_FUNC_QUALIFIER bool epsilonEqual
(
double const& x,
double const& y,
double const& epsilon
)
{
return abs(x - y) < epsilon;
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, bool, Q> epsilonEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, T const& epsilon)
{
return lessThan(abs(x - y), vec<L, T, Q>(epsilon));
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, bool, Q> epsilonEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& epsilon)
{
return lessThan(abs(x - y), vec<L, T, Q>(epsilon));
}
template<>
GLM_FUNC_QUALIFIER bool epsilonNotEqual(float const& x, float const& y, float const& epsilon)
{
return abs(x - y) >= epsilon;
}
template<>
GLM_FUNC_QUALIFIER bool epsilonNotEqual(double const& x, double const& y, double const& epsilon)
{
return abs(x - y) >= epsilon;
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, bool, Q> epsilonNotEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, T const& epsilon)
{
return greaterThanEqual(abs(x - y), vec<L, T, Q>(epsilon));
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, bool, Q> epsilonNotEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& epsilon)
{
return greaterThanEqual(abs(x - y), vec<L, T, Q>(epsilon));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> epsilonEqual(qua<T, Q> const& x, qua<T, Q> const& y, T const& epsilon)
{
vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w);
return lessThan(abs(v), vec<4, T, Q>(epsilon));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> epsilonNotEqual(qua<T, Q> const& x, qua<T, Q> const& y, T const& epsilon)
{
vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w);
return greaterThanEqual(abs(v), vec<4, T, Q>(epsilon));
}
}//namespace glm
+43
View File
@@ -0,0 +1,43 @@
/// @ref gtc_integer
/// @file glm/gtc/integer.hpp
///
/// @see core (dependence)
/// @see gtc_integer (dependence)
///
/// @defgroup gtc_integer GLM_GTC_integer
/// @ingroup gtc
///
/// Include <glm/gtc/integer.hpp> to use the features of this extension.
///
/// @brief Allow to perform bit operations on integer values
#pragma once
// Dependencies
#include "../detail/setup.hpp"
#include "../detail/qualifier.hpp"
#include "../common.hpp"
#include "../integer.hpp"
#include "../exponential.hpp"
#include "../ext/scalar_common.hpp"
#include "../ext/vector_common.hpp"
#include <limits>
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_integer extension included")
#endif
namespace glm
{
/// @addtogroup gtc_integer
/// @{
/// Returns the log2 of x for integer values. Useful to compute mipmap count from the texture size.
/// @see gtc_integer
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> log2(vec<L, T, Q> const& v);
/// @}
} //namespace glm
#include "integer.inl"
+33
View File
@@ -0,0 +1,33 @@
/// @ref gtc_integer
namespace glm{
namespace detail
{
template<length_t L, typename T, qualifier Q, bool Aligned>
struct compute_log2<L, T, Q, false, Aligned>
{
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& v)
{
//Equivalent to return findMSB(vec); but save one function call in ASM with VC
//return findMSB(vec);
return vec<L, T, Q>(detail::compute_findMSB_vec<L, T, Q, sizeof(T) * 8>::call(v));
}
};
# if GLM_HAS_BITSCAN_WINDOWS
template<qualifier Q, bool Aligned>
struct compute_log2<4, int, Q, false, Aligned>
{
GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v)
{
vec<4, int, Q> Result;
_BitScanReverse(reinterpret_cast<unsigned long*>(&Result.x), v.x);
_BitScanReverse(reinterpret_cast<unsigned long*>(&Result.y), v.y);
_BitScanReverse(reinterpret_cast<unsigned long*>(&Result.z), v.z);
_BitScanReverse(reinterpret_cast<unsigned long*>(&Result.w), v.w);
return Result;
}
};
# endif//GLM_HAS_BITSCAN_WINDOWS
}//namespace detail
}//namespace glm
+60
View File
@@ -0,0 +1,60 @@
/// @ref gtc_matrix_access
/// @file glm/gtc/matrix_access.hpp
///
/// @see core (dependence)
///
/// @defgroup gtc_matrix_access GLM_GTC_matrix_access
/// @ingroup gtc
///
/// Include <glm/gtc/matrix_access.hpp> to use the features of this extension.
///
/// Defines functions to access rows or columns of a matrix easily.
#pragma once
// Dependency:
#include "../detail/setup.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_matrix_access extension included")
#endif
namespace glm
{
/// @addtogroup gtc_matrix_access
/// @{
/// Get a specific row of a matrix.
/// @see gtc_matrix_access
template<typename genType>
GLM_FUNC_DECL typename genType::row_type row(
genType const& m,
length_t index);
/// Set a specific row to a matrix.
/// @see gtc_matrix_access
template<typename genType>
GLM_FUNC_DECL genType row(
genType const& m,
length_t index,
typename genType::row_type const& x);
/// Get a specific column of a matrix.
/// @see gtc_matrix_access
template<typename genType>
GLM_FUNC_DECL typename genType::col_type column(
genType const& m,
length_t index);
/// Set a specific column to a matrix.
/// @see gtc_matrix_access
template<typename genType>
GLM_FUNC_DECL genType column(
genType const& m,
length_t index,
typename genType::col_type const& x);
/// @}
}//namespace glm
#include "matrix_access.inl"
+62
View File
@@ -0,0 +1,62 @@
/// @ref gtc_matrix_access
namespace glm
{
template<typename genType>
GLM_FUNC_QUALIFIER genType row
(
genType const& m,
length_t index,
typename genType::row_type const& x
)
{
assert(index >= 0 && index < m[0].length());
genType Result = m;
for(length_t i = 0; i < m.length(); ++i)
Result[i][index] = x[i];
return Result;
}
template<typename genType>
GLM_FUNC_QUALIFIER typename genType::row_type row
(
genType const& m,
length_t index
)
{
assert(index >= 0 && index < m[0].length());
typename genType::row_type Result(0);
for(length_t i = 0; i < m.length(); ++i)
Result[i] = m[i][index];
return Result;
}
template<typename genType>
GLM_FUNC_QUALIFIER genType column
(
genType const& m,
length_t index,
typename genType::col_type const& x
)
{
assert(index >= 0 && index < m.length());
genType Result = m;
Result[index] = x;
return Result;
}
template<typename genType>
GLM_FUNC_QUALIFIER typename genType::col_type column
(
genType const& m,
length_t index
)
{
assert(index >= 0 && index < m.length());
return m[index];
}
}//namespace glm
+433
View File
@@ -0,0 +1,433 @@
/// @ref gtc_matrix_integer
/// @file glm/gtc/matrix_integer.hpp
///
/// @see core (dependence)
///
/// @defgroup gtc_matrix_integer GLM_GTC_matrix_integer
/// @ingroup gtc
///
/// Include <glm/gtc/matrix_integer.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat2x2.hpp"
#include "../mat2x3.hpp"
#include "../mat2x4.hpp"
#include "../mat3x2.hpp"
#include "../mat3x3.hpp"
#include "../mat3x4.hpp"
#include "../mat4x2.hpp"
#include "../mat4x3.hpp"
#include "../mat4x4.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_matrix_integer extension included")
#endif
namespace glm
{
/// @addtogroup gtc_matrix_integer
/// @{
/// High-qualifier signed integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, int, highp> highp_imat2;
/// High-qualifier signed integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, int, highp> highp_imat3;
/// High-qualifier signed integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, int, highp> highp_imat4;
/// High-qualifier signed integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, int, highp> highp_imat2x2;
/// High-qualifier signed integer 2x3 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 3, int, highp> highp_imat2x3;
/// High-qualifier signed integer 2x4 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 4, int, highp> highp_imat2x4;
/// High-qualifier signed integer 3x2 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 2, int, highp> highp_imat3x2;
/// High-qualifier signed integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, int, highp> highp_imat3x3;
/// High-qualifier signed integer 3x4 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 4, int, highp> highp_imat3x4;
/// High-qualifier signed integer 4x2 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 2, int, highp> highp_imat4x2;
/// High-qualifier signed integer 4x3 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 3, int, highp> highp_imat4x3;
/// High-qualifier signed integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, int, highp> highp_imat4x4;
/// Medium-qualifier signed integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, int, mediump> mediump_imat2;
/// Medium-qualifier signed integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, int, mediump> mediump_imat3;
/// Medium-qualifier signed integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, int, mediump> mediump_imat4;
/// Medium-qualifier signed integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, int, mediump> mediump_imat2x2;
/// Medium-qualifier signed integer 2x3 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 3, int, mediump> mediump_imat2x3;
/// Medium-qualifier signed integer 2x4 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 4, int, mediump> mediump_imat2x4;
/// Medium-qualifier signed integer 3x2 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 2, int, mediump> mediump_imat3x2;
/// Medium-qualifier signed integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, int, mediump> mediump_imat3x3;
/// Medium-qualifier signed integer 3x4 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 4, int, mediump> mediump_imat3x4;
/// Medium-qualifier signed integer 4x2 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 2, int, mediump> mediump_imat4x2;
/// Medium-qualifier signed integer 4x3 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 3, int, mediump> mediump_imat4x3;
/// Medium-qualifier signed integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, int, mediump> mediump_imat4x4;
/// Low-qualifier signed integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, int, lowp> lowp_imat2;
/// Low-qualifier signed integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, int, lowp> lowp_imat3;
/// Low-qualifier signed integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, int, lowp> lowp_imat4;
/// Low-qualifier signed integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, int, lowp> lowp_imat2x2;
/// Low-qualifier signed integer 2x3 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 3, int, lowp> lowp_imat2x3;
/// Low-qualifier signed integer 2x4 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 4, int, lowp> lowp_imat2x4;
/// Low-qualifier signed integer 3x2 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 2, int, lowp> lowp_imat3x2;
/// Low-qualifier signed integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, int, lowp> lowp_imat3x3;
/// Low-qualifier signed integer 3x4 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 4, int, lowp> lowp_imat3x4;
/// Low-qualifier signed integer 4x2 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 2, int, lowp> lowp_imat4x2;
/// Low-qualifier signed integer 4x3 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 3, int, lowp> lowp_imat4x3;
/// Low-qualifier signed integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, int, lowp> lowp_imat4x4;
/// High-qualifier unsigned integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, uint, highp> highp_umat2;
/// High-qualifier unsigned integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, uint, highp> highp_umat3;
/// High-qualifier unsigned integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, uint, highp> highp_umat4;
/// High-qualifier unsigned integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, uint, highp> highp_umat2x2;
/// High-qualifier unsigned integer 2x3 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 3, uint, highp> highp_umat2x3;
/// High-qualifier unsigned integer 2x4 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 4, uint, highp> highp_umat2x4;
/// High-qualifier unsigned integer 3x2 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 2, uint, highp> highp_umat3x2;
/// High-qualifier unsigned integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, uint, highp> highp_umat3x3;
/// High-qualifier unsigned integer 3x4 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 4, uint, highp> highp_umat3x4;
/// High-qualifier unsigned integer 4x2 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 2, uint, highp> highp_umat4x2;
/// High-qualifier unsigned integer 4x3 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 3, uint, highp> highp_umat4x3;
/// High-qualifier unsigned integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, uint, highp> highp_umat4x4;
/// Medium-qualifier unsigned integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, uint, mediump> mediump_umat2;
/// Medium-qualifier unsigned integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, uint, mediump> mediump_umat3;
/// Medium-qualifier unsigned integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, uint, mediump> mediump_umat4;
/// Medium-qualifier unsigned integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, uint, mediump> mediump_umat2x2;
/// Medium-qualifier unsigned integer 2x3 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 3, uint, mediump> mediump_umat2x3;
/// Medium-qualifier unsigned integer 2x4 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 4, uint, mediump> mediump_umat2x4;
/// Medium-qualifier unsigned integer 3x2 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 2, uint, mediump> mediump_umat3x2;
/// Medium-qualifier unsigned integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, uint, mediump> mediump_umat3x3;
/// Medium-qualifier unsigned integer 3x4 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 4, uint, mediump> mediump_umat3x4;
/// Medium-qualifier unsigned integer 4x2 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 2, uint, mediump> mediump_umat4x2;
/// Medium-qualifier unsigned integer 4x3 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 3, uint, mediump> mediump_umat4x3;
/// Medium-qualifier unsigned integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, uint, mediump> mediump_umat4x4;
/// Low-qualifier unsigned integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, uint, lowp> lowp_umat2;
/// Low-qualifier unsigned integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, uint, lowp> lowp_umat3;
/// Low-qualifier unsigned integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, uint, lowp> lowp_umat4;
/// Low-qualifier unsigned integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, uint, lowp> lowp_umat2x2;
/// Low-qualifier unsigned integer 2x3 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 3, uint, lowp> lowp_umat2x3;
/// Low-qualifier unsigned integer 2x4 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 4, uint, lowp> lowp_umat2x4;
/// Low-qualifier unsigned integer 3x2 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 2, uint, lowp> lowp_umat3x2;
/// Low-qualifier unsigned integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, uint, lowp> lowp_umat3x3;
/// Low-qualifier unsigned integer 3x4 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 4, uint, lowp> lowp_umat3x4;
/// Low-qualifier unsigned integer 4x2 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 2, uint, lowp> lowp_umat4x2;
/// Low-qualifier unsigned integer 4x3 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 3, uint, lowp> lowp_umat4x3;
/// Low-qualifier unsigned integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, uint, lowp> lowp_umat4x4;
/// Signed integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, int, defaultp> imat2;
/// Signed integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, int, defaultp> imat3;
/// Signed integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, int, defaultp> imat4;
/// Signed integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, int, defaultp> imat2x2;
/// Signed integer 2x3 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 3, int, defaultp> imat2x3;
/// Signed integer 2x4 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 4, int, defaultp> imat2x4;
/// Signed integer 3x2 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 2, int, defaultp> imat3x2;
/// Signed integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, int, defaultp> imat3x3;
/// Signed integer 3x4 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 4, int, defaultp> imat3x4;
/// Signed integer 4x2 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 2, int, defaultp> imat4x2;
/// Signed integer 4x3 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 3, int, defaultp> imat4x3;
/// Signed integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, int, defaultp> imat4x4;
/// Unsigned integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, uint, defaultp> umat2;
/// Unsigned integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, uint, defaultp> umat3;
/// Unsigned integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, uint, defaultp> umat4;
/// Unsigned integer 2x2 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 2, uint, defaultp> umat2x2;
/// Unsigned integer 2x3 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 3, uint, defaultp> umat2x3;
/// Unsigned integer 2x4 matrix.
/// @see gtc_matrix_integer
typedef mat<2, 4, uint, defaultp> umat2x4;
/// Unsigned integer 3x2 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 2, uint, defaultp> umat3x2;
/// Unsigned integer 3x3 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 3, uint, defaultp> umat3x3;
/// Unsigned integer 3x4 matrix.
/// @see gtc_matrix_integer
typedef mat<3, 4, uint, defaultp> umat3x4;
/// Unsigned integer 4x2 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 2, uint, defaultp> umat4x2;
/// Unsigned integer 4x3 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 3, uint, defaultp> umat4x3;
/// Unsigned integer 4x4 matrix.
/// @see gtc_matrix_integer
typedef mat<4, 4, uint, defaultp> umat4x4;
/// @}
}//namespace glm
+50
View File
@@ -0,0 +1,50 @@
/// @ref gtc_matrix_inverse
/// @file glm/gtc/matrix_inverse.hpp
///
/// @see core (dependence)
///
/// @defgroup gtc_matrix_inverse GLM_GTC_matrix_inverse
/// @ingroup gtc
///
/// Include <glm/gtc/matrix_inverse.hpp> to use the features of this extension.
///
/// Defines additional matrix inverting functions.
#pragma once
// Dependencies
#include "../detail/setup.hpp"
#include "../matrix.hpp"
#include "../mat2x2.hpp"
#include "../mat3x3.hpp"
#include "../mat4x4.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_matrix_inverse extension included")
#endif
namespace glm
{
/// @addtogroup gtc_matrix_inverse
/// @{
/// Fast matrix inverse for affine matrix.
///
/// @param m Input matrix to invert.
/// @tparam genType Squared floating-point matrix: half, float or double. Inverse of matrix based of half-qualifier floating point value is highly inaccurate.
/// @see gtc_matrix_inverse
template<typename genType>
GLM_FUNC_DECL genType affineInverse(genType const& m);
/// Compute the inverse transpose of a matrix.
///
/// @param m Input matrix to invert transpose.
/// @tparam genType Squared floating-point matrix: half, float or double. Inverse of matrix based of half-qualifier floating point value is highly inaccurate.
/// @see gtc_matrix_inverse
template<typename genType>
GLM_FUNC_DECL genType inverseTranspose(genType const& m);
/// @}
}//namespace glm
#include "matrix_inverse.inl"
+118
View File
@@ -0,0 +1,118 @@
/// @ref gtc_matrix_inverse
namespace glm
{
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> affineInverse(mat<3, 3, T, Q> const& m)
{
mat<2, 2, T, Q> const Inv(inverse(mat<2, 2, T, Q>(m)));
return mat<3, 3, T, Q>(
vec<3, T, Q>(Inv[0], static_cast<T>(0)),
vec<3, T, Q>(Inv[1], static_cast<T>(0)),
vec<3, T, Q>(-Inv * vec<2, T, Q>(m[2]), static_cast<T>(1)));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> affineInverse(mat<4, 4, T, Q> const& m)
{
mat<3, 3, T, Q> const Inv(inverse(mat<3, 3, T, Q>(m)));
return mat<4, 4, T, Q>(
vec<4, T, Q>(Inv[0], static_cast<T>(0)),
vec<4, T, Q>(Inv[1], static_cast<T>(0)),
vec<4, T, Q>(Inv[2], static_cast<T>(0)),
vec<4, T, Q>(-Inv * vec<3, T, Q>(m[3]), static_cast<T>(1)));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<2, 2, T, Q> inverseTranspose(mat<2, 2, T, Q> const& m)
{
T Determinant = m[0][0] * m[1][1] - m[1][0] * m[0][1];
mat<2, 2, T, Q> Inverse(
+ m[1][1] / Determinant,
- m[0][1] / Determinant,
- m[1][0] / Determinant,
+ m[0][0] / Determinant);
return Inverse;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> inverseTranspose(mat<3, 3, T, Q> const& m)
{
T Determinant =
+ m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1])
- m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0])
+ m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
mat<3, 3, T, Q> Inverse;
Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
Inverse[0][1] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]);
Inverse[0][2] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]);
Inverse[1][0] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]);
Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]);
Inverse[1][2] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]);
Inverse[2][0] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
Inverse[2][1] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]);
Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]);
Inverse /= Determinant;
return Inverse;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> inverseTranspose(mat<4, 4, T, Q> const& m)
{
T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
T SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
T SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
T SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
T SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
T SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
T SubFactor11 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
T SubFactor12 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
T SubFactor13 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
T SubFactor14 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
T SubFactor15 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
T SubFactor16 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
T SubFactor17 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
mat<4, 4, T, Q> Inverse;
Inverse[0][0] = + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02);
Inverse[0][1] = - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04);
Inverse[0][2] = + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05);
Inverse[0][3] = - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05);
Inverse[1][0] = - (m[0][1] * SubFactor00 - m[0][2] * SubFactor01 + m[0][3] * SubFactor02);
Inverse[1][1] = + (m[0][0] * SubFactor00 - m[0][2] * SubFactor03 + m[0][3] * SubFactor04);
Inverse[1][2] = - (m[0][0] * SubFactor01 - m[0][1] * SubFactor03 + m[0][3] * SubFactor05);
Inverse[1][3] = + (m[0][0] * SubFactor02 - m[0][1] * SubFactor04 + m[0][2] * SubFactor05);
Inverse[2][0] = + (m[0][1] * SubFactor06 - m[0][2] * SubFactor07 + m[0][3] * SubFactor08);
Inverse[2][1] = - (m[0][0] * SubFactor06 - m[0][2] * SubFactor09 + m[0][3] * SubFactor10);
Inverse[2][2] = + (m[0][0] * SubFactor07 - m[0][1] * SubFactor09 + m[0][3] * SubFactor11);
Inverse[2][3] = - (m[0][0] * SubFactor08 - m[0][1] * SubFactor10 + m[0][2] * SubFactor11);
Inverse[3][0] = - (m[0][1] * SubFactor12 - m[0][2] * SubFactor13 + m[0][3] * SubFactor14);
Inverse[3][1] = + (m[0][0] * SubFactor12 - m[0][2] * SubFactor15 + m[0][3] * SubFactor16);
Inverse[3][2] = - (m[0][0] * SubFactor13 - m[0][1] * SubFactor15 + m[0][3] * SubFactor17);
Inverse[3][3] = + (m[0][0] * SubFactor14 - m[0][1] * SubFactor16 + m[0][2] * SubFactor17);
T Determinant =
+ m[0][0] * Inverse[0][0]
+ m[0][1] * Inverse[0][1]
+ m[0][2] * Inverse[0][2]
+ m[0][3] * Inverse[0][3];
Inverse /= Determinant;
return Inverse;
}
}//namespace glm
+36
View File
@@ -0,0 +1,36 @@
/// @ref gtc_matrix_transform
/// @file glm/gtc/matrix_transform.hpp
///
/// @see core (dependence)
/// @see gtx_transform
/// @see gtx_transform2
///
/// @defgroup gtc_matrix_transform GLM_GTC_matrix_transform
/// @ingroup gtc
///
/// Include <glm/gtc/matrix_transform.hpp> to use the features of this extension.
///
/// Defines functions that generate common transformation matrices.
///
/// The matrices generated by this extension use standard OpenGL fixed-function
/// conventions. For example, the lookAt function generates a transform from world
/// space into the specific eye space that the projective matrix functions
/// (perspective, ortho, etc) are designed to expect. The OpenGL compatibility
/// specifications defines the particular layout of this eye space.
#pragma once
// Dependencies
#include "../mat4x4.hpp"
#include "../vec2.hpp"
#include "../vec3.hpp"
#include "../vec4.hpp"
#include "../ext/matrix_projection.hpp"
#include "../ext/matrix_clip_space.hpp"
#include "../ext/matrix_transform.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_matrix_transform extension included")
#endif
#include "matrix_transform.inl"
+3
View File
@@ -0,0 +1,3 @@
#include "../geometric.hpp"
#include "../trigonometric.hpp"
#include "../matrix.hpp"
+61
View File
@@ -0,0 +1,61 @@
/// @ref gtc_noise
/// @file glm/gtc/noise.hpp
///
/// @see core (dependence)
///
/// @defgroup gtc_noise GLM_GTC_noise
/// @ingroup gtc
///
/// Include <glm/gtc/noise.hpp> to use the features of this extension.
///
/// Defines 2D, 3D and 4D procedural noise functions
/// Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise":
/// https://github.com/ashima/webgl-noise
/// Following Stefan Gustavson's paper "Simplex noise demystified":
/// http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
#pragma once
// Dependencies
#include "../detail/setup.hpp"
#include "../detail/qualifier.hpp"
#include "../detail/_noise.hpp"
#include "../geometric.hpp"
#include "../common.hpp"
#include "../vector_relational.hpp"
#include "../vec2.hpp"
#include "../vec3.hpp"
#include "../vec4.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_noise extension included")
#endif
namespace glm
{
/// @addtogroup gtc_noise
/// @{
/// Classic perlin noise.
/// @see gtc_noise
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL T perlin(
vec<L, T, Q> const& p);
/// Periodic perlin noise.
/// @see gtc_noise
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL T perlin(
vec<L, T, Q> const& p,
vec<L, T, Q> const& rep);
/// Simplex noise.
/// @see gtc_noise
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL T simplex(
vec<L, T, Q> const& p);
/// @}
}//namespace glm
#include "noise.inl"
+807
View File
@@ -0,0 +1,807 @@
/// @ref gtc_noise
///
// Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise":
// https://github.com/stegu/webgl-noise
// Following Stefan Gustavson's paper "Simplex noise demystified":
// https://itn-web.it.liu.se/~stegu76/simplexnoise/simplexnoise.pdf
namespace glm{
namespace detail
{
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, T, Q> grad4(T const& j, vec<4, T, Q> const& ip)
{
vec<3, T, Q> pXYZ = floor(fract(vec<3, T, Q>(j) * vec<3, T, Q>(ip)) * T(7)) * ip[2] - T(1);
T pW = static_cast<T>(1.5) - dot(abs(pXYZ), vec<3, T, Q>(1));
vec<4, T, Q> s = vec<4, T, Q>(lessThan(vec<4, T, Q>(pXYZ, pW), vec<4, T, Q>(0.0)));
pXYZ = pXYZ + (vec<3, T, Q>(s) * T(2) - T(1)) * s.w;
return vec<4, T, Q>(pXYZ, pW);
}
}//namespace detail
// Classic Perlin noise
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T perlin(vec<2, T, Q> const& Position)
{
vec<4, T, Q> Pi = glm::floor(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) + vec<4, T, Q>(0.0, 0.0, 1.0, 1.0);
vec<4, T, Q> Pf = glm::fract(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) - vec<4, T, Q>(0.0, 0.0, 1.0, 1.0);
Pi = mod(Pi, vec<4, T, Q>(289)); // To avoid truncation effects in permutation
vec<4, T, Q> ix(Pi.x, Pi.z, Pi.x, Pi.z);
vec<4, T, Q> iy(Pi.y, Pi.y, Pi.w, Pi.w);
vec<4, T, Q> fx(Pf.x, Pf.z, Pf.x, Pf.z);
vec<4, T, Q> fy(Pf.y, Pf.y, Pf.w, Pf.w);
vec<4, T, Q> i = detail::permute(detail::permute(ix) + iy);
vec<4, T, Q> gx = static_cast<T>(2) * glm::fract(i / T(41)) - T(1);
vec<4, T, Q> gy = glm::abs(gx) - T(0.5);
vec<4, T, Q> tx = glm::floor(gx + T(0.5));
gx = gx - tx;
vec<2, T, Q> g00(gx.x, gy.x);
vec<2, T, Q> g10(gx.y, gy.y);
vec<2, T, Q> g01(gx.z, gy.z);
vec<2, T, Q> g11(gx.w, gy.w);
vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
g00 *= norm.x;
g01 *= norm.y;
g10 *= norm.z;
g11 *= norm.w;
T n00 = dot(g00, vec<2, T, Q>(fx.x, fy.x));
T n10 = dot(g10, vec<2, T, Q>(fx.y, fy.y));
T n01 = dot(g01, vec<2, T, Q>(fx.z, fy.z));
T n11 = dot(g11, vec<2, T, Q>(fx.w, fy.w));
vec<2, T, Q> fade_xy = detail::fade(vec<2, T, Q>(Pf.x, Pf.y));
vec<2, T, Q> n_x = mix(vec<2, T, Q>(n00, n01), vec<2, T, Q>(n10, n11), fade_xy.x);
T n_xy = mix(n_x.x, n_x.y, fade_xy.y);
return T(2.3) * n_xy;
}
// Classic Perlin noise
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T perlin(vec<3, T, Q> const& Position)
{
vec<3, T, Q> Pi0 = floor(Position); // Integer part for indexing
vec<3, T, Q> Pi1 = Pi0 + T(1); // Integer part + 1
Pi0 = detail::mod289(Pi0);
Pi1 = detail::mod289(Pi1);
vec<3, T, Q> Pf0 = fract(Position); // Fractional part for interpolation
vec<3, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0
vec<4, T, Q> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
vec<4, T, Q> iy = vec<4, T, Q>(vec<2, T, Q>(Pi0.y), vec<2, T, Q>(Pi1.y));
vec<4, T, Q> iz0(Pi0.z);
vec<4, T, Q> iz1(Pi1.z);
vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy);
vec<4, T, Q> ixy0 = detail::permute(ixy + iz0);
vec<4, T, Q> ixy1 = detail::permute(ixy + iz1);
vec<4, T, Q> gx0 = ixy0 * T(1.0 / 7.0);
vec<4, T, Q> gy0 = fract(floor(gx0) * T(1.0 / 7.0)) - T(0.5);
gx0 = fract(gx0);
vec<4, T, Q> gz0 = vec<4, T, Q>(0.5) - abs(gx0) - abs(gy0);
vec<4, T, Q> sz0 = step(gz0, vec<4, T, Q>(0.0));
gx0 -= sz0 * (step(T(0), gx0) - T(0.5));
gy0 -= sz0 * (step(T(0), gy0) - T(0.5));
vec<4, T, Q> gx1 = ixy1 * T(1.0 / 7.0);
vec<4, T, Q> gy1 = fract(floor(gx1) * T(1.0 / 7.0)) - T(0.5);
gx1 = fract(gx1);
vec<4, T, Q> gz1 = vec<4, T, Q>(0.5) - abs(gx1) - abs(gy1);
vec<4, T, Q> sz1 = step(gz1, vec<4, T, Q>(0.0));
gx1 -= sz1 * (step(T(0), gx1) - T(0.5));
gy1 -= sz1 * (step(T(0), gy1) - T(0.5));
vec<3, T, Q> g000(gx0.x, gy0.x, gz0.x);
vec<3, T, Q> g100(gx0.y, gy0.y, gz0.y);
vec<3, T, Q> g010(gx0.z, gy0.z, gz0.z);
vec<3, T, Q> g110(gx0.w, gy0.w, gz0.w);
vec<3, T, Q> g001(gx1.x, gy1.x, gz1.x);
vec<3, T, Q> g101(gx1.y, gy1.y, gz1.y);
vec<3, T, Q> g011(gx1.z, gy1.z, gz1.z);
vec<3, T, Q> g111(gx1.w, gy1.w, gz1.w);
vec<4, T, Q> norm0 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
g000 *= norm0.x;
g010 *= norm0.y;
g100 *= norm0.z;
g110 *= norm0.w;
vec<4, T, Q> norm1 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
g001 *= norm1.x;
g011 *= norm1.y;
g101 *= norm1.z;
g111 *= norm1.w;
T n000 = dot(g000, Pf0);
T n100 = dot(g100, vec<3, T, Q>(Pf1.x, Pf0.y, Pf0.z));
T n010 = dot(g010, vec<3, T, Q>(Pf0.x, Pf1.y, Pf0.z));
T n110 = dot(g110, vec<3, T, Q>(Pf1.x, Pf1.y, Pf0.z));
T n001 = dot(g001, vec<3, T, Q>(Pf0.x, Pf0.y, Pf1.z));
T n101 = dot(g101, vec<3, T, Q>(Pf1.x, Pf0.y, Pf1.z));
T n011 = dot(g011, vec<3, T, Q>(Pf0.x, Pf1.y, Pf1.z));
T n111 = dot(g111, Pf1);
vec<3, T, Q> fade_xyz = detail::fade(Pf0);
vec<4, T, Q> n_z = mix(vec<4, T, Q>(n000, n100, n010, n110), vec<4, T, Q>(n001, n101, n011, n111), fade_xyz.z);
vec<2, T, Q> n_yz = mix(vec<2, T, Q>(n_z.x, n_z.y), vec<2, T, Q>(n_z.z, n_z.w), fade_xyz.y);
T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
return T(2.2) * n_xyz;
}
/*
// Classic Perlin noise
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T perlin(vec<3, T, Q> const& P)
{
vec<3, T, Q> Pi0 = floor(P); // Integer part for indexing
vec<3, T, Q> Pi1 = Pi0 + T(1); // Integer part + 1
Pi0 = mod(Pi0, T(289));
Pi1 = mod(Pi1, T(289));
vec<3, T, Q> Pf0 = fract(P); // Fractional part for interpolation
vec<3, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0
vec<4, T, Q> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
vec<4, T, Q> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
vec<4, T, Q> iz0(Pi0.z);
vec<4, T, Q> iz1(Pi1.z);
vec<4, T, Q> ixy = permute(permute(ix) + iy);
vec<4, T, Q> ixy0 = permute(ixy + iz0);
vec<4, T, Q> ixy1 = permute(ixy + iz1);
vec<4, T, Q> gx0 = ixy0 / T(7);
vec<4, T, Q> gy0 = fract(floor(gx0) / T(7)) - T(0.5);
gx0 = fract(gx0);
vec<4, T, Q> gz0 = vec<4, T, Q>(0.5) - abs(gx0) - abs(gy0);
vec<4, T, Q> sz0 = step(gz0, vec<4, T, Q>(0.0));
gx0 -= sz0 * (step(0.0, gx0) - T(0.5));
gy0 -= sz0 * (step(0.0, gy0) - T(0.5));
vec<4, T, Q> gx1 = ixy1 / T(7);
vec<4, T, Q> gy1 = fract(floor(gx1) / T(7)) - T(0.5);
gx1 = fract(gx1);
vec<4, T, Q> gz1 = vec<4, T, Q>(0.5) - abs(gx1) - abs(gy1);
vec<4, T, Q> sz1 = step(gz1, vec<4, T, Q>(0.0));
gx1 -= sz1 * (step(T(0), gx1) - T(0.5));
gy1 -= sz1 * (step(T(0), gy1) - T(0.5));
vec<3, T, Q> g000(gx0.x, gy0.x, gz0.x);
vec<3, T, Q> g100(gx0.y, gy0.y, gz0.y);
vec<3, T, Q> g010(gx0.z, gy0.z, gz0.z);
vec<3, T, Q> g110(gx0.w, gy0.w, gz0.w);
vec<3, T, Q> g001(gx1.x, gy1.x, gz1.x);
vec<3, T, Q> g101(gx1.y, gy1.y, gz1.y);
vec<3, T, Q> g011(gx1.z, gy1.z, gz1.z);
vec<3, T, Q> g111(gx1.w, gy1.w, gz1.w);
vec<4, T, Q> norm0 = taylorInvSqrt(vec<4, T, Q>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
g000 *= norm0.x;
g010 *= norm0.y;
g100 *= norm0.z;
g110 *= norm0.w;
vec<4, T, Q> norm1 = taylorInvSqrt(vec<4, T, Q>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
g001 *= norm1.x;
g011 *= norm1.y;
g101 *= norm1.z;
g111 *= norm1.w;
T n000 = dot(g000, Pf0);
T n100 = dot(g100, vec<3, T, Q>(Pf1.x, Pf0.y, Pf0.z));
T n010 = dot(g010, vec<3, T, Q>(Pf0.x, Pf1.y, Pf0.z));
T n110 = dot(g110, vec<3, T, Q>(Pf1.x, Pf1.y, Pf0.z));
T n001 = dot(g001, vec<3, T, Q>(Pf0.x, Pf0.y, Pf1.z));
T n101 = dot(g101, vec<3, T, Q>(Pf1.x, Pf0.y, Pf1.z));
T n011 = dot(g011, vec<3, T, Q>(Pf0.x, Pf1.y, Pf1.z));
T n111 = dot(g111, Pf1);
vec<3, T, Q> fade_xyz = fade(Pf0);
vec<4, T, Q> n_z = mix(vec<4, T, Q>(n000, n100, n010, n110), vec<4, T, Q>(n001, n101, n011, n111), fade_xyz.z);
vec<2, T, Q> n_yz = mix(
vec<2, T, Q>(n_z.x, n_z.y),
vec<2, T, Q>(n_z.z, n_z.w), fade_xyz.y);
T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
return T(2.2) * n_xyz;
}
*/
// Classic Perlin noise
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T perlin(vec<4, T, Q> const& Position)
{
vec<4, T, Q> Pi0 = floor(Position); // Integer part for indexing
vec<4, T, Q> Pi1 = Pi0 + T(1); // Integer part + 1
Pi0 = mod(Pi0, vec<4, T, Q>(289));
Pi1 = mod(Pi1, vec<4, T, Q>(289));
vec<4, T, Q> Pf0 = fract(Position); // Fractional part for interpolation
vec<4, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0
vec<4, T, Q> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
vec<4, T, Q> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
vec<4, T, Q> iz0(Pi0.z);
vec<4, T, Q> iz1(Pi1.z);
vec<4, T, Q> iw0(Pi0.w);
vec<4, T, Q> iw1(Pi1.w);
vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy);
vec<4, T, Q> ixy0 = detail::permute(ixy + iz0);
vec<4, T, Q> ixy1 = detail::permute(ixy + iz1);
vec<4, T, Q> ixy00 = detail::permute(ixy0 + iw0);
vec<4, T, Q> ixy01 = detail::permute(ixy0 + iw1);
vec<4, T, Q> ixy10 = detail::permute(ixy1 + iw0);
vec<4, T, Q> ixy11 = detail::permute(ixy1 + iw1);
vec<4, T, Q> gx00 = ixy00 / T(7);
vec<4, T, Q> gy00 = floor(gx00) / T(7);
vec<4, T, Q> gz00 = floor(gy00) / T(6);
gx00 = fract(gx00) - T(0.5);
gy00 = fract(gy00) - T(0.5);
gz00 = fract(gz00) - T(0.5);
vec<4, T, Q> gw00 = vec<4, T, Q>(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
vec<4, T, Q> sw00 = step(gw00, vec<4, T, Q>(0.0));
gx00 -= sw00 * (step(T(0), gx00) - T(0.5));
gy00 -= sw00 * (step(T(0), gy00) - T(0.5));
vec<4, T, Q> gx01 = ixy01 / T(7);
vec<4, T, Q> gy01 = floor(gx01) / T(7);
vec<4, T, Q> gz01 = floor(gy01) / T(6);
gx01 = fract(gx01) - T(0.5);
gy01 = fract(gy01) - T(0.5);
gz01 = fract(gz01) - T(0.5);
vec<4, T, Q> gw01 = vec<4, T, Q>(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
vec<4, T, Q> sw01 = step(gw01, vec<4, T, Q>(0.0));
gx01 -= sw01 * (step(T(0), gx01) - T(0.5));
gy01 -= sw01 * (step(T(0), gy01) - T(0.5));
vec<4, T, Q> gx10 = ixy10 / T(7);
vec<4, T, Q> gy10 = floor(gx10) / T(7);
vec<4, T, Q> gz10 = floor(gy10) / T(6);
gx10 = fract(gx10) - T(0.5);
gy10 = fract(gy10) - T(0.5);
gz10 = fract(gz10) - T(0.5);
vec<4, T, Q> gw10 = vec<4, T, Q>(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
vec<4, T, Q> sw10 = step(gw10, vec<4, T, Q>(0));
gx10 -= sw10 * (step(T(0), gx10) - T(0.5));
gy10 -= sw10 * (step(T(0), gy10) - T(0.5));
vec<4, T, Q> gx11 = ixy11 / T(7);
vec<4, T, Q> gy11 = floor(gx11) / T(7);
vec<4, T, Q> gz11 = floor(gy11) / T(6);
gx11 = fract(gx11) - T(0.5);
gy11 = fract(gy11) - T(0.5);
gz11 = fract(gz11) - T(0.5);
vec<4, T, Q> gw11 = vec<4, T, Q>(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
vec<4, T, Q> sw11 = step(gw11, vec<4, T, Q>(0.0));
gx11 -= sw11 * (step(T(0), gx11) - T(0.5));
gy11 -= sw11 * (step(T(0), gy11) - T(0.5));
vec<4, T, Q> g0000(gx00.x, gy00.x, gz00.x, gw00.x);
vec<4, T, Q> g1000(gx00.y, gy00.y, gz00.y, gw00.y);
vec<4, T, Q> g0100(gx00.z, gy00.z, gz00.z, gw00.z);
vec<4, T, Q> g1100(gx00.w, gy00.w, gz00.w, gw00.w);
vec<4, T, Q> g0010(gx10.x, gy10.x, gz10.x, gw10.x);
vec<4, T, Q> g1010(gx10.y, gy10.y, gz10.y, gw10.y);
vec<4, T, Q> g0110(gx10.z, gy10.z, gz10.z, gw10.z);
vec<4, T, Q> g1110(gx10.w, gy10.w, gz10.w, gw10.w);
vec<4, T, Q> g0001(gx01.x, gy01.x, gz01.x, gw01.x);
vec<4, T, Q> g1001(gx01.y, gy01.y, gz01.y, gw01.y);
vec<4, T, Q> g0101(gx01.z, gy01.z, gz01.z, gw01.z);
vec<4, T, Q> g1101(gx01.w, gy01.w, gz01.w, gw01.w);
vec<4, T, Q> g0011(gx11.x, gy11.x, gz11.x, gw11.x);
vec<4, T, Q> g1011(gx11.y, gy11.y, gz11.y, gw11.y);
vec<4, T, Q> g0111(gx11.z, gy11.z, gz11.z, gw11.z);
vec<4, T, Q> g1111(gx11.w, gy11.w, gz11.w, gw11.w);
vec<4, T, Q> norm00 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
g0000 *= norm00.x;
g0100 *= norm00.y;
g1000 *= norm00.z;
g1100 *= norm00.w;
vec<4, T, Q> norm01 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
g0001 *= norm01.x;
g0101 *= norm01.y;
g1001 *= norm01.z;
g1101 *= norm01.w;
vec<4, T, Q> norm10 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
g0010 *= norm10.x;
g0110 *= norm10.y;
g1010 *= norm10.z;
g1110 *= norm10.w;
vec<4, T, Q> norm11 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
g0011 *= norm11.x;
g0111 *= norm11.y;
g1011 *= norm11.z;
g1111 *= norm11.w;
T n0000 = dot(g0000, Pf0);
T n1000 = dot(g1000, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf0.w));
T n0100 = dot(g0100, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf0.w));
T n1100 = dot(g1100, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf0.w));
T n0010 = dot(g0010, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf0.w));
T n1010 = dot(g1010, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
T n0110 = dot(g0110, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf0.w));
T n1110 = dot(g1110, vec<4, T, Q>(Pf1.x, Pf1.y, Pf1.z, Pf0.w));
T n0001 = dot(g0001, vec<4, T, Q>(Pf0.x, Pf0.y, Pf0.z, Pf1.w));
T n1001 = dot(g1001, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf1.w));
T n0101 = dot(g0101, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
T n1101 = dot(g1101, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf1.w));
T n0011 = dot(g0011, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf1.w));
T n1011 = dot(g1011, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf1.w));
T n0111 = dot(g0111, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf1.w));
T n1111 = dot(g1111, Pf1);
vec<4, T, Q> fade_xyzw = detail::fade(Pf0);
vec<4, T, Q> n_0w = mix(vec<4, T, Q>(n0000, n1000, n0100, n1100), vec<4, T, Q>(n0001, n1001, n0101, n1101), fade_xyzw.w);
vec<4, T, Q> n_1w = mix(vec<4, T, Q>(n0010, n1010, n0110, n1110), vec<4, T, Q>(n0011, n1011, n0111, n1111), fade_xyzw.w);
vec<4, T, Q> n_zw = mix(n_0w, n_1w, fade_xyzw.z);
vec<2, T, Q> n_yzw = mix(vec<2, T, Q>(n_zw.x, n_zw.y), vec<2, T, Q>(n_zw.z, n_zw.w), fade_xyzw.y);
T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
return T(2.2) * n_xyzw;
}
// Classic Perlin noise, periodic variant
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T perlin(vec<2, T, Q> const& Position, vec<2, T, Q> const& rep)
{
vec<4, T, Q> Pi = floor(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) + vec<4, T, Q>(0.0, 0.0, 1.0, 1.0);
vec<4, T, Q> Pf = fract(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) - vec<4, T, Q>(0.0, 0.0, 1.0, 1.0);
Pi = mod(Pi, vec<4, T, Q>(rep.x, rep.y, rep.x, rep.y)); // To create noise with explicit period
Pi = mod(Pi, vec<4, T, Q>(289)); // To avoid truncation effects in permutation
vec<4, T, Q> ix(Pi.x, Pi.z, Pi.x, Pi.z);
vec<4, T, Q> iy(Pi.y, Pi.y, Pi.w, Pi.w);
vec<4, T, Q> fx(Pf.x, Pf.z, Pf.x, Pf.z);
vec<4, T, Q> fy(Pf.y, Pf.y, Pf.w, Pf.w);
vec<4, T, Q> i = detail::permute(detail::permute(ix) + iy);
vec<4, T, Q> gx = static_cast<T>(2) * fract(i / T(41)) - T(1);
vec<4, T, Q> gy = abs(gx) - T(0.5);
vec<4, T, Q> tx = floor(gx + T(0.5));
gx = gx - tx;
vec<2, T, Q> g00(gx.x, gy.x);
vec<2, T, Q> g10(gx.y, gy.y);
vec<2, T, Q> g01(gx.z, gy.z);
vec<2, T, Q> g11(gx.w, gy.w);
vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
g00 *= norm.x;
g01 *= norm.y;
g10 *= norm.z;
g11 *= norm.w;
T n00 = dot(g00, vec<2, T, Q>(fx.x, fy.x));
T n10 = dot(g10, vec<2, T, Q>(fx.y, fy.y));
T n01 = dot(g01, vec<2, T, Q>(fx.z, fy.z));
T n11 = dot(g11, vec<2, T, Q>(fx.w, fy.w));
vec<2, T, Q> fade_xy = detail::fade(vec<2, T, Q>(Pf.x, Pf.y));
vec<2, T, Q> n_x = mix(vec<2, T, Q>(n00, n01), vec<2, T, Q>(n10, n11), fade_xy.x);
T n_xy = mix(n_x.x, n_x.y, fade_xy.y);
return T(2.3) * n_xy;
}
// Classic Perlin noise, periodic variant
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T perlin(vec<3, T, Q> const& Position, vec<3, T, Q> const& rep)
{
vec<3, T, Q> Pi0 = mod(floor(Position), rep); // Integer part, modulo period
vec<3, T, Q> Pi1 = mod(Pi0 + vec<3, T, Q>(T(1)), rep); // Integer part + 1, mod period
Pi0 = mod(Pi0, vec<3, T, Q>(289));
Pi1 = mod(Pi1, vec<3, T, Q>(289));
vec<3, T, Q> Pf0 = fract(Position); // Fractional part for interpolation
vec<3, T, Q> Pf1 = Pf0 - vec<3, T, Q>(T(1)); // Fractional part - 1.0
vec<4, T, Q> ix = vec<4, T, Q>(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
vec<4, T, Q> iy = vec<4, T, Q>(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
vec<4, T, Q> iz0(Pi0.z);
vec<4, T, Q> iz1(Pi1.z);
vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy);
vec<4, T, Q> ixy0 = detail::permute(ixy + iz0);
vec<4, T, Q> ixy1 = detail::permute(ixy + iz1);
vec<4, T, Q> gx0 = ixy0 / T(7);
vec<4, T, Q> gy0 = fract(floor(gx0) / T(7)) - T(0.5);
gx0 = fract(gx0);
vec<4, T, Q> gz0 = vec<4, T, Q>(0.5) - abs(gx0) - abs(gy0);
vec<4, T, Q> sz0 = step(gz0, vec<4, T, Q>(0));
gx0 -= sz0 * (step(T(0), gx0) - T(0.5));
gy0 -= sz0 * (step(T(0), gy0) - T(0.5));
vec<4, T, Q> gx1 = ixy1 / T(7);
vec<4, T, Q> gy1 = fract(floor(gx1) / T(7)) - T(0.5);
gx1 = fract(gx1);
vec<4, T, Q> gz1 = vec<4, T, Q>(0.5) - abs(gx1) - abs(gy1);
vec<4, T, Q> sz1 = step(gz1, vec<4, T, Q>(T(0)));
gx1 -= sz1 * (step(T(0), gx1) - T(0.5));
gy1 -= sz1 * (step(T(0), gy1) - T(0.5));
vec<3, T, Q> g000 = vec<3, T, Q>(gx0.x, gy0.x, gz0.x);
vec<3, T, Q> g100 = vec<3, T, Q>(gx0.y, gy0.y, gz0.y);
vec<3, T, Q> g010 = vec<3, T, Q>(gx0.z, gy0.z, gz0.z);
vec<3, T, Q> g110 = vec<3, T, Q>(gx0.w, gy0.w, gz0.w);
vec<3, T, Q> g001 = vec<3, T, Q>(gx1.x, gy1.x, gz1.x);
vec<3, T, Q> g101 = vec<3, T, Q>(gx1.y, gy1.y, gz1.y);
vec<3, T, Q> g011 = vec<3, T, Q>(gx1.z, gy1.z, gz1.z);
vec<3, T, Q> g111 = vec<3, T, Q>(gx1.w, gy1.w, gz1.w);
vec<4, T, Q> norm0 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
g000 *= norm0.x;
g010 *= norm0.y;
g100 *= norm0.z;
g110 *= norm0.w;
vec<4, T, Q> norm1 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
g001 *= norm1.x;
g011 *= norm1.y;
g101 *= norm1.z;
g111 *= norm1.w;
T n000 = dot(g000, Pf0);
T n100 = dot(g100, vec<3, T, Q>(Pf1.x, Pf0.y, Pf0.z));
T n010 = dot(g010, vec<3, T, Q>(Pf0.x, Pf1.y, Pf0.z));
T n110 = dot(g110, vec<3, T, Q>(Pf1.x, Pf1.y, Pf0.z));
T n001 = dot(g001, vec<3, T, Q>(Pf0.x, Pf0.y, Pf1.z));
T n101 = dot(g101, vec<3, T, Q>(Pf1.x, Pf0.y, Pf1.z));
T n011 = dot(g011, vec<3, T, Q>(Pf0.x, Pf1.y, Pf1.z));
T n111 = dot(g111, Pf1);
vec<3, T, Q> fade_xyz = detail::fade(Pf0);
vec<4, T, Q> n_z = mix(vec<4, T, Q>(n000, n100, n010, n110), vec<4, T, Q>(n001, n101, n011, n111), fade_xyz.z);
vec<2, T, Q> n_yz = mix(vec<2, T, Q>(n_z.x, n_z.y), vec<2, T, Q>(n_z.z, n_z.w), fade_xyz.y);
T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
return T(2.2) * n_xyz;
}
// Classic Perlin noise, periodic version
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T perlin(vec<4, T, Q> const& Position, vec<4, T, Q> const& rep)
{
vec<4, T, Q> Pi0 = mod(floor(Position), rep); // Integer part modulo rep
vec<4, T, Q> Pi1 = mod(Pi0 + T(1), rep); // Integer part + 1 mod rep
vec<4, T, Q> Pf0 = fract(Position); // Fractional part for interpolation
vec<4, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0
vec<4, T, Q> ix = vec<4, T, Q>(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
vec<4, T, Q> iy = vec<4, T, Q>(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
vec<4, T, Q> iz0(Pi0.z);
vec<4, T, Q> iz1(Pi1.z);
vec<4, T, Q> iw0(Pi0.w);
vec<4, T, Q> iw1(Pi1.w);
vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy);
vec<4, T, Q> ixy0 = detail::permute(ixy + iz0);
vec<4, T, Q> ixy1 = detail::permute(ixy + iz1);
vec<4, T, Q> ixy00 = detail::permute(ixy0 + iw0);
vec<4, T, Q> ixy01 = detail::permute(ixy0 + iw1);
vec<4, T, Q> ixy10 = detail::permute(ixy1 + iw0);
vec<4, T, Q> ixy11 = detail::permute(ixy1 + iw1);
vec<4, T, Q> gx00 = ixy00 / T(7);
vec<4, T, Q> gy00 = floor(gx00) / T(7);
vec<4, T, Q> gz00 = floor(gy00) / T(6);
gx00 = fract(gx00) - T(0.5);
gy00 = fract(gy00) - T(0.5);
gz00 = fract(gz00) - T(0.5);
vec<4, T, Q> gw00 = vec<4, T, Q>(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
vec<4, T, Q> sw00 = step(gw00, vec<4, T, Q>(0));
gx00 -= sw00 * (step(T(0), gx00) - T(0.5));
gy00 -= sw00 * (step(T(0), gy00) - T(0.5));
vec<4, T, Q> gx01 = ixy01 / T(7);
vec<4, T, Q> gy01 = floor(gx01) / T(7);
vec<4, T, Q> gz01 = floor(gy01) / T(6);
gx01 = fract(gx01) - T(0.5);
gy01 = fract(gy01) - T(0.5);
gz01 = fract(gz01) - T(0.5);
vec<4, T, Q> gw01 = vec<4, T, Q>(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
vec<4, T, Q> sw01 = step(gw01, vec<4, T, Q>(0.0));
gx01 -= sw01 * (step(T(0), gx01) - T(0.5));
gy01 -= sw01 * (step(T(0), gy01) - T(0.5));
vec<4, T, Q> gx10 = ixy10 / T(7);
vec<4, T, Q> gy10 = floor(gx10) / T(7);
vec<4, T, Q> gz10 = floor(gy10) / T(6);
gx10 = fract(gx10) - T(0.5);
gy10 = fract(gy10) - T(0.5);
gz10 = fract(gz10) - T(0.5);
vec<4, T, Q> gw10 = vec<4, T, Q>(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
vec<4, T, Q> sw10 = step(gw10, vec<4, T, Q>(0.0));
gx10 -= sw10 * (step(T(0), gx10) - T(0.5));
gy10 -= sw10 * (step(T(0), gy10) - T(0.5));
vec<4, T, Q> gx11 = ixy11 / T(7);
vec<4, T, Q> gy11 = floor(gx11) / T(7);
vec<4, T, Q> gz11 = floor(gy11) / T(6);
gx11 = fract(gx11) - T(0.5);
gy11 = fract(gy11) - T(0.5);
gz11 = fract(gz11) - T(0.5);
vec<4, T, Q> gw11 = vec<4, T, Q>(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
vec<4, T, Q> sw11 = step(gw11, vec<4, T, Q>(T(0)));
gx11 -= sw11 * (step(T(0), gx11) - T(0.5));
gy11 -= sw11 * (step(T(0), gy11) - T(0.5));
vec<4, T, Q> g0000(gx00.x, gy00.x, gz00.x, gw00.x);
vec<4, T, Q> g1000(gx00.y, gy00.y, gz00.y, gw00.y);
vec<4, T, Q> g0100(gx00.z, gy00.z, gz00.z, gw00.z);
vec<4, T, Q> g1100(gx00.w, gy00.w, gz00.w, gw00.w);
vec<4, T, Q> g0010(gx10.x, gy10.x, gz10.x, gw10.x);
vec<4, T, Q> g1010(gx10.y, gy10.y, gz10.y, gw10.y);
vec<4, T, Q> g0110(gx10.z, gy10.z, gz10.z, gw10.z);
vec<4, T, Q> g1110(gx10.w, gy10.w, gz10.w, gw10.w);
vec<4, T, Q> g0001(gx01.x, gy01.x, gz01.x, gw01.x);
vec<4, T, Q> g1001(gx01.y, gy01.y, gz01.y, gw01.y);
vec<4, T, Q> g0101(gx01.z, gy01.z, gz01.z, gw01.z);
vec<4, T, Q> g1101(gx01.w, gy01.w, gz01.w, gw01.w);
vec<4, T, Q> g0011(gx11.x, gy11.x, gz11.x, gw11.x);
vec<4, T, Q> g1011(gx11.y, gy11.y, gz11.y, gw11.y);
vec<4, T, Q> g0111(gx11.z, gy11.z, gz11.z, gw11.z);
vec<4, T, Q> g1111(gx11.w, gy11.w, gz11.w, gw11.w);
vec<4, T, Q> norm00 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
g0000 *= norm00.x;
g0100 *= norm00.y;
g1000 *= norm00.z;
g1100 *= norm00.w;
vec<4, T, Q> norm01 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
g0001 *= norm01.x;
g0101 *= norm01.y;
g1001 *= norm01.z;
g1101 *= norm01.w;
vec<4, T, Q> norm10 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
g0010 *= norm10.x;
g0110 *= norm10.y;
g1010 *= norm10.z;
g1110 *= norm10.w;
vec<4, T, Q> norm11 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
g0011 *= norm11.x;
g0111 *= norm11.y;
g1011 *= norm11.z;
g1111 *= norm11.w;
T n0000 = dot(g0000, Pf0);
T n1000 = dot(g1000, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf0.w));
T n0100 = dot(g0100, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf0.w));
T n1100 = dot(g1100, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf0.w));
T n0010 = dot(g0010, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf0.w));
T n1010 = dot(g1010, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
T n0110 = dot(g0110, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf0.w));
T n1110 = dot(g1110, vec<4, T, Q>(Pf1.x, Pf1.y, Pf1.z, Pf0.w));
T n0001 = dot(g0001, vec<4, T, Q>(Pf0.x, Pf0.y, Pf0.z, Pf1.w));
T n1001 = dot(g1001, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf1.w));
T n0101 = dot(g0101, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
T n1101 = dot(g1101, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf1.w));
T n0011 = dot(g0011, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf1.w));
T n1011 = dot(g1011, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf1.w));
T n0111 = dot(g0111, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf1.w));
T n1111 = dot(g1111, Pf1);
vec<4, T, Q> fade_xyzw = detail::fade(Pf0);
vec<4, T, Q> n_0w = mix(vec<4, T, Q>(n0000, n1000, n0100, n1100), vec<4, T, Q>(n0001, n1001, n0101, n1101), fade_xyzw.w);
vec<4, T, Q> n_1w = mix(vec<4, T, Q>(n0010, n1010, n0110, n1110), vec<4, T, Q>(n0011, n1011, n0111, n1111), fade_xyzw.w);
vec<4, T, Q> n_zw = mix(n_0w, n_1w, fade_xyzw.z);
vec<2, T, Q> n_yzw = mix(vec<2, T, Q>(n_zw.x, n_zw.y), vec<2, T, Q>(n_zw.z, n_zw.w), fade_xyzw.y);
T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
return T(2.2) * n_xyzw;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T simplex(glm::vec<2, T, Q> const& v)
{
vec<4, T, Q> const C = vec<4, T, Q>(
T( 0.211324865405187), // (3.0 - sqrt(3.0)) / 6.0
T( 0.366025403784439), // 0.5 * (sqrt(3.0) - 1.0)
T(-0.577350269189626), // -1.0 + 2.0 * C.x
T( 0.024390243902439)); // 1.0 / 41.0
// First corner
vec<2, T, Q> i = floor(v + dot(v, vec<2, T, Q>(C[1])));
vec<2, T, Q> x0 = v - i + dot(i, vec<2, T, Q>(C[0]));
// Other corners
//i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
//i1.y = 1.0 - i1.x;
vec<2, T, Q> i1 = (x0.x > x0.y) ? vec<2, T, Q>(1, 0) : vec<2, T, Q>(0, 1);
// x0 = x0 - 0.0 + 0.0 * C.xx ;
// x1 = x0 - i1 + 1.0 * C.xx ;
// x2 = x0 - 1.0 + 2.0 * C.xx ;
vec<4, T, Q> x12 = vec<4, T, Q>(x0.x, x0.y, x0.x, x0.y) + vec<4, T, Q>(C.x, C.x, C.z, C.z);
x12 = vec<4, T, Q>(vec<2, T, Q>(x12) - i1, x12.z, x12.w);
// Permutations
i = mod(i, vec<2, T, Q>(289)); // Avoid truncation effects in permutation
vec<3, T, Q> p = detail::permute(
detail::permute(i.y + vec<3, T, Q>(T(0), i1.y, T(1)))
+ i.x + vec<3, T, Q>(T(0), i1.x, T(1)));
vec<3, T, Q> m = max(vec<3, T, Q>(0.5) - vec<3, T, Q>(
dot(x0, x0),
dot(vec<2, T, Q>(x12.x, x12.y), vec<2, T, Q>(x12.x, x12.y)),
dot(vec<2, T, Q>(x12.z, x12.w), vec<2, T, Q>(x12.z, x12.w))), vec<3, T, Q>(0));
m = m * m ;
m = m * m ;
// Gradients: 41 points uniformly over a line, mapped onto a diamond.
// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
vec<3, T, Q> x = static_cast<T>(2) * fract(p * C.w) - T(1);
vec<3, T, Q> h = abs(x) - T(0.5);
vec<3, T, Q> ox = floor(x + T(0.5));
vec<3, T, Q> a0 = x - ox;
// Normalise gradients implicitly by scaling m
// Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h );
m *= static_cast<T>(1.79284291400159) - T(0.85373472095314) * (a0 * a0 + h * h);
// Compute final noise value at P
vec<3, T, Q> g;
g.x = a0.x * x0.x + h.x * x0.y;
//g.yz = a0.yz * x12.xz + h.yz * x12.yw;
g.y = a0.y * x12.x + h.y * x12.y;
g.z = a0.z * x12.z + h.z * x12.w;
return T(130) * dot(m, g);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T simplex(vec<3, T, Q> const& v)
{
vec<2, T, Q> const C(1.0 / 6.0, 1.0 / 3.0);
vec<4, T, Q> const D(0.0, 0.5, 1.0, 2.0);
// First corner
vec<3, T, Q> i(floor(v + dot(v, vec<3, T, Q>(C.y))));
vec<3, T, Q> x0(v - i + dot(i, vec<3, T, Q>(C.x)));
// Other corners
vec<3, T, Q> g(step(vec<3, T, Q>(x0.y, x0.z, x0.x), x0));
vec<3, T, Q> l(T(1) - g);
vec<3, T, Q> i1(min(g, vec<3, T, Q>(l.z, l.x, l.y)));
vec<3, T, Q> i2(max(g, vec<3, T, Q>(l.z, l.x, l.y)));
// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec<3, T, Q> x1(x0 - i1 + C.x);
vec<3, T, Q> x2(x0 - i2 + C.y); // 2.0*C.x = 1/3 = C.y
vec<3, T, Q> x3(x0 - D.y); // -1.0+3.0*C.x = -0.5 = -D.y
// Permutations
i = detail::mod289(i);
vec<4, T, Q> p(detail::permute(detail::permute(detail::permute(
i.z + vec<4, T, Q>(T(0), i1.z, i2.z, T(1))) +
i.y + vec<4, T, Q>(T(0), i1.y, i2.y, T(1))) +
i.x + vec<4, T, Q>(T(0), i1.x, i2.x, T(1))));
// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
T n_ = static_cast<T>(0.142857142857); // 1.0/7.0
vec<3, T, Q> ns(n_ * vec<3, T, Q>(D.w, D.y, D.z) - vec<3, T, Q>(D.x, D.z, D.x));
vec<4, T, Q> j(p - T(49) * floor(p * ns.z * ns.z)); // mod(p,7*7)
vec<4, T, Q> x_(floor(j * ns.z));
vec<4, T, Q> y_(floor(j - T(7) * x_)); // mod(j,N)
vec<4, T, Q> x(x_ * ns.x + ns.y);
vec<4, T, Q> y(y_ * ns.x + ns.y);
vec<4, T, Q> h(T(1) - abs(x) - abs(y));
vec<4, T, Q> b0(x.x, x.y, y.x, y.y);
vec<4, T, Q> b1(x.z, x.w, y.z, y.w);
// vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
// vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
vec<4, T, Q> s0(floor(b0) * T(2) + T(1));
vec<4, T, Q> s1(floor(b1) * T(2) + T(1));
vec<4, T, Q> sh(-step(h, vec<4, T, Q>(0.0)));
vec<4, T, Q> a0 = vec<4, T, Q>(b0.x, b0.z, b0.y, b0.w) + vec<4, T, Q>(s0.x, s0.z, s0.y, s0.w) * vec<4, T, Q>(sh.x, sh.x, sh.y, sh.y);
vec<4, T, Q> a1 = vec<4, T, Q>(b1.x, b1.z, b1.y, b1.w) + vec<4, T, Q>(s1.x, s1.z, s1.y, s1.w) * vec<4, T, Q>(sh.z, sh.z, sh.w, sh.w);
vec<3, T, Q> p0(a0.x, a0.y, h.x);
vec<3, T, Q> p1(a0.z, a0.w, h.y);
vec<3, T, Q> p2(a1.x, a1.y, h.z);
vec<3, T, Q> p3(a1.z, a1.w, h.w);
// Normalise gradients
vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
vec<4, T, Q> m = max(T(0.6) - vec<4, T, Q>(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), vec<4, T, Q>(0));
m = m * m;
return T(42) * dot(m * m, vec<4, T, Q>(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T simplex(vec<4, T, Q> const& v)
{
vec<4, T, Q> const C(
0.138196601125011, // (5 - sqrt(5))/20 G4
0.276393202250021, // 2 * G4
0.414589803375032, // 3 * G4
-0.447213595499958); // -1 + 4 * G4
// (sqrt(5) - 1)/4 = F4, used once below
T const F4 = static_cast<T>(0.309016994374947451);
// First corner
vec<4, T, Q> i = floor(v + dot(v, vec<4, T, Q>(F4)));
vec<4, T, Q> x0 = v - i + dot(i, vec<4, T, Q>(C.x));
// Other corners
// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
vec<4, T, Q> i0;
vec<3, T, Q> isX = step(vec<3, T, Q>(x0.y, x0.z, x0.w), vec<3, T, Q>(x0.x));
vec<3, T, Q> isYZ = step(vec<3, T, Q>(x0.z, x0.w, x0.w), vec<3, T, Q>(x0.y, x0.y, x0.z));
// i0.x = dot(isX, vec3(1.0));
//i0.x = isX.x + isX.y + isX.z;
//i0.yzw = static_cast<T>(1) - isX;
i0 = vec<4, T, Q>(isX.x + isX.y + isX.z, T(1) - isX);
// i0.y += dot(isYZ.xy, vec2(1.0));
i0.y += isYZ.x + isYZ.y;
//i0.zw += 1.0 - vec<2, T, Q>(isYZ.x, isYZ.y);
i0.z += static_cast<T>(1) - isYZ.x;
i0.w += static_cast<T>(1) - isYZ.y;
i0.z += isYZ.z;
i0.w += static_cast<T>(1) - isYZ.z;
// i0 now contains the unique values 0,1,2,3 in each channel
vec<4, T, Q> i3 = clamp(i0, T(0), T(1));
vec<4, T, Q> i2 = clamp(i0 - T(1), T(0), T(1));
vec<4, T, Q> i1 = clamp(i0 - T(2), T(0), T(1));
// x0 = x0 - 0.0 + 0.0 * C.xxxx
// x1 = x0 - i1 + 0.0 * C.xxxx
// x2 = x0 - i2 + 0.0 * C.xxxx
// x3 = x0 - i3 + 0.0 * C.xxxx
// x4 = x0 - 1.0 + 4.0 * C.xxxx
vec<4, T, Q> x1 = x0 - i1 + C.x;
vec<4, T, Q> x2 = x0 - i2 + C.y;
vec<4, T, Q> x3 = x0 - i3 + C.z;
vec<4, T, Q> x4 = x0 + C.w;
// Permutations
i = mod(i, vec<4, T, Q>(289));
T j0 = detail::permute(detail::permute(detail::permute(detail::permute(i.w) + i.z) + i.y) + i.x);
vec<4, T, Q> j1 = detail::permute(detail::permute(detail::permute(detail::permute(
i.w + vec<4, T, Q>(i1.w, i2.w, i3.w, T(1))) +
i.z + vec<4, T, Q>(i1.z, i2.z, i3.z, T(1))) +
i.y + vec<4, T, Q>(i1.y, i2.y, i3.y, T(1))) +
i.x + vec<4, T, Q>(i1.x, i2.x, i3.x, T(1)));
// Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
vec<4, T, Q> ip = vec<4, T, Q>(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0));
vec<4, T, Q> p0 = detail::grad4(j0, ip);
vec<4, T, Q> p1 = detail::grad4(j1.x, ip);
vec<4, T, Q> p2 = detail::grad4(j1.y, ip);
vec<4, T, Q> p3 = detail::grad4(j1.z, ip);
vec<4, T, Q> p4 = detail::grad4(j1.w, ip);
// Normalise gradients
vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
p4 *= detail::taylorInvSqrt(dot(p4, p4));
// Mix contributions from the five corners
vec<3, T, Q> m0 = max(T(0.6) - vec<3, T, Q>(dot(x0, x0), dot(x1, x1), dot(x2, x2)), vec<3, T, Q>(0));
vec<2, T, Q> m1 = max(T(0.6) - vec<2, T, Q>(dot(x3, x3), dot(x4, x4) ), vec<2, T, Q>(0));
m0 = m0 * m0;
m1 = m1 * m1;
return T(49) *
(dot(m0 * m0, vec<3, T, Q>(dot(p0, x0), dot(p1, x1), dot(p2, x2))) +
dot(m1 * m1, vec<2, T, Q>(dot(p3, x3), dot(p4, x4))));
}
}//namespace glm
+728
View File
@@ -0,0 +1,728 @@
/// @ref gtc_packing
/// @file glm/gtc/packing.hpp
///
/// @see core (dependence)
///
/// @defgroup gtc_packing GLM_GTC_packing
/// @ingroup gtc
///
/// Include <glm/gtc/packing.hpp> to use the features of this extension.
///
/// This extension provides a set of function to convert vertors to packed
/// formats.
#pragma once
// Dependency:
#include "type_precision.hpp"
#include "../ext/vector_packing.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_packing extension included")
#endif
namespace glm
{
/// @addtogroup gtc_packing
/// @{
/// First, converts the normalized floating-point value v into a 8-bit integer value.
/// Then, the results are packed into the returned 8-bit unsigned integer.
///
/// The conversion for component c of v to fixed point is done as follows:
/// packUnorm1x8: round(clamp(c, 0, +1) * 255.0)
///
/// @see gtc_packing
/// @see uint16 packUnorm2x8(vec2 const& v)
/// @see uint32 packUnorm4x8(vec4 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packUnorm4x8.xml">GLSL packUnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL uint8 packUnorm1x8(float v);
/// Convert a single 8-bit integer to a normalized floating-point value.
///
/// The conversion for unpacked fixed-point value f to floating point is done as follows:
/// unpackUnorm4x8: f / 255.0
///
/// @see gtc_packing
/// @see vec2 unpackUnorm2x8(uint16 p)
/// @see vec4 unpackUnorm4x8(uint32 p)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackUnorm4x8.xml">GLSL unpackUnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL float unpackUnorm1x8(uint8 p);
/// First, converts each component of the normalized floating-point value v into 8-bit integer values.
/// Then, the results are packed into the returned 16-bit unsigned integer.
///
/// The conversion for component c of v to fixed point is done as follows:
/// packUnorm2x8: round(clamp(c, 0, +1) * 255.0)
///
/// The first component of the vector will be written to the least significant bits of the output;
/// the last component will be written to the most significant bits.
///
/// @see gtc_packing
/// @see uint8 packUnorm1x8(float const& v)
/// @see uint32 packUnorm4x8(vec4 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packUnorm4x8.xml">GLSL packUnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL uint16 packUnorm2x8(vec2 const& v);
/// First, unpacks a single 16-bit unsigned integer p into a pair of 8-bit unsigned integers.
/// Then, each component is converted to a normalized floating-point value to generate the returned two-component vector.
///
/// The conversion for unpacked fixed-point value f to floating point is done as follows:
/// unpackUnorm4x8: f / 255.0
///
/// The first component of the returned vector will be extracted from the least significant bits of the input;
/// the last component will be extracted from the most significant bits.
///
/// @see gtc_packing
/// @see float unpackUnorm1x8(uint8 v)
/// @see vec4 unpackUnorm4x8(uint32 p)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackUnorm4x8.xml">GLSL unpackUnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL vec2 unpackUnorm2x8(uint16 p);
/// First, converts the normalized floating-point value v into 8-bit integer value.
/// Then, the results are packed into the returned 8-bit unsigned integer.
///
/// The conversion to fixed point is done as follows:
/// packSnorm1x8: round(clamp(s, -1, +1) * 127.0)
///
/// @see gtc_packing
/// @see uint16 packSnorm2x8(vec2 const& v)
/// @see uint32 packSnorm4x8(vec4 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packSnorm4x8.xml">GLSL packSnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL uint8 packSnorm1x8(float s);
/// First, unpacks a single 8-bit unsigned integer p into a single 8-bit signed integers.
/// Then, the value is converted to a normalized floating-point value to generate the returned scalar.
///
/// The conversion for unpacked fixed-point value f to floating point is done as follows:
/// unpackSnorm1x8: clamp(f / 127.0, -1, +1)
///
/// @see gtc_packing
/// @see vec2 unpackSnorm2x8(uint16 p)
/// @see vec4 unpackSnorm4x8(uint32 p)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackSnorm4x8.xml">GLSL unpackSnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL float unpackSnorm1x8(uint8 p);
/// First, converts each component of the normalized floating-point value v into 8-bit integer values.
/// Then, the results are packed into the returned 16-bit unsigned integer.
///
/// The conversion for component c of v to fixed point is done as follows:
/// packSnorm2x8: round(clamp(c, -1, +1) * 127.0)
///
/// The first component of the vector will be written to the least significant bits of the output;
/// the last component will be written to the most significant bits.
///
/// @see gtc_packing
/// @see uint8 packSnorm1x8(float const& v)
/// @see uint32 packSnorm4x8(vec4 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packSnorm4x8.xml">GLSL packSnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL uint16 packSnorm2x8(vec2 const& v);
/// First, unpacks a single 16-bit unsigned integer p into a pair of 8-bit signed integers.
/// Then, each component is converted to a normalized floating-point value to generate the returned two-component vector.
///
/// The conversion for unpacked fixed-point value f to floating point is done as follows:
/// unpackSnorm2x8: clamp(f / 127.0, -1, +1)
///
/// The first component of the returned vector will be extracted from the least significant bits of the input;
/// the last component will be extracted from the most significant bits.
///
/// @see gtc_packing
/// @see float unpackSnorm1x8(uint8 p)
/// @see vec4 unpackSnorm4x8(uint32 p)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackSnorm4x8.xml">GLSL unpackSnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL vec2 unpackSnorm2x8(uint16 p);
/// First, converts the normalized floating-point value v into a 16-bit integer value.
/// Then, the results are packed into the returned 16-bit unsigned integer.
///
/// The conversion for component c of v to fixed point is done as follows:
/// packUnorm1x16: round(clamp(c, 0, +1) * 65535.0)
///
/// @see gtc_packing
/// @see uint16 packSnorm1x16(float const& v)
/// @see uint64 packSnorm4x16(vec4 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packUnorm4x8.xml">GLSL packUnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL uint16 packUnorm1x16(float v);
/// First, unpacks a single 16-bit unsigned integer p into a of 16-bit unsigned integers.
/// Then, the value is converted to a normalized floating-point value to generate the returned scalar.
///
/// The conversion for unpacked fixed-point value f to floating point is done as follows:
/// unpackUnorm1x16: f / 65535.0
///
/// @see gtc_packing
/// @see vec2 unpackUnorm2x16(uint32 p)
/// @see vec4 unpackUnorm4x16(uint64 p)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackUnorm2x16.xml">GLSL unpackUnorm2x16 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL float unpackUnorm1x16(uint16 p);
/// First, converts each component of the normalized floating-point value v into 16-bit integer values.
/// Then, the results are packed into the returned 64-bit unsigned integer.
///
/// The conversion for component c of v to fixed point is done as follows:
/// packUnorm4x16: round(clamp(c, 0, +1) * 65535.0)
///
/// The first component of the vector will be written to the least significant bits of the output;
/// the last component will be written to the most significant bits.
///
/// @see gtc_packing
/// @see uint16 packUnorm1x16(float const& v)
/// @see uint32 packUnorm2x16(vec2 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packUnorm4x8.xml">GLSL packUnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL uint64 packUnorm4x16(vec4 const& v);
/// First, unpacks a single 64-bit unsigned integer p into four 16-bit unsigned integers.
/// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector.
///
/// The conversion for unpacked fixed-point value f to floating point is done as follows:
/// unpackUnormx4x16: f / 65535.0
///
/// The first component of the returned vector will be extracted from the least significant bits of the input;
/// the last component will be extracted from the most significant bits.
///
/// @see gtc_packing
/// @see float unpackUnorm1x16(uint16 p)
/// @see vec2 unpackUnorm2x16(uint32 p)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackUnorm2x16.xml">GLSL unpackUnorm2x16 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL vec4 unpackUnorm4x16(uint64 p);
/// First, converts the normalized floating-point value v into 16-bit integer value.
/// Then, the results are packed into the returned 16-bit unsigned integer.
///
/// The conversion to fixed point is done as follows:
/// packSnorm1x8: round(clamp(s, -1, +1) * 32767.0)
///
/// @see gtc_packing
/// @see uint32 packSnorm2x16(vec2 const& v)
/// @see uint64 packSnorm4x16(vec4 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packSnorm4x8.xml">GLSL packSnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL uint16 packSnorm1x16(float v);
/// First, unpacks a single 16-bit unsigned integer p into a single 16-bit signed integers.
/// Then, each component is converted to a normalized floating-point value to generate the returned scalar.
///
/// The conversion for unpacked fixed-point value f to floating point is done as follows:
/// unpackSnorm1x16: clamp(f / 32767.0, -1, +1)
///
/// @see gtc_packing
/// @see vec2 unpackSnorm2x16(uint32 p)
/// @see vec4 unpackSnorm4x16(uint64 p)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackSnorm1x16.xml">GLSL unpackSnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL float unpackSnorm1x16(uint16 p);
/// First, converts each component of the normalized floating-point value v into 16-bit integer values.
/// Then, the results are packed into the returned 64-bit unsigned integer.
///
/// The conversion for component c of v to fixed point is done as follows:
/// packSnorm2x8: round(clamp(c, -1, +1) * 32767.0)
///
/// The first component of the vector will be written to the least significant bits of the output;
/// the last component will be written to the most significant bits.
///
/// @see gtc_packing
/// @see uint16 packSnorm1x16(float const& v)
/// @see uint32 packSnorm2x16(vec2 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packSnorm4x8.xml">GLSL packSnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL uint64 packSnorm4x16(vec4 const& v);
/// First, unpacks a single 64-bit unsigned integer p into four 16-bit signed integers.
/// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector.
///
/// The conversion for unpacked fixed-point value f to floating point is done as follows:
/// unpackSnorm4x16: clamp(f / 32767.0, -1, +1)
///
/// The first component of the returned vector will be extracted from the least significant bits of the input;
/// the last component will be extracted from the most significant bits.
///
/// @see gtc_packing
/// @see float unpackSnorm1x16(uint16 p)
/// @see vec2 unpackSnorm2x16(uint32 p)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackSnorm2x16.xml">GLSL unpackSnorm4x8 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL vec4 unpackSnorm4x16(uint64 p);
/// Returns an unsigned integer obtained by converting the components of a floating-point scalar
/// to the 16-bit floating-point representation found in the OpenGL Specification,
/// and then packing this 16-bit value into a 16-bit unsigned integer.
///
/// @see gtc_packing
/// @see uint32 packHalf2x16(vec2 const& v)
/// @see uint64 packHalf4x16(vec4 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packHalf2x16.xml">GLSL packHalf2x16 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL uint16 packHalf1x16(float v);
/// Returns a floating-point scalar with components obtained by unpacking a 16-bit unsigned integer into a 16-bit value,
/// interpreted as a 16-bit floating-point number according to the OpenGL Specification,
/// and converting it to 32-bit floating-point values.
///
/// @see gtc_packing
/// @see vec2 unpackHalf2x16(uint32 const& v)
/// @see vec4 unpackHalf4x16(uint64 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackHalf2x16.xml">GLSL unpackHalf2x16 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL float unpackHalf1x16(uint16 v);
/// Returns an unsigned integer obtained by converting the components of a four-component floating-point vector
/// to the 16-bit floating-point representation found in the OpenGL Specification,
/// and then packing these four 16-bit values into a 64-bit unsigned integer.
/// The first vector component specifies the 16 least-significant bits of the result;
/// the forth component specifies the 16 most-significant bits.
///
/// @see gtc_packing
/// @see uint16 packHalf1x16(float const& v)
/// @see uint32 packHalf2x16(vec2 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packHalf2x16.xml">GLSL packHalf2x16 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL uint64 packHalf4x16(vec4 const& v);
/// Returns a four-component floating-point vector with components obtained by unpacking a 64-bit unsigned integer into four 16-bit values,
/// interpreting those values as 16-bit floating-point numbers according to the OpenGL Specification,
/// and converting them to 32-bit floating-point values.
/// The first component of the vector is obtained from the 16 least-significant bits of v;
/// the forth component is obtained from the 16 most-significant bits of v.
///
/// @see gtc_packing
/// @see float unpackHalf1x16(uint16 const& v)
/// @see vec2 unpackHalf2x16(uint32 const& v)
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackHalf2x16.xml">GLSL unpackHalf2x16 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
GLM_FUNC_DECL vec4 unpackHalf4x16(uint64 p);
/// Returns an unsigned integer obtained by converting the components of a four-component signed integer vector
/// to the 10-10-10-2-bit signed integer representation found in the OpenGL Specification,
/// and then packing these four values into a 32-bit unsigned integer.
/// The first vector component specifies the 10 least-significant bits of the result;
/// the forth component specifies the 2 most-significant bits.
///
/// @see gtc_packing
/// @see uint32 packI3x10_1x2(uvec4 const& v)
/// @see uint32 packSnorm3x10_1x2(vec4 const& v)
/// @see uint32 packUnorm3x10_1x2(vec4 const& v)
/// @see ivec4 unpackI3x10_1x2(uint32 const& p)
GLM_FUNC_DECL uint32 packI3x10_1x2(ivec4 const& v);
/// Unpacks a single 32-bit unsigned integer p into three 10-bit and one 2-bit signed integers.
///
/// The first component of the returned vector will be extracted from the least significant bits of the input;
/// the last component will be extracted from the most significant bits.
///
/// @see gtc_packing
/// @see uint32 packU3x10_1x2(uvec4 const& v)
/// @see vec4 unpackSnorm3x10_1x2(uint32 const& p);
/// @see uvec4 unpackI3x10_1x2(uint32 const& p);
GLM_FUNC_DECL ivec4 unpackI3x10_1x2(uint32 p);
/// Returns an unsigned integer obtained by converting the components of a four-component unsigned integer vector
/// to the 10-10-10-2-bit unsigned integer representation found in the OpenGL Specification,
/// and then packing these four values into a 32-bit unsigned integer.
/// The first vector component specifies the 10 least-significant bits of the result;
/// the forth component specifies the 2 most-significant bits.
///
/// @see gtc_packing
/// @see uint32 packI3x10_1x2(ivec4 const& v)
/// @see uint32 packSnorm3x10_1x2(vec4 const& v)
/// @see uint32 packUnorm3x10_1x2(vec4 const& v)
/// @see ivec4 unpackU3x10_1x2(uint32 const& p)
GLM_FUNC_DECL uint32 packU3x10_1x2(uvec4 const& v);
/// Unpacks a single 32-bit unsigned integer p into three 10-bit and one 2-bit unsigned integers.
///
/// The first component of the returned vector will be extracted from the least significant bits of the input;
/// the last component will be extracted from the most significant bits.
///
/// @see gtc_packing
/// @see uint32 packU3x10_1x2(uvec4 const& v)
/// @see vec4 unpackSnorm3x10_1x2(uint32 const& p);
/// @see uvec4 unpackI3x10_1x2(uint32 const& p);
GLM_FUNC_DECL uvec4 unpackU3x10_1x2(uint32 p);
/// First, converts the first three components of the normalized floating-point value v into 10-bit signed integer values.
/// Then, converts the forth component of the normalized floating-point value v into 2-bit signed integer values.
/// Then, the results are packed into the returned 32-bit unsigned integer.
///
/// The conversion for component c of v to fixed point is done as follows:
/// packSnorm3x10_1x2(xyz): round(clamp(c, -1, +1) * 511.0)
/// packSnorm3x10_1x2(w): round(clamp(c, -1, +1) * 1.0)
///
/// The first vector component specifies the 10 least-significant bits of the result;
/// the forth component specifies the 2 most-significant bits.
///
/// @see gtc_packing
/// @see vec4 unpackSnorm3x10_1x2(uint32 const& p)
/// @see uint32 packUnorm3x10_1x2(vec4 const& v)
/// @see uint32 packU3x10_1x2(uvec4 const& v)
/// @see uint32 packI3x10_1x2(ivec4 const& v)
GLM_FUNC_DECL uint32 packSnorm3x10_1x2(vec4 const& v);
/// First, unpacks a single 32-bit unsigned integer p into four 16-bit signed integers.
/// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector.
///
/// The conversion for unpacked fixed-point value f to floating point is done as follows:
/// unpackSnorm3x10_1x2(xyz): clamp(f / 511.0, -1, +1)
/// unpackSnorm3x10_1x2(w): clamp(f / 511.0, -1, +1)
///
/// The first component of the returned vector will be extracted from the least significant bits of the input;
/// the last component will be extracted from the most significant bits.
///
/// @see gtc_packing
/// @see uint32 packSnorm3x10_1x2(vec4 const& v)
/// @see vec4 unpackUnorm3x10_1x2(uint32 const& p))
/// @see uvec4 unpackI3x10_1x2(uint32 const& p)
/// @see uvec4 unpackU3x10_1x2(uint32 const& p)
GLM_FUNC_DECL vec4 unpackSnorm3x10_1x2(uint32 p);
/// First, converts the first three components of the normalized floating-point value v into 10-bit unsigned integer values.
/// Then, converts the forth component of the normalized floating-point value v into 2-bit signed uninteger values.
/// Then, the results are packed into the returned 32-bit unsigned integer.
///
/// The conversion for component c of v to fixed point is done as follows:
/// packUnorm3x10_1x2(xyz): round(clamp(c, 0, +1) * 1023.0)
/// packUnorm3x10_1x2(w): round(clamp(c, 0, +1) * 3.0)
///
/// The first vector component specifies the 10 least-significant bits of the result;
/// the forth component specifies the 2 most-significant bits.
///
/// @see gtc_packing
/// @see vec4 unpackUnorm3x10_1x2(uint32 const& p)
/// @see uint32 packUnorm3x10_1x2(vec4 const& v)
/// @see uint32 packU3x10_1x2(uvec4 const& v)
/// @see uint32 packI3x10_1x2(ivec4 const& v)
GLM_FUNC_DECL uint32 packUnorm3x10_1x2(vec4 const& v);
/// First, unpacks a single 32-bit unsigned integer p into four 16-bit signed integers.
/// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector.
///
/// The conversion for unpacked fixed-point value f to floating point is done as follows:
/// unpackSnorm3x10_1x2(xyz): clamp(f / 1023.0, 0, +1)
/// unpackSnorm3x10_1x2(w): clamp(f / 3.0, 0, +1)
///
/// The first component of the returned vector will be extracted from the least significant bits of the input;
/// the last component will be extracted from the most significant bits.
///
/// @see gtc_packing
/// @see uint32 packSnorm3x10_1x2(vec4 const& v)
/// @see vec4 unpackInorm3x10_1x2(uint32 const& p))
/// @see uvec4 unpackI3x10_1x2(uint32 const& p)
/// @see uvec4 unpackU3x10_1x2(uint32 const& p)
GLM_FUNC_DECL vec4 unpackUnorm3x10_1x2(uint32 p);
/// First, converts the first two components of the normalized floating-point value v into 11-bit signless floating-point values.
/// Then, converts the third component of the normalized floating-point value v into a 10-bit signless floating-point value.
/// Then, the results are packed into the returned 32-bit unsigned integer.
///
/// The first vector component specifies the 11 least-significant bits of the result;
/// the last component specifies the 10 most-significant bits.
///
/// @see gtc_packing
/// @see vec3 unpackF2x11_1x10(uint32 const& p)
GLM_FUNC_DECL uint32 packF2x11_1x10(vec3 const& v);
/// First, unpacks a single 32-bit unsigned integer p into two 11-bit signless floating-point values and one 10-bit signless floating-point value .
/// Then, each component is converted to a normalized floating-point value to generate the returned three-component vector.
///
/// The first component of the returned vector will be extracted from the least significant bits of the input;
/// the last component will be extracted from the most significant bits.
///
/// @see gtc_packing
/// @see uint32 packF2x11_1x10(vec3 const& v)
GLM_FUNC_DECL vec3 unpackF2x11_1x10(uint32 p);
/// First, converts the first two components of the normalized floating-point value v into 11-bit signless floating-point values.
/// Then, converts the third component of the normalized floating-point value v into a 10-bit signless floating-point value.
/// Then, the results are packed into the returned 32-bit unsigned integer.
///
/// The first vector component specifies the 11 least-significant bits of the result;
/// the last component specifies the 10 most-significant bits.
///
/// packF3x9_E1x5 allows encoding into RGBE / RGB9E5 format
///
/// @see gtc_packing
/// @see vec3 unpackF3x9_E1x5(uint32 const& p)
GLM_FUNC_DECL uint32 packF3x9_E1x5(vec3 const& v);
/// First, unpacks a single 32-bit unsigned integer p into two 11-bit signless floating-point values and one 10-bit signless floating-point value .
/// Then, each component is converted to a normalized floating-point value to generate the returned three-component vector.
///
/// The first component of the returned vector will be extracted from the least significant bits of the input;
/// the last component will be extracted from the most significant bits.
///
/// unpackF3x9_E1x5 allows decoding RGBE / RGB9E5 data
///
/// @see gtc_packing
/// @see uint32 packF3x9_E1x5(vec3 const& v)
GLM_FUNC_DECL vec3 unpackF3x9_E1x5(uint32 p);
/// Returns an unsigned integer vector obtained by converting the components of a floating-point vector
/// to the 16-bit floating-point representation found in the OpenGL Specification.
/// The first vector component specifies the 16 least-significant bits of the result;
/// the forth component specifies the 16 most-significant bits.
///
/// @see gtc_packing
/// @see vec<3, T, Q> unpackRGBM(vec<4, T, Q> const& p)
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> packRGBM(vec<3, T, Q> const& rgb);
/// Returns a floating-point vector with components obtained by reinterpreting an integer vector as 16-bit floating-point numbers and converting them to 32-bit floating-point values.
/// The first component of the vector is obtained from the 16 least-significant bits of v;
/// the forth component is obtained from the 16 most-significant bits of v.
///
/// @see gtc_packing
/// @see vec<4, T, Q> packRGBM(vec<3, float, Q> const& v)
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> unpackRGBM(vec<4, T, Q> const& rgbm);
/// Returns an unsigned integer vector obtained by converting the components of a floating-point vector
/// to the 16-bit floating-point representation found in the OpenGL Specification.
/// The first vector component specifies the 16 least-significant bits of the result;
/// the forth component specifies the 16 most-significant bits.
///
/// @see gtc_packing
/// @see vec<L, float, Q> unpackHalf(vec<L, uint16, Q> const& p)
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
template<length_t L, qualifier Q>
GLM_FUNC_DECL vec<L, uint16, Q> packHalf(vec<L, float, Q> const& v);
/// Returns a floating-point vector with components obtained by reinterpreting an integer vector as 16-bit floating-point numbers and converting them to 32-bit floating-point values.
/// The first component of the vector is obtained from the 16 least-significant bits of v;
/// the forth component is obtained from the 16 most-significant bits of v.
///
/// @see gtc_packing
/// @see vec<L, uint16, Q> packHalf(vec<L, float, Q> const& v)
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
template<length_t L, qualifier Q>
GLM_FUNC_DECL vec<L, float, Q> unpackHalf(vec<L, uint16, Q> const& p);
/// Convert each component of the normalized floating-point vector into unsigned integer values.
///
/// @see gtc_packing
/// @see vec<L, floatType, Q> unpackUnorm(vec<L, intType, Q> const& p);
template<typename uintType, length_t L, typename floatType, qualifier Q>
GLM_FUNC_DECL vec<L, uintType, Q> packUnorm(vec<L, floatType, Q> const& v);
/// Convert a packed integer to a normalized floating-point vector.
///
/// @see gtc_packing
/// @see vec<L, intType, Q> packUnorm(vec<L, floatType, Q> const& v)
template<typename floatType, length_t L, typename uintType, qualifier Q>
GLM_FUNC_DECL vec<L, floatType, Q> unpackUnorm(vec<L, uintType, Q> const& v);
/// Convert each component of the normalized floating-point vector into signed integer values.
///
/// @see gtc_packing
/// @see vec<L, floatType, Q> unpackSnorm(vec<L, intType, Q> const& p);
template<typename intType, length_t L, typename floatType, qualifier Q>
GLM_FUNC_DECL vec<L, intType, Q> packSnorm(vec<L, floatType, Q> const& v);
/// Convert a packed integer to a normalized floating-point vector.
///
/// @see gtc_packing
/// @see vec<L, intType, Q> packSnorm(vec<L, floatType, Q> const& v)
template<typename floatType, length_t L, typename intType, qualifier Q>
GLM_FUNC_DECL vec<L, floatType, Q> unpackSnorm(vec<L, intType, Q> const& v);
/// Convert each component of the normalized floating-point vector into unsigned integer values.
///
/// @see gtc_packing
/// @see vec2 unpackUnorm2x4(uint8 p)
GLM_FUNC_DECL uint8 packUnorm2x4(vec2 const& v);
/// Convert a packed integer to a normalized floating-point vector.
///
/// @see gtc_packing
/// @see uint8 packUnorm2x4(vec2 const& v)
GLM_FUNC_DECL vec2 unpackUnorm2x4(uint8 p);
/// Convert each component of the normalized floating-point vector into unsigned integer values.
///
/// @see gtc_packing
/// @see vec4 unpackUnorm4x4(uint16 p)
GLM_FUNC_DECL uint16 packUnorm4x4(vec4 const& v);
/// Convert a packed integer to a normalized floating-point vector.
///
/// @see gtc_packing
/// @see uint16 packUnorm4x4(vec4 const& v)
GLM_FUNC_DECL vec4 unpackUnorm4x4(uint16 p);
/// Convert each component of the normalized floating-point vector into unsigned integer values.
///
/// @see gtc_packing
/// @see vec3 unpackUnorm1x5_1x6_1x5(uint16 p)
GLM_FUNC_DECL uint16 packUnorm1x5_1x6_1x5(vec3 const& v);
/// Convert a packed integer to a normalized floating-point vector.
///
/// @see gtc_packing
/// @see uint16 packUnorm1x5_1x6_1x5(vec3 const& v)
GLM_FUNC_DECL vec3 unpackUnorm1x5_1x6_1x5(uint16 p);
/// Convert each component of the normalized floating-point vector into unsigned integer values.
///
/// @see gtc_packing
/// @see vec4 unpackUnorm3x5_1x1(uint16 p)
GLM_FUNC_DECL uint16 packUnorm3x5_1x1(vec4 const& v);
/// Convert a packed integer to a normalized floating-point vector.
///
/// @see gtc_packing
/// @see uint16 packUnorm3x5_1x1(vec4 const& v)
GLM_FUNC_DECL vec4 unpackUnorm3x5_1x1(uint16 p);
/// Convert each component of the normalized floating-point vector into unsigned integer values.
///
/// @see gtc_packing
/// @see vec3 unpackUnorm2x3_1x2(uint8 p)
GLM_FUNC_DECL uint8 packUnorm2x3_1x2(vec3 const& v);
/// Convert a packed integer to a normalized floating-point vector.
///
/// @see gtc_packing
/// @see uint8 packUnorm2x3_1x2(vec3 const& v)
GLM_FUNC_DECL vec3 unpackUnorm2x3_1x2(uint8 p);
/// Convert each component from an integer vector into a packed integer.
///
/// @see gtc_packing
/// @see i8vec2 unpackInt2x8(int16 p)
GLM_FUNC_DECL int16 packInt2x8(i8vec2 const& v);
/// Convert a packed integer into an integer vector.
///
/// @see gtc_packing
/// @see int16 packInt2x8(i8vec2 const& v)
GLM_FUNC_DECL i8vec2 unpackInt2x8(int16 p);
/// Convert each component from an integer vector into a packed unsigned integer.
///
/// @see gtc_packing
/// @see u8vec2 unpackInt2x8(uint16 p)
GLM_FUNC_DECL uint16 packUint2x8(u8vec2 const& v);
/// Convert a packed integer into an integer vector.
///
/// @see gtc_packing
/// @see uint16 packInt2x8(u8vec2 const& v)
GLM_FUNC_DECL u8vec2 unpackUint2x8(uint16 p);
/// Convert each component from an integer vector into a packed integer.
///
/// @see gtc_packing
/// @see i8vec4 unpackInt4x8(int32 p)
GLM_FUNC_DECL int32 packInt4x8(i8vec4 const& v);
/// Convert a packed integer into an integer vector.
///
/// @see gtc_packing
/// @see int32 packInt2x8(i8vec4 const& v)
GLM_FUNC_DECL i8vec4 unpackInt4x8(int32 p);
/// Convert each component from an integer vector into a packed unsigned integer.
///
/// @see gtc_packing
/// @see u8vec4 unpackUint4x8(uint32 p)
GLM_FUNC_DECL uint32 packUint4x8(u8vec4 const& v);
/// Convert a packed integer into an integer vector.
///
/// @see gtc_packing
/// @see uint32 packUint4x8(u8vec2 const& v)
GLM_FUNC_DECL u8vec4 unpackUint4x8(uint32 p);
/// Convert each component from an integer vector into a packed integer.
///
/// @see gtc_packing
/// @see i16vec2 unpackInt2x16(int p)
GLM_FUNC_DECL int packInt2x16(i16vec2 const& v);
/// Convert a packed integer into an integer vector.
///
/// @see gtc_packing
/// @see int packInt2x16(i16vec2 const& v)
GLM_FUNC_DECL i16vec2 unpackInt2x16(int p);
/// Convert each component from an integer vector into a packed integer.
///
/// @see gtc_packing
/// @see i16vec4 unpackInt4x16(int64 p)
GLM_FUNC_DECL int64 packInt4x16(i16vec4 const& v);
/// Convert a packed integer into an integer vector.
///
/// @see gtc_packing
/// @see int64 packInt4x16(i16vec4 const& v)
GLM_FUNC_DECL i16vec4 unpackInt4x16(int64 p);
/// Convert each component from an integer vector into a packed unsigned integer.
///
/// @see gtc_packing
/// @see u16vec2 unpackUint2x16(uint p)
GLM_FUNC_DECL uint packUint2x16(u16vec2 const& v);
/// Convert a packed integer into an integer vector.
///
/// @see gtc_packing
/// @see uint packUint2x16(u16vec2 const& v)
GLM_FUNC_DECL u16vec2 unpackUint2x16(uint p);
/// Convert each component from an integer vector into a packed unsigned integer.
///
/// @see gtc_packing
/// @see u16vec4 unpackUint4x16(uint64 p)
GLM_FUNC_DECL uint64 packUint4x16(u16vec4 const& v);
/// Convert a packed integer into an integer vector.
///
/// @see gtc_packing
/// @see uint64 packUint4x16(u16vec4 const& v)
GLM_FUNC_DECL u16vec4 unpackUint4x16(uint64 p);
/// Convert each component from an integer vector into a packed integer.
///
/// @see gtc_packing
/// @see i32vec2 unpackInt2x32(int p)
GLM_FUNC_DECL int64 packInt2x32(i32vec2 const& v);
/// Convert a packed integer into an integer vector.
///
/// @see gtc_packing
/// @see int packInt2x16(i32vec2 const& v)
GLM_FUNC_DECL i32vec2 unpackInt2x32(int64 p);
/// Convert each component from an integer vector into a packed unsigned integer.
///
/// @see gtc_packing
/// @see u32vec2 unpackUint2x32(int p)
GLM_FUNC_DECL uint64 packUint2x32(u32vec2 const& v);
/// Convert a packed integer into an integer vector.
///
/// @see gtc_packing
/// @see int packUint2x16(u32vec2 const& v)
GLM_FUNC_DECL u32vec2 unpackUint2x32(uint64 p);
/// @}
}// namespace glm
#include "packing.inl"
+952
View File
@@ -0,0 +1,952 @@
/// @ref gtc_packing
#include "../ext/scalar_relational.hpp"
#include "../ext/vector_relational.hpp"
#include "../common.hpp"
#include "../vec2.hpp"
#include "../vec3.hpp"
#include "../vec4.hpp"
#include "../detail/type_half.hpp"
#include "type_ptr.hpp"
#include <cstring>
#include <limits>
namespace glm{
namespace detail
{
GLM_FUNC_QUALIFIER glm::uint16 float2half(glm::uint32 f)
{
// 10 bits => EE EEEFFFFF
// 11 bits => EEE EEFFFFFF
// Half bits => SEEEEEFF FFFFFFFF
// Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
// 0x00007c00 => 00000000 00000000 01111100 00000000
// 0x000003ff => 00000000 00000000 00000011 11111111
// 0x38000000 => 00111000 00000000 00000000 00000000
// 0x7f800000 => 01111111 10000000 00000000 00000000
// 0x00008000 => 00000000 00000000 10000000 00000000
return
((f >> 16) & 0x8000) | // sign
((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00) | // exponential
((f >> 13) & 0x03ff); // Mantissa
}
GLM_FUNC_QUALIFIER glm::uint32 float2packed11(glm::uint32 f)
{
// 10 bits => EE EEEFFFFF
// 11 bits => EEE EEFFFFFF
// Half bits => SEEEEEFF FFFFFFFF
// Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
// 0x000007c0 => 00000000 00000000 00000111 11000000
// 0x00007c00 => 00000000 00000000 01111100 00000000
// 0x000003ff => 00000000 00000000 00000011 11111111
// 0x38000000 => 00111000 00000000 00000000 00000000
// 0x7f800000 => 01111111 10000000 00000000 00000000
// 0x00008000 => 00000000 00000000 10000000 00000000
return
((((f & 0x7f800000) - 0x38000000) >> 17) & 0x07c0) | // exponential
((f >> 17) & 0x003f); // Mantissa
}
GLM_FUNC_QUALIFIER glm::uint32 packed11ToFloat(glm::uint32 p)
{
// 10 bits => EE EEEFFFFF
// 11 bits => EEE EEFFFFFF
// Half bits => SEEEEEFF FFFFFFFF
// Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
// 0x000007c0 => 00000000 00000000 00000111 11000000
// 0x00007c00 => 00000000 00000000 01111100 00000000
// 0x000003ff => 00000000 00000000 00000011 11111111
// 0x38000000 => 00111000 00000000 00000000 00000000
// 0x7f800000 => 01111111 10000000 00000000 00000000
// 0x00008000 => 00000000 00000000 10000000 00000000
return
((((p & 0x07c0) << 17) + 0x38000000) & 0x7f800000) | // exponential
((p & 0x003f) << 17); // Mantissa
}
GLM_FUNC_QUALIFIER glm::uint32 float2packed10(glm::uint32 f)
{
// 10 bits => EE EEEFFFFF
// 11 bits => EEE EEFFFFFF
// Half bits => SEEEEEFF FFFFFFFF
// Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
// 0x0000001F => 00000000 00000000 00000000 00011111
// 0x0000003F => 00000000 00000000 00000000 00111111
// 0x000003E0 => 00000000 00000000 00000011 11100000
// 0x000007C0 => 00000000 00000000 00000111 11000000
// 0x00007C00 => 00000000 00000000 01111100 00000000
// 0x000003FF => 00000000 00000000 00000011 11111111
// 0x38000000 => 00111000 00000000 00000000 00000000
// 0x7f800000 => 01111111 10000000 00000000 00000000
// 0x00008000 => 00000000 00000000 10000000 00000000
return
((((f & 0x7f800000) - 0x38000000) >> 18) & 0x03E0) | // exponential
((f >> 18) & 0x001f); // Mantissa
}
GLM_FUNC_QUALIFIER glm::uint32 packed10ToFloat(glm::uint32 p)
{
// 10 bits => EE EEEFFFFF
// 11 bits => EEE EEFFFFFF
// Half bits => SEEEEEFF FFFFFFFF
// Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
// 0x0000001F => 00000000 00000000 00000000 00011111
// 0x0000003F => 00000000 00000000 00000000 00111111
// 0x000003E0 => 00000000 00000000 00000011 11100000
// 0x000007C0 => 00000000 00000000 00000111 11000000
// 0x00007C00 => 00000000 00000000 01111100 00000000
// 0x000003FF => 00000000 00000000 00000011 11111111
// 0x38000000 => 00111000 00000000 00000000 00000000
// 0x7f800000 => 01111111 10000000 00000000 00000000
// 0x00008000 => 00000000 00000000 10000000 00000000
return
((((p & 0x03E0) << 18) + 0x38000000) & 0x7f800000) | // exponential
((p & 0x001f) << 18); // Mantissa
}
GLM_FUNC_QUALIFIER glm::uint half2float(glm::uint h)
{
return ((h & 0x8000) << 16) | ((( h & 0x7c00) + 0x1C000) << 13) | ((h & 0x03FF) << 13);
}
GLM_FUNC_QUALIFIER glm::uint floatTo11bit(float x)
{
if(x == 0.0f)
return 0u;
else if(glm::isnan(x))
return ~0u;
else if(glm::isinf(x))
return 0x1Fu << 6u;
uint Pack = 0u;
memcpy(&Pack, &x, sizeof(Pack));
return float2packed11(Pack);
}
GLM_FUNC_QUALIFIER float packed11bitToFloat(glm::uint x)
{
if(x == 0)
return 0.0f;
else if(x == ((1 << 11) - 1))
return ~0;//NaN
else if(x == (0x1f << 6))
return ~0;//Inf
uint Result = packed11ToFloat(x);
float Temp = 0;
memcpy(&Temp, &Result, sizeof(Temp));
return Temp;
}
GLM_FUNC_QUALIFIER glm::uint floatTo10bit(float x)
{
if(x == 0.0f)
return 0u;
else if(glm::isnan(x))
return ~0u;
else if(glm::isinf(x))
return 0x1Fu << 5u;
uint Pack = 0;
memcpy(&Pack, &x, sizeof(Pack));
return float2packed10(Pack);
}
GLM_FUNC_QUALIFIER float packed10bitToFloat(glm::uint x)
{
if(x == 0)
return 0.0f;
else if(x == ((1 << 10) - 1))
return ~0;//NaN
else if(x == (0x1f << 5))
return ~0;//Inf
uint Result = packed10ToFloat(x);
float Temp = 0;
memcpy(&Temp, &Result, sizeof(Temp));
return Temp;
}
// GLM_FUNC_QUALIFIER glm::uint f11_f11_f10(float x, float y, float z)
// {
// return ((floatTo11bit(x) & ((1 << 11) - 1)) << 0) | ((floatTo11bit(y) & ((1 << 11) - 1)) << 11) | ((floatTo10bit(z) & ((1 << 10) - 1)) << 22);
// }
#if GLM_SILENT_WARNINGS == GLM_ENABLE
# if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wpadded"
# endif
#endif
union u3u3u2
{
struct Data
{
uint x : 3;
uint y : 3;
uint z : 2;
} data;
uint8 pack;
};
union u4u4
{
struct Data
{
uint x : 4;
uint y : 4;
} data;
uint8 pack;
};
union u4u4u4u4
{
struct Data
{
uint x : 4;
uint y : 4;
uint z : 4;
uint w : 4;
} data;
uint16 pack;
};
union u5u6u5
{
struct Data
{
uint x : 5;
uint y : 6;
uint z : 5;
} data;
uint16 pack;
};
union u5u5u5u1
{
struct Data
{
uint x : 5;
uint y : 5;
uint z : 5;
uint w : 1;
} data;
uint16 pack;
};
#if GLM_SILENT_WARNINGS == GLM_ENABLE
# if defined(__clang__)
# pragma clang diagnostic pop
# endif
#endif
union u10u10u10u2
{
struct Data
{
uint x : 10;
uint y : 10;
uint z : 10;
uint w : 2;
} data;
uint32 pack;
};
union i10i10i10i2
{
struct Data
{
int x : 10;
int y : 10;
int z : 10;
int w : 2;
} data;
uint32 pack;
};
union u9u9u9e5
{
struct Data
{
uint x : 9;
uint y : 9;
uint z : 9;
uint w : 5;
} data;
uint32 pack;
};
template<length_t L, qualifier Q>
struct compute_half
{};
template<qualifier Q>
struct compute_half<1, Q>
{
GLM_FUNC_QUALIFIER static vec<1, uint16, Q> pack(vec<1, float, Q> const& v)
{
int16 const Unpack(detail::toFloat16(v.x));
u16vec1 Packed;
memcpy(value_ptr(Packed), &Unpack, sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER static vec<1, float, Q> unpack(vec<1, uint16, Q> const& v)
{
i16vec1 Unpack;
memcpy(value_ptr(Unpack), value_ptr(v), sizeof(Unpack));
return vec<1, float, Q>(detail::toFloat32(v.x));
}
};
template<qualifier Q>
struct compute_half<2, Q>
{
GLM_FUNC_QUALIFIER static vec<2, uint16, Q> pack(vec<2, float, Q> const& v)
{
vec<2, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y));
u16vec2 Packed;
memcpy(value_ptr(Packed), value_ptr(Unpack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER static vec<2, float, Q> unpack(vec<2, uint16, Q> const& v)
{
i16vec2 Unpack;
memcpy(value_ptr(Unpack), value_ptr(v), sizeof(Unpack));
return vec<2, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y));
}
};
template<qualifier Q>
struct compute_half<3, Q>
{
GLM_FUNC_QUALIFIER static vec<3, uint16, Q> pack(vec<3, float, Q> const& v)
{
vec<3, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y), detail::toFloat16(v.z));
u16vec3 Packed;
memcpy(value_ptr(Packed), value_ptr(Unpack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER static vec<3, float, Q> unpack(vec<3, uint16, Q> const& v)
{
i16vec3 Unpack;
memcpy(value_ptr(Unpack), &v, sizeof(Unpack));
return vec<3, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y), detail::toFloat32(v.z));
}
};
template<qualifier Q>
struct compute_half<4, Q>
{
GLM_FUNC_QUALIFIER static vec<4, uint16, Q> pack(vec<4, float, Q> const& v)
{
vec<4, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y), detail::toFloat16(v.z), detail::toFloat16(v.w));
u16vec4 Packed;
memcpy(value_ptr(Packed), value_ptr(Unpack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER static vec<4, float, Q> unpack(vec<4, uint16, Q> const& v)
{
i16vec4 Unpack;
memcpy(value_ptr(Unpack), &v, sizeof(Unpack));
return vec<4, float, Q>(detail::toFloat32(Unpack.x), detail::toFloat32(Unpack.y), detail::toFloat32(Unpack.z), detail::toFloat32(Unpack.w));
}
};
}//namespace detail
GLM_FUNC_QUALIFIER uint8 packUnorm1x8(float v)
{
return static_cast<uint8>(round(clamp(v, 0.0f, 1.0f) * 255.0f));
}
GLM_FUNC_QUALIFIER float unpackUnorm1x8(uint8 p)
{
float const Unpack(p);
return Unpack * static_cast<float>(0.0039215686274509803921568627451); // 1 / 255
}
GLM_FUNC_QUALIFIER uint16 packUnorm2x8(vec2 const& v)
{
u8vec2 const Topack(round(clamp(v, 0.0f, 1.0f) * 255.0f));
uint16 Unpack = 0;
memcpy(&Unpack, &Topack, sizeof(Unpack));
return Unpack;
}
GLM_FUNC_QUALIFIER vec2 unpackUnorm2x8(uint16 p)
{
u8vec2 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return vec2(Unpack) * float(0.0039215686274509803921568627451); // 1 / 255
}
GLM_FUNC_QUALIFIER uint8 packSnorm1x8(float v)
{
int8 const Topack(static_cast<int8>(round(clamp(v ,-1.0f, 1.0f) * 127.0f)));
uint8 Packed = 0;
memcpy(&Packed, &Topack, sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER float unpackSnorm1x8(uint8 p)
{
int8 Unpack = 0;
memcpy(&Unpack, &p, sizeof(Unpack));
return clamp(
static_cast<float>(Unpack) * 0.00787401574803149606299212598425f, // 1.0f / 127.0f
-1.0f, 1.0f);
}
GLM_FUNC_QUALIFIER uint16 packSnorm2x8(vec2 const& v)
{
i8vec2 const Topack(round(clamp(v, -1.0f, 1.0f) * 127.0f));
uint16 Packed = 0;
memcpy(&Packed, value_ptr(Topack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER vec2 unpackSnorm2x8(uint16 p)
{
i8vec2 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return clamp(
vec2(Unpack) * 0.00787401574803149606299212598425f, // 1.0f / 127.0f
-1.0f, 1.0f);
}
GLM_FUNC_QUALIFIER uint16 packUnorm1x16(float s)
{
return static_cast<uint16>(round(clamp(s, 0.0f, 1.0f) * 65535.0f));
}
GLM_FUNC_QUALIFIER float unpackUnorm1x16(uint16 p)
{
float const Unpack(p);
return Unpack * 1.5259021896696421759365224689097e-5f; // 1.0 / 65535.0
}
GLM_FUNC_QUALIFIER uint64 packUnorm4x16(vec4 const& v)
{
u16vec4 const Topack(round(clamp(v , 0.0f, 1.0f) * 65535.0f));
uint64 Packed = 0;
memcpy(&Packed, &Topack, sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER vec4 unpackUnorm4x16(uint64 p)
{
u16vec4 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return vec4(Unpack) * 1.5259021896696421759365224689097e-5f; // 1.0 / 65535.0
}
GLM_FUNC_QUALIFIER uint16 packSnorm1x16(float v)
{
int16 const Topack = static_cast<int16>(round(clamp(v ,-1.0f, 1.0f) * 32767.0f));
uint16 Packed = 0;
memcpy(&Packed, &Topack, sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER float unpackSnorm1x16(uint16 p)
{
int16 Unpack = 0;
memcpy(&Unpack, &p, sizeof(Unpack));
return clamp(
static_cast<float>(Unpack) * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f,
-1.0f, 1.0f);
}
GLM_FUNC_QUALIFIER uint64 packSnorm4x16(vec4 const& v)
{
i16vec4 const Topack(round(clamp(v ,-1.0f, 1.0f) * 32767.0f));
uint64 Packed = 0;
memcpy(&Packed, value_ptr(Topack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER vec4 unpackSnorm4x16(uint64 p)
{
i16vec4 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return clamp(
vec4(Unpack) * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f,
-1.0f, 1.0f);
}
GLM_FUNC_QUALIFIER uint16 packHalf1x16(float v)
{
int16 const Topack(detail::toFloat16(v));
uint16 Packed = 0;
memcpy(&Packed, &Topack, sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER float unpackHalf1x16(uint16 v)
{
int16 Unpack = 0;
memcpy(&Unpack, &v, sizeof(Unpack));
return detail::toFloat32(Unpack);
}
GLM_FUNC_QUALIFIER uint64 packHalf4x16(glm::vec4 const& v)
{
i16vec4 const Unpack(
detail::toFloat16(v.x),
detail::toFloat16(v.y),
detail::toFloat16(v.z),
detail::toFloat16(v.w));
uint64 Packed = 0;
memcpy(&Packed, value_ptr(Unpack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER glm::vec4 unpackHalf4x16(uint64 v)
{
i16vec4 Unpack;
memcpy(value_ptr(Unpack), &v, sizeof(Unpack));
return vec4(
detail::toFloat32(Unpack.x),
detail::toFloat32(Unpack.y),
detail::toFloat32(Unpack.z),
detail::toFloat32(Unpack.w));
}
GLM_FUNC_QUALIFIER uint32 packI3x10_1x2(ivec4 const& v)
{
detail::i10i10i10i2 Result;
Result.data.x = v.x;
Result.data.y = v.y;
Result.data.z = v.z;
Result.data.w = v.w;
return Result.pack;
}
GLM_FUNC_QUALIFIER ivec4 unpackI3x10_1x2(uint32 v)
{
detail::i10i10i10i2 Unpack;
Unpack.pack = v;
return ivec4(
Unpack.data.x,
Unpack.data.y,
Unpack.data.z,
Unpack.data.w);
}
GLM_FUNC_QUALIFIER uint32 packU3x10_1x2(uvec4 const& v)
{
detail::u10u10u10u2 Result;
Result.data.x = v.x;
Result.data.y = v.y;
Result.data.z = v.z;
Result.data.w = v.w;
return Result.pack;
}
GLM_FUNC_QUALIFIER uvec4 unpackU3x10_1x2(uint32 v)
{
detail::u10u10u10u2 Unpack;
Unpack.pack = v;
return uvec4(
Unpack.data.x,
Unpack.data.y,
Unpack.data.z,
Unpack.data.w);
}
GLM_FUNC_QUALIFIER uint32 packSnorm3x10_1x2(vec4 const& v)
{
ivec4 const Pack(round(clamp(v,-1.0f, 1.0f) * vec4(511.f, 511.f, 511.f, 1.f)));
detail::i10i10i10i2 Result;
Result.data.x = Pack.x;
Result.data.y = Pack.y;
Result.data.z = Pack.z;
Result.data.w = Pack.w;
return Result.pack;
}
GLM_FUNC_QUALIFIER vec4 unpackSnorm3x10_1x2(uint32 v)
{
detail::i10i10i10i2 Unpack;
Unpack.pack = v;
vec4 const Result(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w);
return clamp(Result * vec4(1.f / 511.f, 1.f / 511.f, 1.f / 511.f, 1.f), -1.0f, 1.0f);
}
GLM_FUNC_QUALIFIER uint32 packUnorm3x10_1x2(vec4 const& v)
{
uvec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec4(1023.f, 1023.f, 1023.f, 3.f)));
detail::u10u10u10u2 Result;
Result.data.x = Unpack.x;
Result.data.y = Unpack.y;
Result.data.z = Unpack.z;
Result.data.w = Unpack.w;
return Result.pack;
}
GLM_FUNC_QUALIFIER vec4 unpackUnorm3x10_1x2(uint32 v)
{
vec4 const ScaleFactors(1.0f / 1023.f, 1.0f / 1023.f, 1.0f / 1023.f, 1.0f / 3.f);
detail::u10u10u10u2 Unpack;
Unpack.pack = v;
return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactors;
}
GLM_FUNC_QUALIFIER uint32 packF2x11_1x10(vec3 const& v)
{
return
((detail::floatTo11bit(v.x) & ((1 << 11) - 1)) << 0) |
((detail::floatTo11bit(v.y) & ((1 << 11) - 1)) << 11) |
((detail::floatTo10bit(v.z) & ((1 << 10) - 1)) << 22);
}
GLM_FUNC_QUALIFIER vec3 unpackF2x11_1x10(uint32 v)
{
return vec3(
detail::packed11bitToFloat(v >> 0),
detail::packed11bitToFloat(v >> 11),
detail::packed10bitToFloat(v >> 22));
}
GLM_FUNC_QUALIFIER uint32 packF3x9_E1x5(vec3 const& v)
{
float const SharedExpMax = (pow(2.0f, 9.0f - 1.0f) / pow(2.0f, 9.0f)) * pow(2.0f, 31.f - 15.f);
vec3 const Color = clamp(v, 0.0f, SharedExpMax);
float const MaxColor = max(Color.x, max(Color.y, Color.z));
float const ExpSharedP = max(-15.f - 1.f, floor(log2(MaxColor))) + 1.0f + 15.f;
float const MaxShared = floor(MaxColor / pow(2.0f, (ExpSharedP - 15.f - 9.f)) + 0.5f);
float const ExpShared = equal(MaxShared, pow(2.0f, 9.0f), epsilon<float>()) ? ExpSharedP + 1.0f : ExpSharedP;
uvec3 const ColorComp(floor(Color / pow(2.f, (ExpShared - 15.f - 9.f)) + 0.5f));
detail::u9u9u9e5 Unpack;
Unpack.data.x = ColorComp.x;
Unpack.data.y = ColorComp.y;
Unpack.data.z = ColorComp.z;
Unpack.data.w = uint(ExpShared);
return Unpack.pack;
}
GLM_FUNC_QUALIFIER vec3 unpackF3x9_E1x5(uint32 v)
{
detail::u9u9u9e5 Unpack;
Unpack.pack = v;
return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * pow(2.0f, static_cast<float>(Unpack.data.w) - 15.f - 9.f);
}
// Based on Brian Karis http://graphicrants.blogspot.fr/2009/04/rgbm-color-encoding.html
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, T, Q> packRGBM(vec<3, T, Q> const& rgb)
{
vec<3, T, Q> const Color(rgb * static_cast<T>(1.0 / 6.0));
T Alpha = clamp(max(max(Color.x, Color.y), max(Color.z, static_cast<T>(1e-6))), static_cast<T>(0), static_cast<T>(1));
Alpha = ceil(Alpha * static_cast<T>(255.0)) / static_cast<T>(255.0);
return vec<4, T, Q>(Color / Alpha, Alpha);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> unpackRGBM(vec<4, T, Q> const& rgbm)
{
return vec<3, T, Q>(rgbm.x, rgbm.y, rgbm.z) * rgbm.w * static_cast<T>(6);
}
template<length_t L, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, uint16, Q> packHalf(vec<L, float, Q> const& v)
{
return detail::compute_half<L, Q>::pack(v);
}
template<length_t L, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, float, Q> unpackHalf(vec<L, uint16, Q> const& v)
{
return detail::compute_half<L, Q>::unpack(v);
}
template<typename uintType, length_t L, typename floatType, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, uintType, Q> packUnorm(vec<L, floatType, Q> const& v)
{
GLM_STATIC_ASSERT(std::numeric_limits<uintType>::is_integer, "uintType must be an integer type");
GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "floatType must be a floating point type");
return vec<L, uintType, Q>(round(clamp(v, static_cast<floatType>(0), static_cast<floatType>(1)) * static_cast<floatType>(std::numeric_limits<uintType>::max())));
}
template<typename floatType, length_t L, typename uintType, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, floatType, Q> unpackUnorm(vec<L, uintType, Q> const& v)
{
GLM_STATIC_ASSERT(std::numeric_limits<uintType>::is_integer, "uintType must be an integer type");
GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "floatType must be a floating point type");
return vec<L, floatType, Q>(v) * (static_cast<floatType>(1) / static_cast<floatType>(std::numeric_limits<uintType>::max()));
}
template<typename intType, length_t L, typename floatType, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, intType, Q> packSnorm(vec<L, floatType, Q> const& v)
{
GLM_STATIC_ASSERT(std::numeric_limits<intType>::is_integer, "uintType must be an integer type");
GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "floatType must be a floating point type");
return vec<L, intType, Q>(round(clamp(v , static_cast<floatType>(-1), static_cast<floatType>(1)) * static_cast<floatType>(std::numeric_limits<intType>::max())));
}
template<typename floatType, length_t L, typename intType, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, floatType, Q> unpackSnorm(vec<L, intType, Q> const& v)
{
GLM_STATIC_ASSERT(std::numeric_limits<intType>::is_integer, "uintType must be an integer type");
GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "floatType must be a floating point type");
return clamp(vec<L, floatType, Q>(v) * (static_cast<floatType>(1) / static_cast<floatType>(std::numeric_limits<intType>::max())), static_cast<floatType>(-1), static_cast<floatType>(1));
}
GLM_FUNC_QUALIFIER uint8 packUnorm2x4(vec2 const& v)
{
u32vec2 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f));
detail::u4u4 Result;
Result.data.x = Unpack.x;
Result.data.y = Unpack.y;
return Result.pack;
}
GLM_FUNC_QUALIFIER vec2 unpackUnorm2x4(uint8 v)
{
float const ScaleFactor(1.f / 15.f);
detail::u4u4 Unpack;
Unpack.pack = v;
return vec2(Unpack.data.x, Unpack.data.y) * ScaleFactor;
}
GLM_FUNC_QUALIFIER uint16 packUnorm4x4(vec4 const& v)
{
u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f));
detail::u4u4u4u4 Result;
Result.data.x = Unpack.x;
Result.data.y = Unpack.y;
Result.data.z = Unpack.z;
Result.data.w = Unpack.w;
return Result.pack;
}
GLM_FUNC_QUALIFIER vec4 unpackUnorm4x4(uint16 v)
{
float const ScaleFactor(1.f / 15.f);
detail::u4u4u4u4 Unpack;
Unpack.pack = v;
return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor;
}
GLM_FUNC_QUALIFIER uint16 packUnorm1x5_1x6_1x5(vec3 const& v)
{
u32vec3 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec3(31.f, 63.f, 31.f)));
detail::u5u6u5 Result;
Result.data.x = Unpack.x;
Result.data.y = Unpack.y;
Result.data.z = Unpack.z;
return Result.pack;
}
GLM_FUNC_QUALIFIER vec3 unpackUnorm1x5_1x6_1x5(uint16 v)
{
vec3 const ScaleFactor(1.f / 31.f, 1.f / 63.f, 1.f / 31.f);
detail::u5u6u5 Unpack;
Unpack.pack = v;
return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor;
}
GLM_FUNC_QUALIFIER uint16 packUnorm3x5_1x1(vec4 const& v)
{
u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec4(31.f, 31.f, 31.f, 1.f)));
detail::u5u5u5u1 Result;
Result.data.x = Unpack.x;
Result.data.y = Unpack.y;
Result.data.z = Unpack.z;
Result.data.w = Unpack.w;
return Result.pack;
}
GLM_FUNC_QUALIFIER vec4 unpackUnorm3x5_1x1(uint16 v)
{
vec4 const ScaleFactor(1.f / 31.f, 1.f / 31.f, 1.f / 31.f, 1.f);
detail::u5u5u5u1 Unpack;
Unpack.pack = v;
return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor;
}
GLM_FUNC_QUALIFIER uint8 packUnorm2x3_1x2(vec3 const& v)
{
u32vec3 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec3(7.f, 7.f, 3.f)));
detail::u3u3u2 Result;
Result.data.x = Unpack.x;
Result.data.y = Unpack.y;
Result.data.z = Unpack.z;
return Result.pack;
}
GLM_FUNC_QUALIFIER vec3 unpackUnorm2x3_1x2(uint8 v)
{
vec3 const ScaleFactor(1.f / 7.f, 1.f / 7.f, 1.f / 3.f);
detail::u3u3u2 Unpack;
Unpack.pack = v;
return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor;
}
GLM_FUNC_QUALIFIER int16 packInt2x8(i8vec2 const& v)
{
int16 Pack = 0;
memcpy(&Pack, &v, sizeof(Pack));
return Pack;
}
GLM_FUNC_QUALIFIER i8vec2 unpackInt2x8(int16 p)
{
i8vec2 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
GLM_FUNC_QUALIFIER uint16 packUint2x8(u8vec2 const& v)
{
uint16 Pack = 0;
memcpy(&Pack, &v, sizeof(Pack));
return Pack;
}
GLM_FUNC_QUALIFIER u8vec2 unpackUint2x8(uint16 p)
{
u8vec2 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
GLM_FUNC_QUALIFIER int32 packInt4x8(i8vec4 const& v)
{
int32 Pack = 0;
memcpy(&Pack, &v, sizeof(Pack));
return Pack;
}
GLM_FUNC_QUALIFIER i8vec4 unpackInt4x8(int32 p)
{
i8vec4 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
GLM_FUNC_QUALIFIER uint32 packUint4x8(u8vec4 const& v)
{
uint32 Pack = 0;
memcpy(&Pack, &v, sizeof(Pack));
return Pack;
}
GLM_FUNC_QUALIFIER u8vec4 unpackUint4x8(uint32 p)
{
u8vec4 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
GLM_FUNC_QUALIFIER int packInt2x16(i16vec2 const& v)
{
int Pack = 0;
memcpy(&Pack, &v, sizeof(Pack));
return Pack;
}
GLM_FUNC_QUALIFIER i16vec2 unpackInt2x16(int p)
{
i16vec2 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
GLM_FUNC_QUALIFIER int64 packInt4x16(i16vec4 const& v)
{
int64 Pack = 0;
memcpy(&Pack, &v, sizeof(Pack));
return Pack;
}
GLM_FUNC_QUALIFIER i16vec4 unpackInt4x16(int64 p)
{
i16vec4 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
GLM_FUNC_QUALIFIER uint packUint2x16(u16vec2 const& v)
{
uint Pack = 0;
memcpy(&Pack, &v, sizeof(Pack));
return Pack;
}
GLM_FUNC_QUALIFIER u16vec2 unpackUint2x16(uint p)
{
u16vec2 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
GLM_FUNC_QUALIFIER uint64 packUint4x16(u16vec4 const& v)
{
uint64 Pack = 0;
memcpy(&Pack, &v, sizeof(Pack));
return Pack;
}
GLM_FUNC_QUALIFIER u16vec4 unpackUint4x16(uint64 p)
{
u16vec4 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
GLM_FUNC_QUALIFIER int64 packInt2x32(i32vec2 const& v)
{
int64 Pack = 0;
memcpy(&Pack, &v, sizeof(Pack));
return Pack;
}
GLM_FUNC_QUALIFIER i32vec2 unpackInt2x32(int64 p)
{
i32vec2 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
GLM_FUNC_QUALIFIER uint64 packUint2x32(u32vec2 const& v)
{
uint64 Pack = 0;
memcpy(&Pack, &v, sizeof(Pack));
return Pack;
}
GLM_FUNC_QUALIFIER u32vec2 unpackUint2x32(uint64 p)
{
u32vec2 Unpack;
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
}//namespace glm
+173
View File
@@ -0,0 +1,173 @@
/// @ref gtc_quaternion
/// @file glm/gtc/quaternion.hpp
///
/// @see core (dependence)
/// @see gtc_constants (dependence)
///
/// @defgroup gtc_quaternion GLM_GTC_quaternion
/// @ingroup gtc
///
/// Include <glm/gtc/quaternion.hpp> to use the features of this extension.
///
/// Defines a templated quaternion type and several quaternion operations.
#pragma once
// Dependency:
#include "../gtc/constants.hpp"
#include "../gtc/matrix_transform.hpp"
#include "../ext/vector_relational.hpp"
#include "../ext/quaternion_common.hpp"
#include "../ext/quaternion_float.hpp"
#include "../ext/quaternion_float_precision.hpp"
#include "../ext/quaternion_double.hpp"
#include "../ext/quaternion_double_precision.hpp"
#include "../ext/quaternion_relational.hpp"
#include "../ext/quaternion_geometric.hpp"
#include "../ext/quaternion_trigonometric.hpp"
#include "../ext/quaternion_transform.hpp"
#include "../detail/type_mat3x3.hpp"
#include "../detail/type_mat4x4.hpp"
#include "../detail/type_vec3.hpp"
#include "../detail/type_vec4.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_quaternion extension included")
#endif
namespace glm
{
/// @addtogroup gtc_quaternion
/// @{
/// Returns euler angles, pitch as x, yaw as y, roll as z.
/// The result is expressed in radians.
///
/// @tparam T Floating-point scalar types.
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> eulerAngles(qua<T, Q> const& x);
/// Returns roll value of euler angles expressed in radians.
///
/// @tparam T Floating-point scalar types.
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL T roll(qua<T, Q> const& x);
/// Returns pitch value of euler angles expressed in radians.
///
/// @tparam T Floating-point scalar types.
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL T pitch(qua<T, Q> const& x);
/// Returns yaw value of euler angles expressed in radians.
///
/// @tparam T Floating-point scalar types.
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL T yaw(qua<T, Q> const& x);
/// Converts a quaternion to a 3 * 3 matrix.
///
/// @tparam T Floating-point scalar types.
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL mat<3, 3, T, Q> mat3_cast(qua<T, Q> const& x);
/// Converts a quaternion to a 4 * 4 matrix.
///
/// @tparam T Floating-point scalar types.
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL mat<4, 4, T, Q> mat4_cast(qua<T, Q> const& x);
/// Converts a pure rotation 3 * 3 matrix to a quaternion.
///
/// @tparam T Floating-point scalar types.
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> quat_cast(mat<3, 3, T, Q> const& x);
/// Converts a pure rotation 4 * 4 matrix to a quaternion.
///
/// @tparam T Floating-point scalar types.
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> quat_cast(mat<4, 4, T, Q> const& x);
/// Returns the component-wise comparison result of x < y.
///
/// @tparam T Floating-point scalar types
/// @tparam Q Value from qualifier enum
///
/// @see ext_quaternion_relational
template<typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR vec<4, bool, Q> lessThan(qua<T, Q> const& x, qua<T, Q> const& y);
/// Returns the component-wise comparison of result x <= y.
///
/// @tparam T Floating-point scalar types
/// @tparam Q Value from qualifier enum
///
/// @see ext_quaternion_relational
template<typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR vec<4, bool, Q> lessThanEqual(qua<T, Q> const& x, qua<T, Q> const& y);
/// Returns the component-wise comparison of result x > y.
///
/// @tparam T Floating-point scalar types
/// @tparam Q Value from qualifier enum
///
/// @see ext_quaternion_relational
template<typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR vec<4, bool, Q> greaterThan(qua<T, Q> const& x, qua<T, Q> const& y);
/// Returns the component-wise comparison of result x >= y.
///
/// @tparam T Floating-point scalar types
/// @tparam Q Value from qualifier enum
///
/// @see ext_quaternion_relational
template<typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR vec<4, bool, Q> greaterThanEqual(qua<T, Q> const& x, qua<T, Q> const& y);
/// Build a look at quaternion based on the default handedness.
///
/// @param direction Desired forward direction. Needs to be normalized.
/// @param up Up vector, how the camera is oriented. Typically (0, 1, 0).
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> quatLookAt(
vec<3, T, Q> const& direction,
vec<3, T, Q> const& up);
/// Build a right-handed look at quaternion.
///
/// @param direction Desired forward direction onto which the -z-axis gets mapped. Needs to be normalized.
/// @param up Up vector, how the camera is oriented. Typically (0, 1, 0).
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> quatLookAtRH(
vec<3, T, Q> const& direction,
vec<3, T, Q> const& up);
/// Build a left-handed look at quaternion.
///
/// @param direction Desired forward direction onto which the +z-axis gets mapped. Needs to be normalized.
/// @param up Up vector, how the camera is oriented. Typically (0, 1, 0).
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> quatLookAtLH(
vec<3, T, Q> const& direction,
vec<3, T, Q> const& up);
/// @}
} //namespace glm
#include "quaternion.inl"
+208
View File
@@ -0,0 +1,208 @@
#include "../trigonometric.hpp"
#include "../geometric.hpp"
#include "../exponential.hpp"
#include "epsilon.hpp"
#include <limits>
namespace glm
{
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> eulerAngles(qua<T, Q> const& x)
{
return vec<3, T, Q>(pitch(x), yaw(x), roll(x));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T roll(qua<T, Q> const& q)
{
T const y = static_cast<T>(2) * (q.x * q.y + q.w * q.z);
T const x = q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z;
if(all(equal(vec<2, T, Q>(x, y), vec<2, T, Q>(0), epsilon<T>()))) //avoid atan2(0,0) - handle singularity - Matiis
return static_cast<T>(0);
return static_cast<T>(atan(y, x));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T pitch(qua<T, Q> const& q)
{
//return T(atan(T(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z));
T const y = static_cast<T>(2) * (q.y * q.z + q.w * q.x);
T const x = q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z;
if(all(equal(vec<2, T, Q>(x, y), vec<2, T, Q>(0), epsilon<T>()))) //avoid atan2(0,0) - handle singularity - Matiis
return static_cast<T>(static_cast<T>(2) * atan(q.x, q.w));
return static_cast<T>(atan(y, x));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T yaw(qua<T, Q> const& q)
{
return asin(clamp(static_cast<T>(-2) * (q.x * q.z - q.w * q.y), static_cast<T>(-1), static_cast<T>(1)));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> mat3_cast(qua<T, Q> const& q)
{
mat<3, 3, T, Q> Result(T(1));
T qxx(q.x * q.x);
T qyy(q.y * q.y);
T qzz(q.z * q.z);
T qxz(q.x * q.z);
T qxy(q.x * q.y);
T qyz(q.y * q.z);
T qwx(q.w * q.x);
T qwy(q.w * q.y);
T qwz(q.w * q.z);
Result[0][0] = T(1) - T(2) * (qyy + qzz);
Result[0][1] = T(2) * (qxy + qwz);
Result[0][2] = T(2) * (qxz - qwy);
Result[1][0] = T(2) * (qxy - qwz);
Result[1][1] = T(1) - T(2) * (qxx + qzz);
Result[1][2] = T(2) * (qyz + qwx);
Result[2][0] = T(2) * (qxz + qwy);
Result[2][1] = T(2) * (qyz - qwx);
Result[2][2] = T(1) - T(2) * (qxx + qyy);
return Result;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> mat4_cast(qua<T, Q> const& q)
{
return mat<4, 4, T, Q>(mat3_cast(q));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> quat_cast(mat<3, 3, T, Q> const& m)
{
T fourXSquaredMinus1 = m[0][0] - m[1][1] - m[2][2];
T fourYSquaredMinus1 = m[1][1] - m[0][0] - m[2][2];
T fourZSquaredMinus1 = m[2][2] - m[0][0] - m[1][1];
T fourWSquaredMinus1 = m[0][0] + m[1][1] + m[2][2];
int biggestIndex = 0;
T fourBiggestSquaredMinus1 = fourWSquaredMinus1;
if(fourXSquaredMinus1 > fourBiggestSquaredMinus1)
{
fourBiggestSquaredMinus1 = fourXSquaredMinus1;
biggestIndex = 1;
}
if(fourYSquaredMinus1 > fourBiggestSquaredMinus1)
{
fourBiggestSquaredMinus1 = fourYSquaredMinus1;
biggestIndex = 2;
}
if(fourZSquaredMinus1 > fourBiggestSquaredMinus1)
{
fourBiggestSquaredMinus1 = fourZSquaredMinus1;
biggestIndex = 3;
}
T biggestVal = sqrt(fourBiggestSquaredMinus1 + static_cast<T>(1)) * static_cast<T>(0.5);
T mult = static_cast<T>(0.25) / biggestVal;
switch(biggestIndex)
{
case 0:
return qua<T, Q>::wxyz(biggestVal, (m[1][2] - m[2][1]) * mult, (m[2][0] - m[0][2]) * mult, (m[0][1] - m[1][0]) * mult);
case 1:
return qua<T, Q>::wxyz((m[1][2] - m[2][1]) * mult, biggestVal, (m[0][1] + m[1][0]) * mult, (m[2][0] + m[0][2]) * mult);
case 2:
return qua<T, Q>::wxyz((m[2][0] - m[0][2]) * mult, (m[0][1] + m[1][0]) * mult, biggestVal, (m[1][2] + m[2][1]) * mult);
case 3:
return qua<T, Q>::wxyz((m[0][1] - m[1][0]) * mult, (m[2][0] + m[0][2]) * mult, (m[1][2] + m[2][1]) * mult, biggestVal);
default: // Silence a -Wswitch-default warning in GCC. Should never actually get here. Assert is just for sanity.
assert(false);
return qua<T, Q>::wxyz(1, 0, 0, 0);
}
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> quat_cast(mat<4, 4, T, Q> const& m4)
{
return quat_cast(mat<3, 3, T, Q>(m4));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, bool, Q> lessThan(qua<T, Q> const& x, qua<T, Q> const& y)
{
vec<4, bool, Q> Result(false, false, false, false);
for(length_t i = 0; i < x.length(); ++i)
Result[i] = x[i] < y[i];
return Result;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, bool, Q> lessThanEqual(qua<T, Q> const& x, qua<T, Q> const& y)
{
vec<4, bool, Q> Result(false, false, false, false);
for(length_t i = 0; i < x.length(); ++i)
Result[i] = x[i] <= y[i];
return Result;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, bool, Q> greaterThan(qua<T, Q> const& x, qua<T, Q> const& y)
{
vec<4, bool, Q> Result(false, false, false, false);
for(length_t i = 0; i < x.length(); ++i)
Result[i] = x[i] > y[i];
return Result;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, bool, Q> greaterThanEqual(qua<T, Q> const& x, qua<T, Q> const& y)
{
vec<4, bool, Q> Result(false, false, false, false);
for(length_t i = 0; i < x.length(); ++i)
Result[i] = x[i] >= y[i];
return Result;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> quatLookAt(vec<3, T, Q> const& direction, vec<3, T, Q> const& up)
{
# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
return quatLookAtLH(direction, up);
# else
return quatLookAtRH(direction, up);
# endif
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> quatLookAtRH(vec<3, T, Q> const& direction, vec<3, T, Q> const& up)
{
mat<3, 3, T, Q> Result;
Result[2] = -direction;
vec<3, T, Q> const& Right = cross(up, Result[2]);
Result[0] = Right * inversesqrt(max(static_cast<T>(0.00001), dot(Right, Right)));
Result[1] = cross(Result[2], Result[0]);
return quat_cast(Result);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> quatLookAtLH(vec<3, T, Q> const& direction, vec<3, T, Q> const& up)
{
mat<3, 3, T, Q> Result;
Result[2] = direction;
vec<3, T, Q> const& Right = cross(up, Result[2]);
Result[0] = Right * inversesqrt(max(static_cast<T>(0.00001), dot(Right, Right)));
Result[1] = cross(Result[2], Result[0]);
return quat_cast(Result);
}
}//namespace glm
#if GLM_CONFIG_SIMD == GLM_ENABLE
# include "quaternion_simd.inl"
#endif
+82
View File
@@ -0,0 +1,82 @@
/// @ref gtc_random
/// @file glm/gtc/random.hpp
///
/// @see core (dependence)
/// @see gtx_random (extended)
///
/// @defgroup gtc_random GLM_GTC_random
/// @ingroup gtc
///
/// Include <glm/gtc/random.hpp> to use the features of this extension.
///
/// Generate random number from various distribution methods.
#pragma once
// Dependency:
#include "../ext/scalar_int_sized.hpp"
#include "../ext/scalar_uint_sized.hpp"
#include "../detail/qualifier.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_random extension included")
#endif
namespace glm
{
/// @addtogroup gtc_random
/// @{
/// Generate random numbers in the interval [Min, Max], according a linear distribution
///
/// @param Min Minimum value included in the sampling
/// @param Max Maximum value included in the sampling
/// @tparam genType Value type. Currently supported: float or double scalars.
/// @see gtc_random
template<typename genType>
GLM_FUNC_DECL genType linearRand(genType Min, genType Max);
/// Generate random numbers in the interval [Min, Max], according a linear distribution
///
/// @param Min Minimum value included in the sampling
/// @param Max Maximum value included in the sampling
/// @tparam T Value type. Currently supported: float or double.
///
/// @see gtc_random
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> linearRand(vec<L, T, Q> const& Min, vec<L, T, Q> const& Max);
/// Generate random numbers in the interval [Min, Max], according a gaussian distribution
///
/// @see gtc_random
template<typename genType>
GLM_FUNC_DECL genType gaussRand(genType Mean, genType Deviation);
/// Generate a random 2D vector which coordinates are regularly distributed on a circle of a given radius
///
/// @see gtc_random
template<typename T>
GLM_FUNC_DECL vec<2, T, defaultp> circularRand(T Radius);
/// Generate a random 3D vector which coordinates are regularly distributed on a sphere of a given radius
///
/// @see gtc_random
template<typename T>
GLM_FUNC_DECL vec<3, T, defaultp> sphericalRand(T Radius);
/// Generate a random 2D vector which coordinates are regularly distributed within the area of a disk of a given radius
///
/// @see gtc_random
template<typename T>
GLM_FUNC_DECL vec<2, T, defaultp> diskRand(T Radius);
/// Generate a random 3D vector which coordinates are regularly distributed within the volume of a ball of a given radius
///
/// @see gtc_random
template<typename T>
GLM_FUNC_DECL vec<3, T, defaultp> ballRand(T Radius);
/// @}
}//namespace glm
#include "random.inl"
+303
View File
@@ -0,0 +1,303 @@
#include "../geometric.hpp"
#include "../exponential.hpp"
#include "../trigonometric.hpp"
#include "../detail/type_vec1.hpp"
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <cmath>
namespace glm{
namespace detail
{
template <length_t L, typename T, qualifier Q>
struct compute_rand
{
GLM_FUNC_QUALIFIER static vec<L, T, Q> call();
};
template <qualifier P>
struct compute_rand<1, uint8, P>
{
GLM_FUNC_QUALIFIER static vec<1, uint8, P> call()
{
return vec<1, uint8, P>(
static_cast<uint8>(std::rand() % std::numeric_limits<uint8>::max()));
}
};
template <qualifier P>
struct compute_rand<2, uint8, P>
{
GLM_FUNC_QUALIFIER static vec<2, uint8, P> call()
{
return vec<2, uint8, P>(
std::rand() % std::numeric_limits<uint8>::max(),
std::rand() % std::numeric_limits<uint8>::max());
}
};
template <qualifier P>
struct compute_rand<3, uint8, P>
{
GLM_FUNC_QUALIFIER static vec<3, uint8, P> call()
{
return vec<3, uint8, P>(
std::rand() % std::numeric_limits<uint8>::max(),
std::rand() % std::numeric_limits<uint8>::max(),
std::rand() % std::numeric_limits<uint8>::max());
}
};
template <qualifier P>
struct compute_rand<4, uint8, P>
{
GLM_FUNC_QUALIFIER static vec<4, uint8, P> call()
{
return vec<4, uint8, P>(
std::rand() % std::numeric_limits<uint8>::max(),
std::rand() % std::numeric_limits<uint8>::max(),
std::rand() % std::numeric_limits<uint8>::max(),
std::rand() % std::numeric_limits<uint8>::max());
}
};
template <length_t L, qualifier Q>
struct compute_rand<L, uint16, Q>
{
GLM_FUNC_QUALIFIER static vec<L, uint16, Q> call()
{
return
(vec<L, uint16, Q>(compute_rand<L, uint8, Q>::call()) << static_cast<uint16>(8)) |
(vec<L, uint16, Q>(compute_rand<L, uint8, Q>::call()));
}
};
template <length_t L, qualifier Q>
struct compute_rand<L, uint32, Q>
{
GLM_FUNC_QUALIFIER static vec<L, uint32, Q> call()
{
return
(vec<L, uint32, Q>(compute_rand<L, uint16, Q>::call()) << static_cast<uint32>(16)) |
(vec<L, uint32, Q>(compute_rand<L, uint16, Q>::call()));
}
};
template <length_t L, qualifier Q>
struct compute_rand<L, uint64, Q>
{
GLM_FUNC_QUALIFIER static vec<L, uint64, Q> call()
{
return
(vec<L, uint64, Q>(compute_rand<L, uint32, Q>::call()) << static_cast<uint64>(32)) |
(vec<L, uint64, Q>(compute_rand<L, uint32, Q>::call()));
}
};
template <length_t L, typename T, qualifier Q>
struct compute_linearRand
{
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& Min, vec<L, T, Q> const& Max);
};
template<length_t L, qualifier Q>
struct compute_linearRand<L, int8, Q>
{
GLM_FUNC_QUALIFIER static vec<L, int8, Q> call(vec<L, int8, Q> const& Min, vec<L, int8, Q> const& Max)
{
return (vec<L, int8, Q>(compute_rand<L, uint8, Q>::call() % vec<L, uint8, Q>(Max + static_cast<int8>(1) - Min))) + Min;
}
};
template<length_t L, qualifier Q>
struct compute_linearRand<L, uint8, Q>
{
GLM_FUNC_QUALIFIER static vec<L, uint8, Q> call(vec<L, uint8, Q> const& Min, vec<L, uint8, Q> const& Max)
{
return (compute_rand<L, uint8, Q>::call() % (Max + static_cast<uint8>(1) - Min)) + Min;
}
};
template<length_t L, qualifier Q>
struct compute_linearRand<L, int16, Q>
{
GLM_FUNC_QUALIFIER static vec<L, int16, Q> call(vec<L, int16, Q> const& Min, vec<L, int16, Q> const& Max)
{
return (vec<L, int16, Q>(compute_rand<L, uint16, Q>::call() % vec<L, uint16, Q>(Max + static_cast<int16>(1) - Min))) + Min;
}
};
template<length_t L, qualifier Q>
struct compute_linearRand<L, uint16, Q>
{
GLM_FUNC_QUALIFIER static vec<L, uint16, Q> call(vec<L, uint16, Q> const& Min, vec<L, uint16, Q> const& Max)
{
return (compute_rand<L, uint16, Q>::call() % (Max + static_cast<uint16>(1) - Min)) + Min;
}
};
template<length_t L, qualifier Q>
struct compute_linearRand<L, int32, Q>
{
GLM_FUNC_QUALIFIER static vec<L, int32, Q> call(vec<L, int32, Q> const& Min, vec<L, int32, Q> const& Max)
{
return (vec<L, int32, Q>(compute_rand<L, uint32, Q>::call() % vec<L, uint32, Q>(Max + static_cast<int32>(1) - Min))) + Min;
}
};
template<length_t L, qualifier Q>
struct compute_linearRand<L, uint32, Q>
{
GLM_FUNC_QUALIFIER static vec<L, uint32, Q> call(vec<L, uint32, Q> const& Min, vec<L, uint32, Q> const& Max)
{
return (compute_rand<L, uint32, Q>::call() % (Max + static_cast<uint32>(1) - Min)) + Min;
}
};
template<length_t L, qualifier Q>
struct compute_linearRand<L, int64, Q>
{
GLM_FUNC_QUALIFIER static vec<L, int64, Q> call(vec<L, int64, Q> const& Min, vec<L, int64, Q> const& Max)
{
return (vec<L, int64, Q>(compute_rand<L, uint64, Q>::call() % vec<L, uint64, Q>(Max + static_cast<int64>(1) - Min))) + Min;
}
};
template<length_t L, qualifier Q>
struct compute_linearRand<L, uint64, Q>
{
GLM_FUNC_QUALIFIER static vec<L, uint64, Q> call(vec<L, uint64, Q> const& Min, vec<L, uint64, Q> const& Max)
{
return (compute_rand<L, uint64, Q>::call() % (Max + static_cast<uint64>(1) - Min)) + Min;
}
};
template<length_t L, qualifier Q>
struct compute_linearRand<L, float, Q>
{
GLM_FUNC_QUALIFIER static vec<L, float, Q> call(vec<L, float, Q> const& Min, vec<L, float, Q> const& Max)
{
return vec<L, float, Q>(compute_rand<L, uint32, Q>::call()) / static_cast<float>(std::numeric_limits<uint32>::max()) * (Max - Min) + Min;
}
};
template<length_t L, qualifier Q>
struct compute_linearRand<L, double, Q>
{
GLM_FUNC_QUALIFIER static vec<L, double, Q> call(vec<L, double, Q> const& Min, vec<L, double, Q> const& Max)
{
return vec<L, double, Q>(compute_rand<L, uint64, Q>::call()) / static_cast<double>(std::numeric_limits<uint64>::max()) * (Max - Min) + Min;
}
};
template<length_t L, qualifier Q>
struct compute_linearRand<L, long double, Q>
{
GLM_FUNC_QUALIFIER static vec<L, long double, Q> call(vec<L, long double, Q> const& Min, vec<L, long double, Q> const& Max)
{
return vec<L, long double, Q>(compute_rand<L, uint64, Q>::call()) / static_cast<long double>(std::numeric_limits<uint64>::max()) * (Max - Min) + Min;
}
};
}//namespace detail
template<typename genType>
GLM_FUNC_QUALIFIER genType linearRand(genType Min, genType Max)
{
return detail::compute_linearRand<1, genType, highp>::call(
vec<1, genType, highp>(Min),
vec<1, genType, highp>(Max)).x;
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> linearRand(vec<L, T, Q> const& Min, vec<L, T, Q> const& Max)
{
return detail::compute_linearRand<L, T, Q>::call(Min, Max);
}
template<typename genType>
GLM_FUNC_QUALIFIER genType gaussRand(genType Mean, genType Deviation)
{
genType w, x1, x2;
do
{
x1 = linearRand(genType(-1), genType(1));
x2 = linearRand(genType(-1), genType(1));
w = x1 * x1 + x2 * x2;
} while(w > genType(1));
return static_cast<genType>(x2 * Deviation * Deviation * sqrt((genType(-2) * log(w)) / w) + Mean);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> gaussRand(vec<L, T, Q> const& Mean, vec<L, T, Q> const& Deviation)
{
return detail::functor2<vec, L, T, Q>::call(gaussRand, Mean, Deviation);
}
template<typename T>
GLM_FUNC_QUALIFIER vec<2, T, defaultp> diskRand(T Radius)
{
assert(Radius > static_cast<T>(0));
vec<2, T, defaultp> Result(T(0));
T LenRadius(T(0));
do
{
Result = linearRand(
vec<2, T, defaultp>(-Radius),
vec<2, T, defaultp>(Radius));
LenRadius = length(Result);
}
while(LenRadius > Radius);
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER vec<3, T, defaultp> ballRand(T Radius)
{
assert(Radius > static_cast<T>(0));
vec<3, T, defaultp> Result(T(0));
T LenRadius(T(0));
do
{
Result = linearRand(
vec<3, T, defaultp>(-Radius),
vec<3, T, defaultp>(Radius));
LenRadius = length(Result);
}
while(LenRadius > Radius);
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER vec<2, T, defaultp> circularRand(T Radius)
{
assert(Radius > static_cast<T>(0));
T a = linearRand(T(0), static_cast<T>(6.283185307179586476925286766559));
return vec<2, T, defaultp>(glm::cos(a), glm::sin(a)) * Radius;
}
template<typename T>
GLM_FUNC_QUALIFIER vec<3, T, defaultp> sphericalRand(T Radius)
{
assert(Radius > static_cast<T>(0));
T theta = linearRand(T(0), T(6.283185307179586476925286766559f));
T phi = std::acos(linearRand(T(-1.0f), T(1.0f)));
T x = std::sin(phi) * std::cos(theta);
T y = std::sin(phi) * std::sin(theta);
T z = std::cos(phi);
return vec<3, T, defaultp>(x, y, z) * Radius;
}
}//namespace glm
+24
View File
@@ -0,0 +1,24 @@
/// @ref gtc_reciprocal
/// @file glm/gtc/reciprocal.hpp
///
/// @see core (dependence)
///
/// @defgroup gtc_reciprocal GLM_GTC_reciprocal
/// @ingroup gtc
///
/// Include <glm/gtc/reciprocal.hpp> to use the features of this extension.
///
/// Define secant, cosecant and cotangent functions.
#pragma once
// Dependencies
#include "../detail/setup.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_reciprocal extension included")
#endif
#include "../ext/scalar_reciprocal.hpp"
#include "../ext/vector_reciprocal.hpp"
+160
View File
@@ -0,0 +1,160 @@
/// @ref gtc_round
/// @file glm/gtc/round.hpp
///
/// @see core (dependence)
/// @see gtc_round (dependence)
///
/// @defgroup gtc_round GLM_GTC_round
/// @ingroup gtc
///
/// Include <glm/gtc/round.hpp> to use the features of this extension.
///
/// Rounding value to specific boundings
#pragma once
// Dependencies
#include "../detail/setup.hpp"
#include "../detail/qualifier.hpp"
#include "../detail/_vectorize.hpp"
#include "../vector_relational.hpp"
#include "../common.hpp"
#include <limits>
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_round extension included")
#endif
namespace glm
{
/// @addtogroup gtc_round
/// @{
/// Return the power of two number which value is just higher the input value,
/// round up to a power of two.
///
/// @see gtc_round
template<typename genIUType>
GLM_FUNC_DECL genIUType ceilPowerOfTwo(genIUType v);
/// Return the power of two number which value is just higher the input value,
/// round up to a power of two.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point or integer scalar types
/// @tparam Q Value from qualifier enum
///
/// @see gtc_round
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> ceilPowerOfTwo(vec<L, T, Q> const& v);
/// Return the power of two number which value is just lower the input value,
/// round down to a power of two.
///
/// @see gtc_round
template<typename genIUType>
GLM_FUNC_DECL genIUType floorPowerOfTwo(genIUType v);
/// Return the power of two number which value is just lower the input value,
/// round down to a power of two.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point or integer scalar types
/// @tparam Q Value from qualifier enum
///
/// @see gtc_round
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> floorPowerOfTwo(vec<L, T, Q> const& v);
/// Return the power of two number which value is the closet to the input value.
///
/// @see gtc_round
template<typename genIUType>
GLM_FUNC_DECL genIUType roundPowerOfTwo(genIUType v);
/// Return the power of two number which value is the closet to the input value.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point or integer scalar types
/// @tparam Q Value from qualifier enum
///
/// @see gtc_round
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> roundPowerOfTwo(vec<L, T, Q> const& v);
/// Higher multiple number of Source.
///
/// @tparam genType Floating-point or integer scalar or vector types.
///
/// @param v Source value to which is applied the function
/// @param Multiple Must be a null or positive value
///
/// @see gtc_round
template<typename genType>
GLM_FUNC_DECL genType ceilMultiple(genType v, genType Multiple);
/// Higher multiple number of Source.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point or integer scalar types
/// @tparam Q Value from qualifier enum
///
/// @param v Source values to which is applied the function
/// @param Multiple Must be a null or positive value
///
/// @see gtc_round
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> ceilMultiple(vec<L, T, Q> const& v, vec<L, T, Q> const& Multiple);
/// Lower multiple number of Source.
///
/// @tparam genType Floating-point or integer scalar or vector types.
///
/// @param v Source value to which is applied the function
/// @param Multiple Must be a null or positive value
///
/// @see gtc_round
template<typename genType>
GLM_FUNC_DECL genType floorMultiple(genType v, genType Multiple);
/// Lower multiple number of Source.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point or integer scalar types
/// @tparam Q Value from qualifier enum
///
/// @param v Source values to which is applied the function
/// @param Multiple Must be a null or positive value
///
/// @see gtc_round
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> floorMultiple(vec<L, T, Q> const& v, vec<L, T, Q> const& Multiple);
/// Lower multiple number of Source.
///
/// @tparam genType Floating-point or integer scalar or vector types.
///
/// @param v Source value to which is applied the function
/// @param Multiple Must be a null or positive value
///
/// @see gtc_round
template<typename genType>
GLM_FUNC_DECL genType roundMultiple(genType v, genType Multiple);
/// Lower multiple number of Source.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point or integer scalar types
/// @tparam Q Value from qualifier enum
///
/// @param v Source values to which is applied the function
/// @param Multiple Must be a null or positive value
///
/// @see gtc_round
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> roundMultiple(vec<L, T, Q> const& v, vec<L, T, Q> const& Multiple);
/// @}
} //namespace glm
#include "round.inl"
+155
View File
@@ -0,0 +1,155 @@
/// @ref gtc_round
#include "../integer.hpp"
#include "../ext/vector_integer.hpp"
namespace glm{
namespace detail
{
template<bool is_float, bool is_signed>
struct compute_roundMultiple {};
template<>
struct compute_roundMultiple<true, true>
{
template<typename genType>
GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
{
if (Source >= genType(0))
return Source - std::fmod(Source, Multiple);
else
{
genType Tmp = Source + genType(1);
return Tmp - std::fmod(Tmp, Multiple) - Multiple;
}
}
};
template<>
struct compute_roundMultiple<false, false>
{
template<typename genType>
GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
{
if (Source >= genType(0))
return Source - Source % Multiple;
else
{
genType Tmp = Source + genType(1);
return Tmp - Tmp % Multiple - Multiple;
}
}
};
template<>
struct compute_roundMultiple<false, true>
{
template<typename genType>
GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
{
if (Source >= genType(0))
return Source - Source % Multiple;
else
{
genType Tmp = Source + genType(1);
return Tmp - Tmp % Multiple - Multiple;
}
}
};
}//namespace detail
//////////////////
// ceilPowerOfTwo
template<typename genType>
GLM_FUNC_QUALIFIER genType ceilPowerOfTwo(genType value)
{
return detail::compute_ceilPowerOfTwo<1, genType, defaultp, std::numeric_limits<genType>::is_signed>::call(vec<1, genType, defaultp>(value)).x;
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> ceilPowerOfTwo(vec<L, T, Q> const& v)
{
return detail::compute_ceilPowerOfTwo<L, T, Q, std::numeric_limits<T>::is_signed>::call(v);
}
///////////////////
// floorPowerOfTwo
template<typename genType>
GLM_FUNC_QUALIFIER genType floorPowerOfTwo(genType value)
{
return isPowerOfTwo(value) ? value : static_cast<genType>(1) << findMSB(value);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> floorPowerOfTwo(vec<L, T, Q> const& v)
{
return detail::functor1<vec, L, T, T, Q>::call(floorPowerOfTwo, v);
}
///////////////////
// roundPowerOfTwo
template<typename genIUType>
GLM_FUNC_QUALIFIER genIUType roundPowerOfTwo(genIUType value)
{
if(isPowerOfTwo(value))
return value;
genIUType const prev = static_cast<genIUType>(1) << findMSB(value);
genIUType const next = prev << static_cast<genIUType>(1);
return (next - value) < (value - prev) ? next : prev;
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> roundPowerOfTwo(vec<L, T, Q> const& v)
{
return detail::functor1<vec, L, T, T, Q>::call(roundPowerOfTwo, v);
}
//////////////////////
// ceilMultiple
template<typename genType>
GLM_FUNC_QUALIFIER genType ceilMultiple(genType Source, genType Multiple)
{
return detail::compute_ceilMultiple<std::numeric_limits<genType>::is_iec559, std::numeric_limits<genType>::is_signed>::call(Source, Multiple);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> ceilMultiple(vec<L, T, Q> const& Source, vec<L, T, Q> const& Multiple)
{
return detail::functor2<vec, L, T, Q>::call(ceilMultiple, Source, Multiple);
}
//////////////////////
// floorMultiple
template<typename genType>
GLM_FUNC_QUALIFIER genType floorMultiple(genType Source, genType Multiple)
{
return detail::compute_floorMultiple<std::numeric_limits<genType>::is_iec559, std::numeric_limits<genType>::is_signed>::call(Source, Multiple);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> floorMultiple(vec<L, T, Q> const& Source, vec<L, T, Q> const& Multiple)
{
return detail::functor2<vec, L, T, Q>::call(floorMultiple, Source, Multiple);
}
//////////////////////
// roundMultiple
template<typename genType>
GLM_FUNC_QUALIFIER genType roundMultiple(genType Source, genType Multiple)
{
return detail::compute_roundMultiple<std::numeric_limits<genType>::is_iec559, std::numeric_limits<genType>::is_signed>::call(Source, Multiple);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> roundMultiple(vec<L, T, Q> const& Source, vec<L, T, Q> const& Multiple)
{
return detail::functor2<vec, L, T, Q>::call(roundMultiple, Source, Multiple);
}
}//namespace glm
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
/// @ref gtc_precision
namespace glm
{
}
+230
View File
@@ -0,0 +1,230 @@
/// @ref gtc_type_ptr
/// @file glm/gtc/type_ptr.hpp
///
/// @see core (dependence)
/// @see gtc_quaternion (dependence)
///
/// @defgroup gtc_type_ptr GLM_GTC_type_ptr
/// @ingroup gtc
///
/// Include <glm/gtc/type_ptr.hpp> to use the features of this extension.
///
/// Handles the interaction between pointers and vector, matrix types.
///
/// This extension defines an overloaded function, glm::value_ptr. It returns
/// a pointer to the memory layout of the object. Matrix types store their values
/// in column-major order.
///
/// This is useful for uploading data to matrices or copying data to buffer objects.
///
/// Example:
/// @code
/// #include <glm/glm.hpp>
/// #include <glm/gtc/type_ptr.hpp>
///
/// glm::vec3 aVector(3);
/// glm::mat4 someMatrix(1.0);
///
/// glUniform3fv(uniformLoc, 1, glm::value_ptr(aVector));
/// glUniformMatrix4fv(uniformMatrixLoc, 1, GL_FALSE, glm::value_ptr(someMatrix));
/// @endcode
///
/// <glm/gtc/type_ptr.hpp> need to be included to use the features of this extension.
#pragma once
// Dependency:
#include "../gtc/quaternion.hpp"
#include "../gtc/vec1.hpp"
#include "../vec2.hpp"
#include "../vec3.hpp"
#include "../vec4.hpp"
#include "../mat2x2.hpp"
#include "../mat2x3.hpp"
#include "../mat2x4.hpp"
#include "../mat3x2.hpp"
#include "../mat3x3.hpp"
#include "../mat3x4.hpp"
#include "../mat4x2.hpp"
#include "../mat4x3.hpp"
#include "../mat4x4.hpp"
#include <cstring>
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_type_ptr extension included")
#endif
namespace glm
{
/// @addtogroup gtc_type_ptr
/// @{
/// Return the constant address to the data of the input parameter.
/// @see gtc_type_ptr
template<typename genType>
GLM_FUNC_DECL typename genType::value_type const * value_ptr(genType const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<1, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<2, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<3, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<4, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<1, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<2, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<3, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<4, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<1, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<2, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<3, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<4, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<1, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<2, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<3, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<4, T, Q> const& v);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL vec<2, T, defaultp> make_vec2(T const * const ptr);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL vec<3, T, defaultp> make_vec3(T const * const ptr);
/// Build a vector from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL vec<4, T, defaultp> make_vec4(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<2, 2, T, defaultp> make_mat2x2(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<2, 3, T, defaultp> make_mat2x3(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<2, 4, T, defaultp> make_mat2x4(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<3, 2, T, defaultp> make_mat3x2(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<3, 3, T, defaultp> make_mat3x3(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<3, 4, T, defaultp> make_mat3x4(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<4, 2, T, defaultp> make_mat4x2(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<4, 3, T, defaultp> make_mat4x3(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<4, 4, T, defaultp> make_mat4x4(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<2, 2, T, defaultp> make_mat2(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<3, 3, T, defaultp> make_mat3(T const * const ptr);
/// Build a matrix from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL mat<4, 4, T, defaultp> make_mat4(T const * const ptr);
/// Build a quaternion from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL qua<T, defaultp> make_quat(T const * const ptr);
/// @}
}//namespace glm
#include "type_ptr.inl"
+398
View File
@@ -0,0 +1,398 @@
/// @ref gtc_type_ptr
#include <cstring>
namespace glm
{
/// @addtogroup gtc_type_ptr
/// @{
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(vec<1, T, Q> const& v)
{
return &(v.x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(vec<1, T, Q>& v)
{
return &(v.x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(vec<2, T, Q> const& v)
{
return &(v.x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(vec<2, T, Q>& v)
{
return &(v.x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const * value_ptr(vec<3, T, Q> const& v)
{
return &(v.x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(vec<3, T, Q>& v)
{
return &(v.x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(vec<4, T, Q> const& v)
{
return &(v.x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(vec<4, T, Q>& v)
{
return &(v.x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(mat<2, 2, T, Q> const& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(mat<2, 2, T, Q>& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(mat<3, 3, T, Q> const& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(mat<3, 3, T, Q>& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(mat<4, 4, T, Q> const& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(mat<4, 4, T, Q>& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(mat<2, 3, T, Q> const& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(mat<2, 3, T, Q>& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(mat<3, 2, T, Q> const& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(mat<3, 2, T, Q>& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(mat<2, 4, T, Q> const& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(mat<2, 4, T, Q>& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(mat<4, 2, T, Q> const& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(mat<4, 2, T, Q>& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(mat<3, 4, T, Q> const& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(mat<3, 4, T, Q>& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(mat<4, 3, T, Q> const& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T * value_ptr(mat<4, 3, T, Q>& m)
{
return &(m[0].x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const * value_ptr(qua<T, Q> const& q)
{
return &(q[0]);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(qua<T, Q>& q)
{
return &(q[0]);
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<1, T, Q> const& v)
{
return v;
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<2, T, Q> const& v)
{
return vec<1, T, Q>(v);
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<3, T, Q> const& v)
{
return vec<1, T, Q>(v);
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<4, T, Q> const& v)
{
return vec<1, T, Q>(v);
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<1, T, Q> const& v)
{
return vec<2, T, Q>(v.x, static_cast<T>(0));
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<2, T, Q> const& v)
{
return v;
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<3, T, Q> const& v)
{
return vec<2, T, Q>(v);
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<4, T, Q> const& v)
{
return vec<2, T, Q>(v);
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<1, T, Q> const& v)
{
return vec<3, T, Q>(v.x, static_cast<T>(0), static_cast<T>(0));
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<2, T, Q> const& v)
{
return vec<3, T, Q>(v.x, v.y, static_cast<T>(0));
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<3, T, Q> const& v)
{
return v;
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<4, T, Q> const& v)
{
return vec<3, T, Q>(v);
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<1, T, Q> const& v)
{
return vec<4, T, Q>(v.x, static_cast<T>(0), static_cast<T>(0), static_cast<T>(1));
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<2, T, Q> const& v)
{
return vec<4, T, Q>(v.x, v.y, static_cast<T>(0), static_cast<T>(1));
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<3, T, Q> const& v)
{
return vec<4, T, Q>(v.x, v.y, v.z, static_cast<T>(1));
}
template <typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<4, T, Q> const& v)
{
return v;
}
template<typename T>
GLM_FUNC_QUALIFIER vec<2, T, defaultp> make_vec2(T const *const ptr)
{
vec<2, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(vec<2, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER vec<3, T, defaultp> make_vec3(T const *const ptr)
{
vec<3, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(vec<3, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER vec<4, T, defaultp> make_vec4(T const *const ptr)
{
vec<4, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(vec<4, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER mat<2, 2, T, defaultp> make_mat2x2(T const *const ptr)
{
mat<2, 2, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(mat<2, 2, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER mat<2, 3, T, defaultp> make_mat2x3(T const *const ptr)
{
mat<2, 3, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(mat<2, 3, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER mat<2, 4, T, defaultp> make_mat2x4(T const *const ptr)
{
mat<2, 4, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(mat<2, 4, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER mat<3, 2, T, defaultp> make_mat3x2(T const *const ptr)
{
mat<3, 2, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(mat<3, 2, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER mat<3, 3, T, defaultp> make_mat3x3(T const *const ptr)
{
mat<3, 3, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(mat<3, 3, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER mat<3, 4, T, defaultp> make_mat3x4(T const *const ptr)
{
mat<3, 4, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(mat<3, 4, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER mat<4, 2, T, defaultp> make_mat4x2(T const *const ptr)
{
mat<4, 2, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(mat<4, 2, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER mat<4, 3, T, defaultp> make_mat4x3(T const *const ptr)
{
mat<4, 3, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(mat<4, 3, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> make_mat4x4(T const *const ptr)
{
mat<4, 4, T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(mat<4, 4, T, defaultp>));
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER mat<2, 2, T, defaultp> make_mat2(T const *const ptr)
{
return make_mat2x2(ptr);
}
template<typename T>
GLM_FUNC_QUALIFIER mat<3, 3, T, defaultp> make_mat3(T const *const ptr)
{
return make_mat3x3(ptr);
}
template<typename T>
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> make_mat4(T const *const ptr)
{
return make_mat4x4(ptr);
}
template<typename T>
GLM_FUNC_QUALIFIER qua<T, defaultp> make_quat(T const *const ptr)
{
qua<T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(qua<T, defaultp>));
return Result;
}
/// @}
}//namespace glm
+155
View File
@@ -0,0 +1,155 @@
/// @ref gtc_ulp
/// @file glm/gtc/ulp.hpp
///
/// @see core (dependence)
///
/// @defgroup gtc_ulp GLM_GTC_ulp
/// @ingroup gtc
///
/// Include <glm/gtc/ulp.hpp> to use the features of this extension.
///
/// Allow the measurement of the accuracy of a function against a reference
/// implementation. This extension works on floating-point data and provide results
/// in ULP.
#pragma once
// Dependencies
#include "../detail/setup.hpp"
#include "../detail/qualifier.hpp"
#include "../detail/_vectorize.hpp"
#include "../ext/scalar_int_sized.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_ulp extension included")
#endif
namespace glm
{
/// @addtogroup gtc_ulp
/// @{
/// Return the next ULP value(s) after the input value(s).
///
/// @tparam genType A floating-point scalar type.
///
/// @see gtc_ulp
template<typename genType>
GLM_FUNC_DECL genType next_float(genType x);
/// Return the previous ULP value(s) before the input value(s).
///
/// @tparam genType A floating-point scalar type.
///
/// @see gtc_ulp
template<typename genType>
GLM_FUNC_DECL genType prev_float(genType x);
/// Return the value(s) ULP distance after the input value(s).
///
/// @tparam genType A floating-point scalar type.
///
/// @see gtc_ulp
template<typename genType>
GLM_FUNC_DECL genType next_float(genType x, int ULPs);
/// Return the value(s) ULP distance before the input value(s).
///
/// @tparam genType A floating-point scalar type.
///
/// @see gtc_ulp
template<typename genType>
GLM_FUNC_DECL genType prev_float(genType x, int ULPs);
/// Return the distance in the number of ULP between 2 single-precision floating-point scalars.
///
/// @see gtc_ulp
GLM_FUNC_DECL int float_distance(float x, float y);
/// Return the distance in the number of ULP between 2 double-precision floating-point scalars.
///
/// @see gtc_ulp
GLM_FUNC_DECL int64 float_distance(double x, double y);
/// Return the next ULP value(s) after the input value(s).
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point
/// @tparam Q Value from qualifier enum
///
/// @see gtc_ulp
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> next_float(vec<L, T, Q> const& x);
/// Return the value(s) ULP distance after the input value(s).
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point
/// @tparam Q Value from qualifier enum
///
/// @see gtc_ulp
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> next_float(vec<L, T, Q> const& x, int ULPs);
/// Return the value(s) ULP distance after the input value(s).
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point
/// @tparam Q Value from qualifier enum
///
/// @see gtc_ulp
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> next_float(vec<L, T, Q> const& x, vec<L, int, Q> const& ULPs);
/// Return the previous ULP value(s) before the input value(s).
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point
/// @tparam Q Value from qualifier enum
///
/// @see gtc_ulp
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> prev_float(vec<L, T, Q> const& x);
/// Return the value(s) ULP distance before the input value(s).
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point
/// @tparam Q Value from qualifier enum
///
/// @see gtc_ulp
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> prev_float(vec<L, T, Q> const& x, int ULPs);
/// Return the value(s) ULP distance before the input value(s).
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam T Floating-point
/// @tparam Q Value from qualifier enum
///
/// @see gtc_ulp
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, T, Q> prev_float(vec<L, T, Q> const& x, vec<L, int, Q> const& ULPs);
/// Return the distance in the number of ULP between 2 single-precision floating-point scalars.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam Q Value from qualifier enum
///
/// @see gtc_ulp
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, int, Q> float_distance(vec<L, float, Q> const& x, vec<L, float, Q> const& y);
/// Return the distance in the number of ULP between 2 double-precision floating-point scalars.
///
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
/// @tparam Q Value from qualifier enum
///
/// @see gtc_ulp
template<length_t L, typename T, qualifier Q>
GLM_FUNC_DECL vec<L, int64, Q> float_distance(vec<L, double, Q> const& x, vec<L, double, Q> const& y);
/// @}
}//namespace glm
#include "ulp.inl"
+173
View File
@@ -0,0 +1,173 @@
/// @ref gtc_ulp
#include "../ext/scalar_ulp.hpp"
namespace glm
{
template<>
GLM_FUNC_QUALIFIER float next_float(float x)
{
# if GLM_HAS_CXX11_STL
return std::nextafter(x, std::numeric_limits<float>::max());
# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS)))
return detail::nextafterf(x, FLT_MAX);
# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID)
return __builtin_nextafterf(x, FLT_MAX);
# else
return nextafterf(x, FLT_MAX);
# endif
}
template<>
GLM_FUNC_QUALIFIER double next_float(double x)
{
# if GLM_HAS_CXX11_STL
return std::nextafter(x, std::numeric_limits<double>::max());
# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS)))
return detail::nextafter(x, std::numeric_limits<double>::max());
# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID)
return __builtin_nextafter(x, DBL_MAX);
# else
return nextafter(x, DBL_MAX);
# endif
}
template<typename T>
GLM_FUNC_QUALIFIER T next_float(T x, int ULPs)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'next_float' only accept floating-point input");
assert(ULPs >= 0);
T temp = x;
for (int i = 0; i < ULPs; ++i)
temp = next_float(temp);
return temp;
}
GLM_FUNC_QUALIFIER float prev_float(float x)
{
# if GLM_HAS_CXX11_STL
return std::nextafter(x, std::numeric_limits<float>::min());
# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS)))
return detail::nextafterf(x, FLT_MIN);
# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID)
return __builtin_nextafterf(x, FLT_MIN);
# else
return nextafterf(x, FLT_MIN);
# endif
}
GLM_FUNC_QUALIFIER double prev_float(double x)
{
# if GLM_HAS_CXX11_STL
return std::nextafter(x, std::numeric_limits<double>::min());
# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS)))
return _nextafter(x, DBL_MIN);
# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID)
return __builtin_nextafter(x, DBL_MIN);
# else
return nextafter(x, DBL_MIN);
# endif
}
template<typename T>
GLM_FUNC_QUALIFIER T prev_float(T x, int ULPs)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'prev_float' only accept floating-point input");
assert(ULPs >= 0);
T temp = x;
for (int i = 0; i < ULPs; ++i)
temp = prev_float(temp);
return temp;
}
GLM_FUNC_QUALIFIER int float_distance(float x, float y)
{
detail::float_t<float> const a(x);
detail::float_t<float> const b(y);
return abs(a.i - b.i);
}
GLM_FUNC_QUALIFIER int64 float_distance(double x, double y)
{
detail::float_t<double> const a(x);
detail::float_t<double> const b(y);
return abs(a.i - b.i);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> next_float(vec<L, T, Q> const& x)
{
vec<L, T, Q> Result;
for (length_t i = 0, n = Result.length(); i < n; ++i)
Result[i] = next_float(x[i]);
return Result;
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> next_float(vec<L, T, Q> const& x, int ULPs)
{
vec<L, T, Q> Result;
for (length_t i = 0, n = Result.length(); i < n; ++i)
Result[i] = next_float(x[i], ULPs);
return Result;
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> next_float(vec<L, T, Q> const& x, vec<L, int, Q> const& ULPs)
{
vec<L, T, Q> Result;
for (length_t i = 0, n = Result.length(); i < n; ++i)
Result[i] = next_float(x[i], ULPs[i]);
return Result;
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> prev_float(vec<L, T, Q> const& x)
{
vec<L, T, Q> Result;
for (length_t i = 0, n = Result.length(); i < n; ++i)
Result[i] = prev_float(x[i]);
return Result;
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> prev_float(vec<L, T, Q> const& x, int ULPs)
{
vec<L, T, Q> Result;
for (length_t i = 0, n = Result.length(); i < n; ++i)
Result[i] = prev_float(x[i], ULPs);
return Result;
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> prev_float(vec<L, T, Q> const& x, vec<L, int, Q> const& ULPs)
{
vec<L, T, Q> Result;
for (length_t i = 0, n = Result.length(); i < n; ++i)
Result[i] = prev_float(x[i], ULPs[i]);
return Result;
}
template<length_t L, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, int, Q> float_distance(vec<L, float, Q> const& x, vec<L, float, Q> const& y)
{
vec<L, int, Q> Result;
for (length_t i = 0, n = Result.length(); i < n; ++i)
Result[i] = float_distance(x[i], y[i]);
return Result;
}
template<length_t L, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, int64, Q> float_distance(vec<L, double, Q> const& x, vec<L, double, Q> const& y)
{
vec<L, int64, Q> Result;
for (length_t i = 0, n = Result.length(); i < n; ++i)
Result[i] = float_distance(x[i], y[i]);
return Result;
}
}//namespace glm
+30
View File
@@ -0,0 +1,30 @@
/// @ref gtc_vec1
/// @file glm/gtc/vec1.hpp
///
/// @see core (dependence)
///
/// @defgroup gtc_vec1 GLM_GTC_vec1
/// @ingroup gtc
///
/// Include <glm/gtc/vec1.hpp> to use the features of this extension.
///
/// Add vec1, ivec1, uvec1 and bvec1 types.
#pragma once
// Dependency:
#include "../ext/vector_bool1.hpp"
#include "../ext/vector_bool1_precision.hpp"
#include "../ext/vector_float1.hpp"
#include "../ext/vector_float1_precision.hpp"
#include "../ext/vector_double1.hpp"
#include "../ext/vector_double1_precision.hpp"
#include "../ext/vector_int1.hpp"
#include "../ext/vector_int1_sized.hpp"
#include "../ext/vector_uint1.hpp"
#include "../ext/vector_uint1_sized.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_vec1 extension included")
#endif