From 8b14924da38593e65b43587843e4b0fac7f3234d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Wed, 2 Jul 2025 12:43:42 +0200 Subject: [PATCH] feat(tests_vec3f): add vec3 tests --- .github/workflows/cmake-multi-platform.yml | 2 +- CMakeLists.txt | 12 +- src/math/vec3.c | 13 +- tests/tests.c | 305 --------------------- tests/tests_config.c | 16 ++ tests/tests_vec3f.c | 147 ++++++++++ tests/tests_vec4f.c | 153 +++++++++++ 7 files changed, 327 insertions(+), 321 deletions(-) delete mode 100644 tests/tests.c create mode 100644 tests/tests_config.c create mode 100644 tests/tests_vec3f.c create mode 100644 tests/tests_vec4f.c diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index 40255d1..abfd8de 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -73,4 +73,4 @@ jobs: working-directory: ${{ steps.strings.outputs.build-output-dir }} # Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest --build-config ${{ matrix.build_type }} \ No newline at end of file + run: ctest --build-config ${{ matrix.build_type }} --verbose \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 5695373..da50691 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,10 +18,8 @@ enable_testing() file(GLOB_RECURSE TEST_SOURCES CONFIGURE_DEPENDS tests/*.c) list(FILTER SOURCES EXCLUDE REGEX ".*src/main\\.c$") -if(TEST_SOURCES) - add_executable(tests ${TEST_SOURCES} ${SOURCES}) - if(NOT MSVC) - target_link_libraries(tests m) - endif() - add_test(NAME tests COMMAND tests) -endif() +foreach(test_src ${TEST_SOURCES}) + get_filename_component(test_name ${test_src} NAME_WE) + add_executable(${test_name} ${test_src} ${SOURCES}) + add_test(NAME ${test_name} COMMAND ${test_name}) +endforeach() \ No newline at end of file diff --git a/src/math/vec3.c b/src/math/vec3.c index 162d3be..48ce8b5 100644 --- a/src/math/vec3.c +++ b/src/math/vec3.c @@ -28,25 +28,22 @@ Vec3f_t vec3f_from_array(const float *__restrict val) Vec3f_t vec3f_scalar(float f) { - Vec3f_t vec4; + Vec3f_t vec3; -// store f x 4 in register -// add all register into data #if defined(SIMD_X86) __m128 scalar = _mm_set1_ps(f); - _mm_store_ps(vec4.data, scalar); + _mm_store_ps(vec3.data, scalar); #elif defined(SIMD_ARCH) float32x4_t scalar = vdupq_n_f32(f); - vst1q_f32(vec4.data, scalar); + vst1q_f32(vec3.data, scalar); -// add one by one each value to their specific address #else for (int i = 0; i < VEC_SIZE; i++) { - vec4.data[i] = f; + vec3.data[i] = f; } #endif - return vec4; + return vec3; } Vec3f_t vec3f_zero(void) diff --git a/tests/tests.c b/tests/tests.c deleted file mode 100644 index bf72d88..0000000 --- a/tests/tests.c +++ /dev/null @@ -1,305 +0,0 @@ -// -// tests.c -// tests -// -// Created by Loïc GUEZO on 26/06/2025. -// - -#include -#include -#include "../src/math/mconfig.h" -#include "../src/math/vec3.h" -#include "../src/math/vec4.h" - -#define EPSILON 1e-6f - -void test_vec3f_creation() { - Vec3f_t v = vec3f(1.f, 2.f, 3.f); - assert(fabsf(v.x - 1.f) < EPSILON); - assert(fabsf(v.y - 2.f) < EPSILON); - assert(fabsf(v.z - 3.f) < EPSILON); -} - -// a -> [1, 2, 3] -// b -> [5, 6, 7] -// r -> [6, 8, 10] -void test_vec3f_add() { - Vec3f_t a = vec3f(1.f, 2.f, 3.f); - Vec3f_t b = vec3f(5.f, 6.f, 7.f); - Vec3f_t r = vec3f_add(a, b); - assert(fabsf(r.x - 6.f) < EPSILON); - assert(fabsf(r.y - 8.f) < EPSILON); - assert(fabsf(r.z - 10.f) < EPSILON); -} - -// a -> [5, 6, 7] -// b -> [1, 2, 3] -// r -> [4, 4, 4] -void test_vec3f_sub() { - Vec3f_t a = vec3f(5.f, 6.f, 7.f); - Vec3f_t b = vec3f(1.f, 2.f, 3.f); - Vec3f_t r = vec3f_sub(a, b); - - assert(fabsf(r.x - 4.f) < EPSILON); - assert(fabsf(r.y - 4.f) < EPSILON); - assert(fabsf(r.z - 4.f) < EPSILON); -} -// a -> [1, 2, 3] -// r -> [2, 4, 6] -void test_vec3f_scale() { - Vec3f_t a = vec3f(1.f, 2.f, 3.f); - Vec3f_t r = vec3f_scale(a, 2.f); - assert(fabsf(r.x - 2.f) < EPSILON); - assert(fabsf(r.y - 4.f) < EPSILON); - assert(fabsf(r.z - 6.f) < EPSILON); -} - -// dot product: -// + : same direction -// 0 : orthgonal -// - : opposite direction -void test_vec3f_dot() { - Vec3f_t a = vec3f(1.f, 2.f, 3.f); - Vec3f_t b = vec3f(5.f, 6.f, 7.f); - float d = vec3f_dot(a, b); - assert(fabsf(d - (1*5 + 2*6 + 3*7)) < EPSILON); -} - -// normalize: -// [4, 0, 0] -> [1, 0, 0] -void test_vec3f_norm() { - Vec3f_t v = vec3f(3.f, 0.f, 0.f); - Vec3f_t n = vec3f_norm(v); - assert(fabsf(n.x - 1.f) < EPSILON); - assert(fabsf(n.y) < EPSILON); - assert(fabsf(n.z) < EPSILON); -} - -// lerp: -// return vector between a and b -// if t = 0.5 -// a = [0, 0, 0] -// b = [3, 3, 3] -// r = [1.5, 1.5, 1.5] (t = 0.5) is middle -void test_vec3f_lerp() { - Vec3f_t a = vec3f(0.f, 0.f, 0.f); - Vec3f_t b = vec3f(1.f, 1.f, 1.f); - Vec3f_t r = vec3f_lerp(a, b, 0.5f); - assert(fabsf(r.x - 0.5f) < EPSILON); - assert(fabsf(r.y - 0.5f) < EPSILON); - assert(fabsf(r.z - 0.5f) < EPSILON); -} - -// angle: -// return angle of two vectors -void test_vec3f_angle() { - Vec3f_t a = vec3f(1.f, 0.f, 0.f); - Vec3f_t b = vec3f(0.f, 1.f, 0.f); - float angle = vec3f_angle(a, b); - assert(fabsf(angle - (float)(M_PI / 2)) < EPSILON); -} - -// proj: -// return size of a on b -void test_vec3f_proj() { - Vec3f_t a = vec3f(2.f, 0.f, 0.f); - Vec3f_t b = vec3f(1.f, 0.f, 0.f); - Vec3f_t r = vec3f_proj(a, b); - assert(fabsf(r.x - 2.f) < EPSILON); - assert(fabsf(r.y) < EPSILON); - assert(fabsf(r.z) < EPSILON); -} - -// refl: -// return a bounce vector -// raytracing -void test_vec3f_refl() { - Vec3f_t v = vec3f(1.f, -1.f, 0.f); - Vec3f_t normal = vec3f(0.f, 1.f, 0.f); - Vec3f_t r = vec3f_refl(v, normal); - assert(fabsf(r.x - 1.f) < EPSILON); - assert(fabsf(r.y - 1.f) < EPSILON); - assert(fabsf(r.z) < EPSILON); -} - -// dist: -// return distance between two vectors -void test_vec3f_dist() { - Vec3f_t a = vec3f(1.f, 0.f, 0.f); - Vec3f_t b = vec3f(0.f, 0.f, 0.f); - float d = vec3f_dist(a, b); - assert(fabsf(d - 1.f) < EPSILON); -} - -void test_vec4f_creation() { - Vec4f_t v = vec4f(1.f, 2.f, 3.f, 4.f); - assert(fabsf(v.x - 1.f) < EPSILON); - assert(fabsf(v.y - 2.f) < EPSILON); - assert(fabsf(v.z - 3.f) < EPSILON); - assert(fabsf(v.w - 4.f) < EPSILON); -} - -// a -> [1, 2, 3, 4] -// b -> [5, 6, 7, 8] -// r -> [6, 8, 10, 12] -void test_vec4f_add() { - Vec4f_t a = vec4f(1.f, 2.f, 3.f, 4.f); - Vec4f_t b = vec4f(5.f, 6.f, 7.f, 8.f); - Vec4f_t r = vec4f_add(a, b); - assert(fabsf(r.x - 6.f) < EPSILON); - assert(fabsf(r.y - 8.f) < EPSILON); - assert(fabsf(r.z - 10.f) < EPSILON); - assert(fabsf(r.w - 12.f) < EPSILON); -} - -// a -> [5, 6, 7, 8] -// b -> [1, 2, 3, 4] -// r -> [4, 4, 4, 4] -void test_vec4f_sub() { - Vec4f_t a = vec4f(5.f, 6.f, 7.f, 8.f); - Vec4f_t b = vec4f(1.f, 2.f, 3.f, 4.f); - Vec4f_t r = vec4f_sub(a, b); - - assert(fabsf(r.x - 4.f) < EPSILON); - assert(fabsf(r.y - 4.f) < EPSILON); - assert(fabsf(r.z - 4.f) < EPSILON); - assert(fabsf(r.w - 4.f) < EPSILON); -} -// a -> [1, 2, 3, 4] -// r -> [2, 4, 6, 8] -void test_vec4f_scale() { - Vec4f_t a = vec4f(1.f, 2.f, 3.f, 4.f); - Vec4f_t r = vec4f_scale(a, 2.f); - assert(fabsf(r.x - 2.f) < EPSILON); - assert(fabsf(r.y - 4.f) < EPSILON); - assert(fabsf(r.z - 6.f) < EPSILON); - assert(fabsf(r.w - 8.f) < EPSILON); -} - -// dot product: -// + : same direction -// 0 : orthgonal -// - : opposite direction -void test_vec4f_dot() { - Vec4f_t a = vec4f(1.f, 2.f, 3.f, 4.f); - Vec4f_t b = vec4f(5.f, 6.f, 7.f, 8.f); - float d = vec4f_dot(a, b); - assert(fabsf(d - (1*5 + 2*6 + 3*7 + 4*8)) < EPSILON); -} - -// normalize: -// [4, 0, 0, 0] -> [1, 0, 0, 0] -void test_vec4f_norm() { - Vec4f_t v = vec4f(3.f, 0.f, 0.f, 0.f); - Vec4f_t n = vec4f_norm(v); - assert(fabsf(n.x - 1.f) < EPSILON); - assert(fabsf(n.y) < EPSILON); - assert(fabsf(n.z) < EPSILON); - assert(fabsf(n.w) < EPSILON); -} - -// lerp: -// return vector between a and b -// if t = 0.5 -// a = [0, 0, 0, 0] -// b = [3, 3, 3, 3] -// r = [1.5, 1.5, 1.5, 1.5] (t = 0.5) is middle -void test_vec4f_lerp() { - Vec4f_t a = vec4f(0.f, 0.f, 0.f, 0.f); - Vec4f_t b = vec4f(1.f, 1.f, 1.f, 1.f); - Vec4f_t r = vec4f_lerp(a, b, 0.5f); - assert(fabsf(r.x - 0.5f) < EPSILON); - assert(fabsf(r.y - 0.5f) < EPSILON); - assert(fabsf(r.z - 0.5f) < EPSILON); - assert(fabsf(r.w - 0.5f) < EPSILON); -} - -// angle: -// return angle of two vectors -void test_vec4f_angle() { - Vec4f_t a = vec4f(1.f, 0.f, 0.f, 0.f); - Vec4f_t b = vec4f(0.f, 1.f, 0.f, 0.f); - float angle = vec4f_angle(a, b); - assert(fabsf(angle - (float)(M_PI / 2)) < EPSILON); -} - -// proj: -// return size of a on b -void test_vec4f_proj() { - Vec4f_t a = vec4f(2.f, 0.f, 0.f, 0.f); - Vec4f_t b = vec4f(1.f, 0.f, 0.f, 0.f); - Vec4f_t r = vec4f_proj(a, b); - assert(fabsf(r.x - 2.f) < EPSILON); - assert(fabsf(r.y) < EPSILON); - assert(fabsf(r.z) < EPSILON); - assert(fabsf(r.w) < EPSILON); -} - -// refl: -// return a bounce vector -// raytracing -void test_vec4f_refl() { - Vec4f_t v = vec4f(1.f, -1.f, 0.f, 0.f); - Vec4f_t normal = vec4f(0.f, 1.f, 0.f, 0.f); - Vec4f_t r = vec4f_refl(v, normal); - assert(fabsf(r.x - 1.f) < EPSILON); - assert(fabsf(r.y - 1.f) < EPSILON); - assert(fabsf(r.z) < EPSILON); - assert(fabsf(r.w) < EPSILON); -} - -// dist: -// return distance between two vectors -void test_vec4f_dist() { - Vec4f_t a = vec4f(1.f, 0.f, 0.f, 0.f); - Vec4f_t b = vec4f(0.f, 0.f, 0.f, 0.f); - float d = vec4f_dist(a, b); - assert(fabsf(d - 1.f) < EPSILON); -} - -void run_all_tests_vec4f() { - test_vec4f_creation(); - test_vec4f_add(); - test_vec4f_sub(); - test_vec4f_scale(); - test_vec4f_dot(); - test_vec4f_norm(); - test_vec4f_lerp(); - test_vec4f_angle(); - test_vec4f_proj(); - test_vec4f_refl(); - test_vec4f_dist(); -} - -void run_all_tests_vec3f() { - test_vec3f_creation(); - test_vec3f_add(); - test_vec3f_sub(); - test_vec3f_scale(); - test_vec3f_dot(); - test_vec3f_norm(); - test_vec3f_lerp(); - test_vec3f_angle(); - test_vec3f_proj(); - test_vec3f_refl(); - test_vec3f_dist(); -} - -int main(void) { - - #if defined (SIMD_X86) - printf("SIMD enabled: X86\n"); - #elif defined (SIMD_ARCH) - printf("SIMD enabled: ARCH\n"); - #else - printf("SIMD disabled\n"); - #endif - - printf("vec3f tests... "); - run_all_tests_vec3f(); - printf("Done\n"); - printf("vec4f tests... "); - run_all_tests_vec4f(); - printf("Done\n"); - return 0; // success -} diff --git a/tests/tests_config.c b/tests/tests_config.c new file mode 100644 index 0000000..ab10c51 --- /dev/null +++ b/tests/tests_config.c @@ -0,0 +1,16 @@ +#include "../src/math/mconfig.h" +#include + +void config() { + #if defined (SIMD_X86) + printf("SIMD enabled: X86\n"); + #elif defined (SIMD_ARCH) + printf("SIMD enabled: ARCH\n"); + #else + printf("SIMD disabled\n"); + #endif +} + +int main() { + config(); +} \ No newline at end of file diff --git a/tests/tests_vec3f.c b/tests/tests_vec3f.c new file mode 100644 index 0000000..10c444c --- /dev/null +++ b/tests/tests_vec3f.c @@ -0,0 +1,147 @@ +// +// tests.c +// tests +// +// Created by Loïc GUEZO on 26/06/2025. +// + +#include +#include +#include "../src/math/mconfig.h" +#include "../src/math/vec3.h" +#include "../src/math/vec4.h" + +#define EPSILON 1e-6f + +void test_vec3f_creation() { + Vec3f_t v = vec3f(1.f, 2.f, 3.f); + assert(fabsf(v.x - 1.f) < EPSILON); + assert(fabsf(v.y - 2.f) < EPSILON); + assert(fabsf(v.z - 3.f) < EPSILON); +} + +// a -> [1, 2, 3] +// b -> [5, 6, 7] +// r -> [6, 8, 10] +void test_vec3f_add() { + Vec3f_t a = vec3f(1.f, 2.f, 3.f); + Vec3f_t b = vec3f(5.f, 6.f, 7.f); + Vec3f_t r = vec3f_add(a, b); + assert(fabsf(r.x - 6.f) < EPSILON); + assert(fabsf(r.y - 8.f) < EPSILON); + assert(fabsf(r.z - 10.f) < EPSILON); +} + +// a -> [5, 6, 7] +// b -> [1, 2, 3] +// r -> [4, 4, 4] +void test_vec3f_sub() { + Vec3f_t a = vec3f(5.f, 6.f, 7.f); + Vec3f_t b = vec3f(1.f, 2.f, 3.f); + Vec3f_t r = vec3f_sub(a, b); + + assert(fabsf(r.x - 4.f) < EPSILON); + assert(fabsf(r.y - 4.f) < EPSILON); + assert(fabsf(r.z - 4.f) < EPSILON); +} +// a -> [1, 2, 3] +// r -> [2, 4, 6] +void test_vec3f_scale() { + Vec3f_t a = vec3f(1.f, 2.f, 3.f); + Vec3f_t r = vec3f_scale(a, 2.f); + assert(fabsf(r.x - 2.f) < EPSILON); + assert(fabsf(r.y - 4.f) < EPSILON); + assert(fabsf(r.z - 6.f) < EPSILON); +} + +// dot product: +// + : same direction +// 0 : orthgonal +// - : opposite direction +void test_vec3f_dot() { + Vec3f_t a = vec3f(1.f, 2.f, 3.f); + Vec3f_t b = vec3f(5.f, 6.f, 7.f); + float d = vec3f_dot(a, b); + assert(fabsf(d - (1*5 + 2*6 + 3*7)) < EPSILON); +} + +// normalize: +// [4, 0, 0] -> [1, 0, 0] +void test_vec3f_norm() { + Vec3f_t v = vec3f(3.f, 0.f, 0.f); + Vec3f_t n = vec3f_norm(v); + assert(fabsf(n.x - 1.f) < EPSILON); + assert(fabsf(n.y) < EPSILON); + assert(fabsf(n.z) < EPSILON); +} + +// lerp: +// return vector between a and b +// if t = 0.5 +// a = [0, 0, 0] +// b = [3, 3, 3] +// r = [1.5, 1.5, 1.5] (t = 0.5) is middle +void test_vec3f_lerp() { + Vec3f_t a = vec3f(0.f, 0.f, 0.f); + Vec3f_t b = vec3f(1.f, 1.f, 1.f); + Vec3f_t r = vec3f_lerp(a, b, 0.5f); + assert(fabsf(r.x - 0.5f) < EPSILON); + assert(fabsf(r.y - 0.5f) < EPSILON); + assert(fabsf(r.z - 0.5f) < EPSILON); +} + +// angle: +// return angle of two vectors +void test_vec3f_angle() { + Vec3f_t a = vec3f(1.f, 0.f, 0.f); + Vec3f_t b = vec3f(0.f, 1.f, 0.f); + float angle = vec3f_angle(a, b); + assert(fabsf(angle - (float)(M_PI / 2)) < EPSILON); +} + +// proj: +// return size of a on b +void test_vec3f_proj() { + Vec3f_t a = vec3f(2.f, 0.f, 0.f); + Vec3f_t b = vec3f(1.f, 0.f, 0.f); + Vec3f_t r = vec3f_proj(a, b); + assert(fabsf(r.x - 2.f) < EPSILON); + assert(fabsf(r.y) < EPSILON); + assert(fabsf(r.z) < EPSILON); +} + +// refl: +// return a bounce vector +// raytracing +void test_vec3f_refl() { + Vec3f_t v = vec3f(1.f, -1.f, 0.f); + Vec3f_t normal = vec3f(0.f, 1.f, 0.f); + Vec3f_t r = vec3f_refl(v, normal); + assert(fabsf(r.x - 1.f) < EPSILON); + assert(fabsf(r.y - 1.f) < EPSILON); + assert(fabsf(r.z) < EPSILON); +} + +// dist: +// return distance between two vectors +void test_vec3f_dist() { + Vec3f_t a = vec3f(1.f, 0.f, 0.f); + Vec3f_t b = vec3f(0.f, 0.f, 0.f); + float d = vec3f_dist(a, b); + assert(fabsf(d - 1.f) < EPSILON); +} + +int main(void) { + test_vec3f_creation(); + test_vec3f_add(); + test_vec3f_sub(); + test_vec3f_scale(); + test_vec3f_dot(); + test_vec3f_norm(); + test_vec3f_lerp(); + test_vec3f_angle(); + test_vec3f_proj(); + test_vec3f_refl(); + test_vec3f_dist(); + return 0; // success +} diff --git a/tests/tests_vec4f.c b/tests/tests_vec4f.c new file mode 100644 index 0000000..92dd717 --- /dev/null +++ b/tests/tests_vec4f.c @@ -0,0 +1,153 @@ +// +// tests_vec4f.c +// RUN_TESTS +// +// Created by Loïc GUEZO on 28/06/2025. +// + +#include +#include +#include + +#include "../src/math/vec4.h" + +void test_vec4f_creation() { + Vec4f_t v = vec4f(1.f, 2.f, 3.f, 4.f); + assert(fabsf(v.x - 1.f) < FLT_EPSILON); + assert(fabsf(v.y - 2.f) < FLT_EPSILON); + assert(fabsf(v.z - 3.f) < FLT_EPSILON); + assert(fabsf(v.w - 4.f) < FLT_EPSILON); +} + +// a -> [1, 2, 3, 4] +// b -> [5, 6, 7, 8] +// r -> [6, 8, 10, 12] +void test_vec4f_add() { + Vec4f_t a = vec4f(1.f, 2.f, 3.f, 4.f); + Vec4f_t b = vec4f(5.f, 6.f, 7.f, 8.f); + Vec4f_t r = vec4f_add(a, b); + assert(fabsf(r.x - 6.f) < FLT_EPSILON); + assert(fabsf(r.y - 8.f) < FLT_EPSILON); + assert(fabsf(r.z - 10.f) < FLT_EPSILON); + assert(fabsf(r.w - 12.f) < FLT_EPSILON); +} + +// a -> [5, 6, 7, 8] +// b -> [1, 2, 3, 4] +// r -> [4, 4, 4, 4] +void test_vec4f_sub() { + Vec4f_t a = vec4f(5.f, 6.f, 7.f, 8.f); + Vec4f_t b = vec4f(1.f, 2.f, 3.f, 4.f); + Vec4f_t r = vec4f_sub(a, b); + + assert(fabsf(r.x - 4.f) < FLT_EPSILON); + assert(fabsf(r.y - 4.f) < FLT_EPSILON); + assert(fabsf(r.z - 4.f) < FLT_EPSILON); + assert(fabsf(r.w - 4.f) < FLT_EPSILON); +} +// a -> [1, 2, 3, 4] +// r -> [2, 4, 6, 8] +void test_vec4f_scale() { + Vec4f_t a = vec4f(1.f, 2.f, 3.f, 4.f); + Vec4f_t r = vec4f_scale(a, 2.f); + assert(fabsf(r.x - 2.f) < FLT_EPSILON); + assert(fabsf(r.y - 4.f) < FLT_EPSILON); + assert(fabsf(r.z - 6.f) < FLT_EPSILON); + assert(fabsf(r.w - 8.f) < FLT_EPSILON); +} + +// dot product: +// + : same direction +// 0 : orthgonal +// - : opposite direction +void test_vec4f_dot() { + Vec4f_t a = vec4f(1.f, 2.f, 3.f, 4.f); + Vec4f_t b = vec4f(5.f, 6.f, 7.f, 8.f); + float d = vec4f_dot(a, b); + assert(fabsf(d - (1*5 + 2*6 + 3*7 + 4*8)) < FLT_EPSILON); +} + +// normalize: +// [4, 0, 0, 0] -> [1, 0, 0, 0] +void test_vec4f_norm() { + Vec4f_t v = vec4f(3.f, 0.f, 0.f, 0.f); + Vec4f_t n = vec4f_norm(v); + assert(fabsf(n.x - 1.f) < FLT_EPSILON); + assert(fabsf(n.y) < FLT_EPSILON); + assert(fabsf(n.z) < FLT_EPSILON); + assert(fabsf(n.w) < FLT_EPSILON); +} + +// lerp: +// return vector between a and b +// if t = 0.5 +// a = [0, 0, 0, 0] +// b = [3, 3, 3, 3] +// r = [1.5, 1.5, 1.5, 1.5] (t = 0.5) is middle +void test_vec4f_lerp() { + Vec4f_t a = vec4f(0.f, 0.f, 0.f, 0.f); + Vec4f_t b = vec4f(1.f, 1.f, 1.f, 1.f); + Vec4f_t r = vec4f_lerp(a, b, 0.5f); + assert(fabsf(r.x - 0.5f) < FLT_EPSILON); + assert(fabsf(r.y - 0.5f) < FLT_EPSILON); + assert(fabsf(r.z - 0.5f) < FLT_EPSILON); + assert(fabsf(r.w - 0.5f) < FLT_EPSILON); +} + +// angle: +// return angle of two vectors +void test_vec4f_angle() { + Vec4f_t a = vec4f(1.f, 0.f, 0.f, 0.f); + Vec4f_t b = vec4f(0.f, 1.f, 0.f, 0.f); + float angle = vec4f_angle(a, b); + assert(fabsf(angle - (float)(M_PI / 2)) < FLT_EPSILON); +} + +// proj: +// return size of a on b +void test_vec4f_proj() { + Vec4f_t a = vec4f(2.f, 0.f, 0.f, 0.f); + Vec4f_t b = vec4f(1.f, 0.f, 0.f, 0.f); + Vec4f_t r = vec4f_proj(a, b); + assert(fabsf(r.x - 2.f) < FLT_EPSILON); + assert(fabsf(r.y) < FLT_EPSILON); + assert(fabsf(r.z) < FLT_EPSILON); + assert(fabsf(r.w) < FLT_EPSILON); +} + +// refl: +// return a bounce vector +// raytracing +void test_vec4f_refl() { + Vec4f_t v = vec4f(1.f, -1.f, 0.f, 0.f); + Vec4f_t normal = vec4f(0.f, 1.f, 0.f, 0.f); + Vec4f_t r = vec4f_refl(v, normal); + assert(fabsf(r.x - 1.f) < FLT_EPSILON); + assert(fabsf(r.y - 1.f) < FLT_EPSILON); + assert(fabsf(r.z) < FLT_EPSILON); + assert(fabsf(r.w) < FLT_EPSILON); +} + +// dist: +// return distance between two vectors +void test_vec4f_dist() { + Vec4f_t a = vec4f(1.f, 0.f, 0.f, 0.f); + Vec4f_t b = vec4f(0.f, 0.f, 0.f, 0.f); + float d = vec4f_dist(a, b); + assert(fabsf(d - 1.f) < FLT_EPSILON); +} + +int main(void) { + test_vec4f_creation(); + test_vec4f_add(); + test_vec4f_sub(); + test_vec4f_scale(); + test_vec4f_dot(); + test_vec4f_norm(); + test_vec4f_lerp(); + test_vec4f_angle(); + test_vec4f_proj(); + test_vec4f_refl(); + test_vec4f_dist(); + return 0; // success +}