Browse Source

Added 'fmod' overload to GTX_common with tests, Removed integer specification for 'mod' in GTC_integer #308

Christophe Riccio 10 years ago
parent
commit
042270d049

+ 0 - 9
glm/gtc/integer.inl

@@ -61,14 +61,5 @@ namespace detail
 			}
 		};
 #	endif//GLM_HAS_BITSCAN_WINDOWS
-
-	template <typename T, precision P, template <class, precision> class vecType, typename genType>
-	struct compute_mod<T, P, vecType, genType, false>
-	{
-		GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & a, genType const & b)
-		{
-			return a % b;
-		}
-	};
 }//namespace detail
 }//namespace glm

+ 8 - 0
glm/gtx/common.hpp

@@ -68,6 +68,14 @@ namespace glm
 	template <typename genType> 
 	GLM_FUNC_DECL typename genType::bool_type isdenormal(genType const & x);
 
+	/// Similiar to 'mod' but with a different rounding and integer support.
+	/// Returns 'x - y * trunc(x/y)' instead of 'x - y * floor(x/y)'
+	/// 
+	/// @see <a href="http://stackoverflow.com/questions/7610631/glsl-mod-vs-hlsl-fmod">GLSL mod vs HLSL fmod</a>
+	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> fmod(vecType<T, P> const & v);
+
 	/// @}
 }//namespace glm
 

+ 40 - 1
glm/gtx/common.inl

@@ -32,8 +32,28 @@
 
 #include <cmath>
 
-namespace glm
+namespace glm{
+namespace detail
 {
+	template <typename T, precision P, template <class, precision> class vecType, bool isFloat = true>
+	struct compute_fmod
+	{
+		GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & a, vecType<T, P> const & b)
+		{
+			return detail::functor2<T, P, vecType>::call(std::fmod, a, b);
+		}
+	};
+
+	template <typename T, precision P, template <class, precision> class vecType>
+	struct compute_fmod<T, P, vecType, false>
+	{
+		GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & a, vecType<T, P> const & b)
+		{
+			return a % b;
+		}
+	};
+}//namespace detail
+
 	template <typename T> 
 	GLM_FUNC_QUALIFIER bool isdenormal(T const & x)
 	{
@@ -99,4 +119,23 @@ namespace glm
 			isdenormal(x.z),
 			isdenormal(x.w));
 	}
+
+	// fmod
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType fmod(genType x, genType y)
+	{
+		return fmod(tvec1<genType>(x), y).x;
+	}
+
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> fmod(vecType<T, P> const & x, T y)
+	{
+		return detail::compute_fmod<T, P, vecType, std::numeric_limits<T>::is_iec559>::call(x, vecType<T, P>(y));
+	}
+
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> fmod(vecType<T, P> const & x, vecType<T, P> const & y)
+	{
+		return detail::compute_fmod<T, P, vecType, std::numeric_limits<T>::is_iec559>::call(x, y);
+	}
 }//namespace glm

+ 5 - 1
readme.txt

@@ -67,12 +67,16 @@ http://glm.g-truc.net/glm.pdf
 GLM 0.9.7.0: 2015-XX-XX
 --------------------------------------------------------------------------------
 Features:
-- Added GTC_color: rgbToSrgb and srgbToRgb functions
+- Added GTC_color: convertRgbToSrgb and convertSrgbToRgb functions
+- Added 'fmod' overload to GTX_common with tests #308
 
 Improvements:
 - Changed usage of __has_include to support Intel compiler #307
 - Specialized integer implementation of YCoCg-R #310
 
+Deprecation:
+- Removed integer specification for 'mod' in GTC_integer #308
+
 ================================================================================
 GLM 0.9.6.2: 2015-02-15
 --------------------------------------------------------------------------------

+ 7 - 1
test/core/core_func_trigonometric.cpp

@@ -30,7 +30,13 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
 #include <glm/trigonometric.hpp>
-
+/*
+float sin(float x) {
+	float temp;
+	temp = (x + M_PI) / ((2 * M_PI) - M_PI);
+	return limited_sin((x + M_PI) - ((2 * M_PI) - M_PI) * temp));
+}
+*/
 int main()
 {
 	int Failed = 0;

+ 1 - 59
test/gtc/gtc_integer.cpp

@@ -42,6 +42,7 @@
 #include <ctime>
 #include <cstdio>
 #include <vector>
+#include <cmath>
 
 namespace log2_
 {
@@ -210,70 +211,11 @@ namespace log2_
 	}
 }//namespace log2_
 
