commit 50c1e63b87a5821cdbb5720d22f360f4ef3d64ab
parent 25834a22302c617d1de9bc0529fd77efdfdf87d1
Author: Christian Ermann <christianermann@gmail.com>
Date: Wed, 15 May 2024 18:37:46 -0400
Add more camera controls
Diffstat:
M | src/camera.zig | | | 101 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
1 file changed, 97 insertions(+), 4 deletions(-)
diff --git a/src/camera.zig b/src/camera.zig
@@ -1,5 +1,8 @@
const std = @import("std");
-const WASDInput = @import("input.zig").WASDInput;
+const glfw = @import("mach_glfw");
+
+const UserInput = @import("input.zig").UserInput;
+const KeyCallbackArgs = @import("input.zig").KeyCallbackArgs;
const Camera = @This();
@@ -17,7 +20,49 @@ pitch: f32 = 0.0,
position: f32x3 = .{ 0, 0, -1 },
-input: WASDInput = WASDInput{},
+input: CameraInput = CameraInput{},
+
+pub const CameraInput = struct {
+ w: bool = false,
+ a: bool = false,
+ s: bool = false,
+ d: bool = false,
+
+ shift: bool = false,
+ space: bool = false,
+
+ left: bool = false,
+ right: bool = false,
+ up: bool = false,
+ down: bool = false,
+
+ fn keyCallback(ptr: *anyopaque, args: KeyCallbackArgs) void {
+ const self: *CameraInput = @ptrCast(@alignCast(ptr));
+ if ((args.action != glfw.Action.press) and (args.action != glfw.Action.release)) {
+ return;
+ }
+ switch (args.key) {
+ .w => self.w = !self.w,
+ .a => self.a = !self.a,
+ .s => self.s = !self.s,
+ .d => self.d = !self.d,
+ .left_shift => self.shift = !self.shift,
+ .space => self.space = !self.space,
+ .left => self.left = !self.left,
+ .right => self.right = !self.right,
+ .up => self.up = !self.up,
+ .down => self.down = !self.down,
+ else => {},
+ }
+ }
+
+ pub fn userInput(self: *CameraInput) UserInput {
+ return .{
+ .ptr = self,
+ .keyCallbackFn = CameraInput.keyCallback,
+ };
+ }
+};
pub fn logParams(self: *const Camera) void {
std.log.info("camera fovy: {}", .{self.fovy});
@@ -106,8 +151,49 @@ pub fn proj(self: *const Camera, mat: *mat4) void {
}
pub fn update(self: *Camera, _: f32) void {
+ var yaw: f32 = 0;
+ if (self.input.right) {
+ yaw += 1;
+ }
+ if (self.input.left) {
+ yaw -= 1;
+ }
+ self.yaw += yaw;
+ if (self.yaw > 180) {
+ self.yaw -= 360;
+ }
+ if (self.yaw < -180) {
+ self.yaw += 360;
+ }
+
+ var pitch: f32 = 0;
+ if (self.input.up) {
+ pitch += 1;
+ }
+ if (self.input.down) {
+ pitch -= 1;
+ }
+ self.pitch += pitch;
+ if (self.pitch > 89) {
+ self.pitch = 89;
+ }
+ if (self.pitch < -89) {
+ self.pitch = -89;
+ }
+
+ const cos_yaw = @cos(std.math.degreesToRadians(f32, self.yaw));
+ const sin_yaw = @sin(std.math.degreesToRadians(f32, self.yaw));
+ const cos_pitch = @cos(std.math.degreesToRadians(f32, self.pitch));
+ const sin_pitch = @sin(std.math.degreesToRadians(f32, self.pitch));
+ const f = f32x3_normalize(
+ f32x3{ cos_yaw * cos_pitch, sin_pitch, sin_yaw * cos_pitch },
+ );
+ const s = f32x3_normalize(f32x3_mul(f, f32x3{ 0, 1, 0 }));
+ const u = f32x3_normalize(f32x3_mul(s, f));
+
var forward: f32 = 0;
var right: f32 = 0;
+ var up: f32 = 0;
if (self.input.w) {
forward += 1;
}
@@ -120,7 +206,14 @@ pub fn update(self: *Camera, _: f32) void {
if (self.input.a) {
right -= 1;
}
+ if (self.input.space) {
+ up += 1;
+ }
+ if (self.input.shift) {
+ up -= 1;
+ }
- self.position[0] -= right * 0.01;
- self.position[2] += forward * 0.01;
+ self.position += f * @as(f32x3, @splat(forward * 0.01));
+ self.position += s * @as(f32x3, @splat(right * 0.01));
+ self.position += u * @as(f32x3, @splat(up * 0.01));
}