diff --git a/test/src/test_ray.h b/test/src/test_ray.h index c1b0281..6f2bec5 100644 --- a/test/src/test_ray.h +++ b/test/src/test_ray.h @@ -32,3 +32,43 @@ TEST_IMPL(GLM_PREFIX, ray_triangle) { TEST_SUCCESS } + +TEST_IMPL(GLM_PREFIX, ray_sphere) { + vec4 sphere = {5.0f, 0.0f, 0.0f, 1.0f}; /* Sphere: center at (5, 0, 0) with radius 1 */ + float t1, t2; + bool hit; + + /* Case 1: Ray misses the sphere */ + hit = GLM(ray_sphere)((vec3){10.0f, 3.0f, 0.0f}, (vec3){1.0f, 0.0f, 0.0f}, sphere, &t1, &t2); + ASSERT(!hit); /* Expect no intersection */ + + /* Case 2: Ray starts inside the sphere */ + hit = GLM(ray_sphere)((vec3){5.0f, 0.5f, 0.0f}, (vec3){1.0f, 0.0f, 0.0f}, sphere, &t1, &t2); + ASSERT(hit); /* Expect an intersection */ + ASSERT(t1 < 0 && t2 > 0); /* Ray exits at t2 */ + + /* Case 3: Ray intersects the sphere from outside */ + hit = GLM(ray_sphere)((vec3){0.0f, 0.0f, 0.0f}, (vec3){1.0f, 0.0f, 0.0f}, sphere, &t1, &t2); + ASSERT(hit); /* Expect an intersection */ + ASSERT(t1 > 0 && t2 > 0); /* Intersections at t1 and t2 */ + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, ray_at) { + vec3 origin = {0.0f, 0.0f, 0.0f}; + vec3 direction = {1.0f, 1.0f, 1.0f}; /* Diagonal direction */ + float distance = sqrtf(3.0f); /* Distance along the ray; sqrt(3) for unit length due to direction normalization */ + vec3 result; + + /* Normalize the direction to ensure accurate distance measurement */ + glm_vec3_normalize(direction); + + GLM(ray_at)(origin, direction, distance, result); + ASSERT(fabsf(result[0] - 1.0f) <= 0.0000009); /* Expecting to be 1 unit along the x-axis */ + ASSERT(fabsf(result[1] - 1.0f) <= 0.0000009); /* Expecting to be 1 unit along the y-axis */ + ASSERT(fabsf(result[2] - 1.0f) <= 0.0000009); /* Expecting to be 1 unit along the z-axis */ + + TEST_SUCCESS +} + diff --git a/test/src/test_vec2.h b/test/src/test_vec2.h index aa75b1c..3223165 100644 --- a/test/src/test_vec2.h +++ b/test/src/test_vec2.h @@ -752,3 +752,70 @@ TEST_IMPL(GLM_PREFIX, vec2_make) { TEST_SUCCESS } + +TEST_IMPL(GLM_PREFIX, vec2_reflect) { + vec2 dest; + + /* Reflecting off a "horizontal" surface in 2D */ + vec2 I1 = {1.0f, -1.0f}; /* Incoming vector */ + vec2 N1 = {0.0f, 1.0f}; /* Normal vector */ + GLM(vec2_reflect)(I1, N1, dest); + ASSERT(fabsf(dest[0] - 1.0f) < 0.00001f && + fabsf(dest[1] - 1.0f) < 0.00001f); /* Expect reflection upwards */ + + /* Reflecting at an angle in 2D */ + vec2 I2 = {sqrtf(2)/2, -sqrtf(2)/2}; /* Incoming vector at 45 degrees */ + vec2 N2 = {0.0f, 1.0f}; /* Upwards normal vector */ + GLM(vec2_reflect)(I2, N2, dest); + ASSERT(fabsf(dest[0] - sqrtf(2)/2) < 0.00001f && + fabsf(dest[1] - sqrtf(2)/2) < 0.00001f); /* Expect reflection upwards */ + + /* Reflecting off a line in 2D representing a "vertical" surface analogy */ + vec2 I3 = {1.0f, 0.0f}; /* Incoming vector */ + vec2 N3 = {-1.0f, 0.0f}; /* Normal vector representing a "vertical" line */ + GLM(vec2_reflect)(I3, N3, dest); + ASSERT(fabsf(dest[0] + 1.0f) < 0.00001f && + fabsf(dest[1]) < 0.00001f); /* Expect reflection to the left */ + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_refract) { + vec2 I = {sqrtf(0.5f), -sqrtf(0.5f)}; /* Incoming vector at 45 degrees to normal */ + vec2 N = {0.0f, 1.0f}; /* Surface normal */ + vec2 dest; + float eta; + + /* Water to Air (eta = 1.33/1.0) */ + eta = 1.33f / 1.0f; + GLM(vec2_refract)(I, N, eta, dest); + // In 2D, we expect a similar bending behavior as in 3D, so we check dest[1] + if (!(dest[0] == 0.0f && dest[1] == 0.0f)) { + ASSERT(dest[1] < -sqrtf(0.5f)); // Refracted ray bends away from the normal + } else { + ASSERT(dest[0] == 0.0f && dest[1] == 0.0f); // Total internal reflection + } + + /* Air to Glass (eta = 1.0 / 1.5) */ + eta = 1.0f / 1.5f; + GLM(vec2_refract)(I, N, eta, dest); + ASSERT(dest[1] < -sqrtf(0.5f)); // Expect bending towards the normal + + /* Glass to Water (eta = 1.5 / 1.33) */ + eta = 1.5f / 1.33f; + GLM(vec2_refract)(I, N, eta, dest); + ASSERT(dest[1] < -sqrtf(0.5f)); // Expect bending towards the normal, less bending than air to glass + + /* Diamond to Air (eta = 2.42 / 1.0) */ + eta = 2.42f / 1.0f; + GLM(vec2_refract)(I, N, eta, dest); + if (!(dest[0] == 0.0f && dest[1] == 0.0f)) { + /* High potential for total internal reflection, but if it occurs, expect significant bending */ + ASSERT(dest[1] < -sqrtf(0.5f)); + } else { + ASSERT(dest[0] == 0.0f && dest[1] == 0.0f); // Total internal reflection + } + + TEST_SUCCESS +} + diff --git a/test/src/test_vec3.h b/test/src/test_vec3.h index 65570c0..6fe4df9 100644 --- a/test/src/test_vec3.h +++ b/test/src/test_vec3.h @@ -1840,3 +1840,89 @@ TEST_IMPL(GLM_PREFIX, vec3_make) { TEST_SUCCESS } + +TEST_IMPL(GLM_PREFIX, vec3_faceforward) { + vec3 N = {0.0f, 1.0f, 0.0f}; + vec3 I = {1.0f, -1.0f, 0.0f}; + vec3 Nref = {0.0f, -1.0f, 0.0f}; + vec3 dest; + + GLM(vec3_faceforward)(N, I, Nref, dest); + ASSERT(dest[0] == 0.0f + && dest[1] == -1.0f + && dest[2] == 0.0f); /* Expect N flipped */ + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec3_reflect) { + vec3 dest; + + /* Original test: Reflecting off a horizontal surface */ + vec3 I1 = {1.0f, -1.0f, 0.0f}; /* Incoming vector */ + vec3 N1 = {0.0f, 1.0f, 0.0f}; /* Normal vector */ + GLM(vec3_reflect)(I1, N1, dest); + ASSERT(fabsf(dest[0] - 1.0f) < 0.00001f + && fabsf(dest[1] - 1.0f) < 0.00001f + && fabsf(dest[2] - 0.0f) < 0.00001f); /* Expect reflection */ + + /* Scenario 2: Reflecting off a vertical surface */ + vec3 I2 = {1.0f, 0.0f, 0.0f}; /* Incoming vector */ + vec3 N2 = {-1.0f, 0.0f, 0.0f}; /* Normal vector */ + GLM(vec3_reflect)(I2, N2, dest); + ASSERT(fabsf(dest[0] + 1.0f) < 0.00001f + && fabsf(dest[1]) < 0.00001f + && fabsf(dest[2]) < 0.00001f); /* Expect reflection to the left */ + + /* Scenario 3: Reflecting at an angle */ + vec3 I3 = {sqrtf(2)/2, -sqrtf(2)/2, 0.0f}; /* Incoming vector at 45 degrees */ + vec3 N3 = {0.0f, 1.0f, 0.0f}; /* Upwards normal vector */ + GLM(vec3_reflect)(I3, N3, dest); + ASSERT(fabsf(dest[0] - sqrtf(2)/2) < 0.00001f + && fabsf(dest[1] - sqrtf(2)/2) < 0.00001f + && fabsf(dest[2]) < 0.00001f); /* Expect reflection upwards */ + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec3_refract) { + vec3 I = {sqrtf(0.5f), -sqrtf(0.5f), 0.0f}; /* Incoming vector at 45 degrees to normal */ + vec3 N = {0.0f, 1.0f, 0.0f}; /* Surface normal */ + vec3 dest; + float eta; + + /* Water to Air (eta = 1.33/1.0) */ + eta = 1.33f / 1.0f; + GLM(vec3_refract)(I, N, eta, dest); + if (!(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f)) { + ASSERT(dest[1] < -sqrtf(0.5f)); + } else { + ASSERT(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f); + } + + /* Air to Glass (eta = 1.0 / 1.5) */ + eta = 1.0f / 1.5f; + GLM(vec3_refract)(I, N, eta, dest); + + /* Expect bending towards the normal */ + ASSERT(dest[1] < -sqrtf(0.5f)); + + /* Glass to Water (eta = 1.5 / 1.33) */ + eta = 1.5f / 1.33f; + GLM(vec3_refract)(I, N, eta, dest); + + /* Expect bending towards the normal, less bending than air to glass */ + ASSERT(dest[1] < -sqrtf(0.5f)); + + /* Diamond to Air (eta = 2.42 / 1.0) */ + eta = 2.42f / 1.0f; + GLM(vec3_refract)(I, N, eta, dest); + if (!(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f)) { + /* High potential for total internal reflection, but if it occurs, expect significant bending */ + ASSERT(dest[1] < -sqrtf(0.5f)); + } else { + ASSERT(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f); + } + + TEST_SUCCESS +} diff --git a/test/src/test_vec4.h b/test/src/test_vec4.h index cf73b67..4df471c 100644 --- a/test/src/test_vec4.h +++ b/test/src/test_vec4.h @@ -1536,3 +1536,75 @@ TEST_IMPL(GLM_PREFIX, vec4_make) { TEST_SUCCESS } + +TEST_IMPL(GLM_PREFIX, vec4_reflect) { + vec4 dest; + + /* Original test: Reflecting off a horizontal surface */ + vec4 I1 = {1.0f, -1.0f, 0.0f, 0.0f}; /* Incoming vector */ + vec4 N1 = {0.0f, 1.0f, 0.0f, 0.0f}; /* Normal vector */ + GLM(vec4_reflect)(I1, N1, dest); + ASSERT(fabsf(dest[0] - 1.0f) < 0.00001f && + fabsf(dest[1] - 1.0f) < 0.00001f && + fabsf(dest[2] - 0.0f) < 0.00001f && + fabsf(dest[3] - 0.0f) < 0.00001f); /* Expect reflection */ + + /* Scenario 2: Reflecting off a vertical surface */ + vec4 I2 = {1.0f, 0.0f, 0.0f, 0.0f}; /* Incoming vector */ + vec4 N2 = {-1.0f, 0.0f, 0.0f, 0.0f}; /* Normal vector */ + GLM(vec4_reflect)(I2, N2, dest); + ASSERT(fabsf(dest[0] + 1.0f) < 0.00001f && + fabsf(dest[1]) < 0.00001f && + fabsf(dest[2]) < 0.00001f && + fabsf(dest[3] - 0.0f) < 0.00001f); /* Expect reflection to the left */ + + /* Scenario 3: Reflecting at an angle */ + vec4 I3 = {sqrtf(2)/2, -sqrtf(2)/2, 0.0f, 0.0f}; /* Incoming vector at 45 degrees */ + vec4 N3 = {0.0f, 1.0f, 0.0f, 0.0f}; /* Upwards normal vector */ + GLM(vec4_reflect)(I3, N3, dest); + ASSERT(fabsf(dest[0] - sqrtf(2)/2) < 0.00001f && + fabsf(dest[1] - sqrtf(2)/2) < 0.00001f && + fabsf(dest[2]) < 0.00001f && + fabsf(dest[3] - 0.0f) < 0.00001f); /* Expect reflection upwards */ + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec4_refract) { + vec4 I = {sqrtf(0.5f), -sqrtf(0.5f), 0.0f, 0.0f}; /* Incoming vector */ + vec4 N = {0.0f, 1.0f, 0.0f, 0.0f}; /* Surface normal */ + vec4 dest; + float eta; + + /* Water to Air (eta = 1.33/1.0) */ + eta = 1.33f / 1.0f; + GLM(vec4_refract)(I, N, eta, dest); + if (!(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f && dest[3] == 0.0f)) { + ASSERT(dest[1] < -sqrtf(0.5f)); + } else { + ASSERT(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f && dest[3] == 0.0f); + } + + /* Air to Glass (eta = 1.0 / 1.5) */ + eta = 1.0f / 1.5f; + GLM(vec4_refract)(I, N, eta, dest); + ASSERT(dest[1] < -sqrtf(0.5f)); // Expect bending towards the normal + + /* Glass to Water (eta = 1.5 / 1.33) */ + eta = 1.5f / 1.33f; + GLM(vec4_refract)(I, N, eta, dest); + ASSERT(dest[1] < -sqrtf(0.5f)); // Expect bending towards the normal, less bending than air to glass + + /* Diamond to Air (eta = 2.42 / 1.0) */ + eta = 2.42f / 1.0f; + GLM(vec4_refract)(I, N, eta, dest); + if (!(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f && dest[3] == 0.0f)) { + /* High potential for total internal reflection, but if it occurs, expect significant bending */ + ASSERT(dest[1] < -sqrtf(0.5f)); + } else { + ASSERT(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f && dest[3] == 0.0f); + } + + TEST_SUCCESS +} + diff --git a/test/tests.h b/test/tests.h index e9509bd..d85a155 100644 --- a/test/tests.h +++ b/test/tests.h @@ -392,7 +392,12 @@ TEST_DECLARE(euler) /* ray */ TEST_DECLARE(glm_ray_triangle) +TEST_DECLARE(glm_ray_sphere) +TEST_DECLARE(glm_ray_at) + TEST_DECLARE(glmc_ray_triangle) +TEST_DECLARE(glmc_ray_sphere) +TEST_DECLARE(glmc_ray_at) /* quat */ TEST_DECLARE(MACRO_GLM_QUAT_IDENTITY_INIT) @@ -530,6 +535,8 @@ TEST_DECLARE(glm_vec2_lerp) TEST_DECLARE(glm_vec2_complex_mul) TEST_DECLARE(glm_vec2_complex_div) TEST_DECLARE(glm_vec2_make) +TEST_DECLARE(glm_vec2_reflect) +TEST_DECLARE(glm_vec2_refract) TEST_DECLARE(glmc_vec2) TEST_DECLARE(glmc_vec2_copy) @@ -576,6 +583,8 @@ TEST_DECLARE(glmc_vec2_lerp) TEST_DECLARE(glmc_vec2_complex_mul) TEST_DECLARE(glmc_vec2_complex_div) TEST_DECLARE(glmc_vec2_make) +TEST_DECLARE(glmc_vec2_reflect) +TEST_DECLARE(glmc_vec2_refract) /* vec3 */ TEST_DECLARE(MACRO_GLM_VEC3_ONE_INIT) @@ -678,6 +687,9 @@ TEST_DECLARE(glm_vec3_fract) TEST_DECLARE(glm_vec3_hadd) TEST_DECLARE(glm_vec3_sqrt) TEST_DECLARE(glm_vec3_make) +TEST_DECLARE(glm_vec3_faceforward) +TEST_DECLARE(glm_vec3_reflect) +TEST_DECLARE(glm_vec3_refract) TEST_DECLARE(glmc_vec3) TEST_DECLARE(glmc_vec3_copy) @@ -754,6 +766,9 @@ TEST_DECLARE(glmc_vec3_fract) TEST_DECLARE(glmc_vec3_hadd) TEST_DECLARE(glmc_vec3_sqrt) TEST_DECLARE(glmc_vec3_make) +TEST_DECLARE(glmc_vec3_faceforward) +TEST_DECLARE(glmc_vec3_reflect) +TEST_DECLARE(glmc_vec3_refract) /* vec4 */ TEST_DECLARE(MACRO_GLM_VEC4_ONE_INIT) @@ -842,6 +857,8 @@ TEST_DECLARE(glm_vec4_fract) TEST_DECLARE(glm_vec4_hadd) TEST_DECLARE(glm_vec4_sqrt) TEST_DECLARE(glm_vec4_make) +TEST_DECLARE(glm_vec4_reflect) +TEST_DECLARE(glm_vec4_refract) TEST_DECLARE(glmc_vec4) TEST_DECLARE(glmc_vec4_copy3) @@ -914,6 +931,8 @@ TEST_DECLARE(glmc_vec4_fract) TEST_DECLARE(glmc_vec4_hadd) TEST_DECLARE(glmc_vec4_sqrt) TEST_DECLARE(glmc_vec4_make) +TEST_DECLARE(glmc_vec4_reflect) +TEST_DECLARE(glmc_vec4_refract) /* ivec2 */ TEST_DECLARE(glm_ivec2) @@ -1548,10 +1567,15 @@ TEST_LIST { TEST_ENTRY(glmc_euler_zyx_quat_lh) TEST_ENTRY(euler) - + /* ray */ TEST_ENTRY(glm_ray_triangle) + TEST_ENTRY(glm_ray_sphere) + TEST_ENTRY(glm_ray_at) + TEST_ENTRY(glmc_ray_triangle) + TEST_ENTRY(glmc_ray_sphere) + TEST_ENTRY(glmc_ray_at) /* quat */ TEST_ENTRY(MACRO_GLM_QUAT_IDENTITY_INIT) @@ -1688,6 +1712,8 @@ TEST_LIST { TEST_ENTRY(glm_vec2_complex_mul) TEST_ENTRY(glm_vec2_complex_div) TEST_ENTRY(glm_vec2_make) + TEST_ENTRY(glm_vec2_reflect) + TEST_ENTRY(glm_vec2_refract) TEST_ENTRY(glmc_vec2) TEST_ENTRY(glmc_vec2_copy) @@ -1734,6 +1760,8 @@ TEST_LIST { TEST_ENTRY(glmc_vec2_complex_mul) TEST_ENTRY(glmc_vec2_complex_div) TEST_ENTRY(glmc_vec2_make) + TEST_ENTRY(glmc_vec2_reflect) + TEST_ENTRY(glmc_vec2_refract) /* vec3 */ TEST_ENTRY(MACRO_GLM_VEC3_ONE_INIT) @@ -1835,6 +1863,9 @@ TEST_LIST { TEST_ENTRY(glm_vec3_hadd) TEST_ENTRY(glm_vec3_sqrt) TEST_ENTRY(glm_vec3_make) + TEST_ENTRY(glm_vec3_faceforward) + TEST_ENTRY(glm_vec3_reflect) + TEST_ENTRY(glm_vec3_refract) TEST_ENTRY(glmc_vec3) TEST_ENTRY(glmc_vec3_copy) @@ -1911,6 +1942,9 @@ TEST_LIST { TEST_ENTRY(glmc_vec3_hadd) TEST_ENTRY(glmc_vec3_sqrt) TEST_ENTRY(glmc_vec3_make) + TEST_ENTRY(glmc_vec3_faceforward) + TEST_ENTRY(glmc_vec3_reflect) + TEST_ENTRY(glmc_vec3_refract) /* vec4 */ TEST_ENTRY(MACRO_GLM_VEC4_ONE_INIT) @@ -1999,6 +2033,8 @@ TEST_LIST { TEST_ENTRY(glm_vec4_hadd) TEST_ENTRY(glm_vec4_sqrt) TEST_ENTRY(glm_vec4_make) + TEST_ENTRY(glm_vec4_reflect) + TEST_ENTRY(glm_vec4_refract) TEST_ENTRY(glmc_vec4) TEST_ENTRY(glmc_vec4_copy3) @@ -2071,6 +2107,8 @@ TEST_LIST { TEST_ENTRY(glmc_vec4_hadd) TEST_ENTRY(glmc_vec4_sqrt) TEST_ENTRY(glmc_vec4_make) + TEST_ENTRY(glmc_vec4_reflect) + TEST_ENTRY(glmc_vec4_refract) /* ivec2 */ TEST_ENTRY(glm_ivec2)