-namespace mod_
-{
-	int test()
-	{
-		int Error(0);
-
-		{
-			float A(3.0);
-			float B(2.0f);
-			float C = glm::mod(A, B);
-
-			Error += glm::abs(C - 1.0f) < 0.00001f ? 0 : 1;
-		}
-
-		{
-			glm::vec4 A(3.0);
-			float B(2.0f);
-			glm::vec4 C = glm::mod(A, B);
-
-			Error += glm::all(glm::epsilonEqual(C, glm::vec4(1.0f), 0.00001f)) ? 0 : 1;
-		}
-
-		{
-			glm::vec4 A(3.0);
-			glm::vec4 B(2.0f);
-			glm::vec4 C = glm::mod(A, B);
-
-			Error += glm::all(glm::epsilonEqual(C, glm::vec4(1.0f), 0.00001f)) ? 0 : 1;
-		}
-
-		{
-			int A(3);
-			int B(2);
-			int C = glm::mod(A, B);
-
-			Error += C == 1 ? 0 : 1;
-		}
-
-		{
-			glm::ivec4 A(3);
-			int B(2);
-			glm::ivec4 C = glm::mod(A, B);
-
-			Error += glm::all(glm::equal(C, glm::ivec4(1))) ? 0 : 1;
-		}
-
-		{
-			glm::ivec4 A(3);
-			glm::ivec4 B(2);
-			glm::ivec4 C = glm::mod(A, B);
-
-			Error += glm::all(glm::equal(C, glm::ivec4(1))) ? 0 : 1;
-		}
-
-		return Error;
-	}
-}//namespace mod_
-
 int main()
 {
 	int Error(0);
 
 	Error += ::log2_::test();
-	Error += ::mod_::test();
 
 #	ifdef NDEBUG
 		Error += ::log2_::perf();

+ 104 - 0
test/gtx/gtx_common.cpp

@@ -30,6 +30,109 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
 #include <glm/gtx/common.hpp>
+#include <glm/gtc/integer.hpp>
+#include <glm/gtc/epsilon.hpp>
+#include <glm/vector_relational.hpp>
+#include <glm/common.hpp>
+
+namespace fmod_
+{
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType modTrunc(genType a, genType b)
+	{
+		return a - b * trunc(a / b);
+	}
+
+	int test()
+	{
+		int Error(0);
+
+		{
+			float A0(3.0);
+			float B0(2.0f);
+			float C0 = glm::fmod(A0, B0);
+
+			Error += glm::abs(C0 - 1.0f) < 0.00001f ? 0 : 1;
+
+			glm::vec4 A1(3.0);
+			float B1(2.0f);
+			glm::vec4 C1 = glm::fmod(A1, B1);
+
+			Error += glm::all(glm::epsilonEqual(C1, glm::vec4(1.0f), 0.00001f)) ? 0 : 1;
+
+			glm::vec4 A2(3.0);
+			glm::vec4 B2(2.0f);
+			glm::vec4 C2 = glm::fmod(A2, B2);
+
+			Error += glm::all(glm::epsilonEqual(C2, glm::vec4(1.0f), 0.00001f)) ? 0 : 1;
+
+			glm::ivec4 A3(3);
+			int B3(2);
+			glm::ivec4 C3 = glm::fmod(A3, B3);
+
+			Error += glm::all(glm::equal(C3, glm::ivec4(1))) ? 0 : 1;
+
+			glm::ivec4 A4(3);
+			glm::ivec4 B4(2);
+			glm::ivec4 C4 = glm::fmod(A4, B4);
+
+			Error += glm::all(glm::equal(C4, glm::ivec4(1))) ? 0 : 1;
+		}
+
+		{
+			float A0(22.0);
+			float B0(-10.0f);
+			float C0 = glm::fmod(A0, B0);
+
+			Error += glm::abs(C0 - 2.0f) < 0.00001f ? 0 : 1;
+
+			glm::vec4 A1(22.0);
+			float B1(-10.0f);
+			glm::vec4 C1 = glm::fmod(A1, B1);
+
+			Error += glm::all(glm::epsilonEqual(C1, glm::vec4(2.0f), 0.00001f)) ? 0 : 1;
+
+			glm::vec4 A2(22.0);
+			glm::vec4 B2(-10.0f);
+			glm::vec4 C2 = glm::fmod(A2, B2);
+
+			Error += glm::all(glm::epsilonEqual(C2, glm::vec4(2.0f), 0.00001f)) ? 0 : 1;
+
+			glm::ivec4 A3(22);
+			int B3(-10);
+			glm::ivec4 C3 = glm::fmod(A3, B3);
+
+			Error += glm::all(glm::equal(C3, glm::ivec4(2))) ? 0 : 1;
+
+			glm::ivec4 A4(22);
+			glm::ivec4 B4(-10);
+			glm::ivec4 C4 = glm::fmod(A4, B4);
+
+			Error += glm::all(glm::equal(C4, glm::ivec4(2))) ? 0 : 1;
+		}
+
+		// http://stackoverflow.com/questions/7610631/glsl-mod-vs-hlsl-fmod
+		{
+			for (float y = -10.0f; y < 10.0f; y += 0.1f)
+			for (float x = -10.0f; x < 10.0f; x += 0.1f)
+			{
+				float const A(std::fmod(x, y));
+				//float const B(std::remainder(x, y));
+				float const C(glm::fmod(x, y));
+				float const D(modTrunc(x, y));
+
+				//Error += glm::epsilonEqual(A, B, 0.0001f) ? 0 : 1;
+				//assert(!Error);
+				Error += glm::epsilonEqual(A, C, 0.0001f) ? 0 : 1;
+				assert(!Error);
+				Error += glm::epsilonEqual(A, D, 0.00001f) ? 0 : 1;
+				assert(!Error);
+			}
+		}
+
+		return Error;
+	}
+}//namespace fmod_
 
 int test_isdenormal()
 {
@@ -49,6 +152,7 @@ int main()
 	int Error(0);
 
 	Error += test_isdenormal();
+	Error += ::fmod_::test();
 
 	return Error;
 }

+ 8 - 0
test/gtx/gtx_fast_trigonometry.cpp

@@ -61,6 +61,14 @@ namespace fastCos
 
 namespace fastSin
 {
+	/*
+	float sin(float x) {
+	float temp;
+	temp = (x + M_PI) / ((2 * M_PI) - M_PI);
+	return limited_sin((x + M_PI) - ((2 * M_PI) - M_PI) * temp));
+	}
+	*/
+
 	int perf()
 	{
 		const float begin = -glm::pi<float>();