aboutsummaryrefslogtreecommitdiff
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);