Restructured the codebase yet again but this time with compiler support for monlithic packages
So no need to stage generate symbolic links in a flat directory for the compiler
This commit is contained in:
132
code/sectr/math/math.odin
Normal file
132
code/sectr/math/math.odin
Normal file
@ -0,0 +1,132 @@
|
||||
// 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
|
||||
|
||||
// Newton–Raphson 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")
|
36
code/sectr/math/pga2.odin
Normal file
36
code/sectr/math/pga2.odin
Normal file
@ -0,0 +1,36 @@
|
||||
package sectr
|
||||
|
||||
/*
|
||||
Vec2 : 2D Vector 4D Extension (x, y, z : 0, w : 0)
|
||||
Bivec2 : 2D Bivector
|
||||
Transform2 : 3x3 Matrix where 3rd row is always (0, 0, 1)
|
||||
*/
|
||||
Vec2 :: [2]f32
|
||||
Bivec2 :: distinct f32
|
||||
Tansform2 :: matrix [3, 3] f32
|
||||
UnitVec2 :: distinct Vec2
|
||||
|
||||
Rotor2 :: struct {
|
||||
bv : Bivec2,
|
||||
s : f32, // Scalar
|
||||
}
|
||||
|
||||
rotor2_to_complex64 :: #force_inline proc( rotor : Rotor2 ) -> complex64 { return transmute(complex64) rotor; }
|
||||
|
||||
vec2 :: #force_inline proc "contextless" ( x, y : f32 ) -> Vec2 { return {x, y} }
|
||||
|
||||
dot_vec2 :: proc "contextless" ( a, b : Vec2 ) -> (s : f32) {
|
||||
x := a.x * b.x
|
||||
y := a.y + b.y
|
||||
s = x + y
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
PointFlat2 : CGA: 2D flat point (x, y, z)
|
||||
Line : PGA: 2D line (x, y, z)
|
||||
*/
|
||||
|
||||
Point2 :: distinct Vec2
|
||||
PointFlat2 :: distinct Vec3
|
||||
Line2 :: distinct Vec3
|
239
code/sectr/math/pga3.odin
Normal file
239
code/sectr/math/pga3.odin
Normal file
@ -0,0 +1,239 @@
|
||||
package sectr
|
||||
|
||||
/*
|
||||
Vec3 : 3D Vector (x, y, z) (3x1) 4D Expression : (x, y, z, 0)
|
||||
Bivec3 : 3D Bivector (yz, zx, xy) (3x1)
|
||||
Trivec3 : 3D Trivector (xyz) (1x1)
|
||||
Rotor3 : 3D Rotation Versor-Transform (4x1)
|
||||
Motor3 : 3D Rotation & Translation Transform (4x2)
|
||||
*/
|
||||
|
||||
Vec3 :: [3]f32
|
||||
Vec4 :: [4]f32
|
||||
|
||||
Bivec3 :: struct #raw_union {
|
||||
using _ : struct { yz, zx, xy : f32 },
|
||||
using xyz : Vec3,
|
||||
}
|
||||
|
||||
Trivec3 :: distinct f32
|
||||
|
||||
Rotor3 :: struct {
|
||||
using bv : Bivec3,
|
||||
s : f32, // Scalar
|
||||
}
|
||||
|
||||
Shifter3 :: struct {
|
||||
using bv : Bivec3,
|
||||
s : f32, // Scalar
|
||||
}
|
||||
|
||||
Motor3 :: struct {
|
||||
rotor : Rotor3,
|
||||
md : Shifter3,
|
||||
}
|
||||
|
||||
UnitVec3 :: distinct Vec3
|
||||
UnitVec4 :: distinct Vec4
|
||||
UnitBivec3 :: distinct Bivec3
|
||||
|
||||
//region Vec3
|
||||
|
||||
vec3_via_f32s :: #force_inline proc "contextless" (x, y, z : f32) -> Vec3 { return {x, y, z} }
|
||||
|
||||
// complement_vec3 :: #force_inline proc "contextless" ( v : Vec3 ) -> Bivec3 {return transmute(Bivec3) v}
|
||||
|
||||
cross_vec3 :: proc "contextless" (a, b : Vec3) -> (v : Vec3) {
|
||||
v = vec3( wedge(a, b))
|
||||
return
|
||||
}
|
||||
|
||||
dot_vec3 :: proc "contextless" ( a, b : Vec3 ) -> (s : f32) {
|
||||
mult := a * b // array multiply
|
||||
s = mult.x + mult.y + mult.z
|
||||
return
|
||||
}
|
||||
|
||||
inverse_mag_vec3 :: proc "contextless" (v : Vec3) -> (result : f32) {
|
||||
square := pow2(v)
|
||||
result = inverse_sqrt( square )
|
||||
return
|
||||
}
|
||||
|
||||
magnitude_vec3 :: proc "contextless" (v : Vec3) -> (mag : f32) {
|
||||
square := pow2(v)
|
||||
mag = sqrt(square)
|
||||
return
|
||||
}
|
||||
|
||||
normalize_vec3 :: proc "contextless" (v : Vec3) -> (unit_v : UnitVec3) {
|
||||
unit_v = transmute(UnitVec3) (v * inverse_mag(v))
|
||||
return
|
||||
}
|
||||
|
||||
pow2_vec3 :: #force_inline proc "contextless" ( v : Vec3 ) -> (s : f32) { return dot(v, v) }
|
||||
|
||||
project_vec3 :: proc "contextless" ( a, b : Vec3 ) -> ( a_to_b : Vec3 ) {
|
||||
return
|
||||
}
|
||||
|
||||
reject_vec3 :: proc "contextless" ( a, b : Vec3 ) -> ( a_from_b : Vec3 ) {
|
||||
return
|
||||
}
|
||||
|
||||
project_v3_unitv3 :: proc "contextless" ( v : Vec3, u : UnitVec3 ) -> (v_to_u : Vec3) {
|
||||
inner := dot(v, u)
|
||||
v_to_u = (transmute(Vec3) u) * inner
|
||||
return
|
||||
}
|
||||
project_unitv3_v3 :: #force_inline proc "contextless" (u : UnitVec3, v : Vec3) -> (u_to_v : Vec3) {
|
||||
inner := dot(u, v)
|
||||
u_to_v = v * inner
|
||||
return
|
||||
}
|
||||
|
||||
// Anti-wedge of vectors
|
||||
regress_vec3 :: proc "contextless" ( a, b : Vec3 ) -> f32 {
|
||||
return a.x * b.y - a.y * b.x
|
||||
}
|
||||
|
||||
reject_v3_unitv3 :: proc "contextless" ( v : Vec3, u : UnitVec3 ) -> ( v_from_u : Vec3) {
|
||||
inner := dot(v, u)
|
||||
v_from_u = (v - (transmute(Vec3) u)) * inner
|
||||
return
|
||||
}
|
||||
reject_unitv3_v3 :: proc "contextless" ( v : Vec3, u : UnitVec3 ) -> ( u_from_v : Vec3) {
|
||||
inner := dot(u, v)
|
||||
u_from_v = ((transmute(Vec3) u) - v) * inner
|
||||
return
|
||||
}
|
||||
|
||||
// Combines the deimensions that are present in a & b
|
||||
wedge_vec3 :: proc "contextless" (a, b : Vec3) -> (bv : Bivec3) {
|
||||
yzx_zxy := a.yzx * b.zxy
|
||||
zxy_yzx := a.zxy * b.yzx
|
||||
bv = transmute(Bivec3) (yzx_zxy - zxy_yzx)
|
||||
return
|
||||
}
|
||||
|
||||
//endregion Vec3
|
||||
|
||||
//region Bivec3
|
||||
bivec3_via_f32s :: #force_inline proc "contextless" (yz, zx, xy : f32) -> Bivec3 {return { xyz = {yz, zx, xy} }}
|
||||
|
||||
complement_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> Bivec3 {return transmute(Bivec3) b.xyz}
|
||||
|
||||
//region Operations isomoprhic to vectors
|
||||
negate_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> Bivec3 {return transmute(Bivec3) -b.xyz}
|
||||
add_bivec3 :: #force_inline proc "contextless" (a, b : Bivec3) -> Bivec3 {return transmute(Bivec3) (a.xyz + b.xyz)}
|
||||
sub_bivec3 :: #force_inline proc "contextless" (a, b : Bivec3) -> Bivec3 {return transmute(Bivec3) (a.xyz - b.xyz)}
|
||||
mul_bivec3 :: #force_inline proc "contextless" (a, b : Bivec3) -> Bivec3 {return transmute(Bivec3) (a.xyz * b.xyz)}
|
||||
mul_bivec3_f32 :: #force_inline proc "contextless" (b : Bivec3, s : f32) -> Bivec3 {return transmute(Bivec3) (b.xyz * s)}
|
||||
mul_f32_bivec3 :: #force_inline proc "contextless" (s : f32, b : Bivec3) -> Bivec3 {return transmute(Bivec3) (s * b.xyz)}
|
||||
div_bivec3_f32 :: #force_inline proc "contextless" (b : Bivec3, s : f32) -> Bivec3 {return transmute(Bivec3) (b.xyz / s)}
|
||||
inverse_mag_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> f32 {return inverse_mag_vec3(b.xyz)}
|
||||
magnitude_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> f32 {return magnitude_vec3 (b.xyz)}
|
||||
normalize_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> UnitBivec3 {return transmute(UnitBivec3) normalize_vec3(b.xyz)}
|
||||
squared_mag_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> f32 {return pow2_vec3(b.xyz)}
|
||||
//endregion Operations isomoprhic to vectors
|
||||
|
||||
// The wedge of a bi-vector in 3D vector space results in a Trivector represented as a scalar.
|
||||
// This scalar usually resolves to zero with six possible exceptions that lead to the negative volume element.
|
||||
wedge_bivec3 :: proc ( a, b : Bivec3 ) -> f32 {
|
||||
s := a.yz + b.yz + a.zx + b.zx + a.xy + b.xy
|
||||
return s
|
||||
}
|
||||
|
||||
// anti-wedge (Combines dimensions that are absent from a & b)
|
||||
regress_bivec3 :: #force_inline proc "contextless" ( a, b : Bivec3 ) -> Vec3 {return wedge_vec3(vec3(a), vec3(b))}
|
||||
regress_bivec3_v :: #force_inline proc "contextless" (b : Bivec3, v : Vec3) -> f32 {return regress_vec3(b.xyz, v)}
|
||||
regress_v3_bivec3 :: #force_inline proc "contextless" (v : Vec3, b : Bivec3) -> f32 {return regress_vec3(b.xyz, v)}
|
||||
|
||||
//endregion Bivec3
|
||||
|
||||
//region Rotor3
|
||||
|
||||
rotor3_via_comps :: proc "contextless" (yz, zx, xy, scalar : f32) -> (rotor : Rotor3) {
|
||||
rotor = Rotor3 {bivec3_via_f32s(yz, zx, xy), scalar}
|
||||
return
|
||||
}
|
||||
|
||||
rotor3_via_bv_s :: proc "contextless" (bv : Bivec3, scalar : f32) -> (rotor : Rotor3) {
|
||||
rotor = Rotor3 {bv, scalar}
|
||||
return
|
||||
}
|
||||
|
||||
rotor3_via_from_to :: proc "contextless" ( from, to : Vec3 ) -> (rotor : Rotor3) {
|
||||
scalar := 1 + dot( from, to )
|
||||
return
|
||||
}
|
||||
|
||||
inverse_mag_rotor3 :: proc "contextless" (rotor : Rotor3) -> (s : f32) {
|
||||
return
|
||||
}
|
||||
|
||||
magnitude_rotor3 :: proc "contextless" (rotor : Rotor3) -> (s : f32) {
|
||||
return
|
||||
}
|
||||
|
||||
squared_mag :: proc "contextless" (rotor : Rotor3) -> (s : f32) {
|
||||
return
|
||||
}
|
||||
|
||||
reverse_rotor3 :: proc "contextless" (rotor : Rotor3) -> (reversed : Rotor3) {
|
||||
reversed = { negate_bivec3(rotor.bv), rotor.s }
|
||||
return
|
||||
}
|
||||
|
||||
//endregion Rotor3
|
||||
|
||||
//region Flat Projective Geometry
|
||||
|
||||
Point3 :: distinct Vec3
|
||||
PointFlat3 :: distinct Vec4
|
||||
Line3 :: struct {
|
||||
weight : Vec3,
|
||||
bulk : Bivec3,
|
||||
}
|
||||
Plane3 :: distinct Vec4 // 4D Anti-vector
|
||||
|
||||
// aka: wedge operation for points
|
||||
join_point3 :: proc "contextless" (p, q : Point3) -> (l : Line3) {
|
||||
weight := sub(q, p)
|
||||
bulk := wedge(vec3(p), vec3(q))
|
||||
l = {weight, bulk}
|
||||
return
|
||||
}
|
||||
|
||||
join_pointflat3 :: proc "contextless" (p, q : PointFlat3) -> (l : Line3) {
|
||||
weight := vec3(
|
||||
p.w * q.x - p.x * q.w,
|
||||
p.w * q.y - p.y * q.w,
|
||||
p.w * q.z - p.z * q.w
|
||||
)
|
||||
bulk := wedge(vec3(p), vec3(q))
|
||||
l = { weight, bulk}
|
||||
return
|
||||
}
|
||||
|
||||
sub_point3 :: proc "contextless" (a, b : Point3) -> (v : Vec3) {
|
||||
v = vec3(a) - vec3(b)
|
||||
return
|
||||
}
|
||||
|
||||
//endregion Flat Projective Geometry
|
||||
|
||||
//region Rational Trig
|
||||
|
||||
quadrance :: proc "contextless" (a, b : Point3) -> (q : f32) {
|
||||
q = pow2( sub(a, b))
|
||||
return
|
||||
}
|
||||
|
||||
// Assumes the weight component is normalized.
|
||||
spread :: proc "contextless" (l, m : Line3) -> (s : f32) {
|
||||
s = dot(l.weight, m.weight)
|
||||
return
|
||||
}
|
||||
|
||||
//endregion Rational Trig
|
24
code/sectr/math/pga3_grime.odin
Normal file
24
code/sectr/math/pga3_grime.odin
Normal file
@ -0,0 +1,24 @@
|
||||
package sectr
|
||||
|
||||
// A dump of equivalent symbol generatioon (because the toolchain can't do it yet)
|
||||
// Symbol alias tables are in grim.odin
|
||||
|
||||
vec3_to_bivec3 :: #force_inline proc "contextless" (v : Vec3) -> Bivec3 {return transmute(Bivec3) v }
|
||||
bivec3_to_vec3 :: #force_inline proc "contextless" (bv : Bivec3) -> Vec3 {return transmute(Vec3) bv }
|
||||
rotor3_to_quat128 :: #force_inline proc "contextless" (rotor : Rotor3) -> Quat128 {return transmute(Quat128) rotor}
|
||||
unitvec3_to_vec3 :: #force_inline proc "contextless" (v : UnitVec3) -> Vec3 {return transmute(Vec3) v }
|
||||
unitvec4_to_vec4 :: #force_inline proc "contextless" (v : UnitVec4) -> Vec4 {return transmute(Vec4) v }
|
||||
|
||||
// plane_to_vec4 :: #force_inline proc "contextless" (p : Plane3) -> Vec4 {return transmute(Vec4) p}
|
||||
point3_to_vec3 :: #force_inline proc "contextless" (p : Point3) -> Vec3 {return transmute(Vec3) p}
|
||||
pointflat3_to_vec3 :: #force_inline proc "contextless" (p : PointFlat3) -> Vec3 {return { p.x, p.y, p.z }}
|
||||
vec3_to_point3 :: #force_inline proc "contextless" (v : Vec3) -> Point3 {return transmute(Point3) v}
|
||||
|
||||
cross_v3_unitv3 :: #force_inline proc "contextless" (v : Vec3, u : UnitVec3) -> Vec3 {return cross_vec3(v, transmute(Vec3) u)}
|
||||
cross_unitv3_vs :: #force_inline proc "contextless" (u : UnitVec3, v : Vec3) -> Vec3 {return cross_vec3(transmute(Vec3) u, v)}
|
||||
|
||||
dot_v3_unitv3 :: #force_inline proc "contextless" (v : Vec3, unit_v : UnitVec3) -> f32 {return dot_vec3(v, transmute(Vec3) unit_v)}
|
||||
dot_unitv3_vs :: #force_inline proc "contextless" (unit_v : UnitVec3, v : Vec3) -> f32 {return dot_vec3(v, transmute(Vec3) unit_v)}
|
||||
|
||||
wedge_v3_unitv3 :: #force_inline proc "contextless" (v : Vec3, unit_v : UnitVec3) -> Bivec3 {return wedge_vec3(v, transmute(Vec3) unit_v)}
|
||||
wedge_unitv3_vs :: #force_inline proc "contextless" (unit_v : UnitVec3, v : Vec3) -> Bivec3 {return wedge_vec3(transmute(Vec3) unit_v, v)}
|
Reference in New Issue
Block a user