Skip to content

Commit e68de93

Browse files
committed
Implemented the fast inverse sqrt algoritm
Used in all vector normalization functions instead of `1/sqrt(x)`.
1 parent dfdc85e commit e68de93

File tree

5 files changed

+22
-5
lines changed

5 files changed

+22
-5
lines changed

src/carbon_math.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,16 @@ f32 carbon_math_sqrt(f32 x) {
178178
#endif
179179
}
180180

181+
f32 carbon_math_rsqrt(f32 x) {
182+
// Fast Inverse Square Root algorithm
183+
f32 x2 = x/2, y = x;
184+
i32 i = *((i32 *) &y); // evil floating point bit level hacking
185+
i = 0x5f3759df - (i >> 1); // what the fuck?
186+
y = *((f32 *) &i);
187+
y *= (1.5 - (x2 * y * y));
188+
return y;
189+
}
190+
181191
i32 carbon_math_imod(i32 x, i32 y) {
182192
CBN_ASSERT(y && "division by 0 is not defined");
183193
return (x%y + y) % y;

src/carbon_math.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ CBNDEF f32 carbon_math_snap(f32 x, f32 dx);
151151
*/
152152
CBNDEF f32 carbon_math_sqrt(f32 x);
153153

154+
/**
155+
* @brief Returns the reciprocal (multiplicative inverse) of the square root of a specified number.
156+
* @param x The number.
157+
* @return An approximation of 1/√x, provided x ≥ 0.
158+
*/
159+
CBNDEF f32 carbon_math_rsqrt(f32 x);
160+
154161
/**
155162
* @brief Performs a true modulo operation for integers.
156163
* @param x The dividend.

src/carbon_math_quat.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ f32 carbon_math_quat_len(CBN_Quat q) {
4747
}
4848

4949
CBN_Quat carbon_math_quat_norm(CBN_Quat q) {
50-
f32 len = carbon_math_quat_len(q);
51-
if (!len) return q;
52-
return carbon_math_quat_scale(q, 1/len);
50+
f32 sqlen = carbon_math_quat_len_squared(q);
51+
if (sqlen <= CARBON_EPS_SQ) return q;
52+
return carbon_math_quat_scale(q, carbon_math_rsqrt(sqlen));
5353
}
5454

5555
CBN_Quat carbon_math_quat_inv(CBN_Quat q) {

src/carbon_math_vec2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ f32 carbon_math_vec2_len(CBN_Vec2 v) {
3838
CBN_Vec2 carbon_math_vec2_norm(CBN_Vec2 v) {
3939
f32 sqlen = carbon_math_vec2_len_squared(v);
4040
if (sqlen <= CARBON_EPS_SQ) return v;
41-
return carbon_math_vec2_scale(v, 1/carbon_math_sqrt(sqlen));
41+
return carbon_math_vec2_scale(v, carbon_math_rsqrt(sqlen));
4242
}
4343

4444
CBN_Vec2 carbon_math_vec2_lerp(CBN_Vec2 u, CBN_Vec2 v, f32 t) {

src/carbon_math_vec3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ f32 carbon_math_vec3_len(CBN_Vec3 v) {
4242
CBN_Vec3 carbon_math_vec3_norm(CBN_Vec3 v) {
4343
f32 sqlen = carbon_math_vec3_len_squared(v);
4444
if (sqlen <= CARBON_EPS_SQ) return v;
45-
return carbon_math_vec3_scale(v, 1/carbon_math_sqrt(sqlen));
45+
return carbon_math_vec3_scale(v, carbon_math_rsqrt(sqlen));
4646
}
4747

4848
char *carbon_math_vec3_to_cstr(CBN_Vec3 v) {

0 commit comments

Comments
 (0)