Compare commits

..

4 Commits
ray ... v0.9.3

Author SHA1 Message Date
Recep Aslantas
1de373a9bd normalize: norm == 0.0f to norm < FLT_EPSILON, improving handling of very small vectors to prevent instability and overflow 2024-03-25 02:22:46 +03:00
Recep Aslantas
6a7d03bafb suppress warnings 2024-03-25 02:17:03 +03:00
Recep Aslantas
aad5223da0 change signature of refraction to let caller know if refraction occurs or not 2024-03-24 06:31:29 +03:00
Recep Aslantas
707bff021c Merge pull request #399 from recp/ray
Some missing ray functions
2024-03-23 11:26:17 +03:00
20 changed files with 172 additions and 121 deletions

View File

@@ -406,15 +406,19 @@ Functions documentation
| *[in]* **N** *❗️ normalized ❗️* normal vector
| *[out]* **dest** destination: reflection result
.. c:function:: void glm_vec2_refract(vec2 I, vec2 N, float eta, vec2 dest)
.. c:function:: bool glm_vec2_refract(vec2 I, vec2 N, float eta, vec2 dest)
Refraction vector using entering ray, surface normal and refraction index
If the angle between the entering ray I and the surface normal N is too
great for a given refraction index, the return value is zero
Computes refraction vector for an incident vector and a surface normal.
Calculates the refraction vector based on Snell's law. If total internal reflection
occurs (angle too great given eta), dest is set to zero and returns false.
Otherwise, computes refraction vector, stores it in dest, and returns true.
Parameters:
| *[in]* **I** *❗️ normalized ❗️* incident vector
| *[in]* **N** *❗️ normalized ❗️* normal vector
| *[in]* **eta** ratio of indices of refraction ( η )
| *[out]* **dest** destination: refraction result
| *[in]* **eta** ratio of indices of refraction (incident/transmitted)
| *[out]* **dest** refraction vector if refraction occurs; zero vector otherwise
Returns:
returns true if refraction occurs; false if total internal reflection occurs.

View File

@@ -535,15 +535,20 @@ Functions documentation
| *[in]* **N** *❗️ normalized ❗️* normal vector
| *[out]* **dest** destination: reflection result
.. c:function:: void glm_vec3_refract(vec3 I, vec3 N, float eta, vec3 dest)
.. c:function:: bool glm_vec3_refract(vec3 I, vec3 N, float eta, vec3 dest)
Refraction vector using entering ray, surface normal and refraction index
If the angle between the entering ray I and the surface normal N is too
great for a given refraction index, the return value is zero
Computes refraction vector for an incident vector and a surface normal.
Calculates the refraction vector based on Snell's law. If total internal reflection
occurs (angle too great given eta), dest is set to zero and returns false.
Otherwise, computes refraction vector, stores it in dest, and returns true.
Parameters:
| *[in]* **I** *❗️ normalized ❗️* incident vector
| *[in]* **N** *❗️ normalized ❗️* normal vector
| *[in]* **eta** ratio of indices of refraction ( η )
| *[out]* **dest** destination: refraction result
| *[in]* **eta** ratio of indices of refraction (incident/transmitted)
| *[out]* **dest** refraction vector if refraction occurs; zero vector otherwise
Returns:
returns true if refraction occurs; false if total internal reflection occurs.

View File

