mirror of
https://github.com/g-truc/glm.git
synced 2024-11-16 14:54:35 +00:00
Dedicated extension to represent angle values
Defines a dedicated type and operations for angles taking care of the radians/degrees issue and enforcing semantically sane usage. Applying these types consistently can prevent many problems related to conversions between degrees and radians. Furthermore it only supports operations which preserve the angle's dimension (under the assumption it is not dimensionless) allowing the compiler to detect misuses in equations. By not manually converting between degrees and radians everywhere in your program you can even gain some extra speed efficiency. Where ever you deal with angles (regardless if class members or function arguments) always use fangle/dangle and let it deal with the calculations necessary for radians/degrees conversions. Never again use a plain `float` in interfaces to represent angles or worry about these nuisances. The angle types should be no bigger than the datatype used for representation (if they are complain to your compiler vendor), are as efficient in copy and assignment operations as a native float or double, and can be safely passed by-value without fear of performance problems.
This commit is contained in:
parent
83409a0720
commit
c351089e9f
377
glm/gtx/angle.hpp
Normal file
377
glm/gtx/angle.hpp
Normal file
@ -0,0 +1,377 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// OpenGL Mathematics (glm.g-truc.net)
|
||||
///
|
||||
/// Copyright (c) 2005 - 2015 G-Truc Creation (www.g-truc.net)
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to deal
|
||||
/// in the Software without restriction, including without limitation the rights
|
||||
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
/// copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// Restrictions:
|
||||
/// By making use of the Software for military purposes, you choose to make
|
||||
/// a Bunny unhappy.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
/// THE SOFTWARE.
|
||||
///
|
||||
/// @ref gtx_associated_min_max
|
||||
/// @file glm/gtx/angle.hpp
|
||||
/// @date 2015-05-10
|
||||
/// @author Miroslav Knejp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup gtx_angle GLM_GTX_angle
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// @brief Defines a dedicated type and operations for angles taking care of the radians/degrees issue and enforcing semantically sane usage.
|
||||
///
|
||||
/// Applying these types consistently can prevent many problems related to
|
||||
/// conversions between degrees and radians. Furthermore it only supports
|
||||
/// operations which preserve the angle's dimension (under the assumption it is
|
||||
/// not dimensionless) allowing the compiler to detect misuses in equations. By
|
||||
/// not manually converting between degrees and radians everywhere in your
|
||||
/// program you can even gain some extra speed efficiency.
|
||||
///
|
||||
/// Where ever you deal with angles (regardless if class members or function
|
||||
/// arguments) always use fangle/dangle and let it deal with the calculations
|
||||
/// necessary for radians/degrees conversions. Never again use a plain `float`
|
||||
/// in interfaces to represent angles or worry about these nuisances.
|
||||
///
|
||||
/// The angle types should be no bigger than the datatype used for
|
||||
/// representation (if they are complain to your compiler vendor), are
|
||||
/// as efficient in copy and assignment operations as a native float or double,
|
||||
/// and can be safely passed by-value without fear of performance problems.
|
||||
///
|
||||
/// <glm/gtx/angle.hpp> needs to be included to use this functionality.
|
||||
///
|
||||
/// This extension also adds convenience overloads accepting angles instead of
|
||||
/// plain floats to the following extensions for improved semantic checking:
|
||||
/// - @ref gtc_matrix_transform
|
||||
/// - @ref gtc_quaternion
|
||||
/// - @ref gtx_fast_trigonometry
|
||||
/// - @ref gtx_matrix_interpolation
|
||||
/// - @ref gtx_matrix_transform_2d
|
||||
/// - @ref gtx_rotate_normalized_axis
|
||||
/// - @ref gtx_rotate_vector
|
||||
/// - @ref gtx_transform
|
||||
/// - @ref gtx_vector_angle
|
||||
/// In order to use these overloads the respective extension header must be
|
||||
/// included before <glm/gtx/angle.hpp> otherwise calling them fails to compile.
|
||||
/// This avoids making this extension implicitly dependent on those listed above.
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED))
|
||||
# pragma message("GLM: GLM_GTX_angle included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup gtx_angle
|
||||
/// @{
|
||||
|
||||
template<typename T, precision P = defaultp>
|
||||
class tangle;
|
||||
|
||||
//////////////////////////////////////
|
||||
// Explicit converting factory functions
|
||||
|
||||
/// Create an angle from radians
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle<T> rad(T radians);
|
||||
/// Create an angle from degrees
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle<T> deg(T degrees);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Explicit converting value access
|
||||
|
||||
/// Extract an angle's magnitude converted to radians
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR T rad(tangle<T, P> angle);
|
||||
/// Extract an angle's magnitude converted to degrees
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR T deg(tangle<T, P> angle);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Generic angle class defintion
|
||||
|
||||
template<typename T, precision P>
|
||||
class tangle
|
||||
{
|
||||
public:
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'angle' only accepts floating-point types");
|
||||
|
||||
typedef tangle<T, P> type;
|
||||
typedef T value_type;
|
||||
|
||||
//////////////////////////////////////
|
||||
// Implicit basic constructors
|
||||
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle();
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle(tangle<T, P> const & other);
|
||||
template <precision Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle(tangle<T, Q> const & other);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Explicit basic constructors
|
||||
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR explicit tangle(ctor);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Assignment (compound) operators
|
||||
|
||||
GLM_FUNC_DECL tvec4<T, P> & operator=(tangle<T, P> const & rhs);
|
||||
|
||||
template <typename U>
|
||||
GLM_FUNC_DECL tangle<T, P> & operator=(tangle<U, P> const & rhs);
|
||||
template <typename U>
|
||||
GLM_FUNC_DECL tangle<T, P> & operator+=(tangle<U, P> const & rhs);
|
||||
template <typename U>
|
||||
GLM_FUNC_DECL tangle<T, P> & operator-=(tangle<U, P> const & rhs);
|
||||
template <typename U>
|
||||
GLM_FUNC_DECL tangle<T, P> & operator*=(U rhs);
|
||||
template <typename U>
|
||||
GLM_FUNC_DECL tangle<T, P> & operator/=(U rhs);
|
||||
|
||||
private:
|
||||
friend GLM_CONSTEXPR tangle rad<T>(T radians);
|
||||
friend GLM_CONSTEXPR tangle deg<T>(T degrees);
|
||||
|
||||
friend GLM_CONSTEXPR T rad<T, P>(tangle radians);
|
||||
friend GLM_CONSTEXPR T deg<T, P>(tangle degrees);
|
||||
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle(T radians);
|
||||
|
||||
T _radians;
|
||||
};
|
||||
|
||||
typedef tangle<float> fangle; // angle is already taken :(
|
||||
typedef tangle<double> dangle;
|
||||
|
||||
//////////////////////////////////////
|
||||
// Unary arithmetic operators
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle<T, P> operator+(tangle<T, P> angle);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle<T, P> operator-(tangle<T, P> angle);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Binary arithmetic operators
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle<T, P> operator+(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle<T, P> operator-(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle<T, P> operator*(tangle<T, P> lhs, T rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle<T, P> operator*(T lhs, tangle<T, P> rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR tangle<T, P> operator/(tangle<T, P> lhs, T rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR T operator/(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Comparison operators
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR bool operator<=(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR bool operator>=(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR bool operator<(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR bool operator>(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Common functions
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> abs(tangle<T, P> arg);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> clamp(tangle<T, P> x, tangle<T, P> minVal, tangle<T, P> maxVal);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> max(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> min(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
template <typename T, precision P, typename U>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> mix(tangle<T, P> x, tangle<T, P> y, U a);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> mix(tangle<T, P> x, tangle<T, P> y, bool a);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> mod(tangle<T, P> lhs, tangle<T, P> rhs);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ T sign(tangle<T, P> arg);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Special angle functions
|
||||
|
||||
/// Normalize an angle's representation so lies within the interval [0; 2pi).
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> normalize(tangle<T, P> arg);
|
||||
/// Compute the shortest distance between two *normalized* angles, which is always in the range [-pi; +pi].
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> distance(tangle<T, P> from, tangle<T, P> to);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Trigonometric functions
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ T cos(tangle<T, P> arg);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ T sin(tangle<T, P> arg);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ T tan(tangle<T, P> arg);
|
||||
template <typename T>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T> atan2(T y, T x);
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> atan2(tvec2<T, P> const & v);
|
||||
// TODO: These conflict with existing GLM functions :(
|
||||
// template <typename T>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T> acos(T arg);
|
||||
// template <typename T>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T> asin(T arg);
|
||||
// template <typename T>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T> atan(T arg);
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTC_matrix_transform
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tmat4x4<T, P> infinitePerspective(tangle<T, P> fovy, T aspect, T near);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tmat4x4<T, P> perspective(tangle<T, P> fovy, T aspect, T near, T far);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tmat4x4<T, P> perspectiveFov(tangle<T, P> fov, T width, T height, T near, T far);
|
||||
template<typename T , precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tmat4x4<T, P> rotate(tmat4x4<T, P> const & m, tangle<T, P> angle, tvec3<T, P> const & axis);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tmat4x4<T, P> tweakedInfinitePerspective(tangle<T, P> fovy, T aspect, T near);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tmat4x4<T, P> tweakedInfinitePerspective(tangle<T, P> fovy, T aspect, T near, T ep);
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTC_quaternion
|
||||
|
||||
template<typename T, precision P>
|
||||
struct tquat;
|
||||
|
||||
// TODO: Some conflict with existing GTC functions :(
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> angle(tquat<T, P> const & q);
|
||||
template<typename T , precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tquat<T, P> angleAxis(tangle<T, P> angle, tvec3<T, P> const & axis);
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> pitch(tquat<T, P> const & q);
|
||||
template<typename T , precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tquat<T, P> rotate(tquat< T, P > const & q, tangle<T, P> angle, tvec3<T, P> const & axis);
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> roll(tquat<T, P> const & q);
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T, P> yaw(tquat<T, P> const & q);
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_fast_trigonometry
|
||||
|
||||
// TODO: Some conflict with existing GTX functions :(
|
||||
// template<typename T>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T> fastAcos(T x);
|
||||
// template<typename T>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T> fastAsin(T x);
|
||||
// template<typename T>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T> fastAtan(T y, T x);
|
||||
// template<typename T>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T> fastAtan(T x);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ T fastCos(tangle<T, P> angle);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ T fastSin(tangle<T, P> angle);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ T fastTan(tangle<T, P> angle);
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_matrix_interpolation
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL void axisAngle(tmat4x4<T, P> const & mat, tvec3<T, P> & axis, tangle<T, P> angle);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tmat4x4<T, P> axisAngleMatrix(tvec3<T, P> const & axis, tangle<T, P> angle);
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_matrix_transform_2d
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tmat3x3<T, P> rotate(tmat3x3<T, P> const & m, tangle<T, P> angle);
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_rotate_normalized_axis
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tmat4x4<T, P> rotateNormalizedAxis(tmat4x4<T, P> const & m, tangle<T, P> angle, tvec3<T, P> const & axis);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tquat<T, P> rotateNormalizedAxis(tquat<T, P> const & q, tangle<T, P> angle, tvec3<T, P> const & axis);
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_rotate_vector
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tvec2<T, P> rotate(tvec2<T, P> const & v, tangle<T, P> angle);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tvec3<T, P> rotate(tvec3<T, P> const & v, tangle<T, P> angle, tvec3<T, P> const & normal);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tvec4<T, P> rotate(tvec4<T, P> const & v, tangle<T, P> angle, tvec3<T, P> const & normal);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tvec3<T, P> rotateX(tvec3<T, P> const & v, tangle<T, P> angle);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tvec4<T, P> rotateX(tvec4<T, P> const & v, tangle<T, P> angle);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tvec3<T, P> rotateY(tvec3<T, P> const & v, tangle<T, P> angle);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tvec4<T, P> rotateY(tvec4<T, P> const & v, tangle<T, P> angle);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tvec3<T, P> rotateZ(tvec3<T, P> const & v, tangle<T, P> angle);
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tvec4<T, P> rotateZ(tvec4<T, P> const & v, tangle<T, P> angle);
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_transform
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tmat4x4< T, P > rotate(tangle<T, P> angle, tvec3< T, P > const & v);
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_vector_angle
|
||||
|
||||
// TODO: These conflict with existing GTX functions :(
|
||||
// template<typename vecType>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<vecType::value_type> angle(vecType const & x, vecType const & y);
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T> orientedAngle(tvec2<T, P> const & x, tvec2<T, P> const & y);
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_DECL /*GLM_CONSTEXPR*/ tangle<T> orientedAngle(tvec3<T, P> const & x, tvec3<T, P> const & y, tvec3<T, P> const &ref);
|
||||
|
||||
/// @}
|
||||
} // namespace glm
|
||||
|
||||
#include "angle.inl"
|
583
glm/gtx/angle.inl
Normal file
583
glm/gtx/angle.inl
Normal file
@ -0,0 +1,583 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// OpenGL Mathematics (glm.g-truc.net)
|
||||
///
|
||||
/// Copyright (c) 2005 - 2015 G-Truc Creation (www.g-truc.net)
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to deal
|
||||
/// in the Software without restriction, including without limitation the rights
|
||||
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
/// copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// Restrictions:
|
||||
/// By making use of the Software for military purposes, you choose to make
|
||||
/// a Bunny unhappy.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
/// THE SOFTWARE.
|
||||
///
|
||||
/// @ref gtx_angle
|
||||
/// @file glm/gtx/angle.inl
|
||||
/// @date 2015-05-10
|
||||
/// @author Miroslav Knejp
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace glm
|
||||
{
|
||||
//////////////////////////////////////
|
||||
// Implicit basic constructors
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P>::tangle()
|
||||
# ifndef GLM_FORCE_NO_CTOR_INIT
|
||||
: _radians(0)
|
||||
# endif
|
||||
{}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P>::tangle(tangle<T, P> const & other)
|
||||
: _radians(other._radians)
|
||||
{}
|
||||
|
||||
template <typename T, precision P>
|
||||
template <precision Q>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P>::tangle(tangle<T, Q> const & other)
|
||||
: _radians(other._radians)
|
||||
{}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Explicit basic constructors
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P>::tangle(ctor)
|
||||
{}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Assignment (compound) operators
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER tvec4<T, P> & tangle<T, P>::operator=(tangle<T, P> const & rhs)
|
||||
{
|
||||
this->_radians = rhs._radians;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
template <typename U>
|
||||
GLM_FUNC_QUALIFIER tangle<T, P> & tangle<T, P>::operator=(tangle<U, P> const & rhs)
|
||||
{
|
||||
this->_radians = static_cast<T>(rhs._radians);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
template <typename U>
|
||||
GLM_FUNC_QUALIFIER tangle<T, P> & tangle<T, P>::operator+=(tangle<U, P> const & rhs)
|
||||
{
|
||||
this->_radians += static_cast<T>(rhs._radians);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
template <typename U>
|
||||
GLM_FUNC_QUALIFIER tangle<T, P> & tangle<T, P>::operator-=(tangle<U, P> const & rhs)
|
||||
{
|
||||
this->_radians -= static_cast<T>(rhs._radians);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
template <typename U>
|
||||
GLM_FUNC_QUALIFIER tangle<T, P> & tangle<T, P>::operator*=(U rhs)
|
||||
{
|
||||
this->_radians *= static_cast<T>(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
template <typename U>
|
||||
GLM_FUNC_QUALIFIER tangle<T, P> & tangle<T, P>::operator/=(U rhs)
|
||||
{
|
||||
this->_radians /= static_cast<T>(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Explicit converting factory functions
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P>::tangle(T radians)
|
||||
: _radians(radians)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T> rad(T radians)
|
||||
{
|
||||
return tangle<T>(radians);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T> deg(T degrees)
|
||||
{
|
||||
// glm::radians is not constexpr
|
||||
return tangle<T>(degrees * static_cast<T>(0.01745329251994329576923690768489));
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Explicit converting value access
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T rad(tangle<T, P> angle)
|
||||
{
|
||||
return angle._radians;
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T deg(tangle<T, P> angle)
|
||||
{
|
||||
// glm::degrees is not constexpr
|
||||
return angle._radians * static_cast<T>(57.295779513082320876798154814105);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Unary arithmetic operators
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P> operator+(tangle<T, P> angle)
|
||||
{
|
||||
return angle;
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P> operator-(tangle<T, P> angle)
|
||||
{
|
||||
return rad(-rad(angle));
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Binary arithmetic operators
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P> operator+(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(rad(lhs) + rad(rhs));
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P> operator-(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(rad(lhs) - rad(rhs));
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P> operator*(tangle<T, P> lhs, T rhs)
|
||||
{
|
||||
return rad(rad(lhs) * rhs);
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P> operator*(T lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(lhs * rad(rhs));
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tangle<T, P> operator/(tangle<T, P> lhs, T rhs)
|
||||
{
|
||||
return rad(rad(lhs) / rhs);
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T operator/(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(lhs) / rad(rhs);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Comparison operators
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(lhs) == rad(rhs);
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(lhs) != rad(rhs);
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator<=(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(lhs) <= rad(rhs);
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator>=(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(lhs) >= rad(rhs);
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator<(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(lhs) < rad(rhs);
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator>(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(lhs) > rad(rhs);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Common functions
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> abs(tangle<T, P> arg)
|
||||
{
|
||||
return rad(abs(rad(arg)));
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> clamp(tangle<T, P> x, tangle<T, P> minVal, tangle<T, P> maxVal)
|
||||
{
|
||||
return rad(clamp(rad(x), rad(minVal), rad(maxVal)));
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> max(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(max(rad(lhs), rad(rhs)));
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> min(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(min(rad(lhs), rad(rhs)));
|
||||
}
|
||||
|
||||
template <typename T, precision P, typename U>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> mix(tangle<T, P> x, tangle<T, P> y, U a)
|
||||
{
|
||||
return rad(mix(rad(x), rad(y), a));
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> mix(tangle<T, P> x, tangle<T, P> y, bool a)
|
||||
{
|
||||
return a ? y : x;
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> mod(tangle<T, P> lhs, tangle<T, P> rhs)
|
||||
{
|
||||
return rad(mod(rad(lhs), rad(rhs)));
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ T sign(tangle<T, P> arg)
|
||||
{
|
||||
return sign(rad(arg));
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Special angle functions
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> normalize(tangle<T, P> arg)
|
||||
{
|
||||
tangle<T, P> x = mod(arg, deg(static_cast<T>(360)));
|
||||
return x < deg(static_cast<T>(0)) ? x + deg(static_cast<T>(360)) : x;
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> distance(tangle<T, P> from, tangle<T, P> to)
|
||||
{
|
||||
if(abs(to - from) > deg(static_cast<T>(180)))
|
||||
{
|
||||
return (from > to ? to + deg(static_cast<T>(360)) : to - deg(static_cast<T>(360))) - from;
|
||||
}
|
||||
else
|
||||
{
|
||||
return to - from;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Trigonometric functions
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ T cos(tangle<T, P> arg)
|
||||
{
|
||||
return std::cos(rad(arg));
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ T sin(tangle<T, P> arg)
|
||||
{
|
||||
return std::sin(rad(arg));
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ T tan(tangle<T, P> arg)
|
||||
{
|
||||
return std::tan(rad(arg));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T> atan2(T y, T x)
|
||||
{
|
||||
return rad(std::atan2(y, x));
|
||||
}
|
||||
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> atan2(tvec2<T, P> const & v)
|
||||
{
|
||||
return rad(std::atan2(v.y, v.x));
|
||||
}
|
||||
|
||||
// template <typename T>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T> acos(T arg)
|
||||
// {
|
||||
// return rad(std::acos(arg));
|
||||
// }
|
||||
//
|
||||
// template <typename T>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T> asin(T arg)
|
||||
// {
|
||||
// return rad(std::asin(arg));
|
||||
// }
|
||||
//
|
||||
// template <typename T>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T> atan(T arg)
|
||||
// {
|
||||
// return rad(std::atan(arg));
|
||||
// }
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTC_matrix_transform
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tmat4x4<T, P> infinitePerspective(tangle<T, P> fovy, T aspect, T near)
|
||||
{
|
||||
return infinitePerspective(rad(fovy), aspect, near);
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tmat4x4<T, P> perspective(tangle<T, P> fovy, T aspect, T near, T far)
|
||||
{
|
||||
return perspective(rad(fovy), aspect, near, far);
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tmat4x4<T, P> perspectiveFov(tangle<T, P> fov, T width, T height, T near, T far)
|
||||
{
|
||||
return prespectiveFov(rad(fov), width, height, near, far);
|
||||
}
|
||||
|
||||
template<typename T , precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tmat4x4<T, P> rotate(tmat4x4<T, P> const & m, tangle<T, P> angle, tvec3<T, P> const & axis)
|
||||
{
|
||||
return rotate(m, rad(angle), axis);
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tmat4x4<T, P> tweakedInfinitePerspective(tangle<T, P> fovy, T aspect, T near)
|
||||
{
|
||||
return tweakedInfinitePerspective(rad(fovy), aspect, near);
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tmat4x4<T, P> tweakedInfinitePerspective(tangle<T, P> fovy, T aspect, T near, T ep)
|
||||
{
|
||||
return tweakedInfinitePerspective(rad(fovy), aspect, near, ep);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTC_quaternion
|
||||
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> angle(tquat<T, P> const & q);
|
||||
|
||||
template<typename T , precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tquat<T, P> angleAxis(tangle<T, P> angle, tvec3<T, P> const & axis)
|
||||
{
|
||||
return angleAxis(rad(angle), axis);
|
||||
}
|
||||
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> pitch(tquat<T, P> const & q);
|
||||
|
||||
template<typename T , precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tquat<T, P> rotate(tquat< T, P > const & q, tangle<T, P> angle, tvec3<T, P> const & axis)
|
||||
{
|
||||
return rotate(q, rad(angle), axis);
|
||||
}
|
||||
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> roll(tquat<T, P> const & q);
|
||||
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T, P> yaw(tquat<T, P> const & q);
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_fast_trigonometry
|
||||
|
||||
// template<typename T>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T> fastAcos(T x);
|
||||
|
||||
// template<typename T>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T> fastAsin(T x);
|
||||
|
||||
// template<typename T>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T> fastAtan(T y, T x);
|
||||
|
||||
// template<typename T>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T> fastAtan(T x);
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ T fastCos(tangle<T, P> angle)
|
||||
{
|
||||
return fastCos(rad(angle));
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ T fastSin(tangle<T, P> angle)
|
||||
{
|
||||
return fastSin(rad(angle));
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ T fastTan(tangle<T, P> angle)
|
||||
{
|
||||
return fastTan(rad(angle));
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_matrix_interpolation
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER void axisAngle(tmat4x4<T, P> const & mat, tvec3<T, P> & axis, tangle<T, P> angle)
|
||||
{
|
||||
return axisAngle(mat, axis, rad(angle));
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tmat4x4<T, P> axisAngleMatrix(tvec3<T, P> const & axis, tangle<T, P> angle)
|
||||
{
|
||||
return axisAngleMatrix(axis, rad(angle));
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_matrix_transform_2d
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tmat3x3<T, P> rotate(tmat3x3<T, P> const & m, tangle<T, P> angle)
|
||||
{
|
||||
return rotate(m, rad(angle));
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_rotate_normalized_axis
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tmat4x4<T, P> rotateNormalizedAxis(tmat4x4<T, P> const & m, tangle<T, P> angle, tvec3<T, P> const & axis)
|
||||
{
|
||||
return rotateNormalizedAxis(m, rad(angle), axis);
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tquat<T, P> rotateNormalizedAxis(tquat<T, P> const & q, tangle<T, P> angle, tvec3<T, P> const & axis)
|
||||
{
|
||||
return rotateNormalizedAxis(q, rad(angle), axis);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_rotate_vector
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tvec2<T, P> rotate(tvec2<T, P> const & v, tangle<T, P> angle)
|
||||
{
|
||||
return rotate(v, rad(angle));
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tvec3<T, P> rotate(tvec3<T, P> const & v, tangle<T, P> angle, tvec3<T, P> const & normal)
|
||||
{
|
||||
return rotate(v, rad(angle), normal);
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tvec4<T, P> rotate(tvec4<T, P> const & v, tangle<T, P> angle, tvec3<T, P> const & normal)
|
||||
{
|
||||
return rotate(v, rad(angle), normal);
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tvec3<T, P> rotateX(tvec3<T, P> const & v, tangle<T, P> angle)
|
||||
{
|
||||
return rotateX(v, rad(angle));
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tvec4<T, P> rotateX(tvec4<T, P> const & v, tangle<T, P> angle)
|
||||
{
|
||||
return rotateX(v, rad(angle));
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tvec3<T, P> rotateY(tvec3<T, P> const & v, tangle<T, P> angle)
|
||||
{
|
||||
return rotateY(v, rad(angle));
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tvec4<T, P> rotateY(tvec4<T, P> const & v, tangle<T, P> angle)
|
||||
{
|
||||
return rotateY(v, rad(angle));
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tvec3<T, P> rotateZ(tvec3<T, P> const & v, tangle<T, P> angle)
|
||||
{
|
||||
return rotateZ(v, rad(angle));
|
||||
}
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tvec4<T, P> rotateZ(tvec4<T, P> const & v, tangle<T, P> angle)
|
||||
{
|
||||
return rotateZ(v, rad(angle));
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_transform
|
||||
|
||||
template<typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tmat4x4< T, P > rotate(tangle<T, P> angle, tvec3< T, P > const & v)
|
||||
{
|
||||
return rotate(rad(angle), v);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// GLM_GTX_vector_angle
|
||||
|
||||
// template<typename vecType>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<vecType::value_type> angle(vecType const & x, vecType const & y);
|
||||
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T> orientedAngle(tvec2<T, P> const & x, tvec2<T, P> const & y);
|
||||
|
||||
// template<typename T, precision P>
|
||||
// GLM_FUNC_QUALIFIER /*GLM_CONSTEXPR*/ tangle<T> orientedAngle(tvec3<T, P> const & x, tvec3<T, P> const & y, tvec3<T, P> const &ref);
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
glmCreateTestGTC(gtx_angle)
|
||||
glmCreateTestGTC(gtx_associated_min_max)
|
||||
glmCreateTestGTC(gtx_closest_point)
|
||||
glmCreateTestGTC(gtx_color_space_YCoCg)
|
||||
|
328
test/gtx/gtx_angle.cpp
Normal file
328
test/gtx/gtx_angle.cpp
Normal file
@ -0,0 +1,328 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// OpenGL Mathematics (glm.g-truc.net)
|
||||
///
|
||||
/// Copyright (c) 2005 - 2015 G-Truc Creation (www.g-truc.net)
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to deal
|
||||
/// in the Software without restriction, including without limitation the rights
|
||||
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
/// copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// Restrictions:
|
||||
/// By making use of the Software for military purposes, you choose to make
|
||||
/// a Bunny unhappy.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
/// THE SOFTWARE.
|
||||
///
|
||||
/// @file test/gtx/gtx_angle.cpp
|
||||
/// @date 2015-05-10
|
||||
/// @author Miroslav Knejp
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <glm/gtx/angle.hpp>
|
||||
#include <glm/gtc/epsilon.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
namespace
|
||||
{
|
||||
const float pi = glm::pi<float>();
|
||||
|
||||
int test_factory()
|
||||
{
|
||||
int Error(0);
|
||||
|
||||
{
|
||||
glm::fangle a = glm::rad(0.f);
|
||||
Error += glm::epsilonEqual(rad(a), 0.f, 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(deg(a), 0.f, 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::deg(0.f);
|
||||
Error += glm::epsilonEqual(rad(a), 0.f, 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(deg(a), 0.f, 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(pi);
|
||||
Error += glm::epsilonEqual(rad(a), pi, 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(deg(a), 180.f, 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::deg(180.f);
|
||||
Error += glm::epsilonEqual(rad(a), pi, 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(deg(a), 180.f, 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(-pi / 2);
|
||||
Error += glm::epsilonEqual(rad(a), -pi / 2, 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(deg(a), -90.f, 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::deg(-90.f);
|
||||
Error += glm::epsilonEqual(rad(a), -pi / 2, 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(deg(a), -90.f, 0.01f) ? 0 : 1;
|
||||
}
|
||||
return Error;
|
||||
}
|
||||
|
||||
int test_arithmetic()
|
||||
{
|
||||
int Error(0);
|
||||
float x = static_cast<float>(std::max(std::rand(), 1)) / RAND_MAX;
|
||||
float y = static_cast<float>(std::max(std::rand(), 1)) / RAND_MAX;
|
||||
|
||||
{
|
||||
glm::fangle a = glm::rad(x);
|
||||
glm::fangle b = glm::rad(y);
|
||||
Error += glm::epsilonEqual(x + y, rad(a + b), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(x - y, rad(a - b), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(x);
|
||||
Error += glm::epsilonEqual(y * x, rad(y * a), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(x * y, rad(a * y), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(x);
|
||||
Error += glm::epsilonEqual(x / y, rad(a / y), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(x);
|
||||
glm::fangle b = glm::rad(y);
|
||||
Error += glm::epsilonEqual(x / y, a / b, 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(x);
|
||||
Error += glm::epsilonEqual(+x, rad(+a), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(x);
|
||||
Error += glm::epsilonEqual(-x, rad(-a), 0.01f) ? 0 : 1;
|
||||
}
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
int test_comparison()
|
||||
{
|
||||
int Error(0);
|
||||
float x = -static_cast<float>(std::max(std::rand(), 1)) / RAND_MAX;
|
||||
float y = static_cast<float>(std::max(std::rand(), 1)) / RAND_MAX;
|
||||
|
||||
Error += glm::rad(x) == glm::rad(x) ? 0 : 1;
|
||||
Error += glm::rad(x) == glm::rad(y) ? 1 : 0;
|
||||
Error += glm::rad(x) != glm::rad(x) ? 1 : 0;
|
||||
Error += glm::rad(x) != glm::rad(y) ? 0 : 1;
|
||||
|
||||
Error += glm::rad(x) < glm::rad(x) ? 1 : 0;
|
||||
Error += glm::rad(x) < glm::rad(y) ? 0 : 1;
|
||||
|
||||
Error += glm::rad(x) > glm::rad(x) ? 1 : 0;
|
||||
Error += glm::rad(y) > glm::rad(x) ? 0 : 1;
|
||||
|
||||
Error += glm::rad(x) <= glm::rad(x) ? 0 : 1;
|
||||
Error += glm::rad(x) <= glm::rad(y) ? 0 : 1;
|
||||
|
||||
Error += glm::rad(x) >= glm::rad(x) ? 0 : 1;
|
||||
Error += glm::rad(y) >= glm::rad(x) ? 0 : 1;
|
||||
return Error;
|
||||
}
|
||||
|
||||
int test_constexpr()
|
||||
{
|
||||
int Error(0);
|
||||
|
||||
# if GLM_HAS_CONSTEXPR
|
||||
static_assert(std::is_literal_type<glm::fangle>::value, "");
|
||||
static_assert(std::is_literal_type<glm::angled>::value, "");
|
||||
|
||||
constexpr auto a = glm::deg(1.f);
|
||||
constexpr auto b = glm::rad(2.f);
|
||||
constexpr auto f = 3.f;
|
||||
|
||||
// Force compile-time evaluation
|
||||
static_assert((rad(a), true), "");
|
||||
static_assert((deg(a), true), "");
|
||||
|
||||
static_assert((+a, true), "");
|
||||
static_assert((-a, true), "");
|
||||
|
||||
static_assert((a + b, true), "");
|
||||
static_assert((a - b, true), "");
|
||||
static_assert((a * f, true), "");
|
||||
static_assert((f * b, true), "");
|
||||
static_assert((a / f, true), "");
|
||||
static_assert((a / b, true), "");
|
||||
|
||||
static_assert((a == b) || true, "");
|
||||
static_assert((a != b) || true, "");
|
||||
static_assert((a <= b) || true, "");
|
||||
static_assert((a >= b) || true, "");
|
||||
static_assert((a < b) || true, "");
|
||||
static_assert((a > b) || true, "");
|
||||
# endif
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
int test_common()
|
||||
{
|
||||
int Error(0);
|
||||
|
||||
float x = static_cast<float>(std::max(std::rand(), 1)) / RAND_MAX;
|
||||
float y = static_cast<float>(std::max(std::rand(), 1)) / RAND_MAX;
|
||||
float f = static_cast<float>(std::max(std::rand(), 1)) / RAND_MAX;
|
||||
{
|
||||
glm::fangle a = glm::rad(x);
|
||||
glm::fangle b = glm::rad(-x);
|
||||
Error += glm::epsilonEqual(x, rad(abs(b)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(rad(a), rad(abs(b)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(100.f);
|
||||
glm::fangle b = glm::rad(200.f);
|
||||
glm::fangle c = a - glm::rad(x);
|
||||
glm::fangle d = b + glm::rad(y);
|
||||
glm::fangle e = glm::rad(150.f);
|
||||
Error += clamp(c, a, b) <= b ? 0 : 1;
|
||||
Error += clamp(c, a, b) >= a ? 0 : 1;
|
||||
Error += clamp(d, a, b) <= b ? 0 : 1;
|
||||
Error += clamp(d, a, b) >= a ? 0 : 1;
|
||||
Error += glm::epsilonEqual(rad(clamp(e, a, b)), rad(e), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(x);
|
||||
glm::fangle b = glm::rad(y);
|
||||
Error += glm::epsilonEqual(std::max(x, y), rad(max(a, b)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(std::min(x, y), rad(min(a, b)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(x);
|
||||
glm::fangle b = glm::rad(y);
|
||||
Error += glm::epsilonEqual(glm::mix(x, y, f), rad(mix(a, b, f)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(x, rad(mix(a, b, false)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(y, rad(mix(a, b, true)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(x);
|
||||
glm::fangle b = glm::rad(y);
|
||||
Error += glm::epsilonEqual(glm::mod(x, y), rad(mod(a, b)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(glm::mod(y, x), rad(mod(b, a)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
Error += glm::epsilonEqual(1.f, sign(glm::rad(10.f)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(0.f, sign(glm::rad(0.f)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(-1.f, sign(glm::rad(-10.f)), 0.01f) ? 0 : 1;
|
||||
|
||||
Error += glm::epsilonEqual(1.f, sign(glm::deg(10.f)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(0.f, sign(glm::deg(0.f)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(-1.f, sign(glm::deg(-10.f)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
return Error;
|
||||
}
|
||||
|
||||
int test_special()
|
||||
{
|
||||
int Error(0);
|
||||
|
||||
{
|
||||
glm::fangle a = glm::rad(5 * pi);
|
||||
Error += glm::epsilonEqual(pi, rad(normalize(a)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(2 * pi);
|
||||
Error += glm::epsilonEqual(0.f, rad(normalize(a)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(-pi / 2);
|
||||
Error += glm::epsilonEqual(1.5f * pi, rad(normalize(a)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(-pi * 2);
|
||||
Error += glm::epsilonEqual(0.f, rad(normalize(a)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::rad(5 * -pi);
|
||||
Error += glm::epsilonEqual(pi, rad(normalize(a)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
|
||||
{
|
||||
glm::fangle a = glm::deg(0.f);
|
||||
glm::fangle b = glm::deg(90.f);
|
||||
Error += glm::epsilonEqual(90.f, deg(distance(a, b)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(-90.f, deg(distance(b, a)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::deg(0.f);
|
||||
glm::fangle b = glm::deg(180.f);
|
||||
Error += glm::epsilonEqual(180.f, deg(distance(a, b)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(-180.f, deg(distance(b, a)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::deg(0.f);
|
||||
glm::fangle b = glm::deg(270.f);
|
||||
Error += glm::epsilonEqual(-90.f, deg(distance(a, b)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(90.f, deg(distance(b, a)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::deg(0.f);
|
||||
glm::fangle b = glm::deg(360.f);
|
||||
Error += glm::epsilonEqual(0.f, deg(distance(a, b)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(0.f, deg(distance(b, a)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
{
|
||||
glm::fangle a = glm::deg(10.f);
|
||||
glm::fangle b = glm::deg(350.f);
|
||||
Error += glm::epsilonEqual(-20.f, deg(distance(a, b)), 0.01f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(20.f, deg(distance(b, a)), 0.01f) ? 0 : 1;
|
||||
}
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
int test_trigonometric()
|
||||
{
|
||||
int Error(0);
|
||||
|
||||
float x = static_cast<float>(std::rand());
|
||||
float y = static_cast<float>(std::rand());
|
||||
|
||||
{
|
||||
glm::fangle a = glm::rad(x);
|
||||
Error += glm::epsilonEqual(std::cos(x), cos(a), 0.0001f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(std::sin(x), sin(a), 0.0001f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(std::tan(x), tan(a), 0.0001f) ? 0 : 1;
|
||||
}
|
||||
Error += glm::epsilonEqual(std::atan2(y, x), rad(glm::atan2(y, x)), 0.0001f) ? 0 : 1;
|
||||
Error += glm::epsilonEqual(std::atan2(y, x), rad(glm::atan2(glm::vec2(x, y))), 0.0001f) ? 0 : 1;
|
||||
|
||||
return Error;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int Error(0);
|
||||
std::srand(std::time(NULL));
|
||||
|
||||
Error += test_factory();
|
||||
Error += test_comparison();
|
||||
Error += test_arithmetic();
|
||||
Error += test_constexpr();
|
||||
Error += test_common();
|
||||
Error += test_special();
|
||||
Error += test_trigonometric();
|
||||
|
||||
return Error;
|
||||
}
|
Loading…
Reference in New Issue
Block a user