From 712e5aa6db15501e5df99ddb68900811bbb6020e Mon Sep 17 00:00:00 2001 From: Zak Strange Date: Tue, 30 Aug 2016 11:58:26 -0700 Subject: [PATCH 1/9] Fixed issue #33, #32, #27, #30 --- HandmadeMath.h | 54 +++++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/HandmadeMath.h b/HandmadeMath.h index 540d512..68b09fd 100644 --- a/HandmadeMath.h +++ b/HandmadeMath.h @@ -1,5 +1,5 @@ /* - HandmadeMath.h v0.5.2 + HandmadeMath.h v0.6 This is a single header file with a bunch of useful functions for basic game math operations. @@ -122,7 +122,15 @@ 0.5.2 (*) Fixed SSE code in HMM_SqrtF (*) Fixed SSE code in HMM_RSqrtF - + 0.6 + (*) Added Unit testing + (*) Made HMM_Power faster + (*) Fixed possible efficiency problem with HMM_Normalize + (*) RENAMED HMM_LengthSquareRoot to HMM_LengthSquared + (*) RENAMED HMM_RSqrtF to HMM_RSquareRootF + (*) RENAMED HMM_SqrtF to HMM_SquareRootF + (*) REMOVED Inner function (user should use Dot now) + (*) REMOVED HMM_FastInverseSquareRoot function declaration LICENSE @@ -147,10 +155,6 @@ Insofaras (@insofaras) */ -// NOTE(zak): I think this is the include for SSE 2 on -// MacOS, Windows, and Linux if im wrong just open up -// a issue and tell me, or submit a pull request -// with the fix. #include #ifndef HANDMADE_MATH_H @@ -334,12 +338,11 @@ typedef hmm_mat4 hmm_m4; HMMDEF float HMM_SinF(float Angle); HMMDEF float HMM_TanF(float Angle); HMMDEF float HMM_CosF(float Angle); -HMMDEF float HMM_SqrtF(float Angle); HMMDEF float HMM_ToRadians(float Degrees); -HMMDEF float HMM_Inner(hmm_vec3 A, hmm_vec3 B); -HMMDEF float HMM_SquareRoot(float Float); -HMMDEF float HMM_LengthSquareRoot(hmm_vec3 A); +HMMDEF float HMM_SquareRootF(float Float); +HMMDEF float HMM_RSquareRootF(float Float); +HMMDEF float HMM_LengthSquared(hmm_vec3 A); HMMDEF float HMM_FastInverseSquareRoot(float Number); HMMDEF float HMM_Length(hmm_vec3 A); HMMDEF float HMM_Power(float Base, int Exponent); @@ -528,7 +531,7 @@ HMM_TanF(float Radians) } HINLINE float -HMM_SqrtF(float Value) +HMM_SquareRootF(float Value) { float Result = 0; @@ -544,7 +547,7 @@ HMM_SqrtF(float Value) } HINLINE float -HMM_RSqrtF(float Value) +HMM_RSquareRootF(float Value) { float Result = 0; @@ -569,20 +572,20 @@ HMM_ToRadians(float Degrees) } HINLINE float -HMM_Inner(hmm_vec3 A, hmm_vec3 B) +HMM_Dot(hmm_vec3 VecOne, hmm_vec3 VecTwo) { float Result = 0; - Result = A.X * B.X + A.Y * B.Y + A.Z * B.Z; + Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z); return (Result); } HINLINE float -HMM_LengthSquareRoot(hmm_vec3 A) +HMM_LengthSquared(hmm_vec3 A) { float Result = 0; - Result = HMM_Inner(A, A); + Result = HMM_Dot(A, A); return (Result); } @@ -591,7 +594,7 @@ HMM_Length(hmm_vec3 A) { float Result = 0; - Result = HMM_SqrtF(HMM_LengthSquareRoot(A)); + Result = HMM_SquareRootF(HMM_LengthSquared(A)); return (Result); } @@ -646,9 +649,11 @@ HMM_Normalize(hmm_vec3 A) { hmm_vec3 Result = {0}; - Result.X = A.X * (1.0f / HMM_Length(A)); - Result.Y = A.Y * (1.0f / HMM_Length(A)); - Result.Z = A.Z * (1.0f / HMM_Length(A)); + float VectorLength = HMM_Length(A); + + Result.X = A.X * (1.0f / VectorLength); + Result.Y = A.Y * (1.0f / VectorLength); + Result.Z = A.Z * (1.0f / VectorLength); return (Result); } @@ -665,15 +670,6 @@ HMM_Cross(hmm_vec3 VecOne, hmm_vec3 VecTwo) return (Result); } -HINLINE float -HMM_Dot(hmm_vec3 VecOne, hmm_vec3 VecTwo) -{ - float Result = 0; - - Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z); - return (Result); -} - HINLINE hmm_vec2 HMM_Vec2(float X, float Y) { From b087efc561c05b091cfb57d03697987d4118384f Mon Sep 17 00:00:00 2001 From: Zak Strange Date: Tue, 30 Aug 2016 12:05:33 -0700 Subject: [PATCH 2/9] Added HMM_DotVec2, HMM_DotVec3, and HMM_DotVec4 --- HandmadeMath.h | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/HandmadeMath.h b/HandmadeMath.h index 68b09fd..f09af26 100644 --- a/HandmadeMath.h +++ b/HandmadeMath.h @@ -350,7 +350,10 @@ HMMDEF float HMM_Clamp(float Min, float Value, float Max); HMMDEF hmm_vec3 HMM_Normalize(hmm_vec3 A); HMMDEF hmm_vec3 HMM_Cross(hmm_vec3 VecOne, hmm_vec3 VecTwo); -HMMDEF float HMM_Dot(hmm_vec3 VecOne, hmm_vec3 VecTwo); + +HMMDEF float HMM_DotVec2(hmm_vec3 VecOne, hmm_vec3 VecTwo); +HMMDEF float HMM_DotVec3(hmm_vec3 VecOne, hmm_vec3 VecTwo); +HMMDEF float HMM_DotVec4(hmm_vec3 VecOne, hmm_vec3 VecTwo); HMMDEF hmm_vec2 HMM_Vec2i(int X, int Y); HMMDEF hmm_vec2 HMM_Vec2(float X, float Y); @@ -571,8 +574,18 @@ HMM_ToRadians(float Degrees) return (Result); } + HINLINE float -HMM_Dot(hmm_vec3 VecOne, hmm_vec3 VecTwo) +HMM_DotVec2(hmm_vec2 VecOne, hmm_vec2 VecTwo) +{ + float Result = 0; + + Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y); + return (Result); +} + +HINLINE float +HMM_DotVec3(hmm_vec3 VecOne, hmm_vec3 VecTwo) { float Result = 0; @@ -580,12 +593,23 @@ HMM_Dot(hmm_vec3 VecOne, hmm_vec3 VecTwo) return (Result); } + +HINLINE float +HMM_DotVec4(hmm_vec4 VecOne, hmm_vec4 VecTwo) +{ + float Result = 0; + + Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z); + return (Result); +} + + HINLINE float HMM_LengthSquared(hmm_vec3 A) { float Result = 0; - Result = HMM_Dot(A, A); + Result = HMM_DotVec3(A, A); return (Result); } @@ -1199,9 +1223,9 @@ HMM_LookAt(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up) Result.Elements[2][1] = U.Z; Result.Elements[2][2] = -F.Z; - Result.Elements[3][0] = -HMM_Dot(S, Eye); - Result.Elements[3][1] = -HMM_Dot(U, Eye); - Result.Elements[3][2] = HMM_Dot(F, Eye); + Result.Elements[3][0] = -HMM_DotVec3(S, Eye); + Result.Elements[3][1] = -HMM_DotVec3(U, Eye); + Result.Elements[3][2] = HMM_DotVec3(F, Eye); Result.Elements[3][3] = 1.0f; return (Result); From 857860279905ba8a167fb6648b4f8b40337eafef Mon Sep 17 00:00:00 2001 From: Zak Strange Date: Tue, 30 Aug 2016 13:24:55 -0700 Subject: [PATCH 3/9] Fixed issues in last commit and added a function overloaded HMM_Dot --- HandmadeMath.h | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/HandmadeMath.h b/HandmadeMath.h index f09af26..29b7e89 100644 --- a/HandmadeMath.h +++ b/HandmadeMath.h @@ -343,7 +343,6 @@ HMMDEF float HMM_ToRadians(float Degrees); HMMDEF float HMM_SquareRootF(float Float); HMMDEF float HMM_RSquareRootF(float Float); HMMDEF float HMM_LengthSquared(hmm_vec3 A); -HMMDEF float HMM_FastInverseSquareRoot(float Number); HMMDEF float HMM_Length(hmm_vec3 A); HMMDEF float HMM_Power(float Base, int Exponent); HMMDEF float HMM_Clamp(float Min, float Value, float Max); @@ -351,9 +350,9 @@ HMMDEF float HMM_Clamp(float Min, float Value, float Max); HMMDEF hmm_vec3 HMM_Normalize(hmm_vec3 A); HMMDEF hmm_vec3 HMM_Cross(hmm_vec3 VecOne, hmm_vec3 VecTwo); -HMMDEF float HMM_DotVec2(hmm_vec3 VecOne, hmm_vec3 VecTwo); +HMMDEF float HMM_DotVec2(hmm_vec2 VecOne, hmm_vec2 VecTwo); HMMDEF float HMM_DotVec3(hmm_vec3 VecOne, hmm_vec3 VecTwo); -HMMDEF float HMM_DotVec4(hmm_vec3 VecOne, hmm_vec3 VecTwo); +HMMDEF float HMM_DotVec4(hmm_vec4 VecOne, hmm_vec4 VecTwo); HMMDEF hmm_vec2 HMM_Vec2i(int X, int Y); HMMDEF hmm_vec2 HMM_Vec2(float X, float Y); @@ -408,6 +407,11 @@ HMMDEF hmm_mat4 HMM_LookAt(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up); #ifdef HANDMADE_MATH_CPP_MODE + +HMMDEF float HMM_Dot(hmm_vec2 VecOne, hmm_vec2 VecTwo); +HMMDEF float HMM_Dot(hmm_vec3 VecOne, hmm_vec3 VecTwo); +HMMDEF float HMM_Dot(hmm_vec4 VecOne, hmm_vec4 VecTwo); + HMMDEF hmm_vec2 HMM_Add(hmm_vec2 Left, hmm_vec2 Right); HMMDEF hmm_vec3 HMM_Add(hmm_vec3 Left, hmm_vec3 Right); HMMDEF hmm_vec4 HMM_Add(hmm_vec4 Left, hmm_vec4 Right); @@ -1245,6 +1249,36 @@ HMM_Scale(hmm_vec3 Scale) #ifdef HANDMADE_MATH_CPP_MODE +HINLINE float +HMM_Dot(hmm_vec2 VecOne, hmm_vec2 VecTwo) +{ + float Result = 0; + + Result = HMM_DotVec2(VecOne, VecTwo); + + return(Result); +} + +HINLINE float +HMM_Dot(hmm_vec3 VecOne, hmm_vec3 VecTwo) +{ + float Result = 0; + + Result = HMM_DotVec3(VecOne, VecTwo); + + return(Result); +} + +HMMDEF float +HMM_Dot(hmm_vec4 VecOne, hmm_vec4 VecTwo) +{ + float Result = 0; + + Result = HMM_DotVec4(VecOne, VecTwo); + + return(Result); +} + HINLINE hmm_vec2 HMM_Add(hmm_vec2 Left, hmm_vec2 Right) { From c147a8bd53caa8ec43c3f07cf7a872ee156d9b55 Mon Sep 17 00:00:00 2001 From: Zak Strange Date: Tue, 30 Aug 2016 13:30:52 -0700 Subject: [PATCH 4/9] Updated Unit Test --- test/hmm_test.cpp | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/test/hmm_test.cpp b/test/hmm_test.cpp index 824e58c..a8adb80 100644 --- a/test/hmm_test.cpp +++ b/test/hmm_test.cpp @@ -71,6 +71,11 @@ TEST(ScalarMath, Clamp) EXPECT_FLOAT_EQ(HMM_Clamp(-2.0f, 3.0f, 2.0f), 2.0f); } +TEST(ScalarMath, RSquareRootF) +{ + EXPECT_FLOAT_EQ(HMM_RSquareRootF(16.0f), 0.25f); +} + TEST(Initialization, Vectors) { // @@ -150,14 +155,6 @@ TEST(Initialization, MatrixDiagonal) } } -TEST(VectorOps, Inner) -{ - hmm_vec3 v1 = HMM_Vec3(1.0f, 2.0f, 3.0f); - hmm_vec3 v2 = HMM_Vec3(4.0f, 5.0f, 6.0f); - - EXPECT_FLOAT_EQ(HMM_Inner(v1, v2), 32.0f); -} - TEST(VectorOps, LengthSquareRoot) { hmm_vec3 v = HMM_Vec3(1.0f, -2.0f, 3.0f); @@ -194,12 +191,28 @@ TEST(VectorOps, Cross) EXPECT_FLOAT_EQ(result.Z, -3.0f); } -TEST(VectorOps, Dot) +TEST(VectorOps, DotVec2) +{ + hmm_vec2 v1 = HMM_Vec2(1.0f, 2.0f); + hmm_vec2 v2 = HMM_Vec2(3.0f, 4.0f); + + EXPECT_FLOAT_EQ(HMM_DotVec2(v1, v2), 11.0f); +} + +TEST(VectorOps, DotVec3) { hmm_vec3 v1 = HMM_Vec3(1.0f, 2.0f, 3.0f); hmm_vec3 v2 = HMM_Vec3(4.0f, 5.0f, 6.0f); - EXPECT_FLOAT_EQ(HMM_Inner(v1, v2), 32.0f); + EXPECT_FLOAT_EQ(HMM_DotVec3(v1, v2), 32.0f); +} + +TEST(VectorOps, DotVec4) +{ + hmm_vec4 v1 = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f); + hmm_vec4 v2 = HMM_Vec4(5.0f, 6.0f, 7.0f, 8.0f); + + EXPECT_FLOAT_EQ(HMM_DotVec4(v1, v2), 70.0f); } TEST(Addition, Vec2) From c2dd9f19a7f8ca70f85968e09ef10f7435e57658 Mon Sep 17 00:00:00 2001 From: Zak Strange Date: Tue, 30 Aug 2016 13:33:15 -0700 Subject: [PATCH 5/9] Fixed more issues in Unit test --- test/hmm_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hmm_test.cpp b/test/hmm_test.cpp index a8adb80..0dd6b16 100644 --- a/test/hmm_test.cpp +++ b/test/hmm_test.cpp @@ -35,7 +35,7 @@ TEST(ScalarMath, Trigonometry) TEST(ScalarMath, SqrtF) { - EXPECT_FLOAT_EQ(HMM_SqrtF(16.0f), 4.0f); + EXPECT_FLOAT_EQ(HMM_SquareRootF(16.0f), 4.0f); } TEST(ScalarMath, ToRadians) @@ -159,7 +159,7 @@ TEST(VectorOps, LengthSquareRoot) { hmm_vec3 v = HMM_Vec3(1.0f, -2.0f, 3.0f); - EXPECT_FLOAT_EQ(HMM_LengthSquareRoot(v), 14.0f); + EXPECT_FLOAT_EQ(HMM_LengthSquared(v), 14.0f); } TEST(VectorOps, Length) From fdef0ae0e17ce8487a036f3a6e0d3bfafae9cc0f Mon Sep 17 00:00:00 2001 From: Zak Strange Date: Tue, 30 Aug 2016 13:43:17 -0700 Subject: [PATCH 6/9] Added missing tests to hmm_test.cpp --- test/hmm_test.cpp | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/test/hmm_test.cpp b/test/hmm_test.cpp index 0dd6b16..54a0edf 100644 --- a/test/hmm_test.cpp +++ b/test/hmm_test.cpp @@ -33,11 +33,6 @@ TEST(ScalarMath, Trigonometry) // checking that things work by default. } -TEST(ScalarMath, SqrtF) -{ - EXPECT_FLOAT_EQ(HMM_SquareRootF(16.0f), 4.0f); -} - TEST(ScalarMath, ToRadians) { EXPECT_FLOAT_EQ(HMM_ToRadians(0.0f), 0); @@ -47,33 +42,12 @@ TEST(ScalarMath, ToRadians) TEST(ScalarMath, SquareRoot) { - // EXPECT_FLOAT_EQ(HMM_SquareRoot(16.0f), 4.0f); - FAIL() << "Bad header, function not defined. See commented line above."; -} - -TEST(ScalarMath, FastInverseSquareRoot) -{ - // EXPECT_FLOAT_EQ(HMM_FastInverseSquareRoot(4.0f), 0.5f); // linker error, no function body - FAIL() << "Bad header, function not defined. See commented line above."; -} - -TEST(ScalarMath, Power) -{ - EXPECT_FLOAT_EQ(HMM_Power(2.0f, 0), 1.0f); - EXPECT_FLOAT_EQ(HMM_Power(2.0f, 4), 16.0f); - EXPECT_FLOAT_EQ(HMM_Power(2.0f, -2), 0.25f); -} - -TEST(ScalarMath, Clamp) -{ - EXPECT_FLOAT_EQ(HMM_Clamp(-2.0f, 0.0f, 2.0f), 0.0f); - EXPECT_FLOAT_EQ(HMM_Clamp(-2.0f, -3.0f, 2.0f), -2.0f); - EXPECT_FLOAT_EQ(HMM_Clamp(-2.0f, 3.0f, 2.0f), 2.0f); + EXPECT_FLOAT_EQ(HMM_SquareRootF(16.0f), 4.0f); } TEST(ScalarMath, RSquareRootF) { - EXPECT_FLOAT_EQ(HMM_RSquareRootF(16.0f), 0.25f); + EXPECT_FLOAT_EQ(HMM_RSquareRootF(10.0f), 0.31616211f); } TEST(Initialization, Vectors) From de08310dbd8c647e50d32430803ad29a5e5ea190 Mon Sep 17 00:00:00 2001 From: Zak Strange Date: Tue, 30 Aug 2016 13:46:50 -0700 Subject: [PATCH 7/9] Fixed HMM_Vec4 --- HandmadeMath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HandmadeMath.h b/HandmadeMath.h index 29b7e89..7981a46 100644 --- a/HandmadeMath.h +++ b/HandmadeMath.h @@ -603,7 +603,7 @@ HMM_DotVec4(hmm_vec4 VecOne, hmm_vec4 VecTwo) { float Result = 0; - Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z); + Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z) + (VecOne.W * VecTwo.W); return (Result); } From 86dfb43c1f9a672fc7faf642d2981c494d906ea2 Mon Sep 17 00:00:00 2001 From: Zak Strange Date: Tue, 30 Aug 2016 13:55:14 -0700 Subject: [PATCH 8/9] Updated README.md --- README.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 908e42e..51e57b1 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,14 @@ # Handmade-Math ------ +[![Build Status](https://travis-ci.org/StrangeZak/Handmade-Math.svg?branch=master)](https://travis-ci.org/StrangeZak/Handmade-Math) + Single-file cross-platform public domain game math library for C/C++ Version | Changes | ----------------|----------------| +**0.6** | Made HMM_Power faster, Fixed possible efficiency problem with HMM_Normalize, RENAMED HMM_LengthSquareRoot to HMM_LengthSquared, RENAMED HMM_RSqrtF to HMM_RSquareRootF, RENAMED HMM_SqrtF to HMM_SquareRootF, REMOVED Inner function (user should use Dot now), REMOVED HMM_FastInverseSquareRoot function declaration | **0.5.2** | Fixed SSE code in HMM_SqrtF and HMM_RSqrtF | **0.5.1** | Fixed HMM_Translate producing row-major matrices, ensured column-major order for matrices throughout | **0.5** | Added scalar operations on vectors and matrices, added += and -= for hmm_mat4, reconciled headers and implementations, tidied up in general | @@ -32,12 +35,3 @@ This library is in the public domain. You can do whatever you want with them. **Where can I contact you to ask questions?** You can email me at: Zak@Handmade.Network - - -## Testing - -```shell -cd test -make -./hmm_test -``` From c7c801c51a86ee4073e92d1fd1ec35630b74b526 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Tue, 30 Aug 2016 15:55:21 -0500 Subject: [PATCH 9/9] Test overloaded versions of HMM_Dot --- test/hmm_test.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/hmm_test.cpp b/test/hmm_test.cpp index 54a0edf..c62e706 100644 --- a/test/hmm_test.cpp +++ b/test/hmm_test.cpp @@ -171,6 +171,7 @@ TEST(VectorOps, DotVec2) hmm_vec2 v2 = HMM_Vec2(3.0f, 4.0f); EXPECT_FLOAT_EQ(HMM_DotVec2(v1, v2), 11.0f); + EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 11.0f); } TEST(VectorOps, DotVec3) @@ -179,6 +180,7 @@ TEST(VectorOps, DotVec3) hmm_vec3 v2 = HMM_Vec3(4.0f, 5.0f, 6.0f); EXPECT_FLOAT_EQ(HMM_DotVec3(v1, v2), 32.0f); + EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 32.0f); } TEST(VectorOps, DotVec4) @@ -187,6 +189,7 @@ TEST(VectorOps, DotVec4) hmm_vec4 v2 = HMM_Vec4(5.0f, 6.0f, 7.0f, 8.0f); EXPECT_FLOAT_EQ(HMM_DotVec4(v1, v2), 70.0f); + EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 70.0f); } TEST(Addition, Vec2)