Skip to content

Commit

Permalink
normalize: norm == 0.0f to norm < FLT_EPSILON, improving handling of …
Browse files Browse the repository at this point in the history
…very small vectors to prevent instability and overflow
  • Loading branch information
recp committed Mar 24, 2024
1 parent 6a7d03b commit 1de373a
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 22 deletions.
8 changes: 8 additions & 0 deletions include/cglm/common.h
Expand Up @@ -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))

Expand Down
2 changes: 1 addition & 1 deletion include/cglm/plane.h
Expand Up @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions include/cglm/vec2.h
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions include/cglm/vec3.h
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
8 changes: 4 additions & 4 deletions include/cglm/vec4.h
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions test/src/test_vec2.h
Expand Up @@ -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))

Expand Down Expand Up @@ -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))

Expand All @@ -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))

Expand Down
10 changes: 5 additions & 5 deletions test/src/test_vec3.h
Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand Down
6 changes: 3 additions & 3 deletions test/src/test_vec4.h
Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit 1de373a

Please sign in to comment.