mirror of
https://github.com/HandmadeMath/HandmadeMath.git
synced 2025-12-28 23:54:32 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
142ba3cd9d | ||
|
|
8c2ac269ba | ||
|
|
736ebaaf23 | ||
|
|
bdc7dd2a51 | ||
|
|
b4ce44823b | ||
|
|
2901e70ca3 | ||
|
|
21b4a0d209 | ||
|
|
43836aa3a6 | ||
|
|
bdc04881de | ||
|
|
322826bcee | ||
|
|
4e1e97522d | ||
|
|
6603c796cc | ||
|
|
623215b228 | ||
|
|
fcc510f767 | ||
|
|
133a595b6f | ||
|
|
5f20d693c9 | ||
|
|
e210d8729b | ||
|
|
a1c84320f9 | ||
|
|
8df5da57f5 | ||
|
|
149c18d449 | ||
|
|
98748f702c | ||
|
|
6cf6226c57 | ||
|
|
aaa767bf0b | ||
|
|
422bc588e9 | ||
|
|
beb837a3c6 | ||
|
|
50ab55b3bc | ||
|
|
22d743ce3d | ||
|
|
d4918a514e | ||
|
|
37aa3fa6a0 | ||
|
|
7e493a5481 |
927
HandmadeMath.h
927
HandmadeMath.h
File diff suppressed because it is too large
Load Diff
23
README.md
23
README.md
@@ -1,36 +1,43 @@
|
|||||||
# Handmade Math
|
# Handmade Math
|
||||||
|
|
||||||
A single-file, cross-platform, public domain game math library for both C and C++. Supports vectors, matrices, quaternions, and all the utilities you'd expect.
|
A single-file, cross-platform, public domain graphics math library for both C and C++. Supports vectors, matrices, quaternions, and all the utilities you'd expect.
|
||||||
|
|
||||||
To get started, go download [the latest release](https://github.com/HandmadeMath/HandmadeMath/releases).
|
To get started, go download [the latest release](https://github.com/HandmadeMath/HandmadeMath/releases).
|
||||||
|
|
||||||
> If you are upgrading to version 2 of Handmade Math, save yourself some time and use our [automatic update tool](./update).
|
> If you are upgrading to Handmade Math 2.0, save yourself some time and use our [automatic update tool](./update).
|
||||||
|
|
||||||
Here's what sets Handmade Math apart:
|
Here's what sets Handmade Math apart:
|
||||||
|
|
||||||
- **A simple single-header library.** Just `#include "HandmadeMath.h"`.
|
- **A simple single-header library.** Just `#include "HandmadeMath.h"`.
|
||||||
- **Supports both C and C++.** While libraries like GLM only support C++, Handmade Math supports both C and C++, with convenient overloads wherever possible. For example, C++ codebases get operator overloading, and C11 codebases get `_Generic` versions of common operations.
|
- **Supports both C and C++.** While libraries like GLM only support C++, Handmade Math supports both C and C++, with convenient overloads wherever possible. For example, C++ codebases get operator overloading, and C11 codebases get `_Generic` versions of common operations.
|
||||||
|
- **Supports all graphics APIs.** Handmade Math has left- and right-handed versions of each operation, as well as support for zero-to-one and negative-one-to-one NDC conventions.
|
||||||
- **Swizzling, sort of.** Handmade Math's vector types use unions to provide several ways of accessing the same underlying data. For example, the components of an `HMM_Vec3` can be accessed as `XYZ`, `RGB`, or `UVW` - or subsets can be accessed like `.XY` and `.YZ`.
|
- **Swizzling, sort of.** Handmade Math's vector types use unions to provide several ways of accessing the same underlying data. For example, the components of an `HMM_Vec3` can be accessed as `XYZ`, `RGB`, or `UVW` - or subsets can be accessed like `.XY` and `.YZ`.
|
||||||
- **Your choice of angle unit.** While Handmade Math uses radians by default, you can configure it to use degrees or [turns](https://www.computerenhance.com/p/turns-are-better-than-radians) instead.
|
- **Your choice of angle unit.** While Handmade Math uses radians by default, you can configure it to use degrees or [turns](https://www.computerenhance.com/p/turns-are-better-than-radians) instead.
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Simply `#include "HandmadeMath.h"`. All functions are `static inline`, so no need for an "implementation" file as with some other single-header libraries.
|
Simply `#include "HandmadeMath.h"`. All functions are `static inline`, so there is no need for an "implementation" file as with some other single-header libraries.
|
||||||
|
|
||||||
A few config options are available. See the header comment in [the source](./HandmadeMath.h) for details.
|
A few config options are available. See the header comment in [the source](./HandmadeMath.h) for details.
|
||||||
|
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
**What conventions does HMM use, e.g. row vs. column major, handedness, etc.?**
|
||||||
|
|
||||||
|
Handmade Math's matrices are column-major, i.e. data is stored by columns, then rows. It also assumes column vectors, i.e. vectors are written vertically and matrix-vector multiplication is `M * V` instead of `V * M`. For more information, see [this issue](https://github.com/HandmadeMath/HandmadeMath/issues/124#issuecomment-775737253).
|
||||||
|
|
||||||
|
For other properties, we provide variants for each common convention. Functions that care about handedness have left-handed (`LH`) and right-handed (`RH`) variants. Projection functions have zero-to-one (`ZO`) and negative-one-to-one (`NO`) variants for different NDC conventions.
|
||||||
|
|
||||||
|
**What if I don't want the `HMM_` prefix?**
|
||||||
|
|
||||||
|
Do a find and replace in the library source.
|
||||||
|
|
||||||
**What's the license?**
|
**What's the license?**
|
||||||
|
|
||||||
This library is in the public domain. You can do whatever you want with it.
|
This library is in the public domain. You can do whatever you want with it.
|
||||||
|
|
||||||
**Where can I contact you to ask questions?**
|
**Where can I contact you to ask questions?**
|
||||||
|
|
||||||
Feel free to make Github issues for any questions, concerns, or problems you encounter.
|
Feel free to make GitHub issues for any questions, concerns, or problems you encounter.
|
||||||
|
|
||||||
**What if I don't want the `HMM_` prefix?**
|
|
||||||
|
|
||||||
Do a find and replace in the library source.
|
|
||||||
|
|||||||
@@ -148,25 +148,35 @@ INITIALIZER(_HMT_COVERCASE_FUNCNAME_INIT(name)) { \
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
#define HMT_EXPECT_FLOAT_EQ(_actual, _expected) { \
|
#define HMT_EXPECT_FLOAT_EQ_MSG(_actual, _expected, _msg) { \
|
||||||
_HMT_CASE_START(); \
|
_HMT_CASE_START(); \
|
||||||
float actual = (_actual); \
|
float actual = (_actual); \
|
||||||
float diff = actual - (_expected); \
|
float diff = actual - (_expected); \
|
||||||
if (diff < -FLT_EPSILON || FLT_EPSILON < diff) { \
|
if (diff < -FLT_EPSILON || FLT_EPSILON < diff) { \
|
||||||
_HMT_CASE_FAIL(); \
|
_HMT_CASE_FAIL(); \
|
||||||
printf("Expected %f, got %f", (_expected), actual); \
|
if ((_msg)[0] == 0) { \
|
||||||
|
printf("Expected %f, got %f (error: %.9g)", (_expected), actual, diff); \
|
||||||
|
} else { \
|
||||||
|
printf("%s: Expected %f, got %f (error: %.9g)", (_msg), (_expected), actual, diff); \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
}
|
||||||
|
#define HMT_EXPECT_FLOAT_EQ(_actual, _expected) HMT_EXPECT_FLOAT_EQ_MSG(_actual, _expected, "");
|
||||||
|
|
||||||
#define HMT_EXPECT_NEAR(_actual, _expected, _epsilon) { \
|
#define HMT_EXPECT_NEAR_MSG(_actual, _expected, _epsilon, _msg) { \
|
||||||
_HMT_CASE_START(); \
|
_HMT_CASE_START(); \
|
||||||
float actual = (_actual); \
|
float actual = (_actual); \
|
||||||
float diff = actual - (_expected); \
|
float diff = actual - (_expected); \
|
||||||
if (diff < -(_epsilon) || (_epsilon) < diff) { \
|
if (diff < -(_epsilon) || (_epsilon) < diff) { \
|
||||||
_HMT_CASE_FAIL(); \
|
_HMT_CASE_FAIL(); \
|
||||||
printf("Expected %f, got %f", (_expected), actual); \
|
if ((_msg)[0] == 0) { \
|
||||||
|
printf("Expected %f, got %f", (_expected), actual); \
|
||||||
|
} else { \
|
||||||
|
printf("%s: Expected %f, got %f", (_msg), (_expected), actual); \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
}
|
||||||
|
#define HMT_EXPECT_NEAR(_actual, _expected, _epsilon) HMT_EXPECT_NEAR_MSG(_actual, _expected, _epsilon, "");
|
||||||
|
|
||||||
#define HMT_EXPECT_LT(_actual, _expected) { \
|
#define HMT_EXPECT_LT(_actual, _expected) { \
|
||||||
_HMT_CASE_START(); \
|
_HMT_CASE_START(); \
|
||||||
@@ -192,7 +202,46 @@ INITIALIZER(_HMT_COVERCASE_FUNCNAME_INIT(name)) { \
|
|||||||
#define EXPECT_TRUE(_actual) HMT_EXPECT_TRUE(_actual)
|
#define EXPECT_TRUE(_actual) HMT_EXPECT_TRUE(_actual)
|
||||||
#define EXPECT_FALSE(_actual) HMT_EXPECT_FALSE(_actual)
|
#define EXPECT_FALSE(_actual) HMT_EXPECT_FALSE(_actual)
|
||||||
#define EXPECT_FLOAT_EQ(_actual, _expected) HMT_EXPECT_FLOAT_EQ(_actual, _expected)
|
#define EXPECT_FLOAT_EQ(_actual, _expected) HMT_EXPECT_FLOAT_EQ(_actual, _expected)
|
||||||
|
#define EXPECT_V4_EQ(_actual, _expected) \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.X, _expected.X, "incorrect X"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Y, _expected.Y, "incorrect Y"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Z, _expected.Z, "incorrect Z"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.W, _expected.W, "incorrect W");
|
||||||
|
#define EXPECT_M4_EQ(_actual, _expected) \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[0][0], _expected.Elements[0][0], "incorrect [0][0]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[0][1], _expected.Elements[0][1], "incorrect [0][1]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[0][2], _expected.Elements[0][2], "incorrect [0][2]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[0][3], _expected.Elements[0][3], "incorrect [0][3]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[1][0], _expected.Elements[1][0], "incorrect [1][0]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[1][1], _expected.Elements[1][1], "incorrect [1][1]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[1][2], _expected.Elements[1][2], "incorrect [1][2]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[1][3], _expected.Elements[1][3], "incorrect [1][3]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[2][0], _expected.Elements[2][0], "incorrect [2][0]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[2][1], _expected.Elements[2][1], "incorrect [2][1]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[2][2], _expected.Elements[2][2], "incorrect [2][2]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[2][3], _expected.Elements[2][3], "incorrect [2][3]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[3][0], _expected.Elements[3][0], "incorrect [3][0]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[3][1], _expected.Elements[3][1], "incorrect [3][1]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[3][2], _expected.Elements[3][2], "incorrect [3][2]"); \
|
||||||
|
HMT_EXPECT_FLOAT_EQ_MSG(_actual.Elements[3][3], _expected.Elements[3][3], "incorrect [3][3]");
|
||||||
#define EXPECT_NEAR(_actual, _expected, _epsilon) HMT_EXPECT_NEAR(_actual, _expected, _epsilon)
|
#define EXPECT_NEAR(_actual, _expected, _epsilon) HMT_EXPECT_NEAR(_actual, _expected, _epsilon)
|
||||||
|
#define EXPECT_M4_NEAR(_actual, _expected, _epsilon) \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[0][0], _expected.Elements[0][0], _epsilon, "incorrect [0][0]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[0][1], _expected.Elements[0][1], _epsilon, "incorrect [0][1]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[0][2], _expected.Elements[0][2], _epsilon, "incorrect [0][2]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[0][3], _expected.Elements[0][3], _epsilon, "incorrect [0][3]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[1][0], _expected.Elements[1][0], _epsilon, "incorrect [1][0]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[1][1], _expected.Elements[1][1], _epsilon, "incorrect [1][1]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[1][2], _expected.Elements[1][2], _epsilon, "incorrect [1][2]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[1][3], _expected.Elements[1][3], _epsilon, "incorrect [1][3]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[2][0], _expected.Elements[2][0], _epsilon, "incorrect [2][0]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[2][1], _expected.Elements[2][1], _epsilon, "incorrect [2][1]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[2][2], _expected.Elements[2][2], _epsilon, "incorrect [2][2]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[2][3], _expected.Elements[2][3], _epsilon, "incorrect [2][3]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[3][0], _expected.Elements[3][0], _epsilon, "incorrect [3][0]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[3][1], _expected.Elements[3][1], _epsilon, "incorrect [3][1]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[3][2], _expected.Elements[3][2], _epsilon, "incorrect [3][2]"); \
|
||||||
|
HMT_EXPECT_NEAR_MSG(_actual.Elements[3][3], _expected.Elements[3][3], _epsilon, "incorrect [3][3]");
|
||||||
#define EXPECT_LT(_actual, _expected) HMT_EXPECT_LT(_actual, _expected)
|
#define EXPECT_LT(_actual, _expected) HMT_EXPECT_LT(_actual, _expected)
|
||||||
#define EXPECT_GT(_actual, _expected) HMT_EXPECT_GT(_actual, _expected)
|
#define EXPECT_GT(_actual, _expected) HMT_EXPECT_GT(_actual, _expected)
|
||||||
#endif // HMT_SAFE_MACROS
|
#endif // HMT_SAFE_MACROS
|
||||||
|
|||||||
158
test/Makefile
158
test/Makefile
@@ -2,77 +2,123 @@ BUILD_DIR=./build
|
|||||||
|
|
||||||
CXXFLAGS+=-g -Wall -Wextra -pthread -Wno-missing-braces -Wno-missing-field-initializers -Wfloat-equal
|
CXXFLAGS+=-g -Wall -Wextra -pthread -Wno-missing-braces -Wno-missing-field-initializers -Wfloat-equal
|
||||||
|
|
||||||
all: c c_no_sse cpp cpp_no_sse build_c_without_coverage build_cpp_without_coverage
|
.PHONY: all all_c all_cpp
|
||||||
|
all: all_c all_cpp
|
||||||
build_all: build_c build_c_no_sse build_cpp build_cpp_no_sse
|
all_c: c99 c99_no_simd c11 c17
|
||||||
|
all_cpp: cpp98 cpp98_no_simd cpp03 cpp11 cpp14 cpp17 cpp20
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD_DIR)
|
rm -rf $(BUILD_DIR)
|
||||||
|
|
||||||
c: build_c
|
.PHONY: c99
|
||||||
$(BUILD_DIR)/hmm_test_c
|
c99:
|
||||||
|
@echo "\nCompiling as C99"
|
||||||
build_c: HandmadeMath.c test_impl
|
|
||||||
@echo "\nCompiling in C mode"
|
|
||||||
mkdir -p $(BUILD_DIR)
|
mkdir -p $(BUILD_DIR)
|
||||||
cd $(BUILD_DIR)\
|
cd $(BUILD_DIR)\
|
||||||
&& $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c99 \
|
&& $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c99 \
|
||||||
-c ../HandmadeMath.c ../hmm_test.c \
|
../HandmadeMath.c ../hmm_test.c \
|
||||||
-lm \
|
-lm -o hmm_test_c99 \
|
||||||
&& $(CC) -ohmm_test_c HandmadeMath.o hmm_test.o -lm
|
&& ./hmm_test_c99
|
||||||
|
|
||||||
c_no_sse: build_c_no_sse
|
.PHONY: c99_no_simd
|
||||||
$(BUILD_DIR)/hmm_test_c_no_sse
|
c99_no_simd:
|
||||||
|
@echo "\nCompiling as C99 (no SIMD)"
|
||||||
build_c_no_sse: HandmadeMath.c test_impl
|
|
||||||
@echo "\nCompiling in C mode (no SSE)"
|
|
||||||
mkdir -p $(BUILD_DIR)
|
mkdir -p $(BUILD_DIR)
|
||||||
cd $(BUILD_DIR) \
|
cd $(BUILD_DIR) \
|
||||||
&& $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c99 \
|
&& $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c99 \
|
||||||
-DHANDMADE_MATH_NO_SSE \
|
-DHANDMADE_MATH_NO_SIMD \
|
||||||
-c ../HandmadeMath.c ../hmm_test.c \
|
../HandmadeMath.c ../hmm_test.c \
|
||||||
-lm \
|
-lm -o hmm_test_c99_no_simd \
|
||||||
&& $(CC) -ohmm_test_c_no_sse HandmadeMath.o hmm_test.o -lm
|
&& ./hmm_test_c99_no_simd
|
||||||
|
|
||||||
cpp: build_cpp
|
.PHONY: c11
|
||||||
$(BUILD_DIR)/hmm_test_cpp
|
c11:
|
||||||
|
@echo "\nCompiling as C11"
|
||||||
build_cpp: HandmadeMath.cpp test_impl
|
|
||||||
@echo "\nCompiling in C++ mode"
|
|
||||||
mkdir -p $(BUILD_DIR)
|
|
||||||
cd $(BUILD_DIR) \
|
|
||||||
&& $(CXX) $(CPPFLAGS) $(CXXFLAGS) -ohmm_test_cpp \
|
|
||||||
-DHANDMADE_MATH_CPP_MODE \
|
|
||||||
../HandmadeMath.cpp ../hmm_test.cpp
|
|
||||||
|
|
||||||
cpp_no_sse: build_cpp_no_sse
|
|
||||||
$(BUILD_DIR)/hmm_test_cpp_no_sse
|
|
||||||
|
|
||||||
build_cpp_no_sse: HandmadeMath.cpp test_impl
|
|
||||||
@echo "\nCompiling in C++ mode (no SSE)"
|
|
||||||
mkdir -p $(BUILD_DIR)
|
|
||||||
cd $(BUILD_DIR) \
|
|
||||||
&& $(CXX) $(CPPFLAGS) $(CXXFLAGS) -ohmm_test_cpp_no_sse \
|
|
||||||
-DHANDMADE_MATH_CPP_MODE -DHANDMADE_MATH_NO_SSE \
|
|
||||||
../HandmadeMath.cpp ../hmm_test.cpp
|
|
||||||
|
|
||||||
test_impl: hmm_test.cpp hmm_test.c
|
|
||||||
|
|
||||||
build_c_without_coverage: HandmadeMath.c test_impl
|
|
||||||
@echo "\nCompiling in C mode"
|
|
||||||
mkdir -p $(BUILD_DIR)
|
mkdir -p $(BUILD_DIR)
|
||||||
cd $(BUILD_DIR)\
|
cd $(BUILD_DIR)\
|
||||||
&& $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c99 \
|
&& $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c11 \
|
||||||
-DWITHOUT_COVERAGE \
|
../HandmadeMath.c ../hmm_test.c \
|
||||||
-c ../HandmadeMath.c ../hmm_test.c \
|
-lm -o hmm_test_c11 \
|
||||||
-lm \
|
&& ./hmm_test_c11
|
||||||
&& $(CC) -ohmm_test_c HandmadeMath.o hmm_test.o -lm
|
|
||||||
|
|
||||||
build_cpp_without_coverage: HandmadeMath.cpp test_impl
|
.PHONY: c17
|
||||||
@echo "\nCompiling in C++ mode (no SSE)"
|
c17:
|
||||||
|
@echo "\nCompiling as C17"
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
cd $(BUILD_DIR)\
|
||||||
|
&& $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c17 \
|
||||||
|
../HandmadeMath.c ../hmm_test.c \
|
||||||
|
-lm -o hmm_test_c17 \
|
||||||
|
&& ./hmm_test_c17
|
||||||
|
|
||||||
|
.PHONY: cpp98
|
||||||
|
cpp98:
|
||||||
|
@echo "\nCompiling as C++98"
|
||||||
mkdir -p $(BUILD_DIR)
|
mkdir -p $(BUILD_DIR)
|
||||||
cd $(BUILD_DIR) \
|
cd $(BUILD_DIR) \
|
||||||
&& $(CXX) $(CPPFLAGS) $(CXXFLAGS) -ohmm_test_cpp_no_sse \
|
&& $(CXX) $(CPPFLAGS) $(CXXFLAGS) -std=c++98 \
|
||||||
-DHANDMADE_MATH_CPP_MODE -DWITHOUT_COVERAGE \
|
../HandmadeMath.cpp ../hmm_test.cpp \
|
||||||
../HandmadeMath.cpp ../hmm_test.cpp
|
-lm -o hmm_test_cpp98 \
|
||||||
|
&& ./hmm_test_cpp98
|
||||||
|
|
||||||
|
.PHONY: cpp98_no_simd
|
||||||
|
cpp98_no_simd:
|
||||||
|
@echo "\nCompiling as C++98 (no SIMD)"
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
cd $(BUILD_DIR) \
|
||||||
|
&& $(CXX) $(CPPFLAGS) $(CXXFLAGS) -std=c++98 \
|
||||||
|
-DHANDMADE_MATH_NO_SIMD \
|
||||||
|
../HandmadeMath.cpp ../hmm_test.cpp \
|
||||||
|
-lm -o hmm_test_cpp98 \
|
||||||
|
&& ./hmm_test_cpp98
|
||||||
|
|
||||||
|
.PHONY: cpp03
|
||||||
|
cpp03:
|
||||||
|
@echo "\nCompiling as C++03"
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
cd $(BUILD_DIR) \
|
||||||
|
&& $(CXX) $(CPPFLAGS) $(CXXFLAGS) -std=c++03 \
|
||||||
|
../HandmadeMath.cpp ../hmm_test.cpp \
|
||||||
|
-lm -o hmm_test_cpp03 \
|
||||||
|
&& ./hmm_test_cpp03
|
||||||
|
|
||||||
|
.PHONY: cpp11
|
||||||
|
cpp11:
|
||||||
|
@echo "\nCompiling as C++11"
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
cd $(BUILD_DIR) \
|
||||||
|
&& $(CXX) $(CPPFLAGS) $(CXXFLAGS) -std=c++11 \
|
||||||
|
../HandmadeMath.cpp ../hmm_test.cpp \
|
||||||
|
-lm -o hmm_test_cpp11 \
|
||||||
|
&& ./hmm_test_cpp11
|
||||||
|
|
||||||
|
.PHONY: cpp14
|
||||||
|
cpp14:
|
||||||
|
@echo "\nCompiling as C++14"
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
cd $(BUILD_DIR) \
|
||||||
|
&& $(CXX) $(CPPFLAGS) $(CXXFLAGS) -std=c++14 \
|
||||||
|
../HandmadeMath.cpp ../hmm_test.cpp \
|
||||||
|
-lm -o hmm_test_cpp14 \
|
||||||
|
&& ./hmm_test_cpp14
|
||||||
|
|
||||||
|
.PHONY: cpp17
|
||||||
|
cpp17:
|
||||||
|
@echo "\nCompiling as C++17"
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
cd $(BUILD_DIR) \
|
||||||
|
&& $(CXX) $(CPPFLAGS) $(CXXFLAGS) -std=c++17 \
|
||||||
|
../HandmadeMath.cpp ../hmm_test.cpp \
|
||||||
|
-lm -o hmm_test_cpp17 \
|
||||||
|
&& ./hmm_test_cpp17
|
||||||
|
|
||||||
|
.PHONY: cpp20
|
||||||
|
cpp20:
|
||||||
|
@echo "\nCompiling as C++20"
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
cd $(BUILD_DIR) \
|
||||||
|
&& $(CXX) $(CPPFLAGS) $(CXXFLAGS) -std=c++20 \
|
||||||
|
../HandmadeMath.cpp ../hmm_test.cpp \
|
||||||
|
-lm -o hmm_test_cpp20 \
|
||||||
|
&& ./hmm_test_cpp20
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ TEST(Addition, Vec2)
|
|||||||
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = HMM_Add(v2_1, v2_2);
|
HMM_Vec2 result = HMM_Add(v2_1, v2_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = v2_1 + v2_2;
|
HMM_Vec2 result = v2_1 + v2_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
||||||
@@ -39,13 +41,15 @@ TEST(Addition, Vec3)
|
|||||||
EXPECT_FLOAT_EQ(result.Y, 7.0f);
|
EXPECT_FLOAT_EQ(result.Y, 7.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = HMM_Add(v3_1, v3_2);
|
HMM_Vec3 result = HMM_Add(v3_1, v3_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 5.0f);
|
EXPECT_FLOAT_EQ(result.X, 5.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 7.0f);
|
EXPECT_FLOAT_EQ(result.Y, 7.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = v3_1 + v3_2;
|
HMM_Vec3 result = v3_1 + v3_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, 5.0f);
|
EXPECT_FLOAT_EQ(result.X, 5.0f);
|
||||||
@@ -72,7 +76,7 @@ TEST(Addition, Vec4)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = HMM_Add(v4_1, v4_2);
|
HMM_Vec4 result = HMM_Add(v4_1, v4_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
||||||
@@ -80,6 +84,8 @@ TEST(Addition, Vec4)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = v4_1 + v4_2;
|
HMM_Vec4 result = v4_1 + v4_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
||||||
@@ -125,7 +131,7 @@ TEST(Addition, Mat2)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 12.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][1], 12.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat2 result = HMM_Add(a, b);
|
HMM_Mat2 result = HMM_Add(a, b);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 6.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 6.0f);
|
||||||
@@ -133,6 +139,8 @@ TEST(Addition, Mat2)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 10.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][0], 10.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 12.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][1], 12.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat2 result = a + b;
|
HMM_Mat2 result = a + b;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 6.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 6.0f);
|
||||||
@@ -182,7 +190,7 @@ TEST(Addition, Mat3)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 27.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], 27.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat3 result = HMM_Add(a, b);
|
HMM_Mat3 result = HMM_Add(a, b);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 11.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 11.0f);
|
||||||
@@ -195,6 +203,8 @@ TEST(Addition, Mat3)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 25.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][1], 25.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 27.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], 27.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat3 result = a + b;
|
HMM_Mat3 result = a + b;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 11.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 11.0f);
|
||||||
@@ -257,7 +267,7 @@ TEST(Addition, Mat4)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat4 result = HMM_Add(m4_1, m4_2);
|
HMM_Mat4 result = HMM_Add(m4_1, m4_2);
|
||||||
float Expected = 18.0f;
|
float Expected = 18.0f;
|
||||||
@@ -270,6 +280,8 @@ TEST(Addition, Mat4)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat4 result = m4_1 + m4_2;
|
HMM_Mat4 result = m4_1 + m4_2;
|
||||||
float Expected = 18.0f;
|
float Expected = 18.0f;
|
||||||
@@ -308,7 +320,7 @@ TEST(Addition, Quaternion)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Quat result = HMM_Add(q1, q2);
|
HMM_Quat result = HMM_Add(q1, q2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
||||||
@@ -316,6 +328,8 @@ TEST(Addition, Quaternion)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Quat result = q1 + q2;
|
HMM_Quat result = q1 + q2;
|
||||||
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ TEST(Division, Vec2Vec2)
|
|||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = HMM_Div(v2_1, v2_2);
|
HMM_Vec2 result = HMM_Div(v2_1, v2_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = v2_1 / v2_2;
|
HMM_Vec2 result = v2_1 / v2_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
@@ -38,12 +40,14 @@ TEST(Division, Vec2Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = HMM_Div(v2, s);
|
HMM_Vec2 result = HMM_Div(v2, s);
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = v2 / s;
|
HMM_Vec2 result = v2 / s;
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
@@ -67,13 +71,15 @@ TEST(Division, Vec3Vec3)
|
|||||||
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = HMM_Div(v3_1, v3_2);
|
HMM_Vec3 result = HMM_Div(v3_1, v3_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = v3_1 / v3_2;
|
HMM_Vec3 result = v3_1 / v3_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
@@ -99,13 +105,15 @@ TEST(Division, Vec3Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = HMM_Div(v3, s);
|
HMM_Vec3 result = HMM_Div(v3, s);
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = v3 / s;
|
HMM_Vec3 result = v3 / s;
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
@@ -132,7 +140,7 @@ TEST(Division, Vec4Vec4)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 0.25f);
|
EXPECT_FLOAT_EQ(result.W, 0.25f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = HMM_Div(v4_1, v4_2);
|
HMM_Vec4 result = HMM_Div(v4_1, v4_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
@@ -140,6 +148,8 @@ TEST(Division, Vec4Vec4)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 0.25f);
|
EXPECT_FLOAT_EQ(result.W, 0.25f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = v4_1 / v4_2;
|
HMM_Vec4 result = v4_1 / v4_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
@@ -168,7 +178,7 @@ TEST(Division, Vec4Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 2.0f);
|
EXPECT_FLOAT_EQ(result.W, 2.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = HMM_Div(v4, s);
|
HMM_Vec4 result = HMM_Div(v4, s);
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
@@ -176,6 +186,8 @@ TEST(Division, Vec4Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 2.0f);
|
EXPECT_FLOAT_EQ(result.W, 2.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = v4 / s;
|
HMM_Vec4 result = v4 / s;
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
@@ -212,7 +224,7 @@ TEST(Division, Mat2Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 8.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][1], 8.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat2 result = HMM_Div(m, s);
|
HMM_Mat2 result = HMM_Div(m, s);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
||||||
@@ -220,7 +232,9 @@ TEST(Division, Mat2Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 6.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][0], 6.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 8.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][1], 8.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat2 result = m / s;
|
HMM_Mat2 result = m / s;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
||||||
@@ -257,7 +271,7 @@ TEST(Division, Mat3Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 18.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], 18.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat3 result = HMM_Div(m, s);
|
HMM_Mat3 result = HMM_Div(m, s);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
||||||
@@ -270,7 +284,9 @@ TEST(Division, Mat3Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 16.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][1], 16.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 18.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], 18.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat3 result = m / s;
|
HMM_Mat3 result = m / s;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
||||||
@@ -322,7 +338,7 @@ TEST(Division, Mat4Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[3][2], 7.5f);
|
EXPECT_FLOAT_EQ(result.Elements[3][2], 7.5f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 8.0f);
|
EXPECT_FLOAT_EQ(result.Elements[3][3], 8.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat4 result = HMM_Div(m4, s);
|
HMM_Mat4 result = HMM_Div(m4, s);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 0.5f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 0.5f);
|
||||||
@@ -342,6 +358,8 @@ TEST(Division, Mat4Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[3][2], 7.5f);
|
EXPECT_FLOAT_EQ(result.Elements[3][2], 7.5f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 8.0f);
|
EXPECT_FLOAT_EQ(result.Elements[3][3], 8.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat4 result = m4 / s;
|
HMM_Mat4 result = m4 / s;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 0.5f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 0.5f);
|
||||||
@@ -394,7 +412,7 @@ TEST(Division, QuaternionScalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 2.0f);
|
EXPECT_FLOAT_EQ(result.W, 2.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Quat result = HMM_Div(q, f);
|
HMM_Quat result = HMM_Div(q, f);
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
@@ -402,6 +420,8 @@ TEST(Division, QuaternionScalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 2.0f);
|
EXPECT_FLOAT_EQ(result.W, 2.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Quat result = q / f;
|
HMM_Quat result = q / f;
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ TEST(Equality, Vec2)
|
|||||||
EXPECT_TRUE(HMM_EqV2(a, b));
|
EXPECT_TRUE(HMM_EqV2(a, b));
|
||||||
EXPECT_FALSE(HMM_EqV2(a, c));
|
EXPECT_FALSE(HMM_EqV2(a, c));
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
EXPECT_TRUE(HMM_Eq(a, b));
|
EXPECT_TRUE(HMM_Eq(a, b));
|
||||||
EXPECT_FALSE(HMM_Eq(a, c));
|
EXPECT_FALSE(HMM_Eq(a, c));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
EXPECT_TRUE(a == b);
|
EXPECT_TRUE(a == b);
|
||||||
EXPECT_FALSE(a == c);
|
EXPECT_FALSE(a == c);
|
||||||
|
|
||||||
@@ -30,10 +32,12 @@ TEST(Equality, Vec3)
|
|||||||
EXPECT_TRUE(HMM_EqV3(a, b));
|
EXPECT_TRUE(HMM_EqV3(a, b));
|
||||||
EXPECT_FALSE(HMM_EqV3(a, c));
|
EXPECT_FALSE(HMM_EqV3(a, c));
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
EXPECT_TRUE(HMM_Eq(a, b));
|
EXPECT_TRUE(HMM_Eq(a, b));
|
||||||
EXPECT_FALSE(HMM_Eq(a, c));
|
EXPECT_FALSE(HMM_Eq(a, c));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
EXPECT_TRUE(a == b);
|
EXPECT_TRUE(a == b);
|
||||||
EXPECT_FALSE(a == c);
|
EXPECT_FALSE(a == c);
|
||||||
|
|
||||||
@@ -51,10 +55,12 @@ TEST(Equality, Vec4)
|
|||||||
EXPECT_TRUE(HMM_EqV4(a, b));
|
EXPECT_TRUE(HMM_EqV4(a, b));
|
||||||
EXPECT_FALSE(HMM_EqV4(a, c));
|
EXPECT_FALSE(HMM_EqV4(a, c));
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
EXPECT_TRUE(HMM_Eq(a, b));
|
EXPECT_TRUE(HMM_Eq(a, b));
|
||||||
EXPECT_FALSE(HMM_Eq(a, c));
|
EXPECT_FALSE(HMM_Eq(a, c));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
EXPECT_TRUE(a == b);
|
EXPECT_TRUE(a == b);
|
||||||
EXPECT_FALSE(a == c);
|
EXPECT_FALSE(a == c);
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ TEST(InvMatrix, Transpose)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1][0], Expect.Elements[1][0]);
|
EXPECT_FLOAT_EQ(result.Elements[1][0], Expect.Elements[1][0]);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[1][1], Expect.Elements[1][1]);
|
EXPECT_FLOAT_EQ(result.Elements[1][1], Expect.Elements[1][1]);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat2 result = HMM_Transpose(Matrix);
|
HMM_Mat2 result = HMM_Transpose(Matrix);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], Expect.Elements[0][0]);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], Expect.Elements[0][0]);
|
||||||
@@ -54,7 +54,7 @@ TEST(InvMatrix, Transpose)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][1], Expect.Elements[2][1]);
|
EXPECT_FLOAT_EQ(result.Elements[2][1], Expect.Elements[2][1]);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], Expect.Elements[2][2]);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], Expect.Elements[2][2]);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat3 result = HMM_Transpose(Matrix);
|
HMM_Mat3 result = HMM_Transpose(Matrix);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], Expect.Elements[0][0]);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], Expect.Elements[0][0]);
|
||||||
@@ -94,7 +94,7 @@ TEST(InvMatrix, Transpose)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][1], Expect.Elements[2][1]);
|
EXPECT_FLOAT_EQ(result.Elements[2][1], Expect.Elements[2][1]);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], Expect.Elements[2][2]);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], Expect.Elements[2][2]);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat4 result = HMM_Transpose(Matrix);
|
HMM_Mat4 result = HMM_Transpose(Matrix);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], Expect.Elements[0][0]);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], Expect.Elements[0][0]);
|
||||||
@@ -129,22 +129,22 @@ TEST(InvMatrix, InvGeneral)
|
|||||||
float Det = HMM_DeterminantM4(Matrix);
|
float Det = HMM_DeterminantM4(Matrix);
|
||||||
EXPECT_FLOAT_EQ(Det, -80.0f);
|
EXPECT_FLOAT_EQ(Det, -80.0f);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][0], Expect.Elements[0][0]);
|
EXPECT_NEAR(Result.Elements[0][0], Expect.Elements[0][0], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][1], Expect.Elements[0][1]);
|
EXPECT_NEAR(Result.Elements[0][1], Expect.Elements[0][1], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][2], Expect.Elements[0][2]);
|
EXPECT_NEAR(Result.Elements[0][2], Expect.Elements[0][2], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][3], Expect.Elements[0][3]);
|
EXPECT_NEAR(Result.Elements[0][3], Expect.Elements[0][3], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][0], Expect.Elements[1][0]);
|
EXPECT_NEAR(Result.Elements[1][0], Expect.Elements[1][0], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][1], Expect.Elements[1][1]);
|
EXPECT_NEAR(Result.Elements[1][1], Expect.Elements[1][1], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][2], Expect.Elements[1][2]);
|
EXPECT_NEAR(Result.Elements[1][2], Expect.Elements[1][2], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][3], Expect.Elements[1][3]);
|
EXPECT_NEAR(Result.Elements[1][3], Expect.Elements[1][3], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][0], Expect.Elements[2][0]);
|
EXPECT_NEAR(Result.Elements[2][0], Expect.Elements[2][0], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][1], Expect.Elements[2][1]);
|
EXPECT_NEAR(Result.Elements[2][1], Expect.Elements[2][1], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][2], Expect.Elements[2][2]);
|
EXPECT_NEAR(Result.Elements[2][2], Expect.Elements[2][2], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][3], Expect.Elements[2][3]);
|
EXPECT_NEAR(Result.Elements[2][3], Expect.Elements[2][3], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][0], Expect.Elements[3][0]);
|
EXPECT_NEAR(Result.Elements[3][0], Expect.Elements[3][0], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][1], Expect.Elements[3][1]);
|
EXPECT_NEAR(Result.Elements[3][1], Expect.Elements[3][1], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][2], Expect.Elements[3][2]);
|
EXPECT_NEAR(Result.Elements[3][2], Expect.Elements[3][2], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][3], Expect.Elements[3][3]);
|
EXPECT_NEAR(Result.Elements[3][3], Expect.Elements[3][3], 0.00001f);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
Inverse = HMM_InvGeneral(Matrix);
|
Inverse = HMM_InvGeneral(Matrix);
|
||||||
@@ -153,22 +153,22 @@ TEST(InvMatrix, InvGeneral)
|
|||||||
Det = HMM_Determinant(Matrix);
|
Det = HMM_Determinant(Matrix);
|
||||||
EXPECT_FLOAT_EQ(Det, -80.0f);
|
EXPECT_FLOAT_EQ(Det, -80.0f);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][0], Expect.Elements[0][0]);
|
EXPECT_NEAR(Result.Elements[0][0], Expect.Elements[0][0], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][1], Expect.Elements[0][1]);
|
EXPECT_NEAR(Result.Elements[0][1], Expect.Elements[0][1], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][2], Expect.Elements[0][2]);
|
EXPECT_NEAR(Result.Elements[0][2], Expect.Elements[0][2], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][3], Expect.Elements[0][3]);
|
EXPECT_NEAR(Result.Elements[0][3], Expect.Elements[0][3], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][0], Expect.Elements[1][0]);
|
EXPECT_NEAR(Result.Elements[1][0], Expect.Elements[1][0], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][1], Expect.Elements[1][1]);
|
EXPECT_NEAR(Result.Elements[1][1], Expect.Elements[1][1], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][2], Expect.Elements[1][2]);
|
EXPECT_NEAR(Result.Elements[1][2], Expect.Elements[1][2], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][3], Expect.Elements[1][3]);
|
EXPECT_NEAR(Result.Elements[1][3], Expect.Elements[1][3], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][0], Expect.Elements[2][0]);
|
EXPECT_NEAR(Result.Elements[2][0], Expect.Elements[2][0], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][1], Expect.Elements[2][1]);
|
EXPECT_NEAR(Result.Elements[2][1], Expect.Elements[2][1], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][2], Expect.Elements[2][2]);
|
EXPECT_NEAR(Result.Elements[2][2], Expect.Elements[2][2], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][3], Expect.Elements[2][3]);
|
EXPECT_NEAR(Result.Elements[2][3], Expect.Elements[2][3], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][0], Expect.Elements[3][0]);
|
EXPECT_NEAR(Result.Elements[3][0], Expect.Elements[3][0], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][1], Expect.Elements[3][1]);
|
EXPECT_NEAR(Result.Elements[3][1], Expect.Elements[3][1], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][2], Expect.Elements[3][2]);
|
EXPECT_NEAR(Result.Elements[3][2], Expect.Elements[3][2], 0.00001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][3], Expect.Elements[3][3]);
|
EXPECT_NEAR(Result.Elements[3][3], Expect.Elements[3][3], 0.00001f);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,60 +246,56 @@ TEST(InvMatrix, InvGeneral)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InvMatrix, Mat4Inverses)
|
TEST(InvMatrix, InvOrthographic)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
HMM_Mat4 Matrix = HMM_Orthographic_RH(-160+100, 160+100, -90+200, 90+200, 10, 10000);
|
HMM_Mat4 Matrix = HMM_Orthographic_RH_NO(-160+100, 160+100, -90+200, 90+200, 10, 10000);
|
||||||
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
|
||||||
HMM_Mat4 Inverse = HMM_InvOrthographic(Matrix);
|
HMM_Mat4 Inverse = HMM_InvOrthographic(Matrix);
|
||||||
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
EXPECT_M4_EQ(HMM_MulM4(Matrix, Inverse), HMM_M4D(1.0f));
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][0], Expect.Elements[0][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][1], Expect.Elements[0][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][2], Expect.Elements[0][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][3], Expect.Elements[0][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][0], Expect.Elements[1][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][1], Expect.Elements[1][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][2], Expect.Elements[1][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][3], Expect.Elements[1][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][0], Expect.Elements[2][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][1], Expect.Elements[2][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][2], Expect.Elements[2][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][3], Expect.Elements[2][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][0], Expect.Elements[3][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][1], Expect.Elements[3][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][2], Expect.Elements[3][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][3], Expect.Elements[3][3]);
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
HMM_Mat4 Matrix = HMM_Perspective_RH(HMM_AngleDeg(120), 16.0/9.0, 10, 10000);
|
HMM_Mat4 Matrix = HMM_Orthographic_RH_ZO(-160+100, 160+100, -90+200, 90+200, 10, 10000);
|
||||||
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
HMM_Mat4 Inverse = HMM_InvOrthographic(Matrix);
|
||||||
HMM_Mat4 Inverse = HMM_InvPerspective(Matrix);
|
EXPECT_M4_EQ(HMM_MulM4(Matrix, Inverse), HMM_M4D(1.0f));
|
||||||
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][0], Expect.Elements[0][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][1], Expect.Elements[0][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][2], Expect.Elements[0][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][3], Expect.Elements[0][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][0], Expect.Elements[1][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][1], Expect.Elements[1][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][2], Expect.Elements[1][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][3], Expect.Elements[1][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][0], Expect.Elements[2][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][1], Expect.Elements[2][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][2], Expect.Elements[2][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][3], Expect.Elements[2][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][0], Expect.Elements[3][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][1], Expect.Elements[3][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][2], Expect.Elements[3][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][3], Expect.Elements[3][3]);
|
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
HMM_Mat4 Matrix = HMM_Orthographic_LH_NO(-160+100, 160+100, -90+200, 90+200, 10, 10000);
|
||||||
|
HMM_Mat4 Inverse = HMM_InvOrthographic(Matrix);
|
||||||
|
EXPECT_M4_EQ(HMM_MulM4(Matrix, Inverse), HMM_M4D(1.0f));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HMM_Mat4 Matrix = HMM_Orthographic_LH_ZO(-160+100, 160+100, -90+200, 90+200, 10, 10000);
|
||||||
|
HMM_Mat4 Inverse = HMM_InvOrthographic(Matrix);
|
||||||
|
EXPECT_M4_EQ(HMM_MulM4(Matrix, Inverse), HMM_M4D(1.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(InvMatrix, InvPerspective)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
HMM_Mat4 Matrix = HMM_Perspective_RH_NO(HMM_AngleDeg(120), 16.0/9.0, 10, 10000);
|
||||||
|
HMM_Mat4 Inverse = HMM_InvPerspective_RH(Matrix);
|
||||||
|
EXPECT_M4_EQ(HMM_MulM4(Matrix, Inverse), HMM_M4D(1.0f));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HMM_Mat4 Matrix = HMM_Perspective_RH_ZO(HMM_AngleDeg(120), 16.0/9.0, 10, 10000);
|
||||||
|
HMM_Mat4 Inverse = HMM_InvPerspective_RH(Matrix);
|
||||||
|
EXPECT_M4_EQ(HMM_MulM4(Matrix, Inverse), HMM_M4D(1.0f));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HMM_Mat4 Matrix = HMM_Perspective_LH_NO(HMM_AngleDeg(120), 16.0/9.0, 10, 10000);
|
||||||
|
HMM_Mat4 Inverse = HMM_InvPerspective_LH(Matrix);
|
||||||
|
EXPECT_M4_EQ(HMM_MulM4(Matrix, Inverse), HMM_M4D(1.0f));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HMM_Mat4 Matrix = HMM_Perspective_LH_ZO(HMM_AngleDeg(120), 16.0/9.0, 10, 10000);
|
||||||
|
HMM_Mat4 Inverse = HMM_InvPerspective_LH(Matrix);
|
||||||
|
EXPECT_M4_EQ(HMM_MulM4(Matrix, Inverse), HMM_M4D(1.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(InvMatrix, InvLookAt)
|
||||||
|
{
|
||||||
{
|
{
|
||||||
HMM_Vec3 Eye = {10.0f, 10.0f, 10.0f};
|
HMM_Vec3 Eye = {10.0f, 10.0f, 10.0f};
|
||||||
HMM_Vec3 Center = {100.0f, 200.0f, 30.0f};
|
HMM_Vec3 Center = {100.0f, 200.0f, 30.0f};
|
||||||
@@ -308,106 +304,56 @@ TEST(InvMatrix, Mat4Inverses)
|
|||||||
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
||||||
HMM_Mat4 Inverse = HMM_InvLookAt(Matrix);
|
HMM_Mat4 Inverse = HMM_InvLookAt(Matrix);
|
||||||
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
||||||
|
EXPECT_M4_NEAR(Result, Expect, 0.001f);
|
||||||
EXPECT_NEAR(Result.Elements[0][0], Expect.Elements[0][0], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[0][1], Expect.Elements[0][1], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[0][2], Expect.Elements[0][2], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[0][3], Expect.Elements[0][3], 0.001f);
|
|
||||||
|
|
||||||
EXPECT_NEAR(Result.Elements[1][0], Expect.Elements[1][0], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[1][1], Expect.Elements[1][1], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[1][2], Expect.Elements[1][2], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[1][3], Expect.Elements[1][3], 0.001f);
|
|
||||||
|
|
||||||
EXPECT_NEAR(Result.Elements[2][0], Expect.Elements[2][0], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[2][1], Expect.Elements[2][1], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[2][2], Expect.Elements[2][2], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[2][3], Expect.Elements[2][3], 0.001f);
|
|
||||||
|
|
||||||
EXPECT_NEAR(Result.Elements[3][0], Expect.Elements[3][0], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[3][1], Expect.Elements[3][1], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[3][2], Expect.Elements[3][2], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[3][3], Expect.Elements[3][3], 0.001f);
|
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
HMM_Vec3 Eye = {10.0f, 10.0f, 10.0f};
|
||||||
|
HMM_Vec3 Center = {100.0f, 200.0f, 30.0f};
|
||||||
|
HMM_Vec3 Up = {0.0f, 0.0f, 1.0f};
|
||||||
|
HMM_Mat4 Matrix = HMM_LookAt_LH(Eye, Center, Up);
|
||||||
|
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
||||||
|
HMM_Mat4 Inverse = HMM_InvLookAt(Matrix);
|
||||||
|
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
||||||
|
EXPECT_M4_NEAR(Result, Expect, 0.001f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(InvMatrix, InvRotate)
|
||||||
|
{
|
||||||
{
|
{
|
||||||
HMM_Vec3 Axis = {1.0f, -1.0f, 0.5f};
|
HMM_Vec3 Axis = {1.0f, -1.0f, 0.5f};
|
||||||
HMM_Mat4 Matrix = HMM_Rotate_RH(HMM_AngleDeg(30), HMM_NormV3(Axis));
|
HMM_Mat4 Matrix = HMM_Rotate_RH(HMM_AngleDeg(30), HMM_NormV3(Axis));
|
||||||
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
||||||
HMM_Mat4 Inverse = HMM_InvRotate(Matrix);
|
HMM_Mat4 Inverse = HMM_InvRotate(Matrix);
|
||||||
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
||||||
|
EXPECT_M4_NEAR(Result, Expect, 0.001f);
|
||||||
EXPECT_NEAR(Result.Elements[0][0], Expect.Elements[0][0], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[0][1], Expect.Elements[0][1], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[0][2], Expect.Elements[0][2], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[0][3], Expect.Elements[0][3], 0.001f);
|
|
||||||
|
|
||||||
EXPECT_NEAR(Result.Elements[1][0], Expect.Elements[1][0], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[1][1], Expect.Elements[1][1], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[1][2], Expect.Elements[1][2], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[1][3], Expect.Elements[1][3], 0.001f);
|
|
||||||
|
|
||||||
EXPECT_NEAR(Result.Elements[2][0], Expect.Elements[2][0], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[2][1], Expect.Elements[2][1], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[2][2], Expect.Elements[2][2], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[2][3], Expect.Elements[2][3], 0.001f);
|
|
||||||
|
|
||||||
EXPECT_NEAR(Result.Elements[3][0], Expect.Elements[3][0], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[3][1], Expect.Elements[3][1], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[3][2], Expect.Elements[3][2], 0.001f);
|
|
||||||
EXPECT_NEAR(Result.Elements[3][3], Expect.Elements[3][3], 0.001f);
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
HMM_Vec3 Scale = {1.0f, -1.0f, 0.5f};
|
HMM_Vec3 Axis = {1.0f, -1.0f, 0.5f};
|
||||||
HMM_Mat4 Matrix = HMM_Scale(Scale);
|
HMM_Mat4 Matrix = HMM_Rotate_LH(HMM_AngleDeg(30), HMM_NormV3(Axis));
|
||||||
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
||||||
HMM_Mat4 Inverse = HMM_InvScale(Matrix);
|
HMM_Mat4 Inverse = HMM_InvRotate(Matrix);
|
||||||
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
||||||
|
EXPECT_M4_NEAR(Result, Expect, 0.001f);
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][0], Expect.Elements[0][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][1], Expect.Elements[0][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][2], Expect.Elements[0][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][3], Expect.Elements[0][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][0], Expect.Elements[1][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][1], Expect.Elements[1][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][2], Expect.Elements[1][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][3], Expect.Elements[1][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][0], Expect.Elements[2][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][1], Expect.Elements[2][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][2], Expect.Elements[2][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][3], Expect.Elements[2][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][0], Expect.Elements[3][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][1], Expect.Elements[3][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][2], Expect.Elements[3][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][3], Expect.Elements[3][3]);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
HMM_Vec3 Move = {1.0f, -1.0f, 0.5f};
|
|
||||||
HMM_Mat4 Matrix = HMM_Translate(Move);
|
|
||||||
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
|
||||||
HMM_Mat4 Inverse = HMM_InvTranslate(Matrix);
|
|
||||||
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][0], Expect.Elements[0][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][1], Expect.Elements[0][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][2], Expect.Elements[0][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[0][3], Expect.Elements[0][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][0], Expect.Elements[1][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][1], Expect.Elements[1][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][2], Expect.Elements[1][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[1][3], Expect.Elements[1][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][0], Expect.Elements[2][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][1], Expect.Elements[2][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][2], Expect.Elements[2][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[2][3], Expect.Elements[2][3]);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][0], Expect.Elements[3][0]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][1], Expect.Elements[3][1]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][2], Expect.Elements[3][2]);
|
|
||||||
EXPECT_FLOAT_EQ(Result.Elements[3][3], Expect.Elements[3][3]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(InvMatrix, InvScale)
|
||||||
|
{
|
||||||
|
HMM_Vec3 Scale = {1.0f, -1.0f, 0.5f};
|
||||||
|
HMM_Mat4 Matrix = HMM_Scale(Scale);
|
||||||
|
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
||||||
|
HMM_Mat4 Inverse = HMM_InvScale(Matrix);
|
||||||
|
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
||||||
|
EXPECT_M4_EQ(Result, Expect);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(InvMatrix, InvTranslate)
|
||||||
|
{
|
||||||
|
HMM_Vec3 Move = {1.0f, -1.0f, 0.5f};
|
||||||
|
HMM_Mat4 Matrix = HMM_Translate(Move);
|
||||||
|
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
||||||
|
HMM_Mat4 Inverse = HMM_InvTranslate(Matrix);
|
||||||
|
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
||||||
|
EXPECT_M4_EQ(Result, Expect);
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ TEST(Multiplication, Vec2Vec2)
|
|||||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 8.0f);
|
EXPECT_FLOAT_EQ(result.Y, 8.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = HMM_Mul(v2_1, v2_2);
|
HMM_Vec2 result = HMM_Mul(v2_1, v2_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 8.0f);
|
EXPECT_FLOAT_EQ(result.Y, 8.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = v2_1 * v2_2;
|
HMM_Vec2 result = v2_1 * v2_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||||
@@ -38,12 +40,14 @@ TEST(Multiplication, Vec2Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = HMM_Mul(v2, s);
|
HMM_Vec2 result = HMM_Mul(v2, s);
|
||||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = v2 * s;
|
HMM_Vec2 result = v2 * s;
|
||||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||||
@@ -72,13 +76,15 @@ TEST(Multiplication, Vec3Vec3)
|
|||||||
EXPECT_FLOAT_EQ(result.Y, 10.0f);
|
EXPECT_FLOAT_EQ(result.Y, 10.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, 18.0f);
|
EXPECT_FLOAT_EQ(result.Z, 18.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = HMM_Mul(v3_1, v3_2);
|
HMM_Vec3 result = HMM_Mul(v3_1, v3_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 10.0f);
|
EXPECT_FLOAT_EQ(result.Y, 10.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, 18.0f);
|
EXPECT_FLOAT_EQ(result.Z, 18.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = v3_1 * v3_2;
|
HMM_Vec3 result = v3_1 * v3_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
||||||
@@ -104,13 +110,15 @@ TEST(Multiplication, Vec3Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = HMM_Mul(v3, s);
|
HMM_Vec3 result = HMM_Mul(v3, s);
|
||||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = v3 * s;
|
HMM_Vec3 result = v3 * s;
|
||||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||||
@@ -143,7 +151,7 @@ TEST(Multiplication, Vec4Vec4)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 21.0f);
|
EXPECT_FLOAT_EQ(result.Z, 21.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 32.0f);
|
EXPECT_FLOAT_EQ(result.W, 32.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = HMM_Mul(v4_1, v4_2);
|
HMM_Vec4 result = HMM_Mul(v4_1, v4_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 5.0f);
|
EXPECT_FLOAT_EQ(result.X, 5.0f);
|
||||||
@@ -151,6 +159,8 @@ TEST(Multiplication, Vec4Vec4)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 21.0f);
|
EXPECT_FLOAT_EQ(result.Z, 21.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 32.0f);
|
EXPECT_FLOAT_EQ(result.W, 32.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = v4_1 * v4_2;
|
HMM_Vec4 result = v4_1 * v4_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, 5.0f);
|
EXPECT_FLOAT_EQ(result.X, 5.0f);
|
||||||
@@ -179,7 +189,7 @@ TEST(Multiplication, Vec4Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = HMM_Mul(v4, s);
|
HMM_Vec4 result = HMM_Mul(v4, s);
|
||||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||||
@@ -187,6 +197,8 @@ TEST(Multiplication, Vec4Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = v4 * s;
|
HMM_Vec4 result = v4 * s;
|
||||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||||
@@ -234,7 +246,7 @@ TEST(Multiplication, Mat2Mat2) {
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 46.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][1], 46.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat2 result = HMM_Mul(a,b);
|
HMM_Mat2 result = HMM_Mul(a,b);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 23.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 23.0f);
|
||||||
@@ -242,7 +254,9 @@ TEST(Multiplication, Mat2Mat2) {
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 31.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][0], 31.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 46.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][1], 46.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat2 result = a * b;
|
HMM_Mat2 result = a * b;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 23.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 23.0f);
|
||||||
@@ -271,7 +285,7 @@ TEST(Multiplication, Mat2Scalar) {
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 30.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][0], 30.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 40.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][1], 40.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat2 result = HMM_Mul(m, s);
|
HMM_Mat2 result = HMM_Mul(m, s);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||||
@@ -279,6 +293,8 @@ TEST(Multiplication, Mat2Scalar) {
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 30.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][0], 30.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 40.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1][1], 40.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat2 result = m * s;
|
HMM_Mat2 result = m * s;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||||
@@ -322,13 +338,15 @@ TEST(Multiplication, Mat2Vec2) {
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1], 34.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1], 34.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = HMM_Mul(m, v);
|
HMM_Vec2 result = HMM_Mul(m, v);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0], 23.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0], 23.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[1], 34.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1], 34.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = m * v;
|
HMM_Vec2 result = m * v;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0], 23.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0], 23.0f);
|
||||||
@@ -368,7 +386,7 @@ TEST(Multiplication, Mat3Mat3)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 312.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], 312.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat3 result = HMM_Mul(a,b);
|
HMM_Mat3 result = HMM_Mul(a,b);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 138.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 138.0f);
|
||||||
@@ -381,7 +399,9 @@ TEST(Multiplication, Mat3Mat3)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 261.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][1], 261.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 312.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], 312.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat3 result = a * b;
|
HMM_Mat3 result = a * b;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 138.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 138.0f);
|
||||||
@@ -420,7 +440,7 @@ TEST(Multiplication, Mat3Scalar) {
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 80.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][1], 80.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 90.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], 90.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat3 result = HMM_Mul(m, s);
|
HMM_Mat3 result = HMM_Mul(m, s);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||||
@@ -433,6 +453,8 @@ TEST(Multiplication, Mat3Scalar) {
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 80.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][1], 80.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 90.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], 90.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat3 result = m * s;
|
HMM_Mat3 result = m * s;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||||
@@ -491,14 +513,15 @@ TEST(Multiplication, Mat3Vec3) {
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1], 171.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1], 171.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[2], 204.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2], 204.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = HMM_Mul(m, v);
|
HMM_Vec3 result = HMM_Mul(m, v);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0], 138.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0], 138.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[1], 171.0f);
|
EXPECT_FLOAT_EQ(result.Elements[1], 171.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[2], 204.0f);
|
EXPECT_FLOAT_EQ(result.Elements[2], 204.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = m * v;
|
HMM_Vec3 result = m * v;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0], 138.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0], 138.0f);
|
||||||
@@ -552,7 +575,7 @@ TEST(Multiplication, Mat4Mat4)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[3][2], 1118.0f);
|
EXPECT_FLOAT_EQ(result.Elements[3][2], 1118.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 1240.0f);
|
EXPECT_FLOAT_EQ(result.Elements[3][3], 1240.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat4 result = HMM_Mul(m4_1, m4_2);
|
HMM_Mat4 result = HMM_Mul(m4_1, m4_2);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 538.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 538.0f);
|
||||||
@@ -572,6 +595,8 @@ TEST(Multiplication, Mat4Mat4)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[3][2], 1118.0f);
|
EXPECT_FLOAT_EQ(result.Elements[3][2], 1118.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 1240.0f);
|
EXPECT_FLOAT_EQ(result.Elements[3][3], 1240.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat4 result = m4_1 * m4_2;
|
HMM_Mat4 result = m4_1 * m4_2;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 538.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 538.0f);
|
||||||
@@ -634,7 +659,7 @@ TEST(Multiplication, Mat4Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[3][2], 45.0f);
|
EXPECT_FLOAT_EQ(result.Elements[3][2], 45.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 48.0f);
|
EXPECT_FLOAT_EQ(result.Elements[3][3], 48.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat4 result = HMM_Mul(m4, s);
|
HMM_Mat4 result = HMM_Mul(m4, s);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 3.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 3.0f);
|
||||||
@@ -654,6 +679,8 @@ TEST(Multiplication, Mat4Scalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[3][2], 45.0f);
|
EXPECT_FLOAT_EQ(result.Elements[3][2], 45.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 48.0f);
|
EXPECT_FLOAT_EQ(result.Elements[3][3], 48.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat4 result = m4 * s;
|
HMM_Mat4 result = m4 * s;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 3.0f);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 3.0f);
|
||||||
@@ -737,7 +764,7 @@ TEST(Multiplication, Mat4Vec4)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 110.0f);
|
EXPECT_FLOAT_EQ(result.Z, 110.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 120.0f);
|
EXPECT_FLOAT_EQ(result.W, 120.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = HMM_Mul(m4, v4);
|
HMM_Vec4 result = HMM_Mul(m4, v4);
|
||||||
EXPECT_FLOAT_EQ(result.X, 90.0f);
|
EXPECT_FLOAT_EQ(result.X, 90.0f);
|
||||||
@@ -745,6 +772,8 @@ TEST(Multiplication, Mat4Vec4)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 110.0f);
|
EXPECT_FLOAT_EQ(result.Z, 110.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 120.0f);
|
EXPECT_FLOAT_EQ(result.W, 120.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = m4 * v4;
|
HMM_Vec4 result = m4 * v4;
|
||||||
EXPECT_FLOAT_EQ(result.X, 90.0f);
|
EXPECT_FLOAT_EQ(result.X, 90.0f);
|
||||||
@@ -769,7 +798,7 @@ TEST(Multiplication, QuaternionQuaternion)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 48.0f);
|
EXPECT_FLOAT_EQ(result.Z, 48.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, -6.0f);
|
EXPECT_FLOAT_EQ(result.W, -6.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Quat result = HMM_Mul(q1, q2);
|
HMM_Quat result = HMM_Mul(q1, q2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 24.0f);
|
EXPECT_FLOAT_EQ(result.X, 24.0f);
|
||||||
@@ -777,6 +806,8 @@ TEST(Multiplication, QuaternionQuaternion)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 48.0f);
|
EXPECT_FLOAT_EQ(result.Z, 48.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, -6.0f);
|
EXPECT_FLOAT_EQ(result.W, -6.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Quat result = q1 * q2;
|
HMM_Quat result = q1 * q2;
|
||||||
EXPECT_FLOAT_EQ(result.X, 24.0f);
|
EXPECT_FLOAT_EQ(result.X, 24.0f);
|
||||||
@@ -803,7 +834,7 @@ TEST(Multiplication, QuaternionScalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 6.0f);
|
EXPECT_FLOAT_EQ(result.Z, 6.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 8.0f);
|
EXPECT_FLOAT_EQ(result.W, 8.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Quat result = HMM_Mul(q, f);
|
HMM_Quat result = HMM_Mul(q, f);
|
||||||
EXPECT_FLOAT_EQ(result.X, 2.0f);
|
EXPECT_FLOAT_EQ(result.X, 2.0f);
|
||||||
@@ -811,6 +842,8 @@ TEST(Multiplication, QuaternionScalar)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 6.0f);
|
EXPECT_FLOAT_EQ(result.Z, 6.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 8.0f);
|
EXPECT_FLOAT_EQ(result.W, 8.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Quat result = q * f;
|
HMM_Quat result = q * f;
|
||||||
EXPECT_FLOAT_EQ(result.X, 2.0f);
|
EXPECT_FLOAT_EQ(result.X, 2.0f);
|
||||||
|
|||||||
@@ -2,48 +2,84 @@
|
|||||||
|
|
||||||
TEST(Projection, Orthographic)
|
TEST(Projection, Orthographic)
|
||||||
{
|
{
|
||||||
|
#define ORTHO_BOUNDS -8.0f, 12.0f, 5.0f, 10.0f, 1.0f, 100.0f
|
||||||
|
|
||||||
|
// Right-handed
|
||||||
{
|
{
|
||||||
HMM_Mat4 projection = HMM_Orthographic_RH(-10.0f, 10.0f, -5.0f, 5.0f, 0.0f, -10.0f);
|
// Near and far distances correspond to negative Z, hence the Z coordinates here are negative.
|
||||||
|
HMM_Vec4 minCorner = HMM_V4(-8.0f, 5.0f, -1.0f, 1.0);
|
||||||
|
HMM_Vec4 maxCorner = HMM_V4(12.0f, 10.0f, -100.0f, 1.0);
|
||||||
|
|
||||||
HMM_Vec3 original = HMM_V3(5.0f, 5.0f, -5.0f);
|
// Z from -1 to 1 (GL convention)
|
||||||
HMM_Vec4 projected = HMM_MulM4V4(projection, HMM_V4V(original, 1));
|
{
|
||||||
|
HMM_Mat4 projection = HMM_Orthographic_RH_NO(ORTHO_BOUNDS);
|
||||||
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, minCorner), HMM_V4(-1.0f, -1.0f, -1.0f, 1.0f));
|
||||||
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, maxCorner), HMM_V4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(projected.X, 0.5f);
|
// Z from 0 to 1 (DX convention)
|
||||||
EXPECT_FLOAT_EQ(projected.Y, 1.0f);
|
{
|
||||||
EXPECT_FLOAT_EQ(projected.Z, -2.0f);
|
HMM_Mat4 projection = HMM_Orthographic_RH_ZO(ORTHO_BOUNDS);
|
||||||
EXPECT_FLOAT_EQ(projected.W, 1.0f);
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, minCorner), HMM_V4(-1.0f, -1.0f, 0.0f, 1.0f));
|
||||||
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, maxCorner), HMM_V4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Left-handed
|
||||||
{
|
{
|
||||||
HMM_Mat4 projection = HMM_Orthographic_LH(-10.0f, 10.0f, -5.0f, 5.0f, 0.0f, 10.0f);
|
// Near and far distances correspond to positive Z, hence the Z coordinates here are positive.
|
||||||
|
HMM_Vec4 minCorner = HMM_V4(-8.0f, 5.0f, 1.0f, 1.0);
|
||||||
|
HMM_Vec4 maxCorner = HMM_V4(12.0f, 10.0f, 100.0f, 1.0);
|
||||||
|
|
||||||
HMM_Vec3 original = HMM_V3(5.0f, 5.0f, -5.0f);
|
// Z from -1 to 1 (GL convention)
|
||||||
HMM_Vec4 projected = HMM_MulM4V4(projection, HMM_V4V(original, 1));
|
{
|
||||||
|
HMM_Mat4 projection = HMM_Orthographic_LH_NO(ORTHO_BOUNDS);
|
||||||
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, minCorner), HMM_V4(-1.0f, -1.0f, -1.0f, 1.0f));
|
||||||
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, maxCorner), HMM_V4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(projected.X, 0.5f);
|
// Z from 0 to 1 (DX convention)
|
||||||
EXPECT_FLOAT_EQ(projected.Y, 1.0f);
|
{
|
||||||
EXPECT_FLOAT_EQ(projected.Z, -2.0f);
|
HMM_Mat4 projection = HMM_Orthographic_LH_ZO(ORTHO_BOUNDS);
|
||||||
EXPECT_FLOAT_EQ(projected.W, 1.0f);
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, minCorner), HMM_V4(-1.0f, -1.0f, 0.0f, 1.0f));
|
||||||
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, maxCorner), HMM_V4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Projection, Perspective)
|
TEST(Projection, Perspective)
|
||||||
{
|
{
|
||||||
|
// Right-handed
|
||||||
{
|
{
|
||||||
HMM_Mat4 projection = HMM_Perspective_RH(HMM_AngleDeg(90.0f), 2.0f, 5.0f, 15.0f);
|
// Z from -1 to 1 (GL convention)
|
||||||
HMM_Vec3 original = HMM_V3(5.0f, 5.0f, -15.0f);
|
{
|
||||||
HMM_Vec4 projected = HMM_MulM4V4(projection, HMM_V4V(original, 1));
|
HMM_Mat4 projection = HMM_Perspective_RH_NO(HMM_AngleDeg(90.0f), 2.0f, 1.0f, 15.0f);
|
||||||
EXPECT_FLOAT_EQ(projected.X, 2.5f);
|
HMM_Vec4 original = HMM_V4(5.0f, 5.0f, -1.0f, 1.0f);
|
||||||
EXPECT_FLOAT_EQ(projected.Y, 5.0f);
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, original), HMM_V4(2.5f, 5.0f, -1.0f, 1.0f));
|
||||||
EXPECT_FLOAT_EQ(projected.Z, 15.0f);
|
}
|
||||||
EXPECT_FLOAT_EQ(projected.W, 15.0f);
|
|
||||||
|
// Z from 0 to 1 (DX convention)
|
||||||
|
{
|
||||||
|
HMM_Mat4 projection = HMM_Perspective_RH_ZO(HMM_AngleDeg(90.0f), 2.0f, 1.0f, 15.0f);
|
||||||
|
HMM_Vec4 original = HMM_V4(5.0f, 5.0f, -1.0f, 1.0f);
|
||||||
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, original), HMM_V4(2.5f, 5.0f, 0.0f, 1.0f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Left-handed
|
||||||
{
|
{
|
||||||
HMM_Mat4 projection = HMM_Perspective_LH(HMM_AngleDeg(90.0f), 2.0f, 5.0f, 15.0f);
|
// Z from -1 to 1 (GL convention)
|
||||||
HMM_Vec3 original = HMM_V3(5.0f, 5.0f, -15.0f);
|
{
|
||||||
HMM_Vec4 projected = HMM_MulM4V4(projection, HMM_V4V(original, 1));
|
HMM_Mat4 projection = HMM_Perspective_LH_NO(HMM_AngleDeg(90.0f), 2.0f, 1.0f, 15.0f);
|
||||||
EXPECT_FLOAT_EQ(projected.X, 2.5f);
|
HMM_Vec4 original = HMM_V4(5.0f, 5.0f, 1.0f, 1.0f);
|
||||||
EXPECT_FLOAT_EQ(projected.Y, 5.0f);
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, original), HMM_V4(2.5f, 5.0f, -1.0f, 1.0f));
|
||||||
EXPECT_FLOAT_EQ(projected.Z, 15.0f);
|
}
|
||||||
EXPECT_FLOAT_EQ(projected.W, -15.0f);
|
|
||||||
|
// Z from 0 to 1 (DX convention)
|
||||||
|
{
|
||||||
|
HMM_Mat4 projection = HMM_Perspective_LH_ZO(HMM_AngleDeg(90.0f), 2.0f, 1.0f, 15.0f);
|
||||||
|
HMM_Vec4 original = HMM_V4(5.0f, 5.0f, 1.0f, 1.0f);
|
||||||
|
EXPECT_V4_EQ(HMM_MulM4V4(projection, original), HMM_V4(2.5f, 5.0f, 0.0f, 1.0f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ TEST(QuaternionOps, Dot)
|
|||||||
float result = HMM_DotQ(q1, q2);
|
float result = HMM_DotQ(q1, q2);
|
||||||
EXPECT_FLOAT_EQ(result, 70.0f);
|
EXPECT_FLOAT_EQ(result, 70.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
float result = HMM_Dot(q1, q2);
|
float result = HMM_Dot(q1, q2);
|
||||||
EXPECT_FLOAT_EQ(result, 70.0f);
|
EXPECT_FLOAT_EQ(result, 70.0f);
|
||||||
@@ -41,7 +41,7 @@ TEST(QuaternionOps, Normalize)
|
|||||||
EXPECT_NEAR(result.Z, 0.5477225575f, 0.001f);
|
EXPECT_NEAR(result.Z, 0.5477225575f, 0.001f);
|
||||||
EXPECT_NEAR(result.W, 0.7302967433f, 0.001f);
|
EXPECT_NEAR(result.W, 0.7302967433f, 0.001f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Quat result = HMM_Norm(q);
|
HMM_Quat result = HMM_Norm(q);
|
||||||
EXPECT_NEAR(result.X, 0.1825741858f, 0.001f);
|
EXPECT_NEAR(result.X, 0.1825741858f, 0.001f);
|
||||||
@@ -97,7 +97,7 @@ TEST(QuaternionOps, SLerp)
|
|||||||
EXPECT_NEAR(result.Z, -0.40824830f, 0.001f);
|
EXPECT_NEAR(result.Z, -0.40824830f, 0.001f);
|
||||||
EXPECT_NEAR(result.W, 0.70710676f, 0.001f);
|
EXPECT_NEAR(result.W, 0.70710676f, 0.001f);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
HMM_Quat result = HMM_SLerp(from, 1.0f, to);
|
HMM_Quat result = HMM_SLerp(from, 1.0f, to);
|
||||||
EXPECT_NEAR(result.X, 0.5f, 0.001f);
|
EXPECT_NEAR(result.X, 0.5f, 0.001f);
|
||||||
EXPECT_NEAR(result.Y, 0.5f, 0.001f);
|
EXPECT_NEAR(result.Y, 0.5f, 0.001f);
|
||||||
@@ -254,23 +254,44 @@ TEST(QuaternionOps, Mat4ToQuat)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(QuaternionOps, FromAxisAngle)
|
TEST(QuaternionOps, RotateVectorAxisAngle)
|
||||||
{
|
{
|
||||||
HMM_Vec3 axis = HMM_V3(1.0f, 0.0f, 0.0f);
|
|
||||||
float angle = HMM_PI32 / 2.0f;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
HMM_Quat result = HMM_QFromAxisAngle_RH(axis, angle);
|
HMM_Vec3 axis = HMM_V3(0.0f, 1.0f, 0.0f);
|
||||||
EXPECT_NEAR(result.X, 0.707107f, 0.001f);
|
float angle = HMM_AngleTurn(1.0/4);
|
||||||
|
HMM_Vec3 result = HMM_RotateV3AxisAngle_LH(HMM_V3(1.0f, 0.0f, 0.0f), axis, angle);
|
||||||
|
EXPECT_NEAR(result.X, 0.0f, 0.001f);
|
||||||
EXPECT_NEAR(result.Y, 0.0f, 0.001f);
|
EXPECT_NEAR(result.Y, 0.0f, 0.001f);
|
||||||
EXPECT_NEAR(result.Z, 0.0f, 0.001f);
|
EXPECT_NEAR(result.Z, 1.0f, 0.001f);
|
||||||
EXPECT_NEAR(result.W, 0.707107f, 0.001f);
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
HMM_Quat result = HMM_QFromAxisAngle_LH(axis, angle);
|
HMM_Vec3 axis = HMM_V3(1.0f, 0.0f, 0.0f);
|
||||||
EXPECT_NEAR(result.X, -0.707107f, 0.001f);
|
float angle = HMM_AngleTurn(1.0/8);
|
||||||
EXPECT_NEAR(result.Y, 0.0f, 0.001f);
|
HMM_Vec3 result = HMM_RotateV3AxisAngle_RH(HMM_V3(0.0f, 0.0f, 1.0f), axis, angle);
|
||||||
EXPECT_NEAR(result.Z, 0.0f, 0.001f);
|
EXPECT_NEAR(result.X, 0.0f, 0.001f);
|
||||||
EXPECT_NEAR(result.W, 0.707107f, 0.001f);
|
EXPECT_NEAR(result.Y, -0.707170f, 0.001f);
|
||||||
|
EXPECT_NEAR(result.Z, 0.707170f, 0.001f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(QuaternionOps, QuatFromPairs)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
HMM_Vec3 n1 = HMM_V3(0.0f, 1.0f, 0.0f);
|
||||||
|
HMM_Vec3 n2 = HMM_V3(0.0f, 0.0f, 1.0f);
|
||||||
|
HMM_Quat q = HMM_QFromNormPair(n1, n2);
|
||||||
|
HMM_Vec3 result = HMM_RotateV3Q(n1, q);
|
||||||
|
EXPECT_NEAR(result.X, n2.X, 0.001f);
|
||||||
|
EXPECT_NEAR(result.Y, n2.Y, 0.001f);
|
||||||
|
EXPECT_NEAR(result.Z, n2.Z, 0.001f);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HMM_Vec3 v1 = HMM_V3(2.0f, 2.0f, 2.0f);
|
||||||
|
HMM_Vec3 v2 = HMM_V3(3.0f, 0.0f, 0.0f);
|
||||||
|
HMM_Quat q = HMM_QFromVecPair(v1, v2);
|
||||||
|
HMM_Vec3 result = HMM_RotateV3Q(HMM_V3(0.0f, 1.0f, 0.0f), q);
|
||||||
|
EXPECT_NEAR(result.X, 0.577350, 0.001f);
|
||||||
|
EXPECT_NEAR(result.Y, 0.788675, 0.001f);
|
||||||
|
EXPECT_NEAR(result.Z, -0.211325, 0.001f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ TEST(Subtraction, Vec2)
|
|||||||
EXPECT_FLOAT_EQ(result.X, -2.0f);
|
EXPECT_FLOAT_EQ(result.X, -2.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, -2.0f);
|
EXPECT_FLOAT_EQ(result.Y, -2.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = HMM_Sub(v2_1, v2_2);
|
HMM_Vec2 result = HMM_Sub(v2_1, v2_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, -2.0f);
|
EXPECT_FLOAT_EQ(result.X, -2.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, -2.0f);
|
EXPECT_FLOAT_EQ(result.Y, -2.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = v2_1 - v2_2;
|
HMM_Vec2 result = v2_1 - v2_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, -2.0f);
|
EXPECT_FLOAT_EQ(result.X, -2.0f);
|
||||||
@@ -39,13 +41,15 @@ TEST(Subtraction, Vec3)
|
|||||||
EXPECT_FLOAT_EQ(result.Y, -3.0f);
|
EXPECT_FLOAT_EQ(result.Y, -3.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, -3.0f);
|
EXPECT_FLOAT_EQ(result.Z, -3.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = HMM_Sub(v3_1, v3_2);
|
HMM_Vec3 result = HMM_Sub(v3_1, v3_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, -3.0f);
|
EXPECT_FLOAT_EQ(result.X, -3.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, -3.0f);
|
EXPECT_FLOAT_EQ(result.Y, -3.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, -3.0f);
|
EXPECT_FLOAT_EQ(result.Z, -3.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = v3_1 - v3_2;
|
HMM_Vec3 result = v3_1 - v3_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, -3.0f);
|
EXPECT_FLOAT_EQ(result.X, -3.0f);
|
||||||
@@ -72,7 +76,7 @@ TEST(Subtraction, Vec4)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, -4.0f);
|
EXPECT_FLOAT_EQ(result.W, -4.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = HMM_Sub(v4_1, v4_2);
|
HMM_Vec4 result = HMM_Sub(v4_1, v4_2);
|
||||||
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
||||||
@@ -80,6 +84,8 @@ TEST(Subtraction, Vec4)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, -4.0f);
|
EXPECT_FLOAT_EQ(result.W, -4.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = v4_1 - v4_2;
|
HMM_Vec4 result = v4_1 - v4_2;
|
||||||
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
||||||
@@ -124,7 +130,7 @@ TEST(Subtraction, Mat2)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 4.0);
|
EXPECT_FLOAT_EQ(result.Elements[1][0], 4.0);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 4.0);
|
EXPECT_FLOAT_EQ(result.Elements[1][1], 4.0);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat2 result = HMM_Sub(b,a);
|
HMM_Mat2 result = HMM_Sub(b,a);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 4.0);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 4.0);
|
||||||
@@ -132,7 +138,8 @@ TEST(Subtraction, Mat2)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 4.0);
|
EXPECT_FLOAT_EQ(result.Elements[1][0], 4.0);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 4.0);
|
EXPECT_FLOAT_EQ(result.Elements[1][1], 4.0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat2 result = b - a;
|
HMM_Mat2 result = b - a;
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 4.0);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 4.0);
|
||||||
@@ -183,7 +190,7 @@ TEST(Subtraction, Mat3)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 9.0);
|
EXPECT_FLOAT_EQ(result.Elements[2][1], 9.0);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 9.0);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], 9.0);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat3 result = HMM_Sub(b,a);
|
HMM_Mat3 result = HMM_Sub(b,a);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 9.0);
|
EXPECT_FLOAT_EQ(result.Elements[0][0], 9.0);
|
||||||
@@ -196,7 +203,9 @@ TEST(Subtraction, Mat3)
|
|||||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 9.0);
|
EXPECT_FLOAT_EQ(result.Elements[2][1], 9.0);
|
||||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 9.0);
|
EXPECT_FLOAT_EQ(result.Elements[2][2], 9.0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
b -= a;
|
b -= a;
|
||||||
EXPECT_FLOAT_EQ(b.Elements[0][0], 9.0);
|
EXPECT_FLOAT_EQ(b.Elements[0][0], 9.0);
|
||||||
EXPECT_FLOAT_EQ(b.Elements[0][1], 9.0);
|
EXPECT_FLOAT_EQ(b.Elements[0][1], 9.0);
|
||||||
@@ -245,7 +254,7 @@ TEST(Subtraction, Mat4)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Mat4 result = HMM_Sub(m4_1, m4_2);
|
HMM_Mat4 result = HMM_Sub(m4_1, m4_2);
|
||||||
for (int Column = 0; Column < 4; ++Column)
|
for (int Column = 0; Column < 4; ++Column)
|
||||||
@@ -256,6 +265,8 @@ TEST(Subtraction, Mat4)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Mat4 result = m4_1 - m4_2;
|
HMM_Mat4 result = m4_1 - m4_2;
|
||||||
for (int Column = 0; Column < 4; ++Column)
|
for (int Column = 0; Column < 4; ++Column)
|
||||||
@@ -290,7 +301,7 @@ TEST(Subtraction, Quaternion)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, -4.0f);
|
EXPECT_FLOAT_EQ(result.W, -4.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Quat result = HMM_Sub(q1, q2);
|
HMM_Quat result = HMM_Sub(q1, q2);
|
||||||
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
||||||
@@ -298,6 +309,8 @@ TEST(Subtraction, Quaternion)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
||||||
EXPECT_FLOAT_EQ(result.W, -4.0f);
|
EXPECT_FLOAT_EQ(result.W, -4.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
{
|
{
|
||||||
HMM_Quat result = q1 - q2;
|
HMM_Quat result = q1 - q2;
|
||||||
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ TEST(Transformations, LookAt)
|
|||||||
{
|
{
|
||||||
const float abs_error = 0.001f;
|
const float abs_error = 0.001f;
|
||||||
|
|
||||||
{ HMM_Mat4 result = HMM_LookAt_RH(HMM_V3(1.0f, 0.0f, 0.0f), HMM_V3(0.0f, 2.0f, 1.0f), HMM_V3(2.0f, 1.0f, 1.0f));
|
{
|
||||||
|
HMM_Mat4 result = HMM_LookAt_RH(HMM_V3(1.0f, 0.0f, 0.0f), HMM_V3(0.0f, 2.0f, 1.0f), HMM_V3(2.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
EXPECT_NEAR(result.Elements[0][0], 0.169031f, abs_error);
|
EXPECT_NEAR(result.Elements[0][0], 0.169031f, abs_error);
|
||||||
EXPECT_NEAR(result.Elements[0][1], 0.897085f, abs_error);
|
EXPECT_NEAR(result.Elements[0][1], 0.897085f, abs_error);
|
||||||
@@ -103,3 +104,30 @@ TEST(Transformations, LookAt)
|
|||||||
EXPECT_NEAR(result.Elements[3][3], 1.0f, abs_error);
|
EXPECT_NEAR(result.Elements[3][3], 1.0f, abs_error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Transformations, RotateV2)
|
||||||
|
{
|
||||||
|
HMM_Vec2 v2 = HMM_V2(1, 2);
|
||||||
|
|
||||||
|
float epsilon = 0.000001f;
|
||||||
|
{
|
||||||
|
HMM_Vec2 res = HMM_RotateV2(v2, HMM_AngleDeg(90));
|
||||||
|
EXPECT_NEAR(res.X, -2.0f, epsilon);
|
||||||
|
EXPECT_NEAR(res.Y, 1.0f, epsilon);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HMM_Vec2 res = HMM_RotateV2(v2, HMM_AngleDeg(180));
|
||||||
|
EXPECT_NEAR(res.X, -1.0f, epsilon);
|
||||||
|
EXPECT_NEAR(res.Y, -2.0f, epsilon);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HMM_Vec2 res = HMM_RotateV2(v2, HMM_AngleDeg(270));
|
||||||
|
EXPECT_NEAR(res.X, 2.0f, epsilon);
|
||||||
|
EXPECT_NEAR(res.Y, -1.0f, epsilon);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HMM_Vec2 res = HMM_RotateV2(v2, HMM_AngleDeg(360));
|
||||||
|
EXPECT_NEAR(res.X, 1.0f, epsilon);
|
||||||
|
EXPECT_NEAR(res.Y, 2.0f, epsilon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ TEST(VectorOps, LengthSquared)
|
|||||||
EXPECT_FLOAT_EQ(HMM_LenSqrV3(v3), 14.0f);
|
EXPECT_FLOAT_EQ(HMM_LenSqrV3(v3), 14.0f);
|
||||||
EXPECT_FLOAT_EQ(HMM_LenSqrV4(v4), 15.0f);
|
EXPECT_FLOAT_EQ(HMM_LenSqrV4(v4), 15.0f);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
EXPECT_FLOAT_EQ(HMM_LenSqr(v2), 5.0f);
|
EXPECT_FLOAT_EQ(HMM_LenSqr(v2), 5.0f);
|
||||||
EXPECT_FLOAT_EQ(HMM_LenSqr(v3), 14.0f);
|
EXPECT_FLOAT_EQ(HMM_LenSqr(v3), 14.0f);
|
||||||
EXPECT_FLOAT_EQ(HMM_LenSqr(v4), 15.0f);
|
EXPECT_FLOAT_EQ(HMM_LenSqr(v4), 15.0f);
|
||||||
@@ -27,7 +27,7 @@ TEST(VectorOps, Length)
|
|||||||
EXPECT_FLOAT_EQ(HMM_LenV3(v3), 7.0f);
|
EXPECT_FLOAT_EQ(HMM_LenV3(v3), 7.0f);
|
||||||
EXPECT_FLOAT_EQ(HMM_LenV4(v4), 13.892444f);
|
EXPECT_FLOAT_EQ(HMM_LenV4(v4), 13.892444f);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
EXPECT_FLOAT_EQ(HMM_Len(v2), 9.0553856f);
|
EXPECT_FLOAT_EQ(HMM_Len(v2), 9.0553856f);
|
||||||
EXPECT_FLOAT_EQ(HMM_Len(v3), 7.0f);
|
EXPECT_FLOAT_EQ(HMM_Len(v3), 7.0f);
|
||||||
EXPECT_FLOAT_EQ(HMM_Len(v4), 13.892444f);
|
EXPECT_FLOAT_EQ(HMM_Len(v4), 13.892444f);
|
||||||
@@ -62,7 +62,7 @@ TEST(VectorOps, Normalize)
|
|||||||
EXPECT_LT(result.W, 0.0f);
|
EXPECT_LT(result.W, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = HMM_Norm(v2);
|
HMM_Vec2 result = HMM_Norm(v2);
|
||||||
EXPECT_NEAR(HMM_LenV2(result), 1.0f, 0.001f);
|
EXPECT_NEAR(HMM_LenV2(result), 1.0f, 0.001f);
|
||||||
@@ -112,7 +112,7 @@ TEST(VectorOps, NormalizeZero)
|
|||||||
EXPECT_FLOAT_EQ(result.W, 0.0f);
|
EXPECT_FLOAT_EQ(result.W, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = HMM_Norm(v2);
|
HMM_Vec2 result = HMM_Norm(v2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.0f);
|
EXPECT_FLOAT_EQ(result.X, 0.0f);
|
||||||
@@ -152,7 +152,7 @@ TEST(VectorOps, DotVec2)
|
|||||||
HMM_Vec2 v2 = HMM_V2(3.0f, 4.0f);
|
HMM_Vec2 v2 = HMM_V2(3.0f, 4.0f);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(HMM_DotV2(v1, v2), 11.0f);
|
EXPECT_FLOAT_EQ(HMM_DotV2(v1, v2), 11.0f);
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 11.0f);
|
EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 11.0f);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,7 @@ TEST(VectorOps, DotVec3)
|
|||||||
HMM_Vec3 v2 = HMM_V3(4.0f, 5.0f, 6.0f);
|
HMM_Vec3 v2 = HMM_V3(4.0f, 5.0f, 6.0f);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(HMM_DotV3(v1, v2), 32.0f);
|
EXPECT_FLOAT_EQ(HMM_DotV3(v1, v2), 32.0f);
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 32.0f);
|
EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 32.0f);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -174,7 +174,7 @@ TEST(VectorOps, DotVec4)
|
|||||||
HMM_Vec4 v2 = HMM_V4(5.0f, 6.0f, 7.0f, 8.0f);
|
HMM_Vec4 v2 = HMM_V4(5.0f, 6.0f, 7.0f, 8.0f);
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(HMM_DotV4(v1, v2), 70.0f);
|
EXPECT_FLOAT_EQ(HMM_DotV4(v1, v2), 70.0f);
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 70.0f);
|
EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 70.0f);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ TEST(VectorOps, LerpV2)
|
|||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
EXPECT_FLOAT_EQ(result.Y, 0.5f);
|
EXPECT_FLOAT_EQ(result.Y, 0.5f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec2 result = HMM_Lerp(v1, 0.5, v2);
|
HMM_Vec2 result = HMM_Lerp(v1, 0.5, v2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
@@ -209,7 +209,7 @@ TEST(VectorOps, LerpV3)
|
|||||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||||
EXPECT_FLOAT_EQ(result.Z, 0.5f);
|
EXPECT_FLOAT_EQ(result.Z, 0.5f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec3 result = HMM_Lerp(v1, 0.5, v2);
|
HMM_Vec3 result = HMM_Lerp(v1, 0.5, v2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
@@ -231,7 +231,7 @@ TEST(VectorOps, LerpV4)
|
|||||||
EXPECT_FLOAT_EQ(result.Z, 0.5f);
|
EXPECT_FLOAT_EQ(result.Z, 0.5f);
|
||||||
EXPECT_FLOAT_EQ(result.W, 1.0f);
|
EXPECT_FLOAT_EQ(result.W, 1.0f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#if HANDMADE_MATH__USE_C11_GENERICS || defined(__cplusplus)
|
||||||
{
|
{
|
||||||
HMM_Vec4 result = HMM_Lerp(v1, 0.5, v2);
|
HMM_Vec4 result = HMM_Lerp(v1, 0.5, v2);
|
||||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||||
|
|||||||
@@ -3,16 +3,25 @@
|
|||||||
if not exist "build" mkdir build
|
if not exist "build" mkdir build
|
||||||
pushd build
|
pushd build
|
||||||
|
|
||||||
clang-cl /Fehmm_test_c.exe ..\HandmadeMath.c ..\hmm_test.c
|
clang-cl /std:c11 /Fehmm_test_c11.exe ..\HandmadeMath.c ..\hmm_test.c || exit /b 1
|
||||||
hmm_test_c
|
hmm_test_c11 || exit /b 1
|
||||||
|
|
||||||
clang-cl /Fehmm_test_c_no_sse.exe /DHANDMADE_MATH_NO_SSE ..\HandmadeMath.c ..\hmm_test.c
|
clang-cl /std:c11 /Fehmm_test_c11_no_simd.exe /DHANDMADE_MATH_NO_SIMD ..\HandmadeMath.c ..\hmm_test.c || exit /b 1
|
||||||
hmm_test_c_no_sse
|
hmm_test_c11_no_simd || exit /b 1
|
||||||
|
|
||||||
clang-cl /Fehmm_test_cpp.exe ..\HandmadeMath.cpp ..\hmm_test.cpp
|
clang-cl /std:c17 /Fehmm_test_c17.exe ..\HandmadeMath.c ..\hmm_test.c || exit /b 1
|
||||||
hmm_test_cpp
|
hmm_test_c17 || exit /b 1
|
||||||
|
|
||||||
clang-cl /Fehmm_test_cpp_no_sse.exe /DHANDMADE_MATH_NO_SSE ..\HandmadeMath.cpp ..\hmm_test.cpp
|
clang-cl /std:c++14 /Fehmm_test_cpp14.exe ..\HandmadeMath.cpp ..\hmm_test.cpp || exit /b 1
|
||||||
hmm_test_cpp_no_sse
|
hmm_test_cpp14 || exit /b 1
|
||||||
|
|
||||||
|
clang-cl /std:c++14 /Fehmm_test_cpp14_no_simd.exe /DHANDMADE_MATH_NO_SIMD ..\HandmadeMath.cpp ..\hmm_test.cpp || exit /b 1
|
||||||
|
hmm_test_cpp14_no_simd || exit /b 1
|
||||||
|
|
||||||
|
clang-cl /std:c++17 /Fehmm_test_cpp17.exe ..\HandmadeMath.cpp ..\hmm_test.cpp || exit /b 1
|
||||||
|
hmm_test_cpp17 || exit /b 1
|
||||||
|
|
||||||
|
clang-cl /std:c++20 /Fehmm_test_cpp20.exe ..\HandmadeMath.cpp ..\hmm_test.cpp || exit /b 1
|
||||||
|
hmm_test_cpp20 || exit /b 1
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|||||||
@@ -1,27 +1,32 @@
|
|||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
if "%1%"=="travis" (
|
where /q cl
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat" -host_arch=amd64 -arch=amd64
|
if ERRORLEVEL 1 (
|
||||||
) else (
|
for /f "delims=" %%a in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -find VC\Auxiliary\Build\vcvarsall.bat') do (%%a x64)
|
||||||
where /q cl
|
|
||||||
if ERRORLEVEL 1 (
|
|
||||||
for /f "delims=" %%a in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -find VC\Auxiliary\Build\vcvarsall.bat') do (%%a x64)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if not exist "build" mkdir build
|
if not exist "build" mkdir build
|
||||||
pushd build
|
pushd build
|
||||||
|
|
||||||
cl /Fehmm_test_c.exe ..\HandmadeMath.c ..\hmm_test.c
|
cl /std:c11 /Fehmm_test_c11.exe ..\HandmadeMath.c ..\hmm_test.c || exit /b 1
|
||||||
hmm_test_c
|
hmm_test_c11 || exit /b 1
|
||||||
|
|
||||||
cl /Fehmm_test_c_no_sse.exe /DHANDMADE_MATH_NO_SSE ..\HandmadeMath.c ..\hmm_test.c
|
cl /std:c11 /Fehmm_test_c11_no_simd.exe /DHANDMADE_MATH_NO_SIMD ..\HandmadeMath.c ..\hmm_test.c || exit /b 1
|
||||||
hmm_test_c_no_sse
|
hmm_test_c11_no_simd || exit /b 1
|
||||||
|
|
||||||
cl /Fehmm_test_cpp.exe ..\HandmadeMath.cpp ..\hmm_test.cpp
|
cl /std:c17 /Fehmm_test_c17.exe ..\HandmadeMath.c ..\hmm_test.c || exit /b 1
|
||||||
hmm_test_cpp
|
hmm_test_c17 || exit /b 1
|
||||||
|
|
||||||
cl /Fehmm_test_cpp_no_sse.exe /DHANDMADE_MATH_NO_SSE ..\HandmadeMath.cpp ..\hmm_test.cpp
|
cl /std:c++14 /Fehmm_test_cpp14.exe ..\HandmadeMath.cpp ..\hmm_test.cpp || exit /b 1
|
||||||
hmm_test_cpp_no_sse
|
hmm_test_cpp14 || exit /b 1
|
||||||
|
|
||||||
|
cl /std:c++14 /Fehmm_test_cpp14_no_simd.exe /DHANDMADE_MATH_NO_SIMD ..\HandmadeMath.cpp ..\hmm_test.cpp || exit /b 1
|
||||||
|
hmm_test_cpp14_no_simd || exit /b 1
|
||||||
|
|
||||||
|
cl /std:c++17 /Fehmm_test_cpp17.exe ..\HandmadeMath.cpp ..\hmm_test.cpp || exit /b 1
|
||||||
|
hmm_test_cpp17 || exit /b 1
|
||||||
|
|
||||||
|
cl /std:c++20 /Fehmm_test_cpp20.exe ..\HandmadeMath.cpp ..\hmm_test.cpp || exit /b 1
|
||||||
|
hmm_test_cpp20 || exit /b 1
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|||||||
@@ -1,36 +1,24 @@
|
|||||||
# Handmade Math 2.0 Update Tool
|
# Handmade Math 2.0 Update Tool
|
||||||
|
|
||||||
Due to the large number of breaking naming changes in Handmade Math 2, we provide a small tool to update your programs automatically. It's a C program that takes a list of files and updates their text, along with some scripts to recursively run the program on all code in a directory.
|
Due to the large number of breaking naming changes in Handmade Math 2, we provide a small Python script to update your programs automatically. It can run on individual files or on all files in a directory (recursively).
|
||||||
|
|
||||||
You can compile the tool yourself with any C/C++ compiler:
|
**Warning!** This tool is not very smart! Please ensure that your work is committed and backed up, in case you have to revert this tool's changes.
|
||||||
|
|
||||||
```bash
|
|
||||||
# MSVC (Windows)
|
|
||||||
cl update_hmm.c
|
|
||||||
|
|
||||||
# gcc
|
|
||||||
gcc update_hmm.c -o update_hmm
|
|
||||||
|
|
||||||
# clang
|
|
||||||
clang update_hmm.c -o update_hmm
|
|
||||||
```
|
```
|
||||||
|
# see usage info and options
|
||||||
|
> python3 update_hmm.py -h
|
||||||
|
usage: update_hmm [-h] [--exts .foo [.foo ...]] filename [filename ...]
|
||||||
|
...
|
||||||
|
|
||||||
Once built, the tool can be run on any C or C++ files:
|
# run on individual files
|
||||||
|
> python3 update_hmm.py MyPlatformLayer.c MyPlatformLayer.h
|
||||||
|
Updating: MyPlatformLayer.c
|
||||||
|
Updating: MyPlatformLayer.h
|
||||||
|
Updated 2 files with 0 warnings.
|
||||||
|
|
||||||
```bash
|
# run on a whole directory
|
||||||
# Windows
|
> python3 update_hmm.py projects/MyCoolGame
|
||||||
update_hmm.exe MyGame.cpp MyPlatformLayer.cpp
|
Updating: projects/MyCoolGame/src/MyPlatformLayer.c
|
||||||
|
Updating: projects/MyCoolGame/include/MyPlatformLayer.h
|
||||||
# Other platforms
|
...
|
||||||
update_hmm MyGame.cpp MyPlatformLayer.cpp
|
|
||||||
```
|
|
||||||
|
|
||||||
Or, update all C/C++ files in a directory by running one of the provided shell scripts:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Windows
|
|
||||||
update_hmm_all.bat "path\to\project"
|
|
||||||
|
|
||||||
# Other platforms
|
|
||||||
update_hmm_all.sh path/to/project
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,562 +0,0 @@
|
|||||||
/* Compile:
|
|
||||||
Windows (MSVC): cl update_hmm.c
|
|
||||||
Linux (GCC): gcc update_hmm.c -o update_hmm
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** LCF stuff **/
|
|
||||||
/* I used my personally library when writing this so I am dumping the necessary things here
|
|
||||||
so that it's all in one file. */
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
/* Types */
|
|
||||||
#define global static
|
|
||||||
#define internal static
|
|
||||||
typedef int32_t s32; global s32 s32_MAX = 0x7FFFFFFF; global s32 s32_MIN = -1 - 0x7FFFFFFF;
|
|
||||||
typedef int64_t s64; global s64 s64_MAX = 0x7FFFFFFFFFFFFFFF; global s64 s64_MIN = -1 - 0x7FFFFFFFFFFFFFFF;
|
|
||||||
typedef uint32_t u32; global u32 u32_MAX = 0xFFFFFFFF; global u32 u32_MIN = 0;
|
|
||||||
typedef uint64_t u64; global u64 u64_MAX = 0xFFFFFFFFFFFFFFFF; global u64 u64_MIN = 0;
|
|
||||||
typedef u32 b32;
|
|
||||||
typedef u64 b64;
|
|
||||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
|
||||||
#define CLAMPTOP(a,b) MIN(a,b)
|
|
||||||
|
|
||||||
/* Memory */
|
|
||||||
struct lcf_Arena {
|
|
||||||
u64 pos;
|
|
||||||
u64 size;
|
|
||||||
u64 alignment;
|
|
||||||
u64 commited_pos;
|
|
||||||
};
|
|
||||||
typedef struct lcf_Arena Arena;
|
|
||||||
#define KB(x) ((x) << 10)
|
|
||||||
#define GB(x) ((x) << 30)
|
|
||||||
Arena* Arena_create(u64 size);
|
|
||||||
void* Arena_take(Arena *a, u64 size);
|
|
||||||
void* Arena_take_custom(Arena *a, u64 size, u64 alignment);
|
|
||||||
#define Arena_take_array(a, type, count) ((type*) Arena_take(a, sizeof(type)*count))
|
|
||||||
void Arena_reset_all(Arena *a);
|
|
||||||
|
|
||||||
#define LCF_MEMORY_PROVIDE_MEMORY "stdlib"
|
|
||||||
#define LCF_MEMORY_RESERVE_MEMORY(name) void* name(u64 size)
|
|
||||||
#define LCF_MEMORY_COMMIT_MEMORY(name) b32 name(void* memory, u64 size)
|
|
||||||
#define LCF_MEMORY_DECOMMIT_MEMORY(name) void name(void* memory, u64 size)
|
|
||||||
#define LCF_MEMORY_FREE_MEMORY(name) void name(void* memory, u64 size)
|
|
||||||
/* This implementation of an arena doesn't take advantage of virtual memory at all.
|
|
||||||
It's just convenient to have something portable so I can use the Arena API I'm used to. */
|
|
||||||
internal LCF_MEMORY_RESERVE_MEMORY(_lcf_memory_default_reserve) {
|
|
||||||
return malloc(size);
|
|
||||||
}
|
|
||||||
internal LCF_MEMORY_COMMIT_MEMORY(_lcf_memory_default_commit) {
|
|
||||||
(void) size, memory;
|
|
||||||
return 1; /* malloc commits memory automatically */
|
|
||||||
}
|
|
||||||
internal LCF_MEMORY_DECOMMIT_MEMORY(_lcf_memory_default_decommit) {
|
|
||||||
(void) size, memory;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
internal LCF_MEMORY_FREE_MEMORY(_lcf_memory_default_free) {
|
|
||||||
(void) size;
|
|
||||||
free(memory);
|
|
||||||
}
|
|
||||||
#define LCF_MEMORY_reserve _lcf_memory_default_reserve
|
|
||||||
#define LCF_MEMORY_commit _lcf_memory_default_commit
|
|
||||||
#define LCF_MEMORY_decommit _lcf_memory_default_decommit
|
|
||||||
#define LCF_MEMORY_free _lcf_memory_default_free
|
|
||||||
#define LCF_MEMORY_RESERVE_SIZE GB(1)
|
|
||||||
#define LCF_MEMORY_COMMIT_SIZE KB(4)
|
|
||||||
#define LCF_MEMORY_ALIGNMENT (sizeof(void*))
|
|
||||||
|
|
||||||
Arena* Arena_create(u64 size) {
|
|
||||||
Arena* a = (Arena*) LCF_MEMORY_reserve(size);
|
|
||||||
LCF_MEMORY_commit(a, LCF_MEMORY_COMMIT_SIZE);
|
|
||||||
a->size = size;
|
|
||||||
a->pos = sizeof(Arena);
|
|
||||||
a->commited_pos = LCF_MEMORY_COMMIT_SIZE;
|
|
||||||
a->alignment = LCF_MEMORY_ALIGNMENT;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
#define B_PTR(p) (u8*)(p)
|
|
||||||
|
|
||||||
internal b32 is_power_of_2(u64 x) {
|
|
||||||
return ((x & (x-1)) == 0);
|
|
||||||
}
|
|
||||||
internal u64 next_alignment(u64 ptr, u64 alignment) {
|
|
||||||
/* Fast replacement for mod because alignment is power of 2 */
|
|
||||||
u64 modulo = ptr & (alignment-1);
|
|
||||||
|
|
||||||
if (modulo != 0) {
|
|
||||||
ptr += alignment - modulo;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
void* Arena_take_custom(Arena *a, u64 size, u64 alignment) {
|
|
||||||
void* result = 0;
|
|
||||||
|
|
||||||
/* Align pos pointer to check if "size" can fit */
|
|
||||||
u64 mem = (u64) a;
|
|
||||||
u64 aligned_pos = next_alignment(mem + a->pos, alignment) - mem;
|
|
||||||
u64 new_pos = aligned_pos + size;
|
|
||||||
|
|
||||||
/* Check that there is space */
|
|
||||||
if (new_pos < a->size) {
|
|
||||||
u64 commited_pos = a->commited_pos;
|
|
||||||
|
|
||||||
/* Commit memory if needed */
|
|
||||||
if (new_pos > commited_pos) {
|
|
||||||
u64 new_commited_pos = next_alignment(mem + new_pos, LCF_MEMORY_COMMIT_SIZE)-mem;
|
|
||||||
if (LCF_MEMORY_commit(a, new_commited_pos)) {
|
|
||||||
a->commited_pos = commited_pos = new_commited_pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If enough memory is commited, set result and pos. */
|
|
||||||
if (new_pos <= commited_pos) {
|
|
||||||
result = (void*)(mem + aligned_pos);
|
|
||||||
a->pos = new_pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
void* Arena_take(Arena *a, u64 size) {
|
|
||||||
return Arena_take_custom(a, size, LCF_MEMORY_ALIGNMENT);
|
|
||||||
}
|
|
||||||
void Arena_reset_all(Arena *a) {
|
|
||||||
a->pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* String */
|
|
||||||
typedef char chr8;
|
|
||||||
struct str8 {
|
|
||||||
u64 len;
|
|
||||||
chr8 *str;
|
|
||||||
};
|
|
||||||
typedef struct str8 str8;
|
|
||||||
#define str8_PRINTF_ARGS(s) (int)(s).len, (s).str
|
|
||||||
#define str8_lit(s) str8_from((chr8*)(s),(u64)sizeof(s)-1) /* -1 to exclude null character */
|
|
||||||
#define str8_is_empty(s) ((b32)((s).len == 0))
|
|
||||||
#define LCF_STRING_NO_MATCH 0x8000000000000000
|
|
||||||
#define str8_iter_custom(s, i, c) \
|
|
||||||
s64 i = 0; \
|
|
||||||
chr8 c = s.str[i]; \
|
|
||||||
for (; (i < (s64) s.len); i++, c = s.str[i])
|
|
||||||
|
|
||||||
#define str8_iter(s) str8_iter_custom(s, i, c)
|
|
||||||
|
|
||||||
str8 str8_from(chr8* s, u64 len);
|
|
||||||
str8 str8_from_cstring(chr8 *cstr);
|
|
||||||
str8 str8_first(str8 s, u64 len);
|
|
||||||
str8 str8_skip(str8 s, u64 len);
|
|
||||||
b32 chr8_is_whitespace(chr8 c);
|
|
||||||
b32 str8_contains_char(str8 s, chr8 c);
|
|
||||||
u64 str8_char_location(str8 s, chr8 c);
|
|
||||||
|
|
||||||
#define RET_STR8(s,l) \
|
|
||||||
str8 _str8; \
|
|
||||||
_str8.str = (s); \
|
|
||||||
_str8.len = (l); \
|
|
||||||
return _str8
|
|
||||||
str8 str8_from(chr8* s, u64 len) {
|
|
||||||
RET_STR8(s, len);
|
|
||||||
}
|
|
||||||
str8 str8_from_cstring(chr8 *cstr) {
|
|
||||||
chr8* p2 = cstr;
|
|
||||||
while(*p2 != 0)
|
|
||||||
p2++;
|
|
||||||
RET_STR8(cstr, (u64)(p2 - cstr));
|
|
||||||
}
|
|
||||||
str8 str8_first(str8 s, u64 len) {
|
|
||||||
u64 len_clamped = CLAMPTOP(len, s.len);
|
|
||||||
RET_STR8(s.str, len_clamped);
|
|
||||||
}
|
|
||||||
str8 str8_skip(str8 s, u64 len) {
|
|
||||||
u64 len_clamped = CLAMPTOP(len, s.len);
|
|
||||||
RET_STR8(s.str + len_clamped, s.len - len_clamped);
|
|
||||||
}
|
|
||||||
b32 chr8_is_whitespace(chr8 c) {
|
|
||||||
switch (c) {
|
|
||||||
case ' ':
|
|
||||||
case '\n':
|
|
||||||
case '\t':
|
|
||||||
case '\r':
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b32 str8_contains_char(str8 s, chr8 find) {
|
|
||||||
return str8_char_location(s,find) != LCF_STRING_NO_MATCH;
|
|
||||||
}
|
|
||||||
u64 str8_char_location(str8 s, chr8 find) {
|
|
||||||
str8_iter(s) {
|
|
||||||
if (c == find) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return LCF_STRING_NO_MATCH;
|
|
||||||
}
|
|
||||||
#undef RET_STR8
|
|
||||||
|
|
||||||
struct Str8Node {
|
|
||||||
struct Str8Node *next;
|
|
||||||
struct str8 str;
|
|
||||||
};
|
|
||||||
struct Str8List {
|
|
||||||
struct Str8Node *first;
|
|
||||||
struct Str8Node *last;
|
|
||||||
u64 count;
|
|
||||||
u64 total_len;
|
|
||||||
};
|
|
||||||
typedef struct Str8Node Str8Node;
|
|
||||||
typedef struct Str8List Str8List;
|
|
||||||
|
|
||||||
void Str8List_add_node(Str8List *list, Str8Node *n);
|
|
||||||
void Str8List_add(Arena *arena, Str8List *list, str8 str);
|
|
||||||
void Str8List_add_node(Str8List *list, Str8Node *n) {
|
|
||||||
if (list->last) {
|
|
||||||
list->last->next = n;
|
|
||||||
} else {
|
|
||||||
list->first = n;
|
|
||||||
}
|
|
||||||
list->last = n;
|
|
||||||
list->count++;
|
|
||||||
list->total_len += n->str.len;
|
|
||||||
}
|
|
||||||
void Str8List_add(Arena *arena, Str8List *list, str8 str) {
|
|
||||||
Str8Node *n = Arena_take_array(arena, Str8Node, 1);
|
|
||||||
n->str = str;
|
|
||||||
n->next = 0;
|
|
||||||
Str8List_add_node(list, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CRT - stdio */
|
|
||||||
str8 stdio_load_entire_file(Arena *arena, str8 filepath);
|
|
||||||
b32 stdio_write_file(str8 filepath, Str8List text);
|
|
||||||
|
|
||||||
str8 stdio_load_entire_file(Arena *arena, str8 filepath) {
|
|
||||||
str8 file_content = {0};
|
|
||||||
|
|
||||||
FILE *file = fopen(filepath.str, "rb");
|
|
||||||
if (file != 0) {
|
|
||||||
fseek(file, 0, SEEK_END);
|
|
||||||
u64 file_len = ftell(file);
|
|
||||||
fseek(file, 0, SEEK_SET);
|
|
||||||
file_content.str = (chr8*) Arena_take(arena, file_len+1);
|
|
||||||
if (file_content.str != 0) {
|
|
||||||
file_content.len = file_len;
|
|
||||||
fread(file_content.str, 1, file_len, file);
|
|
||||||
file_content.str[file_content.len] = 0;
|
|
||||||
}
|
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
return file_content;
|
|
||||||
}
|
|
||||||
b32 stdio_write_file(str8 filepath, Str8List text) {
|
|
||||||
u64 bytes_written = 0;
|
|
||||||
FILE *file = fopen(filepath.str, "wb");
|
|
||||||
if (file != 0) {
|
|
||||||
Str8Node* n = text.first;
|
|
||||||
for (s64 i = 0; i < text.count; i++, n = n->next) {
|
|
||||||
if (!fwrite(n->str.str, n->str.len, 1, file)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bytes_written += n->str.len;
|
|
||||||
}
|
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
return bytes_written == text.total_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** HMM2.0 Update Tool **/
|
|
||||||
enum Targets {
|
|
||||||
/* hmm_ and HMM_ prefixes */
|
|
||||||
PREFIX_TYPE, PREFIX_FUNCTION,
|
|
||||||
PREFIXES_Size,
|
|
||||||
/* Struct/Union types */
|
|
||||||
TYPE_VEC, TYPE_MAT, TYPE_QUATERNION, TYPE_BOOL,
|
|
||||||
TYPE_INTERNAL_ELEMENTS_SSE,
|
|
||||||
TYPES_Size,
|
|
||||||
/* Types in Function Names */
|
|
||||||
FUN_VEC, FUN_MAT, FUN_QUATERNION,
|
|
||||||
/* Function Names for Common Operations */
|
|
||||||
FUN_EQUALS, FUN_SUBTRACT, FUN_MULTIPLY, FUN_DIVIDE,
|
|
||||||
FUN_INVERSE, FUN_R_SQUARE_ROOT, FUN_SQUARE_ROOT,
|
|
||||||
FUN_LENGTH_SQUARED, FUN_LENGTH, FUN_FAST_NORM, FUN_NORM,
|
|
||||||
FUN_SLERP, FUN_BY,
|
|
||||||
FUN_LINEAR_COMBINE_SSE, FUN_TRANSPOSE,
|
|
||||||
FUNCTIONS_Size,
|
|
||||||
/* Handedness */
|
|
||||||
HAND_PERSPECTIVE, HAND_ROTATE,
|
|
||||||
HAND_ORTHO, HAND_LOOK_AT, HAND_QUAT_AXIS_ANGLE, HAND_MAT_TO_QUAT,
|
|
||||||
HAND_Size,
|
|
||||||
};
|
|
||||||
|
|
||||||
Str8List update_file_content(Arena* arena, str8 file_content) {
|
|
||||||
Str8List out = {0};
|
|
||||||
|
|
||||||
str8 Find[HAND_Size];
|
|
||||||
str8 Repl[HAND_Size];
|
|
||||||
{ /* NOTE: Initialization */
|
|
||||||
Find[PREFIX_TYPE] = str8_lit("hmm_");
|
|
||||||
Find[PREFIX_FUNCTION] = str8_lit("HMM_");
|
|
||||||
Repl[PREFIX_TYPE] = Find[PREFIX_FUNCTION];
|
|
||||||
|
|
||||||
Find[TYPE_VEC] = str8_lit("vec");
|
|
||||||
Repl[TYPE_VEC] = str8_lit("Vec");
|
|
||||||
Find[TYPE_MAT] = str8_lit("mat");
|
|
||||||
Repl[TYPE_MAT] = str8_lit("Mat");
|
|
||||||
Find[TYPE_QUATERNION] = str8_lit("quaternion");
|
|
||||||
Repl[TYPE_QUATERNION] = str8_lit("Quat");
|
|
||||||
Find[TYPE_BOOL] = str8_lit("bool");
|
|
||||||
Repl[TYPE_BOOL] = str8_lit("Bool");
|
|
||||||
Find[TYPE_INTERNAL_ELEMENTS_SSE] = str8_lit(".InternalElementsSSE");
|
|
||||||
Repl[TYPE_INTERNAL_ELEMENTS_SSE] = str8_lit(".SSE");
|
|
||||||
|
|
||||||
Find[FUN_VEC] = str8_lit("Vec");
|
|
||||||
Repl[FUN_VEC] = str8_lit("V");
|
|
||||||
Find[FUN_MAT] = str8_lit("Mat");
|
|
||||||
Repl[FUN_MAT] = str8_lit("M");
|
|
||||||
Find[FUN_QUATERNION] = str8_lit("Quaternion");
|
|
||||||
Repl[FUN_QUATERNION] = str8_lit("Q");
|
|
||||||
Find[FUN_EQUALS] = str8_lit("Equals");
|
|
||||||
Repl[FUN_EQUALS] = str8_lit("Eq");
|
|
||||||
Find[FUN_SUBTRACT] = str8_lit("Subtract");
|
|
||||||
Repl[FUN_SUBTRACT] = str8_lit("Sub");
|
|
||||||
Find[FUN_MULTIPLY] = str8_lit("Multiply");
|
|
||||||
Repl[FUN_MULTIPLY] = str8_lit("Mul");
|
|
||||||
Find[FUN_DIVIDE] = str8_lit("Divide");
|
|
||||||
Repl[FUN_DIVIDE] = str8_lit("Div");
|
|
||||||
Find[FUN_INVERSE] = str8_lit("Inverse");
|
|
||||||
Repl[FUN_INVERSE] = str8_lit("Inv");
|
|
||||||
Find[FUN_R_SQUARE_ROOT] = str8_lit("RSquareRoot");
|
|
||||||
Repl[FUN_R_SQUARE_ROOT] = str8_lit("InvSqrt");
|
|
||||||
Find[FUN_SQUARE_ROOT] = str8_lit("SquareRoot");
|
|
||||||
Repl[FUN_SQUARE_ROOT] = str8_lit("Sqrt");
|
|
||||||
Find[FUN_LENGTH_SQUARED] = str8_lit("Squared");
|
|
||||||
Repl[FUN_LENGTH_SQUARED] = str8_lit("Sqr"); /* FIXME: not working for some reason */
|
|
||||||
Find[FUN_LENGTH] = str8_lit("Length");
|
|
||||||
Repl[FUN_LENGTH] = str8_lit("Len");
|
|
||||||
|
|
||||||
Find[FUN_SLERP] = str8_lit("Slerp");
|
|
||||||
Repl[FUN_SLERP] = str8_lit("SLerp");
|
|
||||||
Find[FUN_BY] = str8_lit("By");
|
|
||||||
Repl[FUN_BY] = str8_lit("");
|
|
||||||
Find[FUN_LINEAR_COMBINE_SSE] = str8_lit("LinearCombineSSE"); /* TODO: emit warning */
|
|
||||||
Repl[FUN_LINEAR_COMBINE_SSE] = str8_lit("LinearCombineV4M4");
|
|
||||||
Find[FUN_TRANSPOSE] = str8_lit("Transpose");
|
|
||||||
Repl[FUN_TRANSPOSE] = str8_lit("TransposeM4");
|
|
||||||
Find[FUN_FAST_NORM] = str8_lit("Fast"); /* TODO: emit warning, lower precision. */
|
|
||||||
Repl[FUN_FAST_NORM] = str8_lit("");
|
|
||||||
Find[FUN_NORM] = str8_lit("Normalize");
|
|
||||||
Repl[FUN_NORM] = str8_lit("Norm");
|
|
||||||
|
|
||||||
Find[HAND_PERSPECTIVE] = str8_lit("Perspective");
|
|
||||||
Find[HAND_ROTATE] = str8_lit("Rotate");
|
|
||||||
Find[HAND_ORTHO] = str8_lit("Orthographic");
|
|
||||||
Find[HAND_LOOK_AT] = str8_lit("LookAt");
|
|
||||||
Find[HAND_QUAT_AXIS_ANGLE] = str8_lit("FromAxisAngle");
|
|
||||||
Find[HAND_MAT_TO_QUAT] = str8_lit("ToQuaternion");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Match with a bunch of sliding windows, skipping when there can't be a match */
|
|
||||||
u64 MatchProgress[HAND_Size] = {0};
|
|
||||||
b32 FoundTypePrefix = 0;
|
|
||||||
b32 FoundFunctionPrefix = 0;
|
|
||||||
u32 Line = 1;
|
|
||||||
str8_iter(file_content) {
|
|
||||||
if (c == '\n') {
|
|
||||||
Line++;
|
|
||||||
}
|
|
||||||
if (FoundTypePrefix || FoundFunctionPrefix) {
|
|
||||||
if (chr8_is_whitespace(c)
|
|
||||||
|| str8_contains_char(str8_lit("(){}[]:;,.<>~?!@#$%^&+-*/'\""), c)) {
|
|
||||||
FoundTypePrefix = 0;
|
|
||||||
FoundFunctionPrefix = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (u32 t = 0; t < PREFIXES_Size; t++) {
|
|
||||||
if (c == Find[t].str[MatchProgress[t]]) {
|
|
||||||
MatchProgress[t]++;
|
|
||||||
if (MatchProgress[t] == Find[t].len) {
|
|
||||||
if (t == PREFIX_TYPE) {
|
|
||||||
FoundTypePrefix = 1;
|
|
||||||
} else if (t == PREFIX_FUNCTION) {
|
|
||||||
FoundFunctionPrefix = 1;
|
|
||||||
}
|
|
||||||
MatchProgress[t] = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
MatchProgress[t] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Replace hmm_ types */
|
|
||||||
if (FoundTypePrefix) {
|
|
||||||
for (u32 t = PREFIXES_Size+1; t < TYPES_Size; t++) {
|
|
||||||
if (c == Find[t].str[MatchProgress[t]]) {
|
|
||||||
MatchProgress[t]++;
|
|
||||||
if (MatchProgress[t] == Find[t].len) {
|
|
||||||
MatchProgress[t] = 0;
|
|
||||||
printf("\t[%u]: Find: %.*s, Repl: %.*s.\n", Line, str8_PRINTF_ARGS(Find[t]), str8_PRINTF_ARGS(Repl[t]));
|
|
||||||
Str8List_add(arena, &out,
|
|
||||||
str8_first(file_content,
|
|
||||||
i + 1 - (Find[t].len + Find[PREFIX_TYPE].len)));
|
|
||||||
Str8List_add(arena, &out, Repl[PREFIX_TYPE]);
|
|
||||||
Str8List_add(arena, &out, Repl[t]);
|
|
||||||
file_content = str8_skip(file_content, i+1);
|
|
||||||
i = -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
MatchProgress[t] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If in a HMM_ function, do function name replacements */
|
|
||||||
if (FoundFunctionPrefix) {
|
|
||||||
for (u32 t = TYPES_Size+1; t < FUNCTIONS_Size; t++) {
|
|
||||||
if (c == Find[t].str[MatchProgress[t]]) {
|
|
||||||
MatchProgress[t]++;
|
|
||||||
if (MatchProgress[t] == Find[t].len) {
|
|
||||||
MatchProgress[t] = 0;
|
|
||||||
printf("\t[%u]: Find: %.*s, Repl: %.*s.\n", Line, str8_PRINTF_ARGS(Find[t]), str8_PRINTF_ARGS(Repl[t]));
|
|
||||||
Str8List_add(arena, &out, str8_first(file_content, i + 1 - Find[t].len));
|
|
||||||
Str8List_add(arena, &out, Repl[t]);
|
|
||||||
file_content = str8_skip(file_content, i+1);
|
|
||||||
i = -1;
|
|
||||||
|
|
||||||
/* NOTE(lcf): Special case because Find[] overlaps here */
|
|
||||||
if (t == FUN_R_SQUARE_ROOT) {
|
|
||||||
MatchProgress[FUN_SQUARE_ROOT] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t == FUN_LINEAR_COMBINE_SSE) {
|
|
||||||
printf("\t[%u]: HMM_LinearCombineSSE is now HMM_LinearCombineV4M4, and will now use a fallback method when SSE is not available. \n\tYou no longer need to check for the availability of SSE.\n", Line);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t == FUN_VEC) {
|
|
||||||
/* NOTE(lcf): if pattern is Vec2i, this is now i */
|
|
||||||
c = file_content.str[1];
|
|
||||||
if (c == 'i') {
|
|
||||||
Str8List_add(arena, &out, str8_first(file_content, 1));
|
|
||||||
Str8List_add(arena, &out, str8_lit("I"));
|
|
||||||
file_content = str8_skip(file_content, 2);
|
|
||||||
} else if (c == 'v') {
|
|
||||||
Str8List_add(arena, &out, str8_first(file_content, 1));
|
|
||||||
Str8List_add(arena, &out, str8_lit("V"));
|
|
||||||
file_content = str8_skip(file_content, 2);
|
|
||||||
} else if (c == 'f') {
|
|
||||||
Str8List_add(arena, &out, str8_first(file_content, 1));
|
|
||||||
Str8List_add(arena, &out, str8_lit("F"));
|
|
||||||
file_content = str8_skip(file_content, 2);
|
|
||||||
}
|
|
||||||
} else if (t == FUN_MAT) {
|
|
||||||
/* if pattern is Mat4d, this is now d */
|
|
||||||
c = file_content.str[1];
|
|
||||||
if (c == 'd') {
|
|
||||||
Str8List_add(arena, &out, str8_first(file_content, 1));
|
|
||||||
Str8List_add(arena, &out, str8_lit("D"));
|
|
||||||
file_content = str8_skip(file_content, 2);
|
|
||||||
} else if (c == 'f') {
|
|
||||||
Str8List_add(arena, &out, str8_first(file_content, 1));
|
|
||||||
Str8List_add(arena, &out, str8_lit("F"));
|
|
||||||
file_content = str8_skip(file_content, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
MatchProgress[t] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handedness cases. */
|
|
||||||
if (FoundFunctionPrefix) {
|
|
||||||
for (u32 t = FUNCTIONS_Size+1; t < HAND_Size; t++) {
|
|
||||||
if (c == Find[t].str[MatchProgress[t]]) {
|
|
||||||
MatchProgress[t]++;
|
|
||||||
if (MatchProgress[t] == Find[t].len) {
|
|
||||||
MatchProgress[t] = 0;
|
|
||||||
|
|
||||||
chr8 check = file_content.str[i+1];
|
|
||||||
if (check == '(') {
|
|
||||||
printf("\t[%u]: Find: %.*s, Appending: _RH for old default handedness.\n", Line, str8_PRINTF_ARGS(Find[t]));
|
|
||||||
Str8List_add(arena, &out, str8_first(file_content, i + 1));
|
|
||||||
Str8List_add(arena, &out, str8_lit("_RH("));
|
|
||||||
file_content = str8_skip(file_content, i+2);
|
|
||||||
i = -1;
|
|
||||||
|
|
||||||
if (t == HAND_PERSPECTIVE || t == HAND_ROTATE) {
|
|
||||||
printf("\t[%u]: ", Line);
|
|
||||||
if (t == HAND_PERSPECTIVE) {
|
|
||||||
printf("HMM_Perspective_RH()");
|
|
||||||
} else {
|
|
||||||
printf("HMM_Rotate_RH()");
|
|
||||||
}
|
|
||||||
printf(" now takes Radians. Wrapping Degrees with HMM_AngleDeg()\n");
|
|
||||||
u64 end_arg = str8_char_location(file_content, ',');
|
|
||||||
if (end_arg != LCF_STRING_NO_MATCH) {
|
|
||||||
Str8List_add(arena, &out, str8_lit("HMM_AngleDeg("));
|
|
||||||
Str8List_add(arena, &out, str8_first(file_content, end_arg));
|
|
||||||
Str8List_add(arena, &out, str8_lit(")"));
|
|
||||||
file_content = str8_skip(file_content, end_arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
MatchProgress[t] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Str8List_add(arena, &out, file_content);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_usage() {
|
|
||||||
printf("Updates C and C++ source code to use Handmade Math version 2.\n");
|
|
||||||
#ifdef _WIN32
|
|
||||||
printf("Usage: update_hmm.exe <filename> [<filename>...]\n");
|
|
||||||
#else
|
|
||||||
printf("Usage: update_hmm <filename> [<filename>...]\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
Arena *tempa = Arena_create(GB(1));
|
|
||||||
|
|
||||||
if (argc == 1) {
|
|
||||||
print_usage();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 argi = 1;
|
|
||||||
str8 arg = str8_from_cstring(argv[argi]);
|
|
||||||
|
|
||||||
if (arg.len == 2 && (arg.str[1] == 'h' || arg.str[1] == '?')) {
|
|
||||||
print_usage();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; argi < argc; argi++) {
|
|
||||||
arg = str8_from_cstring(argv[argi]);
|
|
||||||
str8 file_content = stdio_load_entire_file(tempa, arg);
|
|
||||||
if (str8_is_empty(file_content)) {
|
|
||||||
printf("X - Invalid file name: %.*s\n\n", str8_PRINTF_ARGS(arg));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
printf("O - Updating file: %.*s -------------------\n", str8_PRINTF_ARGS(arg));
|
|
||||||
Str8List result = update_file_content(tempa, file_content);
|
|
||||||
printf("\n");
|
|
||||||
stdio_write_file(arg, result);
|
|
||||||
|
|
||||||
Arena_reset_all(tempa);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
166
update/update_hmm.py
Executable file
166
update/update_hmm.py
Executable file
@@ -0,0 +1,166 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
typeReplacements = [
|
||||||
|
('hmm_', 'HMM_'),
|
||||||
|
|
||||||
|
('vec', 'Vec'),
|
||||||
|
('mat', 'Mat'),
|
||||||
|
('quaternion', 'Quaternion'),
|
||||||
|
('bool', 'Bool'),
|
||||||
|
('.InternalElementsSSE', '.SSE'),
|
||||||
|
]
|
||||||
|
|
||||||
|
funcReplacements = [
|
||||||
|
('HMM_', 'HMM_'),
|
||||||
|
|
||||||
|
('Vec', 'V'),
|
||||||
|
('Mat', 'M'),
|
||||||
|
('Quaternion', 'Q'),
|
||||||
|
('Equals', 'Eq'),
|
||||||
|
('Subtract', 'Sub'),
|
||||||
|
('Multiply', 'Mul'),
|
||||||
|
('Divide', 'Div'),
|
||||||
|
('Inverse', 'Inv'),
|
||||||
|
('RSquareRoot', 'InvSqrt'),
|
||||||
|
('SquareRoot', 'Sqrt'),
|
||||||
|
('Squared', 'Sqr'),
|
||||||
|
('Length', 'Len'),
|
||||||
|
|
||||||
|
('Slerp', 'SLerp'),
|
||||||
|
('By', ''),
|
||||||
|
('LinearCombineSSE', 'LinearCombineV4M4'),
|
||||||
|
('Transpose', 'TransposeM4'),
|
||||||
|
('Fast', ''), # TODO(port): emit warning, lower precision
|
||||||
|
('Normalize', 'Norm'),
|
||||||
|
('ToRadians', 'ToRad')
|
||||||
|
]
|
||||||
|
|
||||||
|
handedFuncs = [
|
||||||
|
'Perspective',
|
||||||
|
'Rotate',
|
||||||
|
'Orthographic',
|
||||||
|
'LookAt',
|
||||||
|
'FromAxisAngle',
|
||||||
|
'ToQuaternion',
|
||||||
|
]
|
||||||
|
|
||||||
|
projectionFuncs = [
|
||||||
|
'Perspective',
|
||||||
|
'Orthographic',
|
||||||
|
]
|
||||||
|
|
||||||
|
numFiles = 0
|
||||||
|
numWarnings = 0
|
||||||
|
|
||||||
|
def printWarning(msg):
|
||||||
|
global numWarnings
|
||||||
|
numWarnings += 1
|
||||||
|
print('WARNING: {}'.format(msg))
|
||||||
|
|
||||||
|
def updateFile(filename):
|
||||||
|
global numFiles
|
||||||
|
print('Updating: {}'.format(filename))
|
||||||
|
numFiles += 1
|
||||||
|
result = ''
|
||||||
|
with open(filename, 'r', newline='') as f:
|
||||||
|
for lineNo, line in enumerate(f):
|
||||||
|
updatedLine = line
|
||||||
|
|
||||||
|
def printLineWarning(msg):
|
||||||
|
printWarning(' Line {}: {}'.format(lineNo + 1, msg))
|
||||||
|
|
||||||
|
def replaceName(m):
|
||||||
|
name = m.group()
|
||||||
|
if name.startswith('hmm_'):
|
||||||
|
# do type replacements
|
||||||
|
for before, after in typeReplacements:
|
||||||
|
if before not in name:
|
||||||
|
continue
|
||||||
|
name = name.replace(before, after)
|
||||||
|
else:
|
||||||
|
# do func replacements
|
||||||
|
for before, after in funcReplacements:
|
||||||
|
if before not in name:
|
||||||
|
continue
|
||||||
|
name = name.replace(before, after)
|
||||||
|
|
||||||
|
if after == 'LinearCombineV4M4':
|
||||||
|
printLineWarning('HMM_LinearCombineSSE is now HMM_LinearCombineV4M4, and will now use a fallback method when SSE is not available. You no longer need to check for the availability of SSE.')
|
||||||
|
if after == 'V' or after == 'M':
|
||||||
|
# uppercase the modifier, if any
|
||||||
|
name = re.sub(
|
||||||
|
r'[VM]\d[ivfd]?',
|
||||||
|
lambda m: m.group().upper(),
|
||||||
|
name
|
||||||
|
)
|
||||||
|
# and also nuke the integer constructors
|
||||||
|
vecIntMatch = re.search(r'(V\d)I', name)
|
||||||
|
if vecIntMatch:
|
||||||
|
name = name.replace(vecIntMatch.group(), vecIntMatch.group(1))
|
||||||
|
|
||||||
|
# add handedness / NDC modifiers
|
||||||
|
if not any(x in name for x in ['RH', 'LH', 'NO', 'ZO']):
|
||||||
|
for handedFunc in handedFuncs:
|
||||||
|
suffixed = handedFunc + '_RH'
|
||||||
|
if handedFunc in projectionFuncs:
|
||||||
|
suffixed += '_NO'
|
||||||
|
name = name.replace(handedFunc, suffixed)
|
||||||
|
return name
|
||||||
|
|
||||||
|
def wrapDegrees(m):
|
||||||
|
name = m.group('name')
|
||||||
|
arg = m.group('arg')
|
||||||
|
if '(' in arg:
|
||||||
|
# all bets are off, don't wrap the argument
|
||||||
|
printLineWarning('{} now takes radians, but we were unable to automatically wrap the first argument with HMM_AngleDeg().'.format(name))
|
||||||
|
return m.group()
|
||||||
|
return '{}(HMM_AngleDeg({}),'.format(name, arg)
|
||||||
|
|
||||||
|
updatedLine = re.sub(r'(hmm_|HMM_)\w+', replaceName, updatedLine)
|
||||||
|
updatedLine = re.sub(r'(?P<name>HMM_Perspective_RH_NO|HMM_Rotate_RH)\((?P<arg>.*?),', wrapDegrees, updatedLine)
|
||||||
|
|
||||||
|
result += updatedLine
|
||||||
|
|
||||||
|
with open(filename, 'w', newline='') as f:
|
||||||
|
f.write(result)
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog = 'update_hmm',
|
||||||
|
description = 'Updates C and C++ source code to use Handmade Math 2.0.',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'filename', nargs='+',
|
||||||
|
help='A file or directory to update to HMM 2.0. If a directory, all files with extensions from --exts will be processed.',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--exts', nargs='+', default=['.c', '.cpp', '.h', '.hpp'],
|
||||||
|
help='File extensions to run the script on, when targeting a directory. Default: .c, .cpp, .h, .hpp.',
|
||||||
|
metavar='.foo',
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
for path in args.filename:
|
||||||
|
filenames = []
|
||||||
|
if os.path.isfile(path):
|
||||||
|
filenames = [path]
|
||||||
|
else:
|
||||||
|
for root, dirs, files in os.walk(path):
|
||||||
|
for file in files:
|
||||||
|
if file == 'HandmadeMath.h':
|
||||||
|
printWarning('HandmadeMath.h will not be replaced by this script.')
|
||||||
|
elif file.endswith(tuple(args.exts)):
|
||||||
|
filenames.append(os.path.join(root, file))
|
||||||
|
|
||||||
|
for filename in filenames:
|
||||||
|
try:
|
||||||
|
updateFile(filename)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
print('Updated {} files with {} warnings.'.format(numFiles, numWarnings))
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
@REM Batch script to run update_hmm.exe on all your code files.
|
|
||||||
@REM Example:
|
|
||||||
@REM "update_hmm_all.bat Code\Project\" -> Recursively update all files/folders in .\Code\Project\
|
|
||||||
|
|
||||||
for /r %1 %%v in (*.c) do update_hmm.exe "%%v"
|
|
||||||
for /r %1 %%v in (*.h) do update_hmm.exe "%%v"
|
|
||||||
for /r %1 %%v in (*.cpp) do update_hmm.exe "%%v"
|
|
||||||
for /r %1 %%v in (*.hpp) do update_hmm.exe "%%v"
|
|
||||||
|
|
||||||
@REM @REM Uncomment for sokol-samples
|
|
||||||
@REM for /r %1 %%v in (*.glsl) do update_hmm.exe "%%v"
|
|
||||||
@REM for /r %1 %%v in (*.hlsl) do update_hmm.exe "%%v"
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
# Bash script to run update_hmm on all your code files.
|
|
||||||
# Example:
|
|
||||||
# "update_hmm_all Code/Project/" -> Recursively update all files/folders in ./Code/Project/
|
|
||||||
echo $1
|
|
||||||
for file in "$1"/*.{c,h,cpp,hpp} "$1"/**/*.{c,h,cpp,hpp} ; do
|
|
||||||
./update_hmm "$file"
|
|
||||||
done
|
|
||||||
|
|
||||||
# # Uncomment for sokol-samples
|
|
||||||
# for file in "$1"/*.{glsl,hlsl} "$1"/**/*.{glsl,hlsl} ; do
|
|
||||||
# ./update_hmm "$file"
|
|
||||||
# done
|
|
||||||
Reference in New Issue
Block a user