Skip to content

Commit 1de373a

Browse files
committed
normalize: norm == 0.0f to norm < FLT_EPSILON, improving handling of very small vectors to prevent instability and overflow
1 parent 6a7d03b commit 1de373a

File tree

8 files changed

+30
-22
lines changed

8 files changed

+30
-22
lines changed

include/cglm/common.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@
3737
# define CGLM_INLINE static inline __attribute((always_inline))
3838
#endif
3939

40+
#if defined(__GNUC__) || defined(__clang__)
41+
# define CGLM_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
42+
# define CGLM_LIKELY(expr) __builtin_expect(!!(expr), 1)
43+
#else
44+
# define CGLM_UNLIKELY(expr) (expr)
45+
# define CGLM_LIKELY(expr) (expr)
46+
#endif
47+
4048
#define GLM_SHUFFLE4(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w))
4149
#define GLM_SHUFFLE3(z, y, x) (((z) << 4) | ((y) << 2) | (x))
4250

include/cglm/plane.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ void
3333
glm_plane_normalize(vec4 plane) {
3434
float norm;
3535

36-
if ((norm = glm_vec3_norm(plane)) == 0.0f) {
36+
if (CGLM_UNLIKELY((norm = glm_vec3_norm(plane)) < FLT_EPSILON)) {
3737
glm_vec4_zero(plane);
3838
return;
3939
}

include/cglm/vec2.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ glm_vec2_scale_as(vec2 v, float s, vec2 dest) {
278278
float norm;
279279
norm = glm_vec2_norm(v);
280280

281-
if (norm == 0.0f) {
281+
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
282282
glm_vec2_zero(dest);
283283
return;
284284
}
@@ -542,7 +542,7 @@ glm_vec2_normalize(vec2 v) {
542542

543543
norm = glm_vec2_norm(v);
544544

545-
if (norm == 0.0f) {
545+
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
546546
v[0] = v[1] = 0.0f;
547547
return;
548548
}
@@ -563,7 +563,7 @@ glm_vec2_normalize_to(vec2 v, vec2 dest) {
563563

564564
norm = glm_vec2_norm(v);
565565

566-
if (norm == 0.0f) {
566+
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
567567
glm_vec2_zero(dest);
568568
return;
569569
}

include/cglm/vec3.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ glm_vec3_scale_as(vec3 v, float s, vec3 dest) {
372372
float norm;
373373
norm = glm_vec3_norm(v);
374374

375-
if (norm == 0.0f) {
375+
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
376376
glm_vec3_zero(dest);
377377
return;
378378
}
@@ -651,7 +651,7 @@ glm_vec3_normalize(vec3 v) {
651651

652652
norm = glm_vec3_norm(v);
653653

654-
if (norm == 0.0f) {
654+
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
655655
v[0] = v[1] = v[2] = 0.0f;
656656
return;
657657
}
@@ -672,7 +672,7 @@ glm_vec3_normalize_to(vec3 v, vec3 dest) {
672672

673673
norm = glm_vec3_norm(v);
674674

675-
if (norm == 0.0f) {
675+
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
676676
glm_vec3_zero(dest);
677677
return;
678678
}

include/cglm/vec4.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ glm_vec4_scale_as(vec4 v, float s, vec4 dest) {
487487
float norm;
488488
norm = glm_vec4_norm(v);
489489

490-
if (norm == 0.0f) {
490+
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
491491
glm_vec4_zero(dest);
492492
return;
493493
}
@@ -918,7 +918,7 @@ glm_vec4_normalize_to(vec4 v, vec4 dest) {
918918
/* dot = _mm_cvtss_f32(xdot); */
919919
dot = wasm_f32x4_extract_lane(xdot, 0);
920920

921-
if (dot == 0.0f) {
921+
if (CGLM_UNLIKELY(dot < FLT_EPSILON)) {
922922
glmm_store(dest, wasm_f32x4_const_splat(0.f));
923923
return;
924924
}
@@ -932,7 +932,7 @@ glm_vec4_normalize_to(vec4 v, vec4 dest) {
932932
xdot = glmm_vdot(x0, x0);
933933
dot = _mm_cvtss_f32(xdot);
934934

935-
if (dot == 0.0f) {
935+
if (CGLM_UNLIKELY(dot < FLT_EPSILON)) {
936936
glmm_store(dest, _mm_setzero_ps());
937937
return;
938938
}
@@ -943,7 +943,7 @@ glm_vec4_normalize_to(vec4 v, vec4 dest) {
943943

944944
norm = glm_vec4_norm(v);
945945

946-
if (norm == 0.0f) {
946+
if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
947947
glm_vec4_zero(dest);
948948
return;
949949
}

test/src/test_vec2.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ TEST_IMPL(GLM_PREFIX, vec2_scale_as) {
241241
GLM(vec2_scale_as)(v1, s, v2);
242242

243243
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]);
244-
if (norm == 0.0f) {
244+
if (norm < FLT_EPSILON) {
245245
ASSERT(test_eq(v1[0], 0.0f))
246246
ASSERT(test_eq(v1[1], 0.0f))
247247

@@ -492,7 +492,7 @@ TEST_IMPL(GLM_PREFIX, vec2_normalize) {
492492
GLM(vec2_normalize)(v2);
493493

494494
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]);
495-
if (norm == 0.0f) {
495+
if (norm < FLT_EPSILON) {
496496
ASSERT(test_eq(v1[0], 0.0f))
497497
ASSERT(test_eq(v1[1], 0.0f))
498498

@@ -519,7 +519,7 @@ TEST_IMPL(GLM_PREFIX, vec2_normalize_to) {
519519
GLM(vec2_normalize_to)(v1, v2);
520520

521521
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]);
522-
if (norm == 0.0f) {
522+
if (norm < FLT_EPSILON) {
523523
ASSERT(test_eq(v1[0], 0.0f))
524524
ASSERT(test_eq(v1[1], 0.0f))
525525

test/src/test_vec3.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ TEST_IMPL(GLM_PREFIX, vec3_scale_as) {
433433
GLM(vec3_scale_as)(v1, s, v2);
434434

435435
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
436-
if (norm == 0.0f) {
436+
if (norm < FLT_EPSILON) {
437437
ASSERT(test_eq(v1[0], 0.0f))
438438
ASSERT(test_eq(v1[1], 0.0f))
439439
ASSERT(test_eq(v1[2], 0.0f))
@@ -704,7 +704,7 @@ TEST_IMPL(GLM_PREFIX, vec3_normalize) {
704704
GLM(vec3_normalize)(v2);
705705

706706
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
707-
if (norm == 0.0f) {
707+
if (norm < FLT_EPSILON) {
708708
ASSERT(test_eq(v1[0], 0.0f))
709709
ASSERT(test_eq(v1[1], 0.0f))
710710
ASSERT(test_eq(v1[2], 0.0f))
@@ -733,7 +733,7 @@ TEST_IMPL(GLM_PREFIX, vec3_normalize_to) {
733733
GLM(vec3_normalize_to)(v1, v2);
734734

735735
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
736-
if (norm == 0.0f) {
736+
if (norm < FLT_EPSILON) {
737737
ASSERT(test_eq(v1[0], 0.0f))
738738
ASSERT(test_eq(v1[1], 0.0f))
739739
ASSERT(test_eq(v1[2], 0.0f))
@@ -764,7 +764,7 @@ TEST_IMPL(GLM_PREFIX, normalize) {
764764
GLM(vec3_normalize)(v2);
765765

766766
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
767-
if (norm == 0.0f) {
767+
if (norm < FLT_EPSILON) {
768768
ASSERT(test_eq(v1[0], 0.0f))
769769
ASSERT(test_eq(v1[1], 0.0f))
770770
ASSERT(test_eq(v1[2], 0.0f))
@@ -795,7 +795,7 @@ TEST_IMPL(GLM_PREFIX, normalize_to) {
795795
GLM(vec3_normalize_to)(v1, v2);
796796

797797
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
798-
if (norm == 0.0f) {
798+
if (norm < FLT_EPSILON) {
799799
ASSERT(test_eq(v1[0], 0.0f))
800800
ASSERT(test_eq(v1[1], 0.0f))
801801
ASSERT(test_eq(v1[2], 0.0f))

test/src/test_vec4.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ TEST_IMPL(GLM_PREFIX, vec4_scale_as) {
410410
GLM(vec4_scale_as)(v1, s, v2);
411411

412412
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] + v1[3] * v1[3]);
413-
if (norm == 0.0f) {
413+
if (norm < FLT_EPSILON) {
414414
ASSERT(test_eq(v1[0], 0.0f))
415415
ASSERT(test_eq(v1[1], 0.0f))
416416
ASSERT(test_eq(v1[2], 0.0f))
@@ -701,7 +701,7 @@ TEST_IMPL(GLM_PREFIX, vec4_normalize) {
701701
GLM(vec4_normalize)(v2);
702702

703703
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] + v1[3] * v1[3]);
704-
if (norm == 0.0f) {
704+
if (norm < FLT_EPSILON) {
705705
ASSERT(test_eq(v1[0], 0.0f))
706706
ASSERT(test_eq(v1[1], 0.0f))
707707
ASSERT(test_eq(v1[2], 0.0f))
@@ -732,7 +732,7 @@ TEST_IMPL(GLM_PREFIX, vec4_normalize_to) {
732732
GLM(vec4_normalize_to)(v1, v2);
733733

734734
norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] + v1[3] * v1[3]);
735-
if (norm == 0.0f) {
735+
if (norm < FLT_EPSILON) {
736736
ASSERT(test_eq(v1[0], 0.0f))
737737
ASSERT(test_eq(v1[1], 0.0f))
738738
ASSERT(test_eq(v1[2], 0.0f))

0 commit comments

Comments
 (0)