mirror of
https://github.com/HandmadeMath/HandmadeMath.git
synced 2025-12-29 08:04:31 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50ab386db5 | ||
|
|
f5c8f23d62 | ||
|
|
d67607d3d1 | ||
|
|
fabad91c39 | ||
|
|
8332a2d907 | ||
|
|
449091185e | ||
|
|
33f24a8289 | ||
|
|
d24e33c03a | ||
|
|
0a79c70dff | ||
|
|
eedda7ca4c | ||
|
|
850efa3606 | ||
|
|
9097224f37 | ||
|
|
b13e3a317c | ||
|
|
88d583e6ac | ||
|
|
3a382212f9 | ||
|
|
ba02e1a9c4 | ||
|
|
ba5982b2a9 | ||
|
|
373e9517b4 | ||
|
|
2d71b1b11b | ||
|
|
fdea881102 |
34
.github/workflows/ci.yml
vendored
34
.github/workflows/ci.yml
vendored
@@ -1,34 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: TheMrMilchmann/setup-msvc-dev@v2
|
||||
with:
|
||||
arch: x64
|
||||
if: matrix.os == 'windows-latest'
|
||||
- name: Test (Windows, MSVC)
|
||||
run: ./run_test_msvc.bat
|
||||
working-directory: ./test
|
||||
if: matrix.os == 'windows-latest'
|
||||
- name: Test (Windows, clang)
|
||||
run: ./run_test_clang.bat
|
||||
working-directory: ./test
|
||||
if: matrix.os == 'windows-latest'
|
||||
- name: Test (${{ matrix.os }})
|
||||
run: make all
|
||||
working-directory: ./test
|
||||
if: matrix.os != 'windows-latest'
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,7 +5,6 @@
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
*.vs
|
||||
|
||||
# Precompiled Headers
|
||||
@@ -31,4 +30,6 @@
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
test/build
|
||||
example/build
|
||||
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "example/external/glfw"]
|
||||
path = example/external/glfw
|
||||
url = git@github.com:glfw/glfw.git
|
||||
12
.travis.yml
Normal file
12
.travis.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
language: cpp
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
install:
|
||||
- cd test
|
||||
- make
|
||||
script:
|
||||
- build/hmm_test_c
|
||||
- build/hmm_test_c_no_sse
|
||||
- build/hmm_test_cpp
|
||||
- build/hmm_test_cpp_no_sse
|
||||
43
CONTRIBUTING.md
Normal file
43
CONTRIBUTING.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Understanding the structure of Handmade Math
|
||||
|
||||
Most of the functions in Handmade Math are very short, and are the kind of functions you want to have inlined. Because of this, most functions in Handmade Math are defined with `HINLINE`, which is defined as `static inline`.
|
||||
|
||||
The exceptions are functions like `HMM_Rotate`, which are long enough that it doesn't make sense to inline them. These functions are defined with an `HEXTERN` prototype, and implemented in the `#ifdef HANDMADE_MATH_IMPLEMENTATION` block.
|
||||
|
||||
# Quick style guide
|
||||
|
||||
* Put braces on a new line
|
||||
* Float literals should have digits both before and after the decimal.
|
||||
```cpp
|
||||
// Good
|
||||
0.0f;
|
||||
0.5f;
|
||||
1.0f;
|
||||
3.14159f;
|
||||
|
||||
// Bad
|
||||
1.f
|
||||
.0f
|
||||
```
|
||||
* Put parentheses around the returned value:
|
||||
```cpp
|
||||
HINLINE float
|
||||
HMM_MyFunction()
|
||||
{
|
||||
return (1.0f);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Other style notes
|
||||
|
||||
* If a new function is defined with different names for different datatypes, also add C++ overloaded versions of the functions. For example, if you have `HMM_LengthVec2(hmm_vec2)` and `HMM_LengthVec3(hmm_vec3)`, also provide `HMM_Length(hmm_vec2)` and `HMM_Length(hmm_vec3)`.
|
||||
|
||||
It is fine for the overloaded versions to call the C versions.
|
||||
* Only use operator overloading for analogous operators in C. That means `+` for vector addition is fine, but no using `^` for cross product or `|` for dot product.
|
||||
* Try to define functions in the same order as the prototypes.
|
||||
* Don't forget that Handmade Math uses column-major order for matrices!
|
||||
|
||||
# Versioning
|
||||
|
||||
We use [semantic versioning](http://semver.org/) because it's reasonable.
|
||||
4910
HandmadeMath.h
4910
HandmadeMath.h
File diff suppressed because it is too large
Load Diff
53
README.md
53
README.md
@@ -1,26 +1,41 @@
|
||||
# Handmade Math
|
||||
|
||||
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.
|
||||
[](https://travis-ci.org/StrangeZak/Handmade-Math)
|
||||
|
||||
To get started, go download [the latest release](https://github.com/HandmadeMath/HandmadeMath/releases).
|
||||
A single-file, cross-platform, public domain game math library for C/C++.
|
||||
|
||||
> If you are upgrading to Handmade Math 2.0, save yourself some time and use our [automatic update tool](./update).
|
||||
To get started, go download [the latest release](https://github.com/HandmadeMath/Handmade-Math/releases).
|
||||
|
||||
Here's what sets Handmade Math apart:
|
||||
-----
|
||||
|
||||
- **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 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`.
|
||||
- **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
|
||||
|
||||
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.
|
||||
Version | Changes |
|
||||
----------------|----------------|
|
||||
**1.6.0** | Added array subscript operators for vector and matrix types in C++. This is provided as a convenience, but be aware that it may incur an extra function call in unoptimized builds.
|
||||
**1.5.1** | Fixed a bug with uninitialized elements in HMM_LookAt.
|
||||
**1.5.0** | Changed internal structure for better performance and inlining. As a result, `HANDMADE_MATH_NO_INLINE` has been removed and no longer has any effect.
|
||||
**1.4.0** | Fixed bug when using C mode. SSE'd all vec4 operations. Removed zeroing for better performance.
|
||||
**1.3.0** | Removed need to `#define HANDMADE_MATH_CPP_MODE`. C++ definitions are now included automatically in C++ environments.
|
||||
**1.2.0** | Added equality functions for `HMM_Vec2`, `HMM_Vec3`, and `HMM_Vec4`, and SSE'd `HMM_MultiplyMat4` and `HMM_Transpose`.
|
||||
**1.1.5** | Added `Width` and `Height` to `HMM_Vec2`, and made it so you can supply your own `SqrtF`.
|
||||
**1.1.4** | Fixed SSE being included on platforms that don't support it, and fixed divide-by-zero errors when normalizing zero vectors.
|
||||
**1.1.3** | Fixed compile error in C mode
|
||||
**1.1.2** | Fixed invalid HMMDEF's in the function definitions
|
||||
**1.1.1** | Resolved compiler warnings on gcc and g++
|
||||
**1.1** | Quaternions! |
|
||||
**1.0** | Lots of testing |
|
||||
**0.7** | Added HMM_Vec2, and HMM_Vec4 versions of HMM_LengthSquared, HMM_Length, and HMM_Normalize. |
|
||||
**0.6** | Made HMM_Power faster, Fixed possible efficiency problem with HMM_Normalize, RENAMED HMM_LengthSquareRoot to HMM_LengthSquared, RENAMED HMM_RSqrtF to HMM_RSquareRootF, RENAMED HMM_SqrtF to HMM_SquareRootF, REMOVED Inner function (user should use Dot now), REMOVED HMM_FastInverseSquareRoot function declaration |
|
||||
**0.5.2** | Fixed SSE code in HMM_SqrtF and HMM_RSqrtF |
|
||||
**0.5.1** | Fixed HMM_Translate producing row-major matrices, ensured column-major order for matrices throughout |
|
||||
**0.5** | Added scalar operations on vectors and matrices, added += and -= for hmm_mat4, reconciled headers and implementations, tidied up in general |
|
||||
**0.4** | Added SSE Optimized HMM_SqrtF, HMM_RSqrtF, Removed use of C Runtime |
|
||||
**0.3** | Added +=,-=, *=, /= for hmm_vec2, hmm_vec3, hmm_vec4 |
|
||||
**0.2b** | Disabled warning C4201 on MSVC, Added 64bit percision on HMM_PI |
|
||||
**0.2a** | Prefixed Macros |
|
||||
**0.2** | Updated Documentation, Fixed C Compliance, Prefixed all functions, and added better operator overloading |
|
||||
**0.1** | Initial Version |
|
||||
|
||||
-----
|
||||
|
||||
## FAQ
|
||||
|
||||
@@ -30,8 +45,4 @@ This library is in the public domain. You can do whatever you want with it.
|
||||
|
||||
**Where can I contact you to ask questions?**
|
||||
|
||||
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.
|
||||
Feel free to make Github issues for any questions, concerns, or problems you encounter.
|
||||
|
||||
BIN
example/Axes.blend
Normal file
BIN
example/Axes.blend
Normal file
Binary file not shown.
10
example/Axes.mtl
Normal file
10
example/Axes.mtl
Normal file
@@ -0,0 +1,10 @@
|
||||
# Blender MTL File: 'Axes.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl None
|
||||
Ns 0
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.8 0.8 0.8
|
||||
Ks 0.8 0.8 0.8
|
||||
d 1
|
||||
illum 2
|
||||
481
example/Axes.obj
Normal file
481
example/Axes.obj
Normal file
@@ -0,0 +1,481 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'Axes.blend'
|
||||
# www.blender.org
|
||||
mtllib Axes.mtl
|
||||
o Cylinder.002_Cylinder
|
||||
v 0.000000 0.080000 -0.000000
|
||||
v 0.000000 0.080000 2.000000
|
||||
v 0.056569 0.056569 -0.000000
|
||||
v 0.056569 0.056569 2.000000
|
||||
v 0.080000 -0.000000 0.000000
|
||||
v 0.080000 0.000000 2.000000
|
||||
v 0.056569 -0.056569 0.000000
|
||||
v 0.056569 -0.056568 2.000000
|
||||
v -0.000000 -0.080000 0.000000
|
||||
v -0.000000 -0.080000 2.000000
|
||||
v -0.056569 -0.056569 0.000000
|
||||
v -0.056569 -0.056568 2.000000
|
||||
v -0.080000 0.000000 -0.000000
|
||||
v -0.080000 0.000000 2.000000
|
||||
v -0.056569 0.056569 -0.000000
|
||||
v -0.056569 0.056569 2.000000
|
||||
v 0.000000 0.233061 1.965651
|
||||
v 0.089189 0.215320 1.965651
|
||||
v 0.164799 0.164799 1.965651
|
||||
v 0.215320 0.089189 1.965651
|
||||
v 0.233061 0.000000 1.965651
|
||||
v 0.000000 0.000000 2.431772
|
||||
v 0.215320 -0.089188 1.965651
|
||||
v 0.164799 -0.164799 1.965651
|
||||
v 0.089189 -0.215320 1.965651
|
||||
v 0.000000 -0.233061 1.965651
|
||||
v -0.089188 -0.215320 1.965651
|
||||
v -0.164799 -0.164799 1.965651
|
||||
v -0.215320 -0.089188 1.965651
|
||||
v -0.233060 0.000000 1.965651
|
||||
v -0.215320 0.089189 1.965651
|
||||
v -0.164799 0.164799 1.965651
|
||||
v -0.089188 0.215320 1.965651
|
||||
vn 0.3827 0.9239 -0.0000
|
||||
vn 0.9239 0.3827 -0.0000
|
||||
vn 0.9239 -0.3827 0.0000
|
||||
vn 0.3827 -0.9239 0.0000
|
||||
vn -0.3827 -0.9239 0.0000
|
||||
vn -0.9239 -0.3827 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn -0.9239 0.3827 -0.0000
|
||||
vn -0.3827 0.9239 -0.0000
|
||||
vn 0.0000 -0.0000 -1.0000
|
||||
vn 0.1752 0.8806 0.4403
|
||||
vn 0.4988 0.7465 0.4403
|
||||
vn 0.7465 0.4988 0.4403
|
||||
vn 0.8806 0.1752 0.4403
|
||||
vn 0.8806 -0.1752 0.4403
|
||||
vn 0.7465 -0.4988 0.4403
|
||||
vn 0.4988 -0.7465 0.4403
|
||||
vn 0.1752 -0.8806 0.4403
|
||||
vn -0.1752 -0.8806 0.4403
|
||||
vn -0.4988 -0.7465 0.4403
|
||||
vn -0.7465 -0.4988 0.4403
|
||||
vn -0.8806 -0.1752 0.4403
|
||||
vn -0.8806 0.1752 0.4403
|
||||
vn -0.7465 0.4988 0.4403
|
||||
vn -0.4988 0.7465 0.4403
|
||||
vn -0.1752 0.8806 0.4403
|
||||
usemtl None
|
||||
s off
|
||||
f 1//1 2//1 4//1 3//1
|
||||
f 3//2 4//2 6//2 5//2
|
||||
f 5//3 6//3 8//3 7//3
|
||||
f 7//4 8//4 10//4 9//4
|
||||
f 9//5 10//5 12//5 11//5
|
||||
f 11//6 12//6 14//6 13//6
|
||||
f 4//7 2//7 16//7 14//7 12//7 10//7 8//7 6//7
|
||||
f 13//8 14//8 16//8 15//8
|
||||
f 15//9 16//9 2//9 1//9
|
||||
f 1//10 3//10 5//10 7//10 9//10 11//10 13//10 15//10
|
||||
f 17//11 22//11 18//11
|
||||
f 18//12 22//12 19//12
|
||||
f 19//13 22//13 20//13
|
||||
f 20//14 22//14 21//14
|
||||
f 21//15 22//15 23//15
|
||||
f 23//16 22//16 24//16
|
||||
f 24//17 22//17 25//17
|
||||
f 25//18 22//18 26//18
|
||||
f 26//19 22//19 27//19
|
||||
f 27//20 22//20 28//20
|
||||
f 28//21 22//21 29//21
|
||||
f 29//22 22//22 30//22
|
||||
f 30//23 22//23 31//23
|
||||
f 31//24 22//24 32//24
|
||||
f 32//25 22//25 33//25
|
||||
f 33//26 22//26 17//26
|
||||
f 17//10 18//10 19//10 20//10 21//10 23//10 24//10 25//10 26//10 27//10 28//10 29//10 30//10 31//10 32//10 33//10
|
||||
o Cylinder.001_Cylinder
|
||||
v 0.000000 0.000000 -0.080000
|
||||
v 0.000000 2.000000 -0.080000
|
||||
v 0.056569 0.000000 -0.056569
|
||||
v 0.056569 2.000000 -0.056569
|
||||
v 0.080000 0.000000 0.000000
|
||||
v 0.080000 2.000000 0.000000
|
||||
v 0.056569 0.000000 0.056569
|
||||
v 0.056569 2.000000 0.056569
|
||||
v -0.000000 0.000000 0.080000
|
||||
v -0.000000 2.000000 0.080000
|
||||
v -0.056569 0.000000 0.056569
|
||||
v -0.056569 2.000000 0.056569
|
||||
v -0.080000 0.000000 -0.000000
|
||||
v -0.080000 2.000000 -0.000000
|
||||
v -0.056569 0.000000 -0.056569
|
||||
v -0.056569 2.000000 -0.056569
|
||||
v 0.000000 1.965651 -0.233061
|
||||
v 0.089189 1.965651 -0.215320
|
||||
v 0.164799 1.965651 -0.164799
|
||||
v 0.215320 1.965651 -0.089188
|
||||
v 0.233061 1.965651 0.000000
|
||||
v 0.000000 2.431772 0.000000
|
||||
v 0.215320 1.965651 0.089188
|
||||
v 0.164799 1.965651 0.164799
|
||||
v 0.089189 1.965651 0.215320
|
||||
v 0.000000 1.965651 0.233061
|
||||
v -0.089188 1.965651 0.215320
|
||||
v -0.164799 1.965651 0.164799
|
||||
v -0.215320 1.965651 0.089188
|
||||
v -0.233060 1.965651 -0.000000
|
||||
v -0.215320 1.965651 -0.089188
|
||||
v -0.164799 1.965651 -0.164799
|
||||
v -0.089188 1.965651 -0.215320
|
||||
vn 0.3827 0.0000 -0.9239
|
||||
vn 0.9239 0.0000 -0.3827
|
||||
vn 0.9239 0.0000 0.3827
|
||||
vn 0.3827 0.0000 0.9239
|
||||
vn -0.3827 0.0000 0.9239
|
||||
vn -0.9239 0.0000 0.3827
|
||||
vn 0.0000 1.0000 -0.0000
|
||||
vn -0.9239 0.0000 -0.3827
|
||||
vn -0.3827 0.0000 -0.9239
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.1752 0.4403 -0.8806
|
||||
vn 0.4988 0.4403 -0.7465
|
||||
vn 0.7465 0.4403 -0.4988
|
||||
vn 0.8806 0.4403 -0.1752
|
||||
vn 0.8806 0.4403 0.1752
|
||||
vn 0.7465 0.4403 0.4988
|
||||
vn 0.4988 0.4403 0.7465
|
||||
vn 0.1752 0.4403 0.8806
|
||||
vn -0.1752 0.4403 0.8806
|
||||
vn -0.4988 0.4403 0.7465
|
||||
vn -0.7465 0.4403 0.4988
|
||||
vn -0.8806 0.4403 0.1752
|
||||
vn -0.8806 0.4403 -0.1752
|
||||
vn -0.7465 0.4403 -0.4988
|
||||
vn -0.4988 0.4403 -0.7465
|
||||
vn -0.1752 0.4403 -0.8806
|
||||
usemtl None
|
||||
s off
|
||||
f 34//27 35//27 37//27 36//27
|
||||
f 36//28 37//28 39//28 38//28
|
||||
f 38//29 39//29 41//29 40//29
|
||||
f 40//30 41//30 43//30 42//30
|
||||
f 42//31 43//31 45//31 44//31
|
||||
f 44//32 45//32 47//32 46//32
|
||||
f 37//33 35//33 49//33 47//33 45//33 43//33 41//33 39//33
|
||||
f 46//34 47//34 49//34 48//34
|
||||
f 48//35 49//35 35//35 34//35
|
||||
f 34//36 36//36 38//36 40//36 42//36 44//36 46//36 48//36
|
||||
f 50//37 55//37 51//37
|
||||
f 51//38 55//38 52//38
|
||||
f 52//39 55//39 53//39
|
||||
f 53//40 55//40 54//40
|
||||
f 54//41 55//41 56//41
|
||||
f 56//42 55//42 57//42
|
||||
f 57//43 55//43 58//43
|
||||
f 58//44 55//44 59//44
|
||||
f 59//45 55//45 60//45
|
||||
f 60//46 55//46 61//46
|
||||
f 61//47 55//47 62//47
|
||||
f 62//48 55//48 63//48
|
||||
f 63//49 55//49 64//49
|
||||
f 64//50 55//50 65//50
|
||||
f 65//51 55//51 66//51
|
||||
f 66//52 55//52 50//52
|
||||
f 50//36 51//36 52//36 53//36 54//36 56//36 57//36 58//36 59//36 60//36 61//36 62//36 63//36 64//36 65//36 66//36
|
||||
o Cylinder
|
||||
v 0.000000 0.000000 -0.080000
|
||||
v 2.000000 0.000000 -0.080000
|
||||
v 0.000000 -0.056569 -0.056569
|
||||
v 2.000000 -0.056568 -0.056569
|
||||
v 0.000000 -0.080000 0.000000
|
||||
v 2.000000 -0.080000 0.000000
|
||||
v 0.000000 -0.056569 0.056569
|
||||
v 2.000000 -0.056568 0.056569
|
||||
v -0.000000 0.000000 0.080000
|
||||
v 2.000000 0.000000 0.080000
|
||||
v -0.000000 0.056569 0.056569
|
||||
v 2.000000 0.056569 0.056569
|
||||
v -0.000000 0.080000 -0.000000
|
||||
v 2.000000 0.080000 -0.000000
|
||||
v -0.000000 0.056569 -0.056569
|
||||
v 2.000000 0.056569 -0.056569
|
||||
v 1.965651 -0.000000 -0.233061
|
||||
v 1.965651 -0.089188 -0.215320
|
||||
v 1.965651 -0.164799 -0.164799
|
||||
v 1.965651 -0.215320 -0.089188
|
||||
v 1.965651 -0.233061 0.000000
|
||||
v 2.431772 0.000000 0.000000
|
||||
v 1.965651 -0.215320 0.089188
|
||||
v 1.965651 -0.164799 0.164799
|
||||
v 1.965651 -0.089188 0.215320
|
||||
v 1.965651 -0.000000 0.233061
|
||||
v 1.965651 0.089188 0.215320
|
||||
v 1.965651 0.164799 0.164799
|
||||
v 1.965651 0.215320 0.089188
|
||||
v 1.965651 0.233061 -0.000000
|
||||
v 1.965651 0.215320 -0.089188
|
||||
v 1.965651 0.164799 -0.164799
|
||||
v 1.965651 0.089188 -0.215320
|
||||
vn 0.0000 -0.3827 -0.9239
|
||||
vn 0.0000 -0.9239 -0.3827
|
||||
vn 0.0000 -0.9239 0.3827
|
||||
vn 0.0000 -0.3827 0.9239
|
||||
vn -0.0000 0.3827 0.9239
|
||||
vn -0.0000 0.9239 0.3827
|
||||
vn 1.0000 -0.0000 0.0000
|
||||
vn -0.0000 0.9239 -0.3827
|
||||
vn -0.0000 0.3827 -0.9239
|
||||
vn -1.0000 -0.0000 0.0000
|
||||
vn 0.4403 -0.1752 -0.8806
|
||||
vn 0.4403 -0.4988 -0.7465
|
||||
vn 0.4403 -0.7465 -0.4988
|
||||
vn 0.4403 -0.8806 -0.1752
|
||||
vn 0.4403 -0.8806 0.1752
|
||||
vn 0.4403 -0.7465 0.4988
|
||||
vn 0.4403 -0.4988 0.7465
|
||||
vn 0.4403 -0.1752 0.8806
|
||||
vn 0.4403 0.1752 0.8806
|
||||
vn 0.4403 0.4988 0.7465
|
||||
vn 0.4403 0.7465 0.4988
|
||||
vn 0.4403 0.8806 0.1752
|
||||
vn 0.4403 0.8806 -0.1752
|
||||
vn 0.4403 0.7465 -0.4988
|
||||
vn 0.4403 0.4988 -0.7465
|
||||
vn 0.4403 0.1752 -0.8806
|
||||
usemtl None
|
||||
s off
|
||||
f 67//53 68//53 70//53 69//53
|
||||
f 69//54 70//54 72//54 71//54
|
||||
f 71//55 72//55 74//55 73//55
|
||||
f 73//56 74//56 76//56 75//56
|
||||
f 75//57 76//57 78//57 77//57
|
||||
f 77//58 78//58 80//58 79//58
|
||||
f 70//59 68//59 82//59 80//59 78//59 76//59 74//59 72//59
|
||||
f 79//60 80//60 82//60 81//60
|
||||
f 81//61 82//61 68//61 67//61
|
||||
f 67//62 69//62 71//62 73//62 75//62 77//62 79//62 81//62
|
||||
f 83//63 88//63 84//63
|
||||
f 84//64 88//64 85//64
|
||||
f 85//65 88//65 86//65
|
||||
f 86//66 88//66 87//66
|
||||
f 87//67 88//67 89//67
|
||||
f 89//68 88//68 90//68
|
||||
f 90//69 88//69 91//69
|
||||
f 91//70 88//70 92//70
|
||||
f 92//71 88//71 93//71
|
||||
f 93//72 88//72 94//72
|
||||
f 94//73 88//73 95//73
|
||||
f 95//74 88//74 96//74
|
||||
f 96//75 88//75 97//75
|
||||
f 97//76 88//76 98//76
|
||||
f 98//77 88//77 99//77
|
||||
f 99//78 88//78 83//78
|
||||
f 83//62 84//62 85//62 86//62 87//62 89//62 90//62 91//62 92//62 93//62 94//62 95//62 96//62 97//62 98//62 99//62
|
||||
o Text.005
|
||||
v 0.778616 0.000000 -3.449000
|
||||
v 0.395616 0.000000 -3.449000
|
||||
v 0.395616 0.000000 -3.369000
|
||||
v 0.623616 0.000000 -3.369000
|
||||
v 0.385616 0.000000 -3.000000
|
||||
v 0.779616 0.000000 -3.000000
|
||||
v 0.779616 0.000000 -3.080000
|
||||
v 0.539616 0.000000 -3.080000
|
||||
v 0.334616 0.000000 -3.267000
|
||||
v 0.091616 0.000000 -3.267000
|
||||
v 0.091616 0.000000 -3.174000
|
||||
v 0.334616 0.000000 -3.174000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl None
|
||||
s off
|
||||
f 102//79 100//79 101//79
|
||||
f 102//79 103//79 100//79
|
||||
f 103//79 107//79 100//79
|
||||
f 104//79 107//79 103//79
|
||||
f 104//79 106//79 107//79
|
||||
f 104//79 105//79 106//79
|
||||
f 110//79 108//79 109//79
|
||||
f 110//79 111//79 108//79
|
||||
o Text.004
|
||||
v 1.039616 0.000000 2.551000
|
||||
v 0.656616 0.000000 2.551000
|
||||
v 0.656616 0.000000 2.631000
|
||||
v 0.884616 0.000000 2.631000
|
||||
v 0.646616 0.000000 3.000000
|
||||
v 1.040616 0.000000 3.000000
|
||||
v 1.040616 0.000000 2.920000
|
||||
v 0.800616 0.000000 2.920000
|
||||
v 0.302616 0.000000 2.411000
|
||||
v 0.302616 0.000000 2.606000
|
||||
v 0.107616 0.000000 2.606000
|
||||
v 0.107616 0.000000 2.688000
|
||||
v 0.302616 0.000000 2.688000
|
||||
v 0.302616 0.000000 2.883000
|
||||
v 0.384616 0.000000 2.883000
|
||||
v 0.384616 0.000000 2.688000
|
||||
v 0.579616 0.000000 2.688000
|
||||
v 0.579616 0.000000 2.606000
|
||||
v 0.384616 0.000000 2.606000
|
||||
v 0.384616 0.000000 2.411000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
usemtl None
|
||||
s off
|
||||
f 114//80 112//80 113//80
|
||||
f 114//80 115//80 112//80
|
||||
f 115//80 119//80 112//80
|
||||
f 116//80 119//80 115//80
|
||||
f 116//80 118//80 119//80
|
||||
f 116//80 117//80 118//80
|
||||
f 121//80 131//80 120//80
|
||||
f 121//80 130//80 131//80
|
||||
f 123//80 121//80 122//80
|
||||
f 123//80 130//80 121//80
|
||||
f 123//80 129//80 130//80
|
||||
f 123//80 128//80 129//80
|
||||
f 124//81 128//81 123//81
|
||||
f 125//80 127//80 124//80
|
||||
f 127//81 128//81 124//81
|
||||
f 125//80 126//80 127//80
|
||||
o Text.003
|
||||
v 0.812616 -2.551000 -0.000000
|
||||
v 0.712616 -2.551000 -0.000000
|
||||
v 0.596616 -2.804000 -0.000000
|
||||
v 0.475616 -2.551000 -0.000000
|
||||
v 0.374616 -2.551000 -0.000000
|
||||
v 0.548616 -2.904000 -0.000000
|
||||
v 0.395616 -3.230000 0.000000
|
||||
v 0.494616 -3.230000 0.000000
|
||||
v 0.334616 -2.733000 -0.000000
|
||||
v 0.091616 -2.733000 -0.000000
|
||||
v 0.091616 -2.826000 -0.000000
|
||||
v 0.334616 -2.826000 -0.000000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
usemtl None
|
||||
s off
|
||||
f 137//82 135//82 136//82
|
||||
f 137//82 134//82 135//82
|
||||
f 134//82 132//82 133//82
|
||||
f 134//82 139//82 132//82
|
||||
f 137//82 139//82 134//82
|
||||
f 138//82 139//82 137//82
|
||||
f 142//82 140//82 141//82
|
||||
f 142//82 143//82 140//82
|
||||
o Text.002
|
||||
v 1.073616 3.449000 -0.000000
|
||||
v 0.973616 3.449000 -0.000000
|
||||
v 0.857616 3.196000 -0.000000
|
||||
v 0.736616 3.449000 -0.000000
|
||||
v 0.635616 3.449000 -0.000000
|
||||
v 0.809616 3.096000 -0.000000
|
||||
v 0.656616 2.770000 0.000000
|
||||
v 0.755616 2.770000 0.000000
|
||||
v 0.302616 3.589000 -0.000000
|
||||
v 0.302616 3.394000 -0.000000
|
||||
v 0.107616 3.394000 -0.000000
|
||||
v 0.107616 3.312000 -0.000000
|
||||
v 0.302616 3.312000 -0.000000
|
||||
v 0.302616 3.117000 -0.000000
|
||||
v 0.384616 3.117000 -0.000000
|
||||
v 0.384616 3.312000 -0.000000
|
||||
v 0.579616 3.312000 -0.000000
|
||||
v 0.579616 3.394000 -0.000000
|
||||
v 0.384616 3.394000 -0.000000
|
||||
v 0.384616 3.589000 -0.000000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
usemtl None
|
||||
s off
|
||||
f 149//83 147//83 148//83
|
||||
f 149//83 146//83 147//83
|
||||
f 146//83 144//83 145//83
|
||||
f 146//83 151//83 144//83
|
||||
f 149//83 151//83 146//83
|
||||
f 150//83 151//83 149//83
|
||||
f 153//83 163//83 152//83
|
||||
f 153//83 162//83 163//83
|
||||
f 155//83 153//83 154//83
|
||||
f 155//83 162//83 153//83
|
||||
f 155//83 161//83 162//83
|
||||
f 155//83 160//83 161//83
|
||||
f 156//84 160//84 155//84
|
||||
f 157//83 159//83 156//83
|
||||
f 159//83 160//83 156//83
|
||||
f 157//83 158//83 159//83
|
||||
o Text.001
|
||||
v -3.138384 0.000000 -0.449000
|
||||
v -3.252384 0.000000 -0.449000
|
||||
v -3.380384 0.000000 -0.295000
|
||||
v -3.513384 0.000000 -0.449000
|
||||
v -3.625384 0.000000 -0.449000
|
||||
v -3.436384 0.000000 -0.228000
|
||||
v -3.625384 0.000000 0.000000
|
||||
v -3.513384 0.000000 0.000000
|
||||
v -3.380384 0.000000 -0.161000
|
||||
v -3.239384 0.000000 0.000000
|
||||
v -3.125384 0.000000 0.000000
|
||||
v -3.323384 0.000000 -0.228000
|
||||
v -3.665384 0.000000 -0.267000
|
||||
v -3.908384 0.000000 -0.267000
|
||||
v -3.908384 0.000000 -0.174000
|
||||
v -3.665384 0.000000 -0.174000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl None
|
||||
s off
|
||||
f 169//85 167//85 168//85
|
||||
f 169//85 166//85 167//85
|
||||
f 166//85 164//85 165//85
|
||||
f 166//85 175//85 164//85
|
||||
f 169//85 175//85 166//85
|
||||
f 170//85 175//85 169//85
|
||||
f 170//85 172//85 175//85
|
||||
f 172//85 174//85 175//85
|
||||
f 170//85 171//85 172//85
|
||||
f 173//85 174//85 172//85
|
||||
f 178//85 176//85 177//85
|
||||
f 178//85 179//85 176//85
|
||||
o Text
|
||||
v 4.122616 0.000000 -0.449000
|
||||
v 4.008616 0.000000 -0.449000
|
||||
v 3.880616 0.000000 -0.295000
|
||||
v 3.747616 0.000000 -0.449000
|
||||
v 3.635616 0.000000 -0.449000
|
||||
v 3.824616 0.000000 -0.228000
|
||||
v 3.635616 0.000000 0.000000
|
||||
v 3.747616 0.000000 0.000000
|
||||
v 3.880616 0.000000 -0.161000
|
||||
v 4.021616 0.000000 0.000000
|
||||
v 4.135616 0.000000 0.000000
|
||||
v 3.937616 0.000000 -0.228000
|
||||
v 3.302616 0.000000 -0.589000
|
||||
v 3.302616 0.000000 -0.394000
|
||||
v 3.107616 0.000000 -0.394000
|
||||
v 3.107616 0.000000 -0.312000
|
||||
v 3.302616 0.000000 -0.312000
|
||||
v 3.302616 0.000000 -0.117000
|
||||
v 3.384616 0.000000 -0.117000
|
||||
v 3.384616 0.000000 -0.312000
|
||||
v 3.579616 0.000000 -0.312000
|
||||
v 3.579616 0.000000 -0.394000
|
||||
v 3.384616 0.000000 -0.394000
|
||||
v 3.384616 0.000000 -0.589000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
usemtl None
|
||||
s off
|
||||
f 185//86 183//86 184//86
|
||||
f 185//86 182//86 183//86
|
||||
f 182//86 180//86 181//86
|
||||
f 182//86 191//86 180//86
|
||||
f 185//86 191//86 182//86
|
||||
f 186//86 191//86 185//86
|
||||
f 186//86 188//86 191//86
|
||||
f 188//86 190//86 191//86
|
||||
f 186//86 187//86 188//86
|
||||
f 189//86 190//86 188//86
|
||||
f 193//86 203//86 192//86
|
||||
f 193//86 202//86 203//86
|
||||
f 195//86 193//86 194//86
|
||||
f 195//86 202//86 193//86
|
||||
f 195//86 201//86 202//86
|
||||
f 195//86 200//86 201//86
|
||||
f 196//87 200//87 195//87
|
||||
f 197//86 199//86 196//86
|
||||
f 199//87 200//87 196//87
|
||||
f 197//86 198//86 199//86
|
||||
22
example/Makefile
Normal file
22
example/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
BUILD_DIR=build
|
||||
|
||||
CXXFLAGS+=-std=c++11
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
|
||||
glfw:
|
||||
mkdir -p $(BUILD_DIR)/glfw
|
||||
cd $(BUILD_DIR)/glfw \
|
||||
&& cmake -DGLFW_BUILD_TESTS=off -DGLFW_BUILD_DOCS=off -DGLFW_BUILD_EXAMPLES=off ../../external/glfw \
|
||||
&& make
|
||||
|
||||
example:
|
||||
mkdir -p $(BUILD_DIR)/example
|
||||
cd $(BUILD_DIR)/example \
|
||||
&& $(CXX) $(CPPFLAGS) $(CXXFLAGS) -ohmmexample \
|
||||
-I../../external/glfw/include -I../../.. \
|
||||
-L../glfw/src \
|
||||
-lglew -lglfw3 \
|
||||
-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo \
|
||||
../../src/*.cpp
|
||||
10
example/MonkeyFlat.mtl
Normal file
10
example/MonkeyFlat.mtl
Normal file
@@ -0,0 +1,10 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl None
|
||||
Ns 0
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.8 0.8 0.8
|
||||
Ks 0.8 0.8 0.8
|
||||
d 1
|
||||
illum 2
|
||||
1512
example/MonkeyFlat.obj
Normal file
1512
example/MonkeyFlat.obj
Normal file
File diff suppressed because it is too large
Load Diff
10
example/MonkeySmooth.mtl
Normal file
10
example/MonkeySmooth.mtl
Normal file
@@ -0,0 +1,10 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl None
|
||||
Ns 0
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.8 0.8 0.8
|
||||
Ks 0.8 0.8 0.8
|
||||
d 1
|
||||
illum 2
|
||||
5998
example/MonkeySmooth.obj
Normal file
5998
example/MonkeySmooth.obj
Normal file
File diff suppressed because it is too large
Load Diff
14
example/build.bat
Normal file
14
example/build.bat
Normal file
@@ -0,0 +1,14 @@
|
||||
@echo off
|
||||
|
||||
mkdir build\example
|
||||
pushd build\example
|
||||
cl^
|
||||
/I..\..\.. /I..\..\external\glew\include /I..\..\external\glfw-win64\include^
|
||||
/MD /EHsc^
|
||||
..\..\src\*.cpp^
|
||||
/Fehmm_example.exe^
|
||||
/link^
|
||||
/LIBPATH:..\..\external\glew\lib\Release\x64 /LIBPATH:..\..\external\glfw-win64\lib-vc2015^
|
||||
opengl32.lib gdi32.lib user32.lib shell32.lib glew32.lib glfw3.lib
|
||||
copy ..\..\external\glew\bin\Release\x64\glew32.dll glew32.dll
|
||||
popd
|
||||
73
example/external/glew/LICENSE.txt
vendored
Normal file
73
example/external/glew/LICENSE.txt
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
The OpenGL Extension Wrangler Library
|
||||
Copyright (C) 2002-2007, Milan Ikits <milan ikits[]ieee org>
|
||||
Copyright (C) 2002-2007, Marcelo E. Magallon <mmagallo[]debian org>
|
||||
Copyright (C) 2002, Lev Povalahev
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* The name of the author may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Mesa 3-D graphics library
|
||||
Version: 7.0
|
||||
|
||||
Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
Copyright (c) 2007 The Khronos Group Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and/or associated documentation files (the
|
||||
"Materials"), to deal in the Materials without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
permit persons to whom the Materials are furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Materials.
|
||||
|
||||
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
2618
example/external/glew/include/GL/eglew.h
vendored
Normal file
2618
example/external/glew/include/GL/eglew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
23686
example/external/glew/include/GL/glew.h
vendored
Normal file
23686
example/external/glew/include/GL/glew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1775
example/external/glew/include/GL/glxew.h
vendored
Normal file
1775
example/external/glew/include/GL/glxew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1447
example/external/glew/include/GL/wglew.h
vendored
Normal file
1447
example/external/glew/include/GL/wglew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
example/external/glfw
vendored
Submodule
1
example/external/glfw
vendored
Submodule
Submodule example/external/glfw added at 617a322bd8
22
example/external/glfw-win64/COPYING.txt
vendored
Normal file
22
example/external/glfw-win64/COPYING.txt
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2002-2006 Marcus Geelnard
|
||||
Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would
|
||||
be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
4248
example/external/glfw-win64/include/GLFW/glfw3.h
vendored
Normal file
4248
example/external/glfw-win64/include/GLFW/glfw3.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
456
example/external/glfw-win64/include/GLFW/glfw3native.h
vendored
Normal file
456
example/external/glfw-win64/include/GLFW/glfw3native.h
vendored
Normal file
@@ -0,0 +1,456 @@
|
||||
/*************************************************************************
|
||||
* GLFW 3.2 - www.glfw.org
|
||||
* A library for OpenGL, window and input
|
||||
*------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2006 Marcus Geelnard
|
||||
* Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would
|
||||
* be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef _glfw3_native_h_
|
||||
#define _glfw3_native_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Doxygen documentation
|
||||
*************************************************************************/
|
||||
|
||||
/*! @file glfw3native.h
|
||||
* @brief The header of the native access functions.
|
||||
*
|
||||
* This is the header file of the native access functions. See @ref native for
|
||||
* more information.
|
||||
*/
|
||||
/*! @defgroup native Native access
|
||||
*
|
||||
* **By using the native access functions you assert that you know what you're
|
||||
* doing and how to fix problems caused by using them. If you don't, you
|
||||
* shouldn't be using them.**
|
||||
*
|
||||
* Before the inclusion of @ref glfw3native.h, you may define exactly one
|
||||
* window system API macro and zero or more context creation API macros.
|
||||
*
|
||||
* The chosen backends must match those the library was compiled for. Failure
|
||||
* to do this will cause a link-time error.
|
||||
*
|
||||
* The available window API macros are:
|
||||
* * `GLFW_EXPOSE_NATIVE_WIN32`
|
||||
* * `GLFW_EXPOSE_NATIVE_COCOA`
|
||||
* * `GLFW_EXPOSE_NATIVE_X11`
|
||||
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
|
||||
* * `GLFW_EXPOSE_NATIVE_MIR`
|
||||
*
|
||||
* The available context API macros are:
|
||||
* * `GLFW_EXPOSE_NATIVE_WGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_NSGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_GLX`
|
||||
* * `GLFW_EXPOSE_NATIVE_EGL`
|
||||
*
|
||||
* These macros select which of the native access functions that are declared
|
||||
* and which platform-specific headers to include. It is then up your (by
|
||||
* definition platform-specific) code to handle which of these should be
|
||||
* defined.
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* System headers and types
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||
// example to allow applications to correctly declare a GL_ARB_debug_output
|
||||
// callback) but windows.h assumes no one will define APIENTRY before it does
|
||||
#undef APIENTRY
|
||||
#include <windows.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#if defined(__OBJC__)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#else
|
||||
typedef void* id;
|
||||
#endif
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_X11)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
#include <wayland-client.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_MIR)
|
||||
#include <mir_toolkit/mir_client_library.h>
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/* WGL is declared by windows.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/* NSGL is declared by Cocoa.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Functions
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||
/*! @brief Returns the adapter device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
|
||||
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
|
||||
* occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the display device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded display device name (for example
|
||||
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `HWND` of the specified window.
|
||||
*
|
||||
* @return The `HWND` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/*! @brief Returns the `HGLRC` of the specified window.
|
||||
*
|
||||
* @return The `HGLRC` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
|
||||
*
|
||||
* @return The `CGDirectDisplayID` of the specified monitor, or
|
||||
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `NSWindow` of the specified window.
|
||||
*
|
||||
* @return The `NSWindow` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/*! @brief Returns the `NSOpenGLContext` of the specified window.
|
||||
*
|
||||
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_X11)
|
||||
/*! @brief Returns the `Display` used by GLFW.
|
||||
*
|
||||
* @return The `Display` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Display* glfwGetX11Display(void);
|
||||
|
||||
/*! @brief Returns the `RRCrtc` of the specified monitor.
|
||||
*
|
||||
* @return The `RRCrtc` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `RROutput` of the specified monitor.
|
||||
*
|
||||
* @return The `RROutput` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `Window` of the specified window.
|
||||
*
|
||||
* @return The `Window` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
/*! @brief Returns the `GLXContext` of the specified window.
|
||||
*
|
||||
* @return The `GLXContext` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the `GLXWindow` of the specified window.
|
||||
*
|
||||
* @return The `GLXWindow` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
/*! @brief Returns the `struct wl_display*` used by GLFW.
|
||||
*
|
||||
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
|
||||
|
||||
/*! @brief Returns the `struct wl_output*` of the specified monitor.
|
||||
*
|
||||
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the main `struct wl_surface*` of the specified window.
|
||||
*
|
||||
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
|
||||
* an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_MIR)
|
||||
/*! @brief Returns the `MirConnection*` used by GLFW.
|
||||
*
|
||||
* @return The `MirConnection*` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI MirConnection* glfwGetMirDisplay(void);
|
||||
|
||||
/*! @brief Returns the Mir output ID of the specified monitor.
|
||||
*
|
||||
* @return The Mir output ID of the specified monitor, or zero if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `MirSurface*` of the specified window.
|
||||
*
|
||||
* @return The `MirSurface*` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
/*! @brief Returns the `EGLDisplay` used by GLFW.
|
||||
*
|
||||
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
|
||||
|
||||
/*! @brief Returns the `EGLContext` of the specified window.
|
||||
*
|
||||
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the `EGLSurface` of the specified window.
|
||||
*
|
||||
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _glfw3_native_h_ */
|
||||
|
||||
5
example/shell.bat
Normal file
5
example/shell.bat
Normal file
@@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
|
||||
if not defined ORIGINALPATH set ORIGINALPATH=%PATH%
|
||||
set PATH=%ORIGINALPATH%
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
|
||||
161
example/src/Cube.h
Normal file
161
example/src/Cube.h
Normal file
@@ -0,0 +1,161 @@
|
||||
#include <HandmadeMath.h>
|
||||
|
||||
#include "Entity.h"
|
||||
#include "RenderComponent.h"
|
||||
|
||||
#ifndef HMME_CUBE_H
|
||||
#define HMME_CUBE_H
|
||||
|
||||
// Our vertices. Three consecutive floats give a 3D vertex; Three consecutive vertices give a triangle.
|
||||
// A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices
|
||||
static const GLfloat cubeVertices[] = {
|
||||
-1.0f,-1.0f,-1.0f, // triangle 1 : begin
|
||||
-1.0f,-1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 1.0f, // triangle 1 : end
|
||||
1.0f, 1.0f,-1.0f, // triangle 2 : begin
|
||||
-1.0f,-1.0f,-1.0f,
|
||||
-1.0f, 1.0f,-1.0f, // triangle 2 : end
|
||||
1.0f,-1.0f, 1.0f,
|
||||
-1.0f,-1.0f,-1.0f,
|
||||
1.0f,-1.0f,-1.0f,
|
||||
1.0f, 1.0f,-1.0f,
|
||||
1.0f,-1.0f,-1.0f,
|
||||
-1.0f,-1.0f,-1.0f,
|
||||
-1.0f,-1.0f,-1.0f,
|
||||
-1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f,-1.0f,
|
||||
1.0f,-1.0f, 1.0f,
|
||||
-1.0f,-1.0f, 1.0f,
|
||||
-1.0f,-1.0f,-1.0f,
|
||||
-1.0f, 1.0f, 1.0f,
|
||||
-1.0f,-1.0f, 1.0f,
|
||||
1.0f,-1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f,-1.0f,-1.0f,
|
||||
1.0f, 1.0f,-1.0f,
|
||||
1.0f,-1.0f,-1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f,-1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f,-1.0f,
|
||||
-1.0f, 1.0f,-1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f,-1.0f,
|
||||
-1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 1.0f,
|
||||
1.0f,-1.0f, 1.0f
|
||||
};
|
||||
|
||||
// One color for each vertex. They were generated randomly.
|
||||
static const GLfloat cubeColors[] = {
|
||||
0.583f, 0.771f, 0.014f,
|
||||
0.609f, 0.115f, 0.436f,
|
||||
0.327f, 0.483f, 0.844f,
|
||||
0.822f, 0.569f, 0.201f,
|
||||
0.435f, 0.602f, 0.223f,
|
||||
0.310f, 0.747f, 0.185f,
|
||||
0.597f, 0.770f, 0.761f,
|
||||
0.559f, 0.436f, 0.730f,
|
||||
0.359f, 0.583f, 0.152f,
|
||||
0.483f, 0.596f, 0.789f,
|
||||
0.559f, 0.861f, 0.639f,
|
||||
0.195f, 0.548f, 0.859f,
|
||||
0.014f, 0.184f, 0.576f,
|
||||
0.771f, 0.328f, 0.970f,
|
||||
0.406f, 0.615f, 0.116f,
|
||||
0.676f, 0.977f, 0.133f,
|
||||
0.971f, 0.572f, 0.833f,
|
||||
0.140f, 0.616f, 0.489f,
|
||||
0.997f, 0.513f, 0.064f,
|
||||
0.945f, 0.719f, 0.592f,
|
||||
0.543f, 0.021f, 0.978f,
|
||||
0.279f, 0.317f, 0.505f,
|
||||
0.167f, 0.620f, 0.077f,
|
||||
0.347f, 0.857f, 0.137f,
|
||||
0.055f, 0.953f, 0.042f,
|
||||
0.714f, 0.505f, 0.345f,
|
||||
0.783f, 0.290f, 0.734f,
|
||||
0.722f, 0.645f, 0.174f,
|
||||
0.302f, 0.455f, 0.848f,
|
||||
0.225f, 0.587f, 0.040f,
|
||||
0.517f, 0.713f, 0.338f,
|
||||
0.053f, 0.959f, 0.120f,
|
||||
0.393f, 0.621f, 0.362f,
|
||||
0.673f, 0.211f, 0.457f,
|
||||
0.820f, 0.883f, 0.371f,
|
||||
0.982f, 0.099f, 0.879f
|
||||
};
|
||||
|
||||
class CubeRenderComponent : public RenderComponent {
|
||||
public:
|
||||
GLuint vaoID;
|
||||
GLuint vertexBufferID;
|
||||
GLuint colorBufferID;
|
||||
|
||||
CubeRenderComponent() {
|
||||
glGenVertexArrays(1, &vaoID);
|
||||
|
||||
glGenBuffers(1, &vertexBufferID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &colorBufferID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, colorBufferID);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeColors), cubeColors, GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
void Draw() override {
|
||||
glBindVertexArray(vaoID);
|
||||
|
||||
// 1st attribute buffer : vertices
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
|
||||
glVertexAttribPointer(
|
||||
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
|
||||
3, // size
|
||||
GL_FLOAT, // type
|
||||
GL_FALSE, // normalized?
|
||||
0, // stride
|
||||
(void*)0 // array buffer offset
|
||||
);
|
||||
|
||||
// 2nd attribute buffer : colors
|
||||
glEnableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, colorBufferID);
|
||||
glVertexAttribPointer(
|
||||
1, // attribute. No particular reason for 1, but must match the layout in the shader.
|
||||
3, // size
|
||||
GL_FLOAT, // type
|
||||
GL_FALSE, // normalized?
|
||||
0, // stride
|
||||
(void*)0 // array buffer offset
|
||||
);
|
||||
|
||||
// Shader??
|
||||
|
||||
// Draw the triangle!
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36); // Starting from vertex 0; 3 vertices total -> 1 triangle
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
}
|
||||
};
|
||||
|
||||
class Cube : public Entity {
|
||||
public:
|
||||
float x = 0;
|
||||
CubeRenderComponent rc = CubeRenderComponent();
|
||||
|
||||
Cube() {
|
||||
// renderComponent = &rc;
|
||||
}
|
||||
|
||||
void Tick(float deltaSeconds, Input previousInput, Input input) override {
|
||||
x += deltaSeconds;
|
||||
// position.X = 2.0f * HMM_SINF(x);
|
||||
|
||||
rotation *= HMM_QuaternionFromAxisAngle(HMM_Vec3(0.0f, 1.0f, 0.0f), deltaSeconds * HMM_ToRadians(45.0f));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
119
example/src/Entity.h
Normal file
119
example/src/Entity.h
Normal file
@@ -0,0 +1,119 @@
|
||||
#include <vector>
|
||||
|
||||
#include <HandmadeMath.h>
|
||||
|
||||
#ifndef HMME_ENTITY_H
|
||||
#define HMME_ENTITY_H
|
||||
|
||||
#include "RenderComponent.h"
|
||||
|
||||
class Entity {
|
||||
public:
|
||||
hmm_vec3 position = HMM_Vec3(0.0f, 0.0f, 0.0f);
|
||||
hmm_quaternion rotation = HMM_Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
hmm_vec3 scale = HMM_Vec3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
std::vector<Entity*> children;
|
||||
|
||||
void AddChild(Entity* e) {
|
||||
children.push_back(e);
|
||||
}
|
||||
|
||||
virtual void Tick(float deltaSeconds, Input previousInput, Input input) {}
|
||||
|
||||
RenderComponent *renderComponent = NULL;
|
||||
|
||||
struct CameraInfo {
|
||||
float fov = 90.0f;
|
||||
float aspect = 1024.0f / 768.0f;
|
||||
float near = 0.1f;
|
||||
float far = 100.0f;
|
||||
};
|
||||
CameraInfo camera;
|
||||
|
||||
hmm_mat4 projectionMatrix() {
|
||||
return HMM_Perspective(camera.fov, camera.aspect, camera.near, camera.far);
|
||||
}
|
||||
|
||||
hmm_mat4 viewMatrix() {
|
||||
return HMM_LookAt(worldPosition(), worldPosition() + forward(), up());
|
||||
}
|
||||
|
||||
hmm_vec3 worldPosition() {
|
||||
return (modelMatrix * HMM_Vec4(0.0f, 0.0f, 0.0f, 1.0f)).XYZ;
|
||||
}
|
||||
|
||||
hmm_vec3 up() {
|
||||
return (modelMatrix * HMM_Vec4(0.0f, 1.0f, 0.0f, 1.0f)).XYZ - worldPosition();
|
||||
}
|
||||
|
||||
hmm_vec3 forward() {
|
||||
return (modelMatrix * HMM_Vec4(1.0f, 0.0f, 0.0f, 1.0f)).XYZ - worldPosition();
|
||||
}
|
||||
|
||||
hmm_vec3 right() {
|
||||
return (modelMatrix * HMM_Vec4(0.0f, 0.0f, 1.0f, 1.0f)).XYZ - worldPosition();
|
||||
}
|
||||
|
||||
// Context for rendering and stuff
|
||||
hmm_mat4 parentModelMatrix;
|
||||
hmm_mat4 modelMatrix;
|
||||
};
|
||||
|
||||
class EntityIterator {
|
||||
public:
|
||||
typedef struct State {
|
||||
Entity *entity;
|
||||
int childIndex;
|
||||
|
||||
State(Entity *e) {
|
||||
entity = e;
|
||||
childIndex = -1;
|
||||
}
|
||||
} State;
|
||||
|
||||
EntityIterator(Entity *e) {
|
||||
stack.push_back(State(e));
|
||||
}
|
||||
|
||||
bool HasNext() {
|
||||
return !stack.empty();
|
||||
}
|
||||
|
||||
Entity *Next() {
|
||||
Entity *result = 0;
|
||||
|
||||
// Pass 1 - get a result by either grabbing the current entity or making another state
|
||||
while (true) {
|
||||
State *state = &stack.back();
|
||||
|
||||
if (state->childIndex < 0) {
|
||||
result = state->entity;
|
||||
state->childIndex = 0;
|
||||
break;
|
||||
} else {
|
||||
int nextIndex = state->childIndex;
|
||||
state->childIndex++;
|
||||
stack.push_back(State(state->entity->children[nextIndex]));
|
||||
}
|
||||
}
|
||||
|
||||
// Pass 2 - remove exhausted states from the stack
|
||||
while (!stack.empty()) {
|
||||
State state = stack.back();
|
||||
|
||||
if (state.childIndex >= state.entity->children.size()) {
|
||||
stack.pop_back();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<State> stack;
|
||||
};
|
||||
|
||||
#endif
|
||||
62
example/src/FPSCam.h
Normal file
62
example/src/FPSCam.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <stdio.h>
|
||||
#include <tgmath.h>
|
||||
|
||||
#ifndef HMME_FPSCAM_H
|
||||
#define HMME_FPSCAM_H
|
||||
|
||||
#include "Entity.h"
|
||||
#include "FollowCam.h"
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
class FPSCam : public Entity {
|
||||
public:
|
||||
FollowCam cam = FollowCam(0); // TODO: Why on earth is this necessary?? Remove this and fix the error.
|
||||
Entity target;
|
||||
|
||||
// all angles in radians
|
||||
float yaw = 0;
|
||||
float pitch = 0;
|
||||
float sensitivity = 0.002f;
|
||||
|
||||
FPSCam() {
|
||||
target = Entity();
|
||||
target.position = HMM_Vec3(0.0f, 0.0f, -1.0f);
|
||||
|
||||
cam = FollowCam(&target);
|
||||
|
||||
AddChild(&target);
|
||||
AddChild(&cam);
|
||||
}
|
||||
|
||||
void Tick(float deltaSeconds, Input previousInput, Input input) override {
|
||||
double deltaX = input.mouseX - previousInput.mouseX;
|
||||
double deltaY = input.mouseY - previousInput.mouseY;
|
||||
|
||||
// HACK: Pitch is being weird for reasons I don't understand. It works fine for
|
||||
// 360 degrees, then does something silly for 360 degrees, then repeats. I suspect
|
||||
// I'm just doing something wrong with quaternions because I know they encode twice
|
||||
// the angle or whatever. In any case, I've hacked around it for now to splice
|
||||
// together ranges that work.
|
||||
|
||||
yaw = yaw + (-deltaX * sensitivity);
|
||||
pitch = HMM_Clamp(-HMM_PI32 / 2, pitch + (-deltaY * sensitivity), HMM_PI32 / 2);
|
||||
|
||||
// HACK: MEGAHACK: why the heck is the apparent rotation twice what it should be?
|
||||
float hackyPitch = HMM_PI32;
|
||||
if (pitch > 0) {
|
||||
hackyPitch = HMM_PI32 + pitch / 2;
|
||||
} else if (pitch < 0) {
|
||||
hackyPitch = 2 * HMM_PI32 + pitch / 2;
|
||||
}
|
||||
printf("%f\t%f\n", pitch, hackyPitch);
|
||||
|
||||
hmm_quaternion rotationYaw = HMM_QuaternionFromAxisAngle(HMM_Vec3(0.0f, 1.0f, 0.0f), yaw);
|
||||
hmm_quaternion rotationPitch = HMM_QuaternionFromAxisAngle(HMM_Vec3(1.0f, 0.0f, 0.0f), hackyPitch);
|
||||
|
||||
rotation = rotationPitch * rotationYaw;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
71
example/src/FollowCam.h
Normal file
71
example/src/FollowCam.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef HMME_FOLLOWCAM_H
|
||||
#define HMME_FOLLOWCAM_H
|
||||
|
||||
#include "Entity.h"
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
class FollowCam : public Entity {
|
||||
public:
|
||||
Entity *target;
|
||||
|
||||
FollowCam(Entity *t) {
|
||||
target = t;
|
||||
}
|
||||
|
||||
void Tick(float deltaSeconds, Input previousInput, Input input) override {
|
||||
// TODO: Find a way to do this rotation routine in a single quaternion. Maybe that
|
||||
// just means finding a correct method, then doing some quaternion multiplication
|
||||
// on paper to see how the axis and angle shake out.
|
||||
|
||||
rotation = GetLookAtRotation();
|
||||
}
|
||||
|
||||
hmm_quaternion GetLookAtRotation() {
|
||||
hmm_vec3 fwd = (parentModelMatrix * HMM_Vec4(1.0f, 0.0f, 0.0f, 0.0f)).XYZ;
|
||||
hmm_vec3 up = (parentModelMatrix * HMM_Vec4(0.0f, 1.0f, 0.0f, 0.0f)).XYZ;
|
||||
hmm_vec3 to = target->worldPosition() - worldPosition();
|
||||
|
||||
hmm_vec3 pointAxis = HMM_Cross(fwd, to);
|
||||
hmm_quaternion justPointAt;
|
||||
|
||||
// TODO: proper epsilon! and probably implement some kind of nan
|
||||
// protection because a single nan ruins everything.
|
||||
if (HMM_ABS(HMM_Length(pointAxis)) < 0.0001f) {
|
||||
// Already pointing at the thing!
|
||||
justPointAt = HMM_Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
} else {
|
||||
justPointAt = HMM_QuaternionFromAxisAngle(
|
||||
pointAxis,
|
||||
HMM_ACosF(HMM_Dot(HMM_Normalize(fwd), HMM_Normalize(to)))
|
||||
);
|
||||
}
|
||||
|
||||
hmm_vec3 newUp = (HMM_QuaternionToMat4(justPointAt) * HMM_Vec4v(up, 0.0f)).XYZ;
|
||||
hmm_quaternion backUpright = HMM_QuaternionFromAxisAngle(
|
||||
to,
|
||||
// TODO: This angle is not quite right! After this corrective rotation,
|
||||
// the new up vector will *not* necessarily align with world up! So this
|
||||
// will overshoot a little bit.
|
||||
//
|
||||
// You should probably project the world up vector onto the plane of the
|
||||
// to vector before you do the dot product. This is a good opportunity to
|
||||
// add the vector projection stuff that we somehow have left out!
|
||||
-HMM_ACosF(HMM_Dot(HMM_Normalize(newUp), HMM_Vec3(0.0f, 1.0f, 0.0f)))
|
||||
);
|
||||
|
||||
return backUpright * justPointAt;
|
||||
|
||||
// BEN
|
||||
//
|
||||
// YOU MUST ALWAYS REMEMBER THAT QUATERNION MULTIPLICATION IS NOT COMMUTATIVE
|
||||
// AND THAT IT GOES RIGHT TO LEFT
|
||||
//
|
||||
// NEVER FORGET THIS LEST YOU SUFFER THROUGH THIS MESS AGAIN
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
2
example/src/HandmadeMath.cpp
Normal file
2
example/src/HandmadeMath.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
#define HANDMADE_MATH_IMPLEMENTATION
|
||||
#include <HandmadeMath.h>
|
||||
179
example/src/MeshRenderComponent.h
Normal file
179
example/src/MeshRenderComponent.h
Normal file
@@ -0,0 +1,179 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifndef HMME_MESH_RENDER_COMPONENT_H
|
||||
#define HMME_MESH_RENDER_COMPONENT_H
|
||||
|
||||
#include "tiny_obj_loader.h"
|
||||
|
||||
class MeshRenderComponent : public RenderComponent {
|
||||
public:
|
||||
bool didLoad = false;
|
||||
|
||||
struct Shape {
|
||||
GLuint vaoID = 0;
|
||||
GLuint vertexBufferID = 0;
|
||||
GLuint normalBufferID = 0;
|
||||
GLuint uvBufferID = 0;
|
||||
GLuint colorBufferID = 0;
|
||||
int numVerts = 0;
|
||||
};
|
||||
std::vector<Shape> renderShapes;
|
||||
|
||||
MeshRenderComponent(const char *filename) {
|
||||
// Load the model
|
||||
tinyobj::attrib_t attrib;
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
std::vector<tinyobj::material_t> materials;
|
||||
|
||||
std::string err;
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename);
|
||||
|
||||
if (!err.empty()) { // `err` may contain warning message.
|
||||
printf("Failed to load mesh: %s\n", err.c_str());
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto shape : shapes) {
|
||||
std::vector<tinyobj::real_t> vertices;
|
||||
std::vector<tinyobj::real_t> normals;
|
||||
std::vector<tinyobj::real_t> uvs;
|
||||
std::vector<tinyobj::real_t> colors;
|
||||
|
||||
for (auto indices : shape.mesh.indices) {
|
||||
if (indices.vertex_index > -1) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
int attribIndex = 3 * indices.vertex_index + i;
|
||||
vertices.push_back(attrib.vertices[attribIndex]);
|
||||
colors.push_back(attrib.colors[attribIndex]);
|
||||
}
|
||||
}
|
||||
if (indices.normal_index > -1) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
int attribIndex = 3 * indices.normal_index + i;
|
||||
normals.push_back(attrib.normals[attribIndex]);
|
||||
}
|
||||
}
|
||||
if (indices.texcoord_index > -1) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int attribIndex = 2 * indices.texcoord_index + i;
|
||||
uvs.push_back(attrib.texcoords[attribIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shape s; // the new shape to insert into our list
|
||||
|
||||
glGenVertexArrays(1, &s.vaoID);
|
||||
|
||||
if (!vertices.empty()) {
|
||||
glGenBuffers(1, &s.vertexBufferID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, s.vertexBufferID);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(tinyobj::real_t) * vertices.size(), &vertices.front(), GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &s.colorBufferID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, s.colorBufferID);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(tinyobj::real_t) * colors.size(), &colors.front(), GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
if (!normals.empty()) {
|
||||
glGenBuffers(1, &s.normalBufferID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, s.normalBufferID);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(tinyobj::real_t) * normals.size(), &normals.front(), GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
if (!uvs.empty()) {
|
||||
glGenBuffers(1, &s.uvBufferID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, s.uvBufferID);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(tinyobj::real_t) * uvs.size(), &uvs.front(), GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
s.numVerts = vertices.size() / 3;
|
||||
|
||||
renderShapes.push_back(s);
|
||||
}
|
||||
|
||||
didLoad = true;
|
||||
}
|
||||
|
||||
void Draw() override {
|
||||
if (!didLoad) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto s : renderShapes) {
|
||||
glBindVertexArray(s.vaoID);
|
||||
|
||||
// 1st attribute buffer : vertices
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, s.vertexBufferID);
|
||||
glVertexAttribPointer(
|
||||
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
|
||||
3, // size
|
||||
GL_FLOAT, // type
|
||||
GL_FALSE, // normalized?
|
||||
0, // stride
|
||||
(void*)0 // array buffer offset
|
||||
);
|
||||
|
||||
// 2nd attribute buffer : colors
|
||||
glEnableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, s.colorBufferID);
|
||||
glVertexAttribPointer(
|
||||
1, // attribute. No particular reason for 1, but must match the layout in the shader.
|
||||
3, // size
|
||||
GL_FLOAT, // type
|
||||
GL_FALSE, // normalized?
|
||||
0, // stride
|
||||
(void*)0 // array buffer offset
|
||||
);
|
||||
|
||||
if (s.normalBufferID != 0) {
|
||||
// 3rd attribute buffer : normals
|
||||
glEnableVertexAttribArray(2);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, s.normalBufferID);
|
||||
glVertexAttribPointer(
|
||||
2, // must match the layout in the shader
|
||||
3, // size
|
||||
GL_FLOAT, // type
|
||||
GL_FALSE, // normalized?
|
||||
0, // stride
|
||||
(void*)0 // array buffer offset
|
||||
);
|
||||
}
|
||||
|
||||
if (s.uvBufferID != 0) {
|
||||
// 4th attribute buffer : uvs
|
||||
glEnableVertexAttribArray(3);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, s.normalBufferID);
|
||||
glVertexAttribPointer(
|
||||
3, // must match the layout in the shader
|
||||
2, // size
|
||||
GL_FLOAT, // type
|
||||
GL_FALSE, // normalized?
|
||||
0, // stride
|
||||
(void*)0 // array buffer offset
|
||||
);
|
||||
}
|
||||
|
||||
// Shader??
|
||||
|
||||
// Draw the triangle!
|
||||
glDrawArrays(GL_TRIANGLES, 0, s.numVerts); // Starting from vertex 0; 3 vertices total -> 1 triangle
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
if (s.normalBufferID != 0) {
|
||||
glDisableVertexAttribArray(2);
|
||||
}
|
||||
if (s.uvBufferID != 0) {
|
||||
glDisableVertexAttribArray(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
13
example/src/RenderComponent.h
Normal file
13
example/src/RenderComponent.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <HandmadeMath.h>
|
||||
|
||||
#ifndef HMME_RENDER_COMPONENT_H
|
||||
#define HMME_RENDER_COMPONENT_H
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
class RenderComponent {
|
||||
public:
|
||||
virtual void Draw() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
28
example/src/debug.h
Normal file
28
example/src/debug.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
void printVec3(hmm_vec3 v) {
|
||||
printf("%f\t%f\t%f\n", v.X, v.Y, v.Z);
|
||||
}
|
||||
|
||||
void printVec4(hmm_vec4 v) {
|
||||
printf("%f\t%f\t%f\t%f\n", v.X, v.Y, v.Z, v.W);
|
||||
}
|
||||
|
||||
void printQuaternion(hmm_quaternion q) {
|
||||
printf("%f\t%f\t%f\t%f\n", q.X, q.Y, q.Z, q.W);
|
||||
}
|
||||
|
||||
void printMat4(hmm_mat4 m) {
|
||||
printf("/\n");
|
||||
for (int r = 0; r < 4; r++) {
|
||||
printf("| %f\t%f\t%f\t%f |\n", m[0][r], m[1][r], m[2][r], m[3][r]);
|
||||
}
|
||||
printf("\\\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
18
example/src/fragment.glsl
Normal file
18
example/src/fragment.glsl
Normal file
@@ -0,0 +1,18 @@
|
||||
#version 330 core
|
||||
|
||||
in vec3 fragmentPosition_world;
|
||||
in vec3 fragmentColor;
|
||||
in vec3 fragmentNormal_world;
|
||||
in vec2 fragmentUV;
|
||||
|
||||
out vec3 color;
|
||||
|
||||
void main() {
|
||||
vec3 ambient = vec3(0.1, 0.1, 0.1);
|
||||
|
||||
vec3 toLight_world = normalize(vec3(1, 1, 1));
|
||||
|
||||
float cosTheta = clamp(dot(normalize(fragmentNormal_world), toLight_world), 0.1, 1);
|
||||
|
||||
color = cosTheta * fragmentColor + ambient;
|
||||
}
|
||||
19
example/src/input.h
Normal file
19
example/src/input.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#ifndef HMME_INPUT_H
|
||||
#define HMME_INPUT_H
|
||||
|
||||
struct Input {
|
||||
double mouseX;
|
||||
double mouseY;
|
||||
};
|
||||
|
||||
Input GetInput(GLFWwindow *window) {
|
||||
Input i;
|
||||
|
||||
glfwGetCursorPos(window, &i.mouseX, &i.mouseY);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#endif
|
||||
190
example/src/main.cpp
Normal file
190
example/src/main.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
#include <stdio.h>
|
||||
#include <chrono>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <HandmadeMath.h>
|
||||
|
||||
#include "input.h"
|
||||
#include "shaders.h"
|
||||
|
||||
#include "Entity.h"
|
||||
#include "Cube.h"
|
||||
#include "MeshRenderComponent.h"
|
||||
#include "FPSCam.h"
|
||||
|
||||
void TickTree(Entity *e, float deltaSeconds, Input previousInput, Input input);
|
||||
void ComputeModelMatrices(Entity *ep, hmm_mat4 parentModelMatrix);
|
||||
void HandleMouseMove(GLFWwindow *window, double mouseX, double mouseY);
|
||||
|
||||
using std::chrono::high_resolution_clock;
|
||||
|
||||
#define WIDTH 1024
|
||||
#define HEIGHT 768
|
||||
|
||||
int main() {
|
||||
// Initialise GLFW
|
||||
glewExperimental = true; // Needed for core profile
|
||||
if (!glfwInit()) {
|
||||
fprintf( stderr, "Failed to initialize GLFW\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.3
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // We don't want the old OpenGL
|
||||
|
||||
// Open a window and create its OpenGL context
|
||||
GLFWwindow* window; // (In the accompanying source code, this variable is global for simplicity)
|
||||
window = glfwCreateWindow(WIDTH, HEIGHT, "Handmade Math Example", NULL, NULL);
|
||||
if (window == NULL) {
|
||||
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
glfwMakeContextCurrent(window); // Initialize GLEW
|
||||
glewExperimental=true; // Needed in core profile
|
||||
if (glewInit() != GLEW_OK) {
|
||||
fprintf(stderr, "Failed to initialize GLEW\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Ensure we can capture the escape key being pressed below
|
||||
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
|
||||
|
||||
// Hide the mouse cursor
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
// glfwSetCursorPos(window, WIDTH / 2, HEIGHT / 2);
|
||||
// glfwSetCursorPosCallback(window, [](GLFWwindow *window, double mouseX, double mouseY) {
|
||||
// printf("%f\t%f\n", mouseX, mouseY);
|
||||
// // glfwSetCursorPos(window, WIDTH / 2, HEIGHT / 2);
|
||||
// });
|
||||
|
||||
// Create and compile our GLSL program from the shaders
|
||||
GLuint programID = LoadShaders("src/vertex.glsl", "src/fragment.glsl");
|
||||
if (!programID) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get a handle for our "MVP" uniform
|
||||
// Only during the initialisation
|
||||
GLuint uniformID_M = glGetUniformLocation(programID, "M");
|
||||
GLuint uniformID_V = glGetUniformLocation(programID, "V");
|
||||
GLuint uniformID_MVP = glGetUniformLocation(programID, "MVP");
|
||||
|
||||
// Enable depth test
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
// Accept fragment if it closer to the camera than the former one
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
Cube c1 = Cube();
|
||||
|
||||
Entity monkey = Entity();
|
||||
monkey.position = HMM_Vec3(2.1f, 0.0f, 0.0f);
|
||||
monkey.renderComponent = new MeshRenderComponent("MonkeySmooth.obj");
|
||||
|
||||
Entity backmonkey = Entity();
|
||||
backmonkey.position = HMM_Vec3(0.0f, 0.0f, 5.0f);
|
||||
backmonkey.renderComponent = new MeshRenderComponent("MonkeySmooth.obj");
|
||||
|
||||
FPSCam fpsCam = FPSCam();
|
||||
fpsCam.position = HMM_Vec3(-1.0f, 1.0f, 3.0f);
|
||||
|
||||
Entity *cam = &fpsCam.cam;
|
||||
|
||||
// Cube c = Cube();
|
||||
// monkey.position = HMM_Vec3(2.1f, 0.0f, 0.0f);
|
||||
|
||||
// monkey.AddChild(&c);
|
||||
|
||||
c1.AddChild(&monkey);
|
||||
|
||||
Entity root = Entity();
|
||||
root.AddChild(&c1);
|
||||
root.AddChild(&fpsCam);
|
||||
root.AddChild(&backmonkey);
|
||||
|
||||
Entity axes = Entity();
|
||||
axes.renderComponent = new MeshRenderComponent("Axes.obj");
|
||||
root.AddChild(&axes);
|
||||
|
||||
bool hasTicked = false;
|
||||
high_resolution_clock::time_point lastTickTime;
|
||||
|
||||
Input previousInput = GetInput(window);
|
||||
|
||||
do {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Get inputs
|
||||
Input input = GetInput(window);
|
||||
|
||||
// Tick
|
||||
auto now = high_resolution_clock::now();
|
||||
if (hasTicked) {
|
||||
auto elapsedNanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(now - lastTickTime).count();
|
||||
float elapsedSeconds = elapsedNanoseconds / 1000000000.0f;
|
||||
TickTree(&root, elapsedSeconds, previousInput, input);
|
||||
}
|
||||
lastTickTime = now;
|
||||
hasTicked = true;
|
||||
previousInput = input;
|
||||
|
||||
// Compute model positions for rendering
|
||||
ComputeModelMatrices(&root, HMM_Mat4d(1.0f));
|
||||
|
||||
// Render!
|
||||
hmm_mat4 projection = cam->projectionMatrix();
|
||||
hmm_mat4 view = cam->viewMatrix();
|
||||
hmm_mat4 vp = projection * view;
|
||||
|
||||
auto it = EntityIterator(&root);
|
||||
while (it.HasNext()) {
|
||||
Entity *e = it.Next();
|
||||
|
||||
if (e->renderComponent) {
|
||||
// Use our shader
|
||||
glUseProgram(programID);
|
||||
|
||||
// Send uniforms
|
||||
glUniformMatrix4fv(uniformID_M, 1, GL_FALSE, &e->modelMatrix.Elements[0][0]);
|
||||
|
||||
glUniformMatrix4fv(uniformID_V, 1, GL_FALSE, &view.Elements[0][0]);
|
||||
|
||||
hmm_mat4 mvp = vp * e->modelMatrix;
|
||||
glUniformMatrix4fv(uniformID_MVP, 1, GL_FALSE, &mvp.Elements[0][0]);
|
||||
|
||||
e->renderComponent->Draw();
|
||||
}
|
||||
}
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
} while (
|
||||
// Check if the ESC key was pressed or the window was closed
|
||||
glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS
|
||||
&& glfwWindowShouldClose(window) == 0
|
||||
);
|
||||
}
|
||||
|
||||
void TickTree(Entity *e, float deltaSeconds, Input previousInput, Input input) {
|
||||
e->Tick(deltaSeconds, previousInput, input);
|
||||
|
||||
for (auto child : e->children) {
|
||||
TickTree(child, deltaSeconds, previousInput, input);
|
||||
}
|
||||
}
|
||||
|
||||
void ComputeModelMatrices(Entity *e, hmm_mat4 parentModelMatrix) {
|
||||
e->parentModelMatrix = parentModelMatrix;
|
||||
e->modelMatrix = parentModelMatrix * HMM_Translate(e->position) * HMM_QuaternionToMat4(e->rotation) * HMM_Scale(e->scale);
|
||||
|
||||
for (int i = 0; i < e->children.size(); i++) {
|
||||
ComputeModelMatrices(e->children[i], e->modelMatrix);
|
||||
}
|
||||
}
|
||||
94
example/src/shaders.cpp
Normal file
94
example/src/shaders.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include "shaders.h"
|
||||
|
||||
GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path) {
|
||||
// Create the shaders
|
||||
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
// Read the Vertex Shader code from the file
|
||||
std::string VertexShaderCode;
|
||||
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
|
||||
if(VertexShaderStream.is_open()){
|
||||
std::stringstream sstr;
|
||||
sstr << VertexShaderStream.rdbuf();
|
||||
VertexShaderCode = sstr.str();
|
||||
VertexShaderStream.close();
|
||||
}else{
|
||||
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read the Fragment Shader code from the file
|
||||
std::string FragmentShaderCode;
|
||||
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
|
||||
if(FragmentShaderStream.is_open()){
|
||||
std::stringstream sstr;
|
||||
sstr << FragmentShaderStream.rdbuf();
|
||||
FragmentShaderCode = sstr.str();
|
||||
FragmentShaderStream.close();
|
||||
}
|
||||
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
|
||||
// Compile Vertex Shader
|
||||
printf("Compiling shader : %s\n", vertex_file_path);
|
||||
char const * VertexSourcePointer = VertexShaderCode.c_str();
|
||||
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
|
||||
glCompileShader(VertexShaderID);
|
||||
|
||||
// Check Vertex Shader
|
||||
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
|
||||
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
if ( InfoLogLength > 0 ){
|
||||
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
|
||||
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
|
||||
printf("%s\n", &VertexShaderErrorMessage[0]);
|
||||
}
|
||||
|
||||
// Compile Fragment Shader
|
||||
printf("Compiling shader : %s\n", fragment_file_path);
|
||||
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
|
||||
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
|
||||
glCompileShader(FragmentShaderID);
|
||||
|
||||
// Check Fragment Shader
|
||||
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
|
||||
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
if ( InfoLogLength > 0 ){
|
||||
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
|
||||
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
|
||||
printf("%s\n", &FragmentShaderErrorMessage[0]);
|
||||
}
|
||||
|
||||
// Link the program
|
||||
printf("Linking program\n");
|
||||
GLuint ProgramID = glCreateProgram();
|
||||
glAttachShader(ProgramID, VertexShaderID);
|
||||
glAttachShader(ProgramID, FragmentShaderID);
|
||||
glLinkProgram(ProgramID);
|
||||
|
||||
// Check the program
|
||||
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
|
||||
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
if ( InfoLogLength > 0 ){
|
||||
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
|
||||
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
|
||||
printf("%s\n", &ProgramErrorMessage[0]);
|
||||
}
|
||||
|
||||
glDetachShader(ProgramID, VertexShaderID);
|
||||
glDetachShader(ProgramID, FragmentShaderID);
|
||||
|
||||
glDeleteShader(VertexShaderID);
|
||||
glDeleteShader(FragmentShaderID);
|
||||
|
||||
return ProgramID;
|
||||
}
|
||||
9
example/src/shaders.h
Normal file
9
example/src/shaders.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#ifndef HMME_SHADERS_H
|
||||
#define HMME_SHADERS_H
|
||||
|
||||
GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path);
|
||||
|
||||
#endif
|
||||
2
example/src/tiny_obj_loader.cpp
Normal file
2
example/src/tiny_obj_loader.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
#define TINYOBJLOADER_IMPLEMENTATION
|
||||
#include "tiny_obj_loader.h"
|
||||
2338
example/src/tiny_obj_loader.h
Normal file
2338
example/src/tiny_obj_loader.h
Normal file
File diff suppressed because it is too large
Load Diff
28
example/src/vertex.glsl
Normal file
28
example/src/vertex.glsl
Normal file
@@ -0,0 +1,28 @@
|
||||
#version 330 core
|
||||
|
||||
// These match the values in glVertexAttribPointer
|
||||
layout(location = 0) in vec3 vertexPosition_model;
|
||||
layout(location = 1) in vec3 vertexColor;
|
||||
layout(location = 2) in vec3 vertexNormal_model;
|
||||
layout(location = 3) in vec2 vertexUV;
|
||||
|
||||
uniform mat4 M;
|
||||
uniform mat4 V;
|
||||
uniform mat4 MVP;
|
||||
|
||||
out vec3 fragmentPosition_world;
|
||||
out vec3 fragmentColor;
|
||||
out vec3 fragmentNormal_world;
|
||||
out vec2 fragmentUV;
|
||||
|
||||
void main(){
|
||||
// Output position of the vertex, in clip space : MVP * position
|
||||
gl_Position = MVP * vec4(vertexPosition_model, 1);
|
||||
fragmentPosition_world = (M * vec4(vertexPosition_model, 1)).xyz;
|
||||
|
||||
fragmentColor = vertexColor;
|
||||
|
||||
fragmentNormal_world = (M * vec4(vertexNormal_model, 0)).xyz;
|
||||
|
||||
fragmentUV = vertexUV;
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
#ifndef WITHOUT_COVERAGE
|
||||
#include "HandmadeTest.h"
|
||||
#endif
|
||||
|
||||
#define HANDMADE_MATH_IMPLEMENTATION
|
||||
#define HANDMADE_MATH_NO_INLINE
|
||||
#include "../HandmadeMath.h"
|
||||
|
||||
@@ -4,46 +4,19 @@
|
||||
This is Handmade Math's test framework. It is fully compatible with both C
|
||||
and C++, although it requires some compiler-specific features.
|
||||
|
||||
To use Handmade Test, you must #define HANDMADE_TEST_IMPLEMENTATION in
|
||||
exactly one C or C++ file that includes the header, like this:
|
||||
|
||||
#define HANDMADE_TEST_IMPLEMENTATION
|
||||
#include "HandmadeTest.h"
|
||||
|
||||
The basic way of creating a test is using the TEST macro, which registers a
|
||||
single test to be run:
|
||||
|
||||
TEST(MyCategory, MyTestName) {
|
||||
TEST(MyCategory, MyTestName) {
|
||||
// test code, including asserts/expects
|
||||
}
|
||||
}
|
||||
|
||||
Handmade Test also provides macros you can use to check the coverage of
|
||||
important parts of your code. Define a coverage case by using the COVERAGE
|
||||
macro outside the function you wish to test, providing both a name and the
|
||||
number of asserts you expect to see covered over the course of your test.
|
||||
Then use the ASSERT_COVERED macro in every part of the function you wish to
|
||||
check coverage on. For example:
|
||||
The main function of your test code should then call hmt_run_all_tests and
|
||||
return the result:
|
||||
|
||||
COVERAGE(MyCoverageCase, 3)
|
||||
void MyFunction(int a, int b) {
|
||||
if (a > b) {
|
||||
ASSERT_COVERED(MyCoverageCase);
|
||||
return 10;
|
||||
} else if (a < b) {
|
||||
ASSERT_COVERED(MyCoverageCase);
|
||||
return -10;
|
||||
}
|
||||
|
||||
ASSERT_COVERED(MyCoverageCase);
|
||||
return 0;
|
||||
}
|
||||
|
||||
The main function of your test code should then call hmt_run_all_tests (and
|
||||
optionally hmt_check_all_coverage) and return the result:
|
||||
|
||||
int main() {
|
||||
return hmt_run_all_tests() || hmt_check_all_coverage();
|
||||
}
|
||||
int main() {
|
||||
return hmt_run_all_tests();
|
||||
}
|
||||
|
||||
=============================================================================
|
||||
|
||||
@@ -67,7 +40,7 @@
|
||||
#define HMT_RED "\033[31m"
|
||||
#define HMT_GREEN "\033[32m"
|
||||
|
||||
#define HMT_ARRAY_SIZE 1024
|
||||
#define HMT_INITIAL_ARRAY_SIZE 1024
|
||||
|
||||
typedef struct hmt_testresult_struct {
|
||||
int count_cases;
|
||||
@@ -84,188 +57,20 @@ typedef struct hmt_test_struct {
|
||||
typedef struct hmt_category_struct {
|
||||
const char* name;
|
||||
int num_tests;
|
||||
int tests_capacity;
|
||||
hmt_test* tests;
|
||||
} hmt_category;
|
||||
|
||||
typedef struct hmt_covercase_struct {
|
||||
const char* name;
|
||||
int expected_asserts;
|
||||
int actual_asserts;
|
||||
int* asserted_lines;
|
||||
} hmt_covercase;
|
||||
|
||||
hmt_category _hmt_new_category(const char* name);
|
||||
hmt_test _hmt_new_test(const char* name, hmt_test_func func);
|
||||
hmt_covercase _hmt_new_covercase(const char* name, int expected);
|
||||
void _hmt_register_test(const char* category, const char* name, hmt_test_func func);
|
||||
void _hmt_register_covercase(const char* name, const char* expected_asserts);
|
||||
void _hmt_count_cover(const char* name, int line);
|
||||
|
||||
#define _HMT_TEST_FUNCNAME(category, name) _hmt_test_ ## category ## _ ## name
|
||||
#define _HMT_TEST_FUNCNAME_INIT(category, name) _hmt_test_ ## category ## _ ## name ## _init
|
||||
#define _HMT_COVERCASE_FUNCNAME_INIT(name) _hmt_covercase_ ## name ## _init
|
||||
|
||||
#define HMT_TEST(category, name) \
|
||||
void _HMT_TEST_FUNCNAME(category, name)(hmt_testresult* _result); \
|
||||
INITIALIZER(_HMT_TEST_FUNCNAME_INIT(category, name)) { \
|
||||
_hmt_register_test(#category, #name, _HMT_TEST_FUNCNAME(category, name)); \
|
||||
} \
|
||||
void _HMT_TEST_FUNCNAME(category, name)(hmt_testresult* _result)
|
||||
|
||||
#define _HMT_CASE_START() \
|
||||
_result->count_cases++;
|
||||
|
||||
#define _HMT_CASE_FAIL() \
|
||||
_result->count_failures++; \
|
||||
printf("\n - " HMT_RED "[FAIL] (line %d) " HMT_RESET, __LINE__);
|
||||
|
||||
#define HMT_COVERAGE(name, num_asserts) \
|
||||
INITIALIZER(_HMT_COVERCASE_FUNCNAME_INIT(name)) { \
|
||||
_hmt_register_covercase(#name, #num_asserts); \
|
||||
} \
|
||||
|
||||
#define HMT_ASSERT_COVERED(name) \
|
||||
{ \
|
||||
_hmt_count_cover(#name, __LINE__); \
|
||||
} \
|
||||
|
||||
/*
|
||||
* Asserts and expects
|
||||
*/
|
||||
#define HMT_EXPECT_TRUE(_actual) { \
|
||||
_HMT_CASE_START(); \
|
||||
if (!(_actual)) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
printf("Expected true but got something false"); \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define HMT_EXPECT_FALSE(_actual) { \
|
||||
_HMT_CASE_START(); \
|
||||
if (_actual) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
printf("Expected false but got something true"); \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define HMT_EXPECT_FLOAT_EQ_MSG(_actual, _expected, _msg) { \
|
||||
_HMT_CASE_START(); \
|
||||
float actual = (_actual); \
|
||||
float diff = actual - (_expected); \
|
||||
if (diff < -FLT_EPSILON || FLT_EPSILON < diff) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
if ((_msg)[0] == 0) { \
|
||||
printf("Expected %f, got %f", (_expected), actual); \
|
||||
} else { \
|
||||
printf("%s: Expected %f, got %f", (_msg), (_expected), actual); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
#define HMT_EXPECT_FLOAT_EQ(_actual, _expected) HMT_EXPECT_FLOAT_EQ_MSG(_actual, _expected, "");
|
||||
|
||||
#define HMT_EXPECT_NEAR_MSG(_actual, _expected, _epsilon, _msg) { \
|
||||
_HMT_CASE_START(); \
|
||||
float actual = (_actual); \
|
||||
float diff = actual - (_expected); \
|
||||
if (diff < -(_epsilon) || (_epsilon) < diff) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
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) { \
|
||||
_HMT_CASE_START(); \
|
||||
if ((_actual) >= (_expected)) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
printf("Expected %f to be less than %f", (_actual), (_expected)); \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define HMT_EXPECT_GT(_actual, _expected) { \
|
||||
_HMT_CASE_START(); \
|
||||
if ((_actual) <= (_expected)) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
printf("Expected %f to be greater than %f", (_actual), (_expected)); \
|
||||
} \
|
||||
} \
|
||||
|
||||
#ifndef HMT_SAFE_MACROS
|
||||
// Friendly defines
|
||||
#define TEST(category, name) HMT_TEST(category, name)
|
||||
#define COVERAGE(name, expected_asserts) HMT_COVERAGE(name, expected_asserts)
|
||||
#define ASSERT_COVERED(name) HMT_ASSERT_COVERED(name)
|
||||
#define EXPECT_TRUE(_actual) HMT_EXPECT_TRUE(_actual)
|
||||
#define EXPECT_FALSE(_actual) HMT_EXPECT_FALSE(_actual)
|
||||
#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_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_GT(_actual, _expected) HMT_EXPECT_GT(_actual, _expected)
|
||||
#endif // HMT_SAFE_MACROS
|
||||
|
||||
#endif // HANDMADETEST_H
|
||||
|
||||
#ifdef HANDMADE_TEST_IMPLEMENTATION
|
||||
|
||||
#ifndef HANDMADE_TEST_IMPLEMENTATION_GUARD
|
||||
#define HANDMADE_TEST_IMPLEMENTATION_GUARD
|
||||
|
||||
int _hmt_num_categories = 0;
|
||||
hmt_category* _hmt_categories = 0;
|
||||
|
||||
int _hmt_num_covercases = 0;
|
||||
hmt_covercase* _hmt_covercases = 0;
|
||||
|
||||
int _hmt_num_covererrors = 0;
|
||||
int hmt_num_categories = 0;
|
||||
int hmt_category_capacity = HMT_INITIAL_ARRAY_SIZE;
|
||||
hmt_category* categories = 0;
|
||||
|
||||
hmt_category _hmt_new_category(const char* name) {
|
||||
hmt_category cat = {
|
||||
name, // name
|
||||
0, // num_tests
|
||||
(hmt_test*) malloc(HMT_ARRAY_SIZE * sizeof(hmt_test)), // tests
|
||||
.name = name,
|
||||
.num_tests = 0,
|
||||
.tests_capacity = HMT_INITIAL_ARRAY_SIZE,
|
||||
.tests = (hmt_test*) malloc(HMT_INITIAL_ARRAY_SIZE * sizeof(hmt_test))
|
||||
};
|
||||
|
||||
return cat;
|
||||
@@ -273,105 +78,59 @@ hmt_category _hmt_new_category(const char* name) {
|
||||
|
||||
hmt_test _hmt_new_test(const char* name, hmt_test_func func) {
|
||||
hmt_test test = {
|
||||
name, // name
|
||||
func, // func
|
||||
.name = name,
|
||||
.func = func
|
||||
};
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
hmt_covercase _hmt_new_covercase(const char* name, int expected) {
|
||||
hmt_covercase covercase = {
|
||||
name, // name
|
||||
expected, // expected_asserts
|
||||
0, // actual_asserts
|
||||
(int*) malloc(HMT_ARRAY_SIZE * sizeof(int)), // asserted_lines
|
||||
};
|
||||
|
||||
return covercase;
|
||||
}
|
||||
|
||||
void _hmt_register_test(const char* category, const char* name, hmt_test_func func) {
|
||||
int hmt_register_test(const char* category, const char* name, hmt_test_func func) {
|
||||
// initialize categories array if not initialized
|
||||
if (!_hmt_categories) {
|
||||
_hmt_categories = (hmt_category*) malloc(HMT_ARRAY_SIZE * sizeof(hmt_category));
|
||||
if (!categories) {
|
||||
categories = (hmt_category*) malloc(hmt_category_capacity * sizeof(hmt_category));
|
||||
}
|
||||
|
||||
// Find the matching category, if possible
|
||||
int cat_index;
|
||||
for (cat_index = 0; cat_index < _hmt_num_categories; cat_index++) {
|
||||
if (strcmp(_hmt_categories[cat_index].name, category) == 0) {
|
||||
for (cat_index = 0; cat_index < hmt_num_categories; cat_index++) {
|
||||
if (strcmp(categories[cat_index].name, category) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new category if necessary
|
||||
if (cat_index >= _hmt_num_categories) {
|
||||
_hmt_categories[cat_index] = _hmt_new_category(category);
|
||||
_hmt_num_categories++;
|
||||
// Expand the array of categories if necessary
|
||||
if (cat_index >= hmt_category_capacity) {
|
||||
// TODO: If/when we ever split HandmadeTest off into its own package,
|
||||
// we should start with a smaller initial capacity and dynamically expand.
|
||||
}
|
||||
|
||||
hmt_category* cat = &_hmt_categories[cat_index];
|
||||
// Add a new category if necessary
|
||||
if (cat_index >= hmt_num_categories) {
|
||||
categories[cat_index] = _hmt_new_category(category);
|
||||
hmt_num_categories++;
|
||||
}
|
||||
|
||||
hmt_category* cat = &categories[cat_index];
|
||||
|
||||
// Add the test to the category
|
||||
if (cat->num_tests >= cat->tests_capacity) {
|
||||
// TODO: If/when we ever split HandmadeTest off into its own package,
|
||||
// we should start with a smaller initial capacity and dynamically expand.
|
||||
}
|
||||
cat->tests[cat->num_tests] = _hmt_new_test(name, func);
|
||||
cat->num_tests++;
|
||||
}
|
||||
|
||||
void _hmt_register_covercase(const char* name, const char* expected_asserts) {
|
||||
// initialize cases array if not initialized
|
||||
if (!_hmt_covercases) {
|
||||
_hmt_covercases = (hmt_covercase*) malloc(HMT_ARRAY_SIZE * sizeof(hmt_covercase));
|
||||
}
|
||||
|
||||
// check for existing case with that name, because the macro can run multiple
|
||||
// times in different translation units
|
||||
for (int i = 0; i < _hmt_num_covercases; i++) {
|
||||
if (strcmp(_hmt_covercases[i].name, name) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_hmt_covercases[_hmt_num_covercases] = _hmt_new_covercase(name, atoi(expected_asserts));
|
||||
_hmt_num_covercases++;
|
||||
}
|
||||
|
||||
hmt_covercase* _hmt_find_covercase(const char* name) {
|
||||
for (int i = 0; i < _hmt_num_covercases; i++) {
|
||||
if (strcmp(_hmt_covercases[i].name, name) == 0) {
|
||||
return &_hmt_covercases[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _hmt_count_cover(const char* name, int line) {
|
||||
hmt_covercase* covercase = _hmt_find_covercase(name);
|
||||
if (covercase == 0) {
|
||||
printf(HMT_RED "ERROR (line %d): Could not find coverage case with name \"%s\".\n" HMT_RESET, line, name);
|
||||
_hmt_num_covererrors++;
|
||||
return;
|
||||
}
|
||||
|
||||
// see if this line has already been covered
|
||||
for (int i = 0; i < covercase->actual_asserts; i++) {
|
||||
if (covercase->asserted_lines[i] == line) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
covercase->asserted_lines[covercase->actual_asserts] = line;
|
||||
covercase->actual_asserts++;
|
||||
}
|
||||
|
||||
int hmt_run_all_tests() {
|
||||
int count_alltests = 0;
|
||||
int count_allfailedtests = 0; // failed test cases
|
||||
int count_allfailures = 0; // failed asserts
|
||||
|
||||
for (int i = 0; i < _hmt_num_categories; i++) {
|
||||
hmt_category cat = _hmt_categories[i];
|
||||
for (int i = 0; i < hmt_num_categories; i++) {
|
||||
hmt_category cat = categories[i];
|
||||
int count_catfailedtests = 0;
|
||||
int count_catfailures = 0;
|
||||
|
||||
@@ -383,8 +142,8 @@ int hmt_run_all_tests() {
|
||||
printf(" %s:", test.name);
|
||||
|
||||
hmt_testresult result = {
|
||||
0, // count_cases
|
||||
0, // count_failures
|
||||
.count_cases = 0,
|
||||
.count_failures = 0
|
||||
};
|
||||
test.func(&result);
|
||||
|
||||
@@ -418,38 +177,87 @@ int hmt_run_all_tests() {
|
||||
return (count_allfailedtests > 0);
|
||||
}
|
||||
|
||||
int hmt_check_all_coverage() {
|
||||
printf("Coverage:\n");
|
||||
#define _HMT_TEST_FUNCNAME(category, name) category ## _ ## name
|
||||
#define _HMT_TEST_FUNCNAME_INIT(category, name) category ## _ ## name ## _init
|
||||
|
||||
int count_failures = 0;
|
||||
#define HMT_TEST(category, name) \
|
||||
void _HMT_TEST_FUNCNAME(category, name)(hmt_testresult* _result); \
|
||||
INITIALIZER(_HMT_TEST_FUNCNAME_INIT(category, name)) { \
|
||||
hmt_register_test(#category, #name, _HMT_TEST_FUNCNAME(category, name)); \
|
||||
} \
|
||||
void _HMT_TEST_FUNCNAME(category, name)(hmt_testresult* _result)
|
||||
|
||||
for (int i = 0; i < _hmt_num_covercases; i++) {
|
||||
hmt_covercase covercase = _hmt_covercases[i];
|
||||
#define _HMT_CASE_START() \
|
||||
_result->count_cases++;
|
||||
|
||||
if (covercase.expected_asserts != covercase.actual_asserts) {
|
||||
count_failures++;
|
||||
printf("%s: " HMT_RED "FAIL (expected %d asserts, got %d)\n" HMT_RESET, covercase.name, covercase.expected_asserts, covercase.actual_asserts);
|
||||
}
|
||||
}
|
||||
#define _HMT_CASE_FAIL() \
|
||||
_result->count_failures++; \
|
||||
printf("\n - " HMT_RED "[FAIL] (%d) " HMT_RESET, __LINE__);
|
||||
|
||||
if (count_failures > 0) {
|
||||
printf("\n");
|
||||
printf(HMT_RED);
|
||||
} else {
|
||||
printf(HMT_GREEN);
|
||||
}
|
||||
printf("%d coverage cases tested, %d failures\n", _hmt_num_covercases, count_failures);
|
||||
printf(HMT_RESET);
|
||||
/*
|
||||
* Asserts and expects
|
||||
*/
|
||||
#define HMT_EXPECT_TRUE(_actual) do { \
|
||||
_HMT_CASE_START(); \
|
||||
if (!(_actual)) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
printf("Expected true but got something false"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
printf("\n");
|
||||
#define HMT_EXPECT_FALSE(_actual) do { \
|
||||
_HMT_CASE_START(); \
|
||||
if (_actual) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
printf("Expected false but got something true"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
if (_hmt_num_covererrors > 0) {
|
||||
printf(HMT_RED "There were %d other coverage errors; scroll up to see them.\n", _hmt_num_covererrors);
|
||||
return 1;
|
||||
}
|
||||
#define HMT_EXPECT_FLOAT_EQ(_actual, _expected) do { \
|
||||
_HMT_CASE_START(); \
|
||||
float actual = (_actual); \
|
||||
float diff = actual - (_expected); \
|
||||
if (diff < -FLT_EPSILON || FLT_EPSILON < diff) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
printf("Expected %f, got %f", (_expected), actual); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
return (count_failures > 0);
|
||||
}
|
||||
#define HMT_EXPECT_NEAR(_actual, _expected, _epsilon) do { \
|
||||
_HMT_CASE_START(); \
|
||||
float actual = (_actual); \
|
||||
float diff = actual - (_expected); \
|
||||
if (diff < -(_epsilon) || (_epsilon) < diff) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
printf("Expected %f, got %f", (_expected), actual); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif // HANDMADE_TEST_IMPLEMENTATION_GUARD
|
||||
#endif // HANDMADE_TEST_IMPLEMENTATION
|
||||
#define HMT_EXPECT_LT(_actual, _expected) do { \
|
||||
_HMT_CASE_START(); \
|
||||
if ((_actual) >= (_expected)) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
printf("Expected %f to be less than %f", (_actual), (_expected)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define HMT_EXPECT_GT(_actual, _expected) do { \
|
||||
_HMT_CASE_START(); \
|
||||
if ((_actual) <= (_expected)) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
printf("Expected %f to be greater than %f", (_actual), (_expected)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifndef HMT_SAFE_MACROS
|
||||
// Friendly defines
|
||||
#define TEST(category, name) HMT_TEST(category, name)
|
||||
#define EXPECT_TRUE(_actual) HMT_EXPECT_TRUE(_actual)
|
||||
#define EXPECT_FALSE(_actual) HMT_EXPECT_FALSE(_actual)
|
||||
#define EXPECT_FLOAT_EQ(_actual, _expected) HMT_EXPECT_FLOAT_EQ(_actual, _expected)
|
||||
#define EXPECT_NEAR(_actual, _expected, _epsilon) HMT_EXPECT_NEAR(_actual, _expected, _epsilon)
|
||||
#define EXPECT_LT(_actual, _expected) HMT_EXPECT_LT(_actual, _expected)
|
||||
#define EXPECT_GT(_actual, _expected) HMT_EXPECT_GT(_actual, _expected)
|
||||
#endif // HMT_SAFE_MACROS
|
||||
|
||||
#endif // HANDMADETEST_H
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
BUILD_DIR=./build
|
||||
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
|
||||
|
||||
all: c c_no_sse cpp cpp_no_sse build_c_without_coverage build_cpp_without_coverage
|
||||
|
||||
build_all: build_c build_c_no_sse build_cpp build_cpp_no_sse
|
||||
all: c c_no_sse cpp cpp_no_sse
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
|
||||
c: build_c
|
||||
$(BUILD_DIR)/hmm_test_c
|
||||
|
||||
build_c: HandmadeMath.c test_impl
|
||||
c: HandmadeMath.c test_impl
|
||||
@echo "\nCompiling in C mode"
|
||||
mkdir -p $(BUILD_DIR)
|
||||
cd $(BUILD_DIR)\
|
||||
@@ -21,10 +16,7 @@ build_c: HandmadeMath.c test_impl
|
||||
-lm \
|
||||
&& $(CC) -ohmm_test_c HandmadeMath.o hmm_test.o -lm
|
||||
|
||||
c_no_sse: build_c_no_sse
|
||||
$(BUILD_DIR)/hmm_test_c_no_sse
|
||||
|
||||
build_c_no_sse: HandmadeMath.c test_impl
|
||||
c_no_sse: HandmadeMath.c test_impl
|
||||
@echo "\nCompiling in C mode (no SSE)"
|
||||
mkdir -p $(BUILD_DIR)
|
||||
cd $(BUILD_DIR) \
|
||||
@@ -34,10 +26,7 @@ build_c_no_sse: HandmadeMath.c test_impl
|
||||
-lm \
|
||||
&& $(CC) -ohmm_test_c_no_sse HandmadeMath.o hmm_test.o -lm
|
||||
|
||||
cpp: build_cpp
|
||||
$(BUILD_DIR)/hmm_test_cpp
|
||||
|
||||
build_cpp: HandmadeMath.cpp test_impl
|
||||
cpp: HandmadeMath.cpp test_impl
|
||||
@echo "\nCompiling in C++ mode"
|
||||
mkdir -p $(BUILD_DIR)
|
||||
cd $(BUILD_DIR) \
|
||||
@@ -45,10 +34,7 @@ build_cpp: HandmadeMath.cpp test_impl
|
||||
-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
|
||||
cpp_no_sse: HandmadeMath.cpp test_impl
|
||||
@echo "\nCompiling in C++ mode (no SSE)"
|
||||
mkdir -p $(BUILD_DIR)
|
||||
cd $(BUILD_DIR) \
|
||||
@@ -57,22 +43,3 @@ build_cpp_no_sse: HandmadeMath.cpp test_impl
|
||||
../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)
|
||||
cd $(BUILD_DIR)\
|
||||
&& $(CC) $(CPPFLAGS) $(CXXFLAGS) -std=c99 \
|
||||
-DWITHOUT_COVERAGE \
|
||||
-c ../HandmadeMath.c ../hmm_test.c \
|
||||
-lm \
|
||||
&& $(CC) -ohmm_test_c HandmadeMath.o hmm_test.o -lm
|
||||
|
||||
build_cpp_without_coverage: 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 -DWITHOUT_COVERAGE \
|
||||
../HandmadeMath.cpp ../hmm_test.cpp
|
||||
|
||||
|
||||
@@ -4,13 +4,8 @@ You can compile and run the tests yourself by running:
|
||||
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
To run a specific test configuration, run one of:
|
||||
|
||||
```
|
||||
make c
|
||||
make c_no_sse
|
||||
make cpp
|
||||
make cpp_no_sse
|
||||
build/hmm_test_c
|
||||
build/hmm_test_c_no_sse
|
||||
build/hmm_test_cpp
|
||||
build/hmm_test_cpp_no_sse
|
||||
```
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
|
||||
TEST(Addition, Vec2)
|
||||
{
|
||||
HMM_Vec2 v2_1 = HMM_V2(1.0f, 2.0f);
|
||||
HMM_Vec2 v2_2 = HMM_V2(3.0f, 4.0f);
|
||||
hmm_vec2 v2_1 = HMM_Vec2(1.0f, 2.0f);
|
||||
hmm_vec2 v2_2 = HMM_Vec2(3.0f, 4.0f);
|
||||
|
||||
{
|
||||
HMM_Vec2 result = HMM_AddV2(v2_1, v2_2);
|
||||
hmm_vec2 result = HMM_AddVec2(v2_1, v2_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
}
|
||||
#ifdef __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.Y, 6.0f);
|
||||
}
|
||||
{
|
||||
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.Y, 6.0f);
|
||||
}
|
||||
@@ -30,24 +30,24 @@ TEST(Addition, Vec2)
|
||||
|
||||
TEST(Addition, Vec3)
|
||||
{
|
||||
HMM_Vec3 v3_1 = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
HMM_Vec3 v3_2 = HMM_V3(4.0f, 5.0f, 6.0f);
|
||||
hmm_vec3 v3_1 = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec3 v3_2 = HMM_Vec3(4.0f, 5.0f, 6.0f);
|
||||
|
||||
{
|
||||
HMM_Vec3 result = HMM_AddV3(v3_1, v3_2);
|
||||
hmm_vec3 result = HMM_AddVec3(v3_1, v3_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 5.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 7.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||
}
|
||||
#ifdef __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.Y, 7.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||
}
|
||||
{
|
||||
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.Y, 7.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||
@@ -62,11 +62,11 @@ TEST(Addition, Vec3)
|
||||
|
||||
TEST(Addition, Vec4)
|
||||
{
|
||||
HMM_Vec4 v4_1 = HMM_V4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Vec4 v4_2 = HMM_V4(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
hmm_vec4 v4_1 = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_vec4 v4_2 = HMM_Vec4(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
|
||||
{
|
||||
HMM_Vec4 result = HMM_AddV4(v4_1, v4_2);
|
||||
hmm_vec4 result = HMM_AddVec4(v4_1, v4_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
@@ -74,14 +74,14 @@ TEST(Addition, Vec4)
|
||||
}
|
||||
#ifdef __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.Y, 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
||||
}
|
||||
{
|
||||
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.Y, 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
@@ -96,134 +96,10 @@ TEST(Addition, Vec4)
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Addition, Mat2)
|
||||
{
|
||||
HMM_Mat2 a = HMM_M2();
|
||||
HMM_Mat2 b = HMM_M2();
|
||||
|
||||
int Counter = 1;
|
||||
for (int Column = 0; Column < 2; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 2; ++Row)
|
||||
{
|
||||
a.Elements[Column][Row] = Counter++;
|
||||
}
|
||||
}
|
||||
for (int Column = 0; Column < 2; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 2; ++Row)
|
||||
{
|
||||
b.Elements[Column][Row] = Counter++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat2 result = HMM_AddM2(a, b);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 12.0f);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat2 result = HMM_Add(a, b);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 12.0f);
|
||||
}
|
||||
{
|
||||
HMM_Mat2 result = a + b;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 12.0f);
|
||||
}
|
||||
a += b;
|
||||
EXPECT_FLOAT_EQ(a.Elements[0][0], 6.0f);
|
||||
EXPECT_FLOAT_EQ(a.Elements[0][1], 8.0f);
|
||||
EXPECT_FLOAT_EQ(a.Elements[1][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(a.Elements[1][1], 12.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Addition, Mat3)
|
||||
{
|
||||
HMM_Mat3 a = HMM_M3();
|
||||
HMM_Mat3 b = HMM_M3();
|
||||
|
||||
int Counter = 1;
|
||||
for (int Column = 0; Column < 3; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 3; ++Row)
|
||||
{
|
||||
a.Elements[Column][Row] = Counter++;
|
||||
}
|
||||
}
|
||||
for (int Column = 0; Column < 3; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 3; ++Row)
|
||||
{
|
||||
b.Elements[Column][Row] = Counter++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat3 result = HMM_AddM3(a, b);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 11.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 13.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 15.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 17.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 19.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 21.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 23.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 25.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 27.0f);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat3 result = HMM_Add(a, b);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 11.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 13.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 15.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 17.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 19.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 21.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 23.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 25.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 27.0f);
|
||||
}
|
||||
{
|
||||
HMM_Mat3 result = a + b;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 11.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 13.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 15.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 17.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 19.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 21.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 23.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 25.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 27.0f);
|
||||
}
|
||||
a += b;
|
||||
EXPECT_FLOAT_EQ(a.Elements[0][0], 11.0f);
|
||||
EXPECT_FLOAT_EQ(a.Elements[0][1], 13.0f);
|
||||
EXPECT_FLOAT_EQ(a.Elements[0][2], 15.0f);
|
||||
EXPECT_FLOAT_EQ(a.Elements[1][0], 17.0f);
|
||||
EXPECT_FLOAT_EQ(a.Elements[1][1], 19.0f);
|
||||
EXPECT_FLOAT_EQ(a.Elements[1][2], 21.0f);
|
||||
EXPECT_FLOAT_EQ(a.Elements[2][0], 23.0f);
|
||||
EXPECT_FLOAT_EQ(a.Elements[2][1], 25.0f);
|
||||
EXPECT_FLOAT_EQ(a.Elements[2][2], 27.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Addition, Mat4)
|
||||
{
|
||||
HMM_Mat4 m4_1 = HMM_M4(); // will have 1 - 16
|
||||
HMM_Mat4 m4_2 = HMM_M4(); // will have 17 - 32
|
||||
hmm_mat4 m4_1 = HMM_Mat4(); // will have 1 - 16
|
||||
hmm_mat4 m4_2 = HMM_Mat4(); // will have 17 - 32
|
||||
|
||||
// Fill the matrices
|
||||
int Counter = 1;
|
||||
@@ -246,7 +122,7 @@ TEST(Addition, Mat4)
|
||||
|
||||
// Test the results
|
||||
{
|
||||
HMM_Mat4 result = HMM_AddM4(m4_1, m4_2);
|
||||
hmm_mat4 result = HMM_AddMat4(m4_1, m4_2);
|
||||
float Expected = 18.0f;
|
||||
for (int Column = 0; Column < 4; ++Column)
|
||||
{
|
||||
@@ -259,7 +135,7 @@ TEST(Addition, Mat4)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat4 result = HMM_Add(m4_1, m4_2);
|
||||
hmm_mat4 result = HMM_Add(m4_1, m4_2);
|
||||
float Expected = 18.0f;
|
||||
for (int Column = 0; Column < 4; ++Column)
|
||||
{
|
||||
@@ -271,7 +147,7 @@ TEST(Addition, Mat4)
|
||||
}
|
||||
}
|
||||
{
|
||||
HMM_Mat4 result = m4_1 + m4_2;
|
||||
hmm_mat4 result = m4_1 + m4_2;
|
||||
float Expected = 18.0f;
|
||||
for (int Column = 0; Column < 4; ++Column)
|
||||
{
|
||||
@@ -298,11 +174,11 @@ TEST(Addition, Mat4)
|
||||
|
||||
TEST(Addition, Quaternion)
|
||||
{
|
||||
HMM_Quat q1 = HMM_Q(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Quat q2 = HMM_Q(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
hmm_quaternion q1 = HMM_Quaternion(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_quaternion q2 = HMM_Quaternion(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
|
||||
{
|
||||
HMM_Quat result = HMM_AddQ(q1, q2);
|
||||
hmm_quaternion result = HMM_AddQuaternion(q1, q2);
|
||||
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
@@ -310,14 +186,14 @@ TEST(Addition, Quaternion)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Quat result = HMM_Add(q1, q2);
|
||||
hmm_quaternion result = HMM_Add(q1, q2);
|
||||
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
||||
}
|
||||
{
|
||||
HMM_Quat result = q1 + q2;
|
||||
hmm_quaternion result = q1 + q2;
|
||||
EXPECT_FLOAT_EQ(result.X, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
|
||||
TEST(Division, Vec2Vec2)
|
||||
{
|
||||
HMM_Vec2 v2_1 = HMM_V2(1.0f, 3.0f);
|
||||
HMM_Vec2 v2_2 = HMM_V2(2.0f, 4.0f);
|
||||
hmm_vec2 v2_1 = HMM_Vec2(1.0f, 3.0f);
|
||||
hmm_vec2 v2_2 = HMM_Vec2(2.0f, 4.0f);
|
||||
|
||||
{
|
||||
HMM_Vec2 result = HMM_DivV2(v2_1, v2_2);
|
||||
hmm_vec2 result = HMM_DivideVec2(v2_1, v2_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec2 result = HMM_Div(v2_1, v2_2);
|
||||
hmm_vec2 result = HMM_Divide(v2_1, v2_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
||||
}
|
||||
{
|
||||
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.Y, 0.75f);
|
||||
}
|
||||
@@ -30,22 +30,22 @@ TEST(Division, Vec2Vec2)
|
||||
|
||||
TEST(Division, Vec2Scalar)
|
||||
{
|
||||
HMM_Vec2 v2 = HMM_V2(1.0f, 2.0f);
|
||||
hmm_vec2 v2 = HMM_Vec2(1.0f, 2.0f);
|
||||
float s = 2;
|
||||
|
||||
{
|
||||
HMM_Vec2 result = HMM_DivV2F(v2, s);
|
||||
hmm_vec2 result = HMM_DivideVec2f(v2, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec2 result = HMM_Div(v2, s);
|
||||
hmm_vec2 result = HMM_Divide(v2, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec2 result = v2 / s;
|
||||
hmm_vec2 result = v2 / s;
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
}
|
||||
@@ -58,24 +58,24 @@ TEST(Division, Vec2Scalar)
|
||||
|
||||
TEST(Division, Vec3Vec3)
|
||||
{
|
||||
HMM_Vec3 v3_1 = HMM_V3(1.0f, 3.0f, 5.0f);
|
||||
HMM_Vec3 v3_2 = HMM_V3(2.0f, 4.0f, 0.5f);
|
||||
hmm_vec3 v3_1 = HMM_Vec3(1.0f, 3.0f, 5.0f);
|
||||
hmm_vec3 v3_2 = HMM_Vec3(2.0f, 4.0f, 0.5f);
|
||||
|
||||
{
|
||||
HMM_Vec3 result = HMM_DivV3(v3_1, v3_2);
|
||||
hmm_vec3 result = HMM_DivideVec3(v3_1, v3_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec3 result = HMM_Div(v3_1, v3_2);
|
||||
hmm_vec3 result = HMM_Divide(v3_1, v3_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
}
|
||||
{
|
||||
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.Y, 0.75f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
@@ -90,24 +90,24 @@ TEST(Division, Vec3Vec3)
|
||||
|
||||
TEST(Division, Vec3Scalar)
|
||||
{
|
||||
HMM_Vec3 v3 = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec3 v3 = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
float s = 2;
|
||||
|
||||
{
|
||||
HMM_Vec3 result = HMM_DivV3F(v3, s);
|
||||
hmm_vec3 result = HMM_DivideVec3f(v3, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec3 result = HMM_Div(v3, s);
|
||||
hmm_vec3 result = HMM_Divide(v3, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||
}
|
||||
{
|
||||
HMM_Vec3 result = v3 / s;
|
||||
hmm_vec3 result = v3 / s;
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||
@@ -122,11 +122,11 @@ TEST(Division, Vec3Scalar)
|
||||
|
||||
TEST(Division, Vec4Vec4)
|
||||
{
|
||||
HMM_Vec4 v4_1 = HMM_V4(1.0f, 3.0f, 5.0f, 1.0f);
|
||||
HMM_Vec4 v4_2 = HMM_V4(2.0f, 4.0f, 0.5f, 4.0f);
|
||||
hmm_vec4 v4_1 = HMM_Vec4(1.0f, 3.0f, 5.0f, 1.0f);
|
||||
hmm_vec4 v4_2 = HMM_Vec4(2.0f, 4.0f, 0.5f, 4.0f);
|
||||
|
||||
{
|
||||
HMM_Vec4 result = HMM_DivV4(v4_1, v4_2);
|
||||
hmm_vec4 result = HMM_DivideVec4(v4_1, v4_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
@@ -134,14 +134,14 @@ TEST(Division, Vec4Vec4)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec4 result = HMM_Div(v4_1, v4_2);
|
||||
hmm_vec4 result = HMM_Divide(v4_1, v4_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.75f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, 0.25f);
|
||||
}
|
||||
{
|
||||
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.Y, 0.75f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 10.0f);
|
||||
@@ -158,11 +158,11 @@ TEST(Division, Vec4Vec4)
|
||||
|
||||
TEST(Division, Vec4Scalar)
|
||||
{
|
||||
HMM_Vec4 v4 = HMM_V4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_vec4 v4 = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
float s = 2;
|
||||
|
||||
{
|
||||
HMM_Vec4 result = HMM_DivV4F(v4, s);
|
||||
hmm_vec4 result = HMM_DivideVec4f(v4, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||
@@ -170,14 +170,14 @@ TEST(Division, Vec4Scalar)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec4 result = HMM_Div(v4, s);
|
||||
hmm_vec4 result = HMM_Divide(v4, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||
EXPECT_FLOAT_EQ(result.W, 2.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec4 result = v4 / s;
|
||||
hmm_vec4 result = v4 / s;
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||
@@ -192,103 +192,9 @@ TEST(Division, Vec4Scalar)
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Division, Mat2Scalar)
|
||||
{
|
||||
HMM_Mat2 m = HMM_M2();
|
||||
float s = 0.5f;
|
||||
|
||||
int Counter = 1;
|
||||
for (int Column = 0; Column < 2; ++Column) {
|
||||
for (int Row = 0; Row < 2; ++Row) {
|
||||
m.Elements[Column][Row] = Counter++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat2 result = HMM_DivM2F(m, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 8.0f);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat2 result = HMM_Div(m, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 8.0f);
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat2 result = m / s;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 8.0f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TEST(Division, Mat3Scalar)
|
||||
{
|
||||
HMM_Mat3 m = HMM_M3();
|
||||
float s = 0.5f;
|
||||
|
||||
int Counter = 1;
|
||||
for (int Column = 0; Column < 3; ++Column) {
|
||||
for (int Row = 0; Row < 3; ++Row) {
|
||||
m.Elements[Column][Row] = Counter++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat3 result = HMM_DivM3F(m, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 12.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 14.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 16.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 18.0f);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat3 result = HMM_Div(m, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 12.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 14.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 16.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 18.0f);
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat3 result = m / s;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 12.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 14.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 16.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 18.0f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Division, Mat4Scalar)
|
||||
{
|
||||
HMM_Mat4 m4 = HMM_M4(); // will have 1 - 16
|
||||
hmm_mat4 m4 = HMM_Mat4(); // will have 1 - 16
|
||||
float s = 2;
|
||||
|
||||
// Fill the matrix
|
||||
@@ -304,7 +210,7 @@ TEST(Division, Mat4Scalar)
|
||||
|
||||
// Test the results
|
||||
{
|
||||
HMM_Mat4 result = HMM_DivM4F(m4, s);
|
||||
hmm_mat4 result = HMM_DivideMat4f(m4, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 1.5f);
|
||||
@@ -324,7 +230,7 @@ TEST(Division, Mat4Scalar)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat4 result = HMM_Div(m4, s);
|
||||
hmm_mat4 result = HMM_Divide(m4, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 1.5f);
|
||||
@@ -343,7 +249,7 @@ TEST(Division, Mat4Scalar)
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 8.0f);
|
||||
}
|
||||
{
|
||||
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][1], 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 1.5f);
|
||||
@@ -384,11 +290,11 @@ TEST(Division, Mat4Scalar)
|
||||
|
||||
TEST(Division, QuaternionScalar)
|
||||
{
|
||||
HMM_Quat q = HMM_Q(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_quaternion q = HMM_Quaternion(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
float f = 2.0f;
|
||||
|
||||
{
|
||||
HMM_Quat result = HMM_DivQF(q, f);
|
||||
hmm_quaternion result = HMM_DivideQuaternionF(q, f);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||
@@ -396,14 +302,14 @@ TEST(Division, QuaternionScalar)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Quat result = HMM_Div(q, f);
|
||||
hmm_quaternion result = HMM_Divide(q, f);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||
EXPECT_FLOAT_EQ(result.W, 2.0f);
|
||||
}
|
||||
{
|
||||
HMM_Quat result = q / f;
|
||||
hmm_quaternion result = q / f;
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 1.5f);
|
||||
|
||||
@@ -2,63 +2,54 @@
|
||||
|
||||
TEST(Equality, Vec2)
|
||||
{
|
||||
HMM_Vec2 a = HMM_V2(1.0f, 2.0f);
|
||||
HMM_Vec2 b = HMM_V2(1.0f, 2.0f);
|
||||
HMM_Vec2 c = HMM_V2(3.0f, 4.0f);
|
||||
hmm_vec2 a = HMM_Vec2(1.0f, 2.0f);
|
||||
hmm_vec2 b = HMM_Vec2(1.0f, 2.0f);
|
||||
hmm_vec2 c = HMM_Vec2(3.0f, 4.0f);
|
||||
|
||||
EXPECT_TRUE(HMM_EqV2(a, b));
|
||||
EXPECT_FALSE(HMM_EqV2(a, c));
|
||||
EXPECT_TRUE(HMM_EqualsVec2(a, b));
|
||||
EXPECT_FALSE(HMM_EqualsVec2(a, c));
|
||||
|
||||
#ifdef __cplusplus
|
||||
EXPECT_TRUE(HMM_Eq(a, b));
|
||||
EXPECT_FALSE(HMM_Eq(a, c));
|
||||
EXPECT_TRUE(HMM_Equals(a, b));
|
||||
EXPECT_FALSE(HMM_Equals(a, c));
|
||||
|
||||
EXPECT_TRUE(a == b);
|
||||
EXPECT_FALSE(a == c);
|
||||
|
||||
EXPECT_FALSE(a != b);
|
||||
EXPECT_TRUE(a != c);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Equality, Vec3)
|
||||
{
|
||||
HMM_Vec3 a = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
HMM_Vec3 b = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
HMM_Vec3 c = HMM_V3(4.0f, 5.0f, 6.0f);
|
||||
hmm_vec3 a = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec3 b = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec3 c = HMM_Vec3(4.0f, 5.0f, 6.0f);
|
||||
|
||||
EXPECT_TRUE(HMM_EqV3(a, b));
|
||||
EXPECT_FALSE(HMM_EqV3(a, c));
|
||||
EXPECT_TRUE(HMM_EqualsVec3(a, b));
|
||||
EXPECT_FALSE(HMM_EqualsVec3(a, c));
|
||||
|
||||
#ifdef __cplusplus
|
||||
EXPECT_TRUE(HMM_Eq(a, b));
|
||||
EXPECT_FALSE(HMM_Eq(a, c));
|
||||
EXPECT_TRUE(HMM_Equals(a, b));
|
||||
EXPECT_FALSE(HMM_Equals(a, c));
|
||||
|
||||
EXPECT_TRUE(a == b);
|
||||
EXPECT_FALSE(a == c);
|
||||
|
||||
EXPECT_FALSE(a != b);
|
||||
EXPECT_TRUE(a != c);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Equality, Vec4)
|
||||
{
|
||||
HMM_Vec4 a = HMM_V4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Vec4 b = HMM_V4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Vec4 c = HMM_V4(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
hmm_vec4 a = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_vec4 b = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_vec4 c = HMM_Vec4(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
|
||||
EXPECT_TRUE(HMM_EqV4(a, b));
|
||||
EXPECT_FALSE(HMM_EqV4(a, c));
|
||||
EXPECT_TRUE(HMM_EqualsVec4(a, b));
|
||||
EXPECT_FALSE(HMM_EqualsVec4(a, c));
|
||||
|
||||
#ifdef __cplusplus
|
||||
EXPECT_TRUE(HMM_Eq(a, b));
|
||||
EXPECT_FALSE(HMM_Eq(a, c));
|
||||
EXPECT_TRUE(HMM_Equals(a, b));
|
||||
EXPECT_FALSE(HMM_Equals(a, c));
|
||||
|
||||
EXPECT_TRUE(a == b);
|
||||
EXPECT_FALSE(a == c);
|
||||
|
||||
EXPECT_FALSE(a != b);
|
||||
EXPECT_TRUE(a != c);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ TEST(Initialization, Vectors)
|
||||
//
|
||||
// Test vec2
|
||||
//
|
||||
HMM_Vec2 v2 = HMM_V2(1.0f, 2.0f);
|
||||
hmm_vec2 v2 = HMM_Vec2(1.0f, 2.0f);
|
||||
hmm_vec2 v2i = HMM_Vec2(1, 2);
|
||||
|
||||
EXPECT_FLOAT_EQ(v2.X, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v2.Y, 2.0f);
|
||||
@@ -22,10 +23,26 @@ TEST(Initialization, Vectors)
|
||||
EXPECT_FLOAT_EQ(v2[1], 2.0f);
|
||||
#endif
|
||||
|
||||
EXPECT_FLOAT_EQ(v2i.X, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v2i.Y, 2.0f);
|
||||
EXPECT_FLOAT_EQ(v2i.U, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v2i.V, 2.0f);
|
||||
EXPECT_FLOAT_EQ(v2i.Left, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v2i.Right, 2.0f);
|
||||
EXPECT_FLOAT_EQ(v2i.Width, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v2i.Height, 2.0f);
|
||||
EXPECT_FLOAT_EQ(v2i.Elements[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v2i.Elements[1], 2.0f);
|
||||
#ifdef __cplusplus
|
||||
EXPECT_FLOAT_EQ(v2i[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v2i[1], 2.0f);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Test vec3
|
||||
//
|
||||
HMM_Vec3 v3 = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec3 v3 = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec3 v3i = HMM_Vec3i(1, 2, 3);
|
||||
|
||||
EXPECT_FLOAT_EQ(v3.X, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v3.Y, 2.0f);
|
||||
@@ -53,11 +70,38 @@ TEST(Initialization, Vectors)
|
||||
EXPECT_FLOAT_EQ(v3[2], 3.0f);
|
||||
#endif
|
||||
|
||||
EXPECT_FLOAT_EQ(v3i.X, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.Y, 2.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.Z, 3.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.U, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.V, 2.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.W, 3.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.R, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.G, 2.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.B, 3.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.Elements[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.Elements[1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.Elements[2], 3.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.XY.Elements[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.XY.Elements[1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.YZ.Elements[0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.YZ.Elements[1], 3.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.UV.Elements[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.UV.Elements[1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.VW.Elements[0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v3i.VW.Elements[1], 3.0f);
|
||||
#ifdef __cplusplus
|
||||
EXPECT_FLOAT_EQ(v3i[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v3i[1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v3i[2], 3.0f);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Test vec4
|
||||
//
|
||||
HMM_Vec4 v4 = HMM_V4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Vec4 v4v = HMM_V4V(v3, 4.0f);
|
||||
hmm_vec4 v4 = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_vec4 v4i = HMM_Vec4i(1, 2, 3, 4);
|
||||
hmm_vec4 v4v = HMM_Vec4v(v3, 4.0f);
|
||||
|
||||
EXPECT_FLOAT_EQ(v4.X, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v4.Y, 2.0f);
|
||||
@@ -88,6 +132,35 @@ TEST(Initialization, Vectors)
|
||||
EXPECT_FLOAT_EQ(v4[3], 4.0f);
|
||||
#endif
|
||||
|
||||
EXPECT_FLOAT_EQ(v4i.X, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.Y, 2.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.Z, 3.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.W, 4.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.R, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.G, 2.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.B, 3.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.A, 4.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.XY.Elements[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.XY.Elements[1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.YZ.Elements[0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.YZ.Elements[1], 3.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.ZW.Elements[0], 3.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.ZW.Elements[1], 4.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.XY.Elements[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.XY.Elements[1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.XYZ.Elements[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.XYZ.Elements[1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.XYZ.Elements[2], 3.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.RGB.Elements[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.RGB.Elements[1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v4i.RGB.Elements[2], 3.0f);
|
||||
#ifdef __cplusplus
|
||||
EXPECT_FLOAT_EQ(v4i[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v4i[1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v4i[2], 3.0f);
|
||||
EXPECT_FLOAT_EQ(v4i[3], 4.0f);
|
||||
#endif
|
||||
|
||||
EXPECT_FLOAT_EQ(v4v.X, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v4v.Y, 2.0f);
|
||||
EXPECT_FLOAT_EQ(v4v.Z, 3.0f);
|
||||
@@ -120,40 +193,7 @@ TEST(Initialization, Vectors)
|
||||
|
||||
TEST(Initialization, MatrixEmpty)
|
||||
{
|
||||
//
|
||||
// Test mat2
|
||||
//
|
||||
HMM_Mat2 m2 = HMM_M2();
|
||||
for (int Column = 0; Column < 2; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 2; ++Row)
|
||||
{
|
||||
EXPECT_FLOAT_EQ(m2.Elements[Column][Row], 0.0f);
|
||||
#ifdef __cplusplus
|
||||
EXPECT_FLOAT_EQ(m2[Column][Row], 0.0f);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Test mat3
|
||||
//
|
||||
HMM_Mat3 m3 = HMM_M3();
|
||||
for (int Column = 0; Column < 3; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 3; ++Row)
|
||||
{
|
||||
EXPECT_FLOAT_EQ(m3.Elements[Column][Row], 0.0f);
|
||||
#ifdef __cplusplus
|
||||
EXPECT_FLOAT_EQ(m3[Column][Row], 0.0f);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Test mat4
|
||||
//
|
||||
HMM_Mat4 m4 = HMM_M4();
|
||||
hmm_mat4 m4 = HMM_Mat4();
|
||||
for (int Column = 0; Column < 4; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 4; ++Row)
|
||||
@@ -168,42 +208,7 @@ TEST(Initialization, MatrixEmpty)
|
||||
|
||||
TEST(Initialization, MatrixDiagonal)
|
||||
{
|
||||
//
|
||||
// Test mat2
|
||||
//
|
||||
HMM_Mat2 m2d = HMM_M2D(1.0f);
|
||||
for (int Column = 0; Column < 2; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 2; ++Row)
|
||||
{
|
||||
if (Column == Row) {
|
||||
EXPECT_FLOAT_EQ(m2d.Elements[Column][Row], 1.0f);
|
||||
} else {
|
||||
EXPECT_FLOAT_EQ(m2d.Elements[Column][Row], 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Test mat3
|
||||
//
|
||||
HMM_Mat3 m3d = HMM_M3D(1.0f);
|
||||
for (int Column = 0; Column < 3; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 3; ++Row)
|
||||
{
|
||||
if (Column == Row) {
|
||||
EXPECT_FLOAT_EQ(m3d.Elements[Column][Row], 1.0f);
|
||||
} else {
|
||||
EXPECT_FLOAT_EQ(m3d.Elements[Column][Row], 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Test mat4
|
||||
//
|
||||
HMM_Mat4 m4d = HMM_M4D(1.0f);
|
||||
hmm_mat4 m4d = HMM_Mat4d(1.0f);
|
||||
for (int Column = 0; Column < 4; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 4; ++Row)
|
||||
@@ -219,7 +224,7 @@ TEST(Initialization, MatrixDiagonal)
|
||||
|
||||
TEST(Initialization, Quaternion)
|
||||
{
|
||||
HMM_Quat q = HMM_Q(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_quaternion q = HMM_Quaternion(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
|
||||
EXPECT_FLOAT_EQ(q.X, 1.0f);
|
||||
EXPECT_FLOAT_EQ(q.Y, 2.0f);
|
||||
@@ -231,91 +236,11 @@ TEST(Initialization, Quaternion)
|
||||
EXPECT_FLOAT_EQ(q.Elements[2], 3.0f);
|
||||
EXPECT_FLOAT_EQ(q.Elements[3], 4.0f);
|
||||
|
||||
HMM_Vec4 v = HMM_V4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Quat qv = HMM_QV4(v);
|
||||
hmm_vec4 v = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_quaternion qv = HMM_QuaternionV4(v);
|
||||
|
||||
EXPECT_FLOAT_EQ(qv.X, 1.0f);
|
||||
EXPECT_FLOAT_EQ(qv.Y, 2.0f);
|
||||
EXPECT_FLOAT_EQ(qv.Z, 3.0f);
|
||||
EXPECT_FLOAT_EQ(qv.W, 4.0f);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
TEST(Initialization, MatrixOverloads)
|
||||
{
|
||||
// Operator overloads for matrix columns must allow mutation.
|
||||
|
||||
//
|
||||
// Test mat2
|
||||
//
|
||||
HMM_Mat2 m2 = {0};
|
||||
m2[0][0] = 1.0f;
|
||||
m2[0][1] = 2.0f;
|
||||
m2[1][0] = 3.0f;
|
||||
m2[1][1] = 4.0f;
|
||||
EXPECT_FLOAT_EQ(m2.Elements[0][0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(m2.Elements[0][1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(m2.Elements[1][0], 3.0f);
|
||||
EXPECT_FLOAT_EQ(m2.Elements[1][1], 4.0f);
|
||||
|
||||
//
|
||||
// Test mat3
|
||||
//
|
||||
HMM_Mat3 m3 = {0};
|
||||
m3[0][0] = 1.0f;
|
||||
m3[0][1] = 2.0f;
|
||||
m3[0][2] = 3.0f;
|
||||
m3[1][0] = 4.0f;
|
||||
m3[1][1] = 5.0f;
|
||||
m3[1][2] = 6.0f;
|
||||
m3[2][0] = 7.0f;
|
||||
m3[2][1] = 8.0f;
|
||||
m3[2][2] = 9.0f;
|
||||
EXPECT_FLOAT_EQ(m3.Elements[0][0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(m3.Elements[0][1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(m3.Elements[0][2], 3.0f);
|
||||
EXPECT_FLOAT_EQ(m3.Elements[1][0], 4.0f);
|
||||
EXPECT_FLOAT_EQ(m3.Elements[1][1], 5.0f);
|
||||
EXPECT_FLOAT_EQ(m3.Elements[1][2], 6.0f);
|
||||
EXPECT_FLOAT_EQ(m3.Elements[2][0], 7.0f);
|
||||
EXPECT_FLOAT_EQ(m3.Elements[2][1], 8.0f);
|
||||
EXPECT_FLOAT_EQ(m3.Elements[2][2], 9.0f);
|
||||
|
||||
//
|
||||
// Test mat4
|
||||
//
|
||||
HMM_Mat4 m4 = {0};
|
||||
m4[0][0] = 1.0f;
|
||||
m4[0][1] = 2.0f;
|
||||
m4[0][2] = 3.0f;
|
||||
m4[0][3] = 4.0f;
|
||||
m4[1][0] = 5.0f;
|
||||
m4[1][1] = 6.0f;
|
||||
m4[1][2] = 7.0f;
|
||||
m4[1][3] = 8.0f;
|
||||
m4[2][0] = 9.0f;
|
||||
m4[2][1] = 10.0f;
|
||||
m4[2][2] = 11.0f;
|
||||
m4[2][3] = 12.0f;
|
||||
m4[3][0] = 13.0f;
|
||||
m4[3][1] = 14.0f;
|
||||
m4[3][2] = 15.0f;
|
||||
m4[3][3] = 16.0f;
|
||||
EXPECT_FLOAT_EQ(m4.Elements[0][0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[0][1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[0][2], 3.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[0][3], 4.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[1][0], 5.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[1][1], 6.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[1][2], 7.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[1][3], 8.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[2][0], 9.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[2][1], 10.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[2][2], 11.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[2][3], 12.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[3][0], 13.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[3][1], 14.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[3][2], 15.0f);
|
||||
EXPECT_FLOAT_EQ(m4.Elements[3][3], 16.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,359 +1,154 @@
|
||||
#include "../HandmadeTest.h"
|
||||
|
||||
TEST(InvMatrix, Transpose)
|
||||
{
|
||||
{
|
||||
HMM_Mat2 Matrix = {
|
||||
1.0f, 3.0f,
|
||||
2.0f, 4.0f,
|
||||
};
|
||||
HMM_Mat2 Expect = {
|
||||
1.0f, 2.0f,
|
||||
3.0f, 4.0f,
|
||||
};
|
||||
void printQuat(hmm_quaternion quat) {
|
||||
printf("\n%f %f %f %f", quat.X, quat.Y, quat.Z, quat.W);
|
||||
}
|
||||
|
||||
TEST(MatrixOps, Transpose)
|
||||
{
|
||||
hmm_mat4 m4 = HMM_Mat4(); // will have 1 - 16
|
||||
|
||||
// Fill the matrix
|
||||
int Counter = 1;
|
||||
for (int Column = 0; Column < 4; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 4; ++Row)
|
||||
{
|
||||
HMM_Mat2 result = HMM_TransposeM2(Matrix);
|
||||
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[1][0], Expect.Elements[1][0]);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], Expect.Elements[1][1]);
|
||||
m4.Elements[Column][Row] = Counter;
|
||||
++Counter;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat2 result = HMM_Transpose(Matrix);
|
||||
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[1][0], Expect.Elements[1][0]);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], Expect.Elements[1][1]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat3 Matrix = {
|
||||
1.0f, 4.0f, 7.0f,
|
||||
2.0f, 5.0f, 8.0f,
|
||||
3.0f, 6.0f, 9.0f,
|
||||
};
|
||||
HMM_Mat3 Expect = {
|
||||
1.0f, 2.0f, 3.0f,
|
||||
4.0f, 5.0f, 6.0f,
|
||||
7.0f, 8.0f, 9.0f
|
||||
// Test the matrix
|
||||
hmm_mat4 result = HMM_Transpose(m4);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 5.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 9.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][3], 13.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][3], 14.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 7.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 11.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][3], 15.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][0], 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][1], 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][2], 12.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 16.0f);
|
||||
}
|
||||
|
||||
TEST(MatrixOps, ToQuaternion)
|
||||
{
|
||||
{ // Test 90 degree rotation about X axis
|
||||
hmm_mat4 rot = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f, // first column (X)
|
||||
0.0f, 0.0f, 1.0f, 0.0f, // second column (Y)
|
||||
0.0f, -1.0f, 0.0f, 0.0f, // third column (Z)
|
||||
0.0f, 0.0f, 0.0f, 0.0f
|
||||
};
|
||||
|
||||
{
|
||||
HMM_Mat3 result = HMM_TransposeM3(Matrix);
|
||||
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[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[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]);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat3 result = HMM_Transpose(Matrix);
|
||||
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[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[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]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
{
|
||||
HMM_Mat4 Matrix = {
|
||||
1.0f, 5.0f, 9.0f, 13.0f,
|
||||
2.0f, 6.0f, 10.0f, 14.0f,
|
||||
3.0f, 7.0f, 11.0f, 15.0f,
|
||||
4.0f, 8.0f, 12.0f, 16.0f
|
||||
};
|
||||
HMM_Mat4 Expect = {
|
||||
1.0f, 2.0f, 3.0f, 4.0f,
|
||||
5.0f, 6.0f, 7.0f, 8.0f,
|
||||
9.0f, 10.0f, 11.0f, 12.0f,
|
||||
13.0f, 14.0f, 15.0f, 16.0f,
|
||||
};
|
||||
{
|
||||
HMM_Mat4 result = HMM_TransposeM4(Matrix);
|
||||
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[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[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]);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat4 result = HMM_Transpose(Matrix);
|
||||
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[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[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]);
|
||||
}
|
||||
#endif
|
||||
hmm_quaternion expected = HMM_QuaternionFromAxisAngle(HMM_Vec3(1.0f, 0.0f, 0.0f), HMM_ToRadians(90.0f));
|
||||
hmm_quaternion actualResult = HMM_Mat4ToQuaternion(rot);
|
||||
|
||||
EXPECT_FLOAT_EQ(actualResult.X, expected.X);
|
||||
EXPECT_FLOAT_EQ(actualResult.Y, expected.Y);
|
||||
EXPECT_FLOAT_EQ(actualResult.Z, expected.Z);
|
||||
EXPECT_FLOAT_EQ(actualResult.W, expected.W);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST(InvMatrix, InvGeneral)
|
||||
{
|
||||
{
|
||||
HMM_Mat4 Matrix = {
|
||||
12.0f, 2.0f, 1.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.0f, 1.0f, 5.0f, 1.0f,
|
||||
11.0f, 1.0f, 0.0f, 10.0f
|
||||
{ // Test 90 degree rotation about Y axis
|
||||
hmm_mat4 rot = {
|
||||
0.0f, 0.0f, -1.0f, 0.0f, // first column (X)
|
||||
0.0f, 1.0f, 0.0f, 0.0f, // second column (Y)
|
||||
1.0f, 0.0f, 0.0f, 0.0f, // third column (Z)
|
||||
0.0f, 0.0f, 0.0f, 0.0f
|
||||
};
|
||||
|
||||
HMM_Mat4 Expect = HMM_M4D(1.0);
|
||||
HMM_Mat4 Inverse = HMM_InvGeneralM4(Matrix);
|
||||
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
||||
hmm_quaternion expected = HMM_QuaternionFromAxisAngle(HMM_Vec3(0.0f, 1.0f, 0.0f), HMM_ToRadians(90.0f));
|
||||
hmm_quaternion actualResult = HMM_Mat4ToQuaternion(rot);
|
||||
|
||||
float Det = HMM_DeterminantM4(Matrix);
|
||||
EXPECT_FLOAT_EQ(Det, -80.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]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
Inverse = HMM_InvGeneral(Matrix);
|
||||
Result = HMM_Mul(Matrix, Inverse);
|
||||
|
||||
Det = HMM_Determinant(Matrix);
|
||||
EXPECT_FLOAT_EQ(Det, -80.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]);
|
||||
#endif
|
||||
EXPECT_FLOAT_EQ(actualResult.X, expected.X);
|
||||
EXPECT_FLOAT_EQ(actualResult.Y, expected.Y);
|
||||
EXPECT_FLOAT_EQ(actualResult.Z, expected.Z);
|
||||
EXPECT_FLOAT_EQ(actualResult.W, expected.W);
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat3 Matrix = {
|
||||
12.0f, 2.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
0.0f, 1.0f, 5.0f
|
||||
{ // Test 90 degree rotation about Z axis
|
||||
hmm_mat4 rot = {
|
||||
0.0f, 1.0f, 0.0f, 0.0f, // first column (X)
|
||||
-1.0f, 0.0f, 0.0f, 0.0f, // second column (Y)
|
||||
0.0f, 0.0f, 1.0f, 0.0f, // third column (Z)
|
||||
0.0f, 0.0f, 0.0f, 0.0f
|
||||
};
|
||||
|
||||
HMM_Mat3 Expect = HMM_M3D(1.0);
|
||||
HMM_Mat3 Inverse = HMM_InvGeneralM3(Matrix);
|
||||
HMM_Mat3 Result = HMM_MulM3(Matrix, Inverse);
|
||||
hmm_quaternion expected = HMM_QuaternionFromAxisAngle(HMM_Vec3(0.0f, 0.0f, 1.0f), HMM_ToRadians(90.0f));
|
||||
hmm_quaternion actualResult = HMM_Mat4ToQuaternion(rot);
|
||||
|
||||
float Det = HMM_DeterminantM3(Matrix);
|
||||
EXPECT_FLOAT_EQ(Det, -12.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[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[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]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
Inverse = HMM_InvGeneral(Matrix);
|
||||
Result = HMM_Mul(Matrix, Inverse);
|
||||
Det = HMM_Determinant(Matrix);
|
||||
EXPECT_FLOAT_EQ(Det, -12.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[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[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]);
|
||||
#endif
|
||||
EXPECT_FLOAT_EQ(actualResult.X, expected.X);
|
||||
EXPECT_FLOAT_EQ(actualResult.Y, expected.Y);
|
||||
EXPECT_FLOAT_EQ(actualResult.Z, expected.Z);
|
||||
EXPECT_FLOAT_EQ(actualResult.W, expected.W);
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat2 Matrix = {
|
||||
12.0f, 2.0f,
|
||||
1.0f, 5.0f
|
||||
{ // Test 180 degree rotation about X axis
|
||||
hmm_mat4 rot = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f, // first column (X)
|
||||
0.0f, -1.0f, 1.0f, 0.0f, // second column (Y)
|
||||
0.0f, 0.0f, -1.0f, 0.0f, // third column (Z)
|
||||
0.0f, 0.0f, 0.0f, 0.0f
|
||||
};
|
||||
|
||||
HMM_Mat2 Expect = HMM_M2D(1.0);
|
||||
HMM_Mat2 Inverse = HMM_InvGeneralM2(Matrix);
|
||||
HMM_Mat2 Result = HMM_MulM2(Matrix, Inverse);
|
||||
hmm_quaternion expected = HMM_QuaternionFromAxisAngle(HMM_Vec3(1.0f, 0.0f, 0.0f), HMM_ToRadians(180.0f));
|
||||
hmm_quaternion actualResult = HMM_Mat4ToQuaternion(rot);
|
||||
|
||||
float Det = HMM_DeterminantM2(Matrix);
|
||||
EXPECT_FLOAT_EQ(Det, 58.0f);
|
||||
printQuat(expected);
|
||||
printQuat(actualResult);
|
||||
|
||||
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[1][0], Expect.Elements[1][0]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][1], Expect.Elements[1][1]);
|
||||
EXPECT_FLOAT_EQ(actualResult.X, expected.X);
|
||||
EXPECT_FLOAT_EQ(actualResult.Y, expected.Y);
|
||||
EXPECT_FLOAT_EQ(actualResult.Z, expected.Z);
|
||||
EXPECT_FLOAT_EQ(actualResult.W, expected.W);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
Inverse = HMM_InvGeneral(Matrix);
|
||||
Result = HMM_Mul(Matrix, Inverse);
|
||||
Det = HMM_Determinant(Matrix);
|
||||
EXPECT_FLOAT_EQ(Det, 58.0f);
|
||||
{ // Test 180 degree rotation about Y axis
|
||||
hmm_mat4 rot = {
|
||||
-1.0f, 0.0f, 0.0f, 0.0f, // first column (X)
|
||||
0.0f, 1.0f, 1.0f, 0.0f, // second column (Y)
|
||||
0.0f, 0.0f, -1.0f, 0.0f, // third column (Z)
|
||||
0.0f, 0.0f, 0.0f, 0.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[1][0], Expect.Elements[1][0]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][1], Expect.Elements[1][1]);
|
||||
#endif
|
||||
hmm_quaternion expected = HMM_QuaternionFromAxisAngle(HMM_Vec3(0.0f, 1.0f, 0.0f), HMM_ToRadians(180.0f));
|
||||
hmm_quaternion actualResult = HMM_Mat4ToQuaternion(rot);
|
||||
|
||||
printQuat(expected);
|
||||
printQuat(actualResult);
|
||||
|
||||
EXPECT_FLOAT_EQ(actualResult.X, expected.X);
|
||||
EXPECT_FLOAT_EQ(actualResult.Y, expected.Y);
|
||||
EXPECT_FLOAT_EQ(actualResult.Z, expected.Z);
|
||||
EXPECT_FLOAT_EQ(actualResult.W, expected.W);
|
||||
}
|
||||
|
||||
{ // Test 180 degree rotation about Z axis
|
||||
hmm_mat4 rot = {
|
||||
-1.0f, 0.0f, 0.0f, 0.0f, // first column (X)
|
||||
0.0f, -1.0f, 1.0f, 0.0f, // second column (Y)
|
||||
0.0f, 0.0f, 1.0f, 0.0f, // third column (Z)
|
||||
0.0f, 0.0f, 0.0f, 0.0f
|
||||
};
|
||||
|
||||
hmm_quaternion expected = HMM_QuaternionFromAxisAngle(HMM_Vec3(0.0f, 0.0f, 1.0f), HMM_ToRadians(180.0f));
|
||||
hmm_quaternion actualResult = HMM_Mat4ToQuaternion(rot);
|
||||
|
||||
printQuat(expected);
|
||||
printQuat(actualResult);
|
||||
|
||||
EXPECT_FLOAT_EQ(actualResult.X, expected.X);
|
||||
EXPECT_FLOAT_EQ(actualResult.Y, expected.Y);
|
||||
EXPECT_FLOAT_EQ(actualResult.Z, expected.Z);
|
||||
EXPECT_FLOAT_EQ(actualResult.W, expected.W);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(InvMatrix, InvOrthographic)
|
||||
{
|
||||
{
|
||||
HMM_Mat4 Matrix = HMM_Orthographic_RH_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_RH_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));
|
||||
}
|
||||
{
|
||||
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 Center = {100.0f, 200.0f, 30.0f};
|
||||
HMM_Vec3 Up = {0.0f, 0.0f, 1.0f};
|
||||
HMM_Mat4 Matrix = HMM_LookAt_RH(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);
|
||||
}
|
||||
{
|
||||
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_Mat4 Matrix = HMM_Rotate_RH(HMM_AngleDeg(30), HMM_NormV3(Axis));
|
||||
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
||||
HMM_Mat4 Inverse = HMM_InvRotate(Matrix);
|
||||
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
||||
EXPECT_M4_NEAR(Result, Expect, 0.001f);
|
||||
}
|
||||
{
|
||||
HMM_Vec3 Axis = {1.0f, -1.0f, 0.5f};
|
||||
HMM_Mat4 Matrix = HMM_Rotate_LH(HMM_AngleDeg(30), HMM_NormV3(Axis));
|
||||
HMM_Mat4 Expect = HMM_M4D(1.0f);
|
||||
HMM_Mat4 Inverse = HMM_InvRotate(Matrix);
|
||||
HMM_Mat4 Result = HMM_MulM4(Matrix, Inverse);
|
||||
EXPECT_M4_NEAR(Result, Expect, 0.001f);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
|
||||
TEST(Multiplication, Vec2Vec2)
|
||||
{
|
||||
HMM_Vec2 v2_1 = HMM_V2(1.0f, 2.0f);
|
||||
HMM_Vec2 v2_2 = HMM_V2(3.0f, 4.0f);
|
||||
hmm_vec2 v2_1 = HMM_Vec2(1.0f, 2.0f);
|
||||
hmm_vec2 v2_2 = HMM_Vec2(3.0f, 4.0f);
|
||||
|
||||
{
|
||||
HMM_Vec2 result = HMM_MulV2(v2_1, v2_2);
|
||||
hmm_vec2 result = HMM_MultiplyVec2(v2_1, v2_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 8.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec2 result = HMM_Mul(v2_1, v2_2);
|
||||
hmm_vec2 result = HMM_Multiply(v2_1, v2_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 8.0f);
|
||||
}
|
||||
{
|
||||
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.Y, 8.0f);
|
||||
}
|
||||
@@ -30,27 +30,27 @@ TEST(Multiplication, Vec2Vec2)
|
||||
|
||||
TEST(Multiplication, Vec2Scalar)
|
||||
{
|
||||
HMM_Vec2 v2 = HMM_V2(1.0f, 2.0f);
|
||||
hmm_vec2 v2 = HMM_Vec2(1.0f, 2.0f);
|
||||
float s = 3.0f;
|
||||
|
||||
{
|
||||
HMM_Vec2 result = HMM_MulV2F(v2, s);
|
||||
hmm_vec2 result = HMM_MultiplyVec2f(v2, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec2 result = HMM_Mul(v2, s);
|
||||
hmm_vec2 result = HMM_Multiply(v2, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec2 result = v2 * s;
|
||||
hmm_vec2 result = v2 * s;
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec2 result = s * v2;
|
||||
hmm_vec2 result = s * v2;
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
}
|
||||
@@ -63,24 +63,24 @@ TEST(Multiplication, Vec2Scalar)
|
||||
|
||||
TEST(Multiplication, Vec3Vec3)
|
||||
{
|
||||
HMM_Vec3 v3_1 = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
HMM_Vec3 v3_2 = HMM_V3(4.0f, 5.0f, 6.0f);
|
||||
hmm_vec3 v3_1 = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec3 v3_2 = HMM_Vec3(4.0f, 5.0f, 6.0f);
|
||||
|
||||
{
|
||||
HMM_Vec3 result = HMM_MulV3(v3_1, v3_2);
|
||||
hmm_vec3 result = HMM_MultiplyVec3(v3_1, v3_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 18.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec3 result = HMM_Mul(v3_1, v3_2);
|
||||
hmm_vec3 result = HMM_Multiply(v3_1, v3_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 18.0f);
|
||||
}
|
||||
{
|
||||
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.Y, 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 18.0f);
|
||||
@@ -95,30 +95,30 @@ TEST(Multiplication, Vec3Vec3)
|
||||
|
||||
TEST(Multiplication, Vec3Scalar)
|
||||
{
|
||||
HMM_Vec3 v3 = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec3 v3 = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
float s = 3.0f;
|
||||
|
||||
{
|
||||
HMM_Vec3 result = HMM_MulV3F(v3, s);
|
||||
hmm_vec3 result = HMM_MultiplyVec3f(v3, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec3 result = HMM_Mul(v3, s);
|
||||
hmm_vec3 result = HMM_Multiply(v3, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec3 result = v3 * s;
|
||||
hmm_vec3 result = v3 * s;
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec3 result = s * v3;
|
||||
hmm_vec3 result = s * v3;
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||
@@ -133,11 +133,11 @@ TEST(Multiplication, Vec3Scalar)
|
||||
|
||||
TEST(Multiplication, Vec4Vec4)
|
||||
{
|
||||
HMM_Vec4 v4_1 = HMM_V4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Vec4 v4_2 = HMM_V4(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
hmm_vec4 v4_1 = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_vec4 v4_2 = HMM_Vec4(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
|
||||
{
|
||||
HMM_Vec4 result = HMM_MulV4(v4_1, v4_2);
|
||||
hmm_vec4 result = HMM_MultiplyVec4(v4_1, v4_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 5.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 12.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 21.0f);
|
||||
@@ -145,14 +145,14 @@ TEST(Multiplication, Vec4Vec4)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec4 result = HMM_Mul(v4_1, v4_2);
|
||||
hmm_vec4 result = HMM_Multiply(v4_1, v4_2);
|
||||
EXPECT_FLOAT_EQ(result.X, 5.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 12.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 21.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, 32.0f);
|
||||
}
|
||||
{
|
||||
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.Y, 12.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 21.0f);
|
||||
@@ -169,11 +169,11 @@ TEST(Multiplication, Vec4Vec4)
|
||||
|
||||
TEST(Multiplication, Vec4Scalar)
|
||||
{
|
||||
HMM_Vec4 v4 = HMM_V4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_vec4 v4 = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
float s = 3.0f;
|
||||
|
||||
{
|
||||
HMM_Vec4 result = HMM_MulV4F(v4, s);
|
||||
hmm_vec4 result = HMM_MultiplyVec4f(v4, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||
@@ -181,21 +181,21 @@ TEST(Multiplication, Vec4Scalar)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec4 result = HMM_Mul(v4, s);
|
||||
hmm_vec4 result = HMM_Multiply(v4, s);
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec4 result = v4 * s;
|
||||
hmm_vec4 result = v4 * s;
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, 12.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec4 result = s * v4;
|
||||
hmm_vec4 result = s * v4;
|
||||
EXPECT_FLOAT_EQ(result.X, 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 9.0f);
|
||||
@@ -209,309 +209,10 @@ TEST(Multiplication, Vec4Scalar)
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Multiplication, Mat2Mat2) {
|
||||
HMM_Mat2 a = HMM_M2();
|
||||
HMM_Mat2 b = HMM_M2();
|
||||
|
||||
int counter = 1;
|
||||
for (int Column = 0; Column < 2; Column++) {
|
||||
for (int Row = 0; Row < 2; Row++) {
|
||||
a.Elements[Column][Row] = counter++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int Column = 0; Column < 2; Column++) {
|
||||
for (int Row = 0; Row < 2; Row++) {
|
||||
b.Elements[Column][Row] = counter++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat2 result = HMM_MulM2(a,b);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 23.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 34.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 31.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 46.0f);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat2 result = HMM_Mul(a,b);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 23.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 34.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 31.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 46.0f);
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat2 result = a * b;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 23.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 34.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 31.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 46.0f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Multiplication, Mat2Scalar) {
|
||||
HMM_Mat2 m = HMM_M2();
|
||||
float s = 10.0f;
|
||||
|
||||
int counter = 1;
|
||||
for (int Column = 0; Column < 2; Column++) {
|
||||
for (int Row = 0; Row < 2; Row++) {
|
||||
m.Elements[Column][Row] = counter++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat2 result = HMM_MulM2F(m, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 20.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 30.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 40.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat2 result = HMM_Mul(m, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 20.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 30.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 40.0f);
|
||||
}
|
||||
{
|
||||
HMM_Mat2 result = m * s;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 20.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 30.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 40.0f);
|
||||
}
|
||||
{
|
||||
HMM_Mat2 result = s * m;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 20.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 30.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 40.0f);
|
||||
}
|
||||
m *= s;
|
||||
EXPECT_FLOAT_EQ(m.Elements[0][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(m.Elements[0][1], 20.0f);
|
||||
EXPECT_FLOAT_EQ(m.Elements[1][0], 30.0f);
|
||||
EXPECT_FLOAT_EQ(m.Elements[1][1], 40.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Multiplication, Mat2Vec2) {
|
||||
HMM_Mat2 m = HMM_M2();
|
||||
HMM_Vec2 v = HMM_V2(0.0f, 0.0f);
|
||||
|
||||
int counter = 1;
|
||||
for (int Column = 0; Column < 2; Column++) {
|
||||
for (int Row = 0; Row < 2; Row++) {
|
||||
m.Elements[Column][Row] = counter++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int Row = 0; Row < 2; Row++) {
|
||||
v.Elements[Row] = counter++;
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Vec2 result = HMM_MulM2V2(m, v);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0], 23.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1], 34.0f);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec2 result = HMM_Mul(m, v);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0], 23.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1], 34.0f);
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Vec2 result = m * v;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0], 23.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1], 34.0f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Multiplication, Mat3Mat3)
|
||||
{
|
||||
HMM_Mat3 a = HMM_M3();
|
||||
HMM_Mat3 b = HMM_M3();
|
||||
|
||||
int counter = 1;
|
||||
for (int Column = 0; Column < 3; Column++) {
|
||||
for (int Row = 0; Row < 3; Row++) {
|
||||
a.Elements[Column][Row] = counter++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int Column = 0; Column < 3; Column++) {
|
||||
for (int Row = 0; Row < 3; Row++) {
|
||||
b.Elements[Column][Row] = counter++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat3 result = HMM_MulM3(a,b);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 138.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 171.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 204.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 174.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 216.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 258.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 210.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 261.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 312.0f);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat3 result = HMM_Mul(a,b);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 138.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 171.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 204.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 174.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 216.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 258.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 210.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 261.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 312.0f);
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat3 result = a * b;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 138.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 171.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 204.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 174.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 216.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 258.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 210.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 261.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 312.0f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Multiplication, Mat3Scalar) {
|
||||
HMM_Mat3 m = HMM_M3();
|
||||
float s = 10.0f;
|
||||
|
||||
int counter = 1;
|
||||
for (int Column = 0; Column < 3; Column++) {
|
||||
for (int Row = 0; Row < 3; Row++) {
|
||||
m.Elements[Column][Row] = counter++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat3 result = HMM_MulM3F(m, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 20.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 30.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 40.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 50.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 60.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 70.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 80.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 90.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat3 result = HMM_Mul(m, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 20.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 30.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 40.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 50.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 60.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 70.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 80.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 90.0f);
|
||||
}
|
||||
{
|
||||
HMM_Mat3 result = m * s;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 20.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 30.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 40.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 50.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 60.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 70.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 80.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 90.0f);
|
||||
}
|
||||
{
|
||||
HMM_Mat3 result = s * m;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 20.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 30.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 40.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 50.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 60.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 70.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 80.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 90.0f);
|
||||
}
|
||||
m *= s;
|
||||
EXPECT_FLOAT_EQ(m.Elements[0][0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(m.Elements[0][1], 20.0f);
|
||||
EXPECT_FLOAT_EQ(m.Elements[0][2], 30.0f);
|
||||
EXPECT_FLOAT_EQ(m.Elements[1][0], 40.0f);
|
||||
EXPECT_FLOAT_EQ(m.Elements[1][1], 50.0f);
|
||||
EXPECT_FLOAT_EQ(m.Elements[1][2], 60.0f);
|
||||
EXPECT_FLOAT_EQ(m.Elements[2][0], 70.0f);
|
||||
EXPECT_FLOAT_EQ(m.Elements[2][1], 80.0f);
|
||||
EXPECT_FLOAT_EQ(m.Elements[2][2], 90.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Multiplication, Mat3Vec3) {
|
||||
HMM_Mat3 m = HMM_M3();
|
||||
HMM_Vec3 v = HMM_V3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
int counter = 1;
|
||||
for (int Column = 0; Column < 3; Column++) {
|
||||
for (int Row = 0; Row < 3; Row++) {
|
||||
m.Elements[Column][Row] = counter++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int Row = 0; Row < 3; Row++) {
|
||||
v.Elements[Row] = counter++;
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Vec3 result = HMM_MulM3V3(m, v);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0], 138.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1], 171.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2], 204.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec3 result = HMM_Mul(m, v);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0], 138.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1], 171.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2], 204.0f);
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Vec3 result = m * v;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0], 138.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1], 171.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2], 204.0f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Multiplication, Mat4Mat4)
|
||||
{
|
||||
HMM_Mat4 m4_1 = HMM_M4(); // will have 1 - 16
|
||||
HMM_Mat4 m4_2 = HMM_M4(); // will have 17 - 32
|
||||
hmm_mat4 m4_1 = HMM_Mat4(); // will have 1 - 16
|
||||
hmm_mat4 m4_2 = HMM_Mat4(); // will have 17 - 32
|
||||
|
||||
// Fill the matrices
|
||||
int Counter = 1;
|
||||
@@ -534,7 +235,7 @@ TEST(Multiplication, Mat4Mat4)
|
||||
|
||||
// Test the results
|
||||
{
|
||||
HMM_Mat4 result = HMM_MulM4(m4_1, m4_2);
|
||||
hmm_mat4 result = HMM_MultiplyMat4(m4_1, m4_2);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 538.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 612.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 686.0f);
|
||||
@@ -554,7 +255,7 @@ TEST(Multiplication, Mat4Mat4)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat4 result = HMM_Mul(m4_1, m4_2);
|
||||
hmm_mat4 result = HMM_Multiply(m4_1, m4_2);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 538.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 612.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 686.0f);
|
||||
@@ -573,7 +274,7 @@ TEST(Multiplication, Mat4Mat4)
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 1240.0f);
|
||||
}
|
||||
{
|
||||
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][1], 612.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 686.0f);
|
||||
@@ -600,7 +301,7 @@ TEST(Multiplication, Mat4Mat4)
|
||||
|
||||
TEST(Multiplication, Mat4Scalar)
|
||||
{
|
||||
HMM_Mat4 m4 = HMM_M4(); // will have 1 - 16
|
||||
hmm_mat4 m4 = HMM_Mat4(); // will have 1 - 16
|
||||
float s = 3;
|
||||
|
||||
// Fill the matrix
|
||||
@@ -616,7 +317,7 @@ TEST(Multiplication, Mat4Scalar)
|
||||
|
||||
// Test the results
|
||||
{
|
||||
HMM_Mat4 result = HMM_MulM4F(m4, s);
|
||||
hmm_mat4 result = HMM_MultiplyMat4f(m4, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 9.0f);
|
||||
@@ -636,7 +337,7 @@ TEST(Multiplication, Mat4Scalar)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat4 result = HMM_Mul(m4, s);
|
||||
hmm_mat4 result = HMM_Multiply(m4, s);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 9.0f);
|
||||
@@ -655,7 +356,7 @@ TEST(Multiplication, Mat4Scalar)
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 48.0f);
|
||||
}
|
||||
{
|
||||
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][1], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 9.0f);
|
||||
@@ -674,7 +375,7 @@ TEST(Multiplication, Mat4Scalar)
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 48.0f);
|
||||
}
|
||||
{
|
||||
HMM_Mat4 result = s * m4;
|
||||
hmm_mat4 result = s * m4;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 9.0f);
|
||||
@@ -715,8 +416,8 @@ TEST(Multiplication, Mat4Scalar)
|
||||
|
||||
TEST(Multiplication, Mat4Vec4)
|
||||
{
|
||||
HMM_Mat4 m4 = HMM_M4(); // will have 1 - 16
|
||||
HMM_Vec4 v4 = HMM_V4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_mat4 m4 = HMM_Mat4(); // will have 1 - 16
|
||||
hmm_vec4 v4 = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
|
||||
// Fill the matrix
|
||||
int Counter = 1;
|
||||
@@ -731,7 +432,7 @@ TEST(Multiplication, Mat4Vec4)
|
||||
|
||||
// Test the results
|
||||
{
|
||||
HMM_Vec4 result = HMM_MulM4V4(m4, v4);
|
||||
hmm_vec4 result = HMM_MultiplyMat4ByVec4(m4, v4);
|
||||
EXPECT_FLOAT_EQ(result.X, 90.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 100.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 110.0f);
|
||||
@@ -739,14 +440,14 @@ TEST(Multiplication, Mat4Vec4)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec4 result = HMM_Mul(m4, v4);
|
||||
hmm_vec4 result = HMM_Multiply(m4, v4);
|
||||
EXPECT_FLOAT_EQ(result.X, 90.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 100.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 110.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, 120.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec4 result = m4 * v4;
|
||||
hmm_vec4 result = m4 * v4;
|
||||
EXPECT_FLOAT_EQ(result.X, 90.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 100.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 110.0f);
|
||||
@@ -759,11 +460,11 @@ TEST(Multiplication, Mat4Vec4)
|
||||
|
||||
TEST(Multiplication, QuaternionQuaternion)
|
||||
{
|
||||
HMM_Quat q1 = HMM_Q(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Quat q2 = HMM_Q(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
hmm_quaternion q1 = HMM_Quaternion(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_quaternion q2 = HMM_Quaternion(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
|
||||
{
|
||||
HMM_Quat result = HMM_MulQ(q1, q2);
|
||||
hmm_quaternion result = HMM_MultiplyQuaternion(q1, q2);
|
||||
EXPECT_FLOAT_EQ(result.X, 24.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 48.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 48.0f);
|
||||
@@ -771,14 +472,14 @@ TEST(Multiplication, QuaternionQuaternion)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Quat result = HMM_Mul(q1, q2);
|
||||
hmm_quaternion result = HMM_Multiply(q1, q2);
|
||||
EXPECT_FLOAT_EQ(result.X, 24.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 48.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 48.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, -6.0f);
|
||||
}
|
||||
{
|
||||
HMM_Quat result = q1 * q2;
|
||||
hmm_quaternion result = q1 * q2;
|
||||
EXPECT_FLOAT_EQ(result.X, 24.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 48.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 48.0f);
|
||||
@@ -793,11 +494,11 @@ TEST(Multiplication, QuaternionQuaternion)
|
||||
|
||||
TEST(Multiplication, QuaternionScalar)
|
||||
{
|
||||
HMM_Quat q = HMM_Q(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_quaternion q = HMM_Quaternion(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
float f = 2.0f;
|
||||
|
||||
{
|
||||
HMM_Quat result = HMM_MulQF(q, f);
|
||||
hmm_quaternion result = HMM_MultiplyQuaternionF(q, f);
|
||||
EXPECT_FLOAT_EQ(result.X, 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 6.0f);
|
||||
@@ -805,21 +506,21 @@ TEST(Multiplication, QuaternionScalar)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Quat result = HMM_Mul(q, f);
|
||||
hmm_quaternion result = HMM_Multiply(q, f);
|
||||
EXPECT_FLOAT_EQ(result.X, 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, 8.0f);
|
||||
}
|
||||
{
|
||||
HMM_Quat result = q * f;
|
||||
hmm_quaternion result = q * f;
|
||||
EXPECT_FLOAT_EQ(result.X, 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, 8.0f);
|
||||
}
|
||||
{
|
||||
HMM_Quat result = f * q;
|
||||
hmm_quaternion result = f * q;
|
||||
EXPECT_FLOAT_EQ(result.X, 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 6.0f);
|
||||
|
||||
@@ -2,84 +2,35 @@
|
||||
|
||||
TEST(Projection, Orthographic)
|
||||
{
|
||||
#define ORTHO_BOUNDS -8.0f, 12.0f, 5.0f, 10.0f, 1.0f, 100.0f
|
||||
hmm_mat4 projection = HMM_Orthographic(-10.0f, 10.0f, -5.0f, 5.0f, 0.0f, -10.0f);
|
||||
|
||||
// Right-handed
|
||||
{
|
||||
// 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_Vec3(5.0f, 5.0f, -5.0f);
|
||||
hmm_vec4 projected = HMM_MultiplyMat4ByVec4(projection, HMM_Vec4v(original, 1));
|
||||
|
||||
// Z from -1 to 1 (GL convention)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
// Z from 0 to 1 (DX convention)
|
||||
{
|
||||
HMM_Mat4 projection = HMM_Orthographic_RH_ZO(ORTHO_BOUNDS);
|
||||
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
|
||||
{
|
||||
// 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);
|
||||
|
||||
// Z from -1 to 1 (GL convention)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
// Z from 0 to 1 (DX convention)
|
||||
{
|
||||
HMM_Mat4 projection = HMM_Orthographic_LH_ZO(ORTHO_BOUNDS);
|
||||
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));
|
||||
}
|
||||
}
|
||||
EXPECT_FLOAT_EQ(projected.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(projected.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(projected.Z, -2.0f);
|
||||
EXPECT_FLOAT_EQ(projected.W, 1.0f);
|
||||
}
|
||||
|
||||
TEST(Projection, Perspective)
|
||||
{
|
||||
// Right-handed
|
||||
{
|
||||
// Z from -1 to 1 (GL convention)
|
||||
{
|
||||
HMM_Mat4 projection = HMM_Perspective_RH_NO(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, -1.0f, 1.0f));
|
||||
}
|
||||
hmm_mat4 projection = HMM_Perspective(90.0f, 2.0f, 5.0f, 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));
|
||||
}
|
||||
{
|
||||
hmm_vec3 original = HMM_Vec3(5.0f, 5.0f, -15.0f);
|
||||
hmm_vec4 projected = HMM_MultiplyMat4ByVec4(projection, HMM_Vec4v(original, 1));
|
||||
EXPECT_FLOAT_EQ(projected.X, 5.0f);
|
||||
EXPECT_FLOAT_EQ(projected.Y, 10.0f);
|
||||
EXPECT_FLOAT_EQ(projected.Z, 15.0f);
|
||||
EXPECT_FLOAT_EQ(projected.W, 15.0f);
|
||||
}
|
||||
|
||||
// Left-handed
|
||||
{
|
||||
// Z from -1 to 1 (GL convention)
|
||||
{
|
||||
HMM_Mat4 projection = HMM_Perspective_LH_NO(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, -1.0f, 1.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));
|
||||
}
|
||||
hmm_vec3 original = HMM_Vec3(5.0f, 5.0f, -5.0f);
|
||||
hmm_vec4 projected = HMM_MultiplyMat4ByVec4(projection, HMM_Vec4v(original, 1));
|
||||
EXPECT_FLOAT_EQ(projected.X, 5.0f);
|
||||
EXPECT_FLOAT_EQ(projected.Y, 10.0f);
|
||||
EXPECT_FLOAT_EQ(projected.Z, -5.0f);
|
||||
EXPECT_FLOAT_EQ(projected.W, 5.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
TEST(QuaternionOps, Inverse)
|
||||
{
|
||||
HMM_Quat q1 = HMM_Q(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Quat inverse = HMM_InvQ(q1);
|
||||
hmm_quaternion q1 = HMM_Quaternion(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_quaternion inverse = HMM_InverseQuaternion(q1);
|
||||
|
||||
HMM_Quat result = HMM_MulQ(q1, inverse);
|
||||
hmm_quaternion result = HMM_MultiplyQuaternion(q1, inverse);
|
||||
|
||||
EXPECT_FLOAT_EQ(result.X, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.0f);
|
||||
@@ -15,11 +15,11 @@ TEST(QuaternionOps, Inverse)
|
||||
|
||||
TEST(QuaternionOps, Dot)
|
||||
{
|
||||
HMM_Quat q1 = HMM_Q(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Quat q2 = HMM_Q(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
hmm_quaternion q1 = HMM_Quaternion(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_quaternion q2 = HMM_Quaternion(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
|
||||
{
|
||||
float result = HMM_DotQ(q1, q2);
|
||||
float result = HMM_DotQuaternion(q1, q2);
|
||||
EXPECT_FLOAT_EQ(result, 70.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
@@ -32,245 +32,117 @@ TEST(QuaternionOps, Dot)
|
||||
|
||||
TEST(QuaternionOps, Normalize)
|
||||
{
|
||||
HMM_Quat q = HMM_Q(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_quaternion q = HMM_Quaternion(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
|
||||
{
|
||||
HMM_Quat result = HMM_NormQ(q);
|
||||
EXPECT_NEAR(result.X, 0.1825741858f, 0.001f);
|
||||
EXPECT_NEAR(result.Y, 0.3651483717f, 0.001f);
|
||||
EXPECT_NEAR(result.Z, 0.5477225575f, 0.001f);
|
||||
EXPECT_NEAR(result.W, 0.7302967433f, 0.001f);
|
||||
hmm_quaternion result = HMM_NormalizeQuaternion(q);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.1825741858f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.3651483717f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.5477225575f);
|
||||
EXPECT_FLOAT_EQ(result.W, 0.7302967433f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Quat result = HMM_Norm(q);
|
||||
EXPECT_NEAR(result.X, 0.1825741858f, 0.001f);
|
||||
EXPECT_NEAR(result.Y, 0.3651483717f, 0.001f);
|
||||
EXPECT_NEAR(result.Z, 0.5477225575f, 0.001f);
|
||||
EXPECT_NEAR(result.W, 0.7302967433f, 0.001f);
|
||||
hmm_quaternion result = HMM_Normalize(q);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.1825741858f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.3651483717f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.5477225575f);
|
||||
EXPECT_FLOAT_EQ(result.W, 0.7302967433f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(QuaternionOps, NLerp)
|
||||
{
|
||||
HMM_Quat from = HMM_Q(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
HMM_Quat to = HMM_Q(0.5f, 0.5f, -0.5f, 0.5f);
|
||||
hmm_quaternion from = HMM_Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
hmm_quaternion to = HMM_Quaternion(0.5f, 0.5f, -0.5f, 0.5f);
|
||||
|
||||
HMM_Quat result = HMM_NLerp(from, 0.5f, to);
|
||||
EXPECT_NEAR(result.X, 0.28867513f, 0.001f);
|
||||
EXPECT_NEAR(result.Y, 0.28867513f, 0.001f);
|
||||
EXPECT_NEAR(result.Z, -0.28867513f, 0.001f);
|
||||
EXPECT_NEAR(result.W, 0.86602540f, 0.001f);
|
||||
hmm_quaternion result = HMM_NLerp(from, 0.5f, to);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.28867513f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.28867513f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -0.28867513f);
|
||||
EXPECT_FLOAT_EQ(result.W, 0.86602540f);
|
||||
}
|
||||
|
||||
TEST(QuaternionOps, SLerp)
|
||||
TEST(QuaternionOps, Slerp)
|
||||
{
|
||||
HMM_Quat from = HMM_Q(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
HMM_Quat to = HMM_Q(0.5f, 0.5f, -0.5f, 0.5f);
|
||||
hmm_quaternion from = HMM_Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
hmm_quaternion to = HMM_Quaternion(0.5f, 0.5f, -0.5f, 0.5f);
|
||||
|
||||
{
|
||||
HMM_Quat result = HMM_SLerp(from, 0.0f, to);
|
||||
EXPECT_NEAR(result.X, 0.0f, 0.001f);
|
||||
EXPECT_NEAR(result.Y, 0.0f, 0.001f);
|
||||
EXPECT_NEAR(result.Z, 0.0f, 0.001f);
|
||||
EXPECT_NEAR(result.W, 1.0, 0.001f);
|
||||
}
|
||||
{
|
||||
HMM_Quat result = HMM_SLerp(from, 0.25f, to);
|
||||
EXPECT_NEAR(result.X, 0.149429246f, 0.001f);
|
||||
EXPECT_NEAR(result.Y, 0.149429246f, 0.001f);
|
||||
EXPECT_NEAR(result.Z, -0.149429246f, 0.001f);
|
||||
EXPECT_NEAR(result.W, 0.965925812f, 0.001f);
|
||||
}
|
||||
{
|
||||
HMM_Quat result = HMM_SLerp(from, 0.5f, to);
|
||||
EXPECT_NEAR(result.X, 0.28867513f, 0.001f);
|
||||
EXPECT_NEAR(result.Y, 0.28867513f, 0.001f);
|
||||
EXPECT_NEAR(result.Z, -0.28867513f, 0.001f);
|
||||
EXPECT_NEAR(result.W, 0.86602540f, 0.001f);
|
||||
}
|
||||
{
|
||||
HMM_Quat result = HMM_SLerp(from, 0.75f, to);
|
||||
EXPECT_NEAR(result.X, 0.40824830f, 0.001f);
|
||||
EXPECT_NEAR(result.Y, 0.40824830f, 0.001f);
|
||||
EXPECT_NEAR(result.Z, -0.40824830f, 0.001f);
|
||||
EXPECT_NEAR(result.W, 0.70710676f, 0.001f);
|
||||
}
|
||||
{
|
||||
HMM_Quat result = HMM_SLerp(from, 1.0f, to);
|
||||
EXPECT_NEAR(result.X, 0.5f, 0.001f);
|
||||
EXPECT_NEAR(result.Y, 0.5f, 0.001f);
|
||||
EXPECT_NEAR(result.Z, -0.5f, 0.001f);
|
||||
EXPECT_NEAR(result.W, 0.5f, 0.001f);
|
||||
}
|
||||
hmm_quaternion result = HMM_Slerp(from, 0.5f, to);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.28867513f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.28867513f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -0.28867513f);
|
||||
EXPECT_FLOAT_EQ(result.W, 0.86602540f);
|
||||
}
|
||||
|
||||
TEST(QuaternionOps, QuatToMat4)
|
||||
{
|
||||
const float abs_error = 0.001f;
|
||||
|
||||
HMM_Quat rot = HMM_Q(0.707107f, 0.0f, 0.0f, 0.707107f);
|
||||
|
||||
HMM_Mat4 result = HMM_QToM4(rot);
|
||||
|
||||
EXPECT_NEAR(result.Elements[0][0], 1.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][1], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][2], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][3], 0.0f, abs_error);
|
||||
|
||||
EXPECT_NEAR(result.Elements[1][0], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][1], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][2], 1.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][3], 0.0f, abs_error);
|
||||
|
||||
EXPECT_NEAR(result.Elements[2][0], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][1], -1.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][2], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][3], 0.0f, abs_error);
|
||||
|
||||
EXPECT_NEAR(result.Elements[3][0], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][1], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][2], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][3], 1.0f, abs_error);
|
||||
}
|
||||
|
||||
TEST(QuaternionOps, Mat4ToQuat)
|
||||
TEST(QuaternionOps, ToMat4)
|
||||
{
|
||||
const float abs_error = 0.0001f;
|
||||
|
||||
// Rotate 90 degrees on the X axis
|
||||
{
|
||||
HMM_Mat4 m = HMM_Rotate_RH(HMM_AngleDeg(90.0f), HMM_V3(1, 0, 0));
|
||||
HMM_Quat result = HMM_M4ToQ_RH(m);
|
||||
// Identity quaternion
|
||||
hmm_quaternion rot = HMM_Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
float cosf = 0.707107f; // cos(90/2 degrees)
|
||||
float sinf = 0.707107f; // sin(90/2 degrees)
|
||||
hmm_mat4 result = HMM_QuaternionToMat4(rot);
|
||||
|
||||
EXPECT_NEAR(result.X, sinf, abs_error);
|
||||
EXPECT_NEAR(result.Y, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Z, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.W, cosf, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][0], 1.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][1], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][2], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][3], 0.0f, abs_error);
|
||||
|
||||
EXPECT_NEAR(result.Elements[1][0], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][1], 1.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][2], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][3], 0.0f, abs_error);
|
||||
|
||||
EXPECT_NEAR(result.Elements[2][0], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][1], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][2], 1.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][3], 0.0f, abs_error);
|
||||
|
||||
EXPECT_NEAR(result.Elements[3][0], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][1], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][2], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][3], 1.0f, abs_error);
|
||||
}
|
||||
|
||||
// Rotate 90 degrees on the Y axis (axis not normalized, just for fun)
|
||||
{
|
||||
HMM_Mat4 m = HMM_Rotate_RH(HMM_AngleDeg(90.0f), HMM_V3(0, 2, 0));
|
||||
HMM_Quat result = HMM_M4ToQ_RH(m);
|
||||
// Straightforward 90 degree rotation
|
||||
hmm_quaternion rot = HMM_Quaternion(0.707107f, 0.0f, 0.0f, 0.707107f);
|
||||
|
||||
float cosf = 0.707107f; // cos(90/2 degrees)
|
||||
float sinf = 0.707107f; // sin(90/2 degrees)
|
||||
hmm_mat4 result = HMM_QuaternionToMat4(rot);
|
||||
|
||||
EXPECT_NEAR(result.X, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Y, sinf, abs_error);
|
||||
EXPECT_NEAR(result.Z, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.W, cosf, abs_error);
|
||||
}
|
||||
EXPECT_NEAR(result.Elements[0][0], 1.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][1], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][2], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][3], 0.0f, abs_error);
|
||||
|
||||
// Rotate 90 degrees on the Z axis
|
||||
{
|
||||
HMM_Mat4 m = HMM_Rotate_RH(HMM_AngleDeg(90.0f), HMM_V3(0, 0, 1));
|
||||
HMM_Quat result = HMM_M4ToQ_RH(m);
|
||||
EXPECT_NEAR(result.Elements[1][0], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][1], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][2], 1.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][3], 0.0f, abs_error);
|
||||
|
||||
float cosf = 0.707107f; // cos(90/2 degrees)
|
||||
float sinf = 0.707107f; // sin(90/2 degrees)
|
||||
EXPECT_NEAR(result.Elements[2][0], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][1], -1.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][2], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][3], 0.0f, abs_error);
|
||||
|
||||
EXPECT_NEAR(result.X, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Y, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Z, sinf, abs_error);
|
||||
EXPECT_NEAR(result.W, cosf, abs_error);
|
||||
}
|
||||
|
||||
// Rotate 45 degrees on the X axis (this hits case 4)
|
||||
{
|
||||
HMM_Mat4 m = HMM_Rotate_RH(HMM_AngleDeg(45.0f), HMM_V3(1, 0, 0));
|
||||
HMM_Quat result = HMM_M4ToQ_RH(m);
|
||||
|
||||
float cosf = 0.9238795325f; // cos(90/2 degrees)
|
||||
float sinf = 0.3826834324f; // sin(90/2 degrees)
|
||||
|
||||
EXPECT_NEAR(result.X, sinf, abs_error);
|
||||
EXPECT_NEAR(result.Y, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Z, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.W, cosf, abs_error);
|
||||
}
|
||||
|
||||
/* NOTE(lcf): Left-handed cases. Since both Rotate and M4ToQ are LH results should be
|
||||
the same with no changes to input. */
|
||||
// Rotate 90 degrees on the X axis
|
||||
{
|
||||
HMM_Mat4 m = HMM_Rotate_LH(HMM_AngleDeg(90.0f), HMM_V3(1, 0, 0));
|
||||
HMM_Quat result = HMM_M4ToQ_LH(m);
|
||||
|
||||
float cosf = 0.707107f; // cos(90/2 degrees)
|
||||
float sinf = 0.707107f; // sin(90/2 degrees)
|
||||
|
||||
EXPECT_NEAR(result.X, sinf, abs_error);
|
||||
EXPECT_NEAR(result.Y, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Z, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.W, cosf, abs_error);
|
||||
}
|
||||
|
||||
// Rotate 90 degrees on the Y axis (axis not normalized, just for fun)
|
||||
{
|
||||
HMM_Mat4 m = HMM_Rotate_LH(HMM_AngleDeg(90.0f), HMM_V3(0, 2, 0));
|
||||
HMM_Quat result = HMM_M4ToQ_LH(m);
|
||||
|
||||
float cosf = 0.707107f; // cos(90/2 degrees)
|
||||
float sinf = 0.707107f; // sin(90/2 degrees)
|
||||
|
||||
EXPECT_NEAR(result.X, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Y, sinf, abs_error);
|
||||
EXPECT_NEAR(result.Z, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.W, cosf, abs_error);
|
||||
}
|
||||
|
||||
// Rotate 90 degrees on the Z axis
|
||||
{
|
||||
HMM_Mat4 m = HMM_Rotate_LH(HMM_AngleDeg(90.0f), HMM_V3(0, 0, 1));
|
||||
HMM_Quat result = HMM_M4ToQ_LH(m);
|
||||
|
||||
float cosf = 0.707107f; // cos(90/2 degrees)
|
||||
float sinf = 0.707107f; // sin(90/2 degrees)
|
||||
|
||||
EXPECT_NEAR(result.X, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Y, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Z, sinf, abs_error);
|
||||
EXPECT_NEAR(result.W, cosf, abs_error);
|
||||
}
|
||||
|
||||
// Rotate 45 degrees on the X axis (this hits case 4)
|
||||
{
|
||||
HMM_Mat4 m = HMM_Rotate_LH(HMM_AngleDeg(45.0f), HMM_V3(1, 0, 0));
|
||||
HMM_Quat result = HMM_M4ToQ_LH(m);
|
||||
|
||||
float cosf = 0.9238795325f; // cos(90/2 degrees)
|
||||
float sinf = 0.3826834324f; // sin(90/2 degrees)
|
||||
|
||||
EXPECT_NEAR(result.X, sinf, abs_error);
|
||||
EXPECT_NEAR(result.Y, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Z, 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.W, cosf, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][0], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][1], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][2], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][3], 1.0f, abs_error);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(QuaternionOps, FromAxisAngle)
|
||||
{
|
||||
HMM_Vec3 axis = HMM_V3(1.0f, 0.0f, 0.0f);
|
||||
hmm_vec3 axis = HMM_Vec3(1.0f, 0.0f, 0.0f);
|
||||
float angle = HMM_PI32 / 2.0f;
|
||||
|
||||
{
|
||||
HMM_Quat result = HMM_QFromAxisAngle_RH(axis, angle);
|
||||
EXPECT_NEAR(result.X, 0.707107f, 0.001f);
|
||||
EXPECT_NEAR(result.Y, 0.0f, 0.001f);
|
||||
EXPECT_NEAR(result.Z, 0.0f, 0.001f);
|
||||
EXPECT_NEAR(result.W, 0.707107f, 0.001f);
|
||||
}
|
||||
{
|
||||
HMM_Quat result = HMM_QFromAxisAngle_LH(axis, angle);
|
||||
EXPECT_NEAR(result.X, -0.707107f, 0.001f);
|
||||
EXPECT_NEAR(result.Y, 0.0f, 0.001f);
|
||||
EXPECT_NEAR(result.Z, 0.0f, 0.001f);
|
||||
EXPECT_NEAR(result.W, 0.707107f, 0.001f);
|
||||
}
|
||||
hmm_quaternion result = HMM_QuaternionFromAxisAngle(axis, angle);
|
||||
EXPECT_NEAR(result.X, 0.707107f, FLT_EPSILON * 2);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.0f);
|
||||
EXPECT_NEAR(result.W, 0.707107f, FLT_EPSILON * 2);
|
||||
}
|
||||
@@ -4,14 +4,14 @@
|
||||
|
||||
TEST(SSE, LinearCombine)
|
||||
{
|
||||
HMM_Mat4 MatrixOne = HMM_M4D(2.0f);
|
||||
HMM_Mat4 MatrixTwo = HMM_M4D(4.0f);
|
||||
HMM_Mat4 Result;
|
||||
hmm_mat4 MatrixOne = HMM_Mat4d(2.0f);
|
||||
hmm_mat4 MatrixTwo = HMM_Mat4d(4.0f);
|
||||
hmm_mat4 Result;
|
||||
|
||||
Result.Columns[0] = HMM_LinearCombineV4M4(MatrixOne.Columns[0], MatrixTwo);
|
||||
Result.Columns[1] = HMM_LinearCombineV4M4(MatrixOne.Columns[1], MatrixTwo);
|
||||
Result.Columns[2] = HMM_LinearCombineV4M4(MatrixOne.Columns[2], MatrixTwo);
|
||||
Result.Columns[3] = HMM_LinearCombineV4M4(MatrixOne.Columns[3], MatrixTwo);
|
||||
Result.Rows[0] = HMM_LinearCombineSSE(MatrixOne.Rows[0], MatrixTwo);
|
||||
Result.Rows[1] = HMM_LinearCombineSSE(MatrixOne.Rows[1], MatrixTwo);
|
||||
Result.Rows[2] = HMM_LinearCombineSSE(MatrixOne.Rows[2], MatrixTwo);
|
||||
Result.Rows[3] = HMM_LinearCombineSSE(MatrixOne.Rows[3], MatrixTwo);
|
||||
|
||||
{
|
||||
EXPECT_FLOAT_EQ(Result.Elements[0][0], 8.0f);
|
||||
@@ -24,11 +24,13 @@ TEST(SSE, LinearCombine)
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][2], 0.0f);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][3], 0.0f);
|
||||
|
||||
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][0], 0.0f);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][1], 0.0f);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][2], 8.0f);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][3], 0.0f);
|
||||
|
||||
|
||||
EXPECT_FLOAT_EQ(Result.Elements[3][0], 0.0f);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[3][1], 0.0f);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[3][2], 0.0f);
|
||||
|
||||
@@ -28,14 +28,35 @@ TEST(ScalarMath, Trigonometry)
|
||||
// checking that things work by default.
|
||||
}
|
||||
|
||||
TEST(ScalarMath, ToRadians)
|
||||
{
|
||||
EXPECT_FLOAT_EQ(HMM_ToRadians(0.0f), 0.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_ToRadians(180.0f), HMM_PI32);
|
||||
EXPECT_FLOAT_EQ(HMM_ToRadians(-180.0f), -HMM_PI32);
|
||||
}
|
||||
|
||||
TEST(ScalarMath, SquareRoot)
|
||||
{
|
||||
EXPECT_FLOAT_EQ(HMM_SqrtF(16.0f), 4.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_SquareRootF(16.0f), 4.0f);
|
||||
}
|
||||
|
||||
TEST(ScalarMath, RSquareRootF)
|
||||
{
|
||||
EXPECT_NEAR(HMM_InvSqrtF(10.0f), 0.31616211f, 0.0001f);
|
||||
EXPECT_NEAR(HMM_RSquareRootF(10.0f), 0.31616211f, 0.0001f);
|
||||
}
|
||||
|
||||
TEST(ScalarMath, Power)
|
||||
{
|
||||
EXPECT_FLOAT_EQ(HMM_Power(2.0f, 0), 1.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_Power(2.0f, 4), 16.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_Power(2.0f, -2), 0.25f);
|
||||
}
|
||||
|
||||
TEST(ScalarMath, PowerF)
|
||||
{
|
||||
EXPECT_FLOAT_EQ(HMM_PowerF(2.0f, 0), 1.0f);
|
||||
EXPECT_NEAR(HMM_PowerF(2.0f, 4.1), 17.148376f, 0.0001f);
|
||||
EXPECT_NEAR(HMM_PowerF(2.0f, -2.5), 0.176777f, 0.0001f);
|
||||
}
|
||||
|
||||
TEST(ScalarMath, Lerp)
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
|
||||
TEST(Subtraction, Vec2)
|
||||
{
|
||||
HMM_Vec2 v2_1 = HMM_V2(1.0f, 2.0f);
|
||||
HMM_Vec2 v2_2 = HMM_V2(3.0f, 4.0f);
|
||||
hmm_vec2 v2_1 = HMM_Vec2(1.0f, 2.0f);
|
||||
hmm_vec2 v2_2 = HMM_Vec2(3.0f, 4.0f);
|
||||
|
||||
{
|
||||
HMM_Vec2 result = HMM_SubV2(v2_1, v2_2);
|
||||
hmm_vec2 result = HMM_SubtractVec2(v2_1, v2_2);
|
||||
EXPECT_FLOAT_EQ(result.X, -2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, -2.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec2 result = HMM_Sub(v2_1, v2_2);
|
||||
hmm_vec2 result = HMM_Subtract(v2_1, v2_2);
|
||||
EXPECT_FLOAT_EQ(result.X, -2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, -2.0f);
|
||||
}
|
||||
{
|
||||
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.Y, -2.0f);
|
||||
}
|
||||
@@ -30,24 +30,24 @@ TEST(Subtraction, Vec2)
|
||||
|
||||
TEST(Subtraction, Vec3)
|
||||
{
|
||||
HMM_Vec3 v3_1 = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
HMM_Vec3 v3_2 = HMM_V3(4.0f, 5.0f, 6.0f);
|
||||
hmm_vec3 v3_1 = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec3 v3_2 = HMM_Vec3(4.0f, 5.0f, 6.0f);
|
||||
|
||||
{
|
||||
HMM_Vec3 result = HMM_SubV3(v3_1, v3_2);
|
||||
hmm_vec3 result = HMM_SubtractVec3(v3_1, v3_2);
|
||||
EXPECT_FLOAT_EQ(result.X, -3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, -3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -3.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec3 result = HMM_Sub(v3_1, v3_2);
|
||||
hmm_vec3 result = HMM_Subtract(v3_1, v3_2);
|
||||
EXPECT_FLOAT_EQ(result.X, -3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, -3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -3.0f);
|
||||
}
|
||||
{
|
||||
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.Y, -3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -3.0f);
|
||||
@@ -62,11 +62,11 @@ TEST(Subtraction, Vec3)
|
||||
|
||||
TEST(Subtraction, Vec4)
|
||||
{
|
||||
HMM_Vec4 v4_1 = HMM_V4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Vec4 v4_2 = HMM_V4(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
hmm_vec4 v4_1 = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_vec4 v4_2 = HMM_Vec4(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
|
||||
{
|
||||
HMM_Vec4 result = HMM_SubV4(v4_1, v4_2);
|
||||
hmm_vec4 result = HMM_SubtractVec4(v4_1, v4_2);
|
||||
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
||||
@@ -74,14 +74,14 @@ TEST(Subtraction, Vec4)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec4 result = HMM_Sub(v4_1, v4_2);
|
||||
hmm_vec4 result = HMM_Subtract(v4_1, v4_2);
|
||||
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, -4.0f);
|
||||
}
|
||||
{
|
||||
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.Y, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
||||
@@ -96,124 +96,10 @@ TEST(Subtraction, Vec4)
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Subtraction, Mat2)
|
||||
{
|
||||
HMM_Mat2 a = HMM_M2();
|
||||
HMM_Mat2 b = HMM_M2();
|
||||
|
||||
int Counter = 1;
|
||||
for (int Column = 0; Column < 2; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 2; ++Row)
|
||||
{
|
||||
a.Elements[Column][Row] = Counter++;
|
||||
}
|
||||
}
|
||||
for (int Column = 0; Column < 2; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 2; ++Row)
|
||||
{
|
||||
b.Elements[Column][Row] = Counter++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat2 result = HMM_SubM2(b,a);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 4.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 4.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 4.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 4.0);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat2 result = HMM_Sub(b,a);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 4.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 4.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 4.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 4.0);
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat2 result = b - a;
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 4.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 4.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 4.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 4.0);
|
||||
}
|
||||
|
||||
b -= a;
|
||||
EXPECT_FLOAT_EQ(b.Elements[0][0], 4.0);
|
||||
EXPECT_FLOAT_EQ(b.Elements[0][1], 4.0);
|
||||
EXPECT_FLOAT_EQ(b.Elements[1][0], 4.0);
|
||||
EXPECT_FLOAT_EQ(b.Elements[1][1], 4.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TEST(Subtraction, Mat3)
|
||||
{
|
||||
HMM_Mat3 a = HMM_M3();
|
||||
HMM_Mat3 b = HMM_M3();
|
||||
|
||||
int Counter = 1;
|
||||
for (int Column = 0; Column < 3; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 3; ++Row)
|
||||
{
|
||||
a.Elements[Column][Row] = Counter++;
|
||||
}
|
||||
}
|
||||
for (int Column = 0; Column < 3; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 3; ++Row)
|
||||
{
|
||||
b.Elements[Column][Row] = Counter++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HMM_Mat3 result = HMM_SubM3(b,a);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 9.0);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat3 result = HMM_Sub(b,a);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 9.0);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 9.0);
|
||||
}
|
||||
|
||||
b -= a;
|
||||
EXPECT_FLOAT_EQ(b.Elements[0][0], 9.0);
|
||||
EXPECT_FLOAT_EQ(b.Elements[0][1], 9.0);
|
||||
EXPECT_FLOAT_EQ(b.Elements[0][2], 9.0);
|
||||
EXPECT_FLOAT_EQ(b.Elements[1][0], 9.0);
|
||||
EXPECT_FLOAT_EQ(b.Elements[1][1], 9.0);
|
||||
EXPECT_FLOAT_EQ(b.Elements[1][2], 9.0);
|
||||
EXPECT_FLOAT_EQ(b.Elements[2][0], 9.0);
|
||||
EXPECT_FLOAT_EQ(b.Elements[2][1], 9.0);
|
||||
EXPECT_FLOAT_EQ(b.Elements[2][2], 9.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Subtraction, Mat4)
|
||||
{
|
||||
HMM_Mat4 m4_1 = HMM_M4(); // will have 1 - 16
|
||||
HMM_Mat4 m4_2 = HMM_M4(); // will have 17 - 32
|
||||
hmm_mat4 m4_1 = HMM_Mat4(); // will have 1 - 16
|
||||
hmm_mat4 m4_2 = HMM_Mat4(); // will have 17 - 32
|
||||
|
||||
// Fill the matrices
|
||||
int Counter = 1;
|
||||
@@ -236,7 +122,7 @@ TEST(Subtraction, Mat4)
|
||||
|
||||
// Test the results
|
||||
{
|
||||
HMM_Mat4 result = HMM_SubM4(m4_1, m4_2);
|
||||
hmm_mat4 result = HMM_SubtractMat4(m4_1, m4_2);
|
||||
for (int Column = 0; Column < 4; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 4; ++Row)
|
||||
@@ -247,7 +133,7 @@ TEST(Subtraction, Mat4)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Mat4 result = HMM_Sub(m4_1, m4_2);
|
||||
hmm_mat4 result = HMM_Subtract(m4_1, m4_2);
|
||||
for (int Column = 0; Column < 4; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 4; ++Row)
|
||||
@@ -257,7 +143,7 @@ TEST(Subtraction, Mat4)
|
||||
}
|
||||
}
|
||||
{
|
||||
HMM_Mat4 result = m4_1 - m4_2;
|
||||
hmm_mat4 result = m4_1 - m4_2;
|
||||
for (int Column = 0; Column < 4; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 4; ++Row)
|
||||
@@ -280,11 +166,11 @@ TEST(Subtraction, Mat4)
|
||||
|
||||
TEST(Subtraction, Quaternion)
|
||||
{
|
||||
HMM_Quat q1 = HMM_Q(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Quat q2 = HMM_Q(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
hmm_quaternion q1 = HMM_Quaternion(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_quaternion q2 = HMM_Quaternion(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
|
||||
{
|
||||
HMM_Quat result = HMM_SubQ(q1, q2);
|
||||
hmm_quaternion result = HMM_SubtractQuaternion(q1, q2);
|
||||
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
||||
@@ -292,14 +178,14 @@ TEST(Subtraction, Quaternion)
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Quat result = HMM_Sub(q1, q2);
|
||||
hmm_quaternion result = HMM_Subtract(q1, q2);
|
||||
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.W, -4.0f);
|
||||
}
|
||||
{
|
||||
HMM_Quat result = q1 - q2;
|
||||
hmm_quaternion result = q1 - q2;
|
||||
EXPECT_FLOAT_EQ(result.X, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, -4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -4.0f);
|
||||
@@ -313,32 +199,3 @@ TEST(Subtraction, Quaternion)
|
||||
EXPECT_FLOAT_EQ(q1.W, -4.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
TEST(UnaryMinus, Vec2)
|
||||
{
|
||||
HMM_Vec2 VectorOne = {1.0f, 2.0f};
|
||||
HMM_Vec2 Result = -VectorOne;
|
||||
EXPECT_FLOAT_EQ(Result.X, -1.0f);
|
||||
EXPECT_FLOAT_EQ(Result.Y, -2.0f);
|
||||
}
|
||||
|
||||
TEST(UnaryMinus, Vec3)
|
||||
{
|
||||
HMM_Vec3 VectorOne = {1.0f, 2.0f, 3.0f};
|
||||
HMM_Vec3 Result = -VectorOne;
|
||||
EXPECT_FLOAT_EQ(Result.X, -1.0f);
|
||||
EXPECT_FLOAT_EQ(Result.Y, -2.0f);
|
||||
EXPECT_FLOAT_EQ(Result.Z, -3.0f);
|
||||
}
|
||||
|
||||
TEST(UnaryMinus, Vec4)
|
||||
{
|
||||
HMM_Vec4 VectorOne = {1.0f, 2.0f, 3.0f, 4.0f};
|
||||
HMM_Vec4 Result = -VectorOne;
|
||||
EXPECT_FLOAT_EQ(Result.X, -1.0f);
|
||||
EXPECT_FLOAT_EQ(Result.Y, -2.0f);
|
||||
EXPECT_FLOAT_EQ(Result.Z, -3.0f);
|
||||
EXPECT_FLOAT_EQ(Result.W, -4.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2,104 +2,76 @@
|
||||
|
||||
TEST(Transformations, Translate)
|
||||
{
|
||||
HMM_Mat4 translate = HMM_Translate(HMM_V3(1.0f, -3.0f, 6.0f));
|
||||
hmm_mat4 translate = HMM_Translate(HMM_Vec3(1.0f, -3.0f, 6.0f));
|
||||
|
||||
HMM_Vec3 original = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
HMM_Vec4 translated = HMM_MulM4V4(translate, HMM_V4V(original, 1));
|
||||
hmm_vec3 original = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec4 translated = HMM_MultiplyMat4ByVec4(translate, HMM_Vec4v(original, 1));
|
||||
|
||||
EXPECT_NEAR(translated.X, 2.0f, 0.001f);
|
||||
EXPECT_NEAR(translated.Y, -1.0f, 0.001f);
|
||||
EXPECT_NEAR(translated.Z, 9.0f, 0.001f);
|
||||
EXPECT_NEAR(translated.W, 1.0f, 0.001f);
|
||||
EXPECT_FLOAT_EQ(translated.X, 2.0f);
|
||||
EXPECT_FLOAT_EQ(translated.Y, -1.0f);
|
||||
EXPECT_FLOAT_EQ(translated.Z, 9.0f);
|
||||
EXPECT_FLOAT_EQ(translated.W, 1.0f);
|
||||
}
|
||||
|
||||
TEST(Transformations, Rotate)
|
||||
{
|
||||
HMM_Vec3 original = HMM_V3(1.0f, 1.0f, 1.0f);
|
||||
hmm_vec3 original = HMM_Vec3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
HMM_Mat4 rotateX = HMM_Rotate_RH(HMM_AngleDeg(90.0f), HMM_V3(1, 0, 0));
|
||||
HMM_Vec4 rotatedX = HMM_MulM4V4(rotateX, HMM_V4V(original, 1));
|
||||
EXPECT_NEAR(rotatedX.X, 1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedX.Y, -1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedX.Z, 1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedX.W, 1.0f, 0.001f);
|
||||
hmm_mat4 rotateX = HMM_Rotate(90, HMM_Vec3(1, 0, 0));
|
||||
hmm_vec4 rotatedX = HMM_MultiplyMat4ByVec4(rotateX, HMM_Vec4v(original, 1));
|
||||
EXPECT_FLOAT_EQ(rotatedX.X, 1.0f);
|
||||
EXPECT_FLOAT_EQ(rotatedX.Y, -1.0f);
|
||||
EXPECT_FLOAT_EQ(rotatedX.Z, 1.0f);
|
||||
EXPECT_FLOAT_EQ(rotatedX.W, 1.0f);
|
||||
|
||||
HMM_Mat4 rotateY = HMM_Rotate_RH(HMM_AngleDeg(90.0f), HMM_V3(0, 1, 0));
|
||||
HMM_Vec4 rotatedY = HMM_MulM4V4(rotateY, HMM_V4V(original, 1));
|
||||
EXPECT_NEAR(rotatedY.X, 1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedY.Y, 1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedY.Z, -1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedY.W, 1.0f, 0.001f);
|
||||
hmm_mat4 rotateY = HMM_Rotate(90, HMM_Vec3(0, 1, 0));
|
||||
hmm_vec4 rotatedY = HMM_MultiplyMat4ByVec4(rotateY, HMM_Vec4v(original, 1));
|
||||
EXPECT_FLOAT_EQ(rotatedY.X, 1.0f);
|
||||
EXPECT_FLOAT_EQ(rotatedY.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(rotatedY.Z, -1.0f);
|
||||
EXPECT_FLOAT_EQ(rotatedY.W, 1.0f);
|
||||
|
||||
HMM_Mat4 rotateZ = HMM_Rotate_RH(HMM_AngleDeg(90.0f), HMM_V3(0, 0, 1));
|
||||
HMM_Vec4 rotatedZ = HMM_MulM4V4(rotateZ, HMM_V4V(original, 1));
|
||||
EXPECT_NEAR(rotatedZ.X, -1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedZ.Y, 1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedZ.Z, 1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedZ.W, 1.0f, 0.001f);
|
||||
|
||||
HMM_Mat4 rotateZLH = HMM_Rotate_LH(HMM_AngleDeg(90.0f), HMM_V3(0, 0, 1));
|
||||
HMM_Vec4 rotatedZLH = HMM_MulM4V4(rotateZLH, HMM_V4V(original, 1));
|
||||
EXPECT_NEAR(rotatedZLH.X, 1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedZLH.Y, -1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedZLH.Z, 1.0f, 0.001f);
|
||||
EXPECT_NEAR(rotatedZLH.W, 1.0f, 0.001f);
|
||||
hmm_mat4 rotateZ = HMM_Rotate(90, HMM_Vec3(0, 0, 1));
|
||||
hmm_vec4 rotatedZ = HMM_MultiplyMat4ByVec4(rotateZ, HMM_Vec4v(original, 1));
|
||||
EXPECT_FLOAT_EQ(rotatedZ.X, -1.0f);
|
||||
EXPECT_FLOAT_EQ(rotatedZ.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(rotatedZ.Z, 1.0f);
|
||||
EXPECT_FLOAT_EQ(rotatedZ.W, 1.0f);
|
||||
}
|
||||
|
||||
TEST(Transformations, Scale)
|
||||
{
|
||||
HMM_Mat4 scale = HMM_Scale(HMM_V3(2.0f, -3.0f, 0.5f));
|
||||
hmm_mat4 scale = HMM_Scale(HMM_Vec3(2.0f, -3.0f, 0.5f));
|
||||
|
||||
HMM_Vec3 original = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
HMM_Vec4 scaled = HMM_MulM4V4(scale, HMM_V4V(original, 1));
|
||||
hmm_vec3 original = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec4 scaled = HMM_MultiplyMat4ByVec4(scale, HMM_Vec4v(original, 1));
|
||||
|
||||
EXPECT_NEAR(scaled.X, 2.0f, 0.001f);
|
||||
EXPECT_NEAR(scaled.Y, -6.0f, 0.001f);
|
||||
EXPECT_NEAR(scaled.Z, 1.5f, 0.001f);
|
||||
EXPECT_NEAR(scaled.W, 1.0f, 0.001f);
|
||||
EXPECT_FLOAT_EQ(scaled.X, 2.0f);
|
||||
EXPECT_FLOAT_EQ(scaled.Y, -6.0f);
|
||||
EXPECT_FLOAT_EQ(scaled.Z, 1.5f);
|
||||
EXPECT_FLOAT_EQ(scaled.W, 1.0f);
|
||||
}
|
||||
|
||||
TEST(Transformations, LookAt)
|
||||
{
|
||||
const float abs_error = 0.001f;
|
||||
const float abs_error = 0.0001f;
|
||||
|
||||
{ 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(HMM_Vec3(1.0f, 0.0f, 0.0f), HMM_Vec3(0.0f, 2.0f, 1.0f), HMM_Vec3(2.0f, 1.0f, 1.0f));
|
||||
|
||||
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][2], 0.408248f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][3], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][0], 0.507093f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][1], 0.276026f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][2], -0.816497f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][3], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][0], -0.845154f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][1], 0.345033f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][2], -0.408248f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][3], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][0], -0.169031f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][1], -0.897085f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][2], -0.408248f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][3], 1.0f, abs_error);
|
||||
}
|
||||
{
|
||||
HMM_Mat4 result = HMM_LookAt_LH(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][1], 0.897085f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][2], -0.408248f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][3], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][0], -0.507093f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][1], 0.276026f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][2], 0.816497f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][3], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][0], 0.845154f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][1], 0.345033f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][2], 0.408248f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][3], 0.0f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][0], 0.169031f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][1], -0.897085f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][2], 0.408248f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][3], 1.0f, 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][2], 0.408248f, abs_error);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][3], 0.0f);
|
||||
EXPECT_NEAR(result.Elements[1][0], 0.507093f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][1], 0.276026f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[1][2], -0.816497f, abs_error);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][3], 0.0f);
|
||||
EXPECT_NEAR(result.Elements[2][0], -0.845154f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][1], 0.345033f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[2][2], -0.408248f, abs_error);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][3], 0.0f);
|
||||
EXPECT_NEAR(result.Elements[3][0], -0.169031f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][1], -0.897085f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[3][2], -0.408248f, abs_error);
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 1.0f);
|
||||
}
|
||||
|
||||
@@ -2,60 +2,60 @@
|
||||
|
||||
TEST(VectorOps, LengthSquared)
|
||||
{
|
||||
HMM_Vec2 v2 = HMM_V2(1.0f, -2.0f);
|
||||
HMM_Vec3 v3 = HMM_V3(1.0f, -2.0f, 3.0f);
|
||||
HMM_Vec4 v4 = HMM_V4(1.0f, -2.0f, 3.0f, 1.0f);
|
||||
hmm_vec2 v2 = HMM_Vec2(1.0f, -2.0f);
|
||||
hmm_vec3 v3 = HMM_Vec3(1.0f, -2.0f, 3.0f);
|
||||
hmm_vec4 v4 = HMM_Vec4(1.0f, -2.0f, 3.0f, 1.0f);
|
||||
|
||||
EXPECT_FLOAT_EQ(HMM_LenSqrV2(v2), 5.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LenSqrV3(v3), 14.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LenSqrV4(v4), 15.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthSquaredVec2(v2), 5.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthSquaredVec3(v3), 14.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthSquaredVec4(v4), 15.0f);
|
||||
|
||||
#ifdef __cplusplus
|
||||
EXPECT_FLOAT_EQ(HMM_LenSqr(v2), 5.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LenSqr(v3), 14.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LenSqr(v4), 15.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthSquared(v2), 5.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthSquared(v3), 14.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthSquared(v4), 15.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(VectorOps, Length)
|
||||
{
|
||||
HMM_Vec2 v2 = HMM_V2(1.0f, -9.0f);
|
||||
HMM_Vec3 v3 = HMM_V3(2.0f, -3.0f, 6.0f);
|
||||
HMM_Vec4 v4 = HMM_V4(2.0f, -3.0f, 6.0f, 12.0f);
|
||||
hmm_vec2 v2 = HMM_Vec2(1.0f, -9.0f);
|
||||
hmm_vec3 v3 = HMM_Vec3(2.0f, -3.0f, 6.0f);
|
||||
hmm_vec4 v4 = HMM_Vec4(2.0f, -3.0f, 6.0f, 12.0f);
|
||||
|
||||
EXPECT_FLOAT_EQ(HMM_LenV2(v2), 9.0553856f);
|
||||
EXPECT_FLOAT_EQ(HMM_LenV3(v3), 7.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LenV4(v4), 13.892444f);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthVec2(v2), 9.0553856f);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthVec3(v3), 7.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthVec4(v4), 13.892444f);
|
||||
|
||||
#ifdef __cplusplus
|
||||
EXPECT_FLOAT_EQ(HMM_Len(v2), 9.0553856f);
|
||||
EXPECT_FLOAT_EQ(HMM_Len(v3), 7.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_Len(v4), 13.892444f);
|
||||
EXPECT_FLOAT_EQ(HMM_Length(v2), 9.0553856f);
|
||||
EXPECT_FLOAT_EQ(HMM_Length(v3), 7.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_Length(v4), 13.892444f);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(VectorOps, Normalize)
|
||||
{
|
||||
HMM_Vec2 v2 = HMM_V2(1.0f, -2.0f);
|
||||
HMM_Vec3 v3 = HMM_V3(1.0f, -2.0f, 3.0f);
|
||||
HMM_Vec4 v4 = HMM_V4(1.0f, -2.0f, 3.0f, -1.0f);
|
||||
hmm_vec2 v2 = HMM_Vec2(1.0f, -2.0f);
|
||||
hmm_vec3 v3 = HMM_Vec3(1.0f, -2.0f, 3.0f);
|
||||
hmm_vec4 v4 = HMM_Vec4(1.0f, -2.0f, 3.0f, -1.0f);
|
||||
|
||||
{
|
||||
HMM_Vec2 result = HMM_NormV2(v2);
|
||||
EXPECT_NEAR(HMM_LenV2(result), 1.0f, 0.001f);
|
||||
hmm_vec2 result = HMM_NormalizeVec2(v2);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthVec2(result), 1.0f);
|
||||
EXPECT_GT(result.X, 0.0f);
|
||||
EXPECT_LT(result.Y, 0.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec3 result = HMM_NormV3(v3);
|
||||
EXPECT_NEAR(HMM_LenV3(result), 1.0f, 0.001f);
|
||||
hmm_vec3 result = HMM_NormalizeVec3(v3);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthVec3(result), 1.0f);
|
||||
EXPECT_GT(result.X, 0.0f);
|
||||
EXPECT_LT(result.Y, 0.0f);
|
||||
EXPECT_GT(result.Z, 0.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec4 result = HMM_NormV4(v4);
|
||||
EXPECT_NEAR(HMM_LenV4(result), 1.0f, 0.001f);
|
||||
hmm_vec4 result = HMM_NormalizeVec4(v4);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthVec4(result), 1.0f);
|
||||
EXPECT_GT(result.X, 0.0f);
|
||||
EXPECT_LT(result.Y, 0.0f);
|
||||
EXPECT_GT(result.Z, 0.0f);
|
||||
@@ -64,21 +64,21 @@ TEST(VectorOps, Normalize)
|
||||
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec2 result = HMM_Norm(v2);
|
||||
EXPECT_NEAR(HMM_LenV2(result), 1.0f, 0.001f);
|
||||
hmm_vec2 result = HMM_Normalize(v2);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthVec2(result), 1.0f);
|
||||
EXPECT_GT(result.X, 0.0f);
|
||||
EXPECT_LT(result.Y, 0.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec3 result = HMM_Norm(v3);
|
||||
EXPECT_NEAR(HMM_LenV3(result), 1.0f, 0.001f);
|
||||
hmm_vec3 result = HMM_Normalize(v3);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthVec3(result), 1.0f);
|
||||
EXPECT_GT(result.X, 0.0f);
|
||||
EXPECT_LT(result.Y, 0.0f);
|
||||
EXPECT_GT(result.Z, 0.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec4 result = HMM_Norm(v4);
|
||||
EXPECT_NEAR(HMM_LenV4(result), 1.0f, 0.001f);
|
||||
hmm_vec4 result = HMM_Normalize(v4);
|
||||
EXPECT_FLOAT_EQ(HMM_LengthVec4(result), 1.0f);
|
||||
EXPECT_GT(result.X, 0.0f);
|
||||
EXPECT_LT(result.Y, 0.0f);
|
||||
EXPECT_GT(result.Z, 0.0f);
|
||||
@@ -89,23 +89,23 @@ TEST(VectorOps, Normalize)
|
||||
|
||||
TEST(VectorOps, NormalizeZero)
|
||||
{
|
||||
HMM_Vec2 v2 = HMM_V2(0.0f, 0.0f);
|
||||
HMM_Vec3 v3 = HMM_V3(0.0f, 0.0f, 0.0f);
|
||||
HMM_Vec4 v4 = HMM_V4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
hmm_vec2 v2 = HMM_Vec2(0.0f, 0.0f);
|
||||
hmm_vec3 v3 = HMM_Vec3(0.0f, 0.0f, 0.0f);
|
||||
hmm_vec4 v4 = HMM_Vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
{
|
||||
HMM_Vec2 result = HMM_NormV2(v2);
|
||||
hmm_vec2 result = HMM_NormalizeVec2(v2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec3 result = HMM_NormV3(v3);
|
||||
hmm_vec3 result = HMM_NormalizeVec3(v3);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec4 result = HMM_NormV4(v4);
|
||||
hmm_vec4 result = HMM_NormalizeVec4(v4);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.0f);
|
||||
@@ -114,18 +114,18 @@ TEST(VectorOps, NormalizeZero)
|
||||
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec2 result = HMM_Norm(v2);
|
||||
hmm_vec2 result = HMM_Normalize(v2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec3 result = HMM_Norm(v3);
|
||||
hmm_vec3 result = HMM_Normalize(v3);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.0f);
|
||||
}
|
||||
{
|
||||
HMM_Vec4 result = HMM_Norm(v4);
|
||||
hmm_vec4 result = HMM_Normalize(v4);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.0f);
|
||||
@@ -136,22 +136,36 @@ TEST(VectorOps, NormalizeZero)
|
||||
|
||||
TEST(VectorOps, Cross)
|
||||
{
|
||||
HMM_Vec3 v1 = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
HMM_Vec3 v2 = HMM_V3(4.0f, 5.0f, 6.0f);
|
||||
{
|
||||
// Normal cross
|
||||
hmm_vec3 v1 = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec3 v2 = HMM_Vec3(4.0f, 5.0f, 6.0f);
|
||||
|
||||
HMM_Vec3 result = HMM_Cross(v1, v2);
|
||||
hmm_vec3 result = HMM_Cross(v1, v2);
|
||||
|
||||
EXPECT_FLOAT_EQ(result.X, -3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -3.0f);
|
||||
EXPECT_FLOAT_EQ(result.X, -3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, -3.0f);
|
||||
}
|
||||
|
||||
{
|
||||
// Vector with itself
|
||||
hmm_vec3 v = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
|
||||
hmm_vec3 result = HMM_Cross(v, v);
|
||||
|
||||
EXPECT_FLOAT_EQ(result.X, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(VectorOps, DotVec2)
|
||||
{
|
||||
HMM_Vec2 v1 = HMM_V2(1.0f, 2.0f);
|
||||
HMM_Vec2 v2 = HMM_V2(3.0f, 4.0f);
|
||||
hmm_vec2 v1 = HMM_Vec2(1.0f, 2.0f);
|
||||
hmm_vec2 v2 = HMM_Vec2(3.0f, 4.0f);
|
||||
|
||||
EXPECT_FLOAT_EQ(HMM_DotV2(v1, v2), 11.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_DotVec2(v1, v2), 11.0f);
|
||||
#ifdef __cplusplus
|
||||
EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 11.0f);
|
||||
#endif
|
||||
@@ -159,10 +173,10 @@ TEST(VectorOps, DotVec2)
|
||||
|
||||
TEST(VectorOps, DotVec3)
|
||||
{
|
||||
HMM_Vec3 v1 = HMM_V3(1.0f, 2.0f, 3.0f);
|
||||
HMM_Vec3 v2 = HMM_V3(4.0f, 5.0f, 6.0f);
|
||||
hmm_vec3 v1 = HMM_Vec3(1.0f, 2.0f, 3.0f);
|
||||
hmm_vec3 v2 = HMM_Vec3(4.0f, 5.0f, 6.0f);
|
||||
|
||||
EXPECT_FLOAT_EQ(HMM_DotV3(v1, v2), 32.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_DotVec3(v1, v2), 32.0f);
|
||||
#ifdef __cplusplus
|
||||
EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 32.0f);
|
||||
#endif
|
||||
@@ -170,113 +184,11 @@ TEST(VectorOps, DotVec3)
|
||||
|
||||
TEST(VectorOps, DotVec4)
|
||||
{
|
||||
HMM_Vec4 v1 = HMM_V4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
HMM_Vec4 v2 = HMM_V4(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
hmm_vec4 v1 = HMM_Vec4(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
hmm_vec4 v2 = HMM_Vec4(5.0f, 6.0f, 7.0f, 8.0f);
|
||||
|
||||
EXPECT_FLOAT_EQ(HMM_DotV4(v1, v2), 70.0f);
|
||||
EXPECT_FLOAT_EQ(HMM_DotVec4(v1, v2), 70.0f);
|
||||
#ifdef __cplusplus
|
||||
EXPECT_FLOAT_EQ(HMM_Dot(v1, v2), 70.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(VectorOps, LerpV2)
|
||||
{
|
||||
HMM_Vec2 v1 = HMM_V2(1.0f, 0.0f);
|
||||
HMM_Vec2 v2 = HMM_V2(0.0f, 1.0f);
|
||||
|
||||
{
|
||||
HMM_Vec2 result = HMM_LerpV2(v1, 0.5, v2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.5f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec2 result = HMM_Lerp(v1, 0.5, v2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 0.5f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(VectorOps, LerpV3)
|
||||
{
|
||||
HMM_Vec3 v1 = HMM_V3(1.0f, 1.0f, 0.0f);
|
||||
HMM_Vec3 v2 = HMM_V3(0.0f, 1.0f, 1.0f);
|
||||
|
||||
{
|
||||
HMM_Vec3 result = HMM_LerpV3(v1, 0.5, v2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.5f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec3 result = HMM_Lerp(v1, 0.5, v2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.5f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(VectorOps, LerpV4)
|
||||
{
|
||||
HMM_Vec4 v1 = HMM_V4(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
HMM_Vec4 v2 = HMM_V4(0.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
{
|
||||
HMM_Vec4 result = HMM_LerpV4(v1, 0.5, v2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.W, 1.0f);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
HMM_Vec4 result = HMM_Lerp(v1, 0.5, v2);
|
||||
EXPECT_FLOAT_EQ(result.X, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.Y, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Z, 0.5f);
|
||||
EXPECT_FLOAT_EQ(result.W, 1.0f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* MatrixOps tests
|
||||
*/
|
||||
|
||||
TEST(MatrixOps, TransposeM4)
|
||||
{
|
||||
HMM_Mat4 m4 = HMM_M4(); // will have 1 - 16
|
||||
|
||||
// Fill the matrix
|
||||
int Counter = 1;
|
||||
for (int Column = 0; Column < 4; ++Column)
|
||||
{
|
||||
for (int Row = 0; Row < 4; ++Row)
|
||||
{
|
||||
m4.Elements[Column][Row] = Counter;
|
||||
++Counter;
|
||||
}
|
||||
}
|
||||
|
||||
// Test the matrix
|
||||
HMM_Mat4 result = HMM_TransposeM4(m4);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][1], 5.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][2], 9.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[0][3], 13.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][1], 6.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][2], 10.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[1][3], 14.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][0], 3.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][1], 7.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][2], 11.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[2][3], 15.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][0], 4.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][1], 8.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][2], 12.0f);
|
||||
EXPECT_FLOAT_EQ(result.Elements[3][3], 16.0f);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#include "HandmadeTest.h"
|
||||
#include "hmm_test.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
int tests_failed = hmt_run_all_tests();
|
||||
int coverage_failed = hmt_check_all_coverage();
|
||||
|
||||
return tests_failed || coverage_failed;
|
||||
return hmt_run_all_tests();
|
||||
}
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
#include <float.h>
|
||||
|
||||
#define HANDMADE_TEST_IMPLEMENTATION
|
||||
#include "HandmadeTest.h"
|
||||
|
||||
#undef COVERAGE // Make sure we don't double-define initializers from the header part
|
||||
#include "../HandmadeMath.h"
|
||||
|
||||
#include "categories/ScalarMath.h"
|
||||
#include "categories/Initialization.h"
|
||||
#include "categories/VectorOps.h"
|
||||
#include "categories/MatrixOps.h"
|
||||
#include "categories/QuaternionOps.h"
|
||||
#include "categories/Addition.h"
|
||||
#include "categories/Subtraction.h"
|
||||
#include "categories/Multiplication.h"
|
||||
#include "categories/Division.h"
|
||||
#include "categories/Equality.h"
|
||||
#include "categories/Initialization.h"
|
||||
#include "categories/MatrixOps.h"
|
||||
#include "categories/Multiplication.h"
|
||||
#include "categories/Projection.h"
|
||||
#include "categories/Transformation.h"
|
||||
#include "categories/QuaternionOps.h"
|
||||
#include "categories/ScalarMath.h"
|
||||
#include "categories/SSE.h"
|
||||
#include "categories/Subtraction.h"
|
||||
#include "categories/Transformation.h"
|
||||
#include "categories/VectorOps.h"
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
@echo off
|
||||
|
||||
if not exist "build" mkdir build
|
||||
pushd build
|
||||
|
||||
clang-cl /Fehmm_test_c.exe ..\HandmadeMath.c ..\hmm_test.c
|
||||
hmm_test_c
|
||||
|
||||
clang-cl /Fehmm_test_c_no_sse.exe /DHANDMADE_MATH_NO_SSE ..\HandmadeMath.c ..\hmm_test.c
|
||||
hmm_test_c_no_sse
|
||||
|
||||
clang-cl /Fehmm_test_cpp.exe ..\HandmadeMath.cpp ..\hmm_test.cpp
|
||||
hmm_test_cpp
|
||||
|
||||
clang-cl /Fehmm_test_cpp_no_sse.exe /DHANDMADE_MATH_NO_SSE ..\HandmadeMath.cpp ..\hmm_test.cpp
|
||||
hmm_test_cpp_no_sse
|
||||
|
||||
popd
|
||||
@@ -1,27 +0,0 @@
|
||||
@echo off
|
||||
|
||||
if "%1%"=="travis" (
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat" -host_arch=amd64 -arch=amd64
|
||||
) else (
|
||||
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
|
||||
pushd build
|
||||
|
||||
cl /Fehmm_test_c.exe ..\HandmadeMath.c ..\hmm_test.c
|
||||
hmm_test_c
|
||||
|
||||
cl /Fehmm_test_c_no_sse.exe /DHANDMADE_MATH_NO_SSE ..\HandmadeMath.c ..\hmm_test.c
|
||||
hmm_test_c_no_sse
|
||||
|
||||
cl /Fehmm_test_cpp.exe ..\HandmadeMath.cpp ..\hmm_test.cpp
|
||||
hmm_test_cpp
|
||||
|
||||
cl /Fehmm_test_cpp_no_sse.exe /DHANDMADE_MATH_NO_SSE ..\HandmadeMath.cpp ..\hmm_test.cpp
|
||||
hmm_test_cpp_no_sse
|
||||
|
||||
popd
|
||||
@@ -1,24 +0,0 @@
|
||||
# Handmade Math 2.0 Update Tool
|
||||
|
||||
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).
|
||||
|
||||
**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.
|
||||
|
||||
```
|
||||
# see usage info and options
|
||||
> python3 update_hmm.py -h
|
||||
usage: update_hmm [-h] [--exts .foo [.foo ...]] filename [filename ...]
|
||||
...
|
||||
|
||||
# run on individual files
|
||||
> python3 update_hmm.py MyPlatformLayer.c MyPlatformLayer.h
|
||||
Updating: MyPlatformLayer.c
|
||||
Updating: MyPlatformLayer.h
|
||||
Updated 2 files with 0 warnings.
|
||||
|
||||
# run on a whole directory
|
||||
> python3 update_hmm.py projects/MyCoolGame
|
||||
Updating: projects/MyCoolGame/src/MyPlatformLayer.c
|
||||
Updating: projects/MyCoolGame/include/MyPlatformLayer.h
|
||||
...
|
||||
```
|
||||
@@ -1,166 +0,0 @@
|
||||
#!/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))
|
||||
Reference in New Issue
Block a user