From 6d1c2a4bd8f469ad60c5333128654bde9b131d08 Mon Sep 17 00:00:00 2001 From: Peter Li Date: Wed, 23 Apr 2025 07:34:43 -0700 Subject: [PATCH] corrected camera transforms --- engine/core/src/math.zig | 4 ++ engine/core/src/scene.zig | 8 +-- engine/platform/src/platform.zig | 4 ++ engine/platform/src/windowing.zig | 6 ++ engine/rend/src/camera/CameraComponent.zig | 19 ++++-- lib/sdl3/src/sdl3.zig | 4 ++ projects/sampleGame/main.zig | 75 +++++++++++++++++----- 7 files changed, 97 insertions(+), 23 deletions(-) diff --git a/engine/core/src/math.zig b/engine/core/src/math.zig index e25f800..2227a5d 100644 --- a/engine/core/src/math.zig +++ b/engine/core/src/math.zig @@ -575,6 +575,10 @@ pub const Rotation = struct { }; } + pub fn forward(self: *@This()) Vectorf { + return self.rotateVector(.{ .z = 1 }); + } + pub fn rotateVector(self: @This(), other: Vectorf) Vectorf { return Vectorf.fromZm( zm.mul( diff --git a/engine/core/src/scene.zig b/engine/core/src/scene.zig index 96bece4..8c6ca97 100644 --- a/engine/core/src/scene.zig +++ b/engine/core/src/scene.zig @@ -315,11 +315,11 @@ pub const SceneSystem = struct { // }); repr.transform = core.zm.mul( core.zm.mul( - core.zm.mul( - core.zm.scalingV(posRot.scale.toZm()), - core.zm.matFromQuat(posRot.rotation.quat), - ), core.zm.translationV(posRot.position.toZm()), + core.zm.mul( + core.zm.matFromQuat(posRot.rotation.quat), + core.zm.scalingV(posRot.scale.toZm()), + ), ), final, ); diff --git a/engine/platform/src/platform.zig b/engine/platform/src/platform.zig index a6c182c..975f23e 100644 --- a/engine/platform/src/platform.zig +++ b/engine/platform/src/platform.zig @@ -19,6 +19,10 @@ pub fn setWindowSettings(params: windowing.PlatformParams) void { gStartupParams = params; } +pub fn getCursorPosition() core.Vector2u { + gPlatformInstance.getCursorPosition(); +} + pub fn start_module(comptime programSpec: anytype, args: anytype, allocator: std.mem.Allocator) !void { _ = args; _ = programSpec; diff --git a/engine/platform/src/windowing.zig b/engine/platform/src/windowing.zig index aa66352..064fbeb 100644 --- a/engine/platform/src/windowing.zig +++ b/engine/platform/src/windowing.zig @@ -77,6 +77,8 @@ pub const PlatformInstance = struct { processFuncs: std.ArrayListUnmanaged(*const fn (*sdl3.Event) void) = .{}, + cursorPos: core.Vector2f = .{}, + pub fn deinit(self: *@This()) void { self.allocator.free(self.windowName); self.allocator.free(self.iconPath); @@ -146,6 +148,10 @@ pub const PlatformInstance = struct { const inputStack = core.getInputStack(); inputStack.updatePreviousInputs(); while (sdl3.pollEvent()) |event| { + if (event.type == sdl3.events.mouse_motion) { + sdl3.getMouseState(&self.cursorPos.x, &self.cursorPos.y); + } + if (core.inputs.convertEvent(event)) |converted| { inputStack.routeEvent(converted); } diff --git a/engine/rend/src/camera/CameraComponent.zig b/engine/rend/src/camera/CameraComponent.zig index 5182c72..00a5a92 100644 --- a/engine/rend/src/camera/CameraComponent.zig +++ b/engine/rend/src/camera/CameraComponent.zig @@ -47,8 +47,14 @@ pub fn resolve(self: *@This()) void { self.updateProjections(); var position = scene.getPosition(); + var rotation = scene.getRotation(); self.finalPos = position; + // negate the handedness of the quaternion + rotation.quat[0] *= -1; + rotation.quat[1] *= -1; + rotation.quat[2] *= -1; + position.z = -position.z; position.y = -position.y; position.x = -position.x; @@ -67,12 +73,17 @@ pub fn resolve(self: *@This()) void { // calculate viewProjections { - // var base = core.zm.rotationY(self.yaw + core.radians(180.0)); - // base = mul(base, core.zm.rotationX(self.pitch)); - // base = mul(base, core.zm.rotationZ(self.roll)); self.transform = core.zm.identity(); - self.transform = mul(zm.translationV(position.toZm()), self.transform); + var base = core.zm.rotationY(self.yaw); + base = mul(base, core.zm.rotationX(self.pitch)); + base = mul(base, core.zm.rotationZ(self.roll)); + + self.transform = mul(base, self.transform); + // self.transform = core.zm.identity(); + + self.transform = mul(core.zm.matFromQuat(rotation.quat), self.transform); + self.transform = mul(core.zm.translationV(position.toZm()), self.transform); self.final = mul(self.transform, self.projection); // core.engine_log("{any}", .{self.final}); self.finalAlt = mul(self.transform, self.projectionAlt); diff --git a/lib/sdl3/src/sdl3.zig b/lib/sdl3/src/sdl3.zig index 1870875..6555922 100644 --- a/lib/sdl3/src/sdl3.zig +++ b/lib/sdl3/src/sdl3.zig @@ -44,6 +44,10 @@ pub fn pollEvent() ?*Event { return null; } +pub fn getMouseState(x: *f32, y: *f32) void { + _ = c.SDL_GetMouseState(@ptrCast(x), @ptrCast(y)); +} + pub fn getError() [*c]const u8 { return c.SDL_GetError(); } diff --git a/projects/sampleGame/main.zig b/projects/sampleGame/main.zig index 7a4d3a7..c0501f0 100644 --- a/projects/sampleGame/main.zig +++ b/projects/sampleGame/main.zig @@ -1,13 +1,19 @@ allocator: std.mem.Allocator, camera: core.Entity = undefined, +cameraComponent: *rend.CameraComponent = undefined, cameraSpeed: f32 = 10.0, moveInput: *core.Axis2dBinding = undefined, moveVector: core.Vectorf = .{}, +rotateAxis: f32 = 0.0, +rotateAxisPitch: f32 = 0.0, + verticalMove: f32 = 0.0, +yaw: f32 = 0.0, +pitch: f32 = 0.0, pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); @@ -40,11 +46,11 @@ const assetReferences = [_]assets.AssetImportReference{ "t_fox", .{ .path = "gltf-samples/Fox/glTF/Texture.png" }, ), - assets.MakeImportRefOptions( - "Texture", - "t_empire", - .{ .path = "textures/lost_empire-RGBA.png" }, - ), + // assets.MakeImportRefOptions( + // "Texture", + // "t_empire", + // .{ .path = "textures/lost_empire-RGBA.png" }, + // ), }; pub fn prepare(self: *@This()) !void { @@ -73,7 +79,7 @@ pub fn prepare(self: *@This()) !void { self.camera = try core.createEntity(); const cameraScene = self.camera.addComponent(core.Scene).?; cameraScene.setPosition(.{ .z = -15 }); - const camera = self.camera.addComponent(rend.CameraComponent).?; + self.cameraComponent = self.camera.addComponent(rend.CameraComponent).?; { const lostEmpire = try core.createEntity(); @@ -81,7 +87,7 @@ pub fn prepare(self: *@This()) !void { scene.setPosition(.{ .y = -20 }); const empireMesh = lostEmpire.addComponent(rend.MeshComponent).?; empireMesh.setMesh("m_empire"); - empireMesh.setTexture("t_empire"); + empireMesh.setTexture("t_default"); } { @@ -104,7 +110,7 @@ pub fn prepare(self: *@This()) !void { mesh.setTexture("t_default"); } - rend.setActiveCamera(camera); + rend.setActiveCamera(self.cameraComponent); self.moveInput = try core.Axis2dBinding.create(core.MakeName("movement")); @@ -116,6 +122,24 @@ pub fn prepare(self: *@This()) !void { _ = self.moveInput.data.addListener(self, onMove); self.moveInput.activate(); + { + const i = try core.Axis1dBinding.create(core.MakeName("movementRotation")); + i.addKey(.z, 1.0); + i.addKey(.x, -1.0); + + _ = i.data.addListener(self, cameraRotate); + i.activate(); + } + + { + const i = try core.Axis1dBinding.create(core.MakeName("rotPitch")); + i.addKey(.f, 1.0); + i.addKey(.v, -1.0); + + _ = i.data.addListener(self, cameraRotatePitch); + i.activate(); + } + const verticalInput = try core.Axis1dBinding.create(core.MakeName("movementVertical")); verticalInput.addKey(.e, 1.0); verticalInput.addKey(.q, -1.0); @@ -150,6 +174,16 @@ fn slowDown(ctx: ?*anyopaque, action: core.ActionEvent) void { } } +fn cameraRotatePitch(ctx: ?*anyopaque, axis: f32) void { + const self: *@This() = @ptrCast(@alignCast(ctx)); + self.rotateAxisPitch = axis; +} + +fn cameraRotate(ctx: ?*anyopaque, axis: f32) void { + const self: *@This() = @ptrCast(@alignCast(ctx)); + self.rotateAxis = axis; +} + fn verticalMovement(ctx: ?*anyopaque, axis: f32) void { const self: *@This() = @ptrCast(@alignCast(ctx)); self.verticalMove = axis; @@ -169,15 +203,26 @@ pub fn onExit(ctx: ?*anyopaque, action: core.ActionEvent) void { pub fn tick(self: *@This(), dt: f64) void { const fdt: f32 = @floatCast(dt); + if (self.camera.fetch(core.Scene)) |scene| { const vector = core.Vectorf{ .x = self.moveVector.x, .z = self.moveVector.z, .y = self.verticalMove }; - scene.getPosRot().position = scene.getPosRot().position.add(vector.fmul(self.cameraSpeed * fdt)); - core.debugSphere(scene.getPosRot().position.add(.{ .z = 2 }), 0.3, .{}); - core.debugSphere( - scene.getPosRot().position.add(.{ .z = 2 }), - 0.1, - .{ .color = .{ .x = 1.0 } }, - ); + + const posRot = scene.getPosRot(); + + self.yaw += self.rotateAxis * fdt * 20; + self.pitch += self.rotateAxisPitch * fdt * 20; + + self.cameraComponent.pitch = std.math.clamp(core.radians(self.pitch), core.radians(-90.0), core.radians(90.0)); + posRot.rotation = core.Rotation.eulerY(core.radians(self.yaw)); + const movement = scene.getPosRot().rotation.rotateVector(vector.fmul(self.cameraSpeed * fdt)); + + scene.getPosRot().position = scene.getPosRot().position.add(movement); + + const forward = posRot.rotation.forward(); + const debugCenter = scene.getPosRot().position.add(forward.fmul(2)); + + core.debugSphere(debugCenter, 0.3, .{}); + core.debugSphere(debugCenter, 0.1, .{ .color = .{ .x = 1.0 } }); } var show: bool = true;