From 68ccaf8b68da82026f116d0b4710f1992e44b91d Mon Sep 17 00:00:00 2001 From: Lorenzo Torres Date: Tue, 12 Aug 2025 23:00:42 +0200 Subject: [PATCH] Implemented a RTS-style camera --- src/math.zig | 41 +++++++++++++++++++++++--------------- src/rendering/Camera.zig | 26 +++++++++++++++++++++++- src/rendering/Renderer.zig | 4 ++-- src/sideros.zig | 2 +- src/systems.zig | 14 ++++--------- 5 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/math.zig b/src/math.zig index ad93c0c..6768c52 100644 --- a/src/math.zig +++ b/src/math.zig @@ -45,24 +45,33 @@ pub const Transform = extern struct { pub const Matrix = extern struct { rows: [4][4]f32, - pub fn lookAt(eye: [3]f32, target: [3]f32, arbitrary_up: [3]f32) Matrix { - const t: @Vector(3, f32) = target; - const e: @Vector(3, f32) = eye; - const u: @Vector(3, f32) = arbitrary_up; - const forward = normalize(t - e); - const right = normalize(cross(forward, u)); - const up = cross(right, forward); + //pub fn lookAt(eye: [3]f32, target: [3]f32, arbitrary_up: [3]f32) Matrix { + // const t: @Vector(3, f32) = target; + // const e: @Vector(3, f32) = eye; + // const u: @Vector(3, f32) = arbitrary_up; + // const forward = normalize(t - e); + // const right = normalize(cross(forward, u)); + // const up = cross(right, forward); - const view = [4][4]f32{ - [4]f32{ right[0], up[0], -forward[0], 0.0 }, - [4]f32{ right[1], up[1], -forward[1], 0.0 }, - [4]f32{ right[2], up[2], -forward[2], 0.0 }, - [4]f32{ -dot(e, right), -dot(e, up), -dot(e, forward), 1.0 }, - }; + // const view = [4][4]f32{ + // [4]f32{ right[0], up[0], -forward[0], 0.0 }, + // [4]f32{ right[1], up[1], -forward[1], 0.0 }, + // [4]f32{ right[2], up[2], -forward[2], 0.0 }, + // [4]f32{ -dot(e, right), -dot(e, up), -dot(e, forward), 1.0 }, + // }; - return .{ - .rows = view, - }; + // return .{ + // .rows = view, + // }; + //} + + pub fn lookAt(eye: [3]f32, yaw: f32, pitch: f32) Matrix { + var translation = Matrix.identity(); + translation.translate(.{ -eye[0], -eye[1], -eye[2] }); + const yaw_rotation = Quaternion.fromAxisAngle(.{0.0, 1.0, 0.0}, -yaw); + const pitch_rotation = Quaternion.fromAxisAngle(.{1.0, 0.0, 0.0}, -pitch); + + return translation.mul(yaw_rotation.matrix()).mul(pitch_rotation.matrix()); } pub fn perspective(fov: f32, aspect: f32, near: f32, far: f32) Matrix { diff --git a/src/rendering/Camera.zig b/src/rendering/Camera.zig index 4cd4e38..4e27850 100644 --- a/src/rendering/Camera.zig +++ b/src/rendering/Camera.zig @@ -15,13 +15,37 @@ position: @Vector(3, f32), target: @Vector(3, f32) = .{ 0.0, 0.0, -1.0 }, up: @Vector(3, f32) = .{ 0.0, 1.0, 0.0 }, speed: f32 = 5, +pitch: f32 = -45, +yaw: f32 = 0, +distance: f32 = 5.0, pub fn getProjection(width: usize, height: usize) math.Matrix { return math.Matrix.perspective(math.rad(45.0), (@as(f32, @floatFromInt(width)) / @as(f32, @floatFromInt(height))), 0.1, 100.0); } pub fn getView(self: *Camera) math.Matrix { - return math.Matrix.lookAt(self.position, self.position + self.target, self.up); + return math.Matrix.lookAt(self.position, math.rad(self.yaw), math.rad(self.pitch)); +} + +pub fn getTarget(self: *Camera) @Vector(3, f32) { + const direction: @Vector(3, f32) = .{ + math.sin(math.rad(self.yaw)) * math.cos(math.rad(self.pitch)), + math.sin(math.rad(self.pitch)), + math.cos(math.rad(self.yaw)) * math.cos(math.rad(self.pitch)), + }; + + const t = (self.position[1] - (self.position[1] - self.distance)) / direction[1]; + const target: @Vector(3, f32) = .{ + self.position[0] + (t*direction[0]), + (self.position[1] - self.distance), + self.position[2] + (t*direction[2]), + }; + + //target[2] = 0.0; + + std.debug.print("{} {} {}\n", .{direction, t, target}); + + return target; } diff --git a/src/rendering/Renderer.zig b/src/rendering/Renderer.zig index ad6da5b..5f08915 100644 --- a/src/rendering/Renderer.zig +++ b/src/rendering/Renderer.zig @@ -66,7 +66,7 @@ pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_hand graphics_pipeline.point_lights[0].diffuse = .{0.5, 0.5, 0.5}; graphics_pipeline.point_lights[0].specular = .{1.0, 1.0, 1.0}; - graphics_pipeline.point_lights[1].position = .{1.0, 1.0, 0.0}; + graphics_pipeline.point_lights[1].position = .{0.0, 2.0, 0.5}; graphics_pipeline.point_lights[1].data[0] = 1.0; graphics_pipeline.point_lights[1].data[1] = 0.9; graphics_pipeline.point_lights[1].data[2] = 0.8; @@ -76,7 +76,7 @@ pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_hand var transforms = std.ArrayList(math.Transform).init(allocator); - try transforms.append(math.Transform.init(.{0.0, 0.0, -1.0}, .{0.5, 0.5, 0.5}, .{0.0, 0.0, 0.0})); + try transforms.append(math.Transform.init(.{0.0, 0.5, 1.0}, .{0.5, 0.5, 0.5}, .{0.0, 0.0, 0.0})); try transforms.append(math.Transform.init(.{0.0, 0.0, 0.0}, .{0.5, 0.5, 0.5}, .{0.0, 0.0, 0.0})); return .{ diff --git a/src/sideros.zig b/src/sideros.zig index a616681..6d76dcd 100644 --- a/src/sideros.zig +++ b/src/sideros.zig @@ -17,7 +17,7 @@ const allocator = gpa.allocator(); var pool: ecs.Pool = undefined; var renderer: Renderer = undefined; var camera: rendering.Camera = .{ - .position = .{ 0.0, 0.0, 5.0 }, + .position = .{ 0.0, 5.0, -5.0 }, }; var input: ecs.Input = .{ .key_pressed = .{false} ** @intFromEnum(ecs.Input.KeyCode.menu) }; var resources: ecs.Resources = undefined; diff --git a/src/systems.zig b/src/systems.zig index 966db83..fa9c42c 100644 --- a/src/systems.zig +++ b/src/systems.zig @@ -34,21 +34,15 @@ pub fn moveCamera(pool: *ecs.Pool) !void { const mul = @as(@Vector(3, f32), @splat(camera.speed * pool.resources.delta_time)); if (input.isKeyDown(.w)) { - camera.position += camera.target * mul; + camera.position += @as(@Vector(3, f32), .{0.0, 0.0, 1.0}) * mul; } if (input.isKeyDown(.s)) { - camera.position -= camera.target * mul; + camera.position += @as(@Vector(3, f32), .{0.0, 0.0, -1.0}) * mul; } if (input.isKeyDown(.a)) { - camera.position -= math.normalize(math.cross(camera.target, camera.up)) * mul; + camera.position -= @as(@Vector(3, f32), .{1.0, 0.0, 0.0}) * mul; } if (input.isKeyDown(.d)) { - camera.position += math.normalize(math.cross(camera.target, camera.up)) * mul; - } - if (input.isKeyDown(.space)) { - camera.position += camera.up * mul; - } - if (input.isKeyDown(.left_shift)) { - camera.position -= camera.up * mul; + camera.position += @as(@Vector(3, f32), .{1.0, 0.0, 0.0}) * mul; } }