corrected camera transforms

This commit is contained in:
Peter Li 2025-04-23 07:34:43 -07:00
parent 4d6a175e25
commit 6d1c2a4bd8
7 changed files with 97 additions and 23 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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