SectrPrototype/code/math/math.odin
Ed_ 40ffed9538 Changed codebase to be foldered (breaking compiler's conventions)
I now generate the layout the compiler wants, eventually I'll just have a custom policy so that the compiler can accept the non-idiomatic layout

See scripts/build.ps1 & gen_staged_compiler_codebase.ps1 for how this is handled.
2024-05-16 13:18:27 -04:00

133 lines
3.4 KiB
Odin
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// General mathematical constructions used for the prototype
package sectr
import "core:math"
// These are the same as the runtime constants for memory units just using a more general name when not refering to bytes
Kilo :: Kilobyte
Mega :: Megabyte
Giga :: Gigabyte
Tera :: Terabyte
Peta :: Petabyte
Exa :: Exabyte
Axis2 :: enum i32 {
Invalid = -1,
X = 0,
Y = 1,
Count,
}
f32_Infinity :: 0x7F800000
f32_Min :: 0x00800000
// Note(Ed) : I don't see an intrinsict available anywhere for this. So I'll be using the Terathon non-sse impl
// Inverse Square Root
// C++ Source https://github.com/EricLengyel/Terathon-Math-Library/blob/main/TSMath.cpp#L191
inverse_sqrt_f32 :: proc "contextless" ( value : f32 ) -> f32
{
if ( value < f32_Min) {
return f32_Infinity
}
value_u32 := transmute(u32) value
initial_approx := 0x5F375A86 - (value_u32 >> 1)
refined_approx := transmute(f32) initial_approx
// NewtonRaphson method for getting better approximations of square roots
// Done twice for greater accuracy.
refined_approx = refined_approx * (1.5 - value * 0.5 * refined_approx * refined_approx )
refined_approx = refined_approx * (1.5 - value * 0.5 * refined_approx * refined_approx )
// refined_approx = (0.5 * refined_approx) * (3.0 - value * refined_approx * refined_approx)
// refined_approx = (0.5 * refined_approx) * (3.0 - value * refined_approx * refined_approx)
return refined_approx
}
is_power_of_two_u32 :: #force_inline proc "contextless" ( value : u32 ) -> b32
{
return value != 0 && ( value & ( value - 1 )) == 0
}
mov_avg_exp_f32 := #force_inline proc "contextless" ( alpha, delta_interval, last_value : f32 ) -> f32
{
result := (delta_interval * alpha) + (delta_interval * (1.0 - alpha))
return result
}
mov_avg_exp_f64 := #force_inline proc "contextless" ( alpha, delta_interval, last_value : f64 ) -> f64
{
result := (delta_interval * alpha) + (delta_interval * (1.0 - alpha))
return result
}
import "core:math/linalg"
Quat128 :: quaternion128
Matrix2 :: matrix [2, 2] f32
Vec2i :: [2]i32
Vec3i :: [3]i32
vec2i_to_vec2 :: #force_inline proc "contextless" (v : Vec2i) -> Vec2 {return transmute(Vec2) v}
vec3i_to_vec3 :: #force_inline proc "contextless" (v : Vec3i) -> Vec3 {return transmute(Vec3) v}
#region("Range2")
Range2 :: struct #raw_union {
using min_max : struct {
min, max : Vec2
},
using pts : struct {
p0, p1 : Vec2
},
using xy : struct {
x0, y0 : f32,
x1, y1 : f32,
},
using side : struct {
left, bottom : f32,
right, top : f32,
},
ratio : struct {
x, y : f32,
},
// TODO(Ed) : Test these
array : [4]f32,
mat : matrix[2, 2] f32,
}
UnitRange2 :: distinct Range2
range2 :: #force_inline proc "contextless" ( a, b : Vec2 ) -> Range2 {
result := Range2 { pts = { a, b } }
return result
}
add_range2 :: #force_inline proc "contextless" ( a, b : Range2 ) -> Range2 {
result := Range2 { pts = {
a.p0 + b.p0,
a.p1 + b.p1,
}}
return result
}
sub_range2 :: #force_inline proc "contextless" ( a, b : Range2 ) -> Range2 {
// result := Range2 { array = a.array - b.array }
result := Range2 { mat = a.mat - b.mat }
return result
}
equal_range2 :: #force_inline proc "contextless" ( a, b : Range2 ) -> b32 {
result := a.p0 == b.p0 && a.p1 == b.p1
return b32(result)
}
size_range2 :: #force_inline proc "contextless" ( value : Range2 ) -> Vec2 {
return { value.p1.x - value.p0.x, value.p0.y - value.p1.y }
}
#endregion("Range2")