diff --git a/HandmadeMath.h b/HandmadeMath.h index 5e9301b..ccf1be1 100644 --- a/HandmadeMath.h +++ b/HandmadeMath.h @@ -1,10 +1,10 @@ /* - HandmadeMath.h v1.1.5 + HandmadeMath.h v1.1.6 This is a single header file with a bunch of useful functions for basic game math operations. - ========================================================================== + ============================================================================= You MUST @@ -18,7 +18,7 @@ All other files should just #include "HandmadeMath.h" without the #define. - ========================================================================== + ============================================================================= For overloaded and operator overloaded versions of the base C functions, you MUST @@ -34,7 +34,7 @@ All other files should just #include "HandmadeMath.h" without the #define. - ========================================================================== + ============================================================================= To disable SSE intrinsics, you MUST @@ -54,7 +54,7 @@ #define HANDMADE_MATH_NO_SSE #include "HandmadeMath.h" - ========================================================================== + ============================================================================= To disable inlining functions, you MUST @@ -70,7 +70,7 @@ All other files should just #include "HandmadeMath.h" without the #define. - ========================================================================== + ============================================================================= To use HandmadeMath without the CRT, you MUST @@ -84,9 +84,9 @@ #define HMM_ATANF MyATanF #define HMM_ATAN2F MYATan2F - Provide your own implementations of SinF, CosF, TanF, ACosF, ATanF, ATan2F, ExpF and LogF - in EXACTLY one C or C++ file that includes this header, BEFORE the - include, like this: + Provide your own implementations of SinF, CosF, TanF, ACosF, ATanF, ATan2F, + ExpF, and LogF in EXACTLY one C or C++ file that includes this header, + BEFORE the include, like this: #define HMM_SINF MySinF #define HMM_COSF MyCosF @@ -104,7 +104,7 @@ If you do not define all five of these, HandmadeMath.h will use the versions of these functions that are provided by the CRT. - ========================================================================== + ============================================================================= Version History: 0.2 (*) Updated documentation @@ -144,9 +144,15 @@ (*) REMOVED Inner function (user should use Dot now) (*) REMOVED HMM_FastInverseSquareRoot function declaration 0.7 - (*) REMOVED HMM_LengthSquared in HANDMADE_MATH_IMPLEMENTATION (should use HMM_LengthSquaredVec3, or HANDMADE_MATH_CPP_MODE for function overloaded version) - (*) REMOVED HMM_Length in HANDMADE_MATH_IMPLEMENTATION (should use HMM_LengthVec3, HANDMADE_MATH_CPP_MODE for function overloaded version) - (*) REMOVED HMM_Normalize in HANDMADE_MATH_IMPLEMENTATION (should use HMM_NormalizeVec3, or HANDMADE_MATH_CPP_MODE for function overloaded version) + (*) REMOVED HMM_LengthSquared in HANDMADE_MATH_IMPLEMENTATION (should + use HMM_LengthSquaredVec3, or HANDMADE_MATH_CPP_MODE for function + overloaded version) + (*) REMOVED HMM_Length in HANDMADE_MATH_IMPLEMENTATION (should use + HMM_LengthVec3, HANDMADE_MATH_CPP_MODE for function + overloaded version) + (*) REMOVED HMM_Normalize in HANDMADE_MATH_IMPLEMENTATION (should use + HMM_NormalizeVec3, or HANDMADE_MATH_CPP_MODE for function + overloaded version) (*) Added HMM_LengthSquaredVec2 (*) Added HMM_LengthSquaredVec4 (*) Addd HMM_LengthVec2 @@ -183,6 +189,13 @@ 1.1.5 (*) Add Width and Height to HMM_Vec2 (*) Made it so you can supply your own SqrtF + 1.2.0 + (*) Added equality functions for HMM_Vec2, HMM_Vec3, and HMM_Vec4. + (*) Added HMM_EqualsVec2, HMM_EqualsVec3, and HMM_EqualsVec4 + (*) Added C++ overloaded HMM_Equals for all three + (*) Added C++ == and != operators for all three + (*) SSE'd HMM_MultiplyMat4 (this is _WAY_ faster) + (*) SSE'd HMM_Transpose LICENSE @@ -228,6 +241,7 @@ #endif /* #ifndef HANDMADE_MATH_NO_SSE */ +#include // This is for types #ifdef HANDMADE_MATH__USE_SSE #include @@ -440,6 +454,11 @@ typedef union hmm_vec4 typedef union hmm_mat4 { float Elements[4][4]; + + +#ifdef HANDMADE_MATH__USE_SSE + __m128 Rows[4]; +#endif } hmm_mat4; typedef union hmm_quaternion @@ -461,6 +480,8 @@ typedef union hmm_quaternion float Elements[4]; } hmm_quaternion; +typedef int32_t hmm_bool; + typedef hmm_vec2 hmm_v2; typedef hmm_vec3 hmm_v3; typedef hmm_vec4 hmm_v4; @@ -532,10 +553,19 @@ HMMDEF hmm_vec3 HMM_DivideVec3f(hmm_vec3 Left, float Right); HMMDEF hmm_vec4 HMM_DivideVec4(hmm_vec4 Left, hmm_vec4 Right); HMMDEF hmm_vec4 HMM_DivideVec4f(hmm_vec4 Left, float Right); +HMMDEF hmm_bool HMM_EqualsVec2(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_bool HMM_EqualsVec3(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_bool HMM_EqualsVec4(hmm_vec4 Left, hmm_vec4 Right); + HMMDEF hmm_mat4 HMM_Mat4(void); HMMDEF hmm_mat4 HMM_Mat4d(float Diagonal); HMMDEF hmm_mat4 HMM_AddMat4(hmm_mat4 Left, hmm_mat4 Right); HMMDEF hmm_mat4 HMM_SubtractMat4(hmm_mat4 Left, hmm_mat4 Right); + +#ifdef HANDMADE_MATH__USE_SSE +HMMDEF __m128 HMM_LinearCombineSSE(__m128 Left, hmm_mat4 Right); +#endif + HMMDEF hmm_mat4 HMM_MultiplyMat4(hmm_mat4 Left, hmm_mat4 Right); HMMDEF hmm_mat4 HMM_MultiplyMat4f(hmm_mat4 Matrix, float Scalar); HMMDEF hmm_vec4 HMM_MultiplyMat4ByVec4(hmm_mat4 Matrix, hmm_vec4 Vector); @@ -625,6 +655,10 @@ HMMDEF hmm_mat4 HMM_Divide(hmm_mat4 Left, float Right); HMMDEF hmm_quaternion HMM_Divide(hmm_quaternion Left, hmm_quaternion Right); HMMDEF hmm_quaternion HMM_Divide(hmm_quaternion Left, float Right); +HMMDEF hmm_bool HMM_Equals(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_bool HMM_Equals(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_bool HMM_Equals(hmm_vec4 Left, hmm_vec4 Right); + HMMDEF hmm_vec2 operator+(hmm_vec2 Left, hmm_vec2 Right); HMMDEF hmm_vec3 operator+(hmm_vec3 Left, hmm_vec3 Right); HMMDEF hmm_vec4 operator+(hmm_vec4 Left, hmm_vec4 Right); @@ -699,6 +733,14 @@ HMMDEF hmm_vec4 &operator/=(hmm_vec4 &Left, float Right); HMMDEF hmm_mat4 &operator/=(hmm_mat4 &Left, float Right); HMMDEF hmm_quaternion &operator/=(hmm_quaternion &Left, float Right); +HMMDEF hmm_bool operator==(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_bool operator==(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_bool operator==(hmm_vec4 Left, hmm_vec4 Right); + +HMMDEF hmm_bool operator!=(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_bool operator!=(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_bool operator!=(hmm_vec4 Left, hmm_vec4 Right); + #endif /* HANDMADE_MATH_CPP */ #ifdef __clang__ @@ -1329,6 +1371,36 @@ HMM_DivideVec4f(hmm_vec4 Left, float Right) return (Result); } +HINLINE hmm_bool +HMM_EqualsVec2(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_bool Result = 0; + + Result = (Left.X == Right.X && Left.Y == Right.Y); + + return (Result); +} + +HINLINE hmm_bool +HMM_EqualsVec3(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_bool Result = 0; + + Result = (Left.X == Right.X && Left.Y == Right.Y && Left.Z == Right.Z); + + return (Result); +} + +HINLINE hmm_bool +HMM_EqualsVec4(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_bool Result = 0; + + Result = (Left.X == Right.X && Left.Y == Right.Y && Left.Z == Right.Z && Left.W == Right.W); + + return (Result); +} + HINLINE hmm_mat4 HMM_Mat4(void) { @@ -1386,11 +1458,38 @@ HMM_SubtractMat4(hmm_mat4 Left, hmm_mat4 Right) return (Result); } +#ifdef HANDMADE_MATH__USE_SSE +HINLINE __m128 +HMM_LinearCombineSSE(__m128 Left, hmm_mat4 Right) +{ + __m128 Result = {}; + Result = _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0x00), Right.Rows[0]); + Result = _mm_add_ps(Result, _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0x55), Right.Rows[1])); + Result = _mm_add_ps(Result, _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0xaa), Right.Rows[2])); + Result = _mm_add_ps(Result, _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0xff), Right.Rows[3])); + + return(Result); +} +#endif + HINLINE hmm_mat4 HMM_MultiplyMat4(hmm_mat4 Left, hmm_mat4 Right) { hmm_mat4 Result = HMM_Mat4(); +#ifdef HANDMADE_MATH__USE_SSE + + hmm_mat4 TransposedLeft = HMM_Transpose(Left); + hmm_mat4 TransposedRight = HMM_Transpose(Right); + + Result.Rows[0] = HMM_LinearCombineSSE(TransposedLeft.Rows[0], TransposedRight); + Result.Rows[1] = HMM_LinearCombineSSE(TransposedLeft.Rows[1], TransposedRight); + Result.Rows[2] = HMM_LinearCombineSSE(TransposedLeft.Rows[2], TransposedRight); + Result.Rows[3] = HMM_LinearCombineSSE(TransposedLeft.Rows[3], TransposedRight); + + Result = HMM_Transpose(Result); + +#else int Columns; for(Columns = 0; Columns < 4; ++Columns) { @@ -1407,7 +1506,7 @@ HMM_MultiplyMat4(hmm_mat4 Left, hmm_mat4 Right) Result.Elements[Columns][Rows] = Sum; } } - +#endif return (Result); } @@ -1472,6 +1571,11 @@ HMM_Transpose(hmm_mat4 Matrix) { hmm_mat4 Result = HMM_Mat4(); +#ifdef HANDMADE_MATH__USE_SSE + Result = Matrix; + + _MM_TRANSPOSE4_PS(Result.Rows[0], Result.Rows[1], Result.Rows[2], Result.Rows[3]); +#else int Columns; for(Columns = 0; Columns < 4; ++Columns) { @@ -1481,7 +1585,8 @@ HMM_Transpose(hmm_mat4 Matrix) Result.Elements[Rows][Columns] = Matrix.Elements[Columns][Rows]; } } - +#endif + return (Result); } @@ -2239,6 +2344,33 @@ HMM_Divide(hmm_quaternion Left, float Right) return (Result); } +HINLINE hmm_bool +HMM_Equals(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_bool Result = 0; + + Result = HMM_EqualsVec2(Left, Right); + return (Result); +} + +HINLINE hmm_bool +HMM_Equals(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_bool Result = 0; + + Result = HMM_EqualsVec3(Left, Right); + return (Result); +} + +HINLINE hmm_bool +HMM_Equals(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_bool Result = 0; + + Result = HMM_EqualsVec4(Left, Right); + return (Result); +} + HINLINE hmm_vec2 operator+(hmm_vec2 Left, hmm_vec2 Right) { @@ -2701,6 +2833,43 @@ operator*=(hmm_quaternion &Left, float Right) return (Left = Left * Right); } +HINLINE hmm_bool +operator==(hmm_vec2 Left, hmm_vec2 Right) +{ + return HMM_EqualsVec2(Left, Right); +} + +HINLINE hmm_bool +operator==(hmm_vec3 Left, hmm_vec3 Right) +{ + return HMM_EqualsVec3(Left, Right); +} + +HINLINE hmm_bool +operator==(hmm_vec4 Left, hmm_vec4 Right) +{ + return HMM_EqualsVec4(Left, Right); +} + + +HINLINE hmm_bool +operator!=(hmm_vec2 Left, hmm_vec2 Right) +{ + return !HMM_EqualsVec2(Left, Right); +} + +HINLINE hmm_bool +operator!=(hmm_vec3 Left, hmm_vec3 Right) +{ + return !HMM_EqualsVec3(Left, Right); +} + +HINLINE hmm_bool +operator!=(hmm_vec4 Left, hmm_vec4 Right) +{ + return !HMM_EqualsVec4(Left, Right); +} + #endif /* HANDMADE_MATH_CPP_MODE */ #endif /* HANDMADE_MATH_IMPLEMENTATION */ diff --git a/README.md b/README.md index e785fb4..68a74d3 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ _This library is free and will stay free, but if you would like to support devel Version | Changes | ----------------|----------------| +**1.2.0** | Added equality functions for `HMM_Vec2`, `HMM_Vec3`, and `HMM_Vec4`, and SSE'd `HMM_MultiplyMat4` and `HMM_Transpose`. **1.1.5** | Added `Width` and `Height` to `HMM_Vec2`, and made it so you can supply your own `SqrtF`. **1.1.4** | Fixed SSE being included on platforms that don't support it, and fixed divide-by-zero errors when normalizing zero vectors. **1.1.3** | Fixed compile error in C mode diff --git a/test/HandmadeMath.cpp b/test/HandmadeMath.cpp index 5514f0b..aa4c075 100644 --- a/test/HandmadeMath.cpp +++ b/test/HandmadeMath.cpp @@ -1,5 +1,2 @@ - -#define HANDMADE_MATH_IMPLEMENTATION -#define HANDMADE_MATH_CPP_MODE -#define HANDMADE_MATH_NO_INLINE -#include "../HandmadeMath.h" +#include "HandmadeMath.c" +// C++ compilers complain when compiling a .c file... diff --git a/test/HandmadeMath_NoSSE.c b/test/HandmadeMath_NoSSE.c deleted file mode 100644 index 64e88c6..0000000 --- a/test/HandmadeMath_NoSSE.c +++ /dev/null @@ -1,5 +0,0 @@ - -#define HANDMADE_MATH_IMPLEMENTATION -#define HANDMADE_MATH_NO_SSE -#define HANDMADE_MATH_NO_INLINE -#include "../HandmadeMath.h" diff --git a/test/HandmadeMath_NoSSE.cpp b/test/HandmadeMath_NoSSE.cpp deleted file mode 100644 index 1ee7f09..0000000 --- a/test/HandmadeMath_NoSSE.cpp +++ /dev/null @@ -1,6 +0,0 @@ - -#define HANDMADE_MATH_IMPLEMENTATION -#define HANDMADE_MATH_CPP_MODE -#define HANDMADE_MATH_NO_SSE -#define HANDMADE_MATH_NO_INLINE -#include "../HandmadeMath.h" diff --git a/test/HandmadeTest.h b/test/HandmadeTest.h index aa0e0dd..9eb3652 100644 --- a/test/HandmadeTest.h +++ b/test/HandmadeTest.h @@ -45,6 +45,20 @@ int hmt_count_failures = 0; /* * Asserts and expects */ +#define EXPECT_TRUE(_actual) do { \ + if (!(_actual)) { \ + CASE_FAIL(); \ + printf("Expected true but got something false"); \ + } \ +} while (0) + +#define EXPECT_FALSE(_actual) do { \ + if (_actual) { \ + CASE_FAIL(); \ + printf("Expected false but got something true"); \ + } \ +} while (0) + #define EXPECT_FLOAT_EQ(_actual, _expected) do { \ float actual = (_actual); \ float diff = actual - (_expected); \ diff --git a/test/Makefile b/test/Makefile index 70353ee..d98be3a 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,6 +1,6 @@ -ROOT_DIR = .. +ROOT_DIR=.. -CXXFLAGS += -g -Wall -Wextra -pthread -Wno-missing-braces -Wno-missing-field-initializers +CXXFLAGS+=-g -Wall -Wextra -pthread -Wno-missing-braces -Wno-missing-field-initializers all: c c_no_sse cpp cpp_no_sse @@ -8,17 +8,30 @@ clean: rm -f hmm_test_c hmm_test_cpp hmm_test_c_no_sse hmm_test_cpp_no_sse *.o c: $(ROOT_DIR)/test/HandmadeMath.c test_impl - $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c99 -c $(ROOT_DIR)/test/HandmadeMath.c $(ROOT_DIR)/test/hmm_test.c -lm + @echo "\nCompiling in C mode" + $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c99 \ + -c $(ROOT_DIR)/test/HandmadeMath.c $(ROOT_DIR)/test/hmm_test.c \ + -lm $(CC) -ohmm_test_c HandmadeMath.o hmm_test.o -lm -c_no_sse: $(ROOT_DIR)/test/HandmadeMath_NoSSE.c test_impl - $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c99 -c $(ROOT_DIR)/test/HandmadeMath_NoSSE.c $(ROOT_DIR)/test/hmm_test.c -lm - $(CC) -ohmm_test_c_no_sse HandmadeMath_NoSSE.o hmm_test.o -lm +c_no_sse: $(ROOT_DIR)/test/HandmadeMath.c test_impl + @echo "\nCompiling in C mode (no SSE)" + $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c99 \ + -DHANDMADE_MATH_NO_SSE \ + -c $(ROOT_DIR)/test/HandmadeMath.c $(ROOT_DIR)/test/hmm_test.c \ + -lm + $(CC) -ohmm_test_c_no_sse HandmadeMath.o hmm_test.o -lm cpp: $(ROOT_DIR)/test/HandmadeMath.cpp test_impl - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -ohmm_test_cpp $(ROOT_DIR)/test/HandmadeMath.cpp $(ROOT_DIR)/test/hmm_test.cpp + @echo "\nCompiling in C++ mode" + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -ohmm_test_cpp \ + -DHANDMADE_MATH_CPP_MODE \ + $(ROOT_DIR)/test/HandmadeMath.cpp $(ROOT_DIR)/test/hmm_test.cpp -cpp_no_sse: $(ROOT_DIR)/test/HandmadeMath_NoSSE.cpp test_impl - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -ohmm_test_cpp_no_sse $(ROOT_DIR)/test/HandmadeMath_NoSSE.cpp $(ROOT_DIR)/test/hmm_test.cpp +cpp_no_sse: $(ROOT_DIR)/test/HandmadeMath.cpp test_impl + @echo "\nCompiling in C++ mode (no SSE)" + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -ohmm_test_cpp_no_sse \ + -DHANDMADE_MATH_CPP_MODE -DHANDMADE_MATH_NO_SSE \ + $(ROOT_DIR)/test/HandmadeMath.cpp $(ROOT_DIR)/test/hmm_test.cpp test_impl: $(ROOT_DIR)/test/hmm_test.cpp $(ROOT_DIR)/test/hmm_test.c diff --git a/test/README.md b/test/README.md new file mode 100644 index 0000000..c2fdd38 --- /dev/null +++ b/test/README.md @@ -0,0 +1,11 @@ +# Testing + +You can compile and run the tests yourself by running: + +``` +make +./hmm_test_c +./hmm_test_c_no_sse +./hmm_test_cpp +./hmm_test_cpp_no_sse +``` diff --git a/test/hmm_test.c b/test/hmm_test.c index cec33cf..bc6beca 100644 --- a/test/hmm_test.c +++ b/test/hmm_test.c @@ -827,7 +827,7 @@ int run_tests() { for (int Row = 0; Row < 4; ++Row) { - EXPECT_FLOAT_EQ(result.Elements[Column][Row], Expected) << "At column " << Column << ", row " << Row; + EXPECT_FLOAT_EQ(result.Elements[Column][Row], Expected); Expected += 2.0f; } } @@ -839,7 +839,7 @@ int run_tests() { for (int Row = 0; Row < 4; ++Row) { - EXPECT_FLOAT_EQ(result.Elements[Column][Row], Expected) << "At column " << Column << ", row " << Row; + EXPECT_FLOAT_EQ(result.Elements[Column][Row], Expected); Expected += 2.0f; } } @@ -851,7 +851,7 @@ int run_tests() { for (int Row = 0; Row < 4; ++Row) { - EXPECT_FLOAT_EQ(m4_1.Elements[Column][Row], Expected) << "At column " << Column << ", row " << Row; + EXPECT_FLOAT_EQ(m4_1.Elements[Column][Row], Expected); Expected += 2.0f; } } @@ -1041,7 +1041,7 @@ int run_tests() { for (int Row = 0; Row < 4; ++Row) { - EXPECT_FLOAT_EQ(result.Elements[Column][Row], -16.0f) << "At column " << Column << ", row " << Row; + EXPECT_FLOAT_EQ(result.Elements[Column][Row], -16.0f); } } } @@ -1051,7 +1051,7 @@ int run_tests() { for (int Row = 0; Row < 4; ++Row) { - EXPECT_FLOAT_EQ(result.Elements[Column][Row], -16.0f) << "At column " << Column << ", row " << Row; + EXPECT_FLOAT_EQ(result.Elements[Column][Row], -16.0f); } } } @@ -1061,7 +1061,7 @@ int run_tests() { for (int Row = 0; Row < 4; ++Row) { - EXPECT_FLOAT_EQ(m4_1.Elements[Column][Row], -16.0f) << "At column " << Column << ", row " << Row; + EXPECT_FLOAT_EQ(m4_1.Elements[Column][Row], -16.0f); } } #endif @@ -1993,6 +1993,67 @@ int run_tests() } CATEGORY_END() + CATEGORY_BEGIN(Equality) + { + TEST_BEGIN(Vec2) + { + hmm_vec2 a = HMM_Vec2(1.0f, 2.0f); + hmm_vec2 b = HMM_Vec2(1.0f, 2.0f); + hmm_vec2 c = HMM_Vec2(3.0f, 4.0f); + + EXPECT_TRUE(HMM_EqualsVec2(a, b)); + EXPECT_FALSE(HMM_EqualsVec2(a, c)); + +#ifdef HANDMADE_MATH_CPP_MODE + EXPECT_TRUE(HMM_Equals(a, b)); + EXPECT_FALSE(HMM_Equals(a, c)); + + EXPECT_TRUE(a == b); + EXPECT_FALSE(a == c); +#endif + } + TEST_END() + + TEST_BEGIN(Vec3) + { + hmm_vec3 a = HMM_Vec3(1.0f, 2.0f, 3.0f); + hmm_vec3 b = HMM_Vec3(1.0f, 2.0f, 3.0f); + hmm_vec3 c = HMM_Vec3(4.0f, 5.0f, 6.0f); + + EXPECT_TRUE(HMM_EqualsVec3(a, b)); + EXPECT_FALSE(HMM_EqualsVec3(a, c)); + +#ifdef HANDMADE_MATH_CPP_MODE + EXPECT_TRUE(HMM_Equals(a, b)); + EXPECT_FALSE(HMM_Equals(a, c)); + + EXPECT_TRUE(a == b); + EXPECT_FALSE(a == c); +#endif + } + TEST_END() + + TEST_BEGIN(Vec4) + { + hmm_vec4 a = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f); + hmm_vec4 b = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f); + hmm_vec4 c = HMM_Vec4(5.0f, 6.0f, 7.0f, 8.0f); + + EXPECT_TRUE(HMM_EqualsVec4(a, b)); + EXPECT_FALSE(HMM_EqualsVec4(a, c)); + +#ifdef HANDMADE_MATH_CPP_MODE + EXPECT_TRUE(HMM_Equals(a, b)); + EXPECT_FALSE(HMM_Equals(a, c)); + + EXPECT_TRUE(a == b); + EXPECT_FALSE(a == c); +#endif + } + TEST_END() + } + CATEGORY_END() + CATEGORY_BEGIN(Projection) { TEST_BEGIN(Orthographic) @@ -2093,5 +2154,49 @@ int run_tests() } CATEGORY_END() +#ifdef HANDMADE_MATH__USE_SSE + CATEGORY_BEGIN(SSE) + { + TEST_BEGIN(LinearCombine) + { + hmm_mat4 MatrixOne = HMM_Mat4d(2.0f); + hmm_mat4 MatrixTwo = HMM_Mat4d(4.0f); + hmm_mat4 Result; + + Result.Rows[0] = HMM_LinearCombineSSE(MatrixOne.Rows[0], MatrixTwo); + Result.Rows[1] = HMM_LinearCombineSSE(MatrixOne.Rows[1], MatrixTwo); + Result.Rows[2] = HMM_LinearCombineSSE(MatrixOne.Rows[2], MatrixTwo); + Result.Rows[3] = HMM_LinearCombineSSE(MatrixOne.Rows[3], MatrixTwo); + + { + EXPECT_FLOAT_EQ(Result.Elements[0][0], 8.0f); + EXPECT_FLOAT_EQ(Result.Elements[0][1], 0.0f); + EXPECT_FLOAT_EQ(Result.Elements[0][2], 0.0f); + EXPECT_FLOAT_EQ(Result.Elements[0][3], 0.0f); + + EXPECT_FLOAT_EQ(Result.Elements[1][0], 0.0f); + EXPECT_FLOAT_EQ(Result.Elements[1][1], 8.0f); + EXPECT_FLOAT_EQ(Result.Elements[1][2], 0.0f); + EXPECT_FLOAT_EQ(Result.Elements[1][3], 0.0f); + + + EXPECT_FLOAT_EQ(Result.Elements[2][0], 0.0f); + EXPECT_FLOAT_EQ(Result.Elements[2][1], 0.0f); + EXPECT_FLOAT_EQ(Result.Elements[2][2], 8.0f); + EXPECT_FLOAT_EQ(Result.Elements[2][3], 0.0f); + + + EXPECT_FLOAT_EQ(Result.Elements[3][0], 0.0f); + EXPECT_FLOAT_EQ(Result.Elements[3][1], 0.0f); + EXPECT_FLOAT_EQ(Result.Elements[3][2], 0.0f); + EXPECT_FLOAT_EQ(Result.Elements[3][3], 8.0f); + } + + } + TEST_END() + } + CATEGORY_END() +#endif + return 0; }