@@ -427,7 +427,7 @@ Functions documentation
| *[in]* **src** pointer to an array of floats
| *[out]* **dest** destination vector
.. c:function:: void glm_vec4_reflect(vec4 I, vec4 N, vec4 dest)
.. c:function:: bool glm_vec4_reflect(vec4 I, vec4 N, vec4 dest)
Reflection vector using an incident ray and a surface normal
@@ -436,19 +436,23 @@ Functions documentation
| *[in]* **N** *❗️ normalized ❗️* normal vector
| *[out]* **dest** destination: reflection result
.. c:function:: void glm_vec4_refract(vec4 I, vec4 N, float eta, vec4 dest)
.. c:function:: bool glm_vec4_refract(vec4 I, vec4 N, float eta, vec4 dest)
Refraction vector using entering ray, surface normal and refraction index
If the angle between the entering ray I and the surface normal N is too
great for a given refraction index, the return value is zero
this implementation does not explicitly preserve the 'w' component of the
computes refraction vector for an incident vector and a surface normal.
Calculates the refraction vector based on Snell's law. If total internal reflection
occurs (angle too great given eta), dest is set to zero and returns false.
Otherwise, computes refraction vector, stores it in dest, and returns true.
This implementation does not explicitly preserve the 'w' component of the
incident vector 'I' in the output 'dest', users requiring the preservation of
the 'w' component should manually adjust 'dest' after calling this function.
Parameters:
| *[in]* **I** *❗️ normalized ❗️* incident vector
| *[in]* **N** *❗️ normalized ❗️* normal vector
| *[in]* **eta** ratio of indices of refraction ( η )
| *[out]* **dest** destination: refraction result
| *[in]* **eta** ratio of indices of refraction (incident/transmitted)
| *[out]* **dest** refraction vector if refraction occurs; zero vector otherwise
Returns:
returns true if refraction occurs; false if total internal reflection occurs.

View File

@@ -202,7 +202,7 @@ void
glmc_vec2_reflect(vec2 I, vec2 N, vec2 dest);
CGLM_EXPORT
void
bool
glmc_vec2_refract(vec2 I, vec2 N, float eta, vec2 dest);
#ifdef __cplusplus

View File

@@ -343,7 +343,7 @@ void
glmc_vec3_reflect(vec3 I, vec3 N, vec3 dest);
CGLM_EXPORT
void
bool
glmc_vec3_refract(vec3 I, vec3 N, float eta, vec3 dest);
#ifdef __cplusplus

View File

@@ -316,7 +316,7 @@ void
glmc_vec4_reflect(vec4 I, vec4 N, vec4 dest);
CGLM_EXPORT
void
bool
glmc_vec4_refract(vec4 I, vec4 N, float eta, vec4 dest);
#ifdef __cplusplus

View File

@@ -37,6 +37,14 @@
# define CGLM_INLINE static inline __attribute((always_inline))
#endif
#if defined(__GNUC__) || defined(__clang__)
# define CGLM_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
# define CGLM_LIKELY(expr) __builtin_expect(!!(expr), 1)
#else
# define CGLM_UNLIKELY(expr) (expr)
# define CGLM_LIKELY(expr) (expr)
#endif
#define GLM_SHUFFLE4(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w))
#define GLM_SHUFFLE3(z, y, x) (((z) << 4) | ((y) << 2) | (x))

View File

