diff options
Diffstat (limited to 'src/misc.zig')
-rw-r--r-- | src/misc.zig | 50 |
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); |