aboutsummaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2019-12-29 20:35:27 +0000
committergingerBill <bill@gingerbill.org>2019-12-29 20:35:27 +0000
commit2d70a784d16c5fa10f830e12c138f275ae5bb018 (patch)
tree176932300109bf455d8261e5cfa4f477e1fa7a2a /core/math
parenta8a4dc1eb1d70bf54dff983ec70ec5c63fd001a2 (diff)
Add `quaternion_look_at` orientation procedure to `package math/linalg`
Diffstat (limited to 'core/math')
-rw-r--r--core/math/linalg/specific.odin31
1 files changed, 26 insertions, 5 deletions
diff --git a/core/math/linalg/specific.odin b/core/math/linalg/specific.odin
index def6e8ac1..ed235df8d 100644
--- a/core/math/linalg/specific.odin
+++ b/core/math/linalg/specific.odin
@@ -8,6 +8,8 @@ import "intrinsics"
Float :: f32;
+FLOAT_EPSILON :: size_of(Float) == 4 ? 1e-7 : 1e-15;
+
Vector2 :: distinct [2]Float;
Vector3 :: distinct [3]Float;
Vector4 :: distinct [4]Float;
@@ -51,6 +53,14 @@ VECTOR3_Y_AXIS :: Vector3{0, 1, 0};
VECTOR3_Z_AXIS :: Vector3{0, 0, 1};
+radians :: proc(degrees: Float) -> Float {
+ return math.TAU * degrees / 360.0;
+}
+
+degrees :: proc(radians: Float) -> Float {
+ return 360.0 * radians / math.TAU;
+}
+
vector2_orthogonal :: proc(v: Vector2) -> Vector2 {
return {-v.y, v.x};
@@ -191,6 +201,20 @@ euler_angles_from_quaternion :: proc(q: Quaternion) -> (roll, pitch, yaw: Float)
return;
}
+quaternion_look_at :: proc(eye, centre: Vector3, up: Vector3) -> Quaternion {
+ f := normalize(centre - eye);
+ s := normalize(cross(f, up));
+ u := cross(s, f);
+
+ w := math.sqrt(1 + s.x + u.y - f.z)*0.5;
+ iw4 := 0.25/w;
+ x := (+u.z + f.y)*iw4;
+ y := (-f.x - s.z)*iw4;
+ z := (+s.y - u.x)*iw4;
+ q: Quaternion = quaternion(w, x, y, z);
+ return normalize(q);
+}
+
quaternion_nlerp :: proc(a, b: Quaternion, t: Float) -> Quaternion {
c := a + (b-a)*quaternion(t, 0, 0, 0);
@@ -199,7 +223,6 @@ quaternion_nlerp :: proc(a, b: Quaternion, t: Float) -> Quaternion {
quaternion_slerp :: proc(x, y: Quaternion, t: Float) -> Quaternion {
- EPSILON :: size_of(Float) == 4 ? 1e-7 : 1e-15;
a, b := x, y;
cos_angle := dot(a, b);
@@ -207,7 +230,7 @@ quaternion_slerp :: proc(x, y: Quaternion, t: Float) -> Quaternion {
b = -b;
cos_angle = -cos_angle;
}
- if cos_angle > 1 - EPSILON {
+ if cos_angle > 1 - FLOAT_EPSILON {
return a + (b-a)*quaternion(t, 0, 0, 0);
}
@@ -290,13 +313,11 @@ quaternion_from_matrix4 :: proc(m: Matrix4) -> Quaternion {
quaternion_between_two_vector3 :: proc(from, to: Vector3) -> Quaternion {
- EPSILON :: size_of(Float) == 4 ? 1e-7 : 1e-15;
-
x := normalize(from);
y := normalize(to);
cos_theta := dot(x, y);
- if abs(cos_theta + 1) < 2*EPSILON {
+ if abs(cos_theta + 1) < 2*FLOAT_EPSILON {
v := vector3_orthogonal(x);
return quaternion(0, v.x, v.y, v.z);
}