render-zig

A 3D rendering engine written in Zig
git clone git://git.christianermann.dev/render-zig
Log | Files | Refs

commit 50c1e63b87a5821cdbb5720d22f360f4ef3d64ab
parent 25834a22302c617d1de9bc0529fd77efdfdf87d1
Author: Christian Ermann <christianermann@gmail.com>
Date:   Wed, 15 May 2024 18:37:46 -0400

Add more camera controls

Diffstat:
Msrc/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)); }