From 11c705508da0902b651995913a43e266720da3c0 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 28 Dec 2019 23:09:43 +0000 Subject: [PATCH] Split linalg into general and specific parts --- core/math/linalg/general.odin | 393 ++++++++++++++++++ .../linalg/{linalg.odin => specific.odin} | 388 ----------------- 2 files changed, 393 insertions(+), 388 deletions(-) create mode 100644 core/math/linalg/general.odin rename core/math/linalg/{linalg.odin => specific.odin} (64%) diff --git a/core/math/linalg/general.odin b/core/math/linalg/general.odin new file mode 100644 index 000000000..b0ccd3577 --- /dev/null +++ b/core/math/linalg/general.odin @@ -0,0 +1,393 @@ +package linalg + +import "core:math" +import "intrinsics" + +// Generic + +@private IS_NUMERIC :: intrinsics.type_is_numeric; +@private IS_QUATERNION :: intrinsics.type_is_quaternion; +@private IS_ARRAY :: intrinsics.type_is_array; + + +vector_dot :: proc(a, b: $T/[$N]$E) -> (c: E) where IS_NUMERIC(E) { + for i in 0.. (c: f32) { + return real(a)*real(a) + imag(a)*imag(b) + jmag(a)*jmag(b) + kmag(a)*kmag(b); +} +quaternion256_dot :: proc(a, b: $T/quaternion256) -> (c: f64) { + return real(a)*real(a) + imag(a)*imag(b) + jmag(a)*jmag(b) + kmag(a)*kmag(b); +} + +dot :: proc{vector_dot, quaternion128_dot, quaternion256_dot}; + +quaternion_inverse :: proc(q: $Q) -> Q where IS_QUATERNION(Q) { + return conj(q) * quaternion(1.0/dot(q, q), 0, 0, 0); +} + + +vector_cross2 :: proc(a, b: $T/[2]$E) -> E where IS_NUMERIC(E) { + return a[0]*b[1] - b[0]*a[1]; +} + +vector_cross3 :: proc(a, b: $T/[3]$E) -> (c: T) where IS_NUMERIC(E) { + c[0] = a[1]*b[2] - b[1]*a[2]; + c[1] = a[2]*b[0] - b[2]*a[0]; + c[2] = a[0]*b[1] - b[0]*a[1]; + return; +} + +vector_cross :: proc{vector_cross2, vector_cross3}; +cross :: vector_cross; + +vector_normalize :: proc(v: $T/[$N]$E) -> T where IS_NUMERIC(E) { + return v / length(v); +} +quaternion_normalize :: proc(q: $Q) -> Q where IS_QUATERNION(Q) { + return q/abs(q); +} +normalize :: proc{vector_normalize, quaternion_normalize}; + +vector_normalize0 :: proc(v: $T/[$N]$E) -> T where IS_NUMERIC(E) { + m := length(v); + return m == 0 ? 0 : v/m; +} +quaternion_normalize0 :: proc(q: $Q) -> Q where IS_QUATERNION(Q) { + m := abs(q); + return m == 0 ? 0 : q/m; +} +normalize0 :: proc{vector_normalize0, quaternion_normalize0}; + + +vector_length :: proc(v: $T/[$N]$E) -> E where IS_NUMERIC(E) { + return math.sqrt(dot(v, v)); +} + +vector_length2 :: proc(v: $T/[$N]$E) -> E where IS_NUMERIC(E) { + return dot(v, v); +} + +quaternion_length :: proc(q: $Q) -> Q where IS_QUATERNION(Q) { + return abs(q); +} + +quaternion_length2 :: proc(q: $Q) -> Q where IS_QUATERNION(Q) { + return dot(q, q); +} + +length :: proc{vector_length, quaternion_length}; +length2 :: proc{vector_length2, quaternion_length2}; + + +vector_lerp :: proc(x, y, t: $V/[$N]$E) -> V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + s: V; + for i in 0.. V where IS_NUMERIC(E) { + return length(p1 - p0); +} + +vector_reflect :: proc(i, n: $V/[$N]$E) -> V where IS_NUMERIC(E) { + b := n * (2 * dot(n, i)); + return i - b; +} + +vector_refract :: proc(i, n: $V/[$N]$E, eta: E) -> V where IS_NUMERIC(E) { + dv := dot(n, i); + k := 1 - eta*eta - (1 - dv*dv); + a := i * eta; + b := n * eta*dv*math.sqrt(k); + return (a - b) * E(int(k >= 0)); +} + + + +identity :: proc($T: typeid/[$N][N]$E) -> (m: T) { + for i in 0.. (m: T) { + for j in 0.. (c: M) + where !IS_ARRAY(E), + IS_NUMERIC(E) { + for i in 0.. (c: [K][I]E) + where !IS_ARRAY(E), + IS_NUMERIC(E), + I != K { + for k in 0.. (c: B) + where !IS_ARRAY(E), + IS_NUMERIC(E) { + for i in 0.. V { + Raw_Quaternion :: struct {xyz: [3]f32, r: f32}; + + q := transmute(Raw_Quaternion)q; + v := transmute([3]f32)v; + + t := cross(2*q.xyz, v); + return V(v + q.r*t + cross(q.xyz, t)); +} + +quaternion256_mul_vector3 :: proc(q: $Q/quaternion256, v: $V/[3]$F/f64) -> V { + Raw_Quaternion :: struct {xyz: [3]f64, r: f64}; + + q := transmute(Raw_Quaternion)q; + v := transmute([3]f64)v; + + t := cross(2*q.xyz, v); + return V(v + q.r*t + cross(q.xyz, t)); +} +quaternion_mul_vector3 :: proc{quaternion128_mul_vector3, quaternion256_mul_vector3}; + +mul :: proc{ + matrix_mul, + matrix_mul_differ, + matrix_mul_vector, + quaternion128_mul_vector3, + quaternion256_mul_vector3, +}; + +vector_to_ptr :: proc(v: ^$V/[$N]$E) -> ^E where IS_NUMERIC(E) { + return &v[0]; +} +matrix_to_ptr :: proc(m: ^$A/[$I][$J]$E) -> ^E where IS_NUMERIC(E) { + return &m[0][0]; +} + diff --git a/core/math/linalg/linalg.odin b/core/math/linalg/specific.odin similarity index 64% rename from core/math/linalg/linalg.odin rename to core/math/linalg/specific.odin index 8571a1745..def6e8ac1 100644 --- a/core/math/linalg/linalg.odin +++ b/core/math/linalg/specific.odin @@ -3,394 +3,6 @@ package linalg import "core:math" import "intrinsics" -// Generic - -@private IS_NUMERIC :: intrinsics.type_is_numeric; -@private IS_QUATERNION :: intrinsics.type_is_quaternion; -@private IS_ARRAY :: intrinsics.type_is_array; - - -vector_dot :: proc(a, b: $T/[$N]$E) -> (c: E) where IS_NUMERIC(E) { - for i in 0.. (c: f32) { - return real(a)*real(a) + imag(a)*imag(b) + jmag(a)*jmag(b) + kmag(a)*kmag(b); -} -quaternion256_dot :: proc(a, b: $T/quaternion256) -> (c: f64) { - return real(a)*real(a) + imag(a)*imag(b) + jmag(a)*jmag(b) + kmag(a)*kmag(b); -} - -dot :: proc{vector_dot, quaternion128_dot, quaternion256_dot}; - -quaternion_inverse :: proc(q: $Q) -> Q where IS_QUATERNION(Q) { - return conj(q) * quaternion(1.0/dot(q, q), 0, 0, 0); -} - - -vector_cross2 :: proc(a, b: $T/[2]$E) -> E where IS_NUMERIC(E) { - return a[0]*b[1] - b[0]*a[1]; -} - -vector_cross3 :: proc(a, b: $T/[3]$E) -> (c: T) where IS_NUMERIC(E) { - c[0] = a[1]*b[2] - b[1]*a[2]; - c[1] = a[2]*b[0] - b[2]*a[0]; - c[2] = a[0]*b[1] - b[0]*a[1]; - return; -} - -vector_cross :: proc{vector_cross2, vector_cross3}; -cross :: vector_cross; - -vector_normalize :: proc(v: $T/[$N]$E) -> T where IS_NUMERIC(E) { - return v / length(v); -} -quaternion_normalize :: proc(q: $Q) -> Q where IS_QUATERNION(Q) { - return q/abs(q); -} -normalize :: proc{vector_normalize, quaternion_normalize}; - -vector_normalize0 :: proc(v: $T/[$N]$E) -> T where IS_NUMERIC(E) { - m := length(v); - return m == 0 ? 0 : v/m; -} -quaternion_normalize0 :: proc(q: $Q) -> Q where IS_QUATERNION(Q) { - m := abs(q); - return m == 0 ? 0 : q/m; -} -normalize0 :: proc{vector_normalize0, quaternion_normalize0}; - - -vector_length :: proc(v: $T/[$N]$E) -> E where IS_NUMERIC(E) { - return math.sqrt(dot(v, v)); -} - -vector_length2 :: proc(v: $T/[$N]$E) -> E where IS_NUMERIC(E) { - return dot(v, v); -} - -quaternion_length :: proc(q: $Q) -> Q where IS_QUATERNION(Q) { - return abs(q); -} - -quaternion_length2 :: proc(q: $Q) -> Q where IS_QUATERNION(Q) { - return dot(q, q); -} - -length :: proc{vector_length, quaternion_length}; -length2 :: proc{vector_length2, quaternion_length2}; - - -vector_lerp :: proc(x, y, t: $V/[$N]$E) -> V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - s: V; - for i in 0.. V where IS_NUMERIC(E) { - return length(p1 - p0); -} - -vector_reflect :: proc(i, n: $V/[$N]$E) -> V where IS_NUMERIC(E) { - b := n * (2 * dot(n, i)); - return i - b; -} - -vector_refract :: proc(i, n: $V/[$N]$E, eta: E) -> V where IS_NUMERIC(E) { - dv := dot(n, i); - k := 1 - eta*eta - (1 - dv*dv); - a := i * eta; - b := n * eta*dv*math.sqrt(k); - return (a - b) * E(int(k >= 0)); -} - - - -identity :: proc($T: typeid/[$N][N]$E) -> (m: T) { - for i in 0.. (m: T) { - for j in 0.. (c: M) - where !IS_ARRAY(E), - IS_NUMERIC(E) { - for i in 0.. (c: [K][I]E) - where !IS_ARRAY(E), - IS_NUMERIC(E), - I != K { - for k in 0.. (c: B) - where !IS_ARRAY(E), - IS_NUMERIC(E) { - for i in 0.. V { - Raw_Quaternion :: struct {xyz: [3]f32, r: f32}; - - q := transmute(Raw_Quaternion)q; - v := transmute([3]f32)v; - - t := cross(2*q.xyz, v); - return V(v + q.r*t + cross(q.xyz, t)); -} - -quaternion256_mul_vector3 :: proc(q: $Q/quaternion256, v: $V/[3]$F/f64) -> V { - Raw_Quaternion :: struct {xyz: [3]f64, r: f64}; - - q := transmute(Raw_Quaternion)q; - v := transmute([3]f64)v; - - t := cross(2*q.xyz, v); - return V(v + q.r*t + cross(q.xyz, t)); -} -quaternion_mul_vector3 :: proc{quaternion128_mul_vector3, quaternion256_mul_vector3}; - -mul :: proc{ - matrix_mul, - matrix_mul_differ, - matrix_mul_vector, - quaternion128_mul_vector3, - quaternion256_mul_vector3, -}; - -vector_to_ptr :: proc(v: ^$V/[$N]$E) -> ^E where IS_NUMERIC(E) { - return &v[0]; -} -matrix_to_ptr :: proc(m: ^$A/[$I][$J]$E) -> ^E where IS_NUMERIC(E) { - return &m[0][0]; -} - // Specific