diff --git a/core/math/linalg/specific.odin b/core/math/linalg/specific.odin index 1b3bc1f2d..f7b255961 100644 --- a/core/math/linalg/specific.odin +++ b/core/math/linalg/specific.odin @@ -2,11 +2,6 @@ package linalg import "core:math" - -// Specific - -Float :: f64 when #config(ODIN_MATH_LINALG_USE_F64, false) else f32; - F32_EPSILON :: 1e-7; F64_EPSILON :: 1e-15; @@ -123,6 +118,7 @@ orthogonal :: proc{vector2_orthogonal, vector3_orthogonal}; + vector4_srgb_to_linear_f32 :: proc(col: Vector4f32) -> Vector4f32 { r := math.pow(col.x, 2.2); g := math.pow(col.y, 2.2); @@ -142,6 +138,7 @@ vector4_srgb_to_linear :: proc{ vector4_srgb_to_linear_f64, }; + vector4_linear_to_srgb_f32 :: proc(col: Vector4f32) -> Vector4f32 { a :: 2.51; b :: 0.03; @@ -190,6 +187,7 @@ vector4_linear_to_srgb :: proc{ }; + vector4_hsl_to_rgb_f32 :: proc(h, s, l: f32, a: f32 = 1) -> Vector4f32 { hue_to_rgb :: proc(p, q, t: f32) -> f32 { t := t; @@ -249,6 +247,7 @@ vector4_hsl_to_rgb :: proc{ vector4_hsl_to_rgb_f64, }; + vector4_rgb_to_hsl_f32 :: proc(col: Vector4f32) -> Vector4f32 { r := col.x; g := col.y; @@ -314,6 +313,7 @@ vector4_rgb_to_hsl :: proc{ }; + quaternion_angle_axis_f32 :: proc(angle_radians: f32, axis: Vector3f32) -> (q: Quaternionf32) { t := angle_radians*0.5; v := normalize(axis) * math.sin(t); @@ -337,6 +337,7 @@ quaternion_angle_axis :: proc{ quaternion_angle_axis_f64, }; + angle_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 { if abs(q.w) > math.SQRT_THREE*0.5 { return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2; @@ -356,6 +357,7 @@ angle_from_quaternion :: proc{ angle_from_quaternion_f64, }; + axis_from_quaternion_f32 :: proc(q: Quaternionf32) -> Vector3f32 { t1 := 1 - q.w*q.w; if t1 < 0 { @@ -377,6 +379,7 @@ axis_from_quaternion :: proc{ axis_from_quaternion_f64, }; + angle_axis_from_quaternion_f32 :: proc(q: Quaternionf32) -> (angle: f32, axis: Vector3f32) { angle = angle_from_quaternion(q); axis = axis_from_quaternion(q); @@ -484,6 +487,7 @@ quaternion_from_forward_and_up :: proc{ quaternion_from_forward_and_up_f64, }; + quaternion_look_at_f32 :: proc(eye, centre: Vector3f32, up: Vector3f32) -> Quaternionf32 { return quaternion_from_matrix3(matrix3_look_at(eye, centre, up)); } @@ -496,6 +500,7 @@ quaternion_look_at :: proc{ }; + quaternion_nlerp_f32 :: proc(a, b: Quaternionf32, t: f32) -> (c: Quaternionf32) { c.x = a.x + (b.x-a.x)*t; c.y = a.y + (b.y-a.y)*t; @@ -515,6 +520,7 @@ quaternion_nlerp :: proc{ quaternion_nlerp_f64, }; + quaternion_slerp_f32 :: proc(x, y: Quaternionf32, t: f32) -> (q: Quaternionf32) { a, b := x, y; cos_angle := dot(a, b); @@ -574,6 +580,7 @@ quaternion_slerp :: proc{ quaternion_slerp_f64, }; + quaternion_squad_f32 :: proc(q1, q2, s1, s2: Quaternionf32, h: f32) -> Quaternionf32 { slerp :: quaternion_slerp; return slerp(slerp(q1, q2, h), slerp(s1, s2, h), 2 * (1 - h) * h); @@ -587,6 +594,7 @@ quaternion_squad :: proc{ quaternion_squad_f64, }; + quaternion_from_matrix4_f32 :: proc(m: Matrix4f32) -> (q: Quaternionf32) { m3: Matrix3f32 = ---; m3[0][0], m3[0][1], m3[0][2] = m[0][0], m[0][1], m[0][2]; @@ -606,6 +614,7 @@ quaternion_from_matrix4 :: proc{ quaternion_from_matrix4_f64, }; + quaternion_from_matrix3_f32 :: proc(m: Matrix3f32) -> (q: Quaternionf32) { four_x_squared_minus_1 := m[0][0] - m[1][1] - m[2][2]; four_y_squared_minus_1 := m[1][1] - m[0][0] - m[2][2]; @@ -709,6 +718,7 @@ quaternion_from_matrix3 :: proc{ quaternion_from_matrix3_f64, }; + quaternion_between_two_vector3_f32 :: proc(from, to: Vector3f32) -> (q: Quaternionf32) { x := normalize(from); y := normalize(to); @@ -756,6 +766,7 @@ quaternion_between_two_vector3 :: proc{ quaternion_between_two_vector3_f64, }; + matrix2_inverse_transpose_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) { d := m[0][0]*m[1][1] - m[1][0]*m[0][1]; id := 1.0/d; @@ -779,6 +790,7 @@ matrix2_inverse_transpose :: proc{ matrix2_inverse_transpose_f64, }; + matrix2_determinant_f32 :: proc(m: Matrix2f32) -> f32 { return m[0][0]*m[1][1] - m[1][0]*m[0][1]; } @@ -790,6 +802,7 @@ matrix2_determinant :: proc{ matrix2_determinant_f64, }; + matrix2_inverse_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) { d := m[0][0]*m[1][1] - m[1][0]*m[0][1]; id := 1.0/d; @@ -813,6 +826,7 @@ matrix2_inverse :: proc{ matrix2_inverse_f64, }; + matrix2_adjoint_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) { c[0][0] = +m[1][1]; c[0][1] = -m[1][0]; @@ -832,6 +846,7 @@ matrix2_adjoint :: proc{ matrix2_adjoint_f64, }; + matrix3_from_quaternion_f32 :: proc(q: Quaternionf32) -> (m: Matrix3f32) { qxx := q.x * q.x; qyy := q.y * q.y; @@ -885,6 +900,7 @@ matrix3_from_quaternion :: proc{ matrix3_from_quaternion_f64, }; + matrix3_inverse_f32 :: proc(m: Matrix3f32) -> Matrix3f32 { return transpose(matrix3_inverse_transpose(m)); } @@ -896,6 +912,7 @@ matrix3_inverse :: proc{ matrix3_inverse_f64, }; + matrix3_determinant_f32 :: proc(m: Matrix3f32) -> f32 { a := +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]); b := -m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]); @@ -913,6 +930,7 @@ matrix3_determinant :: proc{ matrix3_determinant_f64, }; + matrix3_adjoint_f32 :: proc(m: Matrix3f32) -> (adjoint: Matrix3f32) { adjoint[0][0] = +(m[1][1] * m[2][2] - m[1][2] * m[2][1]); adjoint[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]); @@ -942,6 +960,7 @@ matrix3_adjoint :: proc{ matrix3_adjoint_f64, }; + matrix3_inverse_transpose_f32 :: proc(m: Matrix3f32) -> (inverse_transpose: Matrix3f32) { adjoint := matrix3_adjoint(m); determinant := matrix3_determinant(m); @@ -969,6 +988,7 @@ matrix3_inverse_transpose :: proc{ matrix3_inverse_transpose_f64, }; + matrix3_scale_f32 :: proc(s: Vector3f32) -> (m: Matrix3f32) { m[0][0] = s[0]; m[1][1] = s[1]; @@ -986,6 +1006,7 @@ matrix3_scale :: proc{ matrix3_scale_f64, }; + matrix3_rotate_f32 :: proc(angle_radians: f32, v: Vector3f32) -> (rot: Matrix3f32) { c := math.cos(angle_radians); s := math.sin(angle_radians); @@ -1033,6 +1054,7 @@ matrix3_rotate :: proc{ matrix3_rotate_f64, }; + matrix3_look_at_f32 :: proc(eye, centre, up: Vector3f32) -> Matrix3f32 { f := normalize(centre - eye); s := normalize(cross(f, up)); @@ -1058,6 +1080,7 @@ matrix3_look_at :: proc{ matrix3_look_at_f64, }; + matrix4_from_quaternion_f32 :: proc(q: Quaternionf32) -> (m: Matrix4f32) { qxx := q.x * q.x; qyy := q.y * q.y; @@ -1117,6 +1140,7 @@ matrix4_from_quaternion :: proc{ matrix4_from_quaternion_f64, }; + matrix4_from_trs_f32 :: proc(t: Vector3f32, r: Quaternionf32, s: Vector3f32) -> Matrix4f32 { translation := matrix4_translate(t); rotation := matrix4_from_quaternion(r); @@ -1135,6 +1159,7 @@ matrix4_from_trs :: proc{ }; + matrix4_inverse_f32 :: proc(m: Matrix4f32) -> Matrix4f32 { return transpose(matrix4_inverse_transpose(m)); } @@ -1146,6 +1171,7 @@ matrix4_inverse :: proc{ matrix4_inverse_f64, }; + matrix4_minor_f32 :: proc(m: Matrix4f32, c, r: int) -> f32 { cut_down: Matrix3f32; for i in 0..<3 { @@ -1173,6 +1199,7 @@ matrix4_minor :: proc{ matrix4_minor_f64, }; + matrix4_cofactor_f32 :: proc(m: Matrix4f32, c, r: int) -> f32 { sign, minor: f32; sign = 1 if (c + r) % 2 == 0 else -1; @@ -1190,6 +1217,7 @@ matrix4_cofactor :: proc{ matrix4_cofactor_f64, }; + matrix4_adjoint_f32 :: proc(m: Matrix4f32) -> (adjoint: Matrix4f32) { for i in 0..<4 { for j in 0..<4 { @@ -1211,6 +1239,7 @@ matrix4_adjoint :: proc{ matrix4_adjoint_f64, }; + matrix4_determinant_f32 :: proc(m: Matrix4f32) -> (determinant: f32) { adjoint := matrix4_adjoint(m); for i in 0..<4 { @@ -1230,6 +1259,7 @@ matrix4_determinant :: proc{ matrix4_determinant_f64, }; + matrix4_inverse_transpose_f32 :: proc(m: Matrix4f32) -> (inverse_transpose: Matrix4f32) { adjoint := matrix4_adjoint(m); determinant: f32 = 0; @@ -1263,6 +1293,7 @@ matrix4_inverse_transpose :: proc{ matrix4_inverse_transpose_f64, }; + matrix4_translate_f32 :: proc(v: Vector3f32) -> Matrix4f32 { m := MATRIX4F32_IDENTITY; m[3][0] = v[0]; @@ -1282,6 +1313,7 @@ matrix4_translate :: proc{ matrix4_translate_f64, }; + matrix4_rotate_f32 :: proc(angle_radians: f32, v: Vector3f32) -> Matrix4f32 { c := math.cos(angle_radians); s := math.sin(angle_radians); @@ -1339,6 +1371,7 @@ matrix4_rotate :: proc{ matrix4_rotate_f64, }; + matrix4_scale_f32 :: proc(v: Vector3f32) -> (m: Matrix4f32) { m[0][0] = v[0]; m[1][1] = v[1]; @@ -1358,6 +1391,7 @@ matrix4_scale :: proc{ matrix4_scale_f64, }; + matrix4_look_at_f32 :: proc(eye, centre, up: Vector3f32, flip_z_axis := true) -> (m: Matrix4f32) { f := normalize(centre - eye); s := normalize(cross(f, up)); @@ -1392,6 +1426,7 @@ matrix4_look_at :: proc{ }; + matrix4_perspective_f32 :: proc(fovy, aspect, near, far: f32, flip_z_axis := true) -> (m: Matrix4f32) { tan_half_fovy := math.tan(0.5 * fovy); m[0][0] = 1 / (aspect*tan_half_fovy); @@ -1425,6 +1460,7 @@ matrix4_perspective :: proc{ matrix4_perspective_f64, }; + matrix_ortho3d_f32 :: proc(left, right, bottom, top, near, far: f32, flip_z_axis := true) -> (m: Matrix4f32) { m[0][0] = +2 / (right - left); m[1][1] = +2 / (top - bottom); @@ -1460,6 +1496,7 @@ matrix_ortho3d :: proc{ matrix_ortho3d_f64, }; + matrix4_infinite_perspective_f32 :: proc(fovy, aspect, near: f32, flip_z_axis := true) -> (m: Matrix4f32) { tan_half_fovy := math.tan(0.5 * fovy); m[0][0] = 1 / (aspect*tan_half_fovy); @@ -1494,6 +1531,7 @@ matrix4_infinite_perspective :: proc{ }; + matrix2_from_scalar_f32 :: proc(f: f32) -> (m: Matrix2f32) { m[0][0], m[0][1] = f, 0; m[1][0], m[1][1] = 0, f; @@ -1509,6 +1547,7 @@ matrix2_from_scalar :: proc{ matrix2_from_scalar_f64, }; + matrix3_from_scalar_f32 :: proc(f: f32) -> (m: Matrix3f32) { m[0][0], m[0][1], m[0][2] = f, 0, 0; m[1][0], m[1][1], m[1][2] = 0, f, 0; @@ -1526,6 +1565,7 @@ matrix3_from_scalar :: proc{ matrix3_from_scalar_f64, }; + matrix4_from_scalar_f32 :: proc(f: f32) -> (m: Matrix4f32) { m[0][0], m[0][1], m[0][2], m[0][3] = f, 0, 0, 0; m[1][0], m[1][1], m[1][2], m[1][3] = 0, f, 0, 0; @@ -1545,6 +1585,7 @@ matrix4_from_scalar :: proc{ matrix4_from_scalar_f64, }; + matrix2_from_matrix3_f32 :: proc(m: Matrix3f32) -> (r: Matrix2f32) { r[0][0], r[0][1] = m[0][0], m[0][1]; r[1][0], r[1][1] = m[1][0], m[1][1]; @@ -1560,6 +1601,7 @@ matrix2_from_matrix3 :: proc{ matrix2_from_matrix3_f64, }; + matrix2_from_matrix4_f32 :: proc(m: Matrix4f32) -> (r: Matrix2f32) { r[0][0], r[0][1] = m[0][0], m[0][1]; r[1][0], r[1][1] = m[1][0], m[1][1]; @@ -1575,6 +1617,7 @@ matrix2_from_matrix4 :: proc{ matrix2_from_matrix4_f64, }; + matrix3_from_matrix2_f32 :: proc(m: Matrix2f32) -> (r: Matrix3f32) { r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], 0; r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], 0; @@ -1592,6 +1635,7 @@ matrix3_from_matrix2 :: proc{ matrix3_from_matrix2_f64, }; + matrix3_from_matrix4_f32 :: proc(m: Matrix4f32) -> (r: Matrix3f32) { r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], m[0][2]; r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], m[1][2]; @@ -1609,6 +1653,7 @@ matrix3_from_matrix4 :: proc{ matrix3_from_matrix4_f64, }; + matrix4_from_matrix2_f32 :: proc(m: Matrix2f32) -> (r: Matrix4f32) { r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], 0, 0; r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], 0, 0; @@ -1628,6 +1673,7 @@ matrix4_from_matrix2 :: proc{ matrix4_from_matrix2_f64, }; + matrix4_from_matrix3_f32 :: proc(m: Matrix3f32) -> (r: Matrix4f32) { r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], m[0][2], 0; r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], m[1][2], 0; @@ -1647,6 +1693,7 @@ matrix4_from_matrix3 :: proc{ matrix4_from_matrix3_f64, }; + quaternion_from_scalar_f32 :: proc(f: f32) -> (q: Quaternionf32) { q.w = f; return; @@ -1660,35 +1707,48 @@ quaternion_from_scalar :: proc{ quaternion_from_scalar_f64, }; + to_matrix2f32 :: proc{matrix2_from_scalar_f32, matrix2_from_matrix3_f32, matrix2_from_matrix4_f32}; to_matrix3f32 :: proc{matrix3_from_scalar_f32, matrix3_from_matrix2_f32, matrix3_from_matrix4_f32, matrix3_from_quaternion_f32}; to_matrix4f32 :: proc{matrix4_from_scalar_f32, matrix4_from_matrix2_f32, matrix4_from_matrix3_f32, matrix4_from_quaternion_f32}; to_quaternionf32 :: proc{quaternion_from_scalar_f32, quaternion_from_matrix3_f32, quaternion_from_matrix4_f32}; + + to_matrix2f64 :: proc{matrix2_from_scalar_f64, matrix2_from_matrix3_f64, matrix2_from_matrix4_f64}; + to_matrix3f64 :: proc{matrix3_from_scalar_f64, matrix3_from_matrix2_f64, matrix3_from_matrix4_f64, matrix3_from_quaternion_f64}; + to_matrix4f64 :: proc{matrix4_from_scalar_f64, matrix4_from_matrix2_f64, matrix4_from_matrix3_f64, matrix4_from_quaternion_f64}; to_quaternionf64 :: proc{quaternion_from_scalar_f64, quaternion_from_matrix3_f64, quaternion_from_matrix4_f64}; + + + to_matrix2f :: proc{ + matrix2_from_scalar_f32, matrix2_from_matrix3_f32, matrix2_from_matrix4_f32, matrix2_from_scalar_f64, matrix2_from_matrix3_f64, matrix2_from_matrix4_f64, }; + to_matrix3 :: proc{ matrix3_from_scalar_f32, matrix3_from_matrix2_f32, matrix3_from_matrix4_f32, matrix3_from_quaternion_f32, matrix3_from_scalar_f64, matrix3_from_matrix2_f64, matrix3_from_matrix4_f64, matrix3_from_quaternion_f64, }; + to_matrix4 :: proc{ matrix4_from_scalar_f32, matrix4_from_matrix2_f32, matrix4_from_matrix3_f32, matrix4_from_quaternion_f32, matrix4_from_scalar_f64, matrix4_from_matrix2_f64, matrix4_from_matrix3_f64, matrix4_from_quaternion_f64, }; + to_quaternion :: proc{ quaternion_from_scalar_f32, quaternion_from_matrix3_f32, quaternion_from_matrix4_f32, quaternion_from_scalar_f64, quaternion_from_matrix3_f64, quaternion_from_matrix4_f64, }; + matrix2_orthonormalize_f32 :: proc(m: Matrix2f32) -> (r: Matrix2f32) { r[0] = normalize(m[0]); @@ -1712,6 +1772,7 @@ matrix2_orthonormalize :: proc{ matrix2_orthonormalize_f64, }; + matrix3_orthonormalize_f32 :: proc(m: Matrix3f32) -> (r: Matrix3f32) { r[0] = normalize(m[0]); @@ -1745,6 +1806,7 @@ matrix3_orthonormalize :: proc{ matrix3_orthonormalize_f64, }; + vector3_orthonormalize_f32 :: proc(x, y: Vector3f32) -> (z: Vector3f32) { return normalize(x - y * dot(y, x)); } @@ -1756,10 +1818,12 @@ vector3_orthonormalize :: proc{ vector3_orthonormalize_f64, }; + orthonormalize :: proc{ matrix2_orthonormalize_f32, matrix2_orthonormalize_f64, matrix3_orthonormalize_f32, + matrix3_orthonormalize_f64, vector3_orthonormalize_f32, vector3_orthonormalize_f64, @@ -1791,6 +1855,7 @@ matrix4_orientation :: proc{ matrix4_orientation_f64, }; + euclidean_from_polar_f32 :: proc(polar: Vector2f32) -> Vector3f32 { latitude, longitude := polar.x, polar.y; cx, sx := math.cos(latitude), math.sin(latitude); @@ -1818,6 +1883,7 @@ euclidean_from_polar :: proc{ euclidean_from_polar_f64, }; + polar_from_euclidean_f32 :: proc(euclidean: Vector3f32) -> Vector3f32 { n := length(euclidean); tmp := euclidean / n; @@ -1846,3 +1912,4 @@ polar_from_euclidean :: proc{ polar_from_euclidean_f32, polar_from_euclidean_f64, }; +