Browse Source

Added infinitePerspectiveLH_ZO and tests

Renamed infinitePerspectiveLH -> infinitePerspectiveLH_NO
azhirnov 2 years ago
parent
commit
9cb19aa43f
2 changed files with 83 additions and 4 deletions
  1. 23 3
      glm/ext/matrix_clip_space.inl
  2. 60 1
      test/gtc/gtc_matrix_transform.cpp

+ 23 - 3
glm/ext/matrix_clip_space.inl

@@ -501,7 +501,7 @@ namespace glm
 	}
 
 	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveLH(T fovy, T aspect, T zNear)
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveLH_NO(T fovy, T aspect, T zNear)
 	{
 		T const range = tan(fovy / static_cast<T>(2)) * zNear;
 		T const left = -range * aspect;
@@ -518,11 +518,31 @@ namespace glm
 		return Result;
 	}
 
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveLH_ZO(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] = - 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);
+#		if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO
+			return infinitePerspectiveLH_ZO(fovy, aspect, zNear);
+#		elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
+			return infinitePerspectiveLH_NO(fovy, aspect, zNear);
 #		else
 			return infinitePerspectiveRH(fovy, aspect, zNear);
 #		endif

+ 60 - 1
test/gtc/gtc_matrix_transform.cpp

@@ -1,12 +1,70 @@
 #include <glm/gtc/matrix_transform.hpp>
 #include <glm/gtc/constants.hpp>
 #include <glm/ext/matrix_relational.hpp>
+#include <glm/ext/scalar_relational.hpp>
 
 int test_perspective()
 {
 	int Error = 0;
 
-	glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, 4.0f / 3.0f, 0.1f, 100.0f);
+	const float Near = 0.1f;
+	const float Far = 100.0f;
+	const float Eps = glm::epsilon<float>();
+
+	glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, 4.0f / 3.0f, Near, Far);
+
+	Projection = glm::perspectiveLH_ZO(glm::pi<float>() * 0.25f, 4.0f / 3.0f, Near, Far);
+	{
+		glm::vec4 N = Projection * glm::vec4{0.f, 0.f, Near, 1.f};
+		glm::vec4 F = Projection * glm::vec4{0.f, 0.f, Far, 1.f};
+		N /= N.w;
+		F /= F.w;
+		Error += glm::notEqual(N.z, 0.f, Eps);
+		Error += glm::notEqual(F.z, 1.f, Eps);
+	}
+
+	Projection = glm::perspectiveLH_NO(glm::pi<float>() * 0.25f, 4.0f / 3.0f, Near, Far);
+	{
+		glm::vec4 N = Projection * glm::vec4{0.f, 0.f, Near, 1.f};
+		glm::vec4 F = Projection * glm::vec4{0.f, 0.f, Far, 1.f};
+		N /= N.w;
+		F /= F.w;
+		Error += glm::notEqual(N.z, -1.f, Eps);
+		Error += glm::notEqual(F.z, 1.f, Eps);
+	}
+
+	return Error;
+}
+
+int test_infinitePerspective()
+{
+	int Error = 0;
+
+	const float Near = 0.1f;
+	const float Inf = 1.0e+10f;
+	const float Eps = glm::epsilon<float>();
+
+	glm::mat4 Projection = glm::infinitePerspective(glm::pi<float>() * 0.25f, 4.0f / 3.0f, Near);
+
+	Projection = glm::infinitePerspectiveLH_ZO(glm::pi<float>() * 0.25f, 4.0f / 3.0f, Near);
+	{
+		glm::vec4 N = Projection * glm::vec4{0.f, 0.f, Near, 1.f};
+		glm::vec4 F = Projection * glm::vec4{0.f, 0.f, Inf, 1.f};
+		N /= N.w;
+		F /= F.w;
+		Error += glm::notEqual(N.z, 0.f, Eps);
+		Error += glm::notEqual(F.z, 1.f, Eps);
+	}
+
+	Projection = glm::infinitePerspectiveLH_NO(glm::pi<float>() * 0.25f, 4.0f / 3.0f, Near);
+	{
+		glm::vec4 N = Projection * glm::vec4{0.f, 0.f, Near, 1.f};
+		glm::vec4 F = Projection * glm::vec4{0.f, 0.f, Inf, 1.f};
+		N /= N.w;
+		F /= F.w;
+		Error += glm::notEqual(N.z, -1.f, Eps);
+		Error += glm::notEqual(F.z, 1.f, Eps);
+	}
 
 	return Error;
 }
@@ -50,6 +108,7 @@ int main()
 	Error += test_tweakedInfinitePerspective();
 	Error += test_pick();
 	Error += test_perspective();
+	Error += test_infinitePerspective();
 
 	return Error;
 }