瀏覽代碼

Sliced quaternions into multiple extensions

Christophe Riccio 7 年之前
父節點
當前提交
0e763af6e7

+ 0 - 12
glm/detail/type_quat.inl

@@ -209,18 +209,6 @@ namespace detail
 	}
 #	endif//GLM_HAS_EXPLICIT_CONVERSION_OPERATORS
 
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER qua<T, Q> conjugate(qua<T, Q> const& q)
-	{
-		return qua<T, Q>(q.w, -q.x, -q.y, -q.z);
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER qua<T, Q> inverse(qua<T, Q> const& q)
-	{
-		return conjugate(q) / dot(q, q);
-	}
-
 	// -- Unary arithmetic operators --
 
 #	if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE

+ 729 - 0
glm/ext/matrix_transform.hpp

@@ -0,0 +1,729 @@
+/// @ref ext_matrix_transform
+/// @file glm/ext/matrix_transform.hpp
+///
+/// @see core (dependence)
+///
+/// @defgroup ext_matrix_transform GLM_EXT_matrix_transform
+/// @ingroup ext
+///
+/// Include <glm/ext/matrix_transform.hpp> to use the features of this extension.
+///
+/// Defines functions that generate common transformation matrices.
+///
+/// The matrices generated by this extension use standard OpenGL fixed-function
+/// conventions. For example, the lookAt function generates a transform from world
+/// space into the specific eye space that the projective matrix functions
+/// (perspective, ortho, etc) are designed to expect. The OpenGL compatibility
+/// specifications defines the particular layout of this eye space.
+
+#pragma once
+
+// Dependencies
+#include "../mat4x4.hpp"
+#include "../vec2.hpp"
+#include "../vec3.hpp"
+#include "../vec4.hpp"
+#include "../gtc/constants.hpp"
+
+#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
+#	pragma message("GLM: GLM_EXT_matrix_transform extension included")
+#endif
+
+namespace glm
+{
+	/// @addtogroup ext_matrix_transform
+	/// @{
+
+	/// Builds an identity matrix.
+	template<typename genType>
+	GLM_FUNC_DECL GLM_CONSTEXPR genType identity();
+
+	/// Builds a translation 4 * 4 matrix created from a vector of 3 components.
+	///
+	/// @param m Input matrix multiplied by this translation matrix.
+	/// @param v Coordinates of a translation vector.
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @code
+	/// #include <glm/glm.hpp>
+	/// #include <glm/gtc/matrix_transform.hpp>
+	/// ...
+	/// glm::mat4 m = glm::translate(glm::mat4(1.0f), glm::vec3(1.0f));
+	/// // m[0][0] == 1.0f, m[0][1] == 0.0f, m[0][2] == 0.0f, m[0][3] == 0.0f
+	/// // m[1][0] == 0.0f, m[1][1] == 1.0f, m[1][2] == 0.0f, m[1][3] == 0.0f
+	/// // m[2][0] == 0.0f, m[2][1] == 0.0f, m[2][2] == 1.0f, m[2][3] == 0.0f
+	/// // m[3][0] == 1.0f, m[3][1] == 1.0f, m[3][2] == 1.0f, m[3][3] == 1.0f
+	/// @endcode
+	/// @see gtc_matrix_transform
+	/// @see - translate(mat<4, 4, T, Q> const& m, T x, T y, T z)
+	/// @see - translate(vec<3, T, Q> const& v)
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glTranslate.xml">glTranslate man page</a>
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL mat<4, 4, T, Q> translate(
+		mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v);
+
+	/// Builds a rotation 4 * 4 matrix created from an axis vector and an angle.
+	///
+	/// @param m Input matrix multiplied by this rotation matrix.
+	/// @param angle Rotation angle expressed in radians.
+	/// @param axis Rotation axis, recommended to be normalized.
+	/// @tparam T Value type used to build the matrix. Supported: half, float or double.
+	/// @see gtc_matrix_transform
+	/// @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)
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glRotate.xml">glRotate man page</a>
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL mat<4, 4, T, Q> rotate(
+		mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& axis);
+
+	/// Builds a scale 4 * 4 matrix created from 3 scalars.
+	///
+	/// @param m Input matrix multiplied by this scale matrix.
+	/// @param v Ratio of scaling for each axis.
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - scale(mat<4, 4, T, Q> const& m, T x, T y, T z)
+	/// @see - scale(vec<3, T, Q> const& v)
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glScale.xml">glScale man page</a>
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL mat<4, 4, T, Q> scale(
+		mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v);
+
+	/// Creates a matrix for projecting two-dimensional coordinates onto the screen.
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top, T const& zNear, T const& zFar)
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluOrtho2D.xml">gluOrtho2D man page</a>
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> ortho(
+		T left, T right, T bottom, T top);
+
+	/// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH_ZO(
+		T left, T right, T bottom, T top, T zNear, T zFar);
+
+	/// Creates a matrix for an orthographic parallel viewing volume using right-handed coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH_NO(
+		T left, T right, T bottom, T top, T zNear, T zFar);
+
+	/// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH_ZO(
+		T left, T right, T bottom, T top, T zNear, T zFar);
+
+	/// Creates a matrix for an orthographic parallel viewing volume, using right-handed coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH_NO(
+		T left, T right, T bottom, T top, T zNear, T zFar);
+
+	/// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoZO(
+		T left, T right, T bottom, T top, T zNear, T zFar);
+
+	/// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoNO(
+		T left, T right, T bottom, T top, T zNear, T zFar);
+
+	/// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates.
+	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH(
+		T left, T right, T bottom, T top, T zNear, T zFar);
+
+	/// Creates a matrix for an orthographic parallel viewing volume, using right-handed coordinates.
+	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH(
+		T left, T right, T bottom, T top, T zNear, T zFar);
+
+	/// Creates a matrix for an orthographic parallel viewing volume, using the default handedness and default near and far clip planes definition.
+	/// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml">glOrtho man page</a>
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> ortho(
+		T left, T right, T bottom, T top, T zNear, T zFar);
+
+	/// Creates a left handed frustum matrix.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH_ZO(
+		T left, T right, T bottom, T top, T near, T far);
+
+	/// Creates a left handed frustum matrix.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH_NO(
+		T left, T right, T bottom, T top, T near, T far);
+
+	/// Creates a right handed frustum matrix.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH_ZO(
+		T left, T right, T bottom, T top, T near, T far);
+
+	/// Creates a right handed frustum matrix.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH_NO(
+		T left, T right, T bottom, T top, T near, T far);
+
+	/// Creates a frustum matrix using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumZO(
+		T left, T right, T bottom, T top, T near, T far);
+
+	/// Creates a frustum matrix using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumNO(
+		T left, T right, T bottom, T top, T near, T far);
+
+	/// Creates a left handed frustum matrix.
+	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH(
+		T left, T right, T bottom, T top, T near, T far);
+
+	/// Creates a right handed frustum matrix.
+	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH(
+		T left, T right, T bottom, T top, T near, T far);
+
+	/// Creates a frustum matrix with default handedness, using the default handedness and default near and far clip planes definition.
+	/// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
+	///
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glFrustum.xml">glFrustum man page</a>
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustum(
+		T left, T right, T bottom, T top, T near, T far);
+
+
+	/// Creates a matrix for a right handed, symetric perspective-view frustum.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH_ZO(
+		T fovy, T aspect, T near, T far);
+
+	/// Creates a matrix for a right handed, symetric perspective-view frustum.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH_NO(
+		T fovy, T aspect, T near, T far);
+
+	/// Creates a matrix for a left handed, symetric perspective-view frustum.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH_ZO(
+		T fovy, T aspect, T near, T far);
+
+	/// Creates a matrix for a left handed, symetric perspective-view frustum.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH_NO(
+		T fovy, T aspect, T near, T far);
+
+	/// Creates a matrix for a symetric perspective-view frustum using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveZO(
+		T fovy, T aspect, T near, T far);
+
+	/// Creates a matrix for a symetric perspective-view frustum using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveNO(
+		T fovy, T aspect, T near, T far);
+
+	/// Creates a matrix for a right handed, symetric perspective-view frustum.
+	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH(
+		T fovy, T aspect, T near, T far);
+
+	/// Creates a matrix for a left handed, symetric perspective-view frustum.
+	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH(
+		T fovy, T aspect, T near, T far);
+
+	/// Creates a matrix for a symetric perspective-view frustum based on the default handedness and default near and far clip planes definition.
+	/// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
+	///
+	/// @param fovy Specifies the field of view angle in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml">gluPerspective man page</a>
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspective(
+		T fovy, T aspect, T near, T far);
+
+	/// Builds a perspective projection matrix based on a field of view using right-handed coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @param fov Expressed in radians.
+	/// @param width Width of the viewport
+	/// @param height Height of the viewport
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH_ZO(
+		T fov, T width, T height, T near, T far);
+
+	/// Builds a perspective projection matrix based on a field of view using right-handed coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param fov Expressed in radians.
+	/// @param width Width of the viewport
+	/// @param height Height of the viewport
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH_NO(
+		T fov, T width, T height, T near, T far);
+
+	/// Builds a perspective projection matrix based on a field of view using left-handed coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @param fov Expressed in radians.
+	/// @param width Width of the viewport
+	/// @param height Height of the viewport
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH_ZO(
+		T fov, T width, T height, T near, T far);
+
+	/// Builds a perspective projection matrix based on a field of view using left-handed coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param fov Expressed in radians.
+	/// @param width Width of the viewport
+	/// @param height Height of the viewport
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH_NO(
+		T fov, T width, T height, T near, T far);
+
+	/// Builds a perspective projection matrix based on a field of view using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @param fov Expressed in radians.
+	/// @param width Width of the viewport
+	/// @param height Height of the viewport
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovZO(
+		T fov, T width, T height, T near, T far);
+
+	/// Builds a perspective projection matrix based on a field of view using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param fov Expressed in radians.
+	/// @param width Width of the viewport
+	/// @param height Height of the viewport
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovNO(
+		T fov, T width, T height, T near, T far);
+
+	/// Builds a right handed perspective projection matrix based on a field of view.
+	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param fov Expressed in radians.
+	/// @param width Width of the viewport
+	/// @param height Height of the viewport
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH(
+		T fov, T width, T height, T near, T far);
+
+	/// Builds a left handed perspective projection matrix based on a field of view.
+	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param fov Expressed in radians.
+	/// @param width Width of the viewport
+	/// @param height Height of the viewport
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH(
+		T fov, T width, T height, T near, T far);
+
+	/// Builds a perspective projection matrix based on a field of view and the default handedness and default near and far clip planes definition.
+	/// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
+	///
+	/// @param fov Expressed in radians.
+	/// @param width Width of the viewport
+	/// @param height Height of the viewport
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFov(
+		T fov, T width, T height, T near, T far);
+
+	/// Creates a matrix for a left handed, symmetric perspective-view frustum with far plane at infinite.
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveLH(
+		T fovy, T aspect, T near);
+
+	/// Creates a matrix for a right handed, symmetric perspective-view frustum with far plane at infinite.
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveRH(
+		T fovy, T aspect, T near);
+
+	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite with default handedness.
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspective(
+		T fovy, T aspect, T near);
+
+	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite for graphics hardware that doesn't support depth clamping.
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> tweakedInfinitePerspective(
+		T fovy, T aspect, T near);
+
+	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite for graphics hardware that doesn't support depth clamping.
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @param ep Epsilon
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
+	/// @see gtc_matrix_transform
+	template<typename T>
+	GLM_FUNC_DECL mat<4, 4, T, defaultp> tweakedInfinitePerspective(
+		T fovy, T aspect, T near, T ep);
+
+	/// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @param obj Specify the object coordinates.
+	/// @param model Specifies the current modelview matrix
+	/// @param proj Specifies the current projection matrix
+	/// @param viewport Specifies the current viewport
+	/// @return Return the computed window coordinates.
+	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
+	/// @tparam U Currently supported: Floating-point types and integer types.
+	/// @see gtc_matrix_transform
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluProject.xml">gluProject man page</a>
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_DECL vec<3, T, Q> projectZO(
+		vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
+
+	/// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param obj Specify the object coordinates.
+	/// @param model Specifies the current modelview matrix
+	/// @param proj Specifies the current projection matrix
+	/// @param viewport Specifies the current viewport
+	/// @return Return the computed window coordinates.
+	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
+	/// @tparam U Currently supported: Floating-point types and integer types.
+	/// @see gtc_matrix_transform
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluProject.xml">gluProject man page</a>
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_DECL vec<3, T, Q> projectNO(
+		vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
+
+	/// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates using default near and far clip planes definition.
+	/// To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
+	///
+	/// @param obj Specify the object coordinates.
+	/// @param model Specifies the current modelview matrix
+	/// @param proj Specifies the current projection matrix
+	/// @param viewport Specifies the current viewport
+	/// @return Return the computed window coordinates.
+	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
+	/// @tparam U Currently supported: Floating-point types and integer types.
+	/// @see gtc_matrix_transform
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluProject.xml">gluProject man page</a>
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_DECL vec<3, T, Q> project(
+		vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
+
+	/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
+	///
+	/// @param win Specify the window coordinates to be mapped.
+	/// @param model Specifies the modelview matrix
+	/// @param proj Specifies the projection matrix
+	/// @param viewport Specifies the viewport
+	/// @return Returns the computed object coordinates.
+	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
+	/// @tparam U Currently supported: Floating-point types and integer types.
+	/// @see gtc_matrix_transform
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluUnProject.xml">gluUnProject man page</a>
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_DECL vec<3, T, Q> unProjectZO(
+		vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
+
+	/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates.
+	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
+	///
+	/// @param win Specify the window coordinates to be mapped.
+	/// @param model Specifies the modelview matrix
+	/// @param proj Specifies the projection matrix
+	/// @param viewport Specifies the viewport
+	/// @return Returns the computed object coordinates.
+	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
+	/// @tparam U Currently supported: Floating-point types and integer types.
+	/// @see gtc_matrix_transform
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluUnProject.xml">gluUnProject man page</a>
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_DECL vec<3, T, Q> unProjectNO(
+		vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
+
+	/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates using default near and far clip planes definition.
+	/// To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
+	///
+	/// @param win Specify the window coordinates to be mapped.
+	/// @param model Specifies the modelview matrix
+	/// @param proj Specifies the projection matrix
+	/// @param viewport Specifies the viewport
+	/// @return Returns the computed object coordinates.
+	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
+	/// @tparam U Currently supported: Floating-point types and integer types.
+	/// @see gtc_matrix_transform
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluUnProject.xml">gluUnProject man page</a>
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_DECL vec<3, T, Q> unProject(
+		vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
+
+	/// Define a picking region
+	///
+	/// @param center Specify the center of a picking region in window coordinates.
+	/// @param delta Specify the width and height, respectively, of the picking region in window coordinates.
+	/// @param viewport Rendering viewport
+	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
+	/// @tparam U Currently supported: Floating-point types and integer types.
+	/// @see gtc_matrix_transform
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPickMatrix.xml">gluPickMatrix man page</a>
+	template<typename T, qualifier Q, typename U>
+	GLM_FUNC_DECL mat<4, 4, T, Q> pickMatrix(
+		vec<2, T, Q> const& center, vec<2, T, Q> const& delta, vec<4, U, Q> const& viewport);
+
+	/// Build a right handed look at view matrix.
+	///
+	/// @param eye Position of the camera
+	/// @param center Position where the camera is looking at
+	/// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1)
+	/// @see gtc_matrix_transform
+	/// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal)
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL mat<4, 4, T, Q> lookAtRH(
+		vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up);
+
+	/// Build a left handed look at view matrix.
+	///
+	/// @param eye Position of the camera
+	/// @param center Position where the camera is looking at
+	/// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1)
+	/// @see gtc_matrix_transform
+	/// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal)
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL mat<4, 4, T, Q> lookAtLH(
+		vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up);
+
+	/// Build a look at view matrix based on the default handedness.
+	///
+	/// @param eye Position of the camera
+	/// @param center Position where the camera is looking at
+	/// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1)
+	/// @see gtc_matrix_transform
+	/// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal)
+	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluLookAt.xml">gluLookAt man page</a>
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL mat<4, 4, T, Q> lookAt(
+		vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up);
+
+	/// @}
+}//namespace glm
+
+#include "matrix_transform.inl"

+ 790 - 0
glm/ext/matrix_transform.inl

@@ -0,0 +1,790 @@
+#include "../geometric.hpp"
+#include "../trigonometric.hpp"
+#include "../matrix.hpp"
+
+namespace glm
+{
+	template<typename genType>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType identity()
+	{
+		return detail::init_gentype<genType, detail::genTypeTrait<genType>::GENTYPE>::identity();
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> translate(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v)
+	{
+		mat<4, 4, T, Q> Result(m);
+		Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
+		return Result;
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotate(mat<4, 4, T, Q> const& m, T 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> axis(normalize(v));
+		vec<3, T, Q> temp((T(1) - c) * axis);
+
+		mat<4, 4, T, Q> Rotate;
+		Rotate[0][0] = c + temp[0] * axis[0];
+		Rotate[0][1] = temp[0] * axis[1] + s * axis[2];
+		Rotate[0][2] = temp[0] * axis[2] - s * axis[1];
+
+		Rotate[1][0] = temp[1] * axis[0] - s * axis[2];
+		Rotate[1][1] = c + temp[1] * axis[1];
+		Rotate[1][2] = temp[1] * axis[2] + s * axis[0];
+
+		Rotate[2][0] = temp[2] * axis[0] + s * axis[1];
+		Rotate[2][1] = 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 mat<4, 4, T, Q> rotate_slow(mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& v)
+	{
+		T const a = angle;
+		T const c = cos(a);
+		T const s = sin(a);
+		mat<4, 4, T, Q> Result;
+
+		vec<3, T, Q> axis = normalize(v);
+
+		Result[0][0] = c + (static_cast<T>(1) - c)      * axis.x     * axis.x;
+		Result[0][1] = (static_cast<T>(1) - c) * axis.x * axis.y + s * axis.z;
+		Result[0][2] = (static_cast<T>(1) - c) * axis.x * axis.z - s * axis.y;
+		Result[0][3] = static_cast<T>(0);
+
+		Result[1][0] = (static_cast<T>(1) - c) * axis.y * axis.x - s * axis.z;
+		Result[1][1] = c + (static_cast<T>(1) - c) * axis.y * axis.y;
+		Result[1][2] = (static_cast<T>(1) - c) * axis.y * axis.z + s * axis.x;
+		Result[1][3] = static_cast<T>(0);
+
+		Result[2][0] = (static_cast<T>(1) - c) * axis.z * axis.x + s * axis.y;
+		Result[2][1] = (static_cast<T>(1) - c) * axis.z * axis.y - s * axis.x;
+		Result[2][2] = c + (static_cast<T>(1) - c) * axis.z * axis.z;
+		Result[2][3] = static_cast<T>(0);
+
+		Result[3] = vec<4, T, Q>(0, 0, 0, 1);
+		return m * Result;
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scale(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v)
+	{
+		mat<4, 4, T, Q> Result;
+		Result[0] = m[0] * v[0];
+		Result[1] = m[1] * v[1];
+		Result[2] = m[2] * v[2];
+		Result[3] = m[3];
+		return Result;
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scale_slow(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v)
+	{
+		mat<4, 4, T, Q> Result(T(1));
+		Result[0][0] = v.x;
+		Result[1][1] = v.y;
+		Result[2][2] = v.z;
+		return m * Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top)
+	{
+		mat<4, 4, T, defaultp> Result(static_cast<T>(1));
+		Result[0][0] = static_cast<T>(2) / (right - left);
+		Result[1][1] = static_cast<T>(2) / (top - bottom);
+		Result[2][2] = - static_cast<T>(1);
+		Result[3][0] = - (right + left) / (right - left);
+		Result[3][1] = - (top + bottom) / (top - bottom);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH_ZO(T left, T right, T bottom, T top, T zNear, T zFar)
+	{
+		mat<4, 4, T, defaultp> Result(1);
+		Result[0][0] = static_cast<T>(2) / (right - left);
+		Result[1][1] = static_cast<T>(2) / (top - bottom);
+		Result[2][2] = static_cast<T>(1) / (zFar - zNear);
+		Result[3][0] = - (right + left) / (right - left);
+		Result[3][1] = - (top + bottom) / (top - bottom);
+		Result[3][2] = - zNear / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH_NO(T left, T right, T bottom, T top, T zNear, T zFar)
+	{
+		mat<4, 4, T, defaultp> Result(1);
+		Result[0][0] = static_cast<T>(2) / (right - left);
+		Result[1][1] = static_cast<T>(2) / (top - bottom);
+		Result[2][2] = static_cast<T>(2) / (zFar - zNear);
+		Result[3][0] = - (right + left) / (right - left);
+		Result[3][1] = - (top + bottom) / (top - bottom);
+		Result[3][2] = - (zFar + zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH_ZO(T left, T right, T bottom, T top, T zNear, T zFar)
+	{
+		mat<4, 4, T, defaultp> Result(1);
+		Result[0][0] = static_cast<T>(2) / (right - left);
+		Result[1][1] = static_cast<T>(2) / (top - bottom);
+		Result[2][2] = - static_cast<T>(1) / (zFar - zNear);
+		Result[3][0] = - (right + left) / (right - left);
+		Result[3][1] = - (top + bottom) / (top - bottom);
+		Result[3][2] = - zNear / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH_NO(T left, T right, T bottom, T top, T zNear, T zFar)
+	{
+		mat<4, 4, T, defaultp> Result(1);
+		Result[0][0] = static_cast<T>(2) / (right - left);
+		Result[1][1] = static_cast<T>(2) / (top - bottom);
+		Result[2][2] = - static_cast<T>(2) / (zFar - zNear);
+		Result[3][0] = - (right + left) / (right - left);
+		Result[3][1] = - (top + bottom) / (top - bottom);
+		Result[3][2] = - (zFar + zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoZO(T left, T right, T bottom, T top, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
+			return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
+		else
+			return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoNO(T left, T right, T bottom, T top, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
+			return orthoLH_NO(left, right, bottom, top, zNear, zFar);
+		else
+			return orthoRH_NO(left, right, bottom, top, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH(T left, T right, T bottom, T top, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
+			return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
+		else
+			return orthoLH_NO(left, right, bottom, top, zNear, zFar);
+
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH(T left, T right, T bottom, T top, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
+			return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
+		else
+			return orthoRH_NO(left, right, bottom, top, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
+			return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
+			return orthoLH_NO(left, right, bottom, top, zNear, zFar);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
+			return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
+			return orthoRH_NO(left, right, bottom, top, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH_ZO(T left, T right, T bottom, T top, T nearVal, T farVal)
+	{
+		mat<4, 4, T, defaultp> Result(0);
+		Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
+		Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
+		Result[2][0] = (right + left) / (right - left);
+		Result[2][1] = (top + bottom) / (top - bottom);
+		Result[2][2] = farVal / (farVal - nearVal);
+		Result[2][3] = static_cast<T>(1);
+		Result[3][2] = -(farVal * nearVal) / (farVal - nearVal);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH_NO(T left, T right, T bottom, T top, T nearVal, T farVal)
+	{
+		mat<4, 4, T, defaultp> Result(0);
+		Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
+		Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
+		Result[2][0] = (right + left) / (right - left);
+		Result[2][1] = (top + bottom) / (top - bottom);
+		Result[2][2] = (farVal + nearVal) / (farVal - nearVal);
+		Result[2][3] = static_cast<T>(1);
+		Result[3][2] = - (static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH_ZO(T left, T right, T bottom, T top, T nearVal, T farVal)
+	{
+		mat<4, 4, T, defaultp> Result(0);
+		Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
+		Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
+		Result[2][0] = (right + left) / (right - left);
+		Result[2][1] = (top + bottom) / (top - bottom);
+		Result[2][2] = farVal / (nearVal - farVal);
+		Result[2][3] = static_cast<T>(-1);
+		Result[3][2] = -(farVal * nearVal) / (farVal - nearVal);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH_NO(T left, T right, T bottom, T top, T nearVal, T farVal)
+	{
+		mat<4, 4, T, defaultp> Result(0);
+		Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
+		Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
+		Result[2][0] = (right + left) / (right - left);
+		Result[2][1] = (top + bottom) / (top - bottom);
+		Result[2][2] = - (farVal + nearVal) / (farVal - nearVal);
+		Result[2][3] = static_cast<T>(-1);
+		Result[3][2] = - (static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumZO(T left, T right, T bottom, T top, T nearVal, T farVal)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
+			return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
+		else
+			return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumNO(T left, T right, T bottom, T top, T nearVal, T farVal)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
+			return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
+		else
+			return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH(T left, T right, T bottom, T top, T nearVal, T farVal)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
+			return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
+		else
+			return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH(T left, T right, T bottom, T top, T nearVal, T farVal)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
+			return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
+		else
+			return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustum(T left, T right, T bottom, T top, T nearVal, T farVal)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
+			return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
+			return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
+			return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
+			return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH_ZO(T fovy, T aspect, T zNear, T zFar)
+	{
+		assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
+
+		T const tanHalfFovy = tan(fovy / static_cast<T>(2));
+
+		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
+		Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
+		Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
+		Result[2][2] = zFar / (zNear - zFar);
+		Result[2][3] = - static_cast<T>(1);
+		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH_NO(T fovy, T aspect, T zNear, T zFar)
+	{
+		assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
+
+		T const tanHalfFovy = tan(fovy / static_cast<T>(2));
+
+		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
+		Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
+		Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
+		Result[2][2] = - (zFar + zNear) / (zFar - zNear);
+		Result[2][3] = - static_cast<T>(1);
+		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH_ZO(T fovy, T aspect, T zNear, T zFar)
+	{
+		assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
+
+		T const tanHalfFovy = tan(fovy / static_cast<T>(2));
+
+		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
+		Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
+		Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
+		Result[2][2] = zFar / (zFar - zNear);
+		Result[2][3] = static_cast<T>(1);
+		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH_NO(T fovy, T aspect, T zNear, T zFar)
+	{
+		assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
+
+		T const tanHalfFovy = tan(fovy / static_cast<T>(2));
+
+		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
+		Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
+		Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
+		Result[2][2] = (zFar + zNear) / (zFar - zNear);
+		Result[2][3] = static_cast<T>(1);
+		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveZO(T fovy, T aspect, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
+			return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
+		else
+			return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveNO(T fovy, T aspect, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
+			return perspectiveLH_NO(fovy, aspect, zNear, zFar);
+		else
+			return perspectiveRH_NO(fovy, aspect, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH(T fovy, T aspect, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
+			return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
+		else
+			return perspectiveLH_NO(fovy, aspect, zNear, zFar);
+
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH(T fovy, T aspect, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
+			return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
+		else
+			return perspectiveRH_NO(fovy, aspect, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspective(T fovy, T aspect, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
+			return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
+			return perspectiveLH_NO(fovy, aspect, zNear, zFar);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
+			return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
+			return perspectiveRH_NO(fovy, aspect, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH_ZO(T fov, T width, T height, T zNear, T zFar)
+	{
+		assert(width > static_cast<T>(0));
+		assert(height > static_cast<T>(0));
+		assert(fov > static_cast<T>(0));
+
+		T const rad = fov;
+		T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
+		T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
+
+		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
+		Result[0][0] = w;
+		Result[1][1] = h;
+		Result[2][2] = zFar / (zNear - zFar);
+		Result[2][3] = - static_cast<T>(1);
+		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH_NO(T fov, T width, T height, T zNear, T zFar)
+	{
+		assert(width > static_cast<T>(0));
+		assert(height > static_cast<T>(0));
+		assert(fov > static_cast<T>(0));
+
+		T const rad = fov;
+		T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
+		T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
+
+		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
+		Result[0][0] = w;
+		Result[1][1] = h;
+		Result[2][2] = - (zFar + zNear) / (zFar - zNear);
+		Result[2][3] = - static_cast<T>(1);
+		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH_ZO(T fov, T width, T height, T zNear, T zFar)
+	{
+		assert(width > static_cast<T>(0));
+		assert(height > static_cast<T>(0));
+		assert(fov > static_cast<T>(0));
+
+		T const rad = fov;
+		T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
+		T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
+
+		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
+		Result[0][0] = w;
+		Result[1][1] = h;
+		Result[2][2] = zFar / (zFar - zNear);
+		Result[2][3] = static_cast<T>(1);
+		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH_NO(T fov, T width, T height, T zNear, T zFar)
+	{
+		assert(width > static_cast<T>(0));
+		assert(height > static_cast<T>(0));
+		assert(fov > static_cast<T>(0));
+
+		T const rad = fov;
+		T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
+		T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
+
+		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
+		Result[0][0] = w;
+		Result[1][1] = h;
+		Result[2][2] = (zFar + zNear) / (zFar - zNear);
+		Result[2][3] = static_cast<T>(1);
+		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovZO(T fov, T width, T height, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
+			return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
+		else
+			return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovNO(T fov, T width, T height, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
+			return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
+		else
+			return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH(T fov, T width, T height, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
+			return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
+		else
+			return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH(T fov, T width, T height, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
+			return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
+		else
+			return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFov(T fov, T width, T height, T zNear, T zFar)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
+			return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
+			return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
+			return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
+		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
+			return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveRH(T fovy, T aspect, T zNear)
+	{
+		T const range = tan(fovy / static_cast<T>(2)) * zNear;
+		T const left = -range * aspect;
+		T const right = range * aspect;
+		T const bottom = -range;
+		T const top = range;
+
+		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
+		Result[0][0] = (static_cast<T>(2) * zNear) / (right - left);
+		Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom);
+		Result[2][2] = - static_cast<T>(1);
+		Result[2][3] = - static_cast<T>(1);
+		Result[3][2] = - static_cast<T>(2) * zNear;
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveLH(T fovy, T aspect, T zNear)
+	{
+		T const range = tan(fovy / static_cast<T>(2)) * zNear;
+		T const left = -range * aspect;
+		T const right = range * aspect;
+		T const bottom = -range;
+		T const top = range;
+
+		mat<4, 4, T, defaultp> Result(T(0));
+		Result[0][0] = (static_cast<T>(2) * zNear) / (right - left);
+		Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom);
+		Result[2][2] = static_cast<T>(1);
+		Result[2][3] = static_cast<T>(1);
+		Result[3][2] = - static_cast<T>(2) * zNear;
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspective(T fovy, T aspect, T zNear)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
+			return infinitePerspectiveLH(fovy, aspect, zNear);
+		else
+			return infinitePerspectiveRH(fovy, aspect, zNear);
+	}
+
+	// Infinite projection matrix: http://www.terathon.com/gdc07_lengyel.pdf
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear, T ep)
+	{
+		T const range = tan(fovy / static_cast<T>(2)) * zNear;
+		T const left = -range * aspect;
+		T const right = range * aspect;
+		T const bottom = -range;
+		T const top = range;
+
+		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
+		Result[0][0] = (static_cast<T>(2) * zNear) / (right - left);
+		Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom);
+		Result[2][2] = ep - static_cast<T>(1);
+		Result[2][3] = static_cast<T>(-1);
+		Result[3][2] = (ep - static_cast<T>(2)) * zNear;
+		return Result;
+	}
+
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear)
+	{
+		return tweakedInfinitePerspective(fovy, aspect, zNear, epsilon<T>());
+	}
+
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<3, T, Q> projectZO(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
+	{
+		vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast<T>(1));
+		tmp = model * tmp;
+		tmp = proj * tmp;
+
+		tmp /= tmp.w;
+		tmp.x = tmp.x * static_cast<T>(0.5) + static_cast<T>(0.5);
+		tmp.y = tmp.y * static_cast<T>(0.5) + static_cast<T>(0.5);
+
+		tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]);
+		tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]);
+
+		return vec<3, T, Q>(tmp);
+	}
+
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<3, T, Q> projectNO(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
+	{
+		vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast<T>(1));
+		tmp = model * tmp;
+		tmp = proj * tmp;
+
+		tmp /= tmp.w;
+		tmp = tmp * static_cast<T>(0.5) + static_cast<T>(0.5);
+		tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]);
+		tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]);
+
+		return vec<3, T, Q>(tmp);
+	}
+
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<3, T, Q> project(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
+			return projectZO(obj, model, proj, viewport);
+		else
+			return projectNO(obj, model, proj, viewport);
+	}
+
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<3, T, Q> unProjectZO(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
+	{
+		mat<4, 4, T, Q> Inverse = inverse(proj * model);
+
+		vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1));
+		tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]);
+		tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]);
+		tmp.x = tmp.x * static_cast<T>(2) - static_cast<T>(1);
+		tmp.y = tmp.y * static_cast<T>(2) - static_cast<T>(1);
+
+		vec<4, T, Q> obj = Inverse * tmp;
+		obj /= obj.w;
+
+		return vec<3, T, Q>(obj);
+	}
+
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<3, T, Q> unProjectNO(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
+	{
+		mat<4, 4, T, Q> Inverse = inverse(proj * model);
+
+		vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1));
+		tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]);
+		tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]);
+		tmp = tmp * static_cast<T>(2) - static_cast<T>(1);
+
+		vec<4, T, Q> obj = Inverse * tmp;
+		obj /= obj.w;
+
+		return vec<3, T, Q>(obj);
+	}
+
+	template<typename T, typename U, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<3, T, Q> unProject(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
+			return unProjectZO(win, model, proj, viewport);
+		else
+			return unProjectNO(win, model, proj, viewport);
+	}
+
+	template<typename T, qualifier Q, typename U>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> pickMatrix(vec<2, T, Q> const& center, vec<2, T, Q> const& delta, vec<4, U, Q> const& viewport)
+	{
+		assert(delta.x > static_cast<T>(0) && delta.y > static_cast<T>(0));
+		mat<4, 4, T, Q> Result(static_cast<T>(1));
+
+		if(!(delta.x > static_cast<T>(0) && delta.y > static_cast<T>(0)))
+			return Result; // Error
+
+		vec<3, T, Q> Temp(
+			(static_cast<T>(viewport[2]) - static_cast<T>(2) * (center.x - static_cast<T>(viewport[0]))) / delta.x,
+			(static_cast<T>(viewport[3]) - static_cast<T>(2) * (center.y - static_cast<T>(viewport[1]))) / delta.y,
+			static_cast<T>(0));
+
+		// Translate and scale the picked region to the entire window
+		Result = translate(Result, Temp);
+		return scale(Result, vec<3, T, Q>(static_cast<T>(viewport[2]) / delta.x, static_cast<T>(viewport[3]) / delta.y, static_cast<T>(1)));
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtRH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up)
+	{
+		vec<3, T, Q> const f(normalize(center - eye));
+		vec<3, T, Q> const s(normalize(cross(f, up)));
+		vec<3, T, Q> const u(cross(s, f));
+
+		mat<4, 4, T, Q> Result(1);
+		Result[0][0] = s.x;
+		Result[1][0] = s.y;
+		Result[2][0] = s.z;
+		Result[0][1] = u.x;
+		Result[1][1] = u.y;
+		Result[2][1] = u.z;
+		Result[0][2] =-f.x;
+		Result[1][2] =-f.y;
+		Result[2][2] =-f.z;
+		Result[3][0] =-dot(s, eye);
+		Result[3][1] =-dot(u, eye);
+		Result[3][2] = dot(f, eye);
+		return Result;
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtLH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up)
+	{
+		vec<3, T, Q> const f(normalize(center - eye));
+		vec<3, T, Q> const s(normalize(cross(up, f)));
+		vec<3, T, Q> const u(cross(f, s));
+
+		mat<4, 4, T, Q> Result(1);
+		Result[0][0] = s.x;
+		Result[1][0] = s.y;
+		Result[2][0] = s.z;
+		Result[0][1] = u.x;
+		Result[1][1] = u.y;
+		Result[2][1] = u.z;
+		Result[0][2] = f.x;
+		Result[1][2] = f.y;
+		Result[2][2] = f.z;
+		Result[3][0] = -dot(s, eye);
+		Result[3][1] = -dot(u, eye);
+		Result[3][2] = -dot(f, eye);
+		return Result;
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAt(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up)
+	{
+		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
+			return lookAtLH(eye, center, up);
+		else
+			return lookAtRH(eye, center, up);
+	}
+}//namespace glm

+ 115 - 0
glm/ext/quaternion_common.hpp

@@ -0,0 +1,115 @@
+/// @ref ext_quaternion_common
+/// @file glm/ext/quaternion_common.hpp
+///
+/// @see core (dependence)
+///
+/// @defgroup ext_quaternion_common GLM_EXT_quaternion_common
+/// @ingroup ext
+///
+/// Include <glm/ext/quaternion_common.hpp> to use the features of this extension.
+///
+/// Defines a templated quaternion type and several quaternion operations.
+
+#pragma once
+
+// Dependency:
+#include "../ext/scalar_constants.hpp"
+#include "../ext/quaternion_geometric.hpp"
+#include "../common.hpp"
+#include "../trigonometric.hpp"
+#include "../exponential.hpp"
+#include <limits>
+
+#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
+#	pragma message("GLM: GLM_EXT_quaternion_common extension included")
+#endif
+
+namespace glm
+{
+	/// @addtogroup ext_quaternion_common
+	/// @{
+
+	/// Spherical linear interpolation of two quaternions.
+	/// The interpolation is oriented and the rotation is performed at constant speed.
+	/// For short path spherical linear interpolation, use the slerp function.
+	///
+	/// @param x A quaternion
+	/// @param y A quaternion
+	/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see - slerp(qua<T, Q> const& x, qua<T, Q> const& y, T const& a)
+	/// @see ext_quaternion_common
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL qua<T, Q> mix(qua<T, Q> const& x, qua<T, Q> const& y, T a);
+
+	/// Linear interpolation of two quaternions.
+	/// The interpolation is oriented.
+	///
+	/// @param x A quaternion
+	/// @param y A quaternion
+	/// @param a Interpolation factor. The interpolation is defined in the range [0, 1].
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_common
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL qua<T, Q> lerp(qua<T, Q> const& x, qua<T, Q> const& y, T a);
+
+	/// Spherical linear interpolation of two quaternions.
+	/// The interpolation always take the short path and the rotation is performed at constant speed.
+	///
+	/// @param x A quaternion
+	/// @param y A quaternion
+	/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_common
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL qua<T, Q> slerp(qua<T, Q> const& x, qua<T, Q> const& y, T a);
+
+	/// Returns the q conjugate.
+	///
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_common
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL qua<T, Q> conjugate(qua<T, Q> const& q);
+
+	/// Returns the q inverse.
+	///
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_common
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL qua<T, Q> inverse(qua<T, Q> const& q);
+
+	/// Returns true if x holds a NaN (not a number)
+	/// representation in the underlying implementation's set of
+	/// floating point representations. Returns false otherwise,
+	/// including for implementations with no NaN
+	/// representations.
+	///
+	/// /!\ When using compiler fast math, this function may fail.
+	///
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_common
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL vec<4, bool, Q> isnan(qua<T, Q> const& x);
+
+	/// Returns true if x holds a positive infinity or negative
+	/// infinity representation in the underlying implementation's
+	/// set of floating point representations. Returns false
+	/// otherwise, including for implementations with no infinity
+	/// representations.
+	///
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_common
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL vec<4, bool, Q> isinf(qua<T, Q> const& x);
+
+	/// @}
+} //namespace glm
+
+#include "quaternion_common.inl"

+ 107 - 0
glm/ext/quaternion_common.inl

@@ -0,0 +1,107 @@
+namespace glm
+{
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER qua<T, Q> mix(qua<T, Q> const& x, qua<T, Q> const& y, T a)
+	{
+		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'mix' only accept floating-point inputs");
+
+		T const cosTheta = dot(x, y);
+
+		// Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator
+		if(cosTheta > static_cast<T>(1) - epsilon<T>())
+		{
+			// Linear interpolation
+			return qua<T, Q>(
+				mix(x.w, y.w, a),
+				mix(x.x, y.x, a),
+				mix(x.y, y.y, a),
+				mix(x.z, y.z, a));
+		}
+		else
+		{
+			// Essential Mathematics, page 467
+			T angle = acos(cosTheta);
+			return (sin((static_cast<T>(1) - a) * angle) * x + sin(a * angle) * y) / sin(angle);
+		}
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER qua<T, Q> lerp(qua<T, Q> const& x, qua<T, Q> const& y, T a)
+	{
+		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'lerp' only accept floating-point inputs");
+
+		// Lerp is only defined in [0, 1]
+		assert(a >= static_cast<T>(0));
+		assert(a <= static_cast<T>(1));
+
+		return x * (static_cast<T>(1) - a) + (y * a);
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER qua<T, Q> slerp(qua<T, Q> const& x, qua<T, Q> const& y, T a)
+	{
+		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'slerp' only accept floating-point inputs");
+
+		qua<T, Q> z = y;
+
+		T cosTheta = dot(x, y);
+
+		// If cosTheta < 0, the interpolation will take the long way around the sphere.
+		// To fix this, one quat must be negated.
+		if(cosTheta < static_cast<T>(0))
+		{
+			z = -y;
+			cosTheta = -cosTheta;
+		}
+
+		// Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator
+		if(cosTheta > static_cast<T>(1) - epsilon<T>())
+		{
+			// Linear interpolation
+			return qua<T, Q>(
+				mix(x.w, z.w, a),
+				mix(x.x, z.x, a),
+				mix(x.y, z.y, a),
+				mix(x.z, z.z, a));
+		}
+		else
+		{
+			// Essential Mathematics, page 467
+			T angle = acos(cosTheta);
+			return (sin((static_cast<T>(1) - a) * angle) * x + sin(a * angle) * z) / sin(angle);
+		}
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER qua<T, Q> conjugate(qua<T, Q> const& q)
+	{
+		return qua<T, Q>(q.w, -q.x, -q.y, -q.z);
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER qua<T, Q> inverse(qua<T, Q> const& q)
+	{
+		return conjugate(q) / dot(q, q);
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<4, bool, Q> isnan(qua<T, Q> const& q)
+	{
+		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isnan' only accept floating-point inputs");
+
+		return vec<4, bool, Q>(isnan(q.x), isnan(q.y), isnan(q.z), isnan(q.w));
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<4, bool, Q> isinf(qua<T, Q> const& q)
+	{
+		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isinf' only accept floating-point inputs");
+
+		return vec<4, bool, Q>(isinf(q.x), isinf(q.y), isinf(q.z), isinf(q.w));
+	}
+}//namespace glm
+
+#if GLM_CONFIG_SIMD == GLM_ENABLE
+#	include "quaternion_common_simd.inl"
+#endif
+

+ 13 - 6
glm/ext/quaternion_geometric.hpp

@@ -4,7 +4,7 @@
 /// @see core (dependence)
 ///
 /// @defgroup ext_quaternion_geometric GLM_EXT_quaternion_geometric
-/// @ingroup gtx
+/// @ingroup ext
 ///
 /// Include <glm/ext/quaternion_geometric.hpp> to use the features of this extension.
 ///
@@ -13,10 +13,12 @@
 #pragma once
 
 // Dependency:
-#include "../detail/qualifier.hpp"
+#include "../geometric.hpp"
+#include "../exponential.hpp"
+#include "../ext/vector_relational.hpp"
 
 #if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
-#	pragma message("GLM: GLM_GTC_quaternion extension included")
+#	pragma message("GLM: GLM_EXT_quaternion_geometric extension included")
 #endif
 
 namespace glm
@@ -26,7 +28,8 @@ namespace glm
 
 	/// Returns the norm of a quaternions
 	///
-	/// @tparam T Floating-point scalar types.
+	/// @tparam T Floating-point scalar types
+	/// @tparam Q Value from qualifier enum
 	///
 	/// @see ext_quaternion_geometric
 	template<typename T, qualifier Q>
@@ -34,7 +37,8 @@ namespace glm
 
 	/// Returns the normalized quaternion.
 	///
-	/// @tparam T Floating-point scalar types.
+	/// @tparam T Floating-point scalar types
+	/// @tparam Q Value from qualifier enum
 	///
 	/// @see ext_quaternion_geometric
 	template<typename T, qualifier Q>
@@ -48,7 +52,10 @@ namespace glm
 	template<typename T, qualifier Q>
 	GLM_FUNC_DECL T dot(qua<T, Q> const& x, qua<T, Q> const& y);
 
-	/// Compute a cross product between a quaternion and a vector.
+	/// Compute a cross product.
+	///
+	/// @tparam T Floating-point scalar types
+	/// @tparam Q Value from qualifier enum
 	///
 	/// @see ext_quaternion_geometric
 	template<typename T, qualifier Q>

+ 0 - 6
glm/ext/quaternion_geometric.inl

@@ -1,11 +1,5 @@
-#include "../geometric.hpp"
-#include "../exponential.hpp"
-#include "../ext/vector_relational.hpp"
-
 namespace glm
 {
-	// -- Operations --
-
 	template<typename T, qualifier Q>
 	GLM_FUNC_QUALIFIER T dot(qua<T, Q> const& x, qua<T, Q> const& y)
 	{

+ 2 - 1
glm/ext/quaternion_relational.hpp

@@ -11,7 +11,8 @@
 #pragma once
 
 // Dependency:
-#include "../detail/qualifier.hpp"
+#include "./quaternion_geometric.hpp"
+#include "../vector_relational.hpp"
 
 #if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
 #	pragma message("GLM: GLM_EXT_quaternion_relational extension included")

+ 0 - 3
glm/ext/quaternion_relational.inl

@@ -1,6 +1,3 @@
-#include "./quaternion_geometric.hpp"
-#include "../vector_relational.hpp"
-
 namespace glm
 {
 	template<typename T, qualifier Q>

+ 43 - 0
glm/ext/quaternion_transform.hpp

@@ -0,0 +1,43 @@
+/// @ref ext_quaternion_transform
+/// @file glm/ext/quaternion_transform.hpp
+///
+/// @see core (dependence)
+///
+/// @defgroup ext_quaternion_common GLM_EXT_quaternion_transform
+/// @ingroup ext
+///
+/// Include <glm/ext/quaternion_transform.hpp> to use the features of this extension.
+///
+/// Defines a templated quaternion type and several quaternion operations.
+
+#pragma once
+
+// Dependency:
+#include "../common.hpp"
+#include "../trigonometric.hpp"
+#include "../geometric.hpp"
+
+#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
+#	pragma message("GLM: GLM_EXT_quaternion_transform extension included")
+#endif
+
+namespace glm
+{
+	/// @addtogroup ext_quaternion_transform
+	/// @{
+
+	/// Rotates a quaternion from a vector of 3 components axis and an angle.
+	///
+	/// @param q Source orientation
+	/// @param angle Angle expressed in radians.
+	/// @param axis Axis of the rotation
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_transform
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL qua<T, Q> rotate(qua<T, Q> const& q, T const& angle, vec<3, T, Q> const& axis);
+
+	/// @}
+} //namespace glm
+
+#include "quaternion_transform.inl"

+ 28 - 0
glm/ext/quaternion_transform.inl

@@ -0,0 +1,28 @@
+namespace glm
+{
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER qua<T, Q> rotate(qua<T, Q> const& q, T const& angle, vec<3, T, Q> const& v)
+	{
+		vec<3, T, Q> Tmp = v;
+
+		// Axis of rotation must be normalised
+		T len = glm::length(Tmp);
+		if(abs(len - static_cast<T>(1)) > static_cast<T>(0.001))
+		{
+			T oneOverLen = static_cast<T>(1) / len;
+			Tmp.x *= oneOverLen;
+			Tmp.y *= oneOverLen;
+			Tmp.z *= oneOverLen;
+		}
+
+		T const AngleRad(angle);
+		T const Sin = sin(AngleRad * static_cast<T>(0.5));
+
+		return q * qua<T, Q>(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
+	}
+}//namespace glm
+
+#if GLM_CONFIG_SIMD == GLM_ENABLE
+#	include "quaternion_transform_simd.inl"
+#endif
+

+ 93 - 0
glm/ext/quaternion_trigonometric.hpp

@@ -0,0 +1,93 @@
+/// @ref ext_quaternion_trigonometric
+/// @file glm/ext/quaternion_trigonometric.hpp
+///
+/// @see core (dependence)
+///
+/// @defgroup ext_quaternion_trigonometric GLM_EXT_quaternion_trigonometric
+/// @ingroup ext
+///
+/// Include <glm/ext/quaternion_trigonometric.hpp> to use the features of this extension.
+///
+/// Defines a templated quaternion type and several quaternion operations.
+
+#pragma once
+
+// Dependency:
+#include "../trigonometric.hpp"
+#include "../exponential.hpp"
+#include "scalar_constants.hpp"
+#include "vector_relational.hpp"
+#include <limits>
+
+#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
+#	pragma message("GLM: GLM_EXT_quaternion_trigonometric extension included")
+#endif
+
+namespace glm
+{
+	/// @addtogroup ext_quaternion_trigonometric
+	/// @{
+
+	/// Returns euler angles, pitch as x, yaw as y, roll as z.
+	/// The result is expressed in radians.
+	///
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_trigonometric
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL vec<3, T, Q> eulerAngles(qua<T, Q> const& x);
+
+	/// Returns roll value of euler angles expressed in radians.
+	///
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_trigonometric
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL T roll(qua<T, Q> const& x);
+
+	/// Returns pitch value of euler angles expressed in radians.
+	///
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_trigonometric
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL T pitch(qua<T, Q> const& x);
+
+	/// Returns yaw value of euler angles expressed in radians.
+	///
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_trigonometric
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL T yaw(qua<T, Q> const& x);
+
+	/// Returns the quaternion rotation angle.
+	///
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_trigonometric
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL T angle(qua<T, Q> const& x);
+
+	/// Returns the q rotation axis.
+	///
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_trigonometric
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL vec<3, T, Q> axis(qua<T, Q> const& x);
+
+	/// Build a quaternion from an angle and a normalized axis.
+	///
+	/// @param angle Angle expressed in radians.
+	/// @param axis Axis of the quaternion, must be normalized.
+	/// @tparam T Floating-point scalar types.
+	///
+	/// @see ext_quaternion_trigonometric
+	template<typename T, qualifier Q>
+	GLM_FUNC_DECL qua<T, Q> angleAxis(T const& angle, vec<3, T, Q> const& axis);
+
+	/// @}
+} //namespace glm
+
+#include "quaternion_trigonometric.inl"

+ 62 - 0
glm/ext/quaternion_trigonometric.inl

@@ -0,0 +1,62 @@
+namespace glm
+{
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<3, T, Q> eulerAngles(qua<T, Q> const& x)
+	{
+		return vec<3, T, Q>(pitch(x), yaw(x), roll(x));
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER T roll(qua<T, Q> const& q)
+	{
+		return static_cast<T>(atan(static_cast<T>(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z));
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER T pitch(qua<T, Q> const& q)
+	{
+		T const y = static_cast<T>(2) * (q.y * q.z + q.w * q.x);
+		T const x = q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z;
+
+		if(all(equal(vec<2, T, Q>(x, y), vec<2, T, Q>(0), epsilon<T>()))) //avoid atan2(0,0) - handle singularity - Matiis
+			return static_cast<T>(static_cast<T>(2) * atan(q.x, q.w));
+
+		return static_cast<T>(atan(y, x));
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER T yaw(qua<T, Q> const& q)
+	{
+		return asin(clamp(static_cast<T>(-2) * (q.x * q.z - q.w * q.y), static_cast<T>(-1), static_cast<T>(1)));
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER T angle(qua<T, Q> const& x)
+	{
+		return acos(x.w) * static_cast<T>(2);
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<3, T, Q> axis(qua<T, Q> const& x)
+	{
+		T const tmp1 = static_cast<T>(1) - x.w * x.w;
+		if(tmp1 <= static_cast<T>(0))
+			return vec<3, T, Q>(0, 0, 1);
+		T const tmp2 = static_cast<T>(1) / sqrt(tmp1);
+		return vec<3, T, Q>(x.x * tmp2, x.y * tmp2, x.z * tmp2);
+	}
+
+	template<typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER qua<T, Q> angleAxis(T const& angle, vec<3, T, Q> const& v)
+	{
+		T const a(angle);
+		T const s = glm::sin(a * static_cast<T>(0.5));
+
+		return qua<T, Q>(glm::cos(a * static_cast<T>(0.5)), v * s);
+	}
+}//namespace glm
+
+#if GLM_CONFIG_SIMD == GLM_ENABLE
+#	include "quaternion_trigonometric_simd.inl"
+#endif
+

+ 1 - 698
glm/gtc/matrix_transform.hpp

@@ -25,707 +25,10 @@
 #include "../vec2.hpp"
 #include "../vec3.hpp"
 #include "../vec4.hpp"
-#include "../gtc/constants.hpp"
+#include "../ext/matrix_transform.hpp"
 
 #if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
 #	pragma message("GLM: GLM_GTC_matrix_transform extension included")
 #endif
 
-namespace glm
-{
-	/// @addtogroup gtc_matrix_transform
-	/// @{
-
-	/// Builds an identity matrix.
-	template<typename genType>
-	GLM_FUNC_DECL GLM_CONSTEXPR genType identity();
-
-	/// Builds a translation 4 * 4 matrix created from a vector of 3 components.
-	///
-	/// @param m Input matrix multiplied by this translation matrix.
-	/// @param v Coordinates of a translation vector.
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @code
-	/// #include <glm/glm.hpp>
-	/// #include <glm/gtc/matrix_transform.hpp>
-	/// ...
-	/// glm::mat4 m = glm::translate(glm::mat4(1.0f), glm::vec3(1.0f));
-	/// // m[0][0] == 1.0f, m[0][1] == 0.0f, m[0][2] == 0.0f, m[0][3] == 0.0f
-	/// // m[1][0] == 0.0f, m[1][1] == 1.0f, m[1][2] == 0.0f, m[1][3] == 0.0f
-	/// // m[2][0] == 0.0f, m[2][1] == 0.0f, m[2][2] == 1.0f, m[2][3] == 0.0f
-	/// // m[3][0] == 1.0f, m[3][1] == 1.0f, m[3][2] == 1.0f, m[3][3] == 1.0f
-	/// @endcode
-	/// @see gtc_matrix_transform
-	/// @see - translate(mat<4, 4, T, Q> const& m, T x, T y, T z)
-	/// @see - translate(vec<3, T, Q> const& v)
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glTranslate.xml">glTranslate man page</a>
-	template<typename T, qualifier Q>
-	GLM_FUNC_DECL mat<4, 4, T, Q> translate(
-		mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v);
-
-	/// Builds a rotation 4 * 4 matrix created from an axis vector and an angle.
-	///
-	/// @param m Input matrix multiplied by this rotation matrix.
-	/// @param angle Rotation angle expressed in radians.
-	/// @param axis Rotation axis, recommended to be normalized.
-	/// @tparam T Value type used to build the matrix. Supported: half, float or double.
-	/// @see gtc_matrix_transform
-	/// @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)
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glRotate.xml">glRotate man page</a>
-	template<typename T, qualifier Q>
-	GLM_FUNC_DECL mat<4, 4, T, Q> rotate(
-		mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& axis);
-
-	/// Builds a scale 4 * 4 matrix created from 3 scalars.
-	///
-	/// @param m Input matrix multiplied by this scale matrix.
-	/// @param v Ratio of scaling for each axis.
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see - scale(mat<4, 4, T, Q> const& m, T x, T y, T z)
-	/// @see - scale(vec<3, T, Q> const& v)
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glScale.xml">glScale man page</a>
-	template<typename T, qualifier Q>
-	GLM_FUNC_DECL mat<4, 4, T, Q> scale(
-		mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v);
-
-	/// Creates a matrix for projecting two-dimensional coordinates onto the screen.
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top, T const& zNear, T const& zFar)
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluOrtho2D.xml">gluOrtho2D man page</a>
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> ortho(
-		T left, T right, T bottom, T top);
-
-	/// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH_ZO(
-		T left, T right, T bottom, T top, T zNear, T zFar);
-
-	/// Creates a matrix for an orthographic parallel viewing volume using right-handed coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH_NO(
-		T left, T right, T bottom, T top, T zNear, T zFar);
-
-	/// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH_ZO(
-		T left, T right, T bottom, T top, T zNear, T zFar);
-
-	/// Creates a matrix for an orthographic parallel viewing volume, using right-handed coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH_NO(
-		T left, T right, T bottom, T top, T zNear, T zFar);
-
-	/// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoZO(
-		T left, T right, T bottom, T top, T zNear, T zFar);
-
-	/// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoNO(
-		T left, T right, T bottom, T top, T zNear, T zFar);
-
-	/// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates.
-	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH(
-		T left, T right, T bottom, T top, T zNear, T zFar);
-
-	/// Creates a matrix for an orthographic parallel viewing volume, using right-handed coordinates.
-	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH(
-		T left, T right, T bottom, T top, T zNear, T zFar);
-
-	/// Creates a matrix for an orthographic parallel viewing volume, using the default handedness and default near and far clip planes definition.
-	/// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top)
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml">glOrtho man page</a>
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> ortho(
-		T left, T right, T bottom, T top, T zNear, T zFar);
-
-	/// Creates a left handed frustum matrix.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH_ZO(
-		T left, T right, T bottom, T top, T near, T far);
-
-	/// Creates a left handed frustum matrix.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH_NO(
-		T left, T right, T bottom, T top, T near, T far);
-
-	/// Creates a right handed frustum matrix.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH_ZO(
-		T left, T right, T bottom, T top, T near, T far);
-
-	/// Creates a right handed frustum matrix.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH_NO(
-		T left, T right, T bottom, T top, T near, T far);
-
-	/// Creates a frustum matrix using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumZO(
-		T left, T right, T bottom, T top, T near, T far);
-
-	/// Creates a frustum matrix using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumNO(
-		T left, T right, T bottom, T top, T near, T far);
-
-	/// Creates a left handed frustum matrix.
-	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH(
-		T left, T right, T bottom, T top, T near, T far);
-
-	/// Creates a right handed frustum matrix.
-	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH(
-		T left, T right, T bottom, T top, T near, T far);
-
-	/// Creates a frustum matrix with default handedness, using the default handedness and default near and far clip planes definition.
-	/// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
-	///
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glFrustum.xml">glFrustum man page</a>
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> frustum(
-		T left, T right, T bottom, T top, T near, T far);
-
-
-	/// Creates a matrix for a right handed, symetric perspective-view frustum.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH_ZO(
-		T fovy, T aspect, T near, T far);
-
-	/// Creates a matrix for a right handed, symetric perspective-view frustum.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH_NO(
-		T fovy, T aspect, T near, T far);
-
-	/// Creates a matrix for a left handed, symetric perspective-view frustum.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH_ZO(
-		T fovy, T aspect, T near, T far);
-
-	/// Creates a matrix for a left handed, symetric perspective-view frustum.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH_NO(
-		T fovy, T aspect, T near, T far);
-
-	/// Creates a matrix for a symetric perspective-view frustum using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveZO(
-		T fovy, T aspect, T near, T far);
-
-	/// Creates a matrix for a symetric perspective-view frustum using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveNO(
-		T fovy, T aspect, T near, T far);
-
-	/// Creates a matrix for a right handed, symetric perspective-view frustum.
-	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH(
-		T fovy, T aspect, T near, T far);
-
-	/// Creates a matrix for a left handed, symetric perspective-view frustum.
-	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH(
-		T fovy, T aspect, T near, T far);
-
-	/// Creates a matrix for a symetric perspective-view frustum based on the default handedness and default near and far clip planes definition.
-	/// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
-	///
-	/// @param fovy Specifies the field of view angle in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml">gluPerspective man page</a>
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspective(
-		T fovy, T aspect, T near, T far);
-
-	/// Builds a perspective projection matrix based on a field of view using right-handed coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @param fov Expressed in radians.
-	/// @param width Width of the viewport
-	/// @param height Height of the viewport
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH_ZO(
-		T fov, T width, T height, T near, T far);
-
-	/// Builds a perspective projection matrix based on a field of view using right-handed coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param fov Expressed in radians.
-	/// @param width Width of the viewport
-	/// @param height Height of the viewport
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH_NO(
-		T fov, T width, T height, T near, T far);
-
-	/// Builds a perspective projection matrix based on a field of view using left-handed coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @param fov Expressed in radians.
-	/// @param width Width of the viewport
-	/// @param height Height of the viewport
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH_ZO(
-		T fov, T width, T height, T near, T far);
-
-	/// Builds a perspective projection matrix based on a field of view using left-handed coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param fov Expressed in radians.
-	/// @param width Width of the viewport
-	/// @param height Height of the viewport
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH_NO(
-		T fov, T width, T height, T near, T far);
-
-	/// Builds a perspective projection matrix based on a field of view using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @param fov Expressed in radians.
-	/// @param width Width of the viewport
-	/// @param height Height of the viewport
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovZO(
-		T fov, T width, T height, T near, T far);
-
-	/// Builds a perspective projection matrix based on a field of view using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param fov Expressed in radians.
-	/// @param width Width of the viewport
-	/// @param height Height of the viewport
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovNO(
-		T fov, T width, T height, T near, T far);
-
-	/// Builds a right handed perspective projection matrix based on a field of view.
-	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param fov Expressed in radians.
-	/// @param width Width of the viewport
-	/// @param height Height of the viewport
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH(
-		T fov, T width, T height, T near, T far);
-
-	/// Builds a left handed perspective projection matrix based on a field of view.
-	/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param fov Expressed in radians.
-	/// @param width Width of the viewport
-	/// @param height Height of the viewport
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH(
-		T fov, T width, T height, T near, T far);
-
-	/// Builds a perspective projection matrix based on a field of view and the default handedness and default near and far clip planes definition.
-	/// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
-	///
-	/// @param fov Expressed in radians.
-	/// @param width Width of the viewport
-	/// @param height Height of the viewport
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param far Specifies the distance from the viewer to the far clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFov(
-		T fov, T width, T height, T near, T far);
-
-	/// Creates a matrix for a left handed, symmetric perspective-view frustum with far plane at infinite.
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveLH(
-		T fovy, T aspect, T near);
-
-	/// Creates a matrix for a right handed, symmetric perspective-view frustum with far plane at infinite.
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveRH(
-		T fovy, T aspect, T near);
-
-	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite with default handedness.
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspective(
-		T fovy, T aspect, T near);
-
-	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite for graphics hardware that doesn't support depth clamping.
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> tweakedInfinitePerspective(
-		T fovy, T aspect, T near);
-
-	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite for graphics hardware that doesn't support depth clamping.
-	///
-	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
-	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
-	/// @param ep Epsilon
-	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double.
-	/// @see gtc_matrix_transform
-	template<typename T>
-	GLM_FUNC_DECL mat<4, 4, T, defaultp> tweakedInfinitePerspective(
-		T fovy, T aspect, T near, T ep);
-
-	/// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @param obj Specify the object coordinates.
-	/// @param model Specifies the current modelview matrix
-	/// @param proj Specifies the current projection matrix
-	/// @param viewport Specifies the current viewport
-	/// @return Return the computed window coordinates.
-	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
-	/// @tparam U Currently supported: Floating-point types and integer types.
-	/// @see gtc_matrix_transform
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluProject.xml">gluProject man page</a>
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_DECL vec<3, T, Q> projectZO(
-		vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
-
-	/// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param obj Specify the object coordinates.
-	/// @param model Specifies the current modelview matrix
-	/// @param proj Specifies the current projection matrix
-	/// @param viewport Specifies the current viewport
-	/// @return Return the computed window coordinates.
-	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
-	/// @tparam U Currently supported: Floating-point types and integer types.
-	/// @see gtc_matrix_transform
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluProject.xml">gluProject man page</a>
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_DECL vec<3, T, Q> projectNO(
-		vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
-
-	/// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates using default near and far clip planes definition.
-	/// To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
-	///
-	/// @param obj Specify the object coordinates.
-	/// @param model Specifies the current modelview matrix
-	/// @param proj Specifies the current projection matrix
-	/// @param viewport Specifies the current viewport
-	/// @return Return the computed window coordinates.
-	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
-	/// @tparam U Currently supported: Floating-point types and integer types.
-	/// @see gtc_matrix_transform
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluProject.xml">gluProject man page</a>
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_DECL vec<3, T, Q> project(
-		vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
-
-	/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
-	///
-	/// @param win Specify the window coordinates to be mapped.
-	/// @param model Specifies the modelview matrix
-	/// @param proj Specifies the projection matrix
-	/// @param viewport Specifies the viewport
-	/// @return Returns the computed object coordinates.
-	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
-	/// @tparam U Currently supported: Floating-point types and integer types.
-	/// @see gtc_matrix_transform
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluUnProject.xml">gluUnProject man page</a>
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_DECL vec<3, T, Q> unProjectZO(
-		vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
-
-	/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates.
-	/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
-	///
-	/// @param win Specify the window coordinates to be mapped.
-	/// @param model Specifies the modelview matrix
-	/// @param proj Specifies the projection matrix
-	/// @param viewport Specifies the viewport
-	/// @return Returns the computed object coordinates.
-	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
-	/// @tparam U Currently supported: Floating-point types and integer types.
-	/// @see gtc_matrix_transform
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluUnProject.xml">gluUnProject man page</a>
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_DECL vec<3, T, Q> unProjectNO(
-		vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
-
-	/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates using default near and far clip planes definition.
-	/// To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE.
-	///
-	/// @param win Specify the window coordinates to be mapped.
-	/// @param model Specifies the modelview matrix
-	/// @param proj Specifies the projection matrix
-	/// @param viewport Specifies the viewport
-	/// @return Returns the computed object coordinates.
-	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
-	/// @tparam U Currently supported: Floating-point types and integer types.
-	/// @see gtc_matrix_transform
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluUnProject.xml">gluUnProject man page</a>
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_DECL vec<3, T, Q> unProject(
-		vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport);
-
-	/// Define a picking region
-	///
-	/// @param center Specify the center of a picking region in window coordinates.
-	/// @param delta Specify the width and height, respectively, of the picking region in window coordinates.
-	/// @param viewport Rendering viewport
-	/// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double.
-	/// @tparam U Currently supported: Floating-point types and integer types.
-	/// @see gtc_matrix_transform
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPickMatrix.xml">gluPickMatrix man page</a>
-	template<typename T, qualifier Q, typename U>
-	GLM_FUNC_DECL mat<4, 4, T, Q> pickMatrix(
-		vec<2, T, Q> const& center, vec<2, T, Q> const& delta, vec<4, U, Q> const& viewport);
-
-	/// Build a right handed look at view matrix.
-	///
-	/// @param eye Position of the camera
-	/// @param center Position where the camera is looking at
-	/// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1)
-	/// @see gtc_matrix_transform
-	/// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal)
-	template<typename T, qualifier Q>
-	GLM_FUNC_DECL mat<4, 4, T, Q> lookAtRH(
-		vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up);
-
-	/// Build a left handed look at view matrix.
-	///
-	/// @param eye Position of the camera
-	/// @param center Position where the camera is looking at
-	/// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1)
-	/// @see gtc_matrix_transform
-	/// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal)
-	template<typename T, qualifier Q>
-	GLM_FUNC_DECL mat<4, 4, T, Q> lookAtLH(
-		vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up);
-
-	/// Build a look at view matrix based on the default handedness.
-	///
-	/// @param eye Position of the camera
-	/// @param center Position where the camera is looking at
-	/// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1)
-	/// @see gtc_matrix_transform
-	/// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal)
-	/// @see <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluLookAt.xml">gluLookAt man page</a>
-	template<typename T, qualifier Q>
-	GLM_FUNC_DECL mat<4, 4, T, Q> lookAt(
-		vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up);
-
-	/// @}
-}//namespace glm
-
 #include "matrix_transform.inl"

+ 0 - 789
glm/gtc/matrix_transform.inl

@@ -1,792 +1,3 @@
-/// @ref gtc_matrix_transform
-
 #include "../geometric.hpp"
 #include "../trigonometric.hpp"
 #include "../matrix.hpp"
-
-namespace glm
-{
-	template<typename genType>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType identity()
-	{
-		return detail::init_gentype<genType, detail::genTypeTrait<genType>::GENTYPE>::identity();
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> translate(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v)
-	{
-		mat<4, 4, T, Q> Result(m);
-		Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
-		return Result;
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotate(mat<4, 4, T, Q> const& m, T 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> axis(normalize(v));
-		vec<3, T, Q> temp((T(1) - c) * axis);
-
-		mat<4, 4, T, Q> Rotate;
-		Rotate[0][0] = c + temp[0] * axis[0];
-		Rotate[0][1] = temp[0] * axis[1] + s * axis[2];
-		Rotate[0][2] = temp[0] * axis[2] - s * axis[1];
-
-		Rotate[1][0] = temp[1] * axis[0] - s * axis[2];
-		Rotate[1][1] = c + temp[1] * axis[1];
-		Rotate[1][2] = temp[1] * axis[2] + s * axis[0];
-
-		Rotate[2][0] = temp[2] * axis[0] + s * axis[1];
-		Rotate[2][1] = 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 mat<4, 4, T, Q> rotate_slow(mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& v)
-	{
-		T const a = angle;
-		T const c = cos(a);
-		T const s = sin(a);
-		mat<4, 4, T, Q> Result;
-
-		vec<3, T, Q> axis = normalize(v);
-
-		Result[0][0] = c + (static_cast<T>(1) - c)      * axis.x     * axis.x;
-		Result[0][1] = (static_cast<T>(1) - c) * axis.x * axis.y + s * axis.z;
-		Result[0][2] = (static_cast<T>(1) - c) * axis.x * axis.z - s * axis.y;
-		Result[0][3] = static_cast<T>(0);
-
-		Result[1][0] = (static_cast<T>(1) - c) * axis.y * axis.x - s * axis.z;
-		Result[1][1] = c + (static_cast<T>(1) - c) * axis.y * axis.y;
-		Result[1][2] = (static_cast<T>(1) - c) * axis.y * axis.z + s * axis.x;
-		Result[1][3] = static_cast<T>(0);
-
-		Result[2][0] = (static_cast<T>(1) - c) * axis.z * axis.x + s * axis.y;
-		Result[2][1] = (static_cast<T>(1) - c) * axis.z * axis.y - s * axis.x;
-		Result[2][2] = c + (static_cast<T>(1) - c) * axis.z * axis.z;
-		Result[2][3] = static_cast<T>(0);
-
-		Result[3] = vec<4, T, Q>(0, 0, 0, 1);
-		return m * Result;
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scale(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v)
-	{
-		mat<4, 4, T, Q> Result;
-		Result[0] = m[0] * v[0];
-		Result[1] = m[1] * v[1];
-		Result[2] = m[2] * v[2];
-		Result[3] = m[3];
-		return Result;
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scale_slow(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v)
-	{
-		mat<4, 4, T, Q> Result(T(1));
-		Result[0][0] = v.x;
-		Result[1][1] = v.y;
-		Result[2][2] = v.z;
-		return m * Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top)
-	{
-		mat<4, 4, T, defaultp> Result(static_cast<T>(1));
-		Result[0][0] = static_cast<T>(2) / (right - left);
-		Result[1][1] = static_cast<T>(2) / (top - bottom);
-		Result[2][2] = - static_cast<T>(1);
-		Result[3][0] = - (right + left) / (right - left);
-		Result[3][1] = - (top + bottom) / (top - bottom);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH_ZO(T left, T right, T bottom, T top, T zNear, T zFar)
-	{
-		mat<4, 4, T, defaultp> Result(1);
-		Result[0][0] = static_cast<T>(2) / (right - left);
-		Result[1][1] = static_cast<T>(2) / (top - bottom);
-		Result[2][2] = static_cast<T>(1) / (zFar - zNear);
-		Result[3][0] = - (right + left) / (right - left);
-		Result[3][1] = - (top + bottom) / (top - bottom);
-		Result[3][2] = - zNear / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH_NO(T left, T right, T bottom, T top, T zNear, T zFar)
-	{
-		mat<4, 4, T, defaultp> Result(1);
-		Result[0][0] = static_cast<T>(2) / (right - left);
-		Result[1][1] = static_cast<T>(2) / (top - bottom);
-		Result[2][2] = static_cast<T>(2) / (zFar - zNear);
-		Result[3][0] = - (right + left) / (right - left);
-		Result[3][1] = - (top + bottom) / (top - bottom);
-		Result[3][2] = - (zFar + zNear) / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH_ZO(T left, T right, T bottom, T top, T zNear, T zFar)
-	{
-		mat<4, 4, T, defaultp> Result(1);
-		Result[0][0] = static_cast<T>(2) / (right - left);
-		Result[1][1] = static_cast<T>(2) / (top - bottom);
-		Result[2][2] = - static_cast<T>(1) / (zFar - zNear);
-		Result[3][0] = - (right + left) / (right - left);
-		Result[3][1] = - (top + bottom) / (top - bottom);
-		Result[3][2] = - zNear / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH_NO(T left, T right, T bottom, T top, T zNear, T zFar)
-	{
-		mat<4, 4, T, defaultp> Result(1);
-		Result[0][0] = static_cast<T>(2) / (right - left);
-		Result[1][1] = static_cast<T>(2) / (top - bottom);
-		Result[2][2] = - static_cast<T>(2) / (zFar - zNear);
-		Result[3][0] = - (right + left) / (right - left);
-		Result[3][1] = - (top + bottom) / (top - bottom);
-		Result[3][2] = - (zFar + zNear) / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoZO(T left, T right, T bottom, T top, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
-			return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
-		else
-			return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoNO(T left, T right, T bottom, T top, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
-			return orthoLH_NO(left, right, bottom, top, zNear, zFar);
-		else
-			return orthoRH_NO(left, right, bottom, top, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH(T left, T right, T bottom, T top, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
-			return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
-		else
-			return orthoLH_NO(left, right, bottom, top, zNear, zFar);
-
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH(T left, T right, T bottom, T top, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
-			return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
-		else
-			return orthoRH_NO(left, right, bottom, top, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
-			return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
-			return orthoLH_NO(left, right, bottom, top, zNear, zFar);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
-			return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
-			return orthoRH_NO(left, right, bottom, top, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH_ZO(T left, T right, T bottom, T top, T nearVal, T farVal)
-	{
-		mat<4, 4, T, defaultp> Result(0);
-		Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
-		Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
-		Result[2][0] = (right + left) / (right - left);
-		Result[2][1] = (top + bottom) / (top - bottom);
-		Result[2][2] = farVal / (farVal - nearVal);
-		Result[2][3] = static_cast<T>(1);
-		Result[3][2] = -(farVal * nearVal) / (farVal - nearVal);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH_NO(T left, T right, T bottom, T top, T nearVal, T farVal)
-	{
-		mat<4, 4, T, defaultp> Result(0);
-		Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
-		Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
-		Result[2][0] = (right + left) / (right - left);
-		Result[2][1] = (top + bottom) / (top - bottom);
-		Result[2][2] = (farVal + nearVal) / (farVal - nearVal);
-		Result[2][3] = static_cast<T>(1);
-		Result[3][2] = - (static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH_ZO(T left, T right, T bottom, T top, T nearVal, T farVal)
-	{
-		mat<4, 4, T, defaultp> Result(0);
-		Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
-		Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
-		Result[2][0] = (right + left) / (right - left);
-		Result[2][1] = (top + bottom) / (top - bottom);
-		Result[2][2] = farVal / (nearVal - farVal);
-		Result[2][3] = static_cast<T>(-1);
-		Result[3][2] = -(farVal * nearVal) / (farVal - nearVal);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH_NO(T left, T right, T bottom, T top, T nearVal, T farVal)
-	{
-		mat<4, 4, T, defaultp> Result(0);
-		Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
-		Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
-		Result[2][0] = (right + left) / (right - left);
-		Result[2][1] = (top + bottom) / (top - bottom);
-		Result[2][2] = - (farVal + nearVal) / (farVal - nearVal);
-		Result[2][3] = static_cast<T>(-1);
-		Result[3][2] = - (static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumZO(T left, T right, T bottom, T top, T nearVal, T farVal)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
-			return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
-		else
-			return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumNO(T left, T right, T bottom, T top, T nearVal, T farVal)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
-			return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
-		else
-			return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH(T left, T right, T bottom, T top, T nearVal, T farVal)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
-			return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
-		else
-			return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH(T left, T right, T bottom, T top, T nearVal, T farVal)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
-			return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
-		else
-			return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustum(T left, T right, T bottom, T top, T nearVal, T farVal)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
-			return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
-			return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
-			return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
-			return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH_ZO(T fovy, T aspect, T zNear, T zFar)
-	{
-		assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
-
-		T const tanHalfFovy = tan(fovy / static_cast<T>(2));
-
-		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
-		Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
-		Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
-		Result[2][2] = zFar / (zNear - zFar);
-		Result[2][3] = - static_cast<T>(1);
-		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH_NO(T fovy, T aspect, T zNear, T zFar)
-	{
-		assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
-
-		T const tanHalfFovy = tan(fovy / static_cast<T>(2));
-
-		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
-		Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
-		Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
-		Result[2][2] = - (zFar + zNear) / (zFar - zNear);
-		Result[2][3] = - static_cast<T>(1);
-		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH_ZO(T fovy, T aspect, T zNear, T zFar)
-	{
-		assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
-
-		T const tanHalfFovy = tan(fovy / static_cast<T>(2));
-
-		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
-		Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
-		Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
-		Result[2][2] = zFar / (zFar - zNear);
-		Result[2][3] = static_cast<T>(1);
-		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH_NO(T fovy, T aspect, T zNear, T zFar)
-	{
-		assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
-
-		T const tanHalfFovy = tan(fovy / static_cast<T>(2));
-
-		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
-		Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
-		Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
-		Result[2][2] = (zFar + zNear) / (zFar - zNear);
-		Result[2][3] = static_cast<T>(1);
-		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveZO(T fovy, T aspect, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
-			return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
-		else
-			return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveNO(T fovy, T aspect, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
-			return perspectiveLH_NO(fovy, aspect, zNear, zFar);
-		else
-			return perspectiveRH_NO(fovy, aspect, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH(T fovy, T aspect, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
-			return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
-		else
-			return perspectiveLH_NO(fovy, aspect, zNear, zFar);
-
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH(T fovy, T aspect, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
-			return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
-		else
-			return perspectiveRH_NO(fovy, aspect, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspective(T fovy, T aspect, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
-			return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
-			return perspectiveLH_NO(fovy, aspect, zNear, zFar);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
-			return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
-			return perspectiveRH_NO(fovy, aspect, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH_ZO(T fov, T width, T height, T zNear, T zFar)
-	{
-		assert(width > static_cast<T>(0));
-		assert(height > static_cast<T>(0));
-		assert(fov > static_cast<T>(0));
-
-		T const rad = fov;
-		T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
-		T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
-
-		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
-		Result[0][0] = w;
-		Result[1][1] = h;
-		Result[2][2] = zFar / (zNear - zFar);
-		Result[2][3] = - static_cast<T>(1);
-		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH_NO(T fov, T width, T height, T zNear, T zFar)
-	{
-		assert(width > static_cast<T>(0));
-		assert(height > static_cast<T>(0));
-		assert(fov > static_cast<T>(0));
-
-		T const rad = fov;
-		T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
-		T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
-
-		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
-		Result[0][0] = w;
-		Result[1][1] = h;
-		Result[2][2] = - (zFar + zNear) / (zFar - zNear);
-		Result[2][3] = - static_cast<T>(1);
-		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH_ZO(T fov, T width, T height, T zNear, T zFar)
-	{
-		assert(width > static_cast<T>(0));
-		assert(height > static_cast<T>(0));
-		assert(fov > static_cast<T>(0));
-
-		T const rad = fov;
-		T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
-		T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
-
-		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
-		Result[0][0] = w;
-		Result[1][1] = h;
-		Result[2][2] = zFar / (zFar - zNear);
-		Result[2][3] = static_cast<T>(1);
-		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH_NO(T fov, T width, T height, T zNear, T zFar)
-	{
-		assert(width > static_cast<T>(0));
-		assert(height > static_cast<T>(0));
-		assert(fov > static_cast<T>(0));
-
-		T const rad = fov;
-		T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
-		T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
-
-		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
-		Result[0][0] = w;
-		Result[1][1] = h;
-		Result[2][2] = (zFar + zNear) / (zFar - zNear);
-		Result[2][3] = static_cast<T>(1);
-		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovZO(T fov, T width, T height, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
-			return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
-		else
-			return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovNO(T fov, T width, T height, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
-			return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
-		else
-			return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH(T fov, T width, T height, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
-			return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
-		else
-			return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH(T fov, T width, T height, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
-			return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
-		else
-			return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFov(T fov, T width, T height, T zNear, T zFar)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
-			return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
-			return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
-			return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
-		else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
-			return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveRH(T fovy, T aspect, T zNear)
-	{
-		T const range = tan(fovy / static_cast<T>(2)) * zNear;
-		T const left = -range * aspect;
-		T const right = range * aspect;
-		T const bottom = -range;
-		T const top = range;
-
-		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
-		Result[0][0] = (static_cast<T>(2) * zNear) / (right - left);
-		Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom);
-		Result[2][2] = - static_cast<T>(1);
-		Result[2][3] = - static_cast<T>(1);
-		Result[3][2] = - static_cast<T>(2) * zNear;
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveLH(T fovy, T aspect, T zNear)
-	{
-		T const range = tan(fovy / static_cast<T>(2)) * zNear;
-		T const left = -range * aspect;
-		T const right = range * aspect;
-		T const bottom = -range;
-		T const top = range;
-
-		mat<4, 4, T, defaultp> Result(T(0));
-		Result[0][0] = (static_cast<T>(2) * zNear) / (right - left);
-		Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom);
-		Result[2][2] = static_cast<T>(1);
-		Result[2][3] = static_cast<T>(1);
-		Result[3][2] = - static_cast<T>(2) * zNear;
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspective(T fovy, T aspect, T zNear)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
-			return infinitePerspectiveLH(fovy, aspect, zNear);
-		else
-			return infinitePerspectiveRH(fovy, aspect, zNear);
-	}
-
-	// Infinite projection matrix: http://www.terathon.com/gdc07_lengyel.pdf
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear, T ep)
-	{
-		T const range = tan(fovy / static_cast<T>(2)) * zNear;
-		T const left = -range * aspect;
-		T const right = range * aspect;
-		T const bottom = -range;
-		T const top = range;
-
-		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
-		Result[0][0] = (static_cast<T>(2) * zNear) / (right - left);
-		Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom);
-		Result[2][2] = ep - static_cast<T>(1);
-		Result[2][3] = static_cast<T>(-1);
-		Result[3][2] = (ep - static_cast<T>(2)) * zNear;
-		return Result;
-	}
-
-	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear)
-	{
-		return tweakedInfinitePerspective(fovy, aspect, zNear, epsilon<T>());
-	}
-
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<3, T, Q> projectZO(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
-	{
-		vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast<T>(1));
-		tmp = model * tmp;
-		tmp = proj * tmp;
-
-		tmp /= tmp.w;
-		tmp.x = tmp.x * static_cast<T>(0.5) + static_cast<T>(0.5);
-		tmp.y = tmp.y * static_cast<T>(0.5) + static_cast<T>(0.5);
-
-		tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]);
-		tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]);
-
-		return vec<3, T, Q>(tmp);
-	}
-
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<3, T, Q> projectNO(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
-	{
-		vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast<T>(1));
-		tmp = model * tmp;
-		tmp = proj * tmp;
-
-		tmp /= tmp.w;
-		tmp = tmp * static_cast<T>(0.5) + static_cast<T>(0.5);
-		tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]);
-		tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]);
-
-		return vec<3, T, Q>(tmp);
-	}
-
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<3, T, Q> project(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
-			return projectZO(obj, model, proj, viewport);
-		else
-			return projectNO(obj, model, proj, viewport);
-	}
-
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<3, T, Q> unProjectZO(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
-	{
-		mat<4, 4, T, Q> Inverse = inverse(proj * model);
-
-		vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1));
-		tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]);
-		tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]);
-		tmp.x = tmp.x * static_cast<T>(2) - static_cast<T>(1);
-		tmp.y = tmp.y * static_cast<T>(2) - static_cast<T>(1);
-
-		vec<4, T, Q> obj = Inverse * tmp;
-		obj /= obj.w;
-
-		return vec<3, T, Q>(obj);
-	}
-
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<3, T, Q> unProjectNO(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
-	{
-		mat<4, 4, T, Q> Inverse = inverse(proj * model);
-
-		vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1));
-		tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]);
-		tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]);
-		tmp = tmp * static_cast<T>(2) - static_cast<T>(1);
-
-		vec<4, T, Q> obj = Inverse * tmp;
-		obj /= obj.w;
-
-		return vec<3, T, Q>(obj);
-	}
-
-	template<typename T, typename U, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<3, T, Q> unProject(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
-			return unProjectZO(win, model, proj, viewport);
-		else
-			return unProjectNO(win, model, proj, viewport);
-	}
-
-	template<typename T, qualifier Q, typename U>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> pickMatrix(vec<2, T, Q> const& center, vec<2, T, Q> const& delta, vec<4, U, Q> const& viewport)
-	{
-		assert(delta.x > static_cast<T>(0) && delta.y > static_cast<T>(0));
-		mat<4, 4, T, Q> Result(static_cast<T>(1));
-
-		if(!(delta.x > static_cast<T>(0) && delta.y > static_cast<T>(0)))
-			return Result; // Error
-
-		vec<3, T, Q> Temp(
-			(static_cast<T>(viewport[2]) - static_cast<T>(2) * (center.x - static_cast<T>(viewport[0]))) / delta.x,
-			(static_cast<T>(viewport[3]) - static_cast<T>(2) * (center.y - static_cast<T>(viewport[1]))) / delta.y,
-			static_cast<T>(0));
-
-		// Translate and scale the picked region to the entire window
-		Result = translate(Result, Temp);
-		return scale(Result, vec<3, T, Q>(static_cast<T>(viewport[2]) / delta.x, static_cast<T>(viewport[3]) / delta.y, static_cast<T>(1)));
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtRH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up)
-	{
-		vec<3, T, Q> const f(normalize(center - eye));
-		vec<3, T, Q> const s(normalize(cross(f, up)));
-		vec<3, T, Q> const u(cross(s, f));
-
-		mat<4, 4, T, Q> Result(1);
-		Result[0][0] = s.x;
-		Result[1][0] = s.y;
-		Result[2][0] = s.z;
-		Result[0][1] = u.x;
-		Result[1][1] = u.y;
-		Result[2][1] = u.z;
-		Result[0][2] =-f.x;
-		Result[1][2] =-f.y;
-		Result[2][2] =-f.z;
-		Result[3][0] =-dot(s, eye);
-		Result[3][1] =-dot(u, eye);
-		Result[3][2] = dot(f, eye);
-		return Result;
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtLH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up)
-	{
-		vec<3, T, Q> const f(normalize(center - eye));
-		vec<3, T, Q> const s(normalize(cross(up, f)));
-		vec<3, T, Q> const u(cross(f, s));
-
-		mat<4, 4, T, Q> Result(1);
-		Result[0][0] = s.x;
-		Result[1][0] = s.y;
-		Result[2][0] = s.z;
-		Result[0][1] = u.x;
-		Result[1][1] = u.y;
-		Result[2][1] = u.z;
-		Result[0][2] = f.x;
-		Result[1][2] = f.y;
-		Result[2][2] = f.z;
-		Result[3][0] = -dot(s, eye);
-		Result[3][1] = -dot(u, eye);
-		Result[3][2] = -dot(f, eye);
-		return Result;
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAt(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up)
-	{
-		if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
-			return lookAtLH(eye, center, up);
-		else
-			return lookAtRH(eye, center, up);
-	}
-}//namespace glm

+ 1 - 64
glm/gtc/quaternion.hpp

@@ -17,6 +17,7 @@
 #include "../gtc/constants.hpp"
 #include "../gtc/matrix_transform.hpp"
 #include "../ext/vector_relational.hpp"
+#include "../ext/quaternion_common.hpp"
 #include "../ext/quaternion_float.hpp"
 #include "../ext/quaternion_float_precision.hpp"
 #include "../ext/quaternion_double.hpp"
@@ -37,44 +38,6 @@ namespace glm
 	/// @addtogroup gtc_quaternion
 	/// @{
 
-	/// Spherical linear interpolation of two quaternions.
-	/// The interpolation is oriented and the rotation is performed at constant speed.
-	/// For short path spherical linear interpolation, use the slerp function.
-	///
-	/// @param x A quaternion
-	/// @param y A quaternion
-	/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
-	/// @tparam T Floating-point scalar types.
-	///
-	/// @see - slerp(qua<T, Q> const& x, qua<T, Q> const& y, T const& a)
-	/// @see gtc_quaternion
-	template<typename T, qualifier Q>
-	GLM_FUNC_DECL qua<T, Q> mix(qua<T, Q> const& x, qua<T, Q> const& y, T a);
-
-	/// Linear interpolation of two quaternions.
-	/// The interpolation is oriented.
-	///
-	/// @param x A quaternion
-	/// @param y A quaternion
-	/// @param a Interpolation factor. The interpolation is defined in the range [0, 1].
-	/// @tparam T Floating-point scalar types.
-	///
-	/// @see gtc_quaternion
-	template<typename T, qualifier Q>
-	GLM_FUNC_DECL qua<T, Q> lerp(qua<T, Q> const& x, qua<T, Q> const& y, T a);
-
-	/// Spherical linear interpolation of two quaternions.
-	/// The interpolation always take the short path and the rotation is performed at constant speed.
-	///
-	/// @param x A quaternion
-	/// @param y A quaternion
-	/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
-	/// @tparam T Floating-point scalar types.
-	///
-	/// @see gtc_quaternion
-	template<typename T, qualifier Q>
-	GLM_FUNC_DECL qua<T, Q> slerp(qua<T, Q> const& x, qua<T, Q> const& y, T a);
-
 	/// Returns the q conjugate.
 	///
 	/// @tparam T Floating-point scalar types.
@@ -193,32 +156,6 @@ namespace glm
 	template<typename T, qualifier Q>
 	GLM_FUNC_DECL qua<T, Q> angleAxis(T const& angle, vec<3, T, Q> const& axis);
 
-	/// Returns true if x holds a NaN (not a number)
-	/// representation in the underlying implementation's set of
-	/// floating point representations. Returns false otherwise,
-	/// including for implementations with no NaN
-	/// representations.
-	///
-	/// /!\ When using compiler fast math, this function may fail.
-	///
-	/// @tparam T Floating-point scalar types.
-	///
-	/// @see gtc_quaternion
-	template<typename T, qualifier Q>
-	GLM_FUNC_DECL vec<4, bool, Q> isnan(qua<T, Q> const& x);
-
-	/// Returns true if x holds a positive infinity or negative
-	/// infinity representation in the underlying implementation's
-	/// set of floating point representations. Returns false
-	/// otherwise, including for implementations with no infinity
-	/// representations.
-	///
-	/// @tparam T Floating-point scalar types.
-	///
-	/// @see gtc_quaternion
-	template<typename T, qualifier Q>
-	GLM_FUNC_DECL vec<4, bool, Q> isinf(qua<T, Q> const& x);
-
 	/// Returns the component-wise comparison result of x < y.
 	///
 	/// @tparam T Floating-point scalar types

+ 0 - 184
glm/gtc/quaternion.inl

@@ -1,5 +1,3 @@
-/// @ref gtc_quaternion
-
 #include "../trigonometric.hpp"
 #include "../geometric.hpp"
 #include "../exponential.hpp"
@@ -8,172 +6,6 @@
 
 namespace glm
 {
-	// -- Operations --
-/*
-	// (x * sin(1 - a) * angle / sin(angle)) + (y * sin(a) * angle / sin(angle))
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER qua<T, Q> mix(qua<T, Q> const& x, qua<T, Q> const& y, T const& a)
-	{
-		if(a <= T(0)) return x;
-		if(a >= T(1)) return y;
-
-		float fCos = dot(x, y);
-		qua<T, Q> y2(y); //BUG!!! qua<T, Q> y2;
-		if(fCos < T(0))
-		{
-			y2 = -y;
-			fCos = -fCos;
-		}
-
-		//if(fCos > 1.0f) // problem
-		float k0, k1;
-		if(fCos > T(0.9999))
-		{
-			k0 = T(1) - a;
-			k1 = 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((T(1) - a) * fAngle) * fOneOverSin;
-			k1 = sin((T(0) + a) * fAngle) * fOneOverSin;
-		}
-
-		return qua<T, Q>(
-			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> mix2
-	(
-		qua<T, Q> const& x,
-		qua<T, Q> const& y,
-		T const& a
-	)
-	{
-		bool flip = false;
-		if(a <= static_cast<T>(0)) return x;
-		if(a >= static_cast<T>(1)) return y;
-
-		T cos_t = dot(x, y);
-		if(cos_t < T(0))
-		{
-			cos_t = -cos_t;
-			flip = true;
-		}
-
-		T alpha(0), beta(0);
-
-		if(T(1) - cos_t < 1e-7)
-			beta = static_cast<T>(1) - alpha;
-		else
-		{
-			T theta = acos(cos_t);
-			T sin_t = sin(theta);
-			beta = sin(theta * (T(1) - alpha)) / sin_t;
-			alpha = sin(alpha * theta) / sin_t;
-		}
-
-		if(flip)
-			alpha = -alpha;
-
-		return normalize(beta * x + alpha * y);
-	}
-*/
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER qua<T, Q> mix(qua<T, Q> const& x, qua<T, Q> const& y, T a)
-	{
-		T cosTheta = dot(x, y);
-
-		// Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator
-		if(cosTheta > T(1) - epsilon<T>())
-		{
-			// Linear interpolation
-			return qua<T, Q>(
-				mix(x.w, y.w, a),
-				mix(x.x, y.x, a),
-				mix(x.y, y.y, a),
-				mix(x.z, y.z, a));
-		}
-		else
-		{
-			// Essential Mathematics, page 467
-			T angle = acos(cosTheta);
-			return (sin((T(1) - a) * angle) * x + sin(a * angle) * y) / sin(angle);
-		}
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER qua<T, Q> lerp(qua<T, Q> const& x, qua<T, Q> const& y, T a)
-	{
-		// Lerp is only defined in [0, 1]
-		assert(a >= static_cast<T>(0));
-		assert(a <= static_cast<T>(1));
-
-		return x * (T(1) - a) + (y * a);
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER qua<T, Q> slerp(qua<T, Q> const& x,	qua<T, Q> const& y, T a)
-	{
-		qua<T, Q> z = y;
-
-		T cosTheta = dot(x, y);
-
-		// If cosTheta < 0, the interpolation will take the long way around the sphere.
-		// To fix this, one quat must be negated.
-		if (cosTheta < T(0))
-		{
-			z        = -y;
-			cosTheta = -cosTheta;
-		}
-
-		// Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator
-		if(cosTheta > T(1) - epsilon<T>())
-		{
-			// Linear interpolation
-			return qua<T, Q>(
-				mix(x.w, z.w, a),
-				mix(x.x, z.x, a),
-				mix(x.y, z.y, a),
-				mix(x.z, z.z, a));
-		}
-		else
-		{
-			// Essential Mathematics, page 467
-			T angle = acos(cosTheta);
-			return (sin((T(1) - a) * angle) * x + sin(a * angle) * z) / sin(angle);
-		}
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER qua<T, Q> rotate(qua<T, Q> const& q, T const& angle, vec<3, T, Q> const& v)
-	{
-		vec<3, T, Q> Tmp = v;
-
-		// Axis of rotation must be normalised
-		T len = glm::length(Tmp);
-		if(abs(len - T(1)) > T(0.001))
-		{
-			T oneOverLen = static_cast<T>(1) / len;
-			Tmp.x *= oneOverLen;
-			Tmp.y *= oneOverLen;
-			Tmp.z *= oneOverLen;
-		}
-
-		T const AngleRad(angle);
-		T const Sin = sin(AngleRad * T(0.5));
-
-		return q * qua<T, Q>(cos(AngleRad * T(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
-		//return gtc::quaternion::cross(q, qua<T, Q>(cos(AngleRad * T(0.5)), Tmp.x * fSin, Tmp.y * fSin, Tmp.z * fSin));
-	}
-
 	template<typename T, qualifier Q>
 	GLM_FUNC_QUALIFIER vec<3, T, Q> eulerAngles(qua<T, Q> const& x)
 	{
@@ -321,22 +153,6 @@ namespace glm
 		return Result;
 	}
 
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<4, bool, Q> isnan(qua<T, Q> const& q)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isnan' only accept floating-point inputs");
-
-		return vec<4, bool, Q>(isnan(q.x), isnan(q.y), isnan(q.z), isnan(q.w));
-	}
-
-	template<typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<4, bool, Q> isinf(qua<T, Q> const& q)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isinf' only accept floating-point inputs");
-
-		return vec<4, bool, Q>(isinf(q.x), isinf(q.y), isinf(q.z), isinf(q.w));
-	}
-
 	template<typename T, qualifier Q>
 	GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThan(qua<T, Q> const& x, qua<T, Q> const& y)
 	{

+ 4 - 0
test/ext/CMakeLists.txt

@@ -1,6 +1,10 @@
 glmCreateTestGTC(ext_matrix_relational)
+glmCreateTestGTC(ext_matrix_transform)
+glmCreateTestGTC(ext_quaternion_common)
 glmCreateTestGTC(ext_quaternion_geometric)
 glmCreateTestGTC(ext_quaternion_relational)
+glmCreateTestGTC(ext_quaternion_transform)
+glmCreateTestGTC(ext_quaternion_trigonometric)
 glmCreateTestGTC(ext_quaternion_type)
 glmCreateTestGTC(ext_scalar_constants)
 glmCreateTestGTC(ext_scalar_float_sized)

+ 10 - 0
test/ext/ext_matrix_transform.cpp

@@ -0,0 +1,10 @@
+#include <glm/ext/matrix_relational.hpp>
+//#include <glm/ext/matrix_transform.hpp>
+
+int main()
+{
+	int Error = 0;
+
+
+	return Error;
+}

+ 28 - 0
test/ext/ext_quaternion_common.cpp

@@ -0,0 +1,28 @@
+#include <glm/ext/vector_float3.hpp>
+#include <glm/ext/quaternion_common.hpp>
+#include <glm/ext/quaternion_float.hpp>
+#include <glm/ext/quaternion_relational.hpp>
+#include <glm/ext/scalar_constants.hpp>
+
+static int test_conjugate()
+{
+	int Error = 0;
+
+	glm::quat const A(glm::vec3(1, 0, 0), glm::vec3(0, 1, 0));
+	glm::quat const C = glm::conjugate(A);
+	Error += glm::any(glm::notEqual(A, C, glm::epsilon<float>())) ? 0 : 1;
+
+	glm::quat const B = glm::conjugate(C);
+	Error += glm::all(glm::equal(A, B, glm::epsilon<float>())) ? 0 : 1;
+
+	return Error;
+}
+
+int main()
+{
+	int Error = 0;
+
+	Error += test_conjugate();
+
+	return Error;
+}

+ 23 - 22
test/ext/ext_quaternion_geometric.cpp

@@ -1,6 +1,7 @@
 #include <glm/gtc/constants.hpp>
 #include <glm/ext/quaternion_geometric.hpp>
 #include <glm/ext/quaternion_float.hpp>
+#include <glm/ext/quaternion_trigonometric.hpp>
 #include <glm/ext/quaternion_float_precision.hpp>
 #include <glm/ext/quaternion_double.hpp>
 #include <glm/ext/quaternion_double_precision.hpp>
@@ -10,29 +11,8 @@
 #include <glm/ext/vector_double3_precision.hpp>
 #include <glm/ext/scalar_relational.hpp>
 
-#include <glm/gtc/quaternion.hpp>
-
 float const Epsilon = 0.001f;
 
-static int test_angle()
-{
-	int Error = 0;
-
-	{
-		glm::quat const Q = glm::quat(glm::vec3(1, 0, 0), glm::vec3(0, 1, 0));
-		float const A = glm::degrees(glm::angle(Q));
-		Error += glm::equal(A, 90.0f, Epsilon) ? 0 : 1;
-	}
-
-	{
-		glm::quat const Q = glm::quat(glm::vec3(0, 1, 0), glm::vec3(1, 0, 0));
-		float const A = glm::degrees(glm::angle(Q));
-		Error += glm::equal(A, 90.0f, Epsilon) ? 0 : 1;
-	}
-
-	return Error;
-}
-
 static int test_length()
 {
 	int Error = 0;
@@ -74,14 +54,35 @@ static int test_normalize()
 	return Error;
 }
 
+static int test_dot()
+{
+	int Error = 0;
+
+	{
+		glm::quat const A = glm::quat(1, 0, 0, 0);
+		glm::quat const B = glm::quat(1, 0, 0, 0);
+		float const C = glm::dot(A, B);
+		Error += glm::equal(C, 1.0f, Epsilon) ? 0 : 1;
+	}
+
+	return Error;
+}
+
+static int test_cross()
+{
+	int Error = 0;
+
+	return Error;
+}
 
 int main()
 {
 	int Error = 0;
 
-	Error += test_angle();
 	Error += test_length();
 	Error += test_normalize();
+	Error += test_dot();
+	Error += test_cross();
 
 	return Error;
 }

+ 11 - 0
test/ext/ext_quaternion_transform.cpp

@@ -0,0 +1,11 @@
+#include <glm/ext/quaternion_transform.hpp>
+#include <glm/ext/quaternion_float.hpp>
+#include <glm/ext/vector_relational.hpp>
+#include <glm/ext/scalar_constants.hpp>
+
+int main()
+{
+	int Error = 0;
+
+	return Error;
+}

+ 34 - 0
test/ext/ext_quaternion_trigonometric.cpp

@@ -0,0 +1,34 @@
+#include <glm/ext/quaternion_trigonometric.hpp>
+#include <glm/ext/quaternion_float.hpp>
+#include <glm/ext/vector_relational.hpp>
+#include <glm/ext/scalar_relational.hpp>
+
+float const Epsilon = 0.001f;
+
+static int test_angle()
+{
+	int Error = 0;
+
+	{
+		glm::quat const Q = glm::quat(glm::vec3(1, 0, 0), glm::vec3(0, 1, 0));
+		float const A = glm::degrees(glm::angle(Q));
+		Error += glm::equal(A, 90.0f, Epsilon) ? 0 : 1;
+	}
+
+	{
+		glm::quat const Q = glm::quat(glm::vec3(0, 1, 0), glm::vec3(1, 0, 0));
+		float const A = glm::degrees(glm::angle(Q));
+		Error += glm::equal(A, 90.0f, Epsilon) ? 0 : 1;
+	}
+
+	return Error;
+}
+
+int main()
+{
+	int Error = 0;
+
+	Error += test_angle();
+
+	return Error;
+}