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:
@@ -0,0 +1,205 @@
|
||||
/// @ref gtx_associated_min_max
|
||||
/// @file glm/gtx/associated_min_max.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_extented_min_max (dependence)
|
||||
///
|
||||
/// @defgroup gtx_associated_min_max GLM_GTX_associated_min_max
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/associated_min_max.hpp> to use the features of this extension.
|
||||
///
|
||||
/// @brief Min and max functions that return associated values not the compared ones.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_associated_min_max is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_associated_min_max extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_associated_min_max
|
||||
/// @{
|
||||
|
||||
/// Minimum comparison between 2 variables and returns 2 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_DECL U associatedMin(T x, U a, T y, U b);
|
||||
|
||||
/// Minimum comparison between 2 variables and returns 2 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMin(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b);
|
||||
|
||||
/// Minimum comparison between 2 variables and returns 2 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMin(
|
||||
T x, const vec<L, U, Q>& a,
|
||||
T y, const vec<L, U, Q>& b);
|
||||
|
||||
/// Minimum comparison between 2 variables and returns 2 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMin(
|
||||
vec<L, T, Q> const& x, U a,
|
||||
vec<L, T, Q> const& y, U b);
|
||||
|
||||
/// Minimum comparison between 3 variables and returns 3 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_DECL U associatedMin(
|
||||
T x, U a,
|
||||
T y, U b,
|
||||
T z, U c);
|
||||
|
||||
/// Minimum comparison between 3 variables and returns 3 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMin(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b,
|
||||
vec<L, T, Q> const& z, vec<L, U, Q> const& c);
|
||||
|
||||
/// Minimum comparison between 4 variables and returns 4 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_DECL U associatedMin(
|
||||
T x, U a,
|
||||
T y, U b,
|
||||
T z, U c,
|
||||
T w, U d);
|
||||
|
||||
/// Minimum comparison between 4 variables and returns 4 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMin(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b,
|
||||
vec<L, T, Q> const& z, vec<L, U, Q> const& c,
|
||||
vec<L, T, Q> const& w, vec<L, U, Q> const& d);
|
||||
|
||||
/// Minimum comparison between 4 variables and returns 4 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMin(
|
||||
T x, vec<L, U, Q> const& a,
|
||||
T y, vec<L, U, Q> const& b,
|
||||
T z, vec<L, U, Q> const& c,
|
||||
T w, vec<L, U, Q> const& d);
|
||||
|
||||
/// Minimum comparison between 4 variables and returns 4 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMin(
|
||||
vec<L, T, Q> const& x, U a,
|
||||
vec<L, T, Q> const& y, U b,
|
||||
vec<L, T, Q> const& z, U c,
|
||||
vec<L, T, Q> const& w, U d);
|
||||
|
||||
/// Maximum comparison between 2 variables and returns 2 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_DECL U associatedMax(T x, U a, T y, U b);
|
||||
|
||||
/// Maximum comparison between 2 variables and returns 2 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMax(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b);
|
||||
|
||||
/// Maximum comparison between 2 variables and returns 2 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> associatedMax(
|
||||
T x, vec<L, U, Q> const& a,
|
||||
T y, vec<L, U, Q> const& b);
|
||||
|
||||
/// Maximum comparison between 2 variables and returns 2 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMax(
|
||||
vec<L, T, Q> const& x, U a,
|
||||
vec<L, T, Q> const& y, U b);
|
||||
|
||||
/// Maximum comparison between 3 variables and returns 3 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_DECL U associatedMax(
|
||||
T x, U a,
|
||||
T y, U b,
|
||||
T z, U c);
|
||||
|
||||
/// Maximum comparison between 3 variables and returns 3 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMax(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b,
|
||||
vec<L, T, Q> const& z, vec<L, U, Q> const& c);
|
||||
|
||||
/// Maximum comparison between 3 variables and returns 3 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> associatedMax(
|
||||
T x, vec<L, U, Q> const& a,
|
||||
T y, vec<L, U, Q> const& b,
|
||||
T z, vec<L, U, Q> const& c);
|
||||
|
||||
/// Maximum comparison between 3 variables and returns 3 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMax(
|
||||
vec<L, T, Q> const& x, U a,
|
||||
vec<L, T, Q> const& y, U b,
|
||||
vec<L, T, Q> const& z, U c);
|
||||
|
||||
/// Maximum comparison between 4 variables and returns 4 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_DECL U associatedMax(
|
||||
T x, U a,
|
||||
T y, U b,
|
||||
T z, U c,
|
||||
T w, U d);
|
||||
|
||||
/// Maximum comparison between 4 variables and returns 4 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMax(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b,
|
||||
vec<L, T, Q> const& z, vec<L, U, Q> const& c,
|
||||
vec<L, T, Q> const& w, vec<L, U, Q> const& d);
|
||||
|
||||
/// Maximum comparison between 4 variables and returns 4 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMax(
|
||||
T x, vec<L, U, Q> const& a,
|
||||
T y, vec<L, U, Q> const& b,
|
||||
T z, vec<L, U, Q> const& c,
|
||||
T w, vec<L, U, Q> const& d);
|
||||
|
||||
/// Maximum comparison between 4 variables and returns 4 associated variable values
|
||||
/// @see gtx_associated_min_max
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, U, Q> associatedMax(
|
||||
vec<L, T, Q> const& x, U a,
|
||||
vec<L, T, Q> const& y, U b,
|
||||
vec<L, T, Q> const& z, U c,
|
||||
vec<L, T, Q> const& w, U d);
|
||||
|
||||
/// @}
|
||||
} //namespace glm
|
||||
|
||||
#include "associated_min_max.inl"
|
||||
@@ -0,0 +1,354 @@
|
||||
/// @ref gtx_associated_min_max
|
||||
|
||||
namespace glm{
|
||||
|
||||
// Min comparison between 2 variables
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_QUALIFIER U associatedMin(T x, U a, T y, U b)
|
||||
{
|
||||
return x < y ? a : b;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMin
|
||||
(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
Result[i] = x[i] < y[i] ? a[i] : b[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMin
|
||||
(
|
||||
T x, const vec<L, U, Q>& a,
|
||||
T y, const vec<L, U, Q>& b
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
Result[i] = x < y ? a[i] : b[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMin
|
||||
(
|
||||
vec<L, T, Q> const& x, U a,
|
||||
vec<L, T, Q> const& y, U b
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
Result[i] = x[i] < y[i] ? a : b;
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Min comparison between 3 variables
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_QUALIFIER U associatedMin
|
||||
(
|
||||
T x, U a,
|
||||
T y, U b,
|
||||
T z, U c
|
||||
)
|
||||
{
|
||||
U Result = x < y ? (x < z ? a : c) : (y < z ? b : c);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMin
|
||||
(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b,
|
||||
vec<L, T, Q> const& z, vec<L, U, Q> const& c
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
Result[i] = x[i] < y[i] ? (x[i] < z[i] ? a[i] : c[i]) : (y[i] < z[i] ? b[i] : c[i]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Min comparison between 4 variables
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_QUALIFIER U associatedMin
|
||||
(
|
||||
T x, U a,
|
||||
T y, U b,
|
||||
T z, U c,
|
||||
T w, U d
|
||||
)
|
||||
{
|
||||
T Test1 = min(x, y);
|
||||
T Test2 = min(z, w);
|
||||
U Result1 = x < y ? a : b;
|
||||
U Result2 = z < w ? c : d;
|
||||
U Result = Test1 < Test2 ? Result1 : Result2;
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Min comparison between 4 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMin
|
||||
(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b,
|
||||
vec<L, T, Q> const& z, vec<L, U, Q> const& c,
|
||||
vec<L, T, Q> const& w, vec<L, U, Q> const& d
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
{
|
||||
T Test1 = min(x[i], y[i]);
|
||||
T Test2 = min(z[i], w[i]);
|
||||
U Result1 = x[i] < y[i] ? a[i] : b[i];
|
||||
U Result2 = z[i] < w[i] ? c[i] : d[i];
|
||||
Result[i] = Test1 < Test2 ? Result1 : Result2;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Min comparison between 4 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMin
|
||||
(
|
||||
T x, vec<L, U, Q> const& a,
|
||||
T y, vec<L, U, Q> const& b,
|
||||
T z, vec<L, U, Q> const& c,
|
||||
T w, vec<L, U, Q> const& d
|
||||
)
|
||||
{
|
||||
T Test1 = min(x, y);
|
||||
T Test2 = min(z, w);
|
||||
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
{
|
||||
U Result1 = x < y ? a[i] : b[i];
|
||||
U Result2 = z < w ? c[i] : d[i];
|
||||
Result[i] = Test1 < Test2 ? Result1 : Result2;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Min comparison between 4 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMin
|
||||
(
|
||||
vec<L, T, Q> const& x, U a,
|
||||
vec<L, T, Q> const& y, U b,
|
||||
vec<L, T, Q> const& z, U c,
|
||||
vec<L, T, Q> const& w, U d
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
{
|
||||
T Test1 = min(x[i], y[i]);
|
||||
T Test2 = min(z[i], w[i]);
|
||||
U Result1 = x[i] < y[i] ? a : b;
|
||||
U Result2 = z[i] < w[i] ? c : d;
|
||||
Result[i] = Test1 < Test2 ? Result1 : Result2;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Max comparison between 2 variables
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_QUALIFIER U associatedMax(T x, U a, T y, U b)
|
||||
{
|
||||
return x > y ? a : b;
|
||||
}
|
||||
|
||||
// Max comparison between 2 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMax
|
||||
(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
Result[i] = x[i] > y[i] ? a[i] : b[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Max comparison between 2 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> associatedMax
|
||||
(
|
||||
T x, vec<L, U, Q> const& a,
|
||||
T y, vec<L, U, Q> const& b
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
Result[i] = x > y ? a[i] : b[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Max comparison between 2 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMax
|
||||
(
|
||||
vec<L, T, Q> const& x, U a,
|
||||
vec<L, T, Q> const& y, U b
|
||||
)
|
||||
{
|
||||
vec<L, T, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
Result[i] = x[i] > y[i] ? a : b;
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Max comparison between 3 variables
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_QUALIFIER U associatedMax
|
||||
(
|
||||
T x, U a,
|
||||
T y, U b,
|
||||
T z, U c
|
||||
)
|
||||
{
|
||||
U Result = x > y ? (x > z ? a : c) : (y > z ? b : c);
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Max comparison between 3 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMax
|
||||
(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b,
|
||||
vec<L, T, Q> const& z, vec<L, U, Q> const& c
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a[i] : c[i]) : (y[i] > z[i] ? b[i] : c[i]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Max comparison between 3 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> associatedMax
|
||||
(
|
||||
T x, vec<L, U, Q> const& a,
|
||||
T y, vec<L, U, Q> const& b,
|
||||
T z, vec<L, U, Q> const& c
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
Result[i] = x > y ? (x > z ? a[i] : c[i]) : (y > z ? b[i] : c[i]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Max comparison between 3 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMax
|
||||
(
|
||||
vec<L, T, Q> const& x, U a,
|
||||
vec<L, T, Q> const& y, U b,
|
||||
vec<L, T, Q> const& z, U c
|
||||
)
|
||||
{
|
||||
vec<L, T, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c);
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Max comparison between 4 variables
|
||||
template<typename T, typename U>
|
||||
GLM_FUNC_QUALIFIER U associatedMax
|
||||
(
|
||||
T x, U a,
|
||||
T y, U b,
|
||||
T z, U c,
|
||||
T w, U d
|
||||
)
|
||||
{
|
||||
T Test1 = max(x, y);
|
||||
T Test2 = max(z, w);
|
||||
U Result1 = x > y ? a : b;
|
||||
U Result2 = z > w ? c : d;
|
||||
U Result = Test1 > Test2 ? Result1 : Result2;
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Max comparison between 4 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMax
|
||||
(
|
||||
vec<L, T, Q> const& x, vec<L, U, Q> const& a,
|
||||
vec<L, T, Q> const& y, vec<L, U, Q> const& b,
|
||||
vec<L, T, Q> const& z, vec<L, U, Q> const& c,
|
||||
vec<L, T, Q> const& w, vec<L, U, Q> const& d
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
{
|
||||
T Test1 = max(x[i], y[i]);
|
||||
T Test2 = max(z[i], w[i]);
|
||||
U Result1 = x[i] > y[i] ? a[i] : b[i];
|
||||
U Result2 = z[i] > w[i] ? c[i] : d[i];
|
||||
Result[i] = Test1 > Test2 ? Result1 : Result2;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Max comparison between 4 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMax
|
||||
(
|
||||
T x, vec<L, U, Q> const& a,
|
||||
T y, vec<L, U, Q> const& b,
|
||||
T z, vec<L, U, Q> const& c,
|
||||
T w, vec<L, U, Q> const& d
|
||||
)
|
||||
{
|
||||
T Test1 = max(x, y);
|
||||
T Test2 = max(z, w);
|
||||
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
{
|
||||
U Result1 = x > y ? a[i] : b[i];
|
||||
U Result2 = z > w ? c[i] : d[i];
|
||||
Result[i] = Test1 > Test2 ? Result1 : Result2;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Max comparison between 4 variables
|
||||
template<length_t L, typename T, typename U, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, U, Q> associatedMax
|
||||
(
|
||||
vec<L, T, Q> const& x, U a,
|
||||
vec<L, T, Q> const& y, U b,
|
||||
vec<L, T, Q> const& z, U c,
|
||||
vec<L, T, Q> const& w, U d
|
||||
)
|
||||
{
|
||||
vec<L, U, Q> Result;
|
||||
for(length_t i = 0, n = Result.length(); i < n; ++i)
|
||||
{
|
||||
T Test1 = max(x[i], y[i]);
|
||||
T Test2 = max(z[i], w[i]);
|
||||
U Result1 = x[i] > y[i] ? a : b;
|
||||
U Result2 = z[i] > w[i] ? c : d;
|
||||
Result[i] = Test1 > Test2 ? Result1 : Result2;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,96 @@
|
||||
/// @ref gtx_bit
|
||||
/// @file glm/gtx/bit.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_bit GLM_GTX_bit
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/bit.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Allow to perform bit operations on integer values
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependencies
|
||||
#include "../gtc/bitfield.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_bit is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_bit extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_bit
|
||||
/// @{
|
||||
|
||||
/// @see gtx_bit
|
||||
template<typename genIUType>
|
||||
GLM_FUNC_DECL genIUType highestBitValue(genIUType Value);
|
||||
|
||||
/// @see gtx_bit
|
||||
template<typename genIUType>
|
||||
GLM_FUNC_DECL genIUType lowestBitValue(genIUType Value);
|
||||
|
||||
/// Find the highest bit set to 1 in a integer variable and return its value.
|
||||
///
|
||||
/// @see gtx_bit
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> highestBitValue(vec<L, T, Q> const& value);
|
||||
|
||||
/// Return the power of two number which value is just higher the input value.
|
||||
/// Deprecated, use ceilPowerOfTwo from GTC_round instead
|
||||
///
|
||||
/// @see gtc_round
|
||||
/// @see gtx_bit
|
||||
template<typename genIUType>
|
||||
GLM_DEPRECATED GLM_FUNC_DECL genIUType powerOfTwoAbove(genIUType Value);
|
||||
|
||||
/// Return the power of two number which value is just higher the input value.
|
||||
/// Deprecated, use ceilPowerOfTwo from GTC_round instead
|
||||
///
|
||||
/// @see gtc_round
|
||||
/// @see gtx_bit
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_DEPRECATED GLM_FUNC_DECL vec<L, T, Q> powerOfTwoAbove(vec<L, T, Q> const& value);
|
||||
|
||||
/// Return the power of two number which value is just lower the input value.
|
||||
/// Deprecated, use floorPowerOfTwo from GTC_round instead
|
||||
///
|
||||
/// @see gtc_round
|
||||
/// @see gtx_bit
|
||||
template<typename genIUType>
|
||||
GLM_DEPRECATED GLM_FUNC_DECL genIUType powerOfTwoBelow(genIUType Value);
|
||||
|
||||
/// Return the power of two number which value is just lower the input value.
|
||||
/// Deprecated, use floorPowerOfTwo from GTC_round instead
|
||||
///
|
||||
/// @see gtc_round
|
||||
/// @see gtx_bit
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_DEPRECATED GLM_FUNC_DECL vec<L, T, Q> powerOfTwoBelow(vec<L, T, Q> const& value);
|
||||
|
||||
/// Return the power of two number which value is the closet to the input value.
|
||||
/// Deprecated, use roundPowerOfTwo from GTC_round instead
|
||||
///
|
||||
/// @see gtc_round
|
||||
/// @see gtx_bit
|
||||
template<typename genIUType>
|
||||
GLM_DEPRECATED GLM_FUNC_DECL genIUType powerOfTwoNearest(genIUType Value);
|
||||
|
||||
/// Return the power of two number which value is the closet to the input value.
|
||||
/// Deprecated, use roundPowerOfTwo from GTC_round instead
|
||||
///
|
||||
/// @see gtc_round
|
||||
/// @see gtx_bit
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_DEPRECATED GLM_FUNC_DECL vec<L, T, Q> powerOfTwoNearest(vec<L, T, Q> const& value);
|
||||
|
||||
/// @}
|
||||
} //namespace glm
|
||||
|
||||
|
||||
#include "bit.inl"
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/// @ref gtx_bit
|
||||
|
||||
namespace glm
|
||||
{
|
||||
///////////////////
|
||||
// highestBitValue
|
||||
|
||||
template<typename genIUType>
|
||||
GLM_FUNC_QUALIFIER genIUType highestBitValue(genIUType Value)
|
||||
{
|
||||
genIUType tmp = Value;
|
||||
genIUType result = genIUType(0);
|
||||
while(tmp)
|
||||
{
|
||||
result = (tmp & (~tmp + 1)); // grab lowest bit
|
||||
tmp &= ~result; // clear lowest bit
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> highestBitValue(vec<L, T, Q> const& v)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(highestBitValue, v);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// lowestBitValue
|
||||
|
||||
template<typename genIUType>
|
||||
GLM_FUNC_QUALIFIER genIUType lowestBitValue(genIUType Value)
|
||||
{
|
||||
return (Value & (~Value + 1));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> lowestBitValue(vec<L, T, Q> const& v)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(lowestBitValue, v);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// powerOfTwoAbove
|
||||
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType value)
|
||||
{
|
||||
return isPowerOfTwo(value) ? value : highestBitValue(value) << 1;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> powerOfTwoAbove(vec<L, T, Q> const& v)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(powerOfTwoAbove, v);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// powerOfTwoBelow
|
||||
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType powerOfTwoBelow(genType value)
|
||||
{
|
||||
return isPowerOfTwo(value) ? value : highestBitValue(value);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> powerOfTwoBelow(vec<L, T, Q> const& v)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(powerOfTwoBelow, v);
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// powerOfTwoNearest
|
||||
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType powerOfTwoNearest(genType value)
|
||||
{
|
||||
if(isPowerOfTwo(value))
|
||||
return value;
|
||||
|
||||
genType const prev = highestBitValue(value);
|
||||
genType const next = prev << 1;
|
||||
return (next - value) < (value - prev) ? next : prev;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> powerOfTwoNearest(vec<L, T, Q> const& v)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(powerOfTwoNearest, v);
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,47 @@
|
||||
/// @ref gtx_closest_point
|
||||
/// @file glm/gtx/closest_point.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_closest_point GLM_GTX_closest_point
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/closest_point.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Find the point on a straight line which is the closet of a point.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_closest_point is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_closest_point extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_closest_point
|
||||
/// @{
|
||||
|
||||
/// Find the point on a straight line which is the closet of a point.
|
||||
/// @see gtx_closest_point
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> closestPointOnLine(
|
||||
vec<3, T, Q> const& point,
|
||||
vec<3, T, Q> const& a,
|
||||
vec<3, T, Q> const& b);
|
||||
|
||||
/// 2d lines work as well
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<2, T, Q> closestPointOnLine(
|
||||
vec<2, T, Q> const& point,
|
||||
vec<2, T, Q> const& a,
|
||||
vec<2, T, Q> const& b);
|
||||
|
||||
/// @}
|
||||
}// namespace glm
|
||||
|
||||
#include "closest_point.inl"
|
||||
@@ -0,0 +1,45 @@
|
||||
/// @ref gtx_closest_point
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> closestPointOnLine
|
||||
(
|
||||
vec<3, T, Q> const& point,
|
||||
vec<3, T, Q> const& a,
|
||||
vec<3, T, Q> const& b
|
||||
)
|
||||
{
|
||||
T LineLength = distance(a, b);
|
||||
vec<3, T, Q> Vector = point - a;
|
||||
vec<3, T, Q> LineDirection = (b - a) / LineLength;
|
||||
|
||||
// Project Vector to LineDirection to get the distance of point from a
|
||||
T Distance = dot(Vector, LineDirection);
|
||||
|
||||
if(Distance <= T(0)) return a;
|
||||
if(Distance >= LineLength) return b;
|
||||
return a + LineDirection * Distance;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<2, T, Q> closestPointOnLine
|
||||
(
|
||||
vec<2, T, Q> const& point,
|
||||
vec<2, T, Q> const& a,
|
||||
vec<2, T, Q> const& b
|
||||
)
|
||||
{
|
||||
T LineLength = distance(a, b);
|
||||
vec<2, T, Q> Vector = point - a;
|
||||
vec<2, T, Q> LineDirection = (b - a) / LineLength;
|
||||
|
||||
// Project Vector to LineDirection to get the distance of point from a
|
||||
T Distance = dot(Vector, LineDirection);
|
||||
|
||||
if(Distance <= T(0)) return a;
|
||||
if(Distance >= LineLength) return b;
|
||||
return a + LineDirection * Distance;
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,52 @@
|
||||
/// @ref gtx_color_encoding
|
||||
/// @file glm/gtx/color_encoding.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_color_encoding (dependence)
|
||||
///
|
||||
/// @defgroup gtx_color_encoding GLM_GTX_color_encoding
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/color_encoding.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 "../vec3.hpp"
|
||||
#include <limits>
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTC_color_encoding is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTC_color_encoding extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_color_encoding
|
||||
/// @{
|
||||
|
||||
/// Convert a linear sRGB color to D65 YUV.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> convertLinearSRGBToD65XYZ(vec<3, T, Q> const& ColorLinearSRGB);
|
||||
|
||||
/// Convert a linear sRGB color to D50 YUV.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> convertLinearSRGBToD50XYZ(vec<3, T, Q> const& ColorLinearSRGB);
|
||||
|
||||
/// Convert a D65 YUV color to linear sRGB.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> convertD65XYZToLinearSRGB(vec<3, T, Q> const& ColorD65XYZ);
|
||||
|
||||
/// Convert a D65 YUV color to D50 YUV.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> convertD65XYZToD50XYZ(vec<3, T, Q> const& ColorD65XYZ);
|
||||
|
||||
/// @}
|
||||
} //namespace glm
|
||||
|
||||
#include "color_encoding.inl"
|
||||
@@ -0,0 +1,45 @@
|
||||
/// @ref gtx_color_encoding
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> convertLinearSRGBToD65XYZ(vec<3, T, Q> const& ColorLinearSRGB)
|
||||
{
|
||||
vec<3, T, Q> const M(0.490f, 0.17697f, 0.2f);
|
||||
vec<3, T, Q> const N(0.31f, 0.8124f, 0.01063f);
|
||||
vec<3, T, Q> const O(0.490f, 0.01f, 0.99f);
|
||||
|
||||
return (M * ColorLinearSRGB + N * ColorLinearSRGB + O * ColorLinearSRGB) * static_cast<T>(5.650675255693055f);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> convertLinearSRGBToD50XYZ(vec<3, T, Q> const& ColorLinearSRGB)
|
||||
{
|
||||
vec<3, T, Q> const M(0.436030342570117f, 0.222438466210245f, 0.013897440074263f);
|
||||
vec<3, T, Q> const N(0.385101860087134f, 0.716942745571917f, 0.097076381494207f);
|
||||
vec<3, T, Q> const O(0.143067806654203f, 0.060618777416563f, 0.713926257896652f);
|
||||
|
||||
return M * ColorLinearSRGB + N * ColorLinearSRGB + O * ColorLinearSRGB;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> convertD65XYZToLinearSRGB(vec<3, T, Q> const& ColorD65XYZ)
|
||||
{
|
||||
vec<3, T, Q> const M(0.41847f, -0.091169f, 0.0009209f);
|
||||
vec<3, T, Q> const N(-0.15866f, 0.25243f, 0.015708f);
|
||||
vec<3, T, Q> const O(0.0009209f, -0.0025498f, 0.1786f);
|
||||
|
||||
return M * ColorD65XYZ + N * ColorD65XYZ + O * ColorD65XYZ;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> convertD65XYZToD50XYZ(vec<3, T, Q> const& ColorD65XYZ)
|
||||
{
|
||||
vec<3, T, Q> const M(+1.047844353856414f, +0.029549007606644f, -0.009250984365223f);
|
||||
vec<3, T, Q> const N(+0.022898981050086f, +0.990508028941971f, +0.015072338237051f);
|
||||
vec<3, T, Q> const O(-0.050206647741605f, -0.017074711360960f, +0.751717835079977f);
|
||||
|
||||
return M * ColorD65XYZ + N * ColorD65XYZ + O * ColorD65XYZ;
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,70 @@
|
||||
/// @ref gtx_color_space
|
||||
/// @file glm/gtx/color_space.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_color_space GLM_GTX_color_space
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/color_space.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Related to RGB to HSV conversions and operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_color_space is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_color_space extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_color_space
|
||||
/// @{
|
||||
|
||||
/// Converts a color from HSV color space to its color in RGB color space.
|
||||
/// @see gtx_color_space
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> rgbColor(
|
||||
vec<3, T, Q> const& hsvValue);
|
||||
|
||||
/// Converts a color from RGB color space to its color in HSV color space.
|
||||
/// @see gtx_color_space
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> hsvColor(
|
||||
vec<3, T, Q> const& rgbValue);
|
||||
|
||||
/// Build a saturation matrix.
|
||||
/// @see gtx_color_space
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> saturation(
|
||||
T const s);
|
||||
|
||||
/// Modify the saturation of a color.
|
||||
/// @see gtx_color_space
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> saturation(
|
||||
T const s,
|
||||
vec<3, T, Q> const& color);
|
||||
|
||||
/// Modify the saturation of a color.
|
||||
/// @see gtx_color_space
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, T, Q> saturation(
|
||||
T const s,
|
||||
vec<4, T, Q> const& color);
|
||||
|
||||
/// Compute color luminosity associating ratios (0.33, 0.59, 0.11) to RGB canals.
|
||||
/// @see gtx_color_space
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T luminosity(
|
||||
vec<3, T, Q> const& color);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "color_space.inl"
|
||||
@@ -0,0 +1,144 @@
|
||||
/// @ref gtx_color_space
|
||||
|
||||
#include "../ext/scalar_relational.hpp"
|
||||
#include "../ext/scalar_constants.hpp"
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> rgbColor(const vec<3, T, Q>& hsvColor)
|
||||
{
|
||||
vec<3, T, Q> hsv = hsvColor;
|
||||
vec<3, T, Q> rgbColor;
|
||||
|
||||
if(equal(hsv.y, static_cast<T>(0), epsilon<T>()))
|
||||
// achromatic (grey)
|
||||
rgbColor = vec<3, T, Q>(hsv.z);
|
||||
else
|
||||
{
|
||||
T sector = floor(hsv.x * (T(1) / T(60)));
|
||||
T frac = (hsv.x * (T(1) / T(60))) - sector;
|
||||
// factorial part of h
|
||||
T o = hsv.z * (T(1) - hsv.y);
|
||||
T p = hsv.z * (T(1) - hsv.y * frac);
|
||||
T q = hsv.z * (T(1) - hsv.y * (T(1) - frac));
|
||||
|
||||
switch(int(sector))
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
rgbColor.r = hsv.z;
|
||||
rgbColor.g = q;
|
||||
rgbColor.b = o;
|
||||
break;
|
||||
case 1:
|
||||
rgbColor.r = p;
|
||||
rgbColor.g = hsv.z;
|
||||
rgbColor.b = o;
|
||||
break;
|
||||
case 2:
|
||||
rgbColor.r = o;
|
||||
rgbColor.g = hsv.z;
|
||||
rgbColor.b = q;
|
||||
break;
|
||||
case 3:
|
||||
rgbColor.r = o;
|
||||
rgbColor.g = p;
|
||||
rgbColor.b = hsv.z;
|
||||
break;
|
||||
case 4:
|
||||
rgbColor.r = q;
|
||||
rgbColor.g = o;
|
||||
rgbColor.b = hsv.z;
|
||||
break;
|
||||
case 5:
|
||||
rgbColor.r = hsv.z;
|
||||
rgbColor.g = o;
|
||||
rgbColor.b = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rgbColor;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> hsvColor(const vec<3, T, Q>& rgbColor)
|
||||
{
|
||||
vec<3, T, Q> hsv = rgbColor;
|
||||
T Min = min(min(rgbColor.r, rgbColor.g), rgbColor.b);
|
||||
T Max = max(max(rgbColor.r, rgbColor.g), rgbColor.b);
|
||||
T Delta = Max - Min;
|
||||
|
||||
hsv.z = Max;
|
||||
|
||||
if(!equal(Max, static_cast<T>(0), epsilon<T>()))
|
||||
{
|
||||
hsv.y = Delta / hsv.z;
|
||||
T h = static_cast<T>(0);
|
||||
|
||||
if(equal(rgbColor.r, Max, epsilon<T>()))
|
||||
// between yellow & magenta
|
||||
h = static_cast<T>(0) + T(60) * (rgbColor.g - rgbColor.b) / Delta;
|
||||
else if(equal(rgbColor.g, Max, epsilon<T>()))
|
||||
// between cyan & yellow
|
||||
h = static_cast<T>(120) + T(60) * (rgbColor.b - rgbColor.r) / Delta;
|
||||
else
|
||||
// between magenta & cyan
|
||||
h = static_cast<T>(240) + T(60) * (rgbColor.r - rgbColor.g) / Delta;
|
||||
|
||||
if(h < T(0))
|
||||
hsv.x = h + T(360);
|
||||
else
|
||||
hsv.x = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If r = g = b = 0 then s = 0, h is undefined
|
||||
hsv.y = static_cast<T>(0);
|
||||
hsv.x = static_cast<T>(0);
|
||||
}
|
||||
|
||||
return hsv;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> saturation(T const s)
|
||||
{
|
||||
vec<3, T, defaultp> rgbw = vec<3, T, defaultp>(T(0.2126), T(0.7152), T(0.0722));
|
||||
|
||||
vec<3, T, defaultp> const col((T(1) - s) * rgbw);
|
||||
|
||||
mat<4, 4, T, defaultp> result(T(1));
|
||||
result[0][0] = col.x + s;
|
||||
result[0][1] = col.x;
|
||||
result[0][2] = col.x;
|
||||
result[1][0] = col.y;
|
||||
result[1][1] = col.y + s;
|
||||
result[1][2] = col.y;
|
||||
result[2][0] = col.z;
|
||||
result[2][1] = col.z;
|
||||
result[2][2] = col.z + s;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> saturation(const T s, const vec<3, T, Q>& color)
|
||||
{
|
||||
return vec<3, T, Q>(saturation(s) * vec<4, T, Q>(color, T(0)));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, T, Q> saturation(const T s, const vec<4, T, Q>& color)
|
||||
{
|
||||
return saturation(s) * color;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T luminosity(const vec<3, T, Q>& color)
|
||||
{
|
||||
const vec<3, T, Q> tmp = vec<3, T, Q>(0.33, 0.59, 0.11);
|
||||
return dot(color, tmp);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,58 @@
|
||||
/// @ref gtx_color_space_YCoCg
|
||||
/// @file glm/gtx/color_space_YCoCg.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_color_space_YCoCg GLM_GTX_color_space_YCoCg
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/color_space_YCoCg.hpp> to use the features of this extension.
|
||||
///
|
||||
/// RGB to YCoCg conversions and operations
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_color_space_YCoCg is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_color_space_YCoCg extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_color_space_YCoCg
|
||||
/// @{
|
||||
|
||||
/// Convert a color from RGB color space to YCoCg color space.
|
||||
/// @see gtx_color_space_YCoCg
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> rgb2YCoCg(
|
||||
vec<3, T, Q> const& rgbColor);
|
||||
|
||||
/// Convert a color from YCoCg color space to RGB color space.
|
||||
/// @see gtx_color_space_YCoCg
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> YCoCg2rgb(
|
||||
vec<3, T, Q> const& YCoCgColor);
|
||||
|
||||
/// Convert a color from RGB color space to YCoCgR color space.
|
||||
/// @see "YCoCg-R: A Color Space with RGB Reversibility and Low Dynamic Range"
|
||||
/// @see gtx_color_space_YCoCg
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> rgb2YCoCgR(
|
||||
vec<3, T, Q> const& rgbColor);
|
||||
|
||||
/// Convert a color from YCoCgR color space to RGB color space.
|
||||
/// @see "YCoCg-R: A Color Space with RGB Reversibility and Low Dynamic Range"
|
||||
/// @see gtx_color_space_YCoCg
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> YCoCgR2rgb(
|
||||
vec<3, T, Q> const& YCoCgColor);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "color_space_YCoCg.inl"
|
||||
@@ -0,0 +1,107 @@
|
||||
/// @ref gtx_color_space_YCoCg
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCg
|
||||
(
|
||||
vec<3, T, Q> const& rgbColor
|
||||
)
|
||||
{
|
||||
vec<3, T, Q> result;
|
||||
result.x/*Y */ = rgbColor.r / T(4) + rgbColor.g / T(2) + rgbColor.b / T(4);
|
||||
result.y/*Co*/ = rgbColor.r / T(2) + rgbColor.g * T(0) - rgbColor.b / T(2);
|
||||
result.z/*Cg*/ = - rgbColor.r / T(4) + rgbColor.g / T(2) - rgbColor.b / T(4);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCg2rgb
|
||||
(
|
||||
vec<3, T, Q> const& YCoCgColor
|
||||
)
|
||||
{
|
||||
vec<3, T, Q> result;
|
||||
result.r = YCoCgColor.x + YCoCgColor.y - YCoCgColor.z;
|
||||
result.g = YCoCgColor.x + YCoCgColor.z;
|
||||
result.b = YCoCgColor.x - YCoCgColor.y - YCoCgColor.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q, bool isInteger>
|
||||
class compute_YCoCgR {
|
||||
public:
|
||||
static GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCgR
|
||||
(
|
||||
vec<3, T, Q> const& rgbColor
|
||||
)
|
||||
{
|
||||
vec<3, T, Q> result;
|
||||
result.x/*Y */ = rgbColor.g * static_cast<T>(0.5) + (rgbColor.r + rgbColor.b) * static_cast<T>(0.25);
|
||||
result.y/*Co*/ = rgbColor.r - rgbColor.b;
|
||||
result.z/*Cg*/ = rgbColor.g - (rgbColor.r + rgbColor.b) * static_cast<T>(0.5);
|
||||
return result;
|
||||
}
|
||||
|
||||
static GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCgR2rgb
|
||||
(
|
||||
vec<3, T, Q> const& YCoCgRColor
|
||||
)
|
||||
{
|
||||
vec<3, T, Q> result;
|
||||
T tmp = YCoCgRColor.x - (YCoCgRColor.z * static_cast<T>(0.5));
|
||||
result.g = YCoCgRColor.z + tmp;
|
||||
result.b = tmp - (YCoCgRColor.y * static_cast<T>(0.5));
|
||||
result.r = result.b + YCoCgRColor.y;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
class compute_YCoCgR<T, Q, true> {
|
||||
public:
|
||||
static GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCgR
|
||||
(
|
||||
vec<3, T, Q> const& rgbColor
|
||||
)
|
||||
{
|
||||
vec<3, T, Q> result;
|
||||
result.y/*Co*/ = rgbColor.r - rgbColor.b;
|
||||
T tmp = rgbColor.b + (result.y >> 1);
|
||||
result.z/*Cg*/ = rgbColor.g - tmp;
|
||||
result.x/*Y */ = tmp + (result.z >> 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
static GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCgR2rgb
|
||||
(
|
||||
vec<3, T, Q> const& YCoCgRColor
|
||||
)
|
||||
{
|
||||
vec<3, T, Q> result;
|
||||
T tmp = YCoCgRColor.x - (YCoCgRColor.z >> 1);
|
||||
result.g = YCoCgRColor.z + tmp;
|
||||
result.b = tmp - (YCoCgRColor.y >> 1);
|
||||
result.r = result.b + YCoCgRColor.y;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCgR
|
||||
(
|
||||
vec<3, T, Q> const& rgbColor
|
||||
)
|
||||
{
|
||||
return compute_YCoCgR<T, Q, std::numeric_limits<T>::is_integer>::rgb2YCoCgR(rgbColor);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCgR2rgb
|
||||
(
|
||||
vec<3, T, Q> const& YCoCgRColor
|
||||
)
|
||||
{
|
||||
return compute_YCoCgR<T, Q, std::numeric_limits<T>::is_integer>::YCoCgR2rgb(YCoCgRColor);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,74 @@
|
||||
/// @ref gtx_common
|
||||
/// @file glm/gtx/common.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_common GLM_GTX_common
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/common.hpp> to use the features of this extension.
|
||||
///
|
||||
/// @brief Provide functions to increase the compatibility with Cg and HLSL languages
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependencies:
|
||||
#include "../vec2.hpp"
|
||||
#include "../vec3.hpp"
|
||||
#include "../vec4.hpp"
|
||||
#include "../gtc/vec1.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_common is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_common extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_common
|
||||
/// @{
|
||||
|
||||
/// Returns true if x is a denormalized number
|
||||
/// Numbers whose absolute value is too small to be represented in the normal format are represented in an alternate, denormalized format.
|
||||
/// This format is less precise but can represent values closer to zero.
|
||||
///
|
||||
/// @tparam genType Floating-point scalar or vector types.
|
||||
///
|
||||
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/isnan.xml">GLSL isnan man page</a>
|
||||
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL typename genType::bool_type isdenormal(genType const& x);
|
||||
|
||||
/// Similar to 'mod' but with a different rounding and integer support.
|
||||
/// Returns 'x - y * trunc(x/y)' instead of 'x - y * floor(x/y)'
|
||||
///
|
||||
/// @see <a href="http://stackoverflow.com/questions/7610631/glsl-mod-vs-hlsl-fmod">GLSL mod vs HLSL fmod</a>
|
||||
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fmod(vec<L, T, Q> const& v);
|
||||
|
||||
/// Returns whether vector components values are within an interval. A open interval excludes its endpoints, and is denoted with square brackets.
|
||||
///
|
||||
/// @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 ext_vector_relational
|
||||
template <length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, bool, Q> openBounded(vec<L, T, Q> const& Value, vec<L, T, Q> const& Min, vec<L, T, Q> const& Max);
|
||||
|
||||
/// Returns whether vector components values are within an interval. A closed interval includes its endpoints, and is denoted with square brackets.
|
||||
///
|
||||
/// @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 ext_vector_relational
|
||||
template <length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, bool, Q> closeBounded(vec<L, T, Q> const& Value, vec<L, T, Q> const& Min, vec<L, T, Q> const& Max);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "common.inl"
|
||||
@@ -0,0 +1,125 @@
|
||||
/// @ref gtx_common
|
||||
|
||||
#include <cmath>
|
||||
#include "../gtc/epsilon.hpp"
|
||||
#include "../gtc/constants.hpp"
|
||||
|
||||
namespace glm{
|
||||
namespace detail
|
||||
{
|
||||
template<length_t L, typename T, qualifier Q, bool isFloat = true>
|
||||
struct compute_fmod
|
||||
{
|
||||
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
|
||||
{
|
||||
return detail::functor2<vec, L, T, Q>::call(TFmod<T>(), a, b);
|
||||
}
|
||||
};
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
struct compute_fmod<L, T, Q, false>
|
||||
{
|
||||
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
|
||||
{
|
||||
return a % b;
|
||||
}
|
||||
};
|
||||
}//namespace detail
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER bool isdenormal(T const& x)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'isdenormal' only accept floating-point inputs");
|
||||
|
||||
# if GLM_HAS_CXX11_STL
|
||||
return std::fpclassify(x) == FP_SUBNORMAL;
|
||||
# else
|
||||
return epsilonNotEqual(x, static_cast<T>(0), epsilon<T>()) && std::fabs(x) < std::numeric_limits<T>::min();
|
||||
# endif
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER typename vec<1, T, Q>::bool_type isdenormal
|
||||
(
|
||||
vec<1, T, Q> const& x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'isdenormal' only accept floating-point inputs");
|
||||
|
||||
return typename vec<1, T, Q>::bool_type(
|
||||
isdenormal(x.x));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER typename vec<2, T, Q>::bool_type isdenormal
|
||||
(
|
||||
vec<2, T, Q> const& x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'isdenormal' only accept floating-point inputs");
|
||||
|
||||
return typename vec<2, T, Q>::bool_type(
|
||||
isdenormal(x.x),
|
||||
isdenormal(x.y));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER typename vec<3, T, Q>::bool_type isdenormal
|
||||
(
|
||||
vec<3, T, Q> const& x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'isdenormal' only accept floating-point inputs");
|
||||
|
||||
return typename vec<3, T, Q>::bool_type(
|
||||
isdenormal(x.x),
|
||||
isdenormal(x.y),
|
||||
isdenormal(x.z));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER typename vec<4, T, Q>::bool_type isdenormal
|
||||
(
|
||||
vec<4, T, Q> const& x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'isdenormal' only accept floating-point inputs");
|
||||
|
||||
return typename vec<4, T, Q>::bool_type(
|
||||
isdenormal(x.x),
|
||||
isdenormal(x.y),
|
||||
isdenormal(x.z),
|
||||
isdenormal(x.w));
|
||||
}
|
||||
|
||||
// fmod
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType fmod(genType x, genType y)
|
||||
{
|
||||
return fmod(vec<1, genType>(x), y).x;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fmod(vec<L, T, Q> const& x, T y)
|
||||
{
|
||||
return detail::compute_fmod<L, T, Q, std::numeric_limits<T>::is_iec559>::call(x, vec<L, T, Q>(y));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fmod(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
|
||||
{
|
||||
return detail::compute_fmod<L, T, Q, std::numeric_limits<T>::is_iec559>::call(x, y);
|
||||
}
|
||||
|
||||
template <length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, bool, Q> openBounded(vec<L, T, Q> const& Value, vec<L, T, Q> const& Min, vec<L, T, Q> const& Max)
|
||||
{
|
||||
return greaterThan(Value, Min) && lessThan(Value, Max);
|
||||
}
|
||||
|
||||
template <length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, bool, Q> closeBounded(vec<L, T, Q> const& Value, vec<L, T, Q> const& Min, vec<L, T, Q> const& Max)
|
||||
{
|
||||
return greaterThanEqual(Value, Min) && lessThanEqual(Value, Max);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,132 @@
|
||||
/// @ref gtx_compatibility
|
||||
/// @file glm/gtx/compatibility.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_compatibility GLM_GTX_compatibility
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/compatibility.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Provide functions to increase the compatibility with Cg and HLSL languages
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../gtc/quaternion.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_compatibility is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_compatibility extension included")
|
||||
#endif
|
||||
|
||||
#if GLM_COMPILER & GLM_COMPILER_VC
|
||||
# include <cfloat>
|
||||
#elif GLM_COMPILER & GLM_COMPILER_GCC
|
||||
# include <cmath>
|
||||
# if(GLM_PLATFORM & GLM_PLATFORM_ANDROID)
|
||||
# undef isfinite
|
||||
# endif
|
||||
#endif//GLM_COMPILER
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_compatibility
|
||||
/// @{
|
||||
|
||||
template<typename T> GLM_FUNC_QUALIFIER T lerp(T x, T y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<2, T, Q> lerp(const vec<2, T, Q>& x, const vec<2, T, Q>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
|
||||
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<3, T, Q> lerp(const vec<3, T, Q>& x, const vec<3, T, Q>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<4, T, Q> lerp(const vec<4, T, Q>& x, const vec<4, T, Q>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<2, T, Q> lerp(const vec<2, T, Q>& x, const vec<2, T, Q>& y, const vec<2, T, Q>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<3, T, Q> lerp(const vec<3, T, Q>& x, const vec<3, T, Q>& y, const vec<3, T, Q>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<4, T, Q> lerp(const vec<4, T, Q>& x, const vec<4, T, Q>& y, const vec<4, T, Q>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
|
||||
|
||||
template<typename T> GLM_FUNC_QUALIFIER T saturate(T x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<2, T, Q> saturate(const vec<2, T, Q>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<3, T, Q> saturate(const vec<3, T, Q>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<4, T, Q> saturate(const vec<4, T, Q>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
|
||||
|
||||
template<typename T> GLM_FUNC_QUALIFIER T atan2(T y, T x){return atan(y, x);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<2, T, Q> atan2(const vec<2, T, Q>& y, const vec<2, T, Q>& x){return atan(y, x);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<3, T, Q> atan2(const vec<3, T, Q>& y, const vec<3, T, Q>& x){return atan(y, x);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_QUALIFIER vec<4, T, Q> atan2(const vec<4, T, Q>& y, const vec<4, T, Q>& x){return atan(y, x);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
|
||||
|
||||
template<typename genType> GLM_FUNC_DECL bool isfinite(genType const& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_DECL vec<1, bool, Q> isfinite(const vec<1, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_DECL vec<2, bool, Q> isfinite(const vec<2, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_DECL vec<3, bool, Q> isfinite(const vec<3, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_DECL vec<4, bool, Q> isfinite(const vec<4, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)
|
||||
template<typename T, qualifier Q> GLM_FUNC_DECL vec<4, bool, Q> isfinite(const qua<T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)
|
||||
|
||||
typedef bool bool1; //!< \brief boolean type with 1 component. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<2, bool, highp> bool2; //!< \brief boolean type with 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<3, bool, highp> bool3; //!< \brief boolean type with 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<4, bool, highp> bool4; //!< \brief boolean type with 4 components. (From GLM_GTX_compatibility extension)
|
||||
|
||||
typedef bool bool1x1; //!< \brief boolean matrix with 1 x 1 component. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 2, bool, highp> bool2x2; //!< \brief boolean matrix with 2 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 3, bool, highp> bool2x3; //!< \brief boolean matrix with 2 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 4, bool, highp> bool2x4; //!< \brief boolean matrix with 2 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 2, bool, highp> bool3x2; //!< \brief boolean matrix with 3 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 3, bool, highp> bool3x3; //!< \brief boolean matrix with 3 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 4, bool, highp> bool3x4; //!< \brief boolean matrix with 3 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 2, bool, highp> bool4x2; //!< \brief boolean matrix with 4 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 3, bool, highp> bool4x3; //!< \brief boolean matrix with 4 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 4, bool, highp> bool4x4; //!< \brief boolean matrix with 4 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
|
||||
typedef int int1; //!< \brief integer vector with 1 component. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<2, int, highp> int2; //!< \brief integer vector with 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<3, int, highp> int3; //!< \brief integer vector with 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<4, int, highp> int4; //!< \brief integer vector with 4 components. (From GLM_GTX_compatibility extension)
|
||||
|
||||
typedef int int1x1; //!< \brief integer matrix with 1 component. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 2, int, highp> int2x2; //!< \brief integer matrix with 2 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 3, int, highp> int2x3; //!< \brief integer matrix with 2 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 4, int, highp> int2x4; //!< \brief integer matrix with 2 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 2, int, highp> int3x2; //!< \brief integer matrix with 3 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 3, int, highp> int3x3; //!< \brief integer matrix with 3 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 4, int, highp> int3x4; //!< \brief integer matrix with 3 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 2, int, highp> int4x2; //!< \brief integer matrix with 4 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 3, int, highp> int4x3; //!< \brief integer matrix with 4 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 4, int, highp> int4x4; //!< \brief integer matrix with 4 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
|
||||
typedef float float1; //!< \brief single-qualifier floating-point vector with 1 component. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<2, float, highp> float2; //!< \brief single-qualifier floating-point vector with 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<3, float, highp> float3; //!< \brief single-qualifier floating-point vector with 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<4, float, highp> float4; //!< \brief single-qualifier floating-point vector with 4 components. (From GLM_GTX_compatibility extension)
|
||||
|
||||
typedef float float1x1; //!< \brief single-qualifier floating-point matrix with 1 component. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 2, float, highp> float2x2; //!< \brief single-qualifier floating-point matrix with 2 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 3, float, highp> float2x3; //!< \brief single-qualifier floating-point matrix with 2 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 4, float, highp> float2x4; //!< \brief single-qualifier floating-point matrix with 2 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 2, float, highp> float3x2; //!< \brief single-qualifier floating-point matrix with 3 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 3, float, highp> float3x3; //!< \brief single-qualifier floating-point matrix with 3 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 4, float, highp> float3x4; //!< \brief single-qualifier floating-point matrix with 3 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 2, float, highp> float4x2; //!< \brief single-qualifier floating-point matrix with 4 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 3, float, highp> float4x3; //!< \brief single-qualifier floating-point matrix with 4 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 4, float, highp> float4x4; //!< \brief single-qualifier floating-point matrix with 4 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
|
||||
typedef double double1; //!< \brief double-qualifier floating-point vector with 1 component. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<2, double, highp> double2; //!< \brief double-qualifier floating-point vector with 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<3, double, highp> double3; //!< \brief double-qualifier floating-point vector with 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef vec<4, double, highp> double4; //!< \brief double-qualifier floating-point vector with 4 components. (From GLM_GTX_compatibility extension)
|
||||
|
||||
typedef double double1x1; //!< \brief double-qualifier floating-point matrix with 1 component. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 2, double, highp> double2x2; //!< \brief double-qualifier floating-point matrix with 2 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 3, double, highp> double2x3; //!< \brief double-qualifier floating-point matrix with 2 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<2, 4, double, highp> double2x4; //!< \brief double-qualifier floating-point matrix with 2 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 2, double, highp> double3x2; //!< \brief double-qualifier floating-point matrix with 3 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 3, double, highp> double3x3; //!< \brief double-qualifier floating-point matrix with 3 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<3, 4, double, highp> double3x4; //!< \brief double-qualifier floating-point matrix with 3 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 2, double, highp> double4x2; //!< \brief double-qualifier floating-point matrix with 4 x 2 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 3, double, highp> double4x3; //!< \brief double-qualifier floating-point matrix with 4 x 3 components. (From GLM_GTX_compatibility extension)
|
||||
typedef mat<4, 4, double, highp> double4x4; //!< \brief double-qualifier floating-point matrix with 4 x 4 components. (From GLM_GTX_compatibility extension)
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "compatibility.inl"
|
||||
@@ -0,0 +1,73 @@
|
||||
#include <limits>
|
||||
|
||||
namespace glm
|
||||
{
|
||||
// isfinite
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER bool isfinite(
|
||||
genType const& x)
|
||||
{
|
||||
# if GLM_HAS_CXX11_STL
|
||||
return std::isfinite(x) != 0;
|
||||
# elif GLM_COMPILER & GLM_COMPILER_VC
|
||||
return _finite(x) != 0;
|
||||
# elif GLM_COMPILER & GLM_COMPILER_GCC && GLM_PLATFORM & GLM_PLATFORM_ANDROID
|
||||
return _isfinite(x) != 0;
|
||||
# else
|
||||
if (std::numeric_limits<genType>::is_integer || std::denorm_absent == std::numeric_limits<genType>::has_denorm)
|
||||
return std::numeric_limits<genType>::min() <= x && std::numeric_limits<genType>::max() >= x;
|
||||
else
|
||||
return -std::numeric_limits<genType>::max() <= x && std::numeric_limits<genType>::max() >= x;
|
||||
# endif
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<1, bool, Q> isfinite(
|
||||
vec<1, T, Q> const& x)
|
||||
{
|
||||
return vec<1, bool, Q>(
|
||||
isfinite(x.x));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<2, bool, Q> isfinite(
|
||||
vec<2, T, Q> const& x)
|
||||
{
|
||||
return vec<2, bool, Q>(
|
||||
isfinite(x.x),
|
||||
isfinite(x.y));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, bool, Q> isfinite(
|
||||
vec<3, T, Q> const& x)
|
||||
{
|
||||
return vec<3, bool, Q>(
|
||||
isfinite(x.x),
|
||||
isfinite(x.y),
|
||||
isfinite(x.z));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> isfinite(
|
||||
vec<4, T, Q> const& x)
|
||||
{
|
||||
return vec<4, bool, Q>(
|
||||
isfinite(x.x),
|
||||
isfinite(x.y),
|
||||
isfinite(x.z),
|
||||
isfinite(x.w));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> isfinite(
|
||||
qua<T, Q> const& x)
|
||||
{
|
||||
return vec<4, bool, Q>(
|
||||
isfinite(x.x),
|
||||
isfinite(x.y),
|
||||
isfinite(x.z),
|
||||
isfinite(x.w));
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,77 @@
|
||||
/// @ref gtx_component_wise
|
||||
/// @file glm/gtx/component_wise.hpp
|
||||
/// @date 2007-05-21 / 2011-06-07
|
||||
/// @author Christophe Riccio
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_component_wise GLM_GTX_component_wise
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/component_wise.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Operations between components of a type
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependencies
|
||||
#include "../detail/setup.hpp"
|
||||
#include "../detail/qualifier.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_component_wise is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_component_wise extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_component_wise
|
||||
/// @{
|
||||
|
||||
/// Convert an integer vector to a normalized float vector.
|
||||
/// If the parameter value type is already a floating qualifier type, the value is passed through.
|
||||
/// @see gtx_component_wise
|
||||
template<typename floatType, length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, floatType, Q> compNormalize(vec<L, T, Q> const& v);
|
||||
|
||||
/// Convert a normalized float vector to an integer vector.
|
||||
/// If the parameter value type is already a floating qualifier type, the value is passed through.
|
||||
/// @see gtx_component_wise
|
||||
template<length_t L, typename T, typename floatType, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> compScale(vec<L, floatType, Q> const& v);
|
||||
|
||||
/// Add all vector components together.
|
||||
/// @see gtx_component_wise
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL typename genType::value_type compAdd(genType const& v);
|
||||
|
||||
/// Multiply all vector components together.
|
||||
/// @see gtx_component_wise
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL typename genType::value_type compMul(genType const& v);
|
||||
|
||||
/// Find the minimum value between single vector components.
|
||||
/// @see gtx_component_wise
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL typename genType::value_type compMin(genType const& v);
|
||||
|
||||
/// Find the maximum value between single vector components.
|
||||
/// @see gtx_component_wise
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL typename genType::value_type compMax(genType const& v);
|
||||
|
||||
/// Find the minimum float between single vector components.
|
||||
/// @see gtx_component_wise
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL typename genType::value_type fcompMin(genType const& v);
|
||||
|
||||
/// Find the maximum float between single vector components.
|
||||
/// @see gtx_component_wise
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL typename genType::value_type fcompMax(genType const& v);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "component_wise.inl"
|
||||
@@ -0,0 +1,147 @@
|
||||
/// @ref gtx_component_wise
|
||||
|
||||
#include "../ext/scalar_common.hpp"
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
namespace glm{
|
||||
namespace detail
|
||||
{
|
||||
template<length_t L, typename T, typename floatType, qualifier Q, bool isInteger, bool signedType>
|
||||
struct compute_compNormalize
|
||||
{};
|
||||
|
||||
template<length_t L, typename T, typename floatType, qualifier Q>
|
||||
struct compute_compNormalize<L, T, floatType, Q, true, true>
|
||||
{
|
||||
GLM_FUNC_QUALIFIER static vec<L, floatType, Q> call(vec<L, T, Q> const& v)
|
||||
{
|
||||
floatType const Min = static_cast<floatType>((std::numeric_limits<T>::min)());
|
||||
floatType const Max = static_cast<floatType>((std::numeric_limits<T>::max)());
|
||||
return (vec<L, floatType, Q>(v) - Min) / (Max - Min) * static_cast<floatType>(2) - static_cast<floatType>(1);
|
||||
}
|
||||
};
|
||||
|
||||
template<length_t L, typename T, typename floatType, qualifier Q>
|
||||
struct compute_compNormalize<L, T, floatType, Q, true, false>
|
||||
{
|
||||
GLM_FUNC_QUALIFIER static vec<L, floatType, Q> call(vec<L, T, Q> const& v)
|
||||
{
|
||||
return vec<L, floatType, Q>(v) / static_cast<floatType>((std::numeric_limits<T>::max)());
|
||||
}
|
||||
};
|
||||
|
||||
template<length_t L, typename T, typename floatType, qualifier Q>
|
||||
struct compute_compNormalize<L, T, floatType, Q, false, true>
|
||||
{
|
||||
GLM_FUNC_QUALIFIER static vec<L, floatType, Q> call(vec<L, T, Q> const& v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
template<length_t L, typename T, typename floatType, qualifier Q, bool isInteger, bool signedType>
|
||||
struct compute_compScale
|
||||
{};
|
||||
|
||||
template<length_t L, typename T, typename floatType, qualifier Q>
|
||||
struct compute_compScale<L, T, floatType, Q, true, true>
|
||||
{
|
||||
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, floatType, Q> const& v)
|
||||
{
|
||||
floatType const Max = static_cast<floatType>((std::numeric_limits<T>::max)()) + static_cast<floatType>(0.5);
|
||||
vec<L, floatType, Q> const Scaled(v * Max);
|
||||
vec<L, T, Q> const Result(Scaled - static_cast<floatType>(0.5));
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
|
||||
template<length_t L, typename T, typename floatType, qualifier Q>
|
||||
struct compute_compScale<L, T, floatType, Q, true, false>
|
||||
{
|
||||
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, floatType, Q> const& v)
|
||||
{
|
||||
return vec<L, T, Q>(vec<L, floatType, Q>(v) * static_cast<floatType>((std::numeric_limits<T>::max)()));
|
||||
}
|
||||
};
|
||||
|
||||
template<length_t L, typename T, typename floatType, qualifier Q>
|
||||
struct compute_compScale<L, T, floatType, Q, false, true>
|
||||
{
|
||||
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, floatType, Q> const& v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
};
|
||||
}//namespace detail
|
||||
|
||||
template<typename floatType, length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, floatType, Q> compNormalize(vec<L, T, Q> const& v)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "'compNormalize' accepts only floating-point types for 'floatType' template parameter");
|
||||
|
||||
return detail::compute_compNormalize<L, T, floatType, Q, std::numeric_limits<T>::is_integer, std::numeric_limits<T>::is_signed>::call(v);
|
||||
}
|
||||
|
||||
template<typename T, length_t L, typename floatType, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> compScale(vec<L, floatType, Q> const& v)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "'compScale' accepts only floating-point types for 'floatType' template parameter");
|
||||
|
||||
return detail::compute_compScale<L, T, floatType, Q, std::numeric_limits<T>::is_integer, std::numeric_limits<T>::is_signed>::call(v);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T compAdd(vec<L, T, Q> const& v)
|
||||
{
|
||||
T Result(0);
|
||||
for(length_t i = 0, n = v.length(); i < n; ++i)
|
||||
Result += v[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T compMul(vec<L, T, Q> const& v)
|
||||
{
|
||||
T Result(1);
|
||||
for(length_t i = 0, n = v.length(); i < n; ++i)
|
||||
Result *= v[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T compMin(vec<L, T, Q> const& v)
|
||||
{
|
||||
T Result(v[0]);
|
||||
for(length_t i = 1, n = v.length(); i < n; ++i)
|
||||
Result = min(Result, v[i]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T compMax(vec<L, T, Q> const& v)
|
||||
{
|
||||
T Result(v[0]);
|
||||
for(length_t i = 1, n = v.length(); i < n; ++i)
|
||||
Result = max(Result, v[i]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T fcompMin(vec<L, T, Q> const& v)
|
||||
{
|
||||
T Result(v[0]);
|
||||
for(length_t i = 1, n = v.length(); i < n; ++i)
|
||||
Result = fmin(Result, v[i]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T fcompMax(vec<L, T, Q> const& v)
|
||||
{
|
||||
T Result(v[0]);
|
||||
for(length_t i = 1, n = v.length(); i < n; ++i)
|
||||
Result = fmax(Result, v[i]);
|
||||
return Result;
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,272 @@
|
||||
/// @ref gtx_dual_quaternion
|
||||
/// @file glm/gtx/dual_quaternion.hpp
|
||||
/// @author Maksim Vorobiev ([email protected])
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtc_constants (dependence)
|
||||
/// @see gtc_quaternion (dependence)
|
||||
///
|
||||
/// @defgroup gtx_dual_quaternion GLM_GTX_dual_quaternion
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/dual_quaternion.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Defines a templated dual-quaternion type and several dual-quaternion operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../gtc/constants.hpp"
|
||||
#include "../gtc/quaternion.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_dual_quaternion is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_dual_quaternion extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_dual_quaternion
|
||||
/// @{
|
||||
|
||||
template<typename T, qualifier Q = defaultp>
|
||||
struct tdualquat
|
||||
{
|
||||
// -- Implementation detail --
|
||||
|
||||
typedef T value_type;
|
||||
typedef qua<T, Q> part_type;
|
||||
|
||||
// -- Data --
|
||||
|
||||
qua<T, Q> real, dual;
|
||||
|
||||
// -- Component accesses --
|
||||
|
||||
typedef length_t length_type;
|
||||
/// Return the count of components of a dual quaternion
|
||||
GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 2;}
|
||||
|
||||
GLM_FUNC_DECL part_type & operator[](length_type i);
|
||||
GLM_FUNC_DECL part_type const& operator[](length_type i) const;
|
||||
|
||||
// -- Implicit basic constructors --
|
||||
|
||||
GLM_DEFAULTED_FUNC_DECL GLM_CONSTEXPR tdualquat() GLM_DEFAULT;
|
||||
GLM_DEFAULTED_FUNC_DECL GLM_CONSTEXPR tdualquat(tdualquat<T, Q> const& d) GLM_DEFAULT;
|
||||
template<qualifier P>
|
||||
GLM_CTOR_DECL tdualquat(tdualquat<T, P> const& d);
|
||||
|
||||
// -- Explicit basic constructors --
|
||||
|
||||
GLM_CTOR_DECL tdualquat(qua<T, Q> const& real);
|
||||
GLM_CTOR_DECL tdualquat(qua<T, Q> const& orientation, vec<3, T, Q> const& translation);
|
||||
GLM_CTOR_DECL tdualquat(qua<T, Q> const& real, qua<T, Q> const& dual);
|
||||
|
||||
// -- Conversion constructors --
|
||||
|
||||
template<typename U, qualifier P>
|
||||
GLM_CTOR_DECL GLM_EXPLICIT tdualquat(tdualquat<U, P> const& q);
|
||||
|
||||
GLM_CTOR_DECL GLM_EXPLICIT tdualquat(mat<2, 4, T, Q> const& holder_mat);
|
||||
GLM_CTOR_DECL GLM_EXPLICIT tdualquat(mat<3, 4, T, Q> const& aug_mat);
|
||||
|
||||
// -- Unary arithmetic operators --
|
||||
|
||||
GLM_DEFAULTED_FUNC_DECL tdualquat<T, Q> & operator=(tdualquat<T, Q> const& m) GLM_DEFAULT;
|
||||
|
||||
template<typename U>
|
||||
GLM_FUNC_DISCARD_DECL tdualquat<T, Q> & operator=(tdualquat<U, Q> const& m);
|
||||
template<typename U>
|
||||
GLM_FUNC_DISCARD_DECL tdualquat<T, Q> & operator*=(U s);
|
||||
template<typename U>
|
||||
GLM_FUNC_DISCARD_DECL tdualquat<T, Q> & operator/=(U s);
|
||||
};
|
||||
|
||||
// -- Unary bit operators --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> operator+(tdualquat<T, Q> const& q);
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> operator-(tdualquat<T, Q> const& q);
|
||||
|
||||
// -- Binary operators --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> operator+(tdualquat<T, Q> const& q, tdualquat<T, Q> const& p);
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> operator*(tdualquat<T, Q> const& q, tdualquat<T, Q> const& p);
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> operator*(tdualquat<T, Q> const& q, vec<3, T, Q> const& v);
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> operator*(vec<3, T, Q> const& v, tdualquat<T, Q> const& q);
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, T, Q> operator*(tdualquat<T, Q> const& q, vec<4, T, Q> const& v);
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, T, Q> operator*(vec<4, T, Q> const& v, tdualquat<T, Q> const& q);
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> operator*(tdualquat<T, Q> const& q, T const& s);
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> operator*(T const& s, tdualquat<T, Q> const& q);
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> operator/(tdualquat<T, Q> const& q, T const& s);
|
||||
|
||||
// -- Boolean operators --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL bool operator==(tdualquat<T, Q> const& q1, tdualquat<T, Q> const& q2);
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL bool operator!=(tdualquat<T, Q> const& q1, tdualquat<T, Q> const& q2);
|
||||
|
||||
/// Creates an identity dual quaternion.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
template <typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> dual_quat_identity();
|
||||
|
||||
/// Returns the normalized quaternion.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> normalize(tdualquat<T, Q> const& q);
|
||||
|
||||
/// Returns the linear interpolation of two dual quaternion.
|
||||
///
|
||||
/// @see gtc_dual_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> lerp(tdualquat<T, Q> const& x, tdualquat<T, Q> const& y, T const& a);
|
||||
|
||||
/// Returns the q inverse.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> inverse(tdualquat<T, Q> const& q);
|
||||
|
||||
/// Converts a quaternion to a 2 * 4 matrix.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<2, 4, T, Q> mat2x4_cast(tdualquat<T, Q> const& x);
|
||||
|
||||
/// Converts a quaternion to a 3 * 4 matrix.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 4, T, Q> mat3x4_cast(tdualquat<T, Q> const& x);
|
||||
|
||||
/// Converts a 2 * 4 matrix (matrix which holds real and dual parts) to a quaternion.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> dualquat_cast(mat<2, 4, T, Q> const& x);
|
||||
|
||||
/// Converts a 3 * 4 matrix (augmented matrix rotation + translation) to a quaternion.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL tdualquat<T, Q> dualquat_cast(mat<3, 4, T, Q> const& x);
|
||||
|
||||
|
||||
/// Dual-quaternion of low single-qualifier floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef tdualquat<float, lowp> lowp_dualquat;
|
||||
|
||||
/// Dual-quaternion of medium single-qualifier floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef tdualquat<float, mediump> mediump_dualquat;
|
||||
|
||||
/// Dual-quaternion of high single-qualifier floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef tdualquat<float, highp> highp_dualquat;
|
||||
|
||||
|
||||
/// Dual-quaternion of low single-qualifier floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef tdualquat<float, lowp> lowp_fdualquat;
|
||||
|
||||
/// Dual-quaternion of medium single-qualifier floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef tdualquat<float, mediump> mediump_fdualquat;
|
||||
|
||||
/// Dual-quaternion of high single-qualifier floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef tdualquat<float, highp> highp_fdualquat;
|
||||
|
||||
|
||||
/// Dual-quaternion of low double-qualifier floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef tdualquat<double, lowp> lowp_ddualquat;
|
||||
|
||||
/// Dual-quaternion of medium double-qualifier floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef tdualquat<double, mediump> mediump_ddualquat;
|
||||
|
||||
/// Dual-quaternion of high double-qualifier floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef tdualquat<double, highp> highp_ddualquat;
|
||||
|
||||
|
||||
#if(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
|
||||
/// Dual-quaternion of floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef highp_fdualquat dualquat;
|
||||
|
||||
/// Dual-quaternion of single-qualifier floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef highp_fdualquat fdualquat;
|
||||
#elif(defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
|
||||
typedef highp_fdualquat dualquat;
|
||||
typedef highp_fdualquat fdualquat;
|
||||
#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
|
||||
typedef mediump_fdualquat dualquat;
|
||||
typedef mediump_fdualquat fdualquat;
|
||||
#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && defined(GLM_PRECISION_LOWP_FLOAT))
|
||||
typedef lowp_fdualquat dualquat;
|
||||
typedef lowp_fdualquat fdualquat;
|
||||
#else
|
||||
# error "GLM error: multiple default precision requested for single-precision floating-point types"
|
||||
#endif
|
||||
|
||||
|
||||
#if(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
|
||||
/// Dual-quaternion of default double-qualifier floating-point numbers.
|
||||
///
|
||||
/// @see gtx_dual_quaternion
|
||||
typedef highp_ddualquat ddualquat;
|
||||
#elif(defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
|
||||
typedef highp_ddualquat ddualquat;
|
||||
#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
|
||||
typedef mediump_ddualquat ddualquat;
|
||||
#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && defined(GLM_PRECISION_LOWP_DOUBLE))
|
||||
typedef lowp_ddualquat ddualquat;
|
||||
#else
|
||||
# error "GLM error: Multiple default precision requested for double-precision floating-point types"
|
||||
#endif
|
||||
|
||||
/// @}
|
||||
} //namespace glm
|
||||
|
||||
#include "dual_quaternion.inl"
|
||||
@@ -0,0 +1,352 @@
|
||||
/// @ref gtx_dual_quaternion
|
||||
|
||||
#include "../geometric.hpp"
|
||||
#include <limits>
|
||||
|
||||
namespace glm
|
||||
{
|
||||
// -- Component accesses --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER typename tdualquat<T, Q>::part_type & tdualquat<T, Q>::operator[](typename tdualquat<T, Q>::length_type i)
|
||||
{
|
||||
assert(i >= 0 && i < this->length());
|
||||
return (&real)[i];
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER typename tdualquat<T, Q>::part_type const& tdualquat<T, Q>::operator[](typename tdualquat<T, Q>::length_type i) const
|
||||
{
|
||||
assert(i >= 0 && i < this->length());
|
||||
return (&real)[i];
|
||||
}
|
||||
|
||||
// -- Implicit basic constructors --
|
||||
|
||||
# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE
|
||||
template<typename T, qualifier Q>
|
||||
GLM_DEFAULTED_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat()
|
||||
# if GLM_CONFIG_DEFAULTED_FUNCTIONS != GLM_DISABLE
|
||||
: real(qua<T, Q>())
|
||||
, dual(qua<T, Q>::wxyz(0, 0, 0, 0))
|
||||
# endif
|
||||
{}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_DEFAULTED_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(tdualquat<T, Q> const& d)
|
||||
: real(d.real)
|
||||
, dual(d.dual)
|
||||
{}
|
||||
# endif
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
template<qualifier P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(tdualquat<T, P> const& d)
|
||||
: real(d.real)
|
||||
, dual(d.dual)
|
||||
{}
|
||||
|
||||
// -- Explicit basic constructors --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(qua<T, Q> const& r)
|
||||
: real(r), dual(qua<T, Q>::wxyz(0, 0, 0, 0))
|
||||
{}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(qua<T, Q> const& q, vec<3, T, Q> const& p)
|
||||
: real(q), dual(qua<T, Q>::wxyz(
|
||||
T(-0.5) * ( p.x*q.x + p.y*q.y + p.z*q.z),
|
||||
T(+0.5) * ( p.x*q.w + p.y*q.z - p.z*q.y),
|
||||
T(+0.5) * (-p.x*q.z + p.y*q.w + p.z*q.x),
|
||||
T(+0.5) * ( p.x*q.y - p.y*q.x + p.z*q.w)))
|
||||
{}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(qua<T, Q> const& r, qua<T, Q> const& d)
|
||||
: real(r), dual(d)
|
||||
{}
|
||||
|
||||
// -- Conversion constructors --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
template<typename U, qualifier P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(tdualquat<U, P> const& q)
|
||||
: real(q.real)
|
||||
, dual(q.dual)
|
||||
{}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(mat<2, 4, T, Q> const& m)
|
||||
{
|
||||
*this = dualquat_cast(m);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(mat<3, 4, T, Q> const& m)
|
||||
{
|
||||
*this = dualquat_cast(m);
|
||||
}
|
||||
|
||||
// -- Unary arithmetic operators --
|
||||
|
||||
# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE
|
||||
template<typename T, qualifier Q>
|
||||
GLM_DEFAULTED_FUNC_QUALIFIER tdualquat<T, Q> & tdualquat<T, Q>::operator=(tdualquat<T, Q> const& q)
|
||||
{
|
||||
this->real = q.real;
|
||||
this->dual = q.dual;
|
||||
return *this;
|
||||
}
|
||||
# endif
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
template<typename U>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> & tdualquat<T, Q>::operator=(tdualquat<U, Q> const& q)
|
||||
{
|
||||
this->real = q.real;
|
||||
this->dual = q.dual;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
template<typename U>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> & tdualquat<T, Q>::operator*=(U s)
|
||||
{
|
||||
this->real *= static_cast<T>(s);
|
||||
this->dual *= static_cast<T>(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
template<typename U>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> & tdualquat<T, Q>::operator/=(U s)
|
||||
{
|
||||
this->real /= static_cast<T>(s);
|
||||
this->dual /= static_cast<T>(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// -- Unary bit operators --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> operator+(tdualquat<T, Q> const& q)
|
||||
{
|
||||
return q;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> operator-(tdualquat<T, Q> const& q)
|
||||
{
|
||||
return tdualquat<T, Q>(-q.real, -q.dual);
|
||||
}
|
||||
|
||||
// -- Binary operators --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> operator+(tdualquat<T, Q> const& q, tdualquat<T, Q> const& p)
|
||||
{
|
||||
return tdualquat<T, Q>(q.real + p.real,q.dual + p.dual);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> operator*(tdualquat<T, Q> const& p, tdualquat<T, Q> const& o)
|
||||
{
|
||||
return tdualquat<T, Q>(p.real * o.real,p.real * o.dual + p.dual * o.real);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(tdualquat<T, Q> const& q, vec<3, T, Q> const& v)
|
||||
{
|
||||
vec<3, T, Q> const real_v3(q.real.x,q.real.y,q.real.z);
|
||||
vec<3, T, Q> const dual_v3(q.dual.x,q.dual.y,q.dual.z);
|
||||
return (cross(real_v3, cross(real_v3,v) + v * q.real.w + dual_v3) + dual_v3 * q.real.w - real_v3 * q.dual.w) * T(2) + v;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(vec<3, T, Q> const& v, tdualquat<T, Q> const& q)
|
||||
{
|
||||
return glm::inverse(q) * v;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(tdualquat<T, Q> const& q, vec<4, T, Q> const& v)
|
||||
{
|
||||
return vec<4, T, Q>(q * vec<3, T, Q>(v), v.w);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(vec<4, T, Q> const& v, tdualquat<T, Q> const& q)
|
||||
{
|
||||
return glm::inverse(q) * v;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> operator*(tdualquat<T, Q> const& q, T const& s)
|
||||
{
|
||||
return tdualquat<T, Q>(q.real * s, q.dual * s);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> operator*(T const& s, tdualquat<T, Q> const& q)
|
||||
{
|
||||
return q * s;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> operator/(tdualquat<T, Q> const& q, T const& s)
|
||||
{
|
||||
return tdualquat<T, Q>(q.real / s, q.dual / s);
|
||||
}
|
||||
|
||||
// -- Boolean operators --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool operator==(tdualquat<T, Q> const& q1, tdualquat<T, Q> const& q2)
|
||||
{
|
||||
return (q1.real == q2.real) && (q1.dual == q2.dual);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool operator!=(tdualquat<T, Q> const& q1, tdualquat<T, Q> const& q2)
|
||||
{
|
||||
return (q1.real != q2.real) || (q1.dual != q2.dual);
|
||||
}
|
||||
|
||||
// -- Operations --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> dual_quat_identity()
|
||||
{
|
||||
return tdualquat<T, Q>(
|
||||
qua<T, Q>::wxyz(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)),
|
||||
qua<T, Q>::wxyz(static_cast<T>(0), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> normalize(tdualquat<T, Q> const& q)
|
||||
{
|
||||
return q / length(q.real);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> lerp(tdualquat<T, Q> const& x, tdualquat<T, Q> const& y, T const& a)
|
||||
{
|
||||
// Dual Quaternion Linear blend aka DLB:
|
||||
// Lerp is only defined in [0, 1]
|
||||
assert(a >= static_cast<T>(0));
|
||||
assert(a <= static_cast<T>(1));
|
||||
T const k = dot(x.real,y.real) < static_cast<T>(0) ? -a : a;
|
||||
T const one(1);
|
||||
return tdualquat<T, Q>(x * (one - a) + y * k);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> inverse(tdualquat<T, Q> const& q)
|
||||
{
|
||||
const glm::qua<T, Q> real = conjugate(q.real);
|
||||
const glm::qua<T, Q> dual = conjugate(q.dual);
|
||||
return tdualquat<T, Q>(real, dual + (real * (-2.0f * dot(real,dual))));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<2, 4, T, Q> mat2x4_cast(tdualquat<T, Q> const& x)
|
||||
{
|
||||
return mat<2, 4, T, Q>( x[0].x, x[0].y, x[0].z, x[0].w, x[1].x, x[1].y, x[1].z, x[1].w );
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 4, T, Q> mat3x4_cast(tdualquat<T, Q> const& x)
|
||||
{
|
||||
qua<T, Q> r = x.real / length2(x.real);
|
||||
|
||||
qua<T, Q> const rr(r.w * x.real.w, r.x * x.real.x, r.y * x.real.y, r.z * x.real.z);
|
||||
r *= static_cast<T>(2);
|
||||
|
||||
T const xy = r.x * x.real.y;
|
||||
T const xz = r.x * x.real.z;
|
||||
T const yz = r.y * x.real.z;
|
||||
T const wx = r.w * x.real.x;
|
||||
T const wy = r.w * x.real.y;
|
||||
T const wz = r.w * x.real.z;
|
||||
|
||||
vec<4, T, Q> const a(
|
||||
rr.w + rr.x - rr.y - rr.z,
|
||||
xy - wz,
|
||||
xz + wy,
|
||||
-(x.dual.w * r.x - x.dual.x * r.w + x.dual.y * r.z - x.dual.z * r.y));
|
||||
|
||||
vec<4, T, Q> const b(
|
||||
xy + wz,
|
||||
rr.w + rr.y - rr.x - rr.z,
|
||||
yz - wx,
|
||||
-(x.dual.w * r.y - x.dual.x * r.z - x.dual.y * r.w + x.dual.z * r.x));
|
||||
|
||||
vec<4, T, Q> const c(
|
||||
xz - wy,
|
||||
yz + wx,
|
||||
rr.w + rr.z - rr.x - rr.y,
|
||||
-(x.dual.w * r.z + x.dual.x * r.y - x.dual.y * r.x - x.dual.z * r.w));
|
||||
|
||||
return mat<3, 4, T, Q>(a, b, c);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> dualquat_cast(mat<2, 4, T, Q> const& x)
|
||||
{
|
||||
return tdualquat<T, Q>(
|
||||
qua<T, Q>::wxyz( x[0].w, x[0].x, x[0].y, x[0].z ),
|
||||
qua<T, Q>::wxyz( x[1].w, x[1].x, x[1].y, x[1].z ));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tdualquat<T, Q> dualquat_cast(mat<3, 4, T, Q> const& x)
|
||||
{
|
||||
qua<T, Q> real;
|
||||
|
||||
T const trace = x[0].x + x[1].y + x[2].z;
|
||||
if(trace > static_cast<T>(0))
|
||||
{
|
||||
T const r = sqrt(T(1) + trace);
|
||||
T const invr = static_cast<T>(0.5) / r;
|
||||
real.w = static_cast<T>(0.5) * r;
|
||||
real.x = (x[2].y - x[1].z) * invr;
|
||||
real.y = (x[0].z - x[2].x) * invr;
|
||||
real.z = (x[1].x - x[0].y) * invr;
|
||||
}
|
||||
else if(x[0].x > x[1].y && x[0].x > x[2].z)
|
||||
{
|
||||
T const r = sqrt(T(1) + x[0].x - x[1].y - x[2].z);
|
||||
T const invr = static_cast<T>(0.5) / r;
|
||||
real.x = static_cast<T>(0.5)*r;
|
||||
real.y = (x[1].x + x[0].y) * invr;
|
||||
real.z = (x[0].z + x[2].x) * invr;
|
||||
real.w = (x[2].y - x[1].z) * invr;
|
||||
}
|
||||
else if(x[1].y > x[2].z)
|
||||
{
|
||||
T const r = sqrt(T(1) + x[1].y - x[0].x - x[2].z);
|
||||
T const invr = static_cast<T>(0.5) / r;
|
||||
real.x = (x[1].x + x[0].y) * invr;
|
||||
real.y = static_cast<T>(0.5) * r;
|
||||
real.z = (x[2].y + x[1].z) * invr;
|
||||
real.w = (x[0].z - x[2].x) * invr;
|
||||
}
|
||||
else
|
||||
{
|
||||
T const r = sqrt(T(1) + x[2].z - x[0].x - x[1].y);
|
||||
T const invr = static_cast<T>(0.5) / r;
|
||||
real.x = (x[0].z + x[2].x) * invr;
|
||||
real.y = (x[2].y + x[1].z) * invr;
|
||||
real.z = static_cast<T>(0.5) * r;
|
||||
real.w = (x[1].x - x[0].y) * invr;
|
||||
}
|
||||
|
||||
qua<T, Q> dual;
|
||||
dual.x = static_cast<T>(0.5) * ( x[0].w * real.w + x[1].w * real.z - x[2].w * real.y);
|
||||
dual.y = static_cast<T>(0.5) * (-x[0].w * real.z + x[1].w * real.w + x[2].w * real.x);
|
||||
dual.z = static_cast<T>(0.5) * ( x[0].w * real.y - x[1].w * real.x + x[2].w * real.w);
|
||||
dual.w = -static_cast<T>(0.5) * ( x[0].w * real.x + x[1].w * real.y + x[2].w * real.z);
|
||||
return tdualquat<T, Q>(real, dual);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,217 @@
|
||||
/// @ref gtx_easing
|
||||
/// @file glm/gtx/easing.hpp
|
||||
/// @author Robert Chisholm
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_easing GLM_GTX_easing
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/easing.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Easing functions for animations and transitions
|
||||
/// All functions take a parameter x in the range [0.0,1.0]
|
||||
///
|
||||
/// Based on the AHEasing project of Warren Moore (https://github.com/warrenm/AHEasing)
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../gtc/constants.hpp"
|
||||
#include "../detail/qualifier.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_easing is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_easing extension included")
|
||||
#endif
|
||||
|
||||
namespace glm{
|
||||
/// @addtogroup gtx_easing
|
||||
/// @{
|
||||
|
||||
/// Modelled after the line y = x
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType linearInterpolation(genType const & a);
|
||||
|
||||
/// Modelled after the parabola y = x^2
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType quadraticEaseIn(genType const & a);
|
||||
|
||||
/// Modelled after the parabola y = -x^2 + 2x
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType quadraticEaseOut(genType const & a);
|
||||
|
||||
/// Modelled after the piecewise quadratic
|
||||
/// y = (1/2)((2x)^2) ; [0, 0.5)
|
||||
/// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1]
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType quadraticEaseInOut(genType const & a);
|
||||
|
||||
/// Modelled after the cubic y = x^3
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType cubicEaseIn(genType const & a);
|
||||
|
||||
/// Modelled after the cubic y = (x - 1)^3 + 1
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType cubicEaseOut(genType const & a);
|
||||
|
||||
/// Modelled after the piecewise cubic
|
||||
/// y = (1/2)((2x)^3) ; [0, 0.5)
|
||||
/// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1]
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType cubicEaseInOut(genType const & a);
|
||||
|
||||
/// Modelled after the quartic x^4
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType quarticEaseIn(genType const & a);
|
||||
|
||||
/// Modelled after the quartic y = 1 - (x - 1)^4
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType quarticEaseOut(genType const & a);
|
||||
|
||||
/// Modelled after the piecewise quartic
|
||||
/// y = (1/2)((2x)^4) ; [0, 0.5)
|
||||
/// y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1]
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType quarticEaseInOut(genType const & a);
|
||||
|
||||
/// Modelled after the quintic y = x^5
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType quinticEaseIn(genType const & a);
|
||||
|
||||
/// Modelled after the quintic y = (x - 1)^5 + 1
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType quinticEaseOut(genType const & a);
|
||||
|
||||
/// Modelled after the piecewise quintic
|
||||
/// y = (1/2)((2x)^5) ; [0, 0.5)
|
||||
/// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1]
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType quinticEaseInOut(genType const & a);
|
||||
|
||||
/// Modelled after quarter-cycle of sine wave
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType sineEaseIn(genType const & a);
|
||||
|
||||
/// Modelled after quarter-cycle of sine wave (different phase)
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType sineEaseOut(genType const & a);
|
||||
|
||||
/// Modelled after half sine wave
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType sineEaseInOut(genType const & a);
|
||||
|
||||
/// Modelled after shifted quadrant IV of unit circle
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType circularEaseIn(genType const & a);
|
||||
|
||||
/// Modelled after shifted quadrant II of unit circle
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType circularEaseOut(genType const & a);
|
||||
|
||||
/// Modelled after the piecewise circular function
|
||||
/// y = (1/2)(1 - sqrt(1 - 4x^2)) ; [0, 0.5)
|
||||
/// y = (1/2)(sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1]
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType circularEaseInOut(genType const & a);
|
||||
|
||||
/// Modelled after the exponential function y = 2^(10(x - 1))
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType exponentialEaseIn(genType const & a);
|
||||
|
||||
/// Modelled after the exponential function y = -2^(-10x) + 1
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType exponentialEaseOut(genType const & a);
|
||||
|
||||
/// Modelled after the piecewise exponential
|
||||
/// y = (1/2)2^(10(2x - 1)) ; [0,0.5)
|
||||
/// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1]
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType exponentialEaseInOut(genType const & a);
|
||||
|
||||
/// Modelled after the damped sine wave y = sin(13pi/2*x)*pow(2, 10 * (x - 1))
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType elasticEaseIn(genType const & a);
|
||||
|
||||
/// Modelled after the damped sine wave y = sin(-13pi/2*(x + 1))*pow(2, -10x) + 1
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType elasticEaseOut(genType const & a);
|
||||
|
||||
/// Modelled after the piecewise exponentially-damped sine wave:
|
||||
/// y = (1/2)*sin(13pi/2*(2*x))*pow(2, 10 * ((2*x) - 1)) ; [0,0.5)
|
||||
/// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*pow(2,-10(2*x-1)) + 2) ; [0.5, 1]
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType elasticEaseInOut(genType const & a);
|
||||
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType backEaseIn(genType const& a);
|
||||
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType backEaseOut(genType const& a);
|
||||
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType backEaseInOut(genType const& a);
|
||||
|
||||
/// @param a parameter
|
||||
/// @param o Optional overshoot modifier
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType backEaseIn(genType const& a, genType const& o);
|
||||
|
||||
/// @param a parameter
|
||||
/// @param o Optional overshoot modifier
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType backEaseOut(genType const& a, genType const& o);
|
||||
|
||||
/// @param a parameter
|
||||
/// @param o Optional overshoot modifier
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType backEaseInOut(genType const& a, genType const& o);
|
||||
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType bounceEaseIn(genType const& a);
|
||||
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType bounceEaseOut(genType const& a);
|
||||
|
||||
/// @see gtx_easing
|
||||
template <typename genType>
|
||||
GLM_FUNC_DECL genType bounceEaseInOut(genType const& a);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "easing.inl"
|
||||
@@ -0,0 +1,436 @@
|
||||
/// @ref gtx_easing
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace glm{
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType linearInterpolation(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType quadraticEaseIn(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return a * a;
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType quadraticEaseOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return -(a * (a - static_cast<genType>(2)));
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType quadraticEaseInOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
if(a < static_cast<genType>(0.5))
|
||||
{
|
||||
return static_cast<genType>(2) * a * a;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (-static_cast<genType>(2) * a * a) + (4 * a) - one<genType>();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType cubicEaseIn(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return a * a * a;
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType cubicEaseOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
genType const f = a - one<genType>();
|
||||
return f * f * f + one<genType>();
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType cubicEaseInOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
if (a < static_cast<genType>(0.5))
|
||||
{
|
||||
return static_cast<genType>(4) * a * a * a;
|
||||
}
|
||||
else
|
||||
{
|
||||
genType const f = ((static_cast<genType>(2) * a) - static_cast<genType>(2));
|
||||
return static_cast<genType>(0.5) * f * f * f + one<genType>();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType quarticEaseIn(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return a * a * a * a;
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType quarticEaseOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
genType const f = (a - one<genType>());
|
||||
return f * f * f * (one<genType>() - a) + one<genType>();
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType quarticEaseInOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
if(a < static_cast<genType>(0.5))
|
||||
{
|
||||
return static_cast<genType>(8) * a * a * a * a;
|
||||
}
|
||||
else
|
||||
{
|
||||
genType const f = (a - one<genType>());
|
||||
return -static_cast<genType>(8) * f * f * f * f + one<genType>();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType quinticEaseIn(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return a * a * a * a * a;
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType quinticEaseOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
genType const f = (a - one<genType>());
|
||||
return f * f * f * f * f + one<genType>();
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType quinticEaseInOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
if(a < static_cast<genType>(0.5))
|
||||
{
|
||||
return static_cast<genType>(16) * a * a * a * a * a;
|
||||
}
|
||||
else
|
||||
{
|
||||
genType const f = ((static_cast<genType>(2) * a) - static_cast<genType>(2));
|
||||
return static_cast<genType>(0.5) * f * f * f * f * f + one<genType>();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType sineEaseIn(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return sin((a - one<genType>()) * half_pi<genType>()) + one<genType>();
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType sineEaseOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return sin(a * half_pi<genType>());
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType sineEaseInOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return static_cast<genType>(0.5) * (one<genType>() - cos(a * pi<genType>()));
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType circularEaseIn(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return one<genType>() - sqrt(one<genType>() - (a * a));
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType circularEaseOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return sqrt((static_cast<genType>(2) - a) * a);
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType circularEaseInOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
if(a < static_cast<genType>(0.5))
|
||||
{
|
||||
return static_cast<genType>(0.5) * (one<genType>() - std::sqrt(one<genType>() - static_cast<genType>(4) * (a * a)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<genType>(0.5) * (std::sqrt(-((static_cast<genType>(2) * a) - static_cast<genType>(3)) * ((static_cast<genType>(2) * a) - one<genType>())) + one<genType>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType exponentialEaseIn(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
if(a <= zero<genType>())
|
||||
return a;
|
||||
else
|
||||
{
|
||||
genType const Complementary = a - one<genType>();
|
||||
genType const Two = static_cast<genType>(2);
|
||||
|
||||
return glm::pow(Two, Complementary * static_cast<genType>(10));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType exponentialEaseOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
if(a >= one<genType>())
|
||||
return a;
|
||||
else
|
||||
{
|
||||
return one<genType>() - glm::pow(static_cast<genType>(2), -static_cast<genType>(10) * a);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType exponentialEaseInOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
if(a < static_cast<genType>(0.5))
|
||||
return static_cast<genType>(0.5) * glm::pow(static_cast<genType>(2), (static_cast<genType>(20) * a) - static_cast<genType>(10));
|
||||
else
|
||||
return -static_cast<genType>(0.5) * glm::pow(static_cast<genType>(2), (-static_cast<genType>(20) * a) + static_cast<genType>(10)) + one<genType>();
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType elasticEaseIn(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return std::sin(static_cast<genType>(13) * half_pi<genType>() * a) * glm::pow(static_cast<genType>(2), static_cast<genType>(10) * (a - one<genType>()));
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType elasticEaseOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return std::sin(-static_cast<genType>(13) * half_pi<genType>() * (a + one<genType>())) * glm::pow(static_cast<genType>(2), -static_cast<genType>(10) * a) + one<genType>();
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType elasticEaseInOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
if(a < static_cast<genType>(0.5))
|
||||
return static_cast<genType>(0.5) * std::sin(static_cast<genType>(13) * half_pi<genType>() * (static_cast<genType>(2) * a)) * glm::pow(static_cast<genType>(2), static_cast<genType>(10) * ((static_cast<genType>(2) * a) - one<genType>()));
|
||||
else
|
||||
return static_cast<genType>(0.5) * (std::sin(-static_cast<genType>(13) * half_pi<genType>() * ((static_cast<genType>(2) * a - one<genType>()) + one<genType>())) * glm::pow(static_cast<genType>(2), -static_cast<genType>(10) * (static_cast<genType>(2) * a - one<genType>())) + static_cast<genType>(2));
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType backEaseIn(genType const& a, genType const& o)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
genType z = ((o + one<genType>()) * a) - o;
|
||||
return (a * a * z);
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType backEaseOut(genType const& a, genType const& o)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
genType n = a - one<genType>();
|
||||
genType z = ((o + one<genType>()) * n) + o;
|
||||
return (n * n * z) + one<genType>();
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType backEaseInOut(genType const& a, genType const& o)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
genType s = o * static_cast<genType>(1.525);
|
||||
genType x = static_cast<genType>(0.5);
|
||||
genType n = a / static_cast<genType>(0.5);
|
||||
|
||||
if (n < static_cast<genType>(1))
|
||||
{
|
||||
genType z = ((s + static_cast<genType>(1)) * n) - s;
|
||||
genType m = n * n * z;
|
||||
return x * m;
|
||||
}
|
||||
else
|
||||
{
|
||||
n -= static_cast<genType>(2);
|
||||
genType z = ((s + static_cast<genType>(1)) * n) + s;
|
||||
genType m = (n*n*z) + static_cast<genType>(2);
|
||||
return x * m;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType backEaseIn(genType const& a)
|
||||
{
|
||||
return backEaseIn(a, static_cast<genType>(1.70158));
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType backEaseOut(genType const& a)
|
||||
{
|
||||
return backEaseOut(a, static_cast<genType>(1.70158));
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType backEaseInOut(genType const& a)
|
||||
{
|
||||
return backEaseInOut(a, static_cast<genType>(1.70158));
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType bounceEaseOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
if(a < static_cast<genType>(4.0 / 11.0))
|
||||
{
|
||||
return (static_cast<genType>(121) * a * a) / static_cast<genType>(16);
|
||||
}
|
||||
else if(a < static_cast<genType>(8.0 / 11.0))
|
||||
{
|
||||
return (static_cast<genType>(363.0 / 40.0) * a * a) - (static_cast<genType>(99.0 / 10.0) * a) + static_cast<genType>(17.0 / 5.0);
|
||||
}
|
||||
else if(a < static_cast<genType>(9.0 / 10.0))
|
||||
{
|
||||
return (static_cast<genType>(4356.0 / 361.0) * a * a) - (static_cast<genType>(35442.0 / 1805.0) * a) + static_cast<genType>(16061.0 / 1805.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (static_cast<genType>(54.0 / 5.0) * a * a) - (static_cast<genType>(513.0 / 25.0) * a) + static_cast<genType>(268.0 / 25.0);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType bounceEaseIn(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
return one<genType>() - bounceEaseOut(one<genType>() - a);
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER genType bounceEaseInOut(genType const& a)
|
||||
{
|
||||
// Only defined in [0, 1]
|
||||
assert(a >= zero<genType>());
|
||||
assert(a <= one<genType>());
|
||||
|
||||
if(a < static_cast<genType>(0.5))
|
||||
{
|
||||
return static_cast<genType>(0.5) * (one<genType>() - bounceEaseOut(one<genType>() - a * static_cast<genType>(2)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<genType>(0.5) * bounceEaseOut(a * static_cast<genType>(2) - one<genType>()) + static_cast<genType>(0.5);
|
||||
}
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,333 @@
|
||||
/// @ref gtx_euler_angles
|
||||
/// @file glm/gtx/euler_angles.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_euler_angles GLM_GTX_euler_angles
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/euler_angles.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Build matrices from Euler angles.
|
||||
///
|
||||
/// Extraction of Euler angles from rotation matrix.
|
||||
/// Based on the original paper 2014 Mike Day - Extracting Euler Angles from a Rotation Matrix.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_euler_angles is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_euler_angles extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_euler_angles
|
||||
/// @{
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle X.
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleX(
|
||||
T const& angleX);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle Y.
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleY(
|
||||
T const& angleY);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle Z.
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZ(
|
||||
T const& angleZ);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous derived matrix from the rotation matrix about X-axis.
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> derivedEulerAngleX(
|
||||
T const & angleX, T const & angularVelocityX);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous derived matrix from the rotation matrix about Y-axis.
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> derivedEulerAngleY(
|
||||
T const & angleY, T const & angularVelocityY);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous derived matrix from the rotation matrix about Z-axis.
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> derivedEulerAngleZ(
|
||||
T const & angleZ, T const & angularVelocityZ);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Y).
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXY(
|
||||
T const& angleX,
|
||||
T const& angleY);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X).
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYX(
|
||||
T const& angleY,
|
||||
T const& angleX);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Z).
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXZ(
|
||||
T const& angleX,
|
||||
T const& angleZ);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * X).
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZX(
|
||||
T const& angle,
|
||||
T const& angleX);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * Z).
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYZ(
|
||||
T const& angleY,
|
||||
T const& angleZ);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * Y).
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZY(
|
||||
T const& angleZ,
|
||||
T const& angleY);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Y * Z).
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXYZ(
|
||||
T const& t1,
|
||||
T const& t2,
|
||||
T const& t3);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z).
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYXZ(
|
||||
T const& yaw,
|
||||
T const& pitch,
|
||||
T const& roll);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Z * X).
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXZX(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Y * X).
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXYX(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Y).
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYXY(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * Z * Y).
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYZY(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * Y * Z).
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZYZ(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * X * Z).
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZXZ(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Z * Y).
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXZY(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * Z * X).
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYZX(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * Y * X).
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZYX(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * X * Y).
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZXY(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z).
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<4, 4, T, defaultp> yawPitchRoll(
|
||||
T const& yaw,
|
||||
T const& pitch,
|
||||
T const& roll);
|
||||
|
||||
/// Creates a 2D 2 * 2 rotation matrix from an euler angle.
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<2, 2, T, defaultp> orientate2(T const& angle);
|
||||
|
||||
/// Creates a 2D 4 * 4 homogeneous rotation matrix from an euler angle.
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL mat<3, 3, T, defaultp> orientate3(T const& angle);
|
||||
|
||||
/// Creates a 3D 3 * 3 rotation matrix from euler angles (Y * X * Z).
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 3, T, Q> orientate3(vec<3, T, Q> const& angles);
|
||||
|
||||
/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z).
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> orientate4(vec<3, T, Q> const& angles);
|
||||
|
||||
/// Extracts the (X * Y * Z) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template<typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleXYZ(mat<4, 4, T, defaultp> const& M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// Extracts the (Y * X * Z) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleYXZ(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// Extracts the (X * Z * X) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleXZX(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// Extracts the (X * Y * X) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleXYX(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// Extracts the (Y * X * Y) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleYXY(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// Extracts the (Y * Z * Y) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleYZY(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// Extracts the (Z * Y * Z) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleZYZ(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// Extracts the (Z * X * Z) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleZXZ(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// Extracts the (X * Z * Y) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleXZY(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// Extracts the (Y * Z * X) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleYZX(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// Extracts the (Z * Y * X) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleZYX(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// Extracts the (Z * X * Y) Euler angles from the rotation matrix M
|
||||
/// @see gtx_euler_angles
|
||||
template <typename T>
|
||||
GLM_FUNC_DISCARD_DECL void extractEulerAngleZXY(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "euler_angles.inl"
|
||||
@@ -0,0 +1,899 @@
|
||||
/// @ref gtx_euler_angles
|
||||
|
||||
#include "compatibility.hpp" // glm::atan2
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleX
|
||||
(
|
||||
T const& angleX
|
||||
)
|
||||
{
|
||||
T cosX = glm::cos(angleX);
|
||||
T sinX = glm::sin(angleX);
|
||||
|
||||
return mat<4, 4, T, defaultp>(
|
||||
T(1), T(0), T(0), T(0),
|
||||
T(0), cosX, sinX, T(0),
|
||||
T(0),-sinX, cosX, T(0),
|
||||
T(0), T(0), T(0), T(1));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleY
|
||||
(
|
||||
T const& angleY
|
||||
)
|
||||
{
|
||||
T cosY = glm::cos(angleY);
|
||||
T sinY = glm::sin(angleY);
|
||||
|
||||
return mat<4, 4, T, defaultp>(
|
||||
cosY, T(0), -sinY, T(0),
|
||||
T(0), T(1), T(0), T(0),
|
||||
sinY, T(0), cosY, T(0),
|
||||
T(0), T(0), T(0), T(1));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZ
|
||||
(
|
||||
T const& angleZ
|
||||
)
|
||||
{
|
||||
T cosZ = glm::cos(angleZ);
|
||||
T sinZ = glm::sin(angleZ);
|
||||
|
||||
return mat<4, 4, T, defaultp>(
|
||||
cosZ, sinZ, T(0), T(0),
|
||||
-sinZ, cosZ, T(0), T(0),
|
||||
T(0), T(0), T(1), T(0),
|
||||
T(0), T(0), T(0), T(1));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> derivedEulerAngleX
|
||||
(
|
||||
T const & angleX,
|
||||
T const & angularVelocityX
|
||||
)
|
||||
{
|
||||
T cosX = glm::cos(angleX) * angularVelocityX;
|
||||
T sinX = glm::sin(angleX) * angularVelocityX;
|
||||
|
||||
return mat<4, 4, T, defaultp>(
|
||||
T(0), T(0), T(0), T(0),
|
||||
T(0),-sinX, cosX, T(0),
|
||||
T(0),-cosX,-sinX, T(0),
|
||||
T(0), T(0), T(0), T(0));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> derivedEulerAngleY
|
||||
(
|
||||
T const & angleY,
|
||||
T const & angularVelocityY
|
||||
)
|
||||
{
|
||||
T cosY = glm::cos(angleY) * angularVelocityY;
|
||||
T sinY = glm::sin(angleY) * angularVelocityY;
|
||||
|
||||
return mat<4, 4, T, defaultp>(
|
||||
-sinY, T(0), -cosY, T(0),
|
||||
T(0), T(0), T(0), T(0),
|
||||
cosY, T(0), -sinY, T(0),
|
||||
T(0), T(0), T(0), T(0));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> derivedEulerAngleZ
|
||||
(
|
||||
T const & angleZ,
|
||||
T const & angularVelocityZ
|
||||
)
|
||||
{
|
||||
T cosZ = glm::cos(angleZ) * angularVelocityZ;
|
||||
T sinZ = glm::sin(angleZ) * angularVelocityZ;
|
||||
|
||||
return mat<4, 4, T, defaultp>(
|
||||
-sinZ, cosZ, T(0), T(0),
|
||||
-cosZ, -sinZ, T(0), T(0),
|
||||
T(0), T(0), T(0), T(0),
|
||||
T(0), T(0), T(0), T(0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXY
|
||||
(
|
||||
T const& angleX,
|
||||
T const& angleY
|
||||
)
|
||||
{
|
||||
T cosX = glm::cos(angleX);
|
||||
T sinX = glm::sin(angleX);
|
||||
T cosY = glm::cos(angleY);
|
||||
T sinY = glm::sin(angleY);
|
||||
|
||||
return mat<4, 4, T, defaultp>(
|
||||
cosY, -sinX * -sinY, cosX * -sinY, T(0),
|
||||
T(0), cosX, sinX, T(0),
|
||||
sinY, -sinX * cosY, cosX * cosY, T(0),
|
||||
T(0), T(0), T(0), T(1));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYX
|
||||
(
|
||||
T const& angleY,
|
||||
T const& angleX
|
||||
)
|
||||
{
|
||||
T cosX = glm::cos(angleX);
|
||||
T sinX = glm::sin(angleX);
|
||||
T cosY = glm::cos(angleY);
|
||||
T sinY = glm::sin(angleY);
|
||||
|
||||
return mat<4, 4, T, defaultp>(
|
||||
cosY, 0, -sinY, T(0),
|
||||
sinY * sinX, cosX, cosY * sinX, T(0),
|
||||
sinY * cosX, -sinX, cosY * cosX, T(0),
|
||||
T(0), T(0), T(0), T(1));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXZ
|
||||
(
|
||||
T const& angleX,
|
||||
T const& angleZ
|
||||
)
|
||||
{
|
||||
return eulerAngleX(angleX) * eulerAngleZ(angleZ);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZX
|
||||
(
|
||||
T const& angleZ,
|
||||
T const& angleX
|
||||
)
|
||||
{
|
||||
return eulerAngleZ(angleZ) * eulerAngleX(angleX);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYZ
|
||||
(
|
||||
T const& angleY,
|
||||
T const& angleZ
|
||||
)
|
||||
{
|
||||
return eulerAngleY(angleY) * eulerAngleZ(angleZ);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZY
|
||||
(
|
||||
T const& angleZ,
|
||||
T const& angleY
|
||||
)
|
||||
{
|
||||
return eulerAngleZ(angleZ) * eulerAngleY(angleY);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXYZ
|
||||
(
|
||||
T const& t1,
|
||||
T const& t2,
|
||||
T const& t3
|
||||
)
|
||||
{
|
||||
T c1 = glm::cos(-t1);
|
||||
T c2 = glm::cos(-t2);
|
||||
T c3 = glm::cos(-t3);
|
||||
T s1 = glm::sin(-t1);
|
||||
T s2 = glm::sin(-t2);
|
||||
T s3 = glm::sin(-t3);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = c2 * c3;
|
||||
Result[0][1] =-c1 * s3 + s1 * s2 * c3;
|
||||
Result[0][2] = s1 * s3 + c1 * s2 * c3;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] = c2 * s3;
|
||||
Result[1][1] = c1 * c3 + s1 * s2 * s3;
|
||||
Result[1][2] =-s1 * c3 + c1 * s2 * s3;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] =-s2;
|
||||
Result[2][1] = s1 * c2;
|
||||
Result[2][2] = c1 * c2;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYXZ
|
||||
(
|
||||
T const& yaw,
|
||||
T const& pitch,
|
||||
T const& roll
|
||||
)
|
||||
{
|
||||
T tmp_ch = glm::cos(yaw);
|
||||
T tmp_sh = glm::sin(yaw);
|
||||
T tmp_cp = glm::cos(pitch);
|
||||
T tmp_sp = glm::sin(pitch);
|
||||
T tmp_cb = glm::cos(roll);
|
||||
T tmp_sb = glm::sin(roll);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
|
||||
Result[0][1] = tmp_sb * tmp_cp;
|
||||
Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
|
||||
Result[1][1] = tmp_cb * tmp_cp;
|
||||
Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = tmp_sh * tmp_cp;
|
||||
Result[2][1] = -tmp_sp;
|
||||
Result[2][2] = tmp_ch * tmp_cp;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXZX
|
||||
(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3
|
||||
)
|
||||
{
|
||||
T c1 = glm::cos(t1);
|
||||
T s1 = glm::sin(t1);
|
||||
T c2 = glm::cos(t2);
|
||||
T s2 = glm::sin(t2);
|
||||
T c3 = glm::cos(t3);
|
||||
T s3 = glm::sin(t3);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = c2;
|
||||
Result[0][1] = c1 * s2;
|
||||
Result[0][2] = s1 * s2;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] =-c3 * s2;
|
||||
Result[1][1] = c1 * c2 * c3 - s1 * s3;
|
||||
Result[1][2] = c1 * s3 + c2 * c3 * s1;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = s2 * s3;
|
||||
Result[2][1] =-c3 * s1 - c1 * c2 * s3;
|
||||
Result[2][2] = c1 * c3 - c2 * s1 * s3;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXYX
|
||||
(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3
|
||||
)
|
||||
{
|
||||
T c1 = glm::cos(t1);
|
||||
T s1 = glm::sin(t1);
|
||||
T c2 = glm::cos(t2);
|
||||
T s2 = glm::sin(t2);
|
||||
T c3 = glm::cos(t3);
|
||||
T s3 = glm::sin(t3);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = c2;
|
||||
Result[0][1] = s1 * s2;
|
||||
Result[0][2] =-c1 * s2;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] = s2 * s3;
|
||||
Result[1][1] = c1 * c3 - c2 * s1 * s3;
|
||||
Result[1][2] = c3 * s1 + c1 * c2 * s3;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = c3 * s2;
|
||||
Result[2][1] =-c1 * s3 - c2 * c3 * s1;
|
||||
Result[2][2] = c1 * c2 * c3 - s1 * s3;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYXY
|
||||
(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3
|
||||
)
|
||||
{
|
||||
T c1 = glm::cos(t1);
|
||||
T s1 = glm::sin(t1);
|
||||
T c2 = glm::cos(t2);
|
||||
T s2 = glm::sin(t2);
|
||||
T c3 = glm::cos(t3);
|
||||
T s3 = glm::sin(t3);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = c1 * c3 - c2 * s1 * s3;
|
||||
Result[0][1] = s2* s3;
|
||||
Result[0][2] =-c3 * s1 - c1 * c2 * s3;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] = s1 * s2;
|
||||
Result[1][1] = c2;
|
||||
Result[1][2] = c1 * s2;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = c1 * s3 + c2 * c3 * s1;
|
||||
Result[2][1] =-c3 * s2;
|
||||
Result[2][2] = c1 * c2 * c3 - s1 * s3;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYZY
|
||||
(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3
|
||||
)
|
||||
{
|
||||
T c1 = glm::cos(t1);
|
||||
T s1 = glm::sin(t1);
|
||||
T c2 = glm::cos(t2);
|
||||
T s2 = glm::sin(t2);
|
||||
T c3 = glm::cos(t3);
|
||||
T s3 = glm::sin(t3);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = c1 * c2 * c3 - s1 * s3;
|
||||
Result[0][1] = c3 * s2;
|
||||
Result[0][2] =-c1 * s3 - c2 * c3 * s1;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] =-c1 * s2;
|
||||
Result[1][1] = c2;
|
||||
Result[1][2] = s1 * s2;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = c3 * s1 + c1 * c2 * s3;
|
||||
Result[2][1] = s2 * s3;
|
||||
Result[2][2] = c1 * c3 - c2 * s1 * s3;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZYZ
|
||||
(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3
|
||||
)
|
||||
{
|
||||
T c1 = glm::cos(t1);
|
||||
T s1 = glm::sin(t1);
|
||||
T c2 = glm::cos(t2);
|
||||
T s2 = glm::sin(t2);
|
||||
T c3 = glm::cos(t3);
|
||||
T s3 = glm::sin(t3);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = c1 * c2 * c3 - s1 * s3;
|
||||
Result[0][1] = c1 * s3 + c2 * c3 * s1;
|
||||
Result[0][2] =-c3 * s2;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] =-c3 * s1 - c1 * c2 * s3;
|
||||
Result[1][1] = c1 * c3 - c2 * s1 * s3;
|
||||
Result[1][2] = s2 * s3;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = c1 * s2;
|
||||
Result[2][1] = s1 * s2;
|
||||
Result[2][2] = c2;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZXZ
|
||||
(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3
|
||||
)
|
||||
{
|
||||
T c1 = glm::cos(t1);
|
||||
T s1 = glm::sin(t1);
|
||||
T c2 = glm::cos(t2);
|
||||
T s2 = glm::sin(t2);
|
||||
T c3 = glm::cos(t3);
|
||||
T s3 = glm::sin(t3);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = c1 * c3 - c2 * s1 * s3;
|
||||
Result[0][1] = c3 * s1 + c1 * c2 * s3;
|
||||
Result[0][2] = s2 *s3;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] =-c1 * s3 - c2 * c3 * s1;
|
||||
Result[1][1] = c1 * c2 * c3 - s1 * s3;
|
||||
Result[1][2] = c3 * s2;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = s1 * s2;
|
||||
Result[2][1] =-c1 * s2;
|
||||
Result[2][2] = c2;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXZY
|
||||
(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3
|
||||
)
|
||||
{
|
||||
T c1 = glm::cos(t1);
|
||||
T s1 = glm::sin(t1);
|
||||
T c2 = glm::cos(t2);
|
||||
T s2 = glm::sin(t2);
|
||||
T c3 = glm::cos(t3);
|
||||
T s3 = glm::sin(t3);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = c2 * c3;
|
||||
Result[0][1] = s1 * s3 + c1 * c3 * s2;
|
||||
Result[0][2] = c3 * s1 * s2 - c1 * s3;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] =-s2;
|
||||
Result[1][1] = c1 * c2;
|
||||
Result[1][2] = c2 * s1;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = c2 * s3;
|
||||
Result[2][1] = c1 * s2 * s3 - c3 * s1;
|
||||
Result[2][2] = c1 * c3 + s1 * s2 *s3;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYZX
|
||||
(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3
|
||||
)
|
||||
{
|
||||
T c1 = glm::cos(t1);
|
||||
T s1 = glm::sin(t1);
|
||||
T c2 = glm::cos(t2);
|
||||
T s2 = glm::sin(t2);
|
||||
T c3 = glm::cos(t3);
|
||||
T s3 = glm::sin(t3);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = c1 * c2;
|
||||
Result[0][1] = s2;
|
||||
Result[0][2] =-c2 * s1;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] = s1 * s3 - c1 * c3 * s2;
|
||||
Result[1][1] = c2 * c3;
|
||||
Result[1][2] = c1 * s3 + c3 * s1 * s2;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = c3 * s1 + c1 * s2 * s3;
|
||||
Result[2][1] =-c2 * s3;
|
||||
Result[2][2] = c1 * c3 - s1 * s2 * s3;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZYX
|
||||
(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3
|
||||
)
|
||||
{
|
||||
T c1 = glm::cos(t1);
|
||||
T s1 = glm::sin(t1);
|
||||
T c2 = glm::cos(t2);
|
||||
T s2 = glm::sin(t2);
|
||||
T c3 = glm::cos(t3);
|
||||
T s3 = glm::sin(t3);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = c1 * c2;
|
||||
Result[0][1] = c2 * s1;
|
||||
Result[0][2] =-s2;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] = c1 * s2 * s3 - c3 * s1;
|
||||
Result[1][1] = c1 * c3 + s1 * s2 * s3;
|
||||
Result[1][2] = c2 * s3;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = s1 * s3 + c1 * c3 * s2;
|
||||
Result[2][1] = c3 * s1 * s2 - c1 * s3;
|
||||
Result[2][2] = c2 * c3;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZXY
|
||||
(
|
||||
T const & t1,
|
||||
T const & t2,
|
||||
T const & t3
|
||||
)
|
||||
{
|
||||
T c1 = glm::cos(t1);
|
||||
T s1 = glm::sin(t1);
|
||||
T c2 = glm::cos(t2);
|
||||
T s2 = glm::sin(t2);
|
||||
T c3 = glm::cos(t3);
|
||||
T s3 = glm::sin(t3);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = c1 * c3 - s1 * s2 * s3;
|
||||
Result[0][1] = c3 * s1 + c1 * s2 * s3;
|
||||
Result[0][2] =-c2 * s3;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] =-c2 * s1;
|
||||
Result[1][1] = c1 * c2;
|
||||
Result[1][2] = s2;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = c1 * s3 + c3 * s1 * s2;
|
||||
Result[2][1] = s1 * s3 - c1 * c3 * s2;
|
||||
Result[2][2] = c2 * c3;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> yawPitchRoll
|
||||
(
|
||||
T const& yaw,
|
||||
T const& pitch,
|
||||
T const& roll
|
||||
)
|
||||
{
|
||||
T tmp_ch = glm::cos(yaw);
|
||||
T tmp_sh = glm::sin(yaw);
|
||||
T tmp_cp = glm::cos(pitch);
|
||||
T tmp_sp = glm::sin(pitch);
|
||||
T tmp_cb = glm::cos(roll);
|
||||
T tmp_sb = glm::sin(roll);
|
||||
|
||||
mat<4, 4, T, defaultp> Result;
|
||||
Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
|
||||
Result[0][1] = tmp_sb * tmp_cp;
|
||||
Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
|
||||
Result[0][3] = static_cast<T>(0);
|
||||
Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
|
||||
Result[1][1] = tmp_cb * tmp_cp;
|
||||
Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
|
||||
Result[1][3] = static_cast<T>(0);
|
||||
Result[2][0] = tmp_sh * tmp_cp;
|
||||
Result[2][1] = -tmp_sp;
|
||||
Result[2][2] = tmp_ch * tmp_cp;
|
||||
Result[2][3] = static_cast<T>(0);
|
||||
Result[3][0] = static_cast<T>(0);
|
||||
Result[3][1] = static_cast<T>(0);
|
||||
Result[3][2] = static_cast<T>(0);
|
||||
Result[3][3] = static_cast<T>(1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<2, 2, T, defaultp> orientate2
|
||||
(
|
||||
T const& angle
|
||||
)
|
||||
{
|
||||
T c = glm::cos(angle);
|
||||
T s = glm::sin(angle);
|
||||
|
||||
mat<2, 2, T, defaultp> Result;
|
||||
Result[0][0] = c;
|
||||
Result[0][1] = s;
|
||||
Result[1][0] = -s;
|
||||
Result[1][1] = c;
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, defaultp> orientate3
|
||||
(
|
||||
T const& angle
|
||||
)
|
||||
{
|
||||
T c = glm::cos(angle);
|
||||
T s = glm::sin(angle);
|
||||
|
||||
mat<3, 3, T, defaultp> Result;
|
||||
Result[0][0] = c;
|
||||
Result[0][1] = s;
|
||||
Result[0][2] = T(0.0);
|
||||
Result[1][0] = -s;
|
||||
Result[1][1] = c;
|
||||
Result[1][2] = T(0.0);
|
||||
Result[2][0] = T(0.0);
|
||||
Result[2][1] = T(0.0);
|
||||
Result[2][2] = T(1.0);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> orientate3
|
||||
(
|
||||
vec<3, T, Q> const& angles
|
||||
)
|
||||
{
|
||||
return mat<3, 3, T, Q>(yawPitchRoll(angles.z, angles.x, angles.y));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> orientate4
|
||||
(
|
||||
vec<3, T, Q> const& angles
|
||||
)
|
||||
{
|
||||
return yawPitchRoll(angles.z, angles.x, angles.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleXYZ(mat<4, 4, T, defaultp> const& M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(M[2][1], M[2][2]);
|
||||
T C2 = glm::sqrt(M[0][0]*M[0][0] + M[1][0]*M[1][0]);
|
||||
T T2 = glm::atan2(-M[2][0], C2);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(S1*M[0][2] - C1*M[0][1], C1*M[1][1] - S1*M[1][2 ]);
|
||||
t1 = -T1;
|
||||
t2 = -T2;
|
||||
t3 = -T3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleYXZ(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(M[2][0], M[2][2]);
|
||||
T C2 = glm::sqrt(M[0][1]*M[0][1] + M[1][1]*M[1][1]);
|
||||
T T2 = glm::atan2(-M[2][1], C2);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(S1*M[1][2] - C1*M[1][0], C1*M[0][0] - S1*M[0][2]);
|
||||
t1 = T1;
|
||||
t2 = T2;
|
||||
t3 = T3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleXZX(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(M[0][2], M[0][1]);
|
||||
T S2 = glm::sqrt(M[1][0]*M[1][0] + M[2][0]*M[2][0]);
|
||||
T T2 = glm::atan2(S2, M[0][0]);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(C1*M[1][2] - S1*M[1][1], C1*M[2][2] - S1*M[2][1]);
|
||||
t1 = T1;
|
||||
t2 = T2;
|
||||
t3 = T3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleXYX(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(M[0][1], -M[0][2]);
|
||||
T S2 = glm::sqrt(M[1][0]*M[1][0] + M[2][0]*M[2][0]);
|
||||
T T2 = glm::atan2(S2, M[0][0]);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(-C1*M[2][1] - S1*M[2][2], C1*M[1][1] + S1*M[1][2]);
|
||||
t1 = T1;
|
||||
t2 = T2;
|
||||
t3 = T3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleYXY(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(M[1][0], M[1][2]);
|
||||
T S2 = glm::sqrt(M[0][1]*M[0][1] + M[2][1]*M[2][1]);
|
||||
T T2 = glm::atan2(S2, M[1][1]);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(C1*M[2][0] - S1*M[2][2], C1*M[0][0] - S1*M[0][2]);
|
||||
t1 = T1;
|
||||
t2 = T2;
|
||||
t3 = T3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleYZY(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(M[1][2], -M[1][0]);
|
||||
T S2 = glm::sqrt(M[0][1]*M[0][1] + M[2][1]*M[2][1]);
|
||||
T T2 = glm::atan2(S2, M[1][1]);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(-S1*M[0][0] - C1*M[0][2], S1*M[2][0] + C1*M[2][2]);
|
||||
t1 = T1;
|
||||
t2 = T2;
|
||||
t3 = T3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleZYZ(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(M[2][1], M[2][0]);
|
||||
T S2 = glm::sqrt(M[0][2]*M[0][2] + M[1][2]*M[1][2]);
|
||||
T T2 = glm::atan2(S2, M[2][2]);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(C1*M[0][1] - S1*M[0][0], C1*M[1][1] - S1*M[1][0]);
|
||||
t1 = T1;
|
||||
t2 = T2;
|
||||
t3 = T3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleZXZ(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(M[2][0], -M[2][1]);
|
||||
T S2 = glm::sqrt(M[0][2]*M[0][2] + M[1][2]*M[1][2]);
|
||||
T T2 = glm::atan2(S2, M[2][2]);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(-C1*M[1][0] - S1*M[1][1], C1*M[0][0] + S1*M[0][1]);
|
||||
t1 = T1;
|
||||
t2 = T2;
|
||||
t3 = T3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleXZY(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(M[1][2], M[1][1]);
|
||||
T C2 = glm::sqrt(M[0][0]*M[0][0] + M[2][0]*M[2][0]);
|
||||
T T2 = glm::atan2(-M[1][0], C2);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(S1*M[0][1] - C1*M[0][2], C1*M[2][2] - S1*M[2][1]);
|
||||
t1 = T1;
|
||||
t2 = T2;
|
||||
t3 = T3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleYZX(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(-M[0][2], M[0][0]);
|
||||
T C2 = glm::sqrt(M[1][1]*M[1][1] + M[2][1]*M[2][1]);
|
||||
T T2 = glm::atan2(M[0][1], C2);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(S1*M[1][0] + C1*M[1][2], S1*M[2][0] + C1*M[2][2]);
|
||||
t1 = T1;
|
||||
t2 = T2;
|
||||
t3 = T3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleZYX(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(M[0][1], M[0][0]);
|
||||
T C2 = glm::sqrt(M[1][2]*M[1][2] + M[2][2]*M[2][2]);
|
||||
T T2 = glm::atan2(-M[0][2], C2);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(S1*M[2][0] - C1*M[2][1], C1*M[1][1] - S1*M[1][0]);
|
||||
t1 = T1;
|
||||
t2 = T2;
|
||||
t3 = T3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER void extractEulerAngleZXY(mat<4, 4, T, defaultp> const & M,
|
||||
T & t1,
|
||||
T & t2,
|
||||
T & t3)
|
||||
{
|
||||
T T1 = glm::atan2(-M[1][0], M[1][1]);
|
||||
T C2 = glm::sqrt(M[0][2]*M[0][2] + M[2][2]*M[2][2]);
|
||||
T T2 = glm::atan2(M[1][2], C2);
|
||||
T S1 = glm::sin(T1);
|
||||
T C1 = glm::cos(T1);
|
||||
T T3 = glm::atan2(C1*M[2][0] + S1*M[2][1], C1*M[0][0] + S1*M[0][1]);
|
||||
t1 = T1;
|
||||
t2 = T2;
|
||||
t3 = T3;
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,40 @@
|
||||
/// @ref gtx_extend
|
||||
/// @file glm/gtx/extend.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_extend GLM_GTX_extend
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/extend.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Extend a position from a source to a position at a defined length.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_extend is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_extend extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_extend
|
||||
/// @{
|
||||
|
||||
/// Extends of Length the Origin position using the (Source - Origin) direction.
|
||||
/// @see gtx_extend
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType extend(
|
||||
genType const& Origin,
|
||||
genType const& Source,
|
||||
typename genType::value_type const Length);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "extend.inl"
|
||||
@@ -0,0 +1,48 @@
|
||||
/// @ref gtx_extend
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType extend
|
||||
(
|
||||
genType const& Origin,
|
||||
genType const& Source,
|
||||
genType const& Distance
|
||||
)
|
||||
{
|
||||
return Origin + (Source - Origin) * Distance;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<2, T, Q> extend
|
||||
(
|
||||
vec<2, T, Q> const& Origin,
|
||||
vec<2, T, Q> const& Source,
|
||||
T const& Distance
|
||||
)
|
||||
{
|
||||
return Origin + (Source - Origin) * Distance;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> extend
|
||||
(
|
||||
vec<3, T, Q> const& Origin,
|
||||
vec<3, T, Q> const& Source,
|
||||
T const& Distance
|
||||
)
|
||||
{
|
||||
return Origin + (Source - Origin) * Distance;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, T, Q> extend
|
||||
(
|
||||
vec<4, T, Q> const& Origin,
|
||||
vec<4, T, Q> const& Source,
|
||||
T const& Distance
|
||||
)
|
||||
{
|
||||
return Origin + (Source - Origin) * Distance;
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,135 @@
|
||||
/// @ref gtx_extended_min_max
|
||||
/// @file glm/gtx/extended_min_max.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_extended_min_max GLM_GTX_extended_min_max
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/extended_min_max.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Min and max functions for 3 to 4 parameters.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../ext/vector_common.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_extended_min_max is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_extended_min_max extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_extended_min_max
|
||||
/// @{
|
||||
|
||||
/// Return the minimum component-wise values of 3 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T min(
|
||||
T const& x,
|
||||
T const& y,
|
||||
T const& z);
|
||||
|
||||
/// Return the minimum component-wise values of 3 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_DECL C<T> min(
|
||||
C<T> const& x,
|
||||
typename C<T>::T const& y,
|
||||
typename C<T>::T const& z);
|
||||
|
||||
/// Return the minimum component-wise values of 3 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_DECL C<T> min(
|
||||
C<T> const& x,
|
||||
C<T> const& y,
|
||||
C<T> const& z);
|
||||
|
||||
/// Return the minimum component-wise values of 4 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T min(
|
||||
T const& x,
|
||||
T const& y,
|
||||
T const& z,
|
||||
T const& w);
|
||||
|
||||
/// Return the minimum component-wise values of 4 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_DECL C<T> min(
|
||||
C<T> const& x,
|
||||
typename C<T>::T const& y,
|
||||
typename C<T>::T const& z,
|
||||
typename C<T>::T const& w);
|
||||
|
||||
/// Return the minimum component-wise values of 4 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_DECL C<T> min(
|
||||
C<T> const& x,
|
||||
C<T> const& y,
|
||||
C<T> const& z,
|
||||
C<T> const& w);
|
||||
|
||||
/// Return the maximum component-wise values of 3 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T max(
|
||||
T const& x,
|
||||
T const& y,
|
||||
T const& z);
|
||||
|
||||
/// Return the maximum component-wise values of 3 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_DECL C<T> max(
|
||||
C<T> const& x,
|
||||
typename C<T>::T const& y,
|
||||
typename C<T>::T const& z);
|
||||
|
||||
/// Return the maximum component-wise values of 3 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_DECL C<T> max(
|
||||
C<T> const& x,
|
||||
C<T> const& y,
|
||||
C<T> const& z);
|
||||
|
||||
/// Return the maximum component-wise values of 4 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T max(
|
||||
T const& x,
|
||||
T const& y,
|
||||
T const& z,
|
||||
T const& w);
|
||||
|
||||
/// Return the maximum component-wise values of 4 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_DECL C<T> max(
|
||||
C<T> const& x,
|
||||
typename C<T>::T const& y,
|
||||
typename C<T>::T const& z,
|
||||
typename C<T>::T const& w);
|
||||
|
||||
/// Return the maximum component-wise values of 4 inputs
|
||||
/// @see gtx_extented_min_max
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_DECL C<T> max(
|
||||
C<T> const& x,
|
||||
C<T> const& y,
|
||||
C<T> const& z,
|
||||
C<T> const& w);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "extended_min_max.inl"
|
||||
@@ -0,0 +1,138 @@
|
||||
/// @ref gtx_extended_min_max
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T min(
|
||||
T const& x,
|
||||
T const& y,
|
||||
T const& z)
|
||||
{
|
||||
return glm::min(glm::min(x, y), z);
|
||||
}
|
||||
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_QUALIFIER C<T> min
|
||||
(
|
||||
C<T> const& x,
|
||||
typename C<T>::T const& y,
|
||||
typename C<T>::T const& z
|
||||
)
|
||||
{
|
||||
return glm::min(glm::min(x, y), z);
|
||||
}
|
||||
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_QUALIFIER C<T> min
|
||||
(
|
||||
C<T> const& x,
|
||||
C<T> const& y,
|
||||
C<T> const& z
|
||||
)
|
||||
{
|
||||
return glm::min(glm::min(x, y), z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T min
|
||||
(
|
||||
T const& x,
|
||||
T const& y,
|
||||
T const& z,
|
||||
T const& w
|
||||
)
|
||||
{
|
||||
return glm::min(glm::min(x, y), glm::min(z, w));
|
||||
}
|
||||
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_QUALIFIER C<T> min
|
||||
(
|
||||
C<T> const& x,
|
||||
typename C<T>::T const& y,
|
||||
typename C<T>::T const& z,
|
||||
typename C<T>::T const& w
|
||||
)
|
||||
{
|
||||
return glm::min(glm::min(x, y), glm::min(z, w));
|
||||
}
|
||||
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_QUALIFIER C<T> min
|
||||
(
|
||||
C<T> const& x,
|
||||
C<T> const& y,
|
||||
C<T> const& z,
|
||||
C<T> const& w
|
||||
)
|
||||
{
|
||||
return glm::min(glm::min(x, y), glm::min(z, w));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T max(
|
||||
T const& x,
|
||||
T const& y,
|
||||
T const& z)
|
||||
{
|
||||
return glm::max(glm::max(x, y), z);
|
||||
}
|
||||
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_QUALIFIER C<T> max
|
||||
(
|
||||
C<T> const& x,
|
||||
typename C<T>::T const& y,
|
||||
typename C<T>::T const& z
|
||||
)
|
||||
{
|
||||
return glm::max(glm::max(x, y), z);
|
||||
}
|
||||
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_QUALIFIER C<T> max
|
||||
(
|
||||
C<T> const& x,
|
||||
C<T> const& y,
|
||||
C<T> const& z
|
||||
)
|
||||
{
|
||||
return glm::max(glm::max(x, y), z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T max
|
||||
(
|
||||
T const& x,
|
||||
T const& y,
|
||||
T const& z,
|
||||
T const& w
|
||||
)
|
||||
{
|
||||
return glm::max(glm::max(x, y), glm::max(z, w));
|
||||
}
|
||||
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_QUALIFIER C<T> max
|
||||
(
|
||||
C<T> const& x,
|
||||
typename C<T>::T const& y,
|
||||
typename C<T>::T const& z,
|
||||
typename C<T>::T const& w
|
||||
)
|
||||
{
|
||||
return glm::max(glm::max(x, y), glm::max(z, w));
|
||||
}
|
||||
|
||||
template<typename T, template<typename> class C>
|
||||
GLM_FUNC_QUALIFIER C<T> max
|
||||
(
|
||||
C<T> const& x,
|
||||
C<T> const& y,
|
||||
C<T> const& z,
|
||||
C<T> const& w
|
||||
)
|
||||
{
|
||||
return glm::max(glm::max(x, y), glm::max(z, w));
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,43 @@
|
||||
/// @ref gtx_exterior_product
|
||||
/// @file glm/gtx/exterior_product.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_exterior_product (dependence)
|
||||
///
|
||||
/// @defgroup gtx_exterior_product GLM_GTX_exterior_product
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/exterior_product.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"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_exterior_product is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_exterior_product extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_exterior_product
|
||||
/// @{
|
||||
|
||||
/// Returns the cross product of x and y.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see <a href="https://en.wikipedia.org/wiki/Exterior_algebra#Cross_and_triple_products">Exterior product</a>
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR T cross(vec<2, T, Q> const& v, vec<2, T, Q> const& u);
|
||||
|
||||
/// @}
|
||||
} //namespace glm
|
||||
|
||||
#include "exterior_product.inl"
|
||||
@@ -0,0 +1,26 @@
|
||||
/// @ref gtx_exterior_product
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace glm {
|
||||
namespace detail
|
||||
{
|
||||
template<typename T, qualifier Q, bool Aligned>
|
||||
struct compute_cross_vec2
|
||||
{
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(vec<2, T, Q> const& v, vec<2, T, Q> const& u)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'cross' accepts only floating-point inputs");
|
||||
|
||||
return v.x * u.y - u.x * v.y;
|
||||
}
|
||||
};
|
||||
}//namespace detail
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T cross(vec<2, T, Q> const& x, vec<2, T, Q> const& y)
|
||||
{
|
||||
return detail::compute_cross_vec2<T, Q, detail::is_aligned<Q>::value>::call(x, y);
|
||||
}
|
||||
}//namespace glm
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/// @ref gtx_fast_exponential
|
||||
/// @file glm/gtx/fast_exponential.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_half_float (dependence)
|
||||
///
|
||||
/// @defgroup gtx_fast_exponential GLM_GTX_fast_exponential
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/fast_exponential.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Fast but less accurate implementations of exponential based functions.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_fast_exponential is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_fast_exponential extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_fast_exponential
|
||||
/// @{
|
||||
|
||||
/// Faster than the common pow function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType fastPow(genType x, genType y);
|
||||
|
||||
/// Faster than the common pow function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fastPow(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
|
||||
|
||||
/// Faster than the common pow function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<typename genTypeT, typename genTypeU>
|
||||
GLM_FUNC_DECL genTypeT fastPow(genTypeT x, genTypeU y);
|
||||
|
||||
/// Faster than the common pow function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fastPow(vec<L, T, Q> const& x);
|
||||
|
||||
/// Faster than the common exp function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fastExp(T x);
|
||||
|
||||
/// Faster than the common exp function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fastExp(vec<L, T, Q> const& x);
|
||||
|
||||
/// Faster than the common log function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fastLog(T x);
|
||||
|
||||
/// Faster than the common exp2 function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fastLog(vec<L, T, Q> const& x);
|
||||
|
||||
/// Faster than the common exp2 function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fastExp2(T x);
|
||||
|
||||
/// Faster than the common exp2 function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fastExp2(vec<L, T, Q> const& x);
|
||||
|
||||
/// Faster than the common log2 function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fastLog2(T x);
|
||||
|
||||
/// Faster than the common log2 function but less accurate.
|
||||
/// @see gtx_fast_exponential
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fastLog2(vec<L, T, Q> const& x);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "fast_exponential.inl"
|
||||
@@ -0,0 +1,136 @@
|
||||
/// @ref gtx_fast_exponential
|
||||
|
||||
namespace glm
|
||||
{
|
||||
// fastPow:
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType fastPow(genType x, genType y)
|
||||
{
|
||||
return exp(y * log(x));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastPow(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
|
||||
{
|
||||
return exp(y * log(x));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fastPow(T x, int y)
|
||||
{
|
||||
T f = static_cast<T>(1);
|
||||
for(int i = 0; i < y; ++i)
|
||||
f *= x;
|
||||
return f;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastPow(vec<L, T, Q> const& x, vec<L, int, Q> const& y)
|
||||
{
|
||||
vec<L, T, Q> Result;
|
||||
for(length_t i = 0, n = x.length(); i < n; ++i)
|
||||
Result[i] = fastPow(x[i], y[i]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
// fastExp
|
||||
// Note: This function provides accurate results only for value between -1 and 1, else avoid it.
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fastExp(T x)
|
||||
{
|
||||
// This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower.
|
||||
// return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f))));
|
||||
T x2 = x * x;
|
||||
T x3 = x2 * x;
|
||||
T x4 = x3 * x;
|
||||
T x5 = x4 * x;
|
||||
return T(1) + x + (x2 * T(0.5)) + (x3 * T(0.1666666667)) + (x4 * T(0.041666667)) + (x5 * T(0.008333333333));
|
||||
}
|
||||
/* // Try to handle all values of float... but often shower than std::exp, glm::floor and the loop kill the performance
|
||||
GLM_FUNC_QUALIFIER float fastExp(float x)
|
||||
{
|
||||
const float e = 2.718281828f;
|
||||
const float IntegerPart = floor(x);
|
||||
const float FloatPart = x - IntegerPart;
|
||||
float z = 1.f;
|
||||
|
||||
for(int i = 0; i < int(IntegerPart); ++i)
|
||||
z *= e;
|
||||
|
||||
const float x2 = FloatPart * FloatPart;
|
||||
const float x3 = x2 * FloatPart;
|
||||
const float x4 = x3 * FloatPart;
|
||||
const float x5 = x4 * FloatPart;
|
||||
return z * (1.0f + FloatPart + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f));
|
||||
}
|
||||
|
||||
// Increase accuracy on number bigger that 1 and smaller than -1 but it's not enough for high and negative numbers
|
||||
GLM_FUNC_QUALIFIER float fastExp(float x)
|
||||
{
|
||||
// This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower.
|
||||
// return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f))));
|
||||
float x2 = x * x;
|
||||
float x3 = x2 * x;
|
||||
float x4 = x3 * x;
|
||||
float x5 = x4 * x;
|
||||
float x6 = x5 * x;
|
||||
float x7 = x6 * x;
|
||||
float x8 = x7 * x;
|
||||
return 1.0f + x + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f)+ (x6 * 0.00138888888888f) + (x7 * 0.000198412698f) + (x8 * 0.0000248015873f);;
|
||||
}
|
||||
*/
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastExp(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(fastExp, x);
|
||||
}
|
||||
|
||||
// fastLog
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType fastLog(genType x)
|
||||
{
|
||||
return std::log(x);
|
||||
}
|
||||
|
||||
/* Slower than the VC7.1 function...
|
||||
GLM_FUNC_QUALIFIER float fastLog(float x)
|
||||
{
|
||||
float y1 = (x - 1.0f) / (x + 1.0f);
|
||||
float y2 = y1 * y1;
|
||||
return 2.0f * y1 * (1.0f + y2 * (0.3333333333f + y2 * (0.2f + y2 * 0.1428571429f)));
|
||||
}
|
||||
*/
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastLog(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(fastLog, x);
|
||||
}
|
||||
|
||||
//fastExp2, ln2 = 0.69314718055994530941723212145818f
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType fastExp2(genType x)
|
||||
{
|
||||
return fastExp(static_cast<genType>(0.69314718055994530941723212145818) * x);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastExp2(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(fastExp2, x);
|
||||
}
|
||||
|
||||
// fastLog2, ln2 = 0.69314718055994530941723212145818f
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType fastLog2(genType x)
|
||||
{
|
||||
return fastLog(x) / static_cast<genType>(0.69314718055994530941723212145818);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastLog2(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(fastLog2, x);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,96 @@
|
||||
/// @ref gtx_fast_square_root
|
||||
/// @file glm/gtx/fast_square_root.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_fast_square_root GLM_GTX_fast_square_root
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/fast_square_root.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Fast but less accurate implementations of square root based functions.
|
||||
/// - Sqrt optimisation based on Newton's method,
|
||||
/// www.gamedev.net/community/forums/topic.asp?topic id=139956
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../common.hpp"
|
||||
#include "../exponential.hpp"
|
||||
#include "../geometric.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_fast_square_root is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_fast_square_root extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_fast_square_root
|
||||
/// @{
|
||||
|
||||
/// Faster than the common sqrt function but less accurate.
|
||||
///
|
||||
/// @see gtx_fast_square_root extension.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType fastSqrt(genType x);
|
||||
|
||||
/// Faster than the common sqrt function but less accurate.
|
||||
///
|
||||
/// @see gtx_fast_square_root extension.
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fastSqrt(vec<L, T, Q> const& x);
|
||||
|
||||
/// Faster than the common inversesqrt function but less accurate.
|
||||
///
|
||||
/// @see gtx_fast_square_root extension.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType fastInverseSqrt(genType x);
|
||||
|
||||
/// Faster than the common inversesqrt function but less accurate.
|
||||
///
|
||||
/// @see gtx_fast_square_root extension.
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fastInverseSqrt(vec<L, T, Q> const& x);
|
||||
|
||||
/// Faster than the common length function but less accurate.
|
||||
///
|
||||
/// @see gtx_fast_square_root extension.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType fastLength(genType x);
|
||||
|
||||
/// Faster than the common length function but less accurate.
|
||||
///
|
||||
/// @see gtx_fast_square_root extension.
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T fastLength(vec<L, T, Q> const& x);
|
||||
|
||||
/// Faster than the common distance function but less accurate.
|
||||
///
|
||||
/// @see gtx_fast_square_root extension.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType fastDistance(genType x, genType y);
|
||||
|
||||
/// Faster than the common distance function but less accurate.
|
||||
///
|
||||
/// @see gtx_fast_square_root extension.
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T fastDistance(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
|
||||
|
||||
/// Faster than the common normalize function but less accurate.
|
||||
///
|
||||
/// @see gtx_fast_square_root extension.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType fastNormalize(genType x);
|
||||
|
||||
/// Faster than the common normalize function but less accurate.
|
||||
///
|
||||
/// @see gtx_fast_square_root extension.
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fastNormalize(vec<L, T, Q> const& x);
|
||||
|
||||
/// @}
|
||||
}// namespace glm
|
||||
|
||||
#include "fast_square_root.inl"
|
||||
@@ -0,0 +1,75 @@
|
||||
/// @ref gtx_fast_square_root
|
||||
|
||||
namespace glm
|
||||
{
|
||||
// fastSqrt
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType fastSqrt(genType x)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'fastSqrt' only accept floating-point input");
|
||||
|
||||
return genType(1) / fastInverseSqrt(x);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastSqrt(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(fastSqrt, x);
|
||||
}
|
||||
|
||||
// fastInversesqrt
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType fastInverseSqrt(genType x)
|
||||
{
|
||||
return detail::compute_inversesqrt<1, genType, lowp, detail::is_aligned<lowp>::value>::call(vec<1, genType, lowp>(x)).x;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastInverseSqrt(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::compute_inversesqrt<L, T, Q, detail::is_aligned<Q>::value>::call(x);
|
||||
}
|
||||
|
||||
// fastLength
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType fastLength(genType x)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'fastLength' only accept floating-point inputs");
|
||||
|
||||
return abs(x);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T fastLength(vec<L, T, Q> const& x)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'fastLength' only accept floating-point inputs");
|
||||
|
||||
return fastSqrt(dot(x, x));
|
||||
}
|
||||
|
||||
// fastDistance
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType fastDistance(genType x, genType y)
|
||||
{
|
||||
return fastLength(y - x);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T fastDistance(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
|
||||
{
|
||||
return fastLength(y - x);
|
||||
}
|
||||
|
||||
// fastNormalize
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType fastNormalize(genType x)
|
||||
{
|
||||
return x > genType(0) ? genType(1) : -genType(1);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastNormalize(vec<L, T, Q> const& x)
|
||||
{
|
||||
return x * fastInverseSqrt(dot(x, x));
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,77 @@
|
||||
/// @ref gtx_fast_trigonometry
|
||||
/// @file glm/gtx/fast_trigonometry.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_fast_trigonometry GLM_GTX_fast_trigonometry
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/fast_trigonometry.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Fast but less accurate implementations of trigonometric functions.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../gtc/constants.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_fast_trigonometry is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_fast_trigonometry extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_fast_trigonometry
|
||||
/// @{
|
||||
|
||||
/// Wrap an angle to [0 2pi[
|
||||
/// From GLM_GTX_fast_trigonometry extension.
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T wrapAngle(T angle);
|
||||
|
||||
/// Faster than the common sin function but less accurate.
|
||||
/// From GLM_GTX_fast_trigonometry extension.
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fastSin(T angle);
|
||||
|
||||
/// Faster than the common cos function but less accurate.
|
||||
/// From GLM_GTX_fast_trigonometry extension.
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fastCos(T angle);
|
||||
|
||||
/// Faster than the common tan function but less accurate.
|
||||
/// Defined between -2pi and 2pi.
|
||||
/// From GLM_GTX_fast_trigonometry extension.
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fastTan(T angle);
|
||||
|
||||
/// Faster than the common asin function but less accurate.
|
||||
/// Defined between -2pi and 2pi.
|
||||
/// From GLM_GTX_fast_trigonometry extension.
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fastAsin(T angle);
|
||||
|
||||
/// Faster than the common acos function but less accurate.
|
||||
/// Defined between -2pi and 2pi.
|
||||
/// From GLM_GTX_fast_trigonometry extension.
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fastAcos(T angle);
|
||||
|
||||
/// Faster than the common atan function but less accurate.
|
||||
/// Defined between -2pi and 2pi.
|
||||
/// From GLM_GTX_fast_trigonometry extension.
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fastAtan(T y, T x);
|
||||
|
||||
/// Faster than the common atan function but less accurate.
|
||||
/// Defined between -2pi and 2pi.
|
||||
/// From GLM_GTX_fast_trigonometry extension.
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fastAtan(T angle);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "fast_trigonometry.inl"
|
||||
@@ -0,0 +1,142 @@
|
||||
/// @ref gtx_fast_trigonometry
|
||||
|
||||
namespace glm{
|
||||
namespace detail
|
||||
{
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> taylorCos(vec<L, T, Q> const& x)
|
||||
{
|
||||
return static_cast<T>(1)
|
||||
- (x * x) * (1.f / 2.f)
|
||||
+ ((x * x) * (x * x)) * (1.f / 24.f)
|
||||
- (((x * x) * (x * x)) * (x * x)) * (1.f / 720.f)
|
||||
+ (((x * x) * (x * x)) * ((x * x) * (x * x))) * (1.f / 40320.f);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T cos_52s(T x)
|
||||
{
|
||||
T const xx(x * x);
|
||||
return (T(0.9999932946) + xx * (T(-0.4999124376) + xx * (T(0.0414877472) + xx * T(-0.0012712095))));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> cos_52s(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(cos_52s, x);
|
||||
}
|
||||
}//namespace detail
|
||||
|
||||
// wrapAngle
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T wrapAngle(T angle)
|
||||
{
|
||||
return abs<T>(mod<T>(angle, two_pi<T>()));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> wrapAngle(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(wrapAngle, x);
|
||||
}
|
||||
|
||||
// cos
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fastCos(T x)
|
||||
{
|
||||
T const angle(wrapAngle<T>(x));
|
||||
|
||||
if(angle < half_pi<T>())
|
||||
return detail::cos_52s(angle);
|
||||
if(angle < pi<T>())
|
||||
return -detail::cos_52s(pi<T>() - angle);
|
||||
if(angle < (T(3) * half_pi<T>()))
|
||||
return -detail::cos_52s(angle - pi<T>());
|
||||
|
||||
return detail::cos_52s(two_pi<T>() - angle);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastCos(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(fastCos, x);
|
||||
}
|
||||
|
||||
// sin
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fastSin(T x)
|
||||
{
|
||||
return fastCos<T>(half_pi<T>() - x);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastSin(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(fastSin, x);
|
||||
}
|
||||
|
||||
// tan
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fastTan(T x)
|
||||
{
|
||||
return x + (x * x * x * T(0.3333333333)) + (x * x * x * x * x * T(0.1333333333333)) + (x * x * x * x * x * x * x * T(0.0539682539));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastTan(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(fastTan, x);
|
||||
}
|
||||
|
||||
// asin
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fastAsin(T x)
|
||||
{
|
||||
return x + (x * x * x * T(0.166666667)) + (x * x * x * x * x * T(0.075)) + (x * x * x * x * x * x * x * T(0.0446428571)) + (x * x * x * x * x * x * x * x * x * T(0.0303819444));// + (x * x * x * x * x * x * x * x * x * x * x * T(0.022372159));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastAsin(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(fastAsin, x);
|
||||
}
|
||||
|
||||
// acos
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fastAcos(T x)
|
||||
{
|
||||
return T(1.5707963267948966192313216916398) - fastAsin(x); //(PI / 2)
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastAcos(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(fastAcos, x);
|
||||
}
|
||||
|
||||
// atan
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fastAtan(T y, T x)
|
||||
{
|
||||
T sgn = sign(y) * sign(x);
|
||||
return abs(fastAtan(y / x)) * sgn;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastAtan(vec<L, T, Q> const& y, vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor2<vec, L, T, Q>::call(fastAtan, y, x);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fastAtan(T x)
|
||||
{
|
||||
return x - (x * x * x * T(0.333333333333)) + (x * x * x * x * x * T(0.2)) - (x * x * x * x * x * x * x * T(0.1428571429)) + (x * x * x * x * x * x * x * x * x * T(0.111111111111)) - (x * x * x * x * x * x * x * x * x * x * x * T(0.0909090909));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fastAtan(vec<L, T, Q> const& x)
|
||||
{
|
||||
return detail::functor1<vec, L, T, T, Q>::call(fastAtan, x);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,13 @@
|
||||
/// @ref gtx_float_normalize
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, float, Q> floatNormalize(vec<L, T, Q> const& v)
|
||||
{
|
||||
return vec<L, float, Q>(v) / static_cast<float>(std::numeric_limits<T>::max());
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,54 @@
|
||||
/// @ref gtx_functions
|
||||
/// @file glm/gtx/functions.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtc_quaternion (dependence)
|
||||
///
|
||||
/// @defgroup gtx_functions GLM_GTX_functions
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/functions.hpp> to use the features of this extension.
|
||||
///
|
||||
/// List of useful common functions.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependencies
|
||||
#include "../detail/setup.hpp"
|
||||
#include "../detail/qualifier.hpp"
|
||||
#include "../detail/type_vec2.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_functions is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_functions extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_functions
|
||||
/// @{
|
||||
|
||||
/// 1D gauss function
|
||||
///
|
||||
/// @see gtc_epsilon
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T gauss(
|
||||
T x,
|
||||
T ExpectedValue,
|
||||
T StandardDeviation);
|
||||
|
||||
/// 2D gauss function
|
||||
///
|
||||
/// @see gtc_epsilon
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T gauss(
|
||||
vec<2, T, Q> const& Coord,
|
||||
vec<2, T, Q> const& ExpectedValue,
|
||||
vec<2, T, Q> const& StandardDeviation);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "functions.inl"
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/// @ref gtx_functions
|
||||
|
||||
#include "../exponential.hpp"
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T gauss
|
||||
(
|
||||
T x,
|
||||
T ExpectedValue,
|
||||
T StandardDeviation
|
||||
)
|
||||
{
|
||||
return exp(-((x - ExpectedValue) * (x - ExpectedValue)) / (static_cast<T>(2) * StandardDeviation * StandardDeviation)) / (StandardDeviation * sqrt(static_cast<T>(6.28318530717958647692528676655900576)));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T gauss
|
||||
(
|
||||
vec<2, T, Q> const& Coord,
|
||||
vec<2, T, Q> const& ExpectedValue,
|
||||
vec<2, T, Q> const& StandardDeviation
|
||||
)
|
||||
{
|
||||
vec<2, T, Q> const Squared = ((Coord - ExpectedValue) * (Coord - ExpectedValue)) / (static_cast<T>(2) * StandardDeviation * StandardDeviation);
|
||||
return exp(-(Squared.x + Squared.y));
|
||||
}
|
||||
}//namespace glm
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/// @ref gtx_gradient_paint
|
||||
/// @file glm/gtx/gradient_paint.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_optimum_pow (dependence)
|
||||
///
|
||||
/// @defgroup gtx_gradient_paint GLM_GTX_gradient_paint
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/gradient_paint.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Functions that return the color of procedural gradient for specific coordinates.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../gtx/optimum_pow.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_gradient_paint is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_gradient_paint extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_gradient_paint
|
||||
/// @{
|
||||
|
||||
/// Return a color from a radial gradient.
|
||||
/// @see - gtx_gradient_paint
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T radialGradient(
|
||||
vec<2, T, Q> const& Center,
|
||||
T const& Radius,
|
||||
vec<2, T, Q> const& Focal,
|
||||
vec<2, T, Q> const& Position);
|
||||
|
||||
/// Return a color from a linear gradient.
|
||||
/// @see - gtx_gradient_paint
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T linearGradient(
|
||||
vec<2, T, Q> const& Point0,
|
||||
vec<2, T, Q> const& Point1,
|
||||
vec<2, T, Q> const& Position);
|
||||
|
||||
/// @}
|
||||
}// namespace glm
|
||||
|
||||
#include "gradient_paint.inl"
|
||||
@@ -0,0 +1,36 @@
|
||||
/// @ref gtx_gradient_paint
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T radialGradient
|
||||
(
|
||||
vec<2, T, Q> const& Center,
|
||||
T const& Radius,
|
||||
vec<2, T, Q> const& Focal,
|
||||
vec<2, T, Q> const& Position
|
||||
)
|
||||
{
|
||||
vec<2, T, Q> F = Focal - Center;
|
||||
vec<2, T, Q> D = Position - Focal;
|
||||
T Radius2 = pow2(Radius);
|
||||
T Fx2 = pow2(F.x);
|
||||
T Fy2 = pow2(F.y);
|
||||
|
||||
T Numerator = (D.x * F.x + D.y * F.y) + sqrt(Radius2 * (pow2(D.x) + pow2(D.y)) - pow2(D.x * F.y - D.y * F.x));
|
||||
T Denominator = Radius2 - (Fx2 + Fy2);
|
||||
return Numerator / Denominator;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T linearGradient
|
||||
(
|
||||
vec<2, T, Q> const& Point0,
|
||||
vec<2, T, Q> const& Point1,
|
||||
vec<2, T, Q> const& Position
|
||||
)
|
||||
{
|
||||
vec<2, T, Q> Dist = Point1 - Point0;
|
||||
return (Dist.x * (Position.x - Point0.x) + Dist.y * (Position.y - Point0.y)) / glm::dot(Dist, Dist);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,48 @@
|
||||
/// @ref gtx_handed_coordinate_space
|
||||
/// @file glm/gtx/handed_coordinate_space.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_handed_coordinate_space GLM_GTX_handed_coordinate_space
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/handed_coordinate_space.hpp> to use the features of this extension.
|
||||
///
|
||||
/// To know if a set of three basis vectors defines a right or left-handed coordinate system.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_handed_coordinate_space is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_handed_coordinate_space extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_handed_coordinate_space
|
||||
/// @{
|
||||
|
||||
//! Return if a trihedron right handed or not.
|
||||
//! From GLM_GTX_handed_coordinate_space extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL bool rightHanded(
|
||||
vec<3, T, Q> const& tangent,
|
||||
vec<3, T, Q> const& binormal,
|
||||
vec<3, T, Q> const& normal);
|
||||
|
||||
//! Return if a trihedron left handed or not.
|
||||
//! From GLM_GTX_handed_coordinate_space extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL bool leftHanded(
|
||||
vec<3, T, Q> const& tangent,
|
||||
vec<3, T, Q> const& binormal,
|
||||
vec<3, T, Q> const& normal);
|
||||
|
||||
/// @}
|
||||
}// namespace glm
|
||||
|
||||
#include "handed_coordinate_space.inl"
|
||||
@@ -0,0 +1,26 @@
|
||||
/// @ref gtx_handed_coordinate_space
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool rightHanded
|
||||
(
|
||||
vec<3, T, Q> const& tangent,
|
||||
vec<3, T, Q> const& binormal,
|
||||
vec<3, T, Q> const& normal
|
||||
)
|
||||
{
|
||||
return dot(cross(normal, tangent), binormal) > T(0);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool leftHanded
|
||||
(
|
||||
vec<3, T, Q> const& tangent,
|
||||
vec<3, T, Q> const& binormal,
|
||||
vec<3, T, Q> const& normal
|
||||
)
|
||||
{
|
||||
return dot(cross(normal, tangent), binormal) < T(0);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,156 @@
|
||||
/// @ref gtx_hash
|
||||
/// @file glm/gtx/hash.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_hash GLM_GTX_hash
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/hash.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Add std::hash support for glm types
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(GLM_FORCE_MESSAGES) && !defined(GLM_EXT_INCLUDED)
|
||||
# ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# pragma message("GLM: GLM_GTX_hash is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.")
|
||||
# else
|
||||
# pragma message("GLM: GLM_GTX_hash extension included")
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "../vec2.hpp"
|
||||
#include "../vec3.hpp"
|
||||
#include "../vec4.hpp"
|
||||
#include "../gtc/vec1.hpp"
|
||||
|
||||
#include "../gtc/quaternion.hpp"
|
||||
#include "../gtx/dual_quaternion.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"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// MSVC uses _MSVC_LANG instead of __cplusplus
|
||||
#if _MSVC_LANG < 201103L
|
||||
#pragma message("GLM_GTX_hash requires C++11 standard library support")
|
||||
#endif
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
// GNU and Clang use __cplusplus
|
||||
#if __cplusplus < 201103L
|
||||
#pragma message("GLM_GTX_hash requires C++11 standard library support")
|
||||
#endif
|
||||
#else
|
||||
#error "Unknown compiler"
|
||||
#endif
|
||||
|
||||
#if GLM_LANG & GLM_LANG_CXX11
|
||||
#define GLM_GTX_hash 1
|
||||
#include <functional>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::vec<1, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::vec<1, T, Q> const& v) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::vec<2, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::vec<2, T, Q> const& v) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::vec<3, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::vec<3, T, Q> const& v) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::vec<4, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::vec<4, T, Q> const& v) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::qua<T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::qua<T, Q> const& q) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::tdualquat<T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::tdualquat<T,Q> const& q) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::mat<2, 2, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::mat<2, 2, T,Q> const& m) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::mat<2, 3, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::mat<2, 3, T,Q> const& m) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::mat<2, 4, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::mat<2, 4, T,Q> const& m) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::mat<3, 2, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::mat<3, 2, T,Q> const& m) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::mat<3, 3, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::mat<3, 3, T,Q> const& m) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::mat<3, 4, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::mat<3, 4, T,Q> const& m) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::mat<4, 2, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::mat<4, 2, T,Q> const& m) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::mat<4, 3, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::mat<4, 3, T,Q> const& m) const GLM_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
struct hash<glm::mat<4, 4, T, Q> >
|
||||
{
|
||||
GLM_FUNC_DECL size_t operator()(glm::mat<4, 4, T,Q> const& m) const GLM_NOEXCEPT;
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#include "hash.inl"
|
||||
|
||||
#endif //GLM_LANG & GLM_LANG_CXX11
|
||||
@@ -0,0 +1,175 @@
|
||||
/// @ref gtx_hash
|
||||
|
||||
namespace glm {
|
||||
namespace detail
|
||||
{
|
||||
GLM_INLINE void hash_combine(size_t &seed, size_t hash)
|
||||
{
|
||||
hash += 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
seed ^= hash;
|
||||
}
|
||||
}}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::vec<1, T, Q> >::operator()(glm::vec<1, T, Q> const& v) const GLM_NOEXCEPT
|
||||
{
|
||||
hash<T> hasher;
|
||||
return hasher(v.x);
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::vec<2, T, Q> >::operator()(glm::vec<2, T, Q> const& v) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<T> hasher;
|
||||
glm::detail::hash_combine(seed, hasher(v.x));
|
||||
glm::detail::hash_combine(seed, hasher(v.y));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::vec<3, T, Q> >::operator()(glm::vec<3, T, Q> const& v) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<T> hasher;
|
||||
glm::detail::hash_combine(seed, hasher(v.x));
|
||||
glm::detail::hash_combine(seed, hasher(v.y));
|
||||
glm::detail::hash_combine(seed, hasher(v.z));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::vec<4, T, Q> >::operator()(glm::vec<4, T, Q> const& v) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<T> hasher;
|
||||
glm::detail::hash_combine(seed, hasher(v.x));
|
||||
glm::detail::hash_combine(seed, hasher(v.y));
|
||||
glm::detail::hash_combine(seed, hasher(v.z));
|
||||
glm::detail::hash_combine(seed, hasher(v.w));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::qua<T, Q> >::operator()(glm::qua<T,Q> const& q) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<T> hasher;
|
||||
glm::detail::hash_combine(seed, hasher(q.x));
|
||||
glm::detail::hash_combine(seed, hasher(q.y));
|
||||
glm::detail::hash_combine(seed, hasher(q.z));
|
||||
glm::detail::hash_combine(seed, hasher(q.w));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::tdualquat<T, Q> >::operator()(glm::tdualquat<T, Q> const& q) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<glm::qua<T, Q> > hasher;
|
||||
glm::detail::hash_combine(seed, hasher(q.real));
|
||||
glm::detail::hash_combine(seed, hasher(q.dual));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::mat<2, 2, T, Q> >::operator()(glm::mat<2, 2, T, Q> const& m) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<glm::vec<2, T, Q> > hasher;
|
||||
glm::detail::hash_combine(seed, hasher(m[0]));
|
||||
glm::detail::hash_combine(seed, hasher(m[1]));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::mat<2, 3, T, Q> >::operator()(glm::mat<2, 3, T, Q> const& m) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<glm::vec<3, T, Q> > hasher;
|
||||
glm::detail::hash_combine(seed, hasher(m[0]));
|
||||
glm::detail::hash_combine(seed, hasher(m[1]));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::mat<2, 4, T, Q> >::operator()(glm::mat<2, 4, T, Q> const& m) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<glm::vec<4, T, Q> > hasher;
|
||||
glm::detail::hash_combine(seed, hasher(m[0]));
|
||||
glm::detail::hash_combine(seed, hasher(m[1]));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::mat<3, 2, T, Q> >::operator()(glm::mat<3, 2, T, Q> const& m) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<glm::vec<2, T, Q> > hasher;
|
||||
glm::detail::hash_combine(seed, hasher(m[0]));
|
||||
glm::detail::hash_combine(seed, hasher(m[1]));
|
||||
glm::detail::hash_combine(seed, hasher(m[2]));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::mat<3, 3, T, Q> >::operator()(glm::mat<3, 3, T, Q> const& m) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<glm::vec<3, T, Q> > hasher;
|
||||
glm::detail::hash_combine(seed, hasher(m[0]));
|
||||
glm::detail::hash_combine(seed, hasher(m[1]));
|
||||
glm::detail::hash_combine(seed, hasher(m[2]));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::mat<3, 4, T, Q> >::operator()(glm::mat<3, 4, T, Q> const& m) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<glm::vec<4, T, Q> > hasher;
|
||||
glm::detail::hash_combine(seed, hasher(m[0]));
|
||||
glm::detail::hash_combine(seed, hasher(m[1]));
|
||||
glm::detail::hash_combine(seed, hasher(m[2]));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::mat<4, 2, T,Q> >::operator()(glm::mat<4, 2, T,Q> const& m) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<glm::vec<2, T, Q> > hasher;
|
||||
glm::detail::hash_combine(seed, hasher(m[0]));
|
||||
glm::detail::hash_combine(seed, hasher(m[1]));
|
||||
glm::detail::hash_combine(seed, hasher(m[2]));
|
||||
glm::detail::hash_combine(seed, hasher(m[3]));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::mat<4, 3, T,Q> >::operator()(glm::mat<4, 3, T,Q> const& m) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<glm::vec<3, T, Q> > hasher;
|
||||
glm::detail::hash_combine(seed, hasher(m[0]));
|
||||
glm::detail::hash_combine(seed, hasher(m[1]));
|
||||
glm::detail::hash_combine(seed, hasher(m[2]));
|
||||
glm::detail::hash_combine(seed, hasher(m[3]));
|
||||
return seed;
|
||||
}
|
||||
|
||||
template<typename T, glm::qualifier Q>
|
||||
GLM_FUNC_QUALIFIER size_t hash<glm::mat<4, 4, T,Q> >::operator()(glm::mat<4, 4, T, Q> const& m) const GLM_NOEXCEPT
|
||||
{
|
||||
size_t seed = 0;
|
||||
hash<glm::vec<4, T, Q> > hasher;
|
||||
glm::detail::hash_combine(seed, hasher(m[0]));
|
||||
glm::detail::hash_combine(seed, hasher(m[1]));
|
||||
glm::detail::hash_combine(seed, hasher(m[2]));
|
||||
glm::detail::hash_combine(seed, hasher(m[3]));
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/// @ref gtx_integer
|
||||
/// @file glm/gtx/integer.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_integer GLM_GTX_integer
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/integer.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Add support for integer for core functions
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../gtc/integer.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_integer is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_integer extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_integer
|
||||
/// @{
|
||||
|
||||
//! Returns x raised to the y power.
|
||||
//! From GLM_GTX_integer extension.
|
||||
GLM_FUNC_DECL int pow(int x, uint y);
|
||||
|
||||
//! Returns the positive square root of x.
|
||||
//! From GLM_GTX_integer extension.
|
||||
GLM_FUNC_DECL int sqrt(int x);
|
||||
|
||||
//! Returns the floor log2 of x.
|
||||
//! From GLM_GTX_integer extension.
|
||||
GLM_FUNC_DECL unsigned int floor_log2(unsigned int x);
|
||||
|
||||
//! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
|
||||
//! From GLM_GTX_integer extension.
|
||||
GLM_FUNC_DECL int mod(int x, int y);
|
||||
|
||||
//! Return the factorial value of a number (!12 max, integer only)
|
||||
//! From GLM_GTX_integer extension.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType factorial(genType const& x);
|
||||
|
||||
//! 32bit signed integer.
|
||||
//! From GLM_GTX_integer extension.
|
||||
typedef signed int sint;
|
||||
|
||||
//! Returns x raised to the y power.
|
||||
//! From GLM_GTX_integer extension.
|
||||
GLM_FUNC_DECL uint pow(uint x, uint y);
|
||||
|
||||
//! Returns the positive square root of x.
|
||||
//! From GLM_GTX_integer extension.
|
||||
GLM_FUNC_DECL uint sqrt(uint x);
|
||||
|
||||
//! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
|
||||
//! From GLM_GTX_integer extension.
|
||||
GLM_FUNC_DECL uint mod(uint x, uint y);
|
||||
|
||||
//! Returns the number of leading zeros.
|
||||
//! From GLM_GTX_integer extension.
|
||||
GLM_FUNC_DECL uint nlz(uint x);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "integer.inl"
|
||||
@@ -0,0 +1,185 @@
|
||||
/// @ref gtx_integer
|
||||
|
||||
namespace glm
|
||||
{
|
||||
// pow
|
||||
GLM_FUNC_QUALIFIER int pow(int x, uint y)
|
||||
{
|
||||
if(y == 0)
|
||||
return x >= 0 ? 1 : -1;
|
||||
|
||||
int result = x;
|
||||
for(uint i = 1; i < y; ++i)
|
||||
result *= x;
|
||||
return result;
|
||||
}
|
||||
|
||||
// sqrt: From Christopher J. Musial, An integer square root, Graphics Gems, 1990, page 387
|
||||
GLM_FUNC_QUALIFIER int sqrt(int x)
|
||||
{
|
||||
if(x <= 1) return x;
|
||||
|
||||
int NextTrial = x >> 1;
|
||||
int CurrentAnswer;
|
||||
|
||||
do
|
||||
{
|
||||
CurrentAnswer = NextTrial;
|
||||
NextTrial = (NextTrial + x / NextTrial) >> 1;
|
||||
} while(NextTrial < CurrentAnswer);
|
||||
|
||||
return CurrentAnswer;
|
||||
}
|
||||
|
||||
// Henry Gordon Dietz: http://aggregate.org/MAGIC/
|
||||
namespace detail
|
||||
{
|
||||
GLM_FUNC_QUALIFIER unsigned int ones32(unsigned int x)
|
||||
{
|
||||
/* 32-bit recursive reduction using SWAR...
|
||||
but first step is mapping 2-bit values
|
||||
into sum of 2 1-bit values in sneaky way
|
||||
*/
|
||||
x -= ((x >> 1) & 0x55555555);
|
||||
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
|
||||
x = (((x >> 4) + x) & 0x0f0f0f0f);
|
||||
x += (x >> 8);
|
||||
x += (x >> 16);
|
||||
return(x & 0x0000003f);
|
||||
}
|
||||
}//namespace detail
|
||||
|
||||
// Henry Gordon Dietz: http://aggregate.org/MAGIC/
|
||||
/*
|
||||
GLM_FUNC_QUALIFIER unsigned int floor_log2(unsigned int x)
|
||||
{
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
|
||||
return _detail::ones32(x) >> 1;
|
||||
}
|
||||
*/
|
||||
// mod
|
||||
GLM_FUNC_QUALIFIER int mod(int x, int y)
|
||||
{
|
||||
return ((x % y) + y) % y;
|
||||
}
|
||||
|
||||
// factorial (!12 max, integer only)
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType factorial(genType const& x)
|
||||
{
|
||||
genType Temp = x;
|
||||
genType Result;
|
||||
for(Result = 1; Temp > 1; --Temp)
|
||||
Result *= Temp;
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<2, T, Q> factorial(
|
||||
vec<2, T, Q> const& x)
|
||||
{
|
||||
return vec<2, T, Q>(
|
||||
factorial(x.x),
|
||||
factorial(x.y));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> factorial(
|
||||
vec<3, T, Q> const& x)
|
||||
{
|
||||
return vec<3, T, Q>(
|
||||
factorial(x.x),
|
||||
factorial(x.y),
|
||||
factorial(x.z));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, T, Q> factorial(
|
||||
vec<4, T, Q> const& x)
|
||||
{
|
||||
return vec<4, T, Q>(
|
||||
factorial(x.x),
|
||||
factorial(x.y),
|
||||
factorial(x.z),
|
||||
factorial(x.w));
|
||||
}
|
||||
|
||||
GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
|
||||
{
|
||||
if (y == 0)
|
||||
return 1u;
|
||||
|
||||
uint result = x;
|
||||
for(uint i = 1; i < y; ++i)
|
||||
result *= x;
|
||||
return result;
|
||||
}
|
||||
|
||||
GLM_FUNC_QUALIFIER uint sqrt(uint x)
|
||||
{
|
||||
if(x <= 1) return x;
|
||||
|
||||
uint NextTrial = x >> 1;
|
||||
uint CurrentAnswer;
|
||||
|
||||
do
|
||||
{
|
||||
CurrentAnswer = NextTrial;
|
||||
NextTrial = (NextTrial + x / NextTrial) >> 1;
|
||||
} while(NextTrial < CurrentAnswer);
|
||||
|
||||
return CurrentAnswer;
|
||||
}
|
||||
|
||||
GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
|
||||
{
|
||||
return x - y * (x / y);
|
||||
}
|
||||
|
||||
//#if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC))
|
||||
|
||||
GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x)
|
||||
{
|
||||
return 31u - static_cast<unsigned int>(findMSB(x));
|
||||
}
|
||||
/*
|
||||
#else
|
||||
|
||||
// Hackers Delight: http://www.hackersdelight.org/HDcode/nlz.c.txt
|
||||
GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x)
|
||||
{
|
||||
int y, m, n;
|
||||
|
||||
y = -int(x >> 16); // If left half of x is 0,
|
||||
m = (y >> 16) & 16; // set n = 16. If left half
|
||||
n = 16 - m; // is nonzero, set n = 0 and
|
||||
x = x >> m; // shift x right 16.
|
||||
// Now x is of the form 0000xxxx.
|
||||
y = x - 0x100; // If positions 8-15 are 0,
|
||||
m = (y >> 16) & 8; // add 8 to n and shift x left 8.
|
||||
n = n + m;
|
||||
x = x << m;
|
||||
|
||||
y = x - 0x1000; // If positions 12-15 are 0,
|
||||
m = (y >> 16) & 4; // add 4 to n and shift x left 4.
|
||||
n = n + m;
|
||||
x = x << m;
|
||||
|
||||
y = x - 0x4000; // If positions 14-15 are 0,
|
||||
m = (y >> 16) & 2; // add 2 to n and shift x left 2.
|
||||
n = n + m;
|
||||
x = x << m;
|
||||
|
||||
y = x >> 14; // Set y = 0, 1, 2, or 3.
|
||||
m = y & ~(y >> 1); // Set m = 0, 1, 2, or 2 resp.
|
||||
return unsigned(n + 2 - m);
|
||||
}
|
||||
|
||||
#endif//(GLM_COMPILER)
|
||||
*/
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,90 @@
|
||||
/// @ref gtx_intersect
|
||||
/// @file glm/gtx/intersect.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_closest_point (dependence)
|
||||
///
|
||||
/// @defgroup gtx_intersect GLM_GTX_intersect
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/intersect.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Add intersection functions
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include <cfloat>
|
||||
#include <limits>
|
||||
#include "../glm.hpp"
|
||||
#include "../geometric.hpp"
|
||||
#include "../gtx/closest_point.hpp"
|
||||
#include "../gtx/vector_query.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_closest_point is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_closest_point extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_intersect
|
||||
/// @{
|
||||
|
||||
//! Compute the intersection of a ray and a plane.
|
||||
//! Ray direction and plane normal must be unit length.
|
||||
//! From GLM_GTX_intersect extension.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL bool intersectRayPlane(
|
||||
genType const& orig, genType const& dir,
|
||||
genType const& planeOrig, genType const& planeNormal,
|
||||
typename genType::value_type & intersectionDistance);
|
||||
|
||||
//! Compute the intersection of a ray and a triangle.
|
||||
/// Based om Tomas Möller implementation http://fileadmin.cs.lth.se/cs/Personal/Tomas_Akenine-Moller/raytri/
|
||||
//! From GLM_GTX_intersect extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL bool intersectRayTriangle(
|
||||
vec<3, T, Q> const& orig, vec<3, T, Q> const& dir,
|
||||
vec<3, T, Q> const& v0, vec<3, T, Q> const& v1, vec<3, T, Q> const& v2,
|
||||
vec<2, T, Q>& baryPosition, T& distance);
|
||||
|
||||
//! Compute the intersection of a line and a triangle.
|
||||
//! From GLM_GTX_intersect extension.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL bool intersectLineTriangle(
|
||||
genType const& orig, genType const& dir,
|
||||
genType const& vert0, genType const& vert1, genType const& vert2,
|
||||
genType & position);
|
||||
|
||||
//! Compute the intersection distance of a ray and a sphere.
|
||||
//! The ray direction vector is unit length.
|
||||
//! From GLM_GTX_intersect extension.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL bool intersectRaySphere(
|
||||
genType const& rayStarting, genType const& rayNormalizedDirection,
|
||||
genType const& sphereCenter, typename genType::value_type const sphereRadiusSquared,
|
||||
typename genType::value_type & intersectionDistance);
|
||||
|
||||
//! Compute the intersection of a ray and a sphere.
|
||||
//! From GLM_GTX_intersect extension.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL bool intersectRaySphere(
|
||||
genType const& rayStarting, genType const& rayNormalizedDirection,
|
||||
genType const& sphereCenter, const typename genType::value_type sphereRadius,
|
||||
genType & intersectionPosition, genType & intersectionNormal);
|
||||
|
||||
//! Compute the intersection of a line and a sphere.
|
||||
//! From GLM_GTX_intersect extension
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL bool intersectLineSphere(
|
||||
genType const& point0, genType const& point1,
|
||||
genType const& sphereCenter, typename genType::value_type sphereRadius,
|
||||
genType & intersectionPosition1, genType & intersectionNormal1,
|
||||
genType & intersectionPosition2 = genType(), genType & intersectionNormal2 = genType());
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "intersect.inl"
|
||||
@@ -0,0 +1,200 @@
|
||||
/// @ref gtx_intersect
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER bool intersectRayPlane
|
||||
(
|
||||
genType const& orig, genType const& dir,
|
||||
genType const& planeOrig, genType const& planeNormal,
|
||||
typename genType::value_type & intersectionDistance
|
||||
)
|
||||
{
|
||||
typename genType::value_type d = glm::dot(dir, planeNormal);
|
||||
typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
|
||||
|
||||
if(glm::abs(d) > Epsilon) // if dir and planeNormal are not perpendicular
|
||||
{
|
||||
typename genType::value_type const tmp_intersectionDistance = glm::dot(planeOrig - orig, planeNormal) / d;
|
||||
if (tmp_intersectionDistance > static_cast<typename genType::value_type>(0)) { // allow only intersections
|
||||
intersectionDistance = tmp_intersectionDistance;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool intersectRayTriangle
|
||||
(
|
||||
vec<3, T, Q> const& orig, vec<3, T, Q> const& dir,
|
||||
vec<3, T, Q> const& vert0, vec<3, T, Q> const& vert1, vec<3, T, Q> const& vert2,
|
||||
vec<2, T, Q>& baryPosition, T& distance
|
||||
)
|
||||
{
|
||||
// find vectors for two edges sharing vert0
|
||||
vec<3, T, Q> const edge1 = vert1 - vert0;
|
||||
vec<3, T, Q> const edge2 = vert2 - vert0;
|
||||
|
||||
// begin calculating determinant - also used to calculate U parameter
|
||||
vec<3, T, Q> const p = glm::cross(dir, edge2);
|
||||
|
||||
// if determinant is near zero, ray lies in plane of triangle
|
||||
T const det = glm::dot(edge1, p);
|
||||
|
||||
vec<3, T, Q> Perpendicular(0);
|
||||
|
||||
if (det > static_cast<T>(0))
|
||||
{
|
||||
// calculate distance from vert0 to ray origin
|
||||
vec<3, T, Q> const dist = orig - vert0;
|
||||
|
||||
// calculate U parameter and test bounds
|
||||
baryPosition.x = glm::dot(dist, p);
|
||||
if(baryPosition.x < static_cast<T>(0) || baryPosition.x > det)
|
||||
return false;
|
||||
|
||||
// prepare to test V parameter
|
||||
Perpendicular = glm::cross(dist, edge1);
|
||||
|
||||
// calculate V parameter and test bounds
|
||||
baryPosition.y = glm::dot(dir, Perpendicular);
|
||||
if((baryPosition.y < static_cast<T>(0)) || ((baryPosition.x + baryPosition.y) > det))
|
||||
return false;
|
||||
}
|
||||
else if(det < static_cast<T>(0))
|
||||
{
|
||||
// calculate distance from vert0 to ray origin
|
||||
vec<3, T, Q> const dist = orig - vert0;
|
||||
|
||||
// calculate U parameter and test bounds
|
||||
baryPosition.x = glm::dot(dist, p);
|
||||
if((baryPosition.x > static_cast<T>(0)) || (baryPosition.x < det))
|
||||
return false;
|
||||
|
||||
// prepare to test V parameter
|
||||
Perpendicular = glm::cross(dist, edge1);
|
||||
|
||||
// calculate V parameter and test bounds
|
||||
baryPosition.y = glm::dot(dir, Perpendicular);
|
||||
if((baryPosition.y > static_cast<T>(0)) || (baryPosition.x + baryPosition.y < det))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false; // ray is parallel to the plane of the triangle
|
||||
|
||||
T inv_det = static_cast<T>(1) / det;
|
||||
|
||||
// calculate distance, ray intersects triangle
|
||||
distance = glm::dot(edge2, Perpendicular) * inv_det;
|
||||
baryPosition *= inv_det;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER bool intersectLineTriangle
|
||||
(
|
||||
genType const& orig, genType const& dir,
|
||||
genType const& vert0, genType const& vert1, genType const& vert2,
|
||||
genType & position
|
||||
)
|
||||
{
|
||||
typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
|
||||
|
||||
genType edge1 = vert1 - vert0;
|
||||
genType edge2 = vert2 - vert0;
|
||||
|
||||
genType Perpendicular = cross(dir, edge2);
|
||||
|
||||
typename genType::value_type det = dot(edge1, Perpendicular);
|
||||
|
||||
if (det > -Epsilon && det < Epsilon)
|
||||
return false;
|
||||
typename genType::value_type inv_det = typename genType::value_type(1) / det;
|
||||
|
||||
genType Tangent = orig - vert0;
|
||||
|
||||
position.y = dot(Tangent, Perpendicular) * inv_det;
|
||||
if (position.y < typename genType::value_type(0) || position.y > typename genType::value_type(1))
|
||||
return false;
|
||||
|
||||
genType Cotangent = cross(Tangent, edge1);
|
||||
|
||||
position.z = dot(dir, Cotangent) * inv_det;
|
||||
if (position.z < typename genType::value_type(0) || position.y + position.z > typename genType::value_type(1))
|
||||
return false;
|
||||
|
||||
position.x = dot(edge2, Cotangent) * inv_det;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER bool intersectRaySphere
|
||||
(
|
||||
genType const& rayStarting, genType const& rayNormalizedDirection,
|
||||
genType const& sphereCenter, const typename genType::value_type sphereRadiusSquared,
|
||||
typename genType::value_type & intersectionDistance
|
||||
)
|
||||
{
|
||||
typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
|
||||
genType diff = sphereCenter - rayStarting;
|
||||
typename genType::value_type t0 = dot(diff, rayNormalizedDirection);
|
||||
typename genType::value_type dSquared = dot(diff, diff) - t0 * t0;
|
||||
if( dSquared > sphereRadiusSquared )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
typename genType::value_type t1 = sqrt( sphereRadiusSquared - dSquared );
|
||||
intersectionDistance = t0 > t1 + Epsilon ? t0 - t1 : t0 + t1;
|
||||
return intersectionDistance > Epsilon;
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER bool intersectRaySphere
|
||||
(
|
||||
genType const& rayStarting, genType const& rayNormalizedDirection,
|
||||
genType const& sphereCenter, const typename genType::value_type sphereRadius,
|
||||
genType & intersectionPosition, genType & intersectionNormal
|
||||
)
|
||||
{
|
||||
typename genType::value_type distance;
|
||||
if( intersectRaySphere( rayStarting, rayNormalizedDirection, sphereCenter, sphereRadius * sphereRadius, distance ) )
|
||||
{
|
||||
intersectionPosition = rayStarting + rayNormalizedDirection * distance;
|
||||
intersectionNormal = (intersectionPosition - sphereCenter) / sphereRadius;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER bool intersectLineSphere
|
||||
(
|
||||
genType const& point0, genType const& point1,
|
||||
genType const& sphereCenter, typename genType::value_type sphereRadius,
|
||||
genType & intersectionPoint1, genType & intersectionNormal1,
|
||||
genType & intersectionPoint2, genType & intersectionNormal2
|
||||
)
|
||||
{
|
||||
typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
|
||||
genType dir = normalize(point1 - point0);
|
||||
genType diff = sphereCenter - point0;
|
||||
typename genType::value_type t0 = dot(diff, dir);
|
||||
typename genType::value_type dSquared = dot(diff, diff) - t0 * t0;
|
||||
if( dSquared > sphereRadius * sphereRadius )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
typename genType::value_type t1 = sqrt( sphereRadius * sphereRadius - dSquared );
|
||||
if( t0 < t1 + Epsilon )
|
||||
t1 = -t1;
|
||||
intersectionPoint1 = point0 + dir * (t0 - t1);
|
||||
intersectionNormal1 = (intersectionPoint1 - sphereCenter) / sphereRadius;
|
||||
intersectionPoint2 = point0 + dir * (t0 + t1);
|
||||
intersectionNormal2 = (intersectionPoint2 - sphereCenter) / sphereRadius;
|
||||
return true;
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,210 @@
|
||||
/// @ref gtx_io
|
||||
/// @file glm/gtx/io.hpp
|
||||
/// @author Jan P Springer ([email protected])
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtc_matrix_access (dependence)
|
||||
/// @see gtc_quaternion (dependence)
|
||||
///
|
||||
/// @defgroup gtx_io GLM_GTX_io
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/io.hpp> to use the features of this extension.
|
||||
///
|
||||
/// std::[w]ostream support for glm types
|
||||
///
|
||||
/// std::[w]ostream support for glm types + qualifier/width/etc. manipulators
|
||||
/// based on howard hinnant's std::chrono io proposal
|
||||
/// [http://home.roadrunner.com/~hinnant/bloomington/chrono_io.html]
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../gtx/quaternion.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_io is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_io extension included")
|
||||
#endif
|
||||
|
||||
#if GLM_COMPILER & GLM_COMPILER_CLANG
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wpadded"
|
||||
# pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
# pragma clang diagnostic ignored "-Wglobal-constructors"
|
||||
#endif
|
||||
|
||||
#include <iosfwd> // std::basic_ostream<> (fwd)
|
||||
#include <locale> // std::locale, std::locale::facet, std::locale::id
|
||||
#include <utility> // std::pair<>
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_io
|
||||
/// @{
|
||||
|
||||
namespace io
|
||||
{
|
||||
enum order_type { column_major, row_major};
|
||||
|
||||
template<typename CTy>
|
||||
class format_punct : public std::locale::facet
|
||||
{
|
||||
typedef CTy char_type;
|
||||
|
||||
public:
|
||||
|
||||
static std::locale::id id;
|
||||
|
||||
bool formatted;
|
||||
unsigned precision;
|
||||
unsigned width;
|
||||
char_type separator;
|
||||
char_type delim_left;
|
||||
char_type delim_right;
|
||||
char_type space;
|
||||
char_type newline;
|
||||
order_type order;
|
||||
|
||||
GLM_FUNC_DISCARD_DECL explicit format_punct(size_t a = 0);
|
||||
GLM_FUNC_DISCARD_DECL explicit format_punct(format_punct const&);
|
||||
};
|
||||
|
||||
template<typename CTy, typename CTr = std::char_traits<CTy> >
|
||||
class basic_state_saver {
|
||||
|
||||
public:
|
||||
|
||||
GLM_FUNC_DISCARD_DECL explicit basic_state_saver(std::basic_ios<CTy,CTr>&);
|
||||
GLM_FUNC_DISCARD_DECL ~basic_state_saver();
|
||||
|
||||
private:
|
||||
|
||||
typedef ::std::basic_ios<CTy,CTr> state_type;
|
||||
typedef typename state_type::char_type char_type;
|
||||
typedef ::std::ios_base::fmtflags flags_type;
|
||||
typedef ::std::streamsize streamsize_type;
|
||||
typedef ::std::locale const locale_type;
|
||||
|
||||
state_type& state_;
|
||||
flags_type flags_;
|
||||
streamsize_type precision_;
|
||||
streamsize_type width_;
|
||||
char_type fill_;
|
||||
locale_type locale_;
|
||||
|
||||
GLM_FUNC_DECL basic_state_saver& operator=(basic_state_saver const&);
|
||||
};
|
||||
|
||||
typedef basic_state_saver<char> state_saver;
|
||||
typedef basic_state_saver<wchar_t> wstate_saver;
|
||||
|
||||
template<typename CTy, typename CTr = std::char_traits<CTy> >
|
||||
class basic_format_saver
|
||||
{
|
||||
public:
|
||||
|
||||
GLM_FUNC_DISCARD_DECL explicit basic_format_saver(std::basic_ios<CTy,CTr>&);
|
||||
GLM_FUNC_DISCARD_DECL ~basic_format_saver();
|
||||
|
||||
private:
|
||||
|
||||
basic_state_saver<CTy> const bss_;
|
||||
|
||||
GLM_FUNC_DECL basic_format_saver& operator=(basic_format_saver const&);
|
||||
};
|
||||
|
||||
typedef basic_format_saver<char> format_saver;
|
||||
typedef basic_format_saver<wchar_t> wformat_saver;
|
||||
|
||||
struct precision
|
||||
{
|
||||
unsigned value;
|
||||
|
||||
GLM_FUNC_DISCARD_DECL explicit precision(unsigned);
|
||||
};
|
||||
|
||||
struct width
|
||||
{
|
||||
unsigned value;
|
||||
|
||||
GLM_FUNC_DISCARD_DECL explicit width(unsigned);
|
||||
};
|
||||
|
||||
template<typename CTy>
|
||||
struct delimeter
|
||||
{
|
||||
CTy value[3];
|
||||
|
||||
GLM_FUNC_DISCARD_DECL explicit delimeter(CTy /* left */, CTy /* right */, CTy /* separator */ = ',');
|
||||
};
|
||||
|
||||
struct order
|
||||
{
|
||||
order_type value;
|
||||
|
||||
GLM_FUNC_DISCARD_DECL explicit order(order_type);
|
||||
};
|
||||
|
||||
// functions, inlined (inline)
|
||||
|
||||
template<typename FTy, typename CTy, typename CTr>
|
||||
FTy const& get_facet(std::basic_ios<CTy,CTr>&);
|
||||
template<typename FTy, typename CTy, typename CTr>
|
||||
std::basic_ios<CTy,CTr>& formatted(std::basic_ios<CTy,CTr>&);
|
||||
template<typename FTy, typename CTy, typename CTr>
|
||||
std::basic_ios<CTy,CTr>& unformatted(std::basic_ios<CTy,CTr>&);
|
||||
|
||||
template<typename CTy, typename CTr>
|
||||
std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>&, precision const&);
|
||||
template<typename CTy, typename CTr>
|
||||
std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>&, width const&);
|
||||
template<typename CTy, typename CTr>
|
||||
std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>&, delimeter<CTy> const&);
|
||||
template<typename CTy, typename CTr>
|
||||
std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>&, order const&);
|
||||
}//namespace io
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, qua<T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, vec<1, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, vec<2, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, vec<3, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, vec<4, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, mat<2, 2, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, mat<2, 3, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, mat<2, 4, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, mat<3, 2, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, mat<3, 3, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, mat<3, 4, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, mat<4, 2, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, mat<4, 3, T, Q> const&);
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>&, mat<4, 4, T, Q> const&);
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL std::basic_ostream<CTy,CTr> & operator<<(std::basic_ostream<CTy,CTr> &,
|
||||
std::pair<mat<4, 4, T, Q> const, mat<4, 4, T, Q> const> const&);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#if GLM_COMPILER & GLM_COMPILER_CLANG
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "io.inl"
|
||||
@@ -0,0 +1,453 @@
|
||||
/// @ref gtx_io
|
||||
/// @author Jan P Springer ([email protected])
|
||||
|
||||
#include <iomanip> // std::fixed, std::setfill<>, std::setprecision, std::right, std::setw
|
||||
#include <ostream> // std::basic_ostream<>
|
||||
#include "../gtc/matrix_access.hpp" // glm::col, glm::row
|
||||
#include "../gtx/type_trait.hpp" // glm::type<>
|
||||
|
||||
#if GLM_COMPILER & GLM_COMPILER_CLANG
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wpadded"
|
||||
# pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
# pragma clang diagnostic ignored "-Wglobal-constructors"
|
||||
#endif
|
||||
|
||||
namespace glm{
|
||||
namespace io
|
||||
{
|
||||
template<typename CTy>
|
||||
GLM_FUNC_QUALIFIER format_punct<CTy>::format_punct(size_t a)
|
||||
: std::locale::facet(a)
|
||||
, formatted(true)
|
||||
, precision(3)
|
||||
, width(1 + 4 + 1 + precision)
|
||||
, separator(',')
|
||||
, delim_left('[')
|
||||
, delim_right(']')
|
||||
, space(' ')
|
||||
, newline('\n')
|
||||
, order(column_major)
|
||||
{}
|
||||
|
||||
template<typename CTy>
|
||||
GLM_FUNC_QUALIFIER format_punct<CTy>::format_punct(format_punct const& a)
|
||||
: std::locale::facet(0)
|
||||
, formatted(a.formatted)
|
||||
, precision(a.precision)
|
||||
, width(a.width)
|
||||
, separator(a.separator)
|
||||
, delim_left(a.delim_left)
|
||||
, delim_right(a.delim_right)
|
||||
, space(a.space)
|
||||
, newline(a.newline)
|
||||
, order(a.order)
|
||||
{}
|
||||
|
||||
template<typename CTy> std::locale::id format_punct<CTy>::id;
|
||||
|
||||
template<typename CTy, typename CTr>
|
||||
GLM_FUNC_QUALIFIER basic_state_saver<CTy, CTr>::basic_state_saver(std::basic_ios<CTy, CTr>& a)
|
||||
: state_(a)
|
||||
, flags_(a.flags())
|
||||
, precision_(a.precision())
|
||||
, width_(a.width())
|
||||
, fill_(a.fill())
|
||||
, locale_(a.getloc())
|
||||
{}
|
||||
|
||||
template<typename CTy, typename CTr>
|
||||
GLM_FUNC_QUALIFIER basic_state_saver<CTy, CTr>::~basic_state_saver()
|
||||
{
|
||||
state_.imbue(locale_);
|
||||
state_.fill(fill_);
|
||||
state_.width(width_);
|
||||
state_.precision(precision_);
|
||||
state_.flags(flags_);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr>
|
||||
GLM_FUNC_QUALIFIER basic_format_saver<CTy, CTr>::basic_format_saver(std::basic_ios<CTy, CTr>& a)
|
||||
: bss_(a)
|
||||
{
|
||||
a.imbue(std::locale(a.getloc(), new format_punct<CTy>(get_facet<format_punct<CTy> >(a))));
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr>
|
||||
GLM_FUNC_QUALIFIER
|
||||
basic_format_saver<CTy, CTr>::~basic_format_saver()
|
||||
{}
|
||||
|
||||
GLM_FUNC_QUALIFIER precision::precision(unsigned a)
|
||||
: value(a)
|
||||
{}
|
||||
|
||||
GLM_FUNC_QUALIFIER width::width(unsigned a)
|
||||
: value(a)
|
||||
{}
|
||||
|
||||
template<typename CTy>
|
||||
GLM_FUNC_QUALIFIER delimeter<CTy>::delimeter(CTy a, CTy b, CTy c)
|
||||
: value()
|
||||
{
|
||||
value[0] = a;
|
||||
value[1] = b;
|
||||
value[2] = c;
|
||||
}
|
||||
|
||||
GLM_FUNC_QUALIFIER order::order(order_type a)
|
||||
: value(a)
|
||||
{}
|
||||
|
||||
template<typename FTy, typename CTy, typename CTr>
|
||||
GLM_FUNC_QUALIFIER FTy const& get_facet(std::basic_ios<CTy, CTr>& ios)
|
||||
{
|
||||
if(!std::has_facet<FTy>(ios.getloc()))
|
||||
ios.imbue(std::locale(ios.getloc(), new FTy));
|
||||
|
||||
return std::use_facet<FTy>(ios.getloc());
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr>
|
||||
GLM_FUNC_QUALIFIER std::basic_ios<CTy, CTr>& formatted(std::basic_ios<CTy, CTr>& ios)
|
||||
{
|
||||
const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(ios)).formatted = true;
|
||||
return ios;
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr>
|
||||
GLM_FUNC_QUALIFIER std::basic_ios<CTy, CTr>& unformatted(std::basic_ios<CTy, CTr>& ios)
|
||||
{
|
||||
const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(ios)).formatted = false;
|
||||
return ios;
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>& os, precision const& a)
|
||||
{
|
||||
const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(os)).precision = a.value;
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>& os, width const& a)
|
||||
{
|
||||
const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(os)).width = a.value;
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>& os, delimeter<CTy> const& a)
|
||||
{
|
||||
format_punct<CTy> & fmt(const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(os)));
|
||||
|
||||
fmt.delim_left = a.value[0];
|
||||
fmt.delim_right = a.value[1];
|
||||
fmt.separator = a.value[2];
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>& os, order const& a)
|
||||
{
|
||||
const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(os)).order = a.value;
|
||||
return os;
|
||||
}
|
||||
} // namespace io
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename CTy, typename CTr, typename V>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>&
|
||||
print_vector_on(std::basic_ostream<CTy, CTr>& os, V const& a)
|
||||
{
|
||||
typename std::basic_ostream<CTy, CTr>::sentry const cerberus(os);
|
||||
|
||||
if(cerberus)
|
||||
{
|
||||
io::format_punct<CTy> const& fmt(io::get_facet<io::format_punct<CTy> >(os));
|
||||
|
||||
length_t const& components(type<V>::components);
|
||||
|
||||
if(fmt.formatted)
|
||||
{
|
||||
io::basic_state_saver<CTy> const bss(os);
|
||||
|
||||
os << std::fixed << std::right << std::setprecision(static_cast<std::streamsize>(fmt.precision)) << std::setfill(fmt.space) << fmt.delim_left;
|
||||
|
||||
for(length_t i(0); i < components; ++i)
|
||||
{
|
||||
os << std::setw(static_cast<int>(fmt.width)) << a[i];
|
||||
if(components-1 != i)
|
||||
os << fmt.separator;
|
||||
}
|
||||
|
||||
os << fmt.delim_right;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(length_t i(0); i < components; ++i)
|
||||
{
|
||||
os << a[i];
|
||||
|
||||
if(components-1 != i)
|
||||
os << fmt.space;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
}//namespace detail
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, qua<T, Q> const& a)
|
||||
{
|
||||
return detail::print_vector_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, vec<1, T, Q> const& a)
|
||||
{
|
||||
return detail::print_vector_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, vec<2, T, Q> const& a)
|
||||
{
|
||||
return detail::print_vector_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, vec<3, T, Q> const& a)
|
||||
{
|
||||
return detail::print_vector_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, vec<4, T, Q> const& a)
|
||||
{
|
||||
return detail::print_vector_on(os, a);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename CTy, typename CTr, template<length_t, length_t, typename, qualifier> class M, length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& print_matrix_on(std::basic_ostream<CTy, CTr>& os, M<C, R, T, Q> const& a)
|
||||
{
|
||||
typename std::basic_ostream<CTy,CTr>::sentry const cerberus(os);
|
||||
|
||||
if(cerberus)
|
||||
{
|
||||
io::format_punct<CTy> const& fmt(io::get_facet<io::format_punct<CTy> >(os));
|
||||
|
||||
length_t const& cols(type<M<C, R, T, Q> >::cols);
|
||||
length_t const& rows(type<M<C, R, T, Q> >::rows);
|
||||
|
||||
if(fmt.formatted)
|
||||
{
|
||||
os << fmt.newline << fmt.delim_left;
|
||||
|
||||
switch(fmt.order)
|
||||
{
|
||||
case io::column_major:
|
||||
{
|
||||
for(length_t i(0); i < rows; ++i)
|
||||
{
|
||||
if (0 != i)
|
||||
os << fmt.space;
|
||||
|
||||
os << row(a, i);
|
||||
|
||||
if(rows-1 != i)
|
||||
os << fmt.newline;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case io::row_major:
|
||||
{
|
||||
for(length_t i(0); i < cols; ++i)
|
||||
{
|
||||
if(0 != i)
|
||||
os << fmt.space;
|
||||
|
||||
os << column(a, i);
|
||||
|
||||
if(cols-1 != i)
|
||||
os << fmt.newline;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
os << fmt.delim_right;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (fmt.order)
|
||||
{
|
||||
case io::column_major:
|
||||
{
|
||||
for(length_t i(0); i < cols; ++i)
|
||||
{
|
||||
os << column(a, i);
|
||||
|
||||
if(cols - 1 != i)
|
||||
os << fmt.space;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case io::row_major:
|
||||
{
|
||||
for (length_t i(0); i < rows; ++i)
|
||||
{
|
||||
os << row(a, i);
|
||||
|
||||
if (rows-1 != i)
|
||||
os << fmt.space;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
}//namespace detail
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, mat<2, 2, T, Q> const& a)
|
||||
{
|
||||
return detail::print_matrix_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, mat<2, 3, T, Q> const& a)
|
||||
{
|
||||
return detail::print_matrix_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, mat<2, 4, T, Q> const& a)
|
||||
{
|
||||
return detail::print_matrix_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, mat<3, 2, T, Q> const& a)
|
||||
{
|
||||
return detail::print_matrix_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, mat<3, 3, T, Q> const& a)
|
||||
{
|
||||
return detail::print_matrix_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr> & operator<<(std::basic_ostream<CTy,CTr>& os, mat<3, 4, T, Q> const& a)
|
||||
{
|
||||
return detail::print_matrix_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr> & operator<<(std::basic_ostream<CTy,CTr>& os, mat<4, 2, T, Q> const& a)
|
||||
{
|
||||
return detail::print_matrix_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr> & operator<<(std::basic_ostream<CTy,CTr>& os, mat<4, 3, T, Q> const& a)
|
||||
{
|
||||
return detail::print_matrix_on(os, a);
|
||||
}
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr> & operator<<(std::basic_ostream<CTy,CTr>& os, mat<4, 4, T, Q> const& a)
|
||||
{
|
||||
return detail::print_matrix_on(os, a);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename CTy, typename CTr, template<length_t, length_t, typename, qualifier> class M, length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& print_matrix_pair_on(std::basic_ostream<CTy, CTr>& os, std::pair<M<C, R, T, Q> const, M<C, R, T, Q> const> const& a)
|
||||
{
|
||||
typename std::basic_ostream<CTy,CTr>::sentry const cerberus(os);
|
||||
|
||||
if(cerberus)
|
||||
{
|
||||
io::format_punct<CTy> const& fmt(io::get_facet<io::format_punct<CTy> >(os));
|
||||
M<C, R, T, Q> const& ml(a.first);
|
||||
M<C, R, T, Q> const& mr(a.second);
|
||||
length_t const& cols(type<M<C, R, T, Q> >::cols);
|
||||
length_t const& rows(type<M<C, R, T, Q> >::rows);
|
||||
|
||||
if(fmt.formatted)
|
||||
{
|
||||
os << fmt.newline << fmt.delim_left;
|
||||
|
||||
switch(fmt.order)
|
||||
{
|
||||
default:
|
||||
case io::column_major:
|
||||
{
|
||||
for(length_t i(0); i < rows; ++i)
|
||||
{
|
||||
if(0 != i)
|
||||
os << fmt.space;
|
||||
|
||||
os << row(ml, i) << ((rows-1 != i) ? fmt.space : fmt.delim_right) << fmt.space << ((0 != i) ? fmt.space : fmt.delim_left) << row(mr, i);
|
||||
|
||||
if(rows-1 != i)
|
||||
os << fmt.newline;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case io::row_major:
|
||||
{
|
||||
for(length_t i(0); i < cols; ++i)
|
||||
{
|
||||
if(0 != i)
|
||||
os << fmt.space;
|
||||
|
||||
os << column(ml, i) << ((cols-1 != i) ? fmt.space : fmt.delim_right) << fmt.space << ((0 != i) ? fmt.space : fmt.delim_left) << column(mr, i);
|
||||
|
||||
if(cols-1 != i)
|
||||
os << fmt.newline;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
os << fmt.delim_right;
|
||||
}
|
||||
else
|
||||
{
|
||||
os << ml << fmt.space << mr;
|
||||
}
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
}//namespace detail
|
||||
|
||||
template<typename CTy, typename CTr, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& operator<<(
|
||||
std::basic_ostream<CTy, CTr> & os,
|
||||
std::pair<mat<4, 4, T, Q> const,
|
||||
mat<4, 4, T, Q> const> const& a)
|
||||
{
|
||||
return detail::print_matrix_pair_on(os, a);
|
||||
}
|
||||
}//namespace glm
|
||||
|
||||
#if GLM_COMPILER & GLM_COMPILER_CLANG
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/// @ref gtx_iteration
|
||||
/// @file glm/gtx/iteration.hpp
|
||||
///
|
||||
/// @defgroup gtx_iteration GLM_GTX_iteration
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/iteration.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Defines begin and end for vectors, matrices and quaternions useful for range based for loop construct
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependencies
|
||||
#include "../detail/setup.hpp"
|
||||
#include "../detail/qualifier.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_iteration is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_iteration extension included")
|
||||
#endif
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_iteration
|
||||
/// @{
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR T* begin(vec<L, T, Q>& v);
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR T* begin(mat<C, R, T, Q>& m);
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR T* begin(qua<T, Q>& q);
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR const T* begin(const vec<L, T, Q>& v);
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR const T* begin(const mat<C, R, T, Q>& m);
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR const T* begin(const qua<T, Q>& q);
|
||||
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR T* end(vec<L, T, Q>& v);
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR T* end(mat<C, R, T, Q>& m);
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR T* end(qua<T, Q>& q);
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR const T* end(const vec<L, T, Q>& v);
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR const T* end(const mat<C, R, T, Q>& m);
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR const T* end(const qua<T, Q>& q);
|
||||
|
||||
// Reverse iteration
|
||||
// rbegin,rend
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<T*> rbegin(vec<L, T, Q>& v);
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<T*> rbegin(mat<C, R, T, Q>& m);
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<T*> rbegin(qua<T, Q>& q);
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<const T*> rbegin(const vec<L, T, Q>& v);
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<const T*> rbegin(const mat<C, R, T, Q>& m);
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<const T*> rbegin(const qua<T, Q>& q);
|
||||
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<T*> rend(vec<L, T, Q>& v);
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<T*> rend(mat<C, R, T, Q>& m);
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<T*> rend(qua<T, Q>& q);
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<const T*> rend(const vec<L, T, Q>& v);
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<const T*> rend(const mat<C, R, T, Q>& m);
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR std::reverse_iterator<const T*> rend(const qua<T, Q>& q);
|
||||
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "iteration.inl"
|
||||
@@ -0,0 +1,116 @@
|
||||
namespace glm
|
||||
{
|
||||
/*
|
||||
namespace details {
|
||||
template<typename T, glm::length_t L>
|
||||
struct known_length_iterator;
|
||||
}
|
||||
*/
|
||||
|
||||
/// @addtogroup gtx_iteration
|
||||
/// @{
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T* begin(vec<L,T,Q>& v) {
|
||||
return &v.x;
|
||||
}
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T* begin(mat<C,R,T,Q>& m) {
|
||||
return &m[0].x;
|
||||
}
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T* begin(qua<T,Q>& q) {
|
||||
return &q[0];
|
||||
}
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR const T* begin(const vec<L,T,Q>& v) {
|
||||
return &v.x;
|
||||
}
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR const T* begin(const mat<C,R,T,Q>& m) {
|
||||
return &m[0].x;
|
||||
}
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR const T* begin(const qua<T,Q>& q) {
|
||||
return &q[0];
|
||||
}
|
||||
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T* end(vec<L,T,Q>& v) {
|
||||
return (&v.x) + L;
|
||||
}
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T* end(mat<C,R,T,Q>& m) {
|
||||
return (&m[0].x) + C*R;
|
||||
}
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T* end(qua<T,Q>& q) {
|
||||
return (&q[0]) + 4;
|
||||
}
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR const T* end(const vec<L,T,Q>& v) {
|
||||
return (&v.x) + L;
|
||||
}
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR const T* end(const mat<C,R,T,Q>& m) {
|
||||
return (&m[0].x) + C*R;
|
||||
}
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR const T* end(const qua<T,Q>& q) {
|
||||
return (&q[0]) + 4;
|
||||
}
|
||||
|
||||
// Reverse iteration
|
||||
// rbegin,rend
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<T*> rbegin(vec<L,T,Q>& v) {
|
||||
return std::reverse_iterator<T*>(end(v));
|
||||
}
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<T*> rbegin(mat<C,R,T,Q>& m) {
|
||||
return std::reverse_iterator<T*>(end(m));
|
||||
}
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<T*> rbegin(qua<T,Q>& q) {
|
||||
return std::reverse_iterator<T*>(end(q));
|
||||
}
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<const T*> rbegin(const vec<L,T,Q>& v) {
|
||||
return std::reverse_iterator<const T*>(end(v));
|
||||
}
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<const T*> rbegin(const mat<C,R,T,Q>& m) {
|
||||
return std::reverse_iterator<const T*>(end(m));
|
||||
}
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<const T*> rbegin(const qua<T,Q>& q) {
|
||||
return std::reverse_iterator<const T*>(end(q));
|
||||
}
|
||||
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<T*> rend(vec<L,T,Q>& v) {
|
||||
return std::reverse_iterator<T*>(begin(v));
|
||||
}
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<T*> rend(mat<C,R,T,Q>& m) {
|
||||
return std::reverse_iterator<T*>(begin(m));
|
||||
}
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<T*> rend(qua<T,Q>& q) {
|
||||
return std::reverse_iterator<T*>(begin(q));
|
||||
}
|
||||
template<length_t L,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<const T*> rend(const vec<L,T,Q>& v) {
|
||||
return std::reverse_iterator<const T*>(begin(v));
|
||||
}
|
||||
template<length_t C,length_t R,typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<const T*> rend(const mat<C,R,T,Q>& m) {
|
||||
return std::reverse_iterator<const T*>(begin(m));
|
||||
}
|
||||
template<typename T,qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR std::reverse_iterator<const T*> rend(const qua<T,Q>& q) {
|
||||
return std::reverse_iterator<const T*>(begin(q));
|
||||
}
|
||||
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,46 @@
|
||||
/// @ref gtx_log_base
|
||||
/// @file glm/gtx/log_base.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_log_base GLM_GTX_log_base
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/log_base.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Logarithm for any base. base can be a vector or a scalar.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_log_base is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_log_base extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_log_base
|
||||
/// @{
|
||||
|
||||
/// Logarithm for any base.
|
||||
/// From GLM_GTX_log_base.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType log(
|
||||
genType const& x,
|
||||
genType const& base);
|
||||
|
||||
/// Logarithm for any base.
|
||||
/// From GLM_GTX_log_base.
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> sign(
|
||||
vec<L, T, Q> const& x,
|
||||
vec<L, T, Q> const& base);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "log_base.inl"
|
||||
@@ -0,0 +1,16 @@
|
||||
/// @ref gtx_log_base
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType log(genType const& x, genType const& base)
|
||||
{
|
||||
return glm::log(x) / glm::log(base);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> log(vec<L, T, Q> const& x, vec<L, T, Q> const& base)
|
||||
{
|
||||
return glm::log(x) / glm::log(base);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,45 @@
|
||||
/// @ref gtx_matrix_cross_product
|
||||
/// @file glm/gtx/matrix_cross_product.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_extented_min_max (dependence)
|
||||
///
|
||||
/// @defgroup gtx_matrix_cross_product GLM_GTX_matrix_cross_product
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/matrix_cross_product.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Build cross product matrices
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_matrix_cross_product is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_matrix_cross_product extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_matrix_cross_product
|
||||
/// @{
|
||||
|
||||
//! Build a cross product matrix.
|
||||
//! From GLM_GTX_matrix_cross_product extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 3, T, Q> matrixCross3(
|
||||
vec<3, T, Q> const& x);
|
||||
|
||||
//! Build a cross product matrix.
|
||||
//! From GLM_GTX_matrix_cross_product extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> matrixCross4(
|
||||
vec<3, T, Q> const& x);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "matrix_cross_product.inl"
|
||||
@@ -0,0 +1,37 @@
|
||||
/// @ref gtx_matrix_cross_product
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> matrixCross3
|
||||
(
|
||||
vec<3, T, Q> const& x
|
||||
)
|
||||
{
|
||||
mat<3, 3, T, Q> Result(T(0));
|
||||
Result[0][1] = x.z;
|
||||
Result[1][0] = -x.z;
|
||||
Result[0][2] = -x.y;
|
||||
Result[2][0] = x.y;
|
||||
Result[1][2] = x.x;
|
||||
Result[2][1] = -x.x;
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> matrixCross4
|
||||
(
|
||||
vec<3, T, Q> const& x
|
||||
)
|
||||
{
|
||||
mat<4, 4, T, Q> Result(T(0));
|
||||
Result[0][1] = x.z;
|
||||
Result[1][0] = -x.z;
|
||||
Result[0][2] = -x.y;
|
||||
Result[2][0] = x.y;
|
||||
Result[1][2] = x.x;
|
||||
Result[2][1] = -x.x;
|
||||
return Result;
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,50 @@
|
||||
/// @ref gtx_matrix_decompose
|
||||
/// @file glm/gtx/matrix_decompose.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_matrix_decompose GLM_GTX_matrix_decompose
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/matrix_decompose.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Decomposes a model matrix to translations, rotation and scale components
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependencies
|
||||
#include "../mat4x4.hpp"
|
||||
#include "../vec3.hpp"
|
||||
#include "../vec4.hpp"
|
||||
#include "../geometric.hpp"
|
||||
#include "../gtc/quaternion.hpp"
|
||||
#include "../gtc/matrix_transform.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_matrix_decompose is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_matrix_decompose extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_matrix_decompose
|
||||
/// @{
|
||||
|
||||
/// Decomposes a model matrix to translations, rotation and scale components
|
||||
/// @see gtx_matrix_decompose
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL bool decompose(
|
||||
mat<4, 4, T, Q> const& modelMatrix,
|
||||
vec<3, T, Q> & scale, qua<T, Q> & orientation, vec<3, T, Q> & translation, vec<3, T, Q> & skew, vec<4, T, Q> & perspective);
|
||||
|
||||
// Recomposes a model matrix from a previously-decomposed matrix
|
||||
template <typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL mat<4, 4, T, Q> recompose(
|
||||
vec<3, T, Q> const& scale, qua<T, Q> const& orientation, vec<3, T, Q> const& translation,
|
||||
vec<3, T, Q> const& skew, vec<4, T, Q> const& perspective);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "matrix_decompose.inl"
|
||||
@@ -0,0 +1,234 @@
|
||||
/// @ref gtx_matrix_decompose
|
||||
|
||||
#include "../gtc/constants.hpp"
|
||||
#include "../gtc/epsilon.hpp"
|
||||
#include "../gtx/transform.hpp"
|
||||
|
||||
namespace glm{
|
||||
namespace detail
|
||||
{
|
||||
/// Make a linear combination of two vectors and return the result.
|
||||
// result = (a * ascl) + (b * bscl)
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> combine(
|
||||
vec<3, T, Q> const& a,
|
||||
vec<3, T, Q> const& b,
|
||||
T ascl, T bscl)
|
||||
{
|
||||
return (a * ascl) + (b * bscl);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> scale(vec<3, T, Q> const& v, T desiredLength)
|
||||
{
|
||||
return v * desiredLength / length(v);
|
||||
}
|
||||
}//namespace detail
|
||||
|
||||
// Matrix decompose
|
||||
// http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp
|
||||
// Decomposes the mode matrix to translations,rotation scale components
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool decompose(mat<4, 4, T, Q> const& ModelMatrix, vec<3, T, Q> & Scale, qua<T, Q> & Orientation, vec<3, T, Q> & Translation, vec<3, T, Q> & Skew, vec<4, T, Q> & Perspective)
|
||||
{
|
||||
mat<4, 4, T, Q> LocalMatrix(ModelMatrix);
|
||||
|
||||
// Normalize the matrix.
|
||||
if(epsilonEqual(LocalMatrix[3][3], static_cast<T>(0), epsilon<T>()))
|
||||
return false;
|
||||
|
||||
for(length_t i = 0; i < 4; ++i)
|
||||
for(length_t j = 0; j < 4; ++j)
|
||||
LocalMatrix[i][j] /= LocalMatrix[3][3];
|
||||
|
||||
// perspectiveMatrix is used to solve for perspective, but it also provides
|
||||
// an easy way to test for singularity of the upper 3x3 component.
|
||||
mat<4, 4, T, Q> PerspectiveMatrix(LocalMatrix);
|
||||
|
||||
for(length_t i = 0; i < 3; i++)
|
||||
PerspectiveMatrix[i][3] = static_cast<T>(0);
|
||||
PerspectiveMatrix[3][3] = static_cast<T>(1);
|
||||
|
||||
/// TODO: Fixme!
|
||||
if(epsilonEqual(determinant(PerspectiveMatrix), static_cast<T>(0), epsilon<T>()))
|
||||
return false;
|
||||
|
||||
// First, isolate perspective. This is the messiest.
|
||||
if(
|
||||
epsilonNotEqual(LocalMatrix[0][3], static_cast<T>(0), epsilon<T>()) ||
|
||||
epsilonNotEqual(LocalMatrix[1][3], static_cast<T>(0), epsilon<T>()) ||
|
||||
epsilonNotEqual(LocalMatrix[2][3], static_cast<T>(0), epsilon<T>()))
|
||||
{
|
||||
// rightHandSide is the right hand side of the equation.
|
||||
vec<4, T, Q> RightHandSide;
|
||||
RightHandSide[0] = LocalMatrix[0][3];
|
||||
RightHandSide[1] = LocalMatrix[1][3];
|
||||
RightHandSide[2] = LocalMatrix[2][3];
|
||||
RightHandSide[3] = LocalMatrix[3][3];
|
||||
|
||||
// Solve the equation by inverting PerspectiveMatrix and multiplying
|
||||
// rightHandSide by the inverse. (This is the easiest way, not
|
||||
// necessarily the best.)
|
||||
mat<4, 4, T, Q> InversePerspectiveMatrix = glm::inverse(PerspectiveMatrix);// inverse(PerspectiveMatrix, inversePerspectiveMatrix);
|
||||
mat<4, 4, T, Q> TransposedInversePerspectiveMatrix = glm::transpose(InversePerspectiveMatrix);// transposeMatrix4(inversePerspectiveMatrix, transposedInversePerspectiveMatrix);
|
||||
|
||||
Perspective = TransposedInversePerspectiveMatrix * RightHandSide;
|
||||
// v4MulPointByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspectivePoint);
|
||||
|
||||
// Clear the perspective partition
|
||||
LocalMatrix[0][3] = LocalMatrix[1][3] = LocalMatrix[2][3] = static_cast<T>(0);
|
||||
LocalMatrix[3][3] = static_cast<T>(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No perspective.
|
||||
Perspective = vec<4, T, Q>(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
// Next take care of translation (easy).
|
||||
Translation = vec<3, T, Q>(LocalMatrix[3]);
|
||||
LocalMatrix[3] = vec<4, T, Q>(0, 0, 0, LocalMatrix[3].w);
|
||||
|
||||
vec<3, T, Q> Row[3], Pdum3;
|
||||
|
||||
// Now get scale and shear.
|
||||
for(length_t i = 0; i < 3; ++i)
|
||||
for(length_t j = 0; j < 3; ++j)
|
||||
Row[i][j] = LocalMatrix[i][j];
|
||||
|
||||
// Compute X scale factor and normalize first row.
|
||||
Scale.x = length(Row[0]);// v3Length(Row[0]);
|
||||
|
||||
Row[0] = detail::scale(Row[0], static_cast<T>(1));
|
||||
|
||||
// Compute XY shear factor and make 2nd row orthogonal to 1st.
|
||||
Skew.z = dot(Row[0], Row[1]);
|
||||
Row[1] = detail::combine(Row[1], Row[0], static_cast<T>(1), -Skew.z);
|
||||
|
||||
// Now, compute Y scale and normalize 2nd row.
|
||||
Scale.y = length(Row[1]);
|
||||
Row[1] = detail::scale(Row[1], static_cast<T>(1));
|
||||
Skew.z /= Scale.y;
|
||||
|
||||
// Compute XZ and YZ shears, orthogonalize 3rd row.
|
||||
Skew.y = glm::dot(Row[0], Row[2]);
|
||||
Row[2] = detail::combine(Row[2], Row[0], static_cast<T>(1), -Skew.y);
|
||||
Skew.x = glm::dot(Row[1], Row[2]);
|
||||
Row[2] = detail::combine(Row[2], Row[1], static_cast<T>(1), -Skew.x);
|
||||
|
||||
// Next, get Z scale and normalize 3rd row.
|
||||
Scale.z = length(Row[2]);
|
||||
Row[2] = detail::scale(Row[2], static_cast<T>(1));
|
||||
Skew.y /= Scale.z;
|
||||
Skew.x /= Scale.z;
|
||||
|
||||
// At this point, the matrix (in rows[]) is orthonormal.
|
||||
// Check for a coordinate system flip. If the determinant
|
||||
// is -1, then negate the matrix and the scaling factors.
|
||||
Pdum3 = cross(Row[1], Row[2]); // v3Cross(row[1], row[2], Pdum3);
|
||||
if(dot(Row[0], Pdum3) < 0)
|
||||
{
|
||||
for(length_t i = 0; i < 3; i++)
|
||||
{
|
||||
Scale[i] *= static_cast<T>(-1);
|
||||
Row[i] *= static_cast<T>(-1);
|
||||
}
|
||||
}
|
||||
|
||||
// Now, get the rotations out, as described in the gem.
|
||||
|
||||
// FIXME - Add the ability to return either quaternions (which are
|
||||
// easier to recompose with) or Euler angles (rx, ry, rz), which
|
||||
// are easier for authors to deal with. The latter will only be useful
|
||||
// when we fix https://bugs.webkit.org/show_bug.cgi?id=23799, so I
|
||||
// will leave the Euler angle code here for now.
|
||||
|
||||
// ret.rotateY = asin(-Row[0][2]);
|
||||
// if (cos(ret.rotateY) != 0) {
|
||||
// ret.rotateX = atan2(Row[1][2], Row[2][2]);
|
||||
// ret.rotateZ = atan2(Row[0][1], Row[0][0]);
|
||||
// } else {
|
||||
// ret.rotateX = atan2(-Row[2][0], Row[1][1]);
|
||||
// ret.rotateZ = 0;
|
||||
// }
|
||||
|
||||
int i, j, k = 0;
|
||||
T root, trace = Row[0].x + Row[1].y + Row[2].z;
|
||||
if(trace > static_cast<T>(0))
|
||||
{
|
||||
root = sqrt(trace + static_cast<T>(1.0));
|
||||
Orientation.w = static_cast<T>(0.5) * root;
|
||||
root = static_cast<T>(0.5) / root;
|
||||
Orientation.x = root * (Row[1].z - Row[2].y);
|
||||
Orientation.y = root * (Row[2].x - Row[0].z);
|
||||
Orientation.z = root * (Row[0].y - Row[1].x);
|
||||
} // End if > 0
|
||||
else
|
||||
{
|
||||
static int Next[3] = {1, 2, 0};
|
||||
i = 0;
|
||||
if(Row[1].y > Row[0].x) i = 1;
|
||||
if(Row[2].z > Row[i][i]) i = 2;
|
||||
j = Next[i];
|
||||
k = Next[j];
|
||||
|
||||
# ifdef GLM_FORCE_QUAT_DATA_WXYZ
|
||||
int off = 1;
|
||||
# else
|
||||
int off = 0;
|
||||
# endif
|
||||
|
||||
root = sqrt(Row[i][i] - Row[j][j] - Row[k][k] + static_cast<T>(1.0));
|
||||
|
||||
Orientation[i + off] = static_cast<T>(0.5) * root;
|
||||
root = static_cast<T>(0.5) / root;
|
||||
Orientation[j + off] = root * (Row[i][j] + Row[j][i]);
|
||||
Orientation[k + off] = root * (Row[i][k] + Row[k][i]);
|
||||
Orientation.w = root * (Row[j][k] - Row[k][j]);
|
||||
} // End if <= 0
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Recomposes a model matrix from a previously-decomposed matrix
|
||||
// http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp
|
||||
// https://stackoverflow.com/a/75573092/1047040
|
||||
template <typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> recompose(
|
||||
vec<3, T, Q> const& scale, qua<T, Q> const& orientation, vec<3, T, Q> const& translation,
|
||||
vec<3, T, Q> const& skew, vec<4, T, Q> const& perspective)
|
||||
{
|
||||
glm::mat4 m = glm::mat4(1.f);
|
||||
|
||||
m[0][3] = perspective.x;
|
||||
m[1][3] = perspective.y;
|
||||
m[2][3] = perspective.z;
|
||||
m[3][3] = perspective.w;
|
||||
|
||||
m *= glm::translate(translation);
|
||||
m *= glm::mat4_cast(orientation);
|
||||
|
||||
if (abs(skew.x) > static_cast<T>(0)) {
|
||||
glm::mat4 tmp(1.f);
|
||||
tmp[2][1] = skew.x;
|
||||
m *= tmp;
|
||||
}
|
||||
|
||||
if (abs(skew.y) > static_cast<T>(0)) {
|
||||
glm::mat4 tmp(1.f);
|
||||
tmp[2][0] = skew.y;
|
||||
m *= tmp;
|
||||
}
|
||||
|
||||
if (abs(skew.z) > static_cast<T>(0)) {
|
||||
glm::mat4 tmp(1.f);
|
||||
tmp[1][0] = skew.z;
|
||||
m *= tmp;
|
||||
}
|
||||
|
||||
m *= glm::scale(scale);
|
||||
|
||||
return m;
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,67 @@
|
||||
/// @ref gtx_matrix_factorisation
|
||||
/// @file glm/gtx/matrix_factorisation.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_matrix_factorisation GLM_GTX_matrix_factorisation
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/matrix_factorisation.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Functions to factor matrices in various forms
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_matrix_factorisation is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_matrix_factorisation extension included")
|
||||
#endif
|
||||
|
||||
/*
|
||||
Suggestions:
|
||||
- Move helper functions flipud and fliplr to another file: They may be helpful in more general circumstances.
|
||||
- Implement other types of matrix factorisation, such as: QL and LQ, L(D)U, eigendecompositions, etc...
|
||||
*/
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_matrix_factorisation
|
||||
/// @{
|
||||
|
||||
/// Flips the matrix rows up and down.
|
||||
///
|
||||
/// From GLM_GTX_matrix_factorisation extension.
|
||||
template <length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<C, R, T, Q> flipud(mat<C, R, T, Q> const& in);
|
||||
|
||||
/// Flips the matrix columns right and left.
|
||||
///
|
||||
/// From GLM_GTX_matrix_factorisation extension.
|
||||
template <length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<C, R, T, Q> fliplr(mat<C, R, T, Q> const& in);
|
||||
|
||||
/// Performs QR factorisation of a matrix.
|
||||
/// Returns 2 matrices, q and r, such that the columns of q are orthonormal and span the same subspace than those of the input matrix, r is an upper triangular matrix, and q*r=in.
|
||||
/// Given an n-by-m input matrix, q has dimensions min(n,m)-by-m, and r has dimensions n-by-min(n,m).
|
||||
///
|
||||
/// From GLM_GTX_matrix_factorisation extension.
|
||||
template <length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL void qr_decompose(mat<C, R, T, Q> const& in, mat<(C < R ? C : R), R, T, Q>& q, mat<C, (C < R ? C : R), T, Q>& r);
|
||||
|
||||
/// Performs RQ factorisation of a matrix.
|
||||
/// Returns 2 matrices, r and q, such that r is an upper triangular matrix, the rows of q are orthonormal and span the same subspace than those of the input matrix, and r*q=in.
|
||||
/// Note that in the context of RQ factorisation, the diagonal is seen as starting in the lower-right corner of the matrix, instead of the usual upper-left.
|
||||
/// Given an n-by-m input matrix, r has dimensions min(n,m)-by-m, and q has dimensions n-by-min(n,m).
|
||||
///
|
||||
/// From GLM_GTX_matrix_factorisation extension.
|
||||
template <length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL void rq_decompose(mat<C, R, T, Q> const& in, mat<(C < R ? C : R), R, T, Q>& r, mat<C, (C < R ? C : R), T, Q>& q);
|
||||
|
||||
/// @}
|
||||
}
|
||||
|
||||
#include "matrix_factorisation.inl"
|
||||
@@ -0,0 +1,84 @@
|
||||
/// @ref gtx_matrix_factorisation
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template <length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<C, R, T, Q> flipud(mat<C, R, T, Q> const& in)
|
||||
{
|
||||
mat<R, C, T, Q> tin = transpose(in);
|
||||
tin = fliplr(tin);
|
||||
mat<C, R, T, Q> out = transpose(tin);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
template <length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<C, R, T, Q> fliplr(mat<C, R, T, Q> const& in)
|
||||
{
|
||||
mat<C, R, T, Q> out;
|
||||
for (length_t i = 0; i < C; i++)
|
||||
{
|
||||
out[i] = in[(C - i) - 1];
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
template <length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER void qr_decompose(mat<C, R, T, Q> const& in, mat<(C < R ? C : R), R, T, Q>& q, mat<C, (C < R ? C : R), T, Q>& r)
|
||||
{
|
||||
// Uses modified Gram-Schmidt method
|
||||
// Source: https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process
|
||||
// And https://en.wikipedia.org/wiki/QR_decomposition
|
||||
|
||||
//For all the linearly independs columns of the input...
|
||||
// (there can be no more linearly independents columns than there are rows.)
|
||||
for (length_t i = 0; i < (C < R ? C : R); i++)
|
||||
{
|
||||
//Copy in Q the input's i-th column.
|
||||
q[i] = in[i];
|
||||
|
||||
//j = [0,i[
|
||||
// Make that column orthogonal to all the previous ones by substracting to it the non-orthogonal projection of all the previous columns.
|
||||
// Also: Fill the zero elements of R
|
||||
for (length_t j = 0; j < i; j++)
|
||||
{
|
||||
q[i] -= dot(q[i], q[j])*q[j];
|
||||
r[j][i] = 0;
|
||||
}
|
||||
|
||||
//Now, Q i-th column is orthogonal to all the previous columns. Normalize it.
|
||||
q[i] = normalize(q[i]);
|
||||
|
||||
//j = [i,C[
|
||||
//Finally, compute the corresponding coefficients of R by computing the projection of the resulting column on the other columns of the input.
|
||||
for (length_t j = i; j < C; j++)
|
||||
{
|
||||
r[j][i] = dot(in[j], q[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER void rq_decompose(mat<C, R, T, Q> const& in, mat<(C < R ? C : R), R, T, Q>& r, mat<C, (C < R ? C : R), T, Q>& q)
|
||||
{
|
||||
// From https://en.wikipedia.org/wiki/QR_decomposition:
|
||||
// The RQ decomposition transforms a matrix A into the product of an upper triangular matrix R (also known as right-triangular) and an orthogonal matrix Q. The only difference from QR decomposition is the order of these matrices.
|
||||
// QR decomposition is Gram-Schmidt orthogonalization of columns of A, started from the first column.
|
||||
// RQ decomposition is Gram-Schmidt orthogonalization of rows of A, started from the last row.
|
||||
|
||||
mat<R, C, T, Q> tin = transpose(in);
|
||||
tin = fliplr(tin);
|
||||
|
||||
mat<R, (C < R ? C : R), T, Q> tr;
|
||||
mat<(C < R ? C : R), C, T, Q> tq;
|
||||
qr_decompose(tin, tq, tr);
|
||||
|
||||
tr = fliplr(tr);
|
||||
r = transpose(tr);
|
||||
r = fliplr(r);
|
||||
|
||||
tq = fliplr(tq);
|
||||
q = transpose(tq);
|
||||
}
|
||||
} //namespace glm
|
||||
@@ -0,0 +1,58 @@
|
||||
/// @ref gtx_matrix_interpolation
|
||||
/// @file glm/gtx/matrix_interpolation.hpp
|
||||
/// @author Ghenadii Ursachi ([email protected])
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_matrix_interpolation GLM_GTX_matrix_interpolation
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/matrix_interpolation.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Allows to directly interpolate two matrices.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_matrix_interpolation is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_matrix_interpolation extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_matrix_interpolation
|
||||
/// @{
|
||||
|
||||
/// Get the axis and angle of the rotation from a matrix.
|
||||
/// From GLM_GTX_matrix_interpolation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL void axisAngle(
|
||||
mat<4, 4, T, Q> const& Mat, vec<3, T, Q> & Axis, T & Angle);
|
||||
|
||||
/// Build a matrix from axis and angle.
|
||||
/// From GLM_GTX_matrix_interpolation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> axisAngleMatrix(
|
||||
vec<3, T, Q> const& Axis, T const Angle);
|
||||
|
||||
/// Extracts the rotation part of a matrix.
|
||||
/// From GLM_GTX_matrix_interpolation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> extractMatrixRotation(
|
||||
mat<4, 4, T, Q> const& Mat);
|
||||
|
||||
/// Build a interpolation of 4 * 4 matrixes.
|
||||
/// From GLM_GTX_matrix_interpolation extension.
|
||||
/// Warning! works only with rotation and/or translation matrixes, scale will generate unexpected results.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> interpolate(
|
||||
mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2, T const Delta);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "matrix_interpolation.inl"
|
||||
@@ -0,0 +1,146 @@
|
||||
/// @ref gtx_matrix_interpolation
|
||||
|
||||
#include "../ext/scalar_constants.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER void axisAngle(mat<4, 4, T, Q> const& m, vec<3, T, Q>& axis, T& angle)
|
||||
{
|
||||
T const epsilon =
|
||||
std::numeric_limits<T>::epsilon() * static_cast<T>(1e2);
|
||||
|
||||
bool const nearSymmetrical =
|
||||
abs(m[1][0] - m[0][1]) < epsilon &&
|
||||
abs(m[2][0] - m[0][2]) < epsilon &&
|
||||
abs(m[2][1] - m[1][2]) < epsilon;
|
||||
|
||||
if(nearSymmetrical)
|
||||
{
|
||||
bool const nearIdentity =
|
||||
abs(m[1][0] + m[0][1]) < epsilon &&
|
||||
abs(m[2][0] + m[0][2]) < epsilon &&
|
||||
abs(m[2][1] + m[1][2]) < epsilon &&
|
||||
abs(m[0][0] + m[1][1] + m[2][2] - T(3.0)) < epsilon;
|
||||
if (nearIdentity)
|
||||
{
|
||||
angle = static_cast<T>(0.0);
|
||||
axis = vec<3, T, Q>(
|
||||
static_cast<T>(1.0), static_cast<T>(0.0), static_cast<T>(0.0));
|
||||
return;
|
||||
}
|
||||
angle = pi<T>();
|
||||
T xx = (m[0][0] + static_cast<T>(1.0)) * static_cast<T>(0.5);
|
||||
T yy = (m[1][1] + static_cast<T>(1.0)) * static_cast<T>(0.5);
|
||||
T zz = (m[2][2] + static_cast<T>(1.0)) * static_cast<T>(0.5);
|
||||
T xy = (m[1][0] + m[0][1]) * static_cast<T>(0.25);
|
||||
T xz = (m[2][0] + m[0][2]) * static_cast<T>(0.25);
|
||||
T yz = (m[2][1] + m[1][2]) * static_cast<T>(0.25);
|
||||
if((xx > yy) && (xx > zz))
|
||||
{
|
||||
if(xx < epsilon)
|
||||
{
|
||||
axis.x = static_cast<T>(0.0);
|
||||
axis.y = static_cast<T>(0.7071);
|
||||
axis.z = static_cast<T>(0.7071);
|
||||
}
|
||||
else
|
||||
{
|
||||
axis.x = sqrt(xx);
|
||||
axis.y = xy / axis.x;
|
||||
axis.z = xz / axis.x;
|
||||
}
|
||||
}
|
||||
else if (yy > zz)
|
||||
{
|
||||
if(yy < epsilon)
|
||||
{
|
||||
axis.x = static_cast<T>(0.7071);
|
||||
axis.y = static_cast<T>(0.0);
|
||||
axis.z = static_cast<T>(0.7071);
|
||||
}
|
||||
else
|
||||
{
|
||||
axis.y = sqrt(yy);
|
||||
axis.x = xy / axis.y;
|
||||
axis.z = yz / axis.y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (zz < epsilon)
|
||||
{
|
||||
axis.x = static_cast<T>(0.7071);
|
||||
axis.y = static_cast<T>(0.7071);
|
||||
axis.z = static_cast<T>(0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
axis.z = sqrt(zz);
|
||||
axis.x = xz / axis.z;
|
||||
axis.y = yz / axis.z;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
T const angleCos = (m[0][0] + m[1][1] + m[2][2] - static_cast<T>(1)) * static_cast<T>(0.5);
|
||||
if(angleCos >= static_cast<T>(1.0))
|
||||
{
|
||||
angle = static_cast<T>(0.0);
|
||||
}
|
||||
else if (angleCos <= static_cast<T>(-1.0))
|
||||
{
|
||||
angle = pi<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = acos(angleCos);
|
||||
}
|
||||
|
||||
axis = glm::normalize(glm::vec<3, T, Q>(
|
||||
m[1][2] - m[2][1], m[2][0] - m[0][2], m[0][1] - m[1][0]));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> axisAngleMatrix(vec<3, T, Q> const& axis, T const angle)
|
||||
{
|
||||
T c = cos(angle);
|
||||
T s = sin(angle);
|
||||
T t = static_cast<T>(1) - c;
|
||||
vec<3, T, Q> n = normalize(axis);
|
||||
|
||||
return mat<4, 4, T, Q>(
|
||||
t * n.x * n.x + c, t * n.x * n.y + n.z * s, t * n.x * n.z - n.y * s, static_cast<T>(0.0),
|
||||
t * n.x * n.y - n.z * s, t * n.y * n.y + c, t * n.y * n.z + n.x * s, static_cast<T>(0.0),
|
||||
t * n.x * n.z + n.y * s, t * n.y * n.z - n.x * s, t * n.z * n.z + c, static_cast<T>(0.0),
|
||||
static_cast<T>(0.0), static_cast<T>(0.0), static_cast<T>(0.0), static_cast<T>(1.0));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> extractMatrixRotation(mat<4, 4, T, Q> const& m)
|
||||
{
|
||||
return mat<4, 4, T, Q>(
|
||||
m[0][0], m[0][1], m[0][2], static_cast<T>(0.0),
|
||||
m[1][0], m[1][1], m[1][2], static_cast<T>(0.0),
|
||||
m[2][0], m[2][1], m[2][2], static_cast<T>(0.0),
|
||||
static_cast<T>(0.0), static_cast<T>(0.0), static_cast<T>(0.0), static_cast<T>(1.0));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> interpolate(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2, T const delta)
|
||||
{
|
||||
mat<4, 4, T, Q> m1rot = extractMatrixRotation(m1);
|
||||
mat<4, 4, T, Q> dltRotation = m2 * transpose(m1rot);
|
||||
vec<3, T, Q> dltAxis;
|
||||
T dltAngle;
|
||||
axisAngle(dltRotation, dltAxis, dltAngle);
|
||||
mat<4, 4, T, Q> out = axisAngleMatrix(dltAxis, dltAngle * delta) * m1rot;
|
||||
out[3][0] = m1[3][0] + delta * (m2[3][0] - m1[3][0]);
|
||||
out[3][1] = m1[3][1] + delta * (m2[3][1] - m1[3][1]);
|
||||
out[3][2] = m1[3][2] + delta * (m2[3][2] - m1[3][2]);
|
||||
return out;
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,117 @@
|
||||
/// @ref gtx_matrix_major_storage
|
||||
/// @file glm/gtx/matrix_major_storage.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_extented_min_max (dependence)
|
||||
///
|
||||
/// @defgroup gtx_matrix_major_storage GLM_GTX_matrix_major_storage
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/matrix_major_storage.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Build matrices with specific matrix order, row or column
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_matrix_major_storage is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_matrix_major_storage extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_matrix_major_storage
|
||||
/// @{
|
||||
|
||||
//! Build a row major matrix from row vectors.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<2, 2, T, Q> rowMajor2(
|
||||
vec<2, T, Q> const& v1,
|
||||
vec<2, T, Q> const& v2);
|
||||
|
||||
//! Build a row major matrix from other matrix.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<2, 2, T, Q> rowMajor2(
|
||||
mat<2, 2, T, Q> const& m);
|
||||
|
||||
//! Build a row major matrix from row vectors.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 3, T, Q> rowMajor3(
|
||||
vec<3, T, Q> const& v1,
|
||||
vec<3, T, Q> const& v2,
|
||||
vec<3, T, Q> const& v3);
|
||||
|
||||
//! Build a row major matrix from other matrix.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 3, T, Q> rowMajor3(
|
||||
mat<3, 3, T, Q> const& m);
|
||||
|
||||
//! Build a row major matrix from row vectors.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> rowMajor4(
|
||||
vec<4, T, Q> const& v1,
|
||||
vec<4, T, Q> const& v2,
|
||||
vec<4, T, Q> const& v3,
|
||||
vec<4, T, Q> const& v4);
|
||||
|
||||
//! Build a row major matrix from other matrix.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> rowMajor4(
|
||||
mat<4, 4, T, Q> const& m);
|
||||
|
||||
//! Build a column major matrix from column vectors.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<2, 2, T, Q> colMajor2(
|
||||
vec<2, T, Q> const& v1,
|
||||
vec<2, T, Q> const& v2);
|
||||
|
||||
//! Build a column major matrix from other matrix.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<2, 2, T, Q> colMajor2(
|
||||
mat<2, 2, T, Q> const& m);
|
||||
|
||||
//! Build a column major matrix from column vectors.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 3, T, Q> colMajor3(
|
||||
vec<3, T, Q> const& v1,
|
||||
vec<3, T, Q> const& v2,
|
||||
vec<3, T, Q> const& v3);
|
||||
|
||||
//! Build a column major matrix from other matrix.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 3, T, Q> colMajor3(
|
||||
mat<3, 3, T, Q> const& m);
|
||||
|
||||
//! Build a column major matrix from column vectors.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> colMajor4(
|
||||
vec<4, T, Q> const& v1,
|
||||
vec<4, T, Q> const& v2,
|
||||
vec<4, T, Q> const& v3,
|
||||
vec<4, T, Q> const& v4);
|
||||
|
||||
//! Build a column major matrix from other matrix.
|
||||
//! From GLM_GTX_matrix_major_storage extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> colMajor4(
|
||||
mat<4, 4, T, Q> const& m);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "matrix_major_storage.inl"
|
||||
@@ -0,0 +1,166 @@
|
||||
/// @ref gtx_matrix_major_storage
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<2, 2, T, Q> rowMajor2
|
||||
(
|
||||
vec<2, T, Q> const& v1,
|
||||
vec<2, T, Q> const& v2
|
||||
)
|
||||
{
|
||||
mat<2, 2, T, Q> Result;
|
||||
Result[0][0] = v1.x;
|
||||
Result[1][0] = v1.y;
|
||||
Result[0][1] = v2.x;
|
||||
Result[1][1] = v2.y;
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<2, 2, T, Q> rowMajor2(
|
||||
const mat<2, 2, T, Q>& m)
|
||||
{
|
||||
mat<2, 2, T, Q> Result;
|
||||
Result[0][0] = m[0][0];
|
||||
Result[0][1] = m[1][0];
|
||||
Result[1][0] = m[0][1];
|
||||
Result[1][1] = m[1][1];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rowMajor3(
|
||||
const vec<3, T, Q>& v1,
|
||||
const vec<3, T, Q>& v2,
|
||||
const vec<3, T, Q>& v3)
|
||||
{
|
||||
mat<3, 3, T, Q> Result;
|
||||
Result[0][0] = v1.x;
|
||||
Result[1][0] = v1.y;
|
||||
Result[2][0] = v1.z;
|
||||
Result[0][1] = v2.x;
|
||||
Result[1][1] = v2.y;
|
||||
Result[2][1] = v2.z;
|
||||
Result[0][2] = v3.x;
|
||||
Result[1][2] = v3.y;
|
||||
Result[2][2] = v3.z;
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rowMajor3(
|
||||
const mat<3, 3, T, Q>& m)
|
||||
{
|
||||
mat<3, 3, T, Q> Result;
|
||||
Result[0][0] = m[0][0];
|
||||
Result[0][1] = m[1][0];
|
||||
Result[0][2] = m[2][0];
|
||||
Result[1][0] = m[0][1];
|
||||
Result[1][1] = m[1][1];
|
||||
Result[1][2] = m[2][1];
|
||||
Result[2][0] = m[0][2];
|
||||
Result[2][1] = m[1][2];
|
||||
Result[2][2] = m[2][2];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rowMajor4(
|
||||
const vec<4, T, Q>& v1,
|
||||
const vec<4, T, Q>& v2,
|
||||
const vec<4, T, Q>& v3,
|
||||
const vec<4, T, Q>& v4)
|
||||
{
|
||||
mat<4, 4, T, Q> Result;
|
||||
Result[0][0] = v1.x;
|
||||
Result[1][0] = v1.y;
|
||||
Result[2][0] = v1.z;
|
||||
Result[3][0] = v1.w;
|
||||
Result[0][1] = v2.x;
|
||||
Result[1][1] = v2.y;
|
||||
Result[2][1] = v2.z;
|
||||
Result[3][1] = v2.w;
|
||||
Result[0][2] = v3.x;
|
||||
Result[1][2] = v3.y;
|
||||
Result[2][2] = v3.z;
|
||||
Result[3][2] = v3.w;
|
||||
Result[0][3] = v4.x;
|
||||
Result[1][3] = v4.y;
|
||||
Result[2][3] = v4.z;
|
||||
Result[3][3] = v4.w;
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rowMajor4(
|
||||
const mat<4, 4, T, Q>& m)
|
||||
{
|
||||
mat<4, 4, T, Q> Result;
|
||||
Result[0][0] = m[0][0];
|
||||
Result[0][1] = m[1][0];
|
||||
Result[0][2] = m[2][0];
|
||||
Result[0][3] = m[3][0];
|
||||
Result[1][0] = m[0][1];
|
||||
Result[1][1] = m[1][1];
|
||||
Result[1][2] = m[2][1];
|
||||
Result[1][3] = m[3][1];
|
||||
Result[2][0] = m[0][2];
|
||||
Result[2][1] = m[1][2];
|
||||
Result[2][2] = m[2][2];
|
||||
Result[2][3] = m[3][2];
|
||||
Result[3][0] = m[0][3];
|
||||
Result[3][1] = m[1][3];
|
||||
Result[3][2] = m[2][3];
|
||||
Result[3][3] = m[3][3];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<2, 2, T, Q> colMajor2(
|
||||
const vec<2, T, Q>& v1,
|
||||
const vec<2, T, Q>& v2)
|
||||
{
|
||||
return mat<2, 2, T, Q>(v1, v2);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<2, 2, T, Q> colMajor2(
|
||||
const mat<2, 2, T, Q>& m)
|
||||
{
|
||||
return mat<2, 2, T, Q>(m);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> colMajor3(
|
||||
const vec<3, T, Q>& v1,
|
||||
const vec<3, T, Q>& v2,
|
||||
const vec<3, T, Q>& v3)
|
||||
{
|
||||
return mat<3, 3, T, Q>(v1, v2, v3);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> colMajor3(
|
||||
const mat<3, 3, T, Q>& m)
|
||||
{
|
||||
return mat<3, 3, T, Q>(m);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> colMajor4(
|
||||
const vec<4, T, Q>& v1,
|
||||
const vec<4, T, Q>& v2,
|
||||
const vec<4, T, Q>& v3,
|
||||
const vec<4, T, Q>& v4)
|
||||
{
|
||||
return mat<4, 4, T, Q>(v1, v2, v3, v4);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> colMajor4(
|
||||
const mat<4, 4, T, Q>& m)
|
||||
{
|
||||
return mat<4, 4, T, Q>(m);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,101 @@
|
||||
/// @ref gtx_matrix_operation
|
||||
/// @file glm/gtx/matrix_operation.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_matrix_operation GLM_GTX_matrix_operation
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/matrix_operation.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Build diagonal matrices from vectors.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_matrix_operation is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_matrix_operation extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_matrix_operation
|
||||
/// @{
|
||||
|
||||
//! Build a diagonal matrix.
|
||||
//! From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<2, 2, T, Q> diagonal2x2(
|
||||
vec<2, T, Q> const& v);
|
||||
|
||||
//! Build a diagonal matrix.
|
||||
//! From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<2, 3, T, Q> diagonal2x3(
|
||||
vec<2, T, Q> const& v);
|
||||
|
||||
//! Build a diagonal matrix.
|
||||
//! From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<2, 4, T, Q> diagonal2x4(
|
||||
vec<2, T, Q> const& v);
|
||||
|
||||
//! Build a diagonal matrix.
|
||||
//! From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 2, T, Q> diagonal3x2(
|
||||
vec<2, T, Q> const& v);
|
||||
|
||||
//! Build a diagonal matrix.
|
||||
//! From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 3, T, Q> diagonal3x3(
|
||||
vec<3, T, Q> const& v);
|
||||
|
||||
//! Build a diagonal matrix.
|
||||
//! From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 4, T, Q> diagonal3x4(
|
||||
vec<3, T, Q> const& v);
|
||||
|
||||
//! Build a diagonal matrix.
|
||||
//! From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 2, T, Q> diagonal4x2(
|
||||
vec<2, T, Q> const& v);
|
||||
|
||||
//! Build a diagonal matrix.
|
||||
//! From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 3, T, Q> diagonal4x3(
|
||||
vec<3, T, Q> const& v);
|
||||
|
||||
//! Build a diagonal matrix.
|
||||
//! From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> diagonal4x4(
|
||||
vec<4, T, Q> const& v);
|
||||
|
||||
/// Build an adjugate matrix.
|
||||
/// From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<2, 2, T, Q> adjugate(mat<2, 2, T, Q> const& m);
|
||||
|
||||
/// Build an adjugate matrix.
|
||||
/// From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 3, T, Q> adjugate(mat<3, 3, T, Q> const& m);
|
||||
|
||||
/// Build an adjugate matrix.
|
||||
/// From GLM_GTX_matrix_operation extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> adjugate(mat<4, 4, T, Q> const& m);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "matrix_operation.inl"
|
||||
@@ -0,0 +1,176 @@
|
||||
/// @ref gtx_matrix_operation
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<2, 2, T, Q> diagonal2x2
|
||||
(
|
||||
vec<2, T, Q> const& v
|
||||
)
|
||||
{
|
||||
mat<2, 2, T, Q> Result(static_cast<T>(1));
|
||||
Result[0][0] = v[0];
|
||||
Result[1][1] = v[1];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<2, 3, T, Q> diagonal2x3
|
||||
(
|
||||
vec<2, T, Q> const& v
|
||||
)
|
||||
{
|
||||
mat<2, 3, T, Q> Result(static_cast<T>(1));
|
||||
Result[0][0] = v[0];
|
||||
Result[1][1] = v[1];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<2, 4, T, Q> diagonal2x4
|
||||
(
|
||||
vec<2, T, Q> const& v
|
||||
)
|
||||
{
|
||||
mat<2, 4, T, Q> Result(static_cast<T>(1));
|
||||
Result[0][0] = v[0];
|
||||
Result[1][1] = v[1];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 2, T, Q> diagonal3x2
|
||||
(
|
||||
vec<2, T, Q> const& v
|
||||
)
|
||||
{
|
||||
mat<3, 2, T, Q> Result(static_cast<T>(1));
|
||||
Result[0][0] = v[0];
|
||||
Result[1][1] = v[1];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> diagonal3x3
|
||||
(
|
||||
vec<3, T, Q> const& v
|
||||
)
|
||||
{
|
||||
mat<3, 3, T, Q> Result(static_cast<T>(1));
|
||||
Result[0][0] = v[0];
|
||||
Result[1][1] = v[1];
|
||||
Result[2][2] = v[2];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 4, T, Q> diagonal3x4
|
||||
(
|
||||
vec<3, T, Q> const& v
|
||||
)
|
||||
{
|
||||
mat<3, 4, T, Q> Result(static_cast<T>(1));
|
||||
Result[0][0] = v[0];
|
||||
Result[1][1] = v[1];
|
||||
Result[2][2] = v[2];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> diagonal4x4
|
||||
(
|
||||
vec<4, T, Q> const& v
|
||||
)
|
||||
{
|
||||
mat<4, 4, T, Q> Result(static_cast<T>(1));
|
||||
Result[0][0] = v[0];
|
||||
Result[1][1] = v[1];
|
||||
Result[2][2] = v[2];
|
||||
Result[3][3] = v[3];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 3, T, Q> diagonal4x3
|
||||
(
|
||||
vec<3, T, Q> const& v
|
||||
)
|
||||
{
|
||||
mat<4, 3, T, Q> Result(static_cast<T>(1));
|
||||
Result[0][0] = v[0];
|
||||
Result[1][1] = v[1];
|
||||
Result[2][2] = v[2];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 2, T, Q> diagonal4x2
|
||||
(
|
||||
vec<2, T, Q> const& v
|
||||
)
|
||||
{
|
||||
mat<4, 2, T, Q> Result(static_cast<T>(1));
|
||||
Result[0][0] = v[0];
|
||||
Result[1][1] = v[1];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<2, 2, T, Q> adjugate(mat<2, 2, T, Q> const& m)
|
||||
{
|
||||
return mat<2, 2, T, Q>(
|
||||
+m[1][1], -m[0][1],
|
||||
-m[1][0], +m[0][0]);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> adjugate(mat<3, 3, T, Q> const& m)
|
||||
{
|
||||
T const m00 = determinant(mat<2, 2, T, Q>(m[1][1], m[2][1], m[1][2], m[2][2]));
|
||||
T const m01 = determinant(mat<2, 2, T, Q>(m[0][1], m[2][1], m[0][2], m[2][2]));
|
||||
T const m02 = determinant(mat<2, 2, T, Q>(m[0][1], m[1][1], m[0][2], m[1][2]));
|
||||
|
||||
T const m10 = determinant(mat<2, 2, T, Q>(m[1][0], m[2][0], m[1][2], m[2][2]));
|
||||
T const m11 = determinant(mat<2, 2, T, Q>(m[0][0], m[2][0], m[0][2], m[2][2]));
|
||||
T const m12 = determinant(mat<2, 2, T, Q>(m[0][0], m[1][0], m[0][2], m[1][2]));
|
||||
|
||||
T const m20 = determinant(mat<2, 2, T, Q>(m[1][0], m[2][0], m[1][1], m[2][1]));
|
||||
T const m21 = determinant(mat<2, 2, T, Q>(m[0][0], m[2][0], m[0][1], m[2][1]));
|
||||
T const m22 = determinant(mat<2, 2, T, Q>(m[0][0], m[1][0], m[0][1], m[1][1]));
|
||||
|
||||
return mat<3, 3, T, Q>(
|
||||
+m00, -m01, +m02,
|
||||
-m10, +m11, -m12,
|
||||
+m20, -m21, +m22);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> adjugate(mat<4, 4, T, Q> const& m)
|
||||
{
|
||||
T const m00 = determinant(mat<3, 3, T, Q>(m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3]));
|
||||
T const m01 = determinant(mat<3, 3, T, Q>(m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3]));
|
||||
T const m02 = determinant(mat<3, 3, T, Q>(m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3]));
|
||||
T const m03 = determinant(mat<3, 3, T, Q>(m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2]));
|
||||
|
||||
T const m10 = determinant(mat<3, 3, T, Q>(m[0][1], m[0][2], m[0][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3]));
|
||||
T const m11 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][2], m[0][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3]));
|
||||
T const m12 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3]));
|
||||
T const m13 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2]));
|
||||
|
||||
T const m20 = determinant(mat<3, 3, T, Q>(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[3][1], m[3][2], m[3][3]));
|
||||
T const m21 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[3][0], m[3][2], m[3][3]));
|
||||
T const m22 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3]));
|
||||
T const m23 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[3][0], m[3][1], m[3][2]));
|
||||
|
||||
T const m30 = determinant(mat<3, 3, T, Q>(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3]));
|
||||
T const m31 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3]));
|
||||
T const m32 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3]));
|
||||
T const m33 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2]));
|
||||
|
||||
return mat<4, 4, T, Q>(
|
||||
+m00, -m10, +m20, -m30,
|
||||
-m01, +m11, -m21, +m31,
|
||||
+m02, -m12, +m22, -m32,
|
||||
-m03, +m13, -m23, +m33);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,75 @@
|
||||
/// @ref gtx_matrix_query
|
||||
/// @file glm/gtx/matrix_query.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_vector_query (dependence)
|
||||
///
|
||||
/// @defgroup gtx_matrix_query GLM_GTX_matrix_query
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/matrix_query.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Query to evaluate matrix properties
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../gtx/vector_query.hpp"
|
||||
#include <limits>
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_matrix_query is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_matrix_query extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_matrix_query
|
||||
/// @{
|
||||
|
||||
/// Return whether a matrix a null matrix.
|
||||
/// From GLM_GTX_matrix_query extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL bool isNull(mat<2, 2, T, Q> const& m, T const& epsilon);
|
||||
|
||||
/// Return whether a matrix a null matrix.
|
||||
/// From GLM_GTX_matrix_query extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL bool isNull(mat<3, 3, T, Q> const& m, T const& epsilon);
|
||||
|
||||
/// Return whether a matrix is a null matrix.
|
||||
/// From GLM_GTX_matrix_query extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL bool isNull(mat<4, 4, T, Q> const& m, T const& epsilon);
|
||||
|
||||
/// Return whether a matrix is an identity matrix.
|
||||
/// From GLM_GTX_matrix_query extension.
|
||||
template<length_t C, length_t R, typename T, qualifier Q, template<length_t, length_t, typename, qualifier> class matType>
|
||||
GLM_FUNC_DECL bool isIdentity(matType<C, R, T, Q> const& m, T const& epsilon);
|
||||
|
||||
/// Return whether a matrix is a normalized matrix.
|
||||
/// From GLM_GTX_matrix_query extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL bool isNormalized(mat<2, 2, T, Q> const& m, T const& epsilon);
|
||||
|
||||
/// Return whether a matrix is a normalized matrix.
|
||||
/// From GLM_GTX_matrix_query extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL bool isNormalized(mat<3, 3, T, Q> const& m, T const& epsilon);
|
||||
|
||||
/// Return whether a matrix is a normalized matrix.
|
||||
/// From GLM_GTX_matrix_query extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL bool isNormalized(mat<4, 4, T, Q> const& m, T const& epsilon);
|
||||
|
||||
/// Return whether a matrix is an orthonormalized matrix.
|
||||
/// From GLM_GTX_matrix_query extension.
|
||||
template<length_t C, length_t R, typename T, qualifier Q, template<length_t, length_t, typename, qualifier> class matType>
|
||||
GLM_FUNC_DECL bool isOrthogonal(matType<C, R, T, Q> const& m, T const& epsilon);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "matrix_query.inl"
|
||||
@@ -0,0 +1,119 @@
|
||||
/// @ref gtx_matrix_query
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool isNull(mat<2, 2, T, Q> const& m, T const& epsilon)
|
||||
{
|
||||
bool result = true;
|
||||
for(length_t i = 0; result && i < m.length() ; ++i)
|
||||
result = isNull(m[i], epsilon);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool isNull(mat<3, 3, T, Q> const& m, T const& epsilon)
|
||||
{
|
||||
bool result = true;
|
||||
for(length_t i = 0; result && i < m.length() ; ++i)
|
||||
result = isNull(m[i], epsilon);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool isNull(mat<4, 4, T, Q> const& m, T const& epsilon)
|
||||
{
|
||||
bool result = true;
|
||||
for(length_t i = 0; result && i < m.length() ; ++i)
|
||||
result = isNull(m[i], epsilon);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool isIdentity(mat<C, R, T, Q> const& m, T const& epsilon)
|
||||
{
|
||||
bool result = true;
|
||||
for(length_t i = 0; result && i < m.length(); ++i)
|
||||
{
|
||||
for(length_t j = 0; result && j < glm::min(i, m[0].length()); ++j)
|
||||
result = abs(m[i][j]) <= epsilon;
|
||||
if(result && i < m[0].length())
|
||||
result = abs(m[i][i] - 1) <= epsilon;
|
||||
for(length_t j = i + 1; result && j < m[0].length(); ++j)
|
||||
result = abs(m[i][j]) <= epsilon;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool isNormalized(mat<2, 2, T, Q> const& m, T const& epsilon)
|
||||
{
|
||||
bool result(true);
|
||||
for(length_t i = 0; result && i < m.length(); ++i)
|
||||
result = isNormalized(m[i], epsilon);
|
||||
for(length_t i = 0; result && i < m.length(); ++i)
|
||||
{
|
||||
typename mat<2, 2, T, Q>::col_type v;
|
||||
for(length_t j = 0; j < m.length(); ++j)
|
||||
v[j] = m[j][i];
|
||||
result = isNormalized(v, epsilon);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool isNormalized(mat<3, 3, T, Q> const& m, T const& epsilon)
|
||||
{
|
||||
bool result(true);
|
||||
for(length_t i = 0; result && i < m.length(); ++i)
|
||||
result = isNormalized(m[i], epsilon);
|
||||
for(length_t i = 0; result && i < m.length(); ++i)
|
||||
{
|
||||
typename mat<3, 3, T, Q>::col_type v;
|
||||
for(length_t j = 0; j < m.length(); ++j)
|
||||
v[j] = m[j][i];
|
||||
result = isNormalized(v, epsilon);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool isNormalized(mat<4, 4, T, Q> const& m, T const& epsilon)
|
||||
{
|
||||
bool result(true);
|
||||
for(length_t i = 0; result && i < m.length(); ++i)
|
||||
result = isNormalized(m[i], epsilon);
|
||||
for(length_t i = 0; result && i < m.length(); ++i)
|
||||
{
|
||||
typename mat<4, 4, T, Q>::col_type v;
|
||||
for(length_t j = 0; j < m.length(); ++j)
|
||||
v[j] = m[j][i];
|
||||
result = isNormalized(v, epsilon);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<length_t C, length_t R, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER bool isOrthogonal(mat<C, R, T, Q> const& m, T const& epsilon)
|
||||
{
|
||||
bool result = true;
|
||||
for(length_t i(0); result && i < m.length(); ++i)
|
||||
{
|
||||
result = isNormalized(m[i], epsilon);
|
||||
for(length_t j(i + 1); result && j < m.length(); ++j)
|
||||
result = abs(dot(m[i], m[j])) <= epsilon;
|
||||
}
|
||||
|
||||
if(result)
|
||||
{
|
||||
mat<C, R, T, Q> tmp = transpose(m);
|
||||
for(length_t i(0); result && i < m.length(); ++i)
|
||||
{
|
||||
result = isNormalized(tmp[i], epsilon);
|
||||
for(length_t j(i + 1); result && j < m.length(); ++j)
|
||||
result = abs(dot(tmp[i], tmp[j])) <= epsilon;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,79 @@
|
||||
/// @ref gtx_matrix_transform_2d
|
||||
/// @file glm/gtx/matrix_transform_2d.hpp
|
||||
/// @author Miguel Ángel Pérez Martínez
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_matrix_transform_2d GLM_GTX_matrix_transform_2d
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/matrix_transform_2d.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Defines functions that generate common 2d transformation matrices.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../mat3x3.hpp"
|
||||
#include "../vec2.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_matrix_transform_2d is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_matrix_transform_2d extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_matrix_transform_2d
|
||||
/// @{
|
||||
|
||||
/// Builds a translation 3 * 3 matrix created from a vector of 2 components.
|
||||
///
|
||||
/// @param m Input matrix multiplied by this translation matrix.
|
||||
/// @param v Coordinates of a translation vector.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> translate(
|
||||
mat<3, 3, T, Q> const& m,
|
||||
vec<2, T, Q> const& v);
|
||||
|
||||
/// Builds a rotation 3 * 3 matrix created from an angle.
|
||||
///
|
||||
/// @param m Input matrix multiplied by this translation matrix.
|
||||
/// @param angle Rotation angle expressed in radians.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rotate(
|
||||
mat<3, 3, T, Q> const& m,
|
||||
T angle);
|
||||
|
||||
/// Builds a scale 3 * 3 matrix created from a vector of 2 components.
|
||||
///
|
||||
/// @param m Input matrix multiplied by this translation matrix.
|
||||
/// @param v Coordinates of a scale vector.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> scale(
|
||||
mat<3, 3, T, Q> const& m,
|
||||
vec<2, T, Q> const& v);
|
||||
|
||||
/// Builds an horizontal (parallel to the x axis) shear 3 * 3 matrix.
|
||||
///
|
||||
/// @param m Input matrix multiplied by this translation matrix.
|
||||
/// @param y Shear factor.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearX(
|
||||
mat<3, 3, T, Q> const& m,
|
||||
T y);
|
||||
|
||||
/// Builds a vertical (parallel to the y axis) shear 3 * 3 matrix.
|
||||
///
|
||||
/// @param m Input matrix multiplied by this translation matrix.
|
||||
/// @param x Shear factor.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearY(
|
||||
mat<3, 3, T, Q> const& m,
|
||||
T x);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "matrix_transform_2d.inl"
|
||||
@@ -0,0 +1,68 @@
|
||||
/// @ref gtx_matrix_transform_2d
|
||||
/// @author Miguel Ángel Pérez Martínez
|
||||
|
||||
#include "../trigonometric.hpp"
|
||||
|
||||
namespace glm
|
||||
{
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> translate(
|
||||
mat<3, 3, T, Q> const& m,
|
||||
vec<2, T, Q> const& v)
|
||||
{
|
||||
mat<3, 3, T, Q> Result(m);
|
||||
Result[2] = m[0] * v[0] + m[1] * v[1] + m[2];
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rotate(
|
||||
mat<3, 3, T, Q> const& m,
|
||||
T angle)
|
||||
{
|
||||
T const a = angle;
|
||||
T const c = cos(a);
|
||||
T const s = sin(a);
|
||||
|
||||
mat<3, 3, T, Q> Result;
|
||||
Result[0] = m[0] * c + m[1] * s;
|
||||
Result[1] = m[0] * -s + m[1] * c;
|
||||
Result[2] = m[2];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> scale(
|
||||
mat<3, 3, T, Q> const& m,
|
||||
vec<2, T, Q> const& v)
|
||||
{
|
||||
mat<3, 3, T, Q> Result;
|
||||
Result[0] = m[0] * v[0];
|
||||
Result[1] = m[1] * v[1];
|
||||
Result[2] = m[2];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearX(
|
||||
mat<3, 3, T, Q> const& m,
|
||||
T y)
|
||||
{
|
||||
mat<3, 3, T, Q> Result(1);
|
||||
Result[0][1] = y;
|
||||
return m * Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearY(
|
||||
mat<3, 3, T, Q> const& m,
|
||||
T x)
|
||||
{
|
||||
mat<3, 3, T, Q> Result(1);
|
||||
Result[1][0] = x;
|
||||
return m * Result;
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,39 @@
|
||||
/// @ref gtx_mixed_product
|
||||
/// @file glm/gtx/mixed_product.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_mixed_product GLM_GTX_mixed_producte
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/mixed_product.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Mixed product of 3 vectors.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_mixed_product is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_mixed_product extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_mixed_product
|
||||
/// @{
|
||||
|
||||
/// @brief Mixed product of 3 vectors (from GLM_GTX_mixed_product extension)
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T mixedProduct(
|
||||
vec<3, T, Q> const& v1,
|
||||
vec<3, T, Q> const& v2,
|
||||
vec<3, T, Q> const& v3);
|
||||
|
||||
/// @}
|
||||
}// namespace glm
|
||||
|
||||
#include "mixed_product.inl"
|
||||
@@ -0,0 +1,15 @@
|
||||
/// @ref gtx_mixed_product
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T mixedProduct
|
||||
(
|
||||
vec<3, T, Q> const& v1,
|
||||
vec<3, T, Q> const& v2,
|
||||
vec<3, T, Q> const& v3
|
||||
)
|
||||
{
|
||||
return dot(cross(v1, v2), v3);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,85 @@
|
||||
/// @ref gtx_norm
|
||||
/// @file glm/gtx/norm.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_quaternion (dependence)
|
||||
/// @see gtx_component_wise (dependence)
|
||||
///
|
||||
/// @defgroup gtx_norm GLM_GTX_norm
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/norm.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Various ways to compute vector norms.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../geometric.hpp"
|
||||
#include "../gtx/component_wise.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_norm is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_norm extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_norm
|
||||
/// @{
|
||||
|
||||
/// Returns the squared length of x.
|
||||
/// From GLM_GTX_norm extension.
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T length2(vec<L, T, Q> const& x);
|
||||
|
||||
/// Returns the squared distance between p0 and p1, i.e., length2(p0 - p1).
|
||||
/// From GLM_GTX_norm extension.
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T distance2(vec<L, T, Q> const& p0, vec<L, T, Q> const& p1);
|
||||
|
||||
//! Returns the L1 norm between x and y.
|
||||
//! From GLM_GTX_norm extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T l1Norm(vec<3, T, Q> const& x, vec<3, T, Q> const& y);
|
||||
|
||||
//! Returns the L1 norm of v.
|
||||
//! From GLM_GTX_norm extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T l1Norm(vec<3, T, Q> const& v);
|
||||
|
||||
//! Returns the L2 norm between x and y.
|
||||
//! From GLM_GTX_norm extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T l2Norm(vec<3, T, Q> const& x, vec<3, T, Q> const& y);
|
||||
|
||||
//! Returns the L2 norm of v.
|
||||
//! From GLM_GTX_norm extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T l2Norm(vec<3, T, Q> const& x);
|
||||
|
||||
//! Returns the L norm between x and y.
|
||||
//! From GLM_GTX_norm extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T lxNorm(vec<3, T, Q> const& x, vec<3, T, Q> const& y, unsigned int Depth);
|
||||
|
||||
//! Returns the L norm of v.
|
||||
//! From GLM_GTX_norm extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T lxNorm(vec<3, T, Q> const& x, unsigned int Depth);
|
||||
|
||||
//! Returns the LMax norm between x and y.
|
||||
//! From GLM_GTX_norm extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T lMaxNorm(vec<3, T, Q> const& x, vec<3, T, Q> const& y);
|
||||
|
||||
//! Returns the LMax norm of v.
|
||||
//! From GLM_GTX_norm extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T lMaxNorm(vec<3, T, Q> const& x);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "norm.inl"
|
||||
@@ -0,0 +1,95 @@
|
||||
/// @ref gtx_norm
|
||||
|
||||
#include "../detail/qualifier.hpp"
|
||||
|
||||
namespace glm{
|
||||
namespace detail
|
||||
{
|
||||
template<length_t L, typename T, qualifier Q, bool Aligned>
|
||||
struct compute_length2
|
||||
{
|
||||
GLM_FUNC_QUALIFIER static T call(vec<L, T, Q> const& v)
|
||||
{
|
||||
return dot(v, v);
|
||||
}
|
||||
};
|
||||
}//namespace detail
|
||||
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType length2(genType x)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'length2' accepts only floating-point inputs");
|
||||
return x * x;
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T length2(vec<L, T, Q> const& v)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'length2' accepts only floating-point inputs");
|
||||
return detail::compute_length2<L, T, Q, detail::is_aligned<Q>::value>::call(v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T distance2(T p0, T p1)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'distance2' accepts only floating-point inputs");
|
||||
return length2(p1 - p0);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T distance2(vec<L, T, Q> const& p0, vec<L, T, Q> const& p1)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'distance2' accepts only floating-point inputs");
|
||||
return length2(p1 - p0);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T l1Norm(vec<3, T, Q> const& a, vec<3, T, Q> const& b)
|
||||
{
|
||||
return abs(b.x - a.x) + abs(b.y - a.y) + abs(b.z - a.z);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T l1Norm(vec<3, T, Q> const& v)
|
||||
{
|
||||
return abs(v.x) + abs(v.y) + abs(v.z);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T l2Norm(vec<3, T, Q> const& a, vec<3, T, Q> const& b
|
||||
)
|
||||
{
|
||||
return length(b - a);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T l2Norm(vec<3, T, Q> const& v)
|
||||
{
|
||||
return length(v);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T lxNorm(vec<3, T, Q> const& x, vec<3, T, Q> const& y, unsigned int Depth)
|
||||
{
|
||||
return pow(pow(abs(y.x - x.x), T(Depth)) + pow(abs(y.y - x.y), T(Depth)) + pow(abs(y.z - x.z), T(Depth)), T(1) / T(Depth));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T lxNorm(vec<3, T, Q> const& v, unsigned int Depth)
|
||||
{
|
||||
return pow(pow(abs(v.x), T(Depth)) + pow(abs(v.y), T(Depth)) + pow(abs(v.z), T(Depth)), T(1) / T(Depth));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T lMaxNorm(vec<3, T, Q> const& a, vec<3, T, Q> const& b)
|
||||
{
|
||||
return compMax(abs(b - a));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T lMaxNorm(vec<3, T, Q> const& v)
|
||||
{
|
||||
return compMax(abs(v));
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,39 @@
|
||||
/// @ref gtx_normal
|
||||
/// @file glm/gtx/normal.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_extented_min_max (dependence)
|
||||
///
|
||||
/// @defgroup gtx_normal GLM_GTX_normal
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/normal.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Compute the normal of a triangle.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_normal is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_normal extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_normal
|
||||
/// @{
|
||||
|
||||
/// Computes triangle normal from triangle points.
|
||||
///
|
||||
/// @see gtx_normal
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> triangleNormal(vec<3, T, Q> const& p1, vec<3, T, Q> const& p2, vec<3, T, Q> const& p3);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "normal.inl"
|
||||
@@ -0,0 +1,15 @@
|
||||
/// @ref gtx_normal
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> triangleNormal
|
||||
(
|
||||
vec<3, T, Q> const& p1,
|
||||
vec<3, T, Q> const& p2,
|
||||
vec<3, T, Q> const& p3
|
||||
)
|
||||
{
|
||||
return normalize(cross(p1 - p2, p1 - p3));
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,47 @@
|
||||
/// @ref gtx_normalize_dot
|
||||
/// @file glm/gtx/normalize_dot.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_fast_square_root (dependence)
|
||||
///
|
||||
/// @defgroup gtx_normalize_dot GLM_GTX_normalize_dot
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/normalize_dot.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Dot product of vectors that need to be normalize with a single square root.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../gtx/fast_square_root.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_normalize_dot is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_normalize_dot extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_normalize_dot
|
||||
/// @{
|
||||
|
||||
/// Normalize parameters and returns the dot product of x and y.
|
||||
/// It's faster that dot(normalize(x), normalize(y)).
|
||||
///
|
||||
/// @see gtx_normalize_dot extension.
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T normalizeDot(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
|
||||
|
||||
/// Normalize parameters and returns the dot product of x and y.
|
||||
/// Faster that dot(fastNormalize(x), fastNormalize(y)).
|
||||
///
|
||||
/// @see gtx_normalize_dot extension.
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T fastNormalizeDot(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "normalize_dot.inl"
|
||||
@@ -0,0 +1,16 @@
|
||||
/// @ref gtx_normalize_dot
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T normalizeDot(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
|
||||
{
|
||||
return glm::dot(x, y) * glm::inversesqrt(glm::dot(x, x) * glm::dot(y, y));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T fastNormalizeDot(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
|
||||
{
|
||||
return glm::dot(x, y) * glm::fastInverseSqrt(glm::dot(x, x) * glm::dot(y, y));
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,44 @@
|
||||
/// @ref gtx_number_precision
|
||||
/// @file glm/gtx/number_precision.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtc_type_precision (dependence)
|
||||
/// @see gtc_quaternion (dependence)
|
||||
///
|
||||
/// @defgroup gtx_number_precision GLM_GTX_number_precision
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/number_precision.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Defined size types.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../gtc/type_precision.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_number_precision is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_number_precision extension included")
|
||||
#endif
|
||||
|
||||
namespace glm{
|
||||
/////////////////////////////
|
||||
// Unsigned int vector types
|
||||
|
||||
/// @addtogroup gtx_number_precision
|
||||
/// @{
|
||||
|
||||
//////////////////////
|
||||
// Float matrix types
|
||||
|
||||
typedef f32 f32mat1; //!< \brief Single-qualifier floating-point scalar. (from GLM_GTX_number_precision extension)
|
||||
typedef f32 f32mat1x1; //!< \brief Single-qualifier floating-point scalar. (from GLM_GTX_number_precision extension)
|
||||
typedef f64 f64mat1; //!< \brief Double-qualifier floating-point scalar. (from GLM_GTX_number_precision extension)
|
||||
typedef f64 f64mat1x1; //!< \brief Double-qualifier floating-point scalar. (from GLM_GTX_number_precision extension)
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/// @ref gtx_optimum_pow
|
||||
/// @file glm/gtx/optimum_pow.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_optimum_pow GLM_GTX_optimum_pow
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/optimum_pow.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Integer exponentiation of power functions.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_optimum_pow is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_optimum_pow extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_optimum_pow
|
||||
/// @{
|
||||
|
||||
/// Returns x raised to the power of 2.
|
||||
///
|
||||
/// @see gtx_optimum_pow
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType pow2(genType const& x);
|
||||
|
||||
/// Returns x raised to the power of 3.
|
||||
///
|
||||
/// @see gtx_optimum_pow
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType pow3(genType const& x);
|
||||
|
||||
/// Returns x raised to the power of 4.
|
||||
///
|
||||
/// @see gtx_optimum_pow
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType pow4(genType const& x);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "optimum_pow.inl"
|
||||
@@ -0,0 +1,22 @@
|
||||
/// @ref gtx_optimum_pow
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType pow2(genType const& x)
|
||||
{
|
||||
return x * x;
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType pow3(genType const& x)
|
||||
{
|
||||
return x * x * x;
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType pow4(genType const& x)
|
||||
{
|
||||
return (x * x) * (x * x);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,47 @@
|
||||
/// @ref gtx_orthonormalize
|
||||
/// @file glm/gtx/orthonormalize.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_extented_min_max (dependence)
|
||||
///
|
||||
/// @defgroup gtx_orthonormalize GLM_GTX_orthonormalize
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/orthonormalize.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Orthonormalize matrices.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../vec3.hpp"
|
||||
#include "../mat3x3.hpp"
|
||||
#include "../geometric.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_orthonormalize is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_orthonormalize extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_orthonormalize
|
||||
/// @{
|
||||
|
||||
/// Returns the orthonormalized matrix of m.
|
||||
///
|
||||
/// @see gtx_orthonormalize
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<3, 3, T, Q> orthonormalize(mat<3, 3, T, Q> const& m);
|
||||
|
||||
/// Orthonormalizes x according y.
|
||||
///
|
||||
/// @see gtx_orthonormalize
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> orthonormalize(vec<3, T, Q> const& x, vec<3, T, Q> const& y);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "orthonormalize.inl"
|
||||
@@ -0,0 +1,29 @@
|
||||
/// @ref gtx_orthonormalize
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> orthonormalize(mat<3, 3, T, Q> const& m)
|
||||
{
|
||||
mat<3, 3, T, Q> r = m;
|
||||
|
||||
r[0] = normalize(r[0]);
|
||||
|
||||
T d0 = dot(r[0], r[1]);
|
||||
r[1] -= r[0] * d0;
|
||||
r[1] = normalize(r[1]);
|
||||
|
||||
T d1 = dot(r[1], r[2]);
|
||||
d0 = dot(r[0], r[2]);
|
||||
r[2] -= r[0] * d0 + r[1] * d1;
|
||||
r[2] = normalize(r[2]);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> orthonormalize(vec<3, T, Q> const& x, vec<3, T, Q> const& y)
|
||||
{
|
||||
return normalize(x - y * dot(y, x));
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,112 @@
|
||||
/// @ref gtx_pca
|
||||
/// @file glm/gtx/pca.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see ext_scalar_relational (dependence)
|
||||
///
|
||||
/// @defgroup gtx_pca GLM_GTX_pca
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/pca.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Implements functions required for fundamental 'princple component analysis' in 2D, 3D, and 4D:
|
||||
/// 1) Computing a covariance matrics from a list of _relative_ position vectors
|
||||
/// 2) Compute the eigenvalues and eigenvectors of the covariance matrics
|
||||
/// This is useful, e.g., to compute an object-aligned bounding box from vertices of an object.
|
||||
/// https://en.wikipedia.org/wiki/Principal_component_analysis
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// std::vector<glm::dvec3> ptData;
|
||||
/// // ... fill ptData with some point data, e.g. vertices
|
||||
///
|
||||
/// glm::dvec3 center = computeCenter(ptData);
|
||||
///
|
||||
/// glm::dmat3 covarMat = glm::computeCovarianceMatrix(ptData.data(), ptData.size(), center);
|
||||
///
|
||||
/// glm::dvec3 evals;
|
||||
/// glm::dmat3 evecs;
|
||||
/// int evcnt = glm::findEigenvaluesSymReal(covarMat, evals, evecs);
|
||||
///
|
||||
/// if(evcnt != 3)
|
||||
/// // ... error handling
|
||||
///
|
||||
/// glm::sortEigenvalues(evals, evecs);
|
||||
///
|
||||
/// // ... now evecs[0] points in the direction (symmetric) of the largest spatial distribution within ptData
|
||||
/// ```
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../ext/scalar_relational.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_pca is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_pca extension included")
|
||||
#endif
|
||||
|
||||
namespace glm {
|
||||
/// @addtogroup gtx_pca
|
||||
/// @{
|
||||
|
||||
/// Compute a covariance matrix form an array of relative coordinates `v` (e.g., relative to the center of gravity of the object)
|
||||
/// @param v Points to a memory holding `n` times vectors
|
||||
/// @param n Number of points in v
|
||||
template<length_t D, typename T, qualifier Q>
|
||||
GLM_INLINE mat<D, D, T, Q> computeCovarianceMatrix(vec<D, T, Q> const* v, size_t n);
|
||||
|
||||
/// Compute a covariance matrix form an array of absolute coordinates `v` and a precomputed center of gravity `c`
|
||||
/// @param v Points to a memory holding `n` times vectors
|
||||
/// @param n Number of points in v
|
||||
/// @param c Precomputed center of gravity
|
||||
template<length_t D, typename T, qualifier Q>
|
||||
GLM_INLINE mat<D, D, T, Q> computeCovarianceMatrix(vec<D, T, Q> const* v, size_t n, vec<D, T, Q> const& c);
|
||||
|
||||
/// Compute a covariance matrix form a pair of iterators `b` (begin) and `e` (end) of a container with relative coordinates (e.g., relative to the center of gravity of the object)
|
||||
/// Dereferencing an iterator of type I must yield a `vec<D, T, Q%gt;`
|
||||
template<length_t D, typename T, qualifier Q, typename I>
|
||||
GLM_FUNC_DECL mat<D, D, T, Q> computeCovarianceMatrix(I const& b, I const& e);
|
||||
|
||||
/// Compute a covariance matrix form a pair of iterators `b` (begin) and `e` (end) of a container with absolute coordinates and a precomputed center of gravity `c`
|
||||
/// Dereferencing an iterator of type I must yield a `vec<D, T, Q%gt;`
|
||||
template<length_t D, typename T, qualifier Q, typename I>
|
||||
GLM_FUNC_DECL mat<D, D, T, Q> computeCovarianceMatrix(I const& b, I const& e, vec<D, T, Q> const& c);
|
||||
|
||||
/// Assuming the provided covariance matrix `covarMat` is symmetric and real-valued, this function find the `D` Eigenvalues of the matrix, and also provides the corresponding Eigenvectors.
|
||||
/// Note: the data in `outEigenvalues` and `outEigenvectors` are in matching order, i.e. `outEigenvector[i]` is the Eigenvector of the Eigenvalue `outEigenvalue[i]`.
|
||||
/// This is a numeric implementation to find the Eigenvalues, using 'QL decomposition` (variant of QR decomposition: https://en.wikipedia.org/wiki/QR_decomposition).
|
||||
///
|
||||
/// @param[in] covarMat A symmetric, real-valued covariance matrix, e.g. computed from computeCovarianceMatrix
|
||||
/// @param[out] outEigenvalues Vector to receive the found eigenvalues
|
||||
/// @param[out] outEigenvectors Matrix to receive the found eigenvectors corresponding to the found eigenvalues, as column vectors
|
||||
/// @return The number of eigenvalues found, usually D if the precondition of the covariance matrix is met.
|
||||
template<length_t D, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL unsigned int findEigenvaluesSymReal
|
||||
(
|
||||
mat<D, D, T, Q> const& covarMat,
|
||||
vec<D, T, Q>& outEigenvalues,
|
||||
mat<D, D, T, Q>& outEigenvectors
|
||||
);
|
||||
|
||||
/// Sorts a group of Eigenvalues&Eigenvectors, for largest Eigenvalue to smallest Eigenvalue.
|
||||
/// The data in `outEigenvalues` and `outEigenvectors` are assumed to be matching order, i.e. `outEigenvector[i]` is the Eigenvector of the Eigenvalue `outEigenvalue[i]`.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL void sortEigenvalues(vec<2, T, Q>& eigenvalues, mat<2, 2, T, Q>& eigenvectors);
|
||||
|
||||
/// Sorts a group of Eigenvalues&Eigenvectors, for largest Eigenvalue to smallest Eigenvalue.
|
||||
/// The data in `outEigenvalues` and `outEigenvectors` are assumed to be matching order, i.e. `outEigenvector[i]` is the Eigenvector of the Eigenvalue `outEigenvalue[i]`.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL void sortEigenvalues(vec<3, T, Q>& eigenvalues, mat<3, 3, T, Q>& eigenvectors);
|
||||
|
||||
/// Sorts a group of Eigenvalues&Eigenvectors, for largest Eigenvalue to smallest Eigenvalue.
|
||||
/// The data in `outEigenvalues` and `outEigenvectors` are assumed to be matching order, i.e. `outEigenvector[i]` is the Eigenvector of the Eigenvalue `outEigenvalue[i]`.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DISCARD_DECL void sortEigenvalues(vec<4, T, Q>& eigenvalues, mat<4, 4, T, Q>& eigenvectors);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "pca.inl"
|
||||
@@ -0,0 +1,342 @@
|
||||
/// @ref gtx_pca
|
||||
|
||||
#ifndef GLM_HAS_CXX11_STL
|
||||
#include <algorithm>
|
||||
#endif
|
||||
#include <utility>
|
||||
|
||||
namespace glm {
|
||||
|
||||
|
||||
template<length_t D, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<D, D, T, Q> computeCovarianceMatrix(vec<D, T, Q> const* v, size_t n)
|
||||
{
|
||||
return computeCovarianceMatrix<D, T, Q, vec<D, T, Q> const*>(v, v + n);
|
||||
}
|
||||
|
||||
|
||||
template<length_t D, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<D, D, T, Q> computeCovarianceMatrix(vec<D, T, Q> const* v, size_t n, vec<D, T, Q> const& c)
|
||||
{
|
||||
return computeCovarianceMatrix<D, T, Q, vec<D, T, Q> const*>(v, v + n, c);
|
||||
}
|
||||
|
||||
|
||||
template<length_t D, typename T, qualifier Q, typename I>
|
||||
GLM_FUNC_QUALIFIER mat<D, D, T, Q> computeCovarianceMatrix(I const& b, I const& e)
|
||||
{
|
||||
glm::mat<D, D, T, Q> m(0);
|
||||
|
||||
size_t cnt = 0;
|
||||
for(I i = b; i != e; i++)
|
||||
{
|
||||
vec<D, T, Q> const& v = *i;
|
||||
for(length_t x = 0; x < D; ++x)
|
||||
for(length_t y = 0; y < D; ++y)
|
||||
m[x][y] += static_cast<T>(v[x] * v[y]);
|
||||
cnt++;
|
||||
}
|
||||
if(cnt > 0)
|
||||
m /= static_cast<T>(cnt);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
template<length_t D, typename T, qualifier Q, typename I>
|
||||
GLM_FUNC_QUALIFIER mat<D, D, T, Q> computeCovarianceMatrix(I const& b, I const& e, vec<D, T, Q> const& c)
|
||||
{
|
||||
glm::mat<D, D, T, Q> m(0);
|
||||
glm::vec<D, T, Q> v;
|
||||
|
||||
size_t cnt = 0;
|
||||
for(I i = b; i != e; i++)
|
||||
{
|
||||
v = *i - c;
|
||||
for(length_t x = 0; x < D; ++x)
|
||||
for(length_t y = 0; y < D; ++y)
|
||||
m[x][y] += static_cast<T>(v[x] * v[y]);
|
||||
cnt++;
|
||||
}
|
||||
if(cnt > 0)
|
||||
m /= static_cast<T>(cnt);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
namespace _internal_
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER static T transferSign(T const& v, T const& s)
|
||||
{
|
||||
return ((s) >= 0 ? glm::abs(v) : -glm::abs(v));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER static T pythag(T const& a, T const& b) {
|
||||
static const T epsilon = static_cast<T>(0.0000001);
|
||||
T absa = glm::abs(a);
|
||||
T absb = glm::abs(b);
|
||||
if(absa > absb) {
|
||||
absb /= absa;
|
||||
absb *= absb;
|
||||
return absa * glm::sqrt(static_cast<T>(1) + absb);
|
||||
}
|
||||
if(glm::equal<T>(absb, 0, epsilon)) return static_cast<T>(0);
|
||||
absa /= absb;
|
||||
absa *= absa;
|
||||
return absb * glm::sqrt(static_cast<T>(1) + absa);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<length_t D, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER unsigned int findEigenvaluesSymReal
|
||||
(
|
||||
mat<D, D, T, Q> const& covarMat,
|
||||
vec<D, T, Q>& outEigenvalues,
|
||||
mat<D, D, T, Q>& outEigenvectors
|
||||
)
|
||||
{
|
||||
using _internal_::transferSign;
|
||||
using _internal_::pythag;
|
||||
|
||||
T a[D * D]; // matrix -- input and workspace for algorithm (will be changed inplace)
|
||||
T d[D]; // diagonal elements
|
||||
T e[D]; // off-diagonal elements
|
||||
|
||||
for(length_t r = 0; r < D; r++)
|
||||
for(length_t c = 0; c < D; c++)
|
||||
a[(r) * D + (c)] = covarMat[c][r];
|
||||
|
||||
// 1. Householder reduction.
|
||||
length_t l, k, j, i;
|
||||
T scale, hh, h, g, f;
|
||||
static const T epsilon = static_cast<T>(0.0000001);
|
||||
|
||||
for(i = D; i >= 2; i--)
|
||||
{
|
||||
l = i - 1;
|
||||
h = scale = 0;
|
||||
if(l > 1)
|
||||
{
|
||||
for(k = 1; k <= l; k++)
|
||||
{
|
||||
scale += glm::abs(a[(i - 1) * D + (k - 1)]);
|
||||
}
|
||||
if(glm::equal<T>(scale, 0, epsilon))
|
||||
{
|
||||
e[i - 1] = a[(i - 1) * D + (l - 1)];
|
||||
}
|
||||
else
|
||||
{
|
||||
for(k = 1; k <= l; k++)
|
||||
{
|
||||
a[(i - 1) * D + (k - 1)] /= scale;
|
||||
h += a[(i - 1) * D + (k - 1)] * a[(i - 1) * D + (k - 1)];
|
||||
}
|
||||
f = a[(i - 1) * D + (l - 1)];
|
||||
g = ((f >= 0) ? -glm::sqrt(h) : glm::sqrt(h));
|
||||
e[i - 1] = scale * g;
|
||||
h -= f * g;
|
||||
a[(i - 1) * D + (l - 1)] = f - g;
|
||||
f = 0;
|
||||
for(j = 1; j <= l; j++)
|
||||
{
|
||||
a[(j - 1) * D + (i - 1)] = a[(i - 1) * D + (j - 1)] / h;
|
||||
g = 0;
|
||||
for(k = 1; k <= j; k++)
|
||||
{
|
||||
g += a[(j - 1) * D + (k - 1)] * a[(i - 1) * D + (k - 1)];
|
||||
}
|
||||
for(k = j + 1; k <= l; k++)
|
||||
{
|
||||
g += a[(k - 1) * D + (j - 1)] * a[(i - 1) * D + (k - 1)];
|
||||
}
|
||||
e[j - 1] = g / h;
|
||||
f += e[j - 1] * a[(i - 1) * D + (j - 1)];
|
||||
}
|
||||
hh = f / (h + h);
|
||||
for(j = 1; j <= l; j++)
|
||||
{
|
||||
f = a[(i - 1) * D + (j - 1)];
|
||||
e[j - 1] = g = e[j - 1] - hh * f;
|
||||
for(k = 1; k <= j; k++)
|
||||
{
|
||||
a[(j - 1) * D + (k - 1)] -= (f * e[k - 1] + g * a[(i - 1) * D + (k - 1)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
e[i - 1] = a[(i - 1) * D + (l - 1)];
|
||||
}
|
||||
d[i - 1] = h;
|
||||
}
|
||||
d[0] = 0;
|
||||
e[0] = 0;
|
||||
for(i = 1; i <= D; i++)
|
||||
{
|
||||
l = i - 1;
|
||||
if(!glm::equal<T>(d[i - 1], 0, epsilon))
|
||||
{
|
||||
for(j = 1; j <= l; j++)
|
||||
{
|
||||
g = 0;
|
||||
for(k = 1; k <= l; k++)
|
||||
{
|
||||
g += a[(i - 1) * D + (k - 1)] * a[(k - 1) * D + (j - 1)];
|
||||
}
|
||||
for(k = 1; k <= l; k++)
|
||||
{
|
||||
a[(k - 1) * D + (j - 1)] -= g * a[(k - 1) * D + (i - 1)];
|
||||
}
|
||||
}
|
||||
}
|
||||
d[i - 1] = a[(i - 1) * D + (i - 1)];
|
||||
a[(i - 1) * D + (i - 1)] = 1;
|
||||
for(j = 1; j <= l; j++)
|
||||
{
|
||||
a[(j - 1) * D + (i - 1)] = a[(i - 1) * D + (j - 1)] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Calculation of eigenvalues and eigenvectors (QL algorithm)
|
||||
length_t m, iter;
|
||||
T s, r, p, dd, c, b;
|
||||
const length_t MAX_ITER = 30;
|
||||
|
||||
for(i = 2; i <= D; i++)
|
||||
{
|
||||
e[i - 2] = e[i - 1];
|
||||
}
|
||||
e[D - 1] = 0;
|
||||
|
||||
for(l = 1; l <= D; l++)
|
||||
{
|
||||
iter = 0;
|
||||
do
|
||||
{
|
||||
for(m = l; m <= D - 1; m++)
|
||||
{
|
||||
dd = glm::abs(d[m - 1]) + glm::abs(d[m - 1 + 1]);
|
||||
if(glm::equal<T>(glm::abs(e[m - 1]) + dd, dd, epsilon))
|
||||
break;
|
||||
}
|
||||
if(m != l)
|
||||
{
|
||||
if(iter++ == MAX_ITER)
|
||||
{
|
||||
return 0; // Too many iterations in FindEigenvalues
|
||||
}
|
||||
g = (d[l - 1 + 1] - d[l - 1]) / (2 * e[l - 1]);
|
||||
r = pythag<T>(g, 1);
|
||||
g = d[m - 1] - d[l - 1] + e[l - 1] / (g + transferSign(r, g));
|
||||
s = c = 1;
|
||||
p = 0;
|
||||
for(i = m - 1; i >= l; i--)
|
||||
{
|
||||
f = s * e[i - 1];
|
||||
b = c * e[i - 1];
|
||||
e[i - 1 + 1] = r = pythag(f, g);
|
||||
if(glm::equal<T>(r, 0, epsilon))
|
||||
{
|
||||
d[i - 1 + 1] -= p;
|
||||
e[m - 1] = 0;
|
||||
break;
|
||||
}
|
||||
s = f / r;
|
||||
c = g / r;
|
||||
g = d[i - 1 + 1] - p;
|
||||
r = (d[i - 1] - g) * s + 2 * c * b;
|
||||
d[i - 1 + 1] = g + (p = s * r);
|
||||
g = c * r - b;
|
||||
for(k = 1; k <= D; k++)
|
||||
{
|
||||
f = a[(k - 1) * D + (i - 1 + 1)];
|
||||
a[(k - 1) * D + (i - 1 + 1)] = s * a[(k - 1) * D + (i - 1)] + c * f;
|
||||
a[(k - 1) * D + (i - 1)] = c * a[(k - 1) * D + (i - 1)] - s * f;
|
||||
}
|
||||
}
|
||||
if(glm::equal<T>(r, 0, epsilon) && (i >= l))
|
||||
continue;
|
||||
d[l - 1] -= p;
|
||||
e[l - 1] = g;
|
||||
e[m - 1] = 0;
|
||||
}
|
||||
} while(m != l);
|
||||
}
|
||||
|
||||
// 3. output
|
||||
for(i = 0; i < D; i++)
|
||||
outEigenvalues[i] = d[i];
|
||||
for(i = 0; i < D; i++)
|
||||
for(j = 0; j < D; j++)
|
||||
outEigenvectors[i][j] = a[(j) * D + (i)];
|
||||
|
||||
return D;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER void sortEigenvalues(vec<2, T, Q>& eigenvalues, mat<2, 2, T, Q>& eigenvectors)
|
||||
{
|
||||
if (eigenvalues[0] < eigenvalues[1])
|
||||
{
|
||||
std::swap(eigenvalues[0], eigenvalues[1]);
|
||||
std::swap(eigenvectors[0], eigenvectors[1]);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER void sortEigenvalues(vec<3, T, Q>& eigenvalues, mat<3, 3, T, Q>& eigenvectors)
|
||||
{
|
||||
if (eigenvalues[0] < eigenvalues[1])
|
||||
{
|
||||
std::swap(eigenvalues[0], eigenvalues[1]);
|
||||
std::swap(eigenvectors[0], eigenvectors[1]);
|
||||
}
|
||||
if (eigenvalues[0] < eigenvalues[2])
|
||||
{
|
||||
std::swap(eigenvalues[0], eigenvalues[2]);
|
||||
std::swap(eigenvectors[0], eigenvectors[2]);
|
||||
}
|
||||
if (eigenvalues[1] < eigenvalues[2])
|
||||
{
|
||||
std::swap(eigenvalues[1], eigenvalues[2]);
|
||||
std::swap(eigenvectors[1], eigenvectors[2]);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER void sortEigenvalues(vec<4, T, Q>& eigenvalues, mat<4, 4, T, Q>& eigenvectors)
|
||||
{
|
||||
if (eigenvalues[0] < eigenvalues[2])
|
||||
{
|
||||
std::swap(eigenvalues[0], eigenvalues[2]);
|
||||
std::swap(eigenvectors[0], eigenvectors[2]);
|
||||
}
|
||||
if (eigenvalues[1] < eigenvalues[3])
|
||||
{
|
||||
std::swap(eigenvalues[1], eigenvalues[3]);
|
||||
std::swap(eigenvectors[1], eigenvectors[3]);
|
||||
}
|
||||
if (eigenvalues[0] < eigenvalues[1])
|
||||
{
|
||||
std::swap(eigenvalues[0], eigenvalues[1]);
|
||||
std::swap(eigenvectors[0], eigenvectors[1]);
|
||||
}
|
||||
if (eigenvalues[2] < eigenvalues[3])
|
||||
{
|
||||
std::swap(eigenvalues[2], eigenvalues[3]);
|
||||
std::swap(eigenvectors[2], eigenvectors[3]);
|
||||
}
|
||||
if (eigenvalues[1] < eigenvalues[2])
|
||||
{
|
||||
std::swap(eigenvalues[1], eigenvalues[2]);
|
||||
std::swap(eigenvectors[1], eigenvectors[2]);
|
||||
}
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,39 @@
|
||||
/// @ref gtx_perpendicular
|
||||
/// @file glm/gtx/perpendicular.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_projection (dependence)
|
||||
///
|
||||
/// @defgroup gtx_perpendicular GLM_GTX_perpendicular
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/perpendicular.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Perpendicular of a vector from other one
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../gtx/projection.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_perpendicular is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_perpendicular extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_perpendicular
|
||||
/// @{
|
||||
|
||||
//! Projects x a perpendicular axis of Normal.
|
||||
//! From GLM_GTX_perpendicular extension.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType perp(genType const& x, genType const& Normal);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "perpendicular.inl"
|
||||
@@ -0,0 +1,10 @@
|
||||
/// @ref gtx_perpendicular
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType perp(genType const& x, genType const& Normal)
|
||||
{
|
||||
return x - proj(x, Normal);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,46 @@
|
||||
/// @ref gtx_polar_coordinates
|
||||
/// @file glm/gtx/polar_coordinates.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_polar_coordinates GLM_GTX_polar_coordinates
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/polar_coordinates.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Conversion from Euclidean space to polar space and revert.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_polar_coordinates is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_polar_coordinates extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_polar_coordinates
|
||||
/// @{
|
||||
|
||||
/// Convert Euclidean to Polar coordinates, x is the latitude, y the longitude and z the xz distance.
|
||||
///
|
||||
/// @see gtx_polar_coordinates
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> polar(
|
||||
vec<3, T, Q> const& euclidean);
|
||||
|
||||
/// Convert Polar to Euclidean coordinates.
|
||||
///
|
||||
/// @see gtx_polar_coordinates
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> euclidean(
|
||||
vec<2, T, Q> const& polar);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "polar_coordinates.inl"
|
||||
@@ -0,0 +1,36 @@
|
||||
/// @ref gtx_polar_coordinates
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> polar
|
||||
(
|
||||
vec<3, T, Q> const& euclidean
|
||||
)
|
||||
{
|
||||
T const Length(length(euclidean));
|
||||
vec<3, T, Q> const tmp(euclidean / Length);
|
||||
T const xz_dist(sqrt(tmp.x * tmp.x + tmp.z * tmp.z));
|
||||
|
||||
return vec<3, T, Q>(
|
||||
asin(tmp.y), // latitude
|
||||
atan(tmp.x, tmp.z), // longitude
|
||||
xz_dist); // xz distance
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> euclidean
|
||||
(
|
||||
vec<2, T, Q> const& polar
|
||||
)
|
||||
{
|
||||
T const latitude(polar.x);
|
||||
T const longitude(polar.y);
|
||||
|
||||
return vec<3, T, Q>(
|
||||
cos(latitude) * sin(longitude),
|
||||
sin(latitude),
|
||||
cos(latitude) * cos(longitude));
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,41 @@
|
||||
/// @ref gtx_projection
|
||||
/// @file glm/gtx/projection.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_projection GLM_GTX_projection
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/projection.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Projection of a vector to other one
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../geometric.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_projection is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_projection extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_projection
|
||||
/// @{
|
||||
|
||||
/// Projects x on Normal.
|
||||
///
|
||||
/// @param[in] x A vector to project
|
||||
/// @param[in] Normal A normal that doesn't need to be of unit length.
|
||||
///
|
||||
/// @see gtx_projection
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL genType proj(genType const& x, genType const& Normal);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "projection.inl"
|
||||
@@ -0,0 +1,10 @@
|
||||
/// @ref gtx_projection
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType proj(genType const& x, genType const& Normal)
|
||||
{
|
||||
return glm::dot(x, Normal) / glm::dot(Normal, Normal) * Normal;
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,172 @@
|
||||
/// @ref gtx_quaternion
|
||||
/// @file glm/gtx/quaternion.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_extented_min_max (dependence)
|
||||
///
|
||||
/// @defgroup gtx_quaternion GLM_GTX_quaternion
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/quaternion.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Extended quaternion types and functions
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../gtc/constants.hpp"
|
||||
#include "../gtc/quaternion.hpp"
|
||||
#include "../ext/quaternion_exponential.hpp"
|
||||
#include "../gtx/norm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_quaternion is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_quaternion extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_quaternion
|
||||
/// @{
|
||||
|
||||
/// Create an identity quaternion.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q> quat_identity();
|
||||
|
||||
/// Compute a cross product between a quaternion and a vector.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> cross(
|
||||
qua<T, Q> const& q,
|
||||
vec<3, T, Q> const& v);
|
||||
|
||||
//! Compute a cross product between a vector and a quaternion.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> cross(
|
||||
vec<3, T, Q> const& v,
|
||||
qua<T, Q> const& q);
|
||||
|
||||
//! Compute a point on a path according squad equation.
|
||||
//! q1 and q2 are control points; s1 and s2 are intermediate control points.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> squad(
|
||||
qua<T, Q> const& q1,
|
||||
qua<T, Q> const& q2,
|
||||
qua<T, Q> const& s1,
|
||||
qua<T, Q> const& s2,
|
||||
T const& h);
|
||||
|
||||
//! Returns an intermediate control point for squad interpolation.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> intermediate(
|
||||
qua<T, Q> const& prev,
|
||||
qua<T, Q> const& curr,
|
||||
qua<T, Q> const& next);
|
||||
|
||||
//! Returns quarternion square root.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
//template<typename T, qualifier Q>
|
||||
//qua<T, Q> sqrt(
|
||||
// qua<T, Q> const& q);
|
||||
|
||||
//! Rotates a 3 components vector by a quaternion.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> rotate(
|
||||
qua<T, Q> const& q,
|
||||
vec<3, T, Q> const& v);
|
||||
|
||||
/// Rotates a 4 components vector by a quaternion.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, T, Q> rotate(
|
||||
qua<T, Q> const& q,
|
||||
vec<4, T, Q> const& v);
|
||||
|
||||
/// Extract the real component of a quaternion.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T extractRealComponent(
|
||||
qua<T, Q> const& q);
|
||||
|
||||
/// Converts a quaternion to a 3 * 3 matrix.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> toMat3(
|
||||
qua<T, Q> const& x){return mat3_cast(x);}
|
||||
|
||||
/// Converts a quaternion to a 4 * 4 matrix.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> toMat4(
|
||||
qua<T, Q> const& x){return mat4_cast(x);}
|
||||
|
||||
/// Converts a 3 * 3 matrix to a quaternion.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> toQuat(
|
||||
mat<3, 3, T, Q> const& x){return quat_cast(x);}
|
||||
|
||||
/// Converts a 4 * 4 matrix to a quaternion.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> toQuat(
|
||||
mat<4, 4, T, Q> const& x){return quat_cast(x);}
|
||||
|
||||
/// Quaternion interpolation using the rotation short path.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> shortMix(
|
||||
qua<T, Q> const& x,
|
||||
qua<T, Q> const& y,
|
||||
T const& a);
|
||||
|
||||
/// Quaternion normalized linear interpolation.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> fastMix(
|
||||
qua<T, Q> const& x,
|
||||
qua<T, Q> const& y,
|
||||
T const& a);
|
||||
|
||||
/// Compute the rotation between two vectors.
|
||||
/// @param orig vector, needs to be normalized
|
||||
/// @param dest vector, needs to be normalized
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> rotation(
|
||||
vec<3, T, Q> const& orig,
|
||||
vec<3, T, Q> const& dest);
|
||||
|
||||
/// Returns the squared length of x.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR T length2(qua<T, Q> const& q);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "quaternion.inl"
|
||||
@@ -0,0 +1,159 @@
|
||||
/// @ref gtx_quaternion
|
||||
|
||||
#include <limits>
|
||||
#include "../gtc/constants.hpp"
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> quat_identity()
|
||||
{
|
||||
return qua<T, Q>::wxyz(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> cross(vec<3, T, Q> const& v, qua<T, Q> const& q)
|
||||
{
|
||||
return inverse(q) * v;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> cross(qua<T, Q> const& q, vec<3, T, Q> const& v)
|
||||
{
|
||||
return q * v;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> squad
|
||||
(
|
||||
qua<T, Q> const& q1,
|
||||
qua<T, Q> const& q2,
|
||||
qua<T, Q> const& s1,
|
||||
qua<T, Q> const& s2,
|
||||
T const& h)
|
||||
{
|
||||
return mix(mix(q1, q2, h), mix(s1, s2, h), static_cast<T>(2) * (static_cast<T>(1) - h) * h);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> intermediate
|
||||
(
|
||||
qua<T, Q> const& prev,
|
||||
qua<T, Q> const& curr,
|
||||
qua<T, Q> const& next
|
||||
)
|
||||
{
|
||||
qua<T, Q> invQuat = inverse(curr);
|
||||
return exp((log(next * invQuat) + log(prev * invQuat)) / static_cast<T>(-4)) * curr;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<3, T, Q> rotate(qua<T, Q> const& q, vec<3, T, Q> const& v)
|
||||
{
|
||||
return q * v;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, T, Q> rotate(qua<T, Q> const& q, vec<4, T, Q> const& v)
|
||||
{
|
||||
return q * v;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T extractRealComponent(qua<T, Q> const& q)
|
||||
{
|
||||
T w = static_cast<T>(1) - q.x * q.x - q.y * q.y - q.z * q.z;
|
||||
if(w < T(0))
|
||||
return T(0);
|
||||
else
|
||||
return -sqrt(w);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T length2(qua<T, Q> const& q)
|
||||
{
|
||||
return q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> shortMix(qua<T, Q> const& x, qua<T, Q> const& y, T const& a)
|
||||
{
|
||||
if(a <= static_cast<T>(0)) return x;
|
||||
if(a >= static_cast<T>(1)) return y;
|
||||
|
||||
T fCos = dot(x, y);
|
||||
qua<T, Q> y2(y); //BUG!!! qua<T> y2;
|
||||
if(fCos < static_cast<T>(0))
|
||||
{
|
||||
y2 = -y;
|
||||
fCos = -fCos;
|
||||
}
|
||||
|
||||
//if(fCos > 1.0f) // problem
|
||||
T k0, k1;
|
||||
if(fCos > (static_cast<T>(1) - epsilon<T>()))
|
||||
{
|
||||
k0 = static_cast<T>(1) - a;
|
||||
k1 = static_cast<T>(0) + a; //BUG!!! 1.0f + a;
|
||||
}
|
||||
else
|
||||
{
|
||||
T fSin = sqrt(T(1) - fCos * fCos);
|
||||
T fAngle = atan(fSin, fCos);
|
||||
T fOneOverSin = static_cast<T>(1) / fSin;
|
||||
k0 = sin((static_cast<T>(1) - a) * fAngle) * fOneOverSin;
|
||||
k1 = sin((static_cast<T>(0) + a) * fAngle) * fOneOverSin;
|
||||
}
|
||||
|
||||
return qua<T, Q>::wxyz(
|
||||
k0 * x.w + k1 * y2.w,
|
||||
k0 * x.x + k1 * y2.x,
|
||||
k0 * x.y + k1 * y2.y,
|
||||
k0 * x.z + k1 * y2.z);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> fastMix(qua<T, Q> const& x, qua<T, Q> const& y, T const& a)
|
||||
{
|
||||
return glm::normalize(x * (static_cast<T>(1) - a) + (y * a));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> rotation(vec<3, T, Q> const& orig, vec<3, T, Q> const& dest)
|
||||
{
|
||||
T cosTheta = dot(orig, dest);
|
||||
vec<3, T, Q> rotationAxis;
|
||||
|
||||
if(cosTheta >= static_cast<T>(1) - epsilon<T>()) {
|
||||
// orig and dest point in the same direction
|
||||
return quat_identity<T,Q>();
|
||||
}
|
||||
|
||||
if(cosTheta < static_cast<T>(-1) + epsilon<T>())
|
||||
{
|
||||
// special case when vectors in opposite directions :
|
||||
// there is no "ideal" rotation axis
|
||||
// So guess one; any will do as long as it's perpendicular to start
|
||||
// This implementation favors a rotation around the Up axis (Y),
|
||||
// since it's often what you want to do.
|
||||
rotationAxis = cross(vec<3, T, Q>(0, 0, 1), orig);
|
||||
if(length2(rotationAxis) < epsilon<T>()) // bad luck, they were parallel, try again!
|
||||
rotationAxis = cross(vec<3, T, Q>(1, 0, 0), orig);
|
||||
|
||||
rotationAxis = normalize(rotationAxis);
|
||||
return angleAxis(pi<T>(), rotationAxis);
|
||||
}
|
||||
|
||||
// Implementation from Stan Melax's Game Programming Gems 1 article
|
||||
rotationAxis = cross(orig, dest);
|
||||
|
||||
T s = sqrt((T(1) + cosTheta) * static_cast<T>(2));
|
||||
T invs = static_cast<T>(1) / s;
|
||||
|
||||
return qua<T, Q>::wxyz(
|
||||
s * static_cast<T>(0.5f),
|
||||
rotationAxis.x * invs,
|
||||
rotationAxis.y * invs,
|
||||
rotationAxis.z * invs);
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,96 @@
|
||||
/// @ref gtx_range
|
||||
/// @file glm/gtx/range.hpp
|
||||
/// @author Joshua Moerman
|
||||
///
|
||||
/// @defgroup gtx_range GLM_GTX_range
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/range.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Defines begin and end for vectors and matrices. Useful for range-based for loop.
|
||||
/// The range is defined over the elements, not over columns or rows (e.g. mat4 has 16 elements).
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependencies
|
||||
#include "../detail/setup.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_range is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_range extension included")
|
||||
#endif
|
||||
|
||||
#include "../gtc/type_ptr.hpp"
|
||||
#include "../gtc/vec1.hpp"
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_range
|
||||
/// @{
|
||||
|
||||
# if GLM_COMPILER & GLM_COMPILER_VC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4100) // unreferenced formal parameter
|
||||
# endif
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
inline length_t components(vec<1, T, Q> const& v)
|
||||
{
|
||||
return v.length();
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
inline length_t components(vec<2, T, Q> const& v)
|
||||
{
|
||||
return v.length();
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
inline length_t components(vec<3, T, Q> const& v)
|
||||
{
|
||||
return v.length();
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
inline length_t components(vec<4, T, Q> const& v)
|
||||
{
|
||||
return v.length();
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
inline length_t components(genType const& m)
|
||||
{
|
||||
return m.length() * m[0].length();
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
inline typename genType::value_type const * begin(genType const& v)
|
||||
{
|
||||
return value_ptr(v);
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
inline typename genType::value_type const * end(genType const& v)
|
||||
{
|
||||
return begin(v) + components(v);
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
inline typename genType::value_type * begin(genType& v)
|
||||
{
|
||||
return value_ptr(v);
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
inline typename genType::value_type * end(genType& v)
|
||||
{
|
||||
return begin(v) + components(v);
|
||||
}
|
||||
|
||||
# if GLM_COMPILER & GLM_COMPILER_VC
|
||||
# pragma warning(pop)
|
||||
# endif
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,49 @@
|
||||
/// @ref gtx_raw_data
|
||||
/// @file glm/gtx/raw_data.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_raw_data GLM_GTX_raw_data
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/raw_data.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Projection of a vector to other one
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependencies
|
||||
#include "../ext/scalar_uint_sized.hpp"
|
||||
#include "../detail/setup.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_raw_data is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_raw_data extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_raw_data
|
||||
/// @{
|
||||
|
||||
//! Type for byte numbers.
|
||||
//! From GLM_GTX_raw_data extension.
|
||||
typedef detail::uint8 byte;
|
||||
|
||||
//! Type for word numbers.
|
||||
//! From GLM_GTX_raw_data extension.
|
||||
typedef detail::uint16 word;
|
||||
|
||||
//! Type for dword numbers.
|
||||
//! From GLM_GTX_raw_data extension.
|
||||
typedef detail::uint32 dword;
|
||||
|
||||
//! Type for qword numbers.
|
||||
//! From GLM_GTX_raw_data extension.
|
||||
typedef detail::uint64 qword;
|
||||
|
||||
/// @}
|
||||
}// namespace glm
|
||||
|
||||
#include "raw_data.inl"
|
||||
@@ -0,0 +1,2 @@
|
||||
/// @ref gtx_raw_data
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/// @ref gtx_rotate_normalized_axis
|
||||
/// @file glm/gtx/rotate_normalized_axis.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtc_matrix_transform
|
||||
/// @see gtc_quaternion
|
||||
///
|
||||
/// @defgroup gtx_rotate_normalized_axis GLM_GTX_rotate_normalized_axis
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/rotate_normalized_axis.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Quaternions and matrices rotations around normalized axis.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
#include "../gtc/epsilon.hpp"
|
||||
#include "../gtc/quaternion.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_rotate_normalized_axis is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_rotate_normalized_axis extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_rotate_normalized_axis
|
||||
/// @{
|
||||
|
||||
/// Builds a rotation 4 * 4 matrix created from a normalized axis and an angle.
|
||||
///
|
||||
/// @param m Input matrix multiplied by this rotation matrix.
|
||||
/// @param angle Rotation angle expressed in radians.
|
||||
/// @param axis Rotation axis, must be normalized.
|
||||
/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
|
||||
///
|
||||
/// @see gtx_rotate_normalized_axis
|
||||
/// @see - rotate(T angle, T x, T y, T z)
|
||||
/// @see - rotate(mat<4, 4, T, Q> const& m, T angle, T x, T y, T z)
|
||||
/// @see - rotate(T angle, vec<3, T, Q> const& v)
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> rotateNormalizedAxis(
|
||||
mat<4, 4, T, Q> const& m,
|
||||
T const& angle,
|
||||
vec<3, T, Q> const& axis);
|
||||
|
||||
/// Rotates a quaternion from a vector of 3 components normalized axis and an angle.
|
||||
///
|
||||
/// @param q Source orientation
|
||||
/// @param angle Angle expressed in radians.
|
||||
/// @param axis Normalized axis of the rotation, must be normalized.
|
||||
///
|
||||
/// @see gtx_rotate_normalized_axis
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> rotateNormalizedAxis(
|
||||
qua<T, Q> const& q,
|
||||
T const& angle,
|
||||
vec<3, T, Q> const& axis);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "rotate_normalized_axis.inl"
|
||||
@@ -0,0 +1,58 @@
|
||||
/// @ref gtx_rotate_normalized_axis
|
||||
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotateNormalizedAxis
|
||||
(
|
||||
mat<4, 4, T, Q> const& m,
|
||||
T const& angle,
|
||||
vec<3, T, Q> const& v
|
||||
)
|
||||
{
|
||||
T const a = angle;
|
||||
T const c = cos(a);
|
||||
T const s = sin(a);
|
||||
|
||||
vec<3, T, Q> const axis(v);
|
||||
|
||||
vec<3, T, Q> const temp((static_cast<T>(1) - c) * axis);
|
||||
|
||||
mat<4, 4, T, Q> Rotate;
|
||||
Rotate[0][0] = c + temp[0] * axis[0];
|
||||
Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2];
|
||||
Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1];
|
||||
|
||||
Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2];
|
||||
Rotate[1][1] = c + temp[1] * axis[1];
|
||||
Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0];
|
||||
|
||||
Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1];
|
||||
Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0];
|
||||
Rotate[2][2] = c + temp[2] * axis[2];
|
||||
|
||||
mat<4, 4, T, Q> Result;
|
||||
Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2];
|
||||
Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2];
|
||||
Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2];
|
||||
Result[3] = m[3];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> rotateNormalizedAxis
|
||||
(
|
||||
qua<T, Q> const& q,
|
||||
T const& angle,
|
||||
vec<3, T, Q> const& v
|
||||
)
|
||||
{
|
||||
vec<3, T, Q> const Tmp(v);
|
||||
|
||||
T const AngleRad(angle);
|
||||
T const Sin = sin(AngleRad * T(0.5));
|
||||
|
||||
return q * qua<T, Q>::wxyz(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
|
||||
//return gtc::quaternion::cross(q, tquat<T, Q>(cos(AngleRad * T(0.5)), Tmp.x * fSin, Tmp.y * fSin, Tmp.z * fSin));
|
||||
}
|
||||
}//namespace glm
|
||||
@@ -0,0 +1,121 @@
|
||||
/// @ref gtx_rotate_vector
|
||||
/// @file glm/gtx/rotate_vector.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
/// @see gtx_transform (dependence)
|
||||
///
|
||||
/// @defgroup gtx_rotate_vector GLM_GTX_rotate_vector
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/gtx/rotate_vector.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Function to directly rotate a vector
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../gtx/transform.hpp"
|
||||
#include "../gtc/epsilon.hpp"
|
||||
#include "../ext/vector_relational.hpp"
|
||||
#include "../glm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
# error "GLM: GLM_GTX_rotate_vector is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
|
||||
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTX_rotate_vector extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_rotate_vector
|
||||
/// @{
|
||||
|
||||
/// Returns Spherical interpolation between two vectors
|
||||
///
|
||||
/// @param x A first vector
|
||||
/// @param y A second vector
|
||||
/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
|
||||
///
|
||||
/// @see gtx_rotate_vector
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> slerp(
|
||||
vec<3, T, Q> const& x,
|
||||
vec<3, T, Q> const& y,
|
||||
T const& a);
|
||||
|
||||
//! Rotate a two dimensional vector.
|
||||
//! From GLM_GTX_rotate_vector extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<2, T, Q> rotate(
|
||||
vec<2, T, Q> const& v,
|
||||
T const& angle);
|
||||
|
||||
//! Rotate a three dimensional vector around an axis.
|
||||
//! From GLM_GTX_rotate_vector extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> rotate(
|
||||
vec<3, T, Q> const& v,
|
||||
T const& angle,
|
||||
vec<3, T, Q> const& normal);
|
||||
|
||||
//! Rotate a four dimensional vector around an axis.
|
||||
//! From GLM_GTX_rotate_vector extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, T, Q> rotate(
|
||||
vec<4, T, Q> const& v,
|
||||
T const& angle,
|
||||
vec<3, T, Q> const& normal);
|
||||
|
||||
//! Rotate a three dimensional vector around the X axis.
|
||||
//! From GLM_GTX_rotate_vector extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> rotateX(
|
||||
vec<3, T, Q> const& v,
|
||||
T const& angle);
|
||||
|
||||
//! Rotate a three dimensional vector around the Y axis.
|
||||
//! From GLM_GTX_rotate_vector extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> rotateY(
|
||||
vec<3, T, Q> const& v,
|
||||
T const& angle);
|
||||
|
||||
//! Rotate a three dimensional vector around the Z axis.
|
||||
//! From GLM_GTX_rotate_vector extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<3, T, Q> rotateZ(
|
||||
vec<3, T, Q> const& v,
|
||||
T const& angle);
|
||||
|
||||
//! Rotate a four dimensional vector around the X axis.
|
||||
//! From GLM_GTX_rotate_vector extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, T, Q> rotateX(
|
||||
vec<4, T, Q> const& v,
|
||||
T const& angle);
|
||||
|
||||
//! Rotate a four dimensional vector around the Y axis.
|
||||
//! From GLM_GTX_rotate_vector extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, T, Q> rotateY(
|
||||
vec<4, T, Q> const& v,
|
||||
T const& angle);
|
||||
|
||||
//! Rotate a four dimensional vector around the Z axis.
|
||||
//! From GLM_GTX_rotate_vector extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, T, Q> rotateZ(
|
||||
vec<4, T, Q> const& v,
|
||||
T const& angle);
|
||||
|
||||
//! Build a rotation matrix from a normal and a up vector.
|
||||
//! From GLM_GTX_rotate_vector extension.
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> orientation(
|
||||
vec<3, T, Q> const& Normal,
|
||||
vec<3, T, Q> const& Up);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "rotate_vector.inl"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user