Browse Source

Merge pull request #314 from amc522/master

Left handed perspective and lookAt functions #314
Christophe Riccio 10 years ago
parent
commit
88f4a5ed82
2 changed files with 219 additions and 3 deletions
  1. 94 3
      glm/gtc/matrix_transform.hpp
  2. 125 0
      glm/gtc/matrix_transform.inl

+ 94 - 3
glm/gtc/matrix_transform.hpp

@@ -171,7 +171,7 @@ namespace glm
 		T near,
 		T near,
 		T far);
 		T far);
 
 
-	/// Creates a matrix for a symetric perspective-view frustum.
+	/// Creates a matrix for a symetric perspective-view frustum based on the default handedness.
 	/// 
 	/// 
 	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
 	/// @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 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).
@@ -186,7 +186,38 @@ namespace glm
 		T near,
 		T near,
 		T far);
 		T far);
 
 
-	/// Builds a perspective projection matrix based on a field of view.
+
+	/// Creates a matrix for a right handed, symetric perspective-view frustum.
+	/// 
+	/// @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 recommanded), float or double.
+	/// @see gtc_matrix_transform
+	template <typename T>
+	GLM_FUNC_DECL tmat4x4<T, defaultp> perspectiveRH(
+		T fovy,
+		T aspect,
+		T near,
+		T far);
+
+	/// Creates a matrix for a left handed, symetric perspective-view frustum.
+	/// 
+	/// @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 recommanded), float or double.
+	/// @see gtc_matrix_transform
+	template <typename T>
+	GLM_FUNC_DECL tmat4x4<T, defaultp> perspectiveLH(
+		T fovy,
+		T aspect,
+		T near,
+		T far);
+
+	/// Builds a perspective projection matrix based on a field of view and the default handedness.
 	/// 
 	/// 
 	/// @param fov Expressed in radians.
 	/// @param fov Expressed in radians.
 	/// @param width 
 	/// @param width 
@@ -203,6 +234,40 @@ namespace glm
 		T near,
 		T near,
 		T far);
 		T far);
 
 
+	/// Builds a right handed perspective projection matrix based on a field of view.
+	/// 
+	/// @param fov Expressed in radians.
+	/// @param width 
+	/// @param 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 recommanded), float or double.
+	/// @see gtc_matrix_transform
+	template <typename T>
+	GLM_FUNC_DECL tmat4x4<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.
+	/// 
+	/// @param fov Expressed in radians.
+	/// @param width 
+	/// @param 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 recommanded), float or double.
+	/// @see gtc_matrix_transform
+	template <typename T>
+	GLM_FUNC_DECL tmat4x4<T, defaultp> perspectiveFovLH(
+		T fov,
+		T width,
+		T height,
+		T near,
+		T far);
+
 	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite.
 	/// Creates a matrix for a 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 fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
@@ -285,7 +350,7 @@ namespace glm
 		tvec2<T, P> const & delta,
 		tvec2<T, P> const & delta,
 		tvec4<U, P> const & viewport);
 		tvec4<U, P> const & viewport);
 
 
-	/// Build a look at view matrix.
+	/// Build a look at view matrix based on the default handedness.
 	///
 	///
 	/// @param eye Position of the camera
 	/// @param eye Position of the camera
 	/// @param center Position where the camera is looking at
 	/// @param center Position where the camera is looking at
@@ -298,6 +363,32 @@ namespace glm
 		tvec3<T, P> const & center,
 		tvec3<T, P> const & center,
 		tvec3<T, P> const & up);
 		tvec3<T, P> const & up);
 
 
+	/// 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, precision P>
+	GLM_FUNC_DECL tmat4x4<T, P> lookAtRH(
+		tvec3<T, P> const & eye,
+		tvec3<T, P> const & center,
+		tvec3<T, P> 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, precision P>
+	GLM_FUNC_DECL tmat4x4<T, P> lookAtLH(
+		tvec3<T, P> const & eye,
+		tvec3<T, P> const & center,
+		tvec3<T, P> const & up);
+
 	/// @}
 	/// @}
 }//namespace glm
 }//namespace glm
 
 

+ 125 - 0
glm/gtc/matrix_transform.inl

@@ -216,6 +216,22 @@ namespace glm
 		T zNear,
 		T zNear,
 		T zFar
 		T zFar
 	)
 	)
+	{
+		#ifdef GLM_LEFT_HANDED
+			return perspectiveLH(fovy, aspect, zNear, zFar);
+		#else
+			return perspectiveRH(fovy, aspect, zNear, zFar);
+		#endif
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspectiveRH
+	(
+		T fovy,
+		T aspect,
+		T zNear,
+		T zFar
+	)
 	{
 	{
 		assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
 		assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
 
 
@@ -230,6 +246,28 @@ namespace glm
 		return Result;
 		return Result;
 	}
 	}
 	
 	
+	template <typename T>
+	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspectiveLH
+		(
+		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));
+		
+		tmat4x4<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>
 	template <typename T>
 	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspectiveFov
 	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspectiveFov
 	(
 	(
@@ -239,6 +277,23 @@ namespace glm
 		T zNear,
 		T zNear,
 		T zFar
 		T zFar
 	)
 	)
+	{
+		#ifdef GLM_LEFT_HANDED
+			return perspectiveFovLH(fov, width, height, zNear, zFar);
+		#else
+			return perspectiveFovRH(fov, width, height, zNear, zFar);
+		#endif
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspectiveFovRH
+	(
+		T fov,
+		T width,
+		T height,
+		T zNear,
+		T zFar
+	)
 	{
 	{
 		assert(width > static_cast<T>(0));
 		assert(width > static_cast<T>(0));
 		assert(height > static_cast<T>(0));
 		assert(height > static_cast<T>(0));
@@ -257,6 +312,33 @@ namespace glm
 		return Result;
 		return Result;
 	}
 	}
 
 
+	template <typename T>
+	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspectiveFovLH
+	(
+		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)?
+
+		tmat4x4<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>
 	template <typename T>
 	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> infinitePerspective
 	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> infinitePerspective
 	(
 	(
@@ -390,6 +472,21 @@ namespace glm
 		tvec3<T, P> const & center,
 		tvec3<T, P> const & center,
 		tvec3<T, P> const & up
 		tvec3<T, P> const & up
 	)
 	)
+	{
+		#ifdef GLM_LEFT_HANDED
+			return lookAtLH(eye, center, up);
+		#else
+			return lookAtRH(eye, center, up);
+		#endif
+	}
+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> lookAtRH
+	(
+		tvec3<T, P> const & eye,
+		tvec3<T, P> const & center,
+		tvec3<T, P> const & up
+	)
 	{
 	{
 		tvec3<T, P> const f(normalize(center - eye));
 		tvec3<T, P> const f(normalize(center - eye));
 		tvec3<T, P> const s(normalize(cross(f, up)));
 		tvec3<T, P> const s(normalize(cross(f, up)));
@@ -410,4 +507,32 @@ namespace glm
 		Result[3][2] = dot(f, eye);
 		Result[3][2] = dot(f, eye);
 		return Result;
 		return Result;
 	}
 	}
+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> lookAtLH
+	(
+		tvec3<T, P> const & eye,
+		tvec3<T, P> const & center,
+		tvec3<T, P> const & up
+	)
+	{
+		tvec3<T, P> const f(normalize(center - eye));
+		tvec3<T, P> const s(normalize(cross(up, f)));
+		tvec3<T, P> const u(cross(f, s));
+
+		tmat4x4<T, P> 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;
+	}
 }//namespace glm
 }//namespace glm