@@ -33,7 +33,7 @@ void
glm_plane_normalize(vec4 plane) {
float norm;
if ((norm = glm_vec3_norm(plane)) == 0.0f) {
if (CGLM_UNLIKELY((norm = glm_vec3_norm(plane)) < FLT_EPSILON)) {
glm_vec4_zero(plane);
return;
}

View File

@@ -55,7 +55,7 @@
CGLM_INLINE vec2s glms_vec2_lerp(vec2s from, vec2s to, float t)
CGLM_INLINE vec2s glms_vec2_make(float * restrict src)
CGLM_INLINE vec2s glms_vec2_reflect(vec2s I, vec2s N)
CGLM_INLINE vec2s glms_vec2_refract(vec2s I, vec2s N, float eta)
CGLM_INLINE bool glms_vec2_refract(vec2s I, vec2s N, float eta, vec2s *dest)
*/
#ifndef cglms_vec2s_h
@@ -709,22 +709,23 @@ glms_vec2_(reflect)(vec2s I, vec2s N) {
}
/*!
* @brief refraction vector using entering ray, surface normal and refraction index
* @brief computes refraction vector for an incident vector and a surface normal.
*
* if the angle between the entering ray I and the surface normal N is too great
* for a given refraction index, the return value is zero
* calculates the refraction vector based on Snell's law. If total internal reflection
* occurs (angle too great given eta), dest is set to zero and returns false.
* Otherwise, computes refraction vector, stores it in dest, and returns true.
*
* @param[in] I normalized incident vector
* @param[in] N normalized normal vector
* @param[in] eta ratio of indices of refraction
* @param[out] dest refraction result
* @param[in] eta ratio of indices of refraction (incident/transmitted)
* @param[out] dest refraction vector if refraction occurs; zero vector otherwise
*
* @returns true if refraction occurs; false if total internal reflection occurs.
*/
CGLM_INLINE
vec2s
glms_vec2_(refract)(vec2s I, vec2s N, float eta) {
vec2s dest;
glm_vec2_refract(I.raw, N.raw, eta, dest.raw);
return dest;
bool
glms_vec2_(refract)(vec2s I, vec2s N, float eta, vec2s * __restrict dest) {
return glm_vec2_refract(I.raw, N.raw, eta, dest->raw);
}
#endif /* cglms_vec2s_h */

View File

@@ -78,7 +78,7 @@
CGLM_INLINE vec3s glms_vec3_make(float * restrict src);
CGLM_INLINE vec3s glms_vec3_faceforward(vec3s N, vec3s I, vec3s Nref);
CGLM_INLINE vec3s glms_vec3_reflect(vec3s I, vec3s N);
CGLM_INLINE vec3s glms_vec3_refract(vec3s I, vec3s N, float eta);
CGLM_INLINE bool glms_vec3_refract(vec3s I, vec3s N, float eta, vec3s *dest)
Convenient:
CGLM_INLINE vec3s glms_cross(vec3s a, vec3s b);
@@ -1120,22 +1120,23 @@ glms_vec3_(reflect)(vec3s I, vec3s N) {
}
/*!
* @brief refraction vector using entering ray, surface normal and refraction index
* @brief computes refraction vector for an incident vector and a surface normal.
*
* if the angle between the entering ray I and the surface normal N is too great
* for a given refraction index, the return value is zero
* calculates the refraction vector based on Snell's law. If total internal reflection
* occurs (angle too great given eta), dest is set to zero and returns false.
* Otherwise, computes refraction vector, stores it in dest, and returns true.
*
* @param[in] I normalized incident vector
* @param[in] N normalized normal vector
* @param[in] eta ratio of indices of refraction
* @returns refraction result
* @param[in] eta ratio of indices of refraction (incident/transmitted)
* @param[out] dest refraction vector if refraction occurs; zero vector otherwise
*
* @returns true if refraction occurs; false if total internal reflection occurs.
*/
CGLM_INLINE
vec3s
glms_vec3_(refract)(vec3s I, vec3s N, float eta) {
vec3s dest;
glm_vec3_refract(I.raw, N.raw, eta, dest.raw);
return dest;
bool
glms_vec3_(refract)(vec3s I, vec3s N, float eta, vec3s * __restrict dest) {
return glm_vec3_refract(I.raw, N.raw, eta, dest->raw);
}
#endif /* cglms_vec3s_h */

View File

@@ -68,7 +68,7 @@
CGLM_INLINE vec4s glms_vec4_swizzle(vec4s v, int mask);
CGLM_INLINE vec4s glms_vec4_make(float * restrict src);
CGLM_INLINE vec4s glms_vec4_reflect(vec4s I, vec4s N);
CGLM_INLINE vec4s glms_vec4_refract(vec4s I, vec4s N, float eta);
CGLM_INLINE bool glms_vec4_refract(vec4s I, vec4s N, float eta, vec4s *dest)
*/
#ifndef cglms_vec4s_h
@@ -945,10 +945,11 @@ glms_vec4_(reflect)(vec4s I, vec4s N) {
}
/*!
* @brief refraction vector using entering ray, surface normal and refraction index
* @brief computes refraction vector for an incident vector and a surface normal.
*
* if the angle between the entering ray I and the surface normal N is too great
* for a given refraction index, the return value is zero
* calculates the refraction vector based on Snell's law. If total internal reflection
* occurs (angle too great given eta), dest is set to zero and returns false.
* Otherwise, computes refraction vector, stores it in dest, and returns true.
*
* this implementation does not explicitly preserve the 'w' component of the
* incident vector 'I' in the output 'dest', users requiring the preservation of
@@ -956,15 +957,15 @@ glms_vec4_(reflect)(vec4s I, vec4s N) {
*
* @param[in] I normalized incident vector
* @param[in] N normalized normal vector
* @param[in] eta ratio of indices of refraction
* @returns refraction result
* @param[in] eta ratio of indices of refraction (incident/transmitted)
* @param[out] dest refraction vector if refraction occurs; zero vector otherwise
*
* @returns true if refraction occurs; false if total internal reflection occurs.
*/
CGLM_INLINE
vec4s
glms_vec4_(refract)(vec4s I, vec4s N, float eta) {
vec4s dest;
glm_vec4_refract(I.raw, N.raw, eta, dest.raw);
return dest;
bool
glms_vec4_(refract)(vec4s I, vec4s N, float eta, vec4s * __restrict dest) {
return glm_vec4_refract(I.raw, N.raw, eta, dest->raw);
}
#endif /* cglms_vec4s_h */

View File

@@ -278,7 +278,7 @@ glm_vec2_scale_as(vec2 v, float s, vec2 dest) {
float norm;
norm = glm_vec2_norm(v);
if (norm == 0.0f) {
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
glm_vec2_zero(dest);
return;
}
@@ -542,7 +542,7 @@ glm_vec2_normalize(vec2 v) {
norm = glm_vec2_norm(v);
if (norm == 0.0f) {
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
v[0] = v[1] = 0.0f;
return;
}
@@ -563,7 +563,7 @@ glm_vec2_normalize_to(vec2 v, vec2 dest) {
norm = glm_vec2_norm(v);
if (norm == 0.0f) {
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
glm_vec2_zero(dest);
return;
}
@@ -729,18 +729,21 @@ glm_vec2_reflect(vec2 I, vec2 N, vec2 dest) {
}
/*!
* @brief refraction vector using entering ray, surface normal and refraction index
* @brief computes refraction vector for an incident vector and a surface normal.
*
* if the angle between the entering ray I and the surface normal N is too great
* for a given refraction index, the return value is zero
* calculates the refraction vector based on Snell's law. If total internal reflection
* occurs (angle too great given eta), dest is set to zero and returns false.
* Otherwise, computes refraction vector, stores it in dest, and returns true.
*
* @param[in] I normalized incident vector
* @param[in] N normalized normal vector
* @param[in] eta ratio of indices of refraction
* @param[out] dest refraction result
* @param[in] eta ratio of indices of refraction (incident/transmitted)
* @param[out] dest refraction vector if refraction occurs; zero vector otherwise
*
* @returns true if refraction occurs; false if total internal reflection occurs.
*/
CGLM_INLINE
void
bool
glm_vec2_refract(vec2 I, vec2 N, float eta, vec2 dest) {
float ndi, eni, k;
@@ -750,11 +753,12 @@ glm_vec2_refract(vec2 I, vec2 N, float eta, vec2 dest) {
if (k < 0.0f) {
glm_vec2_zero(dest);
return;
return false;
}
glm_vec2_scale(I, eta, dest);
glm_vec2_mulsubs(N, eni + sqrtf(k), dest);
return true;
}
#endif /* cglm_vec2_h */

View File

@@ -372,7 +372,7 @@ glm_vec3_scale_as(vec3 v, float s, vec3 dest) {
float norm;
norm = glm_vec3_norm(v);
if (norm == 0.0f) {
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
glm_vec3_zero(dest);
return;
}
@@ -651,7 +651,7 @@ glm_vec3_normalize(vec3 v) {
norm = glm_vec3_norm(v);
if (norm == 0.0f) {
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
v[0] = v[1] = v[2] = 0.0f;
return;
}
@@ -672,7 +672,7 @@ glm_vec3_normalize_to(vec3 v, vec3 dest) {
norm = glm_vec3_norm(v);
if (norm == 0.0f) {
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
glm_vec3_zero(dest);
return;
}
@@ -1243,18 +1243,21 @@ glm_vec3_reflect(vec3 I, vec3 N, vec3 dest) {
}
/*!
* @brief refraction vector using entering ray, surface normal and refraction index
* @brief computes refraction vector for an incident vector and a surface normal.
*
* if the angle between the entering ray I and the surface normal N is too great
* for a given refraction index, the return value is zero
* calculates the refraction vector based on Snell's law. If total internal reflection
* occurs (angle too great given eta), dest is set to zero and returns false.
* Otherwise, computes refraction vector, stores it in dest, and returns true.
*
* @param[in] I normalized incident vector
* @param[in] N normalized normal vector
* @param[in] eta ratio of indices of refraction
* @param[out] dest refraction result
* @param[in] eta ratio of indices of refraction (incident/transmitted)
* @param[out] dest refraction vector if refraction occurs; zero vector otherwise
*
* @returns true if refraction occurs; false if total internal reflection occurs.
*/
CGLM_INLINE
void
bool
glm_vec3_refract(vec3 I, vec3 N, float eta, vec3 dest) {
float ndi, eni, k;
@@ -1264,11 +1267,12 @@ glm_vec3_refract(vec3 I, vec3 N, float eta, vec3 dest) {
if (k < 0.0f) {
glm_vec3_zero(dest);
return;
return false;
}
glm_vec3_scale(I, eta, dest);
glm_vec3_mulsubs(N, eni + sqrtf(k), dest);
return true;
}
#endif /* cglm_vec3_h */

View File

@@ -487,7 +487,7 @@ glm_vec4_scale_as(vec4 v, float s, vec4 dest) {
float norm;
norm = glm_vec4_norm(v);
if (norm == 0.0f) {
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
glm_vec4_zero(dest);
return;
}
@@ -918,7 +918,7 @@ glm_vec4_normalize_to(vec4 v, vec4 dest) {
/* dot = _mm_cvtss_f32(xdot); */
dot = wasm_f32x4_extract_lane(xdot, 0);
if (dot == 0.0f) {
if (CGLM_UNLIKELY(dot < FLT_EPSILON)) {
glmm_store(dest, wasm_f32x4_const_splat(0.f));
return;
}
@@ -932,7 +932,7 @@ glm_vec4_normalize_to(vec4 v, vec4 dest) {
xdot = glmm_vdot(x0, x0);
dot = _mm_cvtss_f32(xdot);
if (dot == 0.0f) {
if (CGLM_UNLIKELY(dot < FLT_EPSILON)) {
glmm_store(dest, _mm_setzero_ps());
return;
}
@@ -943,7 +943,7 @@ glm_vec4_normalize_to(vec4 v, vec4 dest) {
norm = glm_vec4_norm(v);
if (norm == 0.0f) {
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
glm_vec4_zero(dest);
return;
}
@@ -1326,10 +1326,11 @@ glm_vec4_reflect(vec4 I, vec4 N, vec4 dest) {
}
/*!
* @brief refraction vector using entering ray, surface normal and refraction index
* @brief computes refraction vector for an incident vector and a surface normal.
*
* if the angle between the entering ray I and the surface normal N is too great
* for a given refraction index, the return value is zero
* calculates the refraction vector based on Snell's law. If total internal reflection
* occurs (angle too great given eta), dest is set to zero and returns false.
* Otherwise, computes refraction vector, stores it in dest, and returns true.
*
* this implementation does not explicitly preserve the 'w' component of the
* incident vector 'I' in the output 'dest', users requiring the preservation of
@@ -1337,11 +1338,13 @@ glm_vec4_reflect(vec4 I, vec4 N, vec4 dest) {
*
* @param[in] I normalized incident vector
* @param[in] N normalized normal vector
* @param[in] eta ratio of indices of refraction
* @param[out] dest refraction result
* @param[in] eta ratio of indices of refraction (incident/transmitted)
* @param[out] dest refraction vector if refraction occurs; zero vector otherwise
*
* @returns true if refraction occurs; false if total internal reflection occurs.
*/
CGLM_INLINE
void
bool
glm_vec4_refract(vec4 I, vec4 N, float eta, vec4 dest) {
float ndi, eni, k;
@@ -1351,11 +1354,12 @@ glm_vec4_refract(vec4 I, vec4 N, float eta, vec4 dest) {
if (k < 0.0f) {
glm_vec4_zero(dest);
return;
return false;
}
glm_vec4_scale(I, eta, dest);
glm_vec4_mulsubs(N, eni + sqrtf(k), dest);
return true;
}
#endif /* cglm_vec4_h */

View File

@@ -310,7 +310,7 @@ glmc_vec2_reflect(vec2 I, vec2 N, vec2 dest) {
}
CGLM_EXPORT
void
bool
glmc_vec2_refract(vec2 I, vec2 N, float eta, vec2 dest) {
glm_vec2_refract(I, N, eta, dest);
return glm_vec2_refract(I, N, eta, dest);
}

View File

@@ -473,7 +473,7 @@ glmc_vec3_reflect(vec3 I, vec3 N, vec3 dest) {
}
CGLM_EXPORT
void
bool
glmc_vec3_refract(vec3 I, vec3 N, float eta, vec3 dest) {
glm_vec3_refract(I, N, eta, dest);
return glm_vec3_refract(I, N, eta, dest);
}

View File

@@ -431,7 +431,7 @@ glmc_vec4_reflect(vec4 I, vec4 N, vec4 dest) {
}
CGLM_EXPORT
void
bool
glmc_vec4_refract(vec4 I, vec4 N, float eta, vec4 dest) {
glm_vec4_refract(I, N, eta, dest);
return glm_vec4_refract(I, N, eta, dest);
}

View File

@@ -241,7 +241,7 @@ TEST_IMPL(GLM_PREFIX, vec2_scale_as) {
GLM(vec2_scale_as)(v1, s, v2);
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]);
if (norm == 0.0f) {
if (norm < FLT_EPSILON) {
ASSERT(test_eq(v1[0], 0.0f))
ASSERT(test_eq(v1[1], 0.0f))
@@ -492,7 +492,7 @@ TEST_IMPL(GLM_PREFIX, vec2_normalize) {
GLM(vec2_normalize)(v2);
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]);
if (norm == 0.0f) {
if (norm < FLT_EPSILON) {
ASSERT(test_eq(v1[0], 0.0f))
ASSERT(test_eq(v1[1], 0.0f))
@@ -519,7 +519,7 @@ TEST_IMPL(GLM_PREFIX, vec2_normalize_to) {
GLM(vec2_normalize_to)(v1, v2);
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]);
if (norm == 0.0f) {
if (norm < FLT_EPSILON) {
ASSERT(test_eq(v1[0], 0.0f))
ASSERT(test_eq(v1[1], 0.0f))
@@ -785,35 +785,40 @@ TEST_IMPL(GLM_PREFIX, vec2_refract) {
vec2 N = {0.0f, 1.0f}; /* Surface normal */
vec2 dest;
float eta;
float r;
/* Water to Air (eta = 1.33/1.0) */
eta = 1.33f / 1.0f;
GLM(vec2_refract)(I, N, eta, dest);
r = 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
ASSERT(r == true);
} else {
ASSERT(dest[0] == 0.0f && dest[1] == 0.0f); // Total internal reflection
ASSERT(r == false);
}
/* Air to Glass (eta = 1.0 / 1.5) */
eta = 1.0f / 1.5f;
GLM(vec2_refract)(I, N, eta, dest);
r = 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);
r = 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);
r = 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));
ASSERT(r == true);
} else {
ASSERT(dest[0] == 0.0f && dest[1] == 0.0f); // Total internal reflection
ASSERT(r == false);
}
TEST_SUCCESS

View File

@@ -433,7 +433,7 @@ TEST_IMPL(GLM_PREFIX, vec3_scale_as) {
GLM(vec3_scale_as)(v1, s, v2);
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
if (norm == 0.0f) {
if (norm < FLT_EPSILON) {
ASSERT(test_eq(v1[0], 0.0f))
ASSERT(test_eq(v1[1], 0.0f))
ASSERT(test_eq(v1[2], 0.0f))
@@ -704,7 +704,7 @@ TEST_IMPL(GLM_PREFIX, vec3_normalize) {
GLM(vec3_normalize)(v2);
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
if (norm == 0.0f) {
if (norm < FLT_EPSILON) {
ASSERT(test_eq(v1[0], 0.0f))
ASSERT(test_eq(v1[1], 0.0f))
ASSERT(test_eq(v1[2], 0.0f))
@@ -733,7 +733,7 @@ TEST_IMPL(GLM_PREFIX, vec3_normalize_to) {
GLM(vec3_normalize_to)(v1, v2);
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
if (norm == 0.0f) {
if (norm < FLT_EPSILON) {
ASSERT(test_eq(v1[0], 0.0f))
ASSERT(test_eq(v1[1], 0.0f))
ASSERT(test_eq(v1[2], 0.0f))
@@ -764,7 +764,7 @@ TEST_IMPL(GLM_PREFIX, normalize) {
GLM(vec3_normalize)(v2);
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
if (norm == 0.0f) {
if (norm < FLT_EPSILON) {
ASSERT(test_eq(v1[0], 0.0f))
ASSERT(test_eq(v1[1], 0.0f))
ASSERT(test_eq(v1[2], 0.0f))
@@ -795,7 +795,7 @@ TEST_IMPL(GLM_PREFIX, normalize_to) {
GLM(vec3_normalize_to)(v1, v2);
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
if (norm == 0.0f) {
if (norm < FLT_EPSILON) {
ASSERT(test_eq(v1[0], 0.0f))
ASSERT(test_eq(v1[1], 0.0f))
ASSERT(test_eq(v1[2], 0.0f))
@@ -1890,38 +1890,43 @@ TEST_IMPL(GLM_PREFIX, vec3_refract) {
vec3 N = {0.0f, 1.0f, 0.0f}; /* Surface normal */
vec3 dest;
float eta;
bool r;
/* Water to Air (eta = 1.33/1.0) */
eta = 1.33f / 1.0f;
GLM(vec3_refract)(I, N, eta, dest);
r = 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));
ASSERT(r == true);
} else {
ASSERT(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f);
ASSERT(r == false);
}
/* Air to Glass (eta = 1.0 / 1.5) */
eta = 1.0f / 1.5f;
GLM(vec3_refract)(I, N, eta, dest);
r = 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);
r = 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);
r = 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));
ASSERT(r == true);
} else {
ASSERT(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f);
ASSERT(r == false);
}
TEST_SUCCESS

View File

@@ -410,7 +410,7 @@ TEST_IMPL(GLM_PREFIX, vec4_scale_as) {
GLM(vec4_scale_as)(v1, s, v2);
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] + v1[3] * v1[3]);
if (norm == 0.0f) {
if (norm < FLT_EPSILON) {
ASSERT(test_eq(v1[0], 0.0f))
ASSERT(test_eq(v1[1], 0.0f))
ASSERT(test_eq(v1[2], 0.0f))
@@ -701,7 +701,7 @@ TEST_IMPL(GLM_PREFIX, vec4_normalize) {
GLM(vec4_normalize)(v2);
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] + v1[3] * v1[3]);
if (norm == 0.0f) {
if (norm < FLT_EPSILON) {
ASSERT(test_eq(v1[0], 0.0f))
ASSERT(test_eq(v1[1], 0.0f))
ASSERT(test_eq(v1[2], 0.0f))
@@ -732,7 +732,7 @@ TEST_IMPL(GLM_PREFIX, vec4_normalize_to) {
GLM(vec4_normalize_to)(v1, v2);
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] + v1[3] * v1[3]);
if (norm == 0.0f) {
if (norm < FLT_EPSILON) {
ASSERT(test_eq(v1[0], 0.0f))
ASSERT(test_eq(v1[1], 0.0f))
ASSERT(test_eq(v1[2], 0.0f))
@@ -1575,34 +1575,39 @@ TEST_IMPL(GLM_PREFIX, vec4_refract) {
vec4 N = {0.0f, 1.0f, 0.0f, 0.0f}; /* Surface normal */
vec4 dest;
float eta;
float r;
/* Water to Air (eta = 1.33/1.0) */
eta = 1.33f / 1.0f;
GLM(vec4_refract)(I, N, eta, dest);
r = 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));
ASSERT(r == true);
} else {
ASSERT(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f && dest[3] == 0.0f);
ASSERT(r == false);
}
/* Air to Glass (eta = 1.0 / 1.5) */
eta = 1.0f / 1.5f;
GLM(vec4_refract)(I, N, eta, dest);
r = 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);
r = 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);
r = 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));
ASSERT(r == true);
} else {
ASSERT(dest[0] == 0.0f && dest[1] == 0.0f && dest[2] == 0.0f && dest[3] == 0.0f);
ASSERT(r == false);
}
TEST_SUCCESS