Implemented a RTS-style camera

This commit is contained in:
Lorenzo Torres 2025-08-12 23:00:42 +02:00
parent f2fd7a3f1b
commit 68ccaf8b68
5 changed files with 57 additions and 30 deletions

View file

@ -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 {

View file

@ -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;
}

View file

@ -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 .{

View file

@ -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;

View file

@ -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;
}
}