summary refs log tree commit diff
path: root/src/misc.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/misc.zig')
-rw-r--r--src/misc.zig50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/misc.zig b/src/misc.zig
index d523827..0b1ad54 100644
--- a/src/misc.zig
+++ b/src/misc.zig
@@ -17,6 +17,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Black Shades.  If not, see <https://www.gnu.org/licenses/>.
 
+const Child = std.meta.Child;
 const Dir = std.fs.Dir;
 const TokenIterator = std.mem.TokenIterator(u8);
 const allocPrint = std.fmt.allocPrint;
@@ -377,6 +378,55 @@ pub fn saveScores(base_dir: []const u8, current: Scores) !void {
     try dir.writeFile("scores.ini", data);
 }
 
+// TODO: move graphics functions to a seperate file
+fn sqr(x: anytype) @TypeOf(x) {
+    return x * x;
+}
+
+fn dot(u: anytype, v: @TypeOf(u)) Child(@TypeOf(u)) {
+    return @reduce(.Add, u * v);
+}
+
+fn norm(v: anytype) Child(@TypeOf(v)) {
+    return @sqrt(dot(v, v));
+}
+
+const XYZ = extern struct { x: f32, y: f32, z: f32 };
+
+export fn crossProduct(u: XYZ, v: XYZ) XYZ {
+    return .{
+        .x = u.y * v.z - u.z * v.y,
+        .y = u.z * v.x - u.x * v.z,
+        .z = u.x * v.y - u.y * v.x,
+    };
+}
+
+export fn normalize(v: XYZ) XYZ {
+    const u = @bitCast(@Vector(3, f32), v);
+    const d = norm(u);
+    return if (d == 0) v else @bitCast(XYZ, u / @splat(3, d));
+}
+
+export fn reflect(v: XYZ, n: XYZ) XYZ {
+    const u = @bitCast(@Vector(3, f32), v);
+    const m = @bitCast(@Vector(3, f32), n);
+    return @bitCast(XYZ, u - m * @splat(3, dot(u, m) * 2));
+}
+
+export fn segmentIntersectsSphere(a: XYZ, b: XYZ, j: XYZ, r: f32) bool {
+    // FIXME: call directly with vectors
+    const p = @bitCast(@Vector(3, f32), a);
+    const q = @bitCast(@Vector(3, f32), b);
+    const i = @bitCast(@Vector(3, f32), j);
+
+    if (@reduce(.Or, @max(p, q) < i - @splat(3, r))) return false;
+    if (@reduce(.Or, @min(p, q) > i + @splat(3, r))) return false;
+    // https://en.wikipedia.org/wiki/Line–sphere_intersection
+    const d = q - p; // line's direction
+    const u = d / @splat(3, norm(d)); // unit vector
+    return sqr(dot(u, (p - i))) >= @reduce(.Add, sqr(p - i)) - sqr(r);
+}
+
 export fn getFrustum(frustum: [*][4]f32) void {
     var proj: [16]f32 = undefined;
     c.glGetFloatv(c.GL_PROJECTION_MATRIX, &proj);