moved fp camera code to extras, then added a directional light to the renderer

This commit is contained in:
Peter Li 2025-04-26 19:32:55 -07:00
parent 19e4bf629a
commit ccab1182e1
20 changed files with 268 additions and 134 deletions

View File

@ -99,7 +99,7 @@ pub const AddProgramOptions = struct {
imports: []const Build.Module.Import = &.{}, imports: []const Build.Module.Import = &.{},
}; };
pub fn addProgram(self: *BuildSystem, opts: AddProgramOptions) *std.Build.Step.Compile { pub fn addProgram(self: *BuildSystem, opts: AddProgramOptions) *std.Build.Module {
const b = self.b; const b = self.b;
const exe = self.nw_builder.addExecutable(.{ const exe = self.nw_builder.addExecutable(.{
@ -199,7 +199,7 @@ pub fn addProgram(self: *BuildSystem, opts: AddProgramOptions) *std.Build.Step.C
b.getInstallStep().dependOn(self.nw_builder.getInstallStep()); b.getInstallStep().dependOn(self.nw_builder.getInstallStep());
return exe; return mod;
} }
pub fn createGameOptions(b: *std.Build) *std.Build.Step.Options { pub fn createGameOptions(b: *std.Build) *std.Build.Step.Options {
@ -235,6 +235,11 @@ pub fn createGameOptions(b: *std.Build) *std.Build.Step.Options {
return opts; return opts;
} }
pub fn addExtraModule(self: *BuildSystem, mod: *std.Build.Module, moduleName: []const u8) void {
const dep = self.b.dependency(moduleName, .{ .target = self.target, .optimize = self.optimize });
mod.addImport(moduleName, dep.module(moduleName));
}
// ========= standalone build instance ======= // ========= standalone build instance =======
// maybe it should be an engine launcher or something.. // maybe it should be an engine launcher or something..
pub fn build(b: *std.Build) void { pub fn build(b: *std.Build) void {

View File

@ -353,18 +353,6 @@ pub const Entity = struct {
} }
}; };
pub const EcsComponentInterface = p2.MakeInterface("EcsComponentInterfaceVTable", struct {
container: ?EcsContainerRef = null,
pub fn Implement(comptime T: type) @This() {
_ = T;
const Impl = struct {};
_ = Impl;
return .{};
}
});
pub const EcsContainerInterface = p2.EcsContainerInterface; pub const EcsContainerInterface = p2.EcsContainerInterface;
pub const EcsContainerRef = p2.Reference(EcsContainerInterface); pub const EcsContainerRef = p2.Reference(EcsContainerInterface);
pub fn makeEcsContainerRef(ptr: anytype) EcsContainerRef { pub fn makeEcsContainerRef(ptr: anytype) EcsContainerRef {

View File

@ -575,8 +575,16 @@ pub const Rotation = struct {
}; };
} }
pub fn forward(self: *@This()) Vectorf { pub fn up(self: @This()) Vectorf {
return self.rotateVector(.{ .z = 1 }); return self.rotateVector(Vectorf.Up);
}
pub fn forward(self: @This()) Vectorf {
return self.rotateVector(Vectorf.Forward);
}
pub fn right(self: @This()) Vectorf {
return self.rotateVector(Vectorf.Right);
} }
pub fn rotateVector(self: @This(), other: Vectorf) Vectorf { pub fn rotateVector(self: @This(), other: Vectorf) Vectorf {

View File

@ -3,6 +3,7 @@ pub const Impl = struct {
device: *gpu.GPUDevice = undefined, device: *gpu.GPUDevice = undefined,
drawData: [*c]ig.DrawData = undefined, drawData: [*c]ig.DrawData = undefined,
rendererDebug: bool = true,
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
@ -70,9 +71,14 @@ pub const Impl = struct {
} }
} }
pub fn preTick(_: *@This(), _: f64) core.EngineDataEventError!void { pub fn preTick(self: *@This(), _: f64) core.EngineDataEventError!void {
c.Imgui_SDL3_NewFrame(); c.Imgui_SDL3_NewFrame();
c.igNewFrame(); c.igNewFrame();
if (ig.begin("renderer debug", &self.rendererDebug, .{})) {
_ = ig.sliderFloat("directional light yaw", &rend.context().directionalLightYaw, 0, 360, null, .{});
ig.end();
}
} }
// renderer plugin // renderer plugin

View File

@ -5,6 +5,8 @@ cbuffer Uniforms : register(b0, space3)
{ {
float4 viewPos; float4 viewPos;
float4 lightPosition; float4 lightPosition;
float4 directionalLight;
float4 directionalLightColor;
float time; float time;
}; };
@ -66,6 +68,23 @@ float3 BlinnPhong(float3 normal, float3 fragPos, float3 lightPos, float3 lightCo
} }
float3 DirectionalLight(float3 normal, float3 fragPos)
{
float3 lightDir = directionalLight.xyz;
float diff = max(dot(lightDir, normal), 0.0);
float3 diffuse = diff * directionalLightColor.xyz;
// specular parameter
float3 viewDir = normalize(fragPos - viewPos.xyz);
float3 reflectDir = reflect(-lightDir, normal);
float spec = 0.0;
float3 halfwayDir = normalize(lightDir + viewDir);
spec = pow(max(dot(normal, halfwayDir), 0.0), 30.0);
float3 specular = spec * directionalLightColor.xyz * 2;
return diffuse;
}
float4 main( float4 main(
float2 UV : TEXCOORD0, float2 UV : TEXCOORD0,
float3 WorldPos: TEXCOORD1, float3 WorldPos: TEXCOORD1,
@ -83,11 +102,11 @@ float4 main(
float3 lightPos = lightPosition.xyz; //+ float3(0, 20, 0); float3 lightPos = lightPosition.xyz; //+ float3(0, 20, 0);
float3 lightColor = float3(0.8, 0.8, 0.5); float3 lightColor = float3(0.8, 0.8, 0.5);
float3 ambient = lerp(float3(0.01, 0.01, 0.003), float3(0.004, 0.004, 0.06), dot(Normal, float3(0.0,1.0,0.0)) ) * 0.001; float3 ambient = lerp(float3(0.01, 0.01, 0.003), float3(0.004, 0.004, 0.06), dot(Normal, float3(0.0,1.0,0.0)) ) * 5;
float3 col = s.xyz; float3 col = s.xyz;
float3 c2 = col * ambient + col * BlinnPhong(Normal, WorldPos, lightPos, lightColor); float3 c2 = col * ambient + col * BlinnPhong(Normal, WorldPos, lightPos, lightColor) + col * DirectionalLight(Normal, WorldPos);
float4 rv = float4(pow(c2, 1.0 / 2.2), alpha); float4 rv = float4(pow(c2, 1.0 / 2.2), alpha);

View File

@ -19,10 +19,20 @@
"type" : "vec4", "type" : "vec4",
"offset" : 16 "offset" : 16
}, },
{
"name" : "directionalLight",
"type" : "vec4",
"offset" : 32
},
{
"name" : "directionalLightColor",
"type" : "vec4",
"offset" : 48
},
{ {
"name" : "time", "name" : "time",
"type" : "float", "type" : "float",
"offset" : 32 "offset" : 64
} }
] ]
} }
@ -71,7 +81,7 @@
{ {
"type" : "_11", "type" : "_11",
"name" : "type.Uniforms", "name" : "type.Uniforms",
"block_size" : 36, "block_size" : 68,
"set" : 3, "set" : 3,
"binding" : 0 "binding" : 0
} }

View File

@ -47,6 +47,10 @@ pub const Renderer = struct {
debugDrawSys: *DebugDrawSystem = undefined, debugDrawSys: *DebugDrawSystem = undefined,
directionalLightYaw: f32 = 0.0,
directionalLightColor: core.colors.Color = .{ .r = 0.8, .g = 0.8, .b = 0.9 },
directionalLightDir: core.Vectorf = core.Vectorf.new(0.5, 0.25, -1).normalize(),
// transients DO NOT TOUCH // transients DO NOT TOUCH
swapchainTexture: ?*gpu.GPUTexture = undefined, swapchainTexture: ?*gpu.GPUTexture = undefined,
@ -83,6 +87,7 @@ pub const Renderer = struct {
try self.discoverFormats(); try self.discoverFormats();
core.engine_log("sgpu device created, using shader format: {s}", .{self.shaderSuffix}); core.engine_log("sgpu device created, using shader format: {s}", .{self.shaderSuffix});
core.engine_log("using renderer... scientist", .{});
try self.createMeshPipeline(); try self.createMeshPipeline();
try self.createBuffers(); try self.createBuffers();
@ -366,9 +371,12 @@ pub const Renderer = struct {
if (self.activeCamera) |cam| { if (self.activeCamera) |cam| {
position = cam.finalPos; position = cam.finalPos;
} }
const resolved = core.Rotation.eulerY(core.radians(self.directionalLightYaw)).rotateVector(self.directionalLightDir);
ptr.viewPos = @bitCast(position.toZm()); ptr.viewPos = @bitCast(position.toZm());
ptr.lightPosition = @bitCast(self.lightPosition.toZm()); ptr.lightPosition = @bitCast(self.lightPosition.toZm());
ptr.directionalLight = @bitCast(resolved.toZm());
ptr.directionalLightColor = @bitCast(self.directionalLightColor);
cmd.pushGPUFragmentUniformData(0, &data, @sizeOf(lit_mesh_frag.Uniforms)); cmd.pushGPUFragmentUniformData(0, &data, @sizeOf(lit_mesh_frag.Uniforms));
} }
} }

View File

@ -0,0 +1,16 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const mod = b.addModule("gameExtras", .{
.target = target,
.optimize = optimize,
.root_source_file = b.path("src/gameExtras.zig"),
});
const dep = b.dependency("Backlog", .{ .target = target, .optimize = optimize });
mod.addImport("Backlog", dep.module("Backlog"));
}

View File

@ -0,0 +1,11 @@
.{
.name = .gameExtras,
.version = "0.0.0",
.dependencies = .{
.Backlog = .{ .path = "../../" },
},
.paths = .{
"",
},
.fingerprint = 0x993cf5f438b86d4a,
}

View File

@ -0,0 +1,5 @@
# extras
These are sample implementations of various common functionality that's meant to be in your game not really part of the engine.
To get access to these extras

View File

@ -0,0 +1,98 @@
// generic first person camera,
//
//
allocator: std.mem.Allocator,
camera: core.Entity = undefined,
cameraComponent: *rend.CameraComponent = undefined,
// mouse sensitivty, measured in degrees per pixel
sensitivity: f32 = 5.0,
yaw: f32 = 0.0,
pitch: f32 = 0.0,
mouseMovement: core.Vector2f = .{},
mouseLookEnabled: bool = true,
pub fn create(allocator: std.mem.Allocator) !*@This() {
const self = try allocator.create(@This());
self.* = .{
.allocator = allocator,
};
self.camera = try core.createEntity();
_ = self.camera.addComponent(core.Scene).?;
self.cameraComponent = self.camera.addComponent(rend.CameraComponent).?;
core.engine_logs("[GameExtras] FpCamera created");
return self;
}
pub fn activateCamera(self: *@This()) void {
rend.setActiveCamera(self.cameraComponent);
}
pub fn resolve(self: *@This()) void {
self.cameraComponent.resolve();
}
pub fn getForward(self: *@This()) core.Vectorf {
return self.cameraComponent.forward();
}
pub fn getForwardXZ(self: *@This()) core.Vectorf {
const rotation = core.Rotation.eulerY(core.radians(self.yaw));
return rotation.rotateVector(core.Vectorf.Forward);
}
pub fn getRightXZ(self: *@This()) core.Vectorf {
const rotation = core.Rotation.eulerY(core.radians(self.yaw));
return rotation.rotateVector(core.Vectorf.Right);
}
pub fn setPosition(self: *@This(), position: core.Vectorf) void {
if (self.camera.fetch(core.Scene)) |scene| {
scene.setPosition(position);
}
}
pub fn getPosition(self: *@This()) core.Vectorf {
return self.camera.fetch(core.Scene).?.getPosition();
}
// movement value can be sourced from a mouse binding that has enableMouseRelative() on
pub fn addMouseMovement(self: *@This(), movement: core.Vector2f) void {
if (self.mouseLookEnabled) {
self.mouseMovement = self.mouseMovement.add(movement);
}
}
pub fn tick(self: *@This(), dt: f64) void {
_ = dt;
const mouseMovement = self.mouseMovement;
self.mouseMovement = .{};
self.yaw += core.radians(mouseMovement.x * self.sensitivity);
self.pitch -= core.radians(mouseMovement.y * self.sensitivity);
if (self.camera.fetch(core.Scene)) |scene| {
const posRot = scene.getPosRot();
self.pitch = std.math.clamp(self.pitch, -90.0, 90.0);
self.cameraComponent.pitch = core.radians(self.pitch);
posRot.rotation = core.Rotation.eulerY(core.radians(self.yaw));
}
}
pub fn destroy(self: *@This()) void {
core.engine_logs("[GameExtras] FpCamera destroyed");
self.allocator.destroy(self);
}
const std = @import("std");
const backlog = @import("Backlog");
const core = backlog.core;
const rend = backlog.rend;

View File

@ -0,0 +1 @@
pub const FpCamera = @import("FpCamera.zig");

0
extras/readme.md Normal file
View File

View File

@ -11,9 +11,11 @@ pub fn build(b: *std.Build) void {
.backlogRoot = "../", .backlogRoot = "../",
}); });
_ = blbuild.addProgram(.{ const sampleGame = blbuild.addProgram(.{
.name = "sampleGame", .name = "sampleGame",
.desc = "sdl3 project sample", .desc = "sdl3 project sample",
.root_source_file = b.path("sampleGame/main.zig"), .root_source_file = b.path("sampleGame/main.zig"),
}); });
blbuild.addExtraModule(sampleGame, "gameExtras");
} }

View File

@ -14,6 +14,7 @@
// engine libraries // engine libraries
.Backlog = .{ .path = "../" }, .Backlog = .{ .path = "../" },
.SpirvReflect = .{ .path = "../lib/spirv-reflect-zig" }, .SpirvReflect = .{ .path = "../lib/spirv-reflect-zig" },
.gameExtras = .{.path = "../extras/gameExtras"}
}, },
.paths = .{ .paths = .{
"", "",

View File

@ -7,6 +7,8 @@ struct type_Uniforms
{ {
float4 viewPos; float4 viewPos;
float4 lightPosition; float4 lightPosition;
float4 directionalLight;
float4 directionalLightColor;
float time; float time;
}; };
@ -25,48 +27,48 @@ struct main0_in
fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], texture2d<float> Texture [[texture(0)]], sampler Sampler [[sampler(0)]]) fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], texture2d<float> Texture [[texture(0)]], sampler Sampler [[sampler(0)]])
{ {
main0_out out = {}; main0_out out = {};
float4 _59 = Texture.sample(Sampler, in.in_var_TEXCOORD0); float4 _61 = Texture.sample(Sampler, in.in_var_TEXCOORD0);
float _60 = _59.w; float _62 = _61.w;
if (_60 < 0.00999999977648258209228515625) if (_62 < 0.00999999977648258209228515625)
{ {
discard_fragment(); discard_fragment();
} }
float3 _117; float3 _119;
do do
{ {
float3 _74 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1; float3 _76 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1;
float _75 = length(_74); float _77 = length(_76);
float _76 = _75 * _75; float _78 = _77 * _77;
float _82; float _84;
if (_75 > 2.0) if (_77 > 2.0)
{ {
_82 = 0.5 / _76; _84 = 0.5 / _78;
} }
else else
{ {
_82 = 1.0 / _76; _84 = 1.0 / _78;
} }
float _87; float _89;
if (_75 > 4.0) if (_77 > 4.0)
{ {
_87 = _82 * 0.5; _89 = _84 * 0.5;
} }
else else
{ {
_87 = _82; _89 = _84;
} }
float _89 = (_75 > 15.0) ? 0.0 : _87; float _91 = (_77 > 15.0) ? 0.0 : _89;
float _91 = (_89 > 1.0) ? 1.0 : _89; float _93 = (_91 > 1.0) ? 1.0 : _91;
if (length(in.in_var_TEXCOORD2) < 0.100000001490116119384765625) if (length(in.in_var_TEXCOORD2) < 0.100000001490116119384765625)
{ {
_117 = (in.in_var_TEXCOORD1 * float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5)) * _91; _119 = (in.in_var_TEXCOORD1 * float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5)) * _93;
break; break;
} }
float3 _98 = fast::normalize(_74); float3 _100 = fast::normalize(_76);
_117 = ((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_98, in.in_var_TEXCOORD2), 0.0)) * _91) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_98 + fast::normalize(in.in_var_TEXCOORD1 - Uniforms.viewPos.xyz))), 0.0), 30.0)) * 2.0) * _91); _119 = ((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_100, in.in_var_TEXCOORD2), 0.0)) * _93) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_100 + fast::normalize(in.in_var_TEXCOORD1 - Uniforms.viewPos.xyz))), 0.0), 30.0)) * 2.0) * _93);
break; break;
} while(false); } while(false);
out.out_var_SV_Target0 = float4(powr(_59.xyz * ((mix(float3(0.00999999977648258209228515625, 0.00999999977648258209228515625, 0.0030000000260770320892333984375), float3(0.0040000001899898052215576171875, 0.0040000001899898052215576171875, 0.0599999986588954925537109375), float3(in.in_var_TEXCOORD2.y)) * 0.001000000047497451305389404296875) + _117), float3(0.4545454680919647216796875)), _60); out.out_var_SV_Target0 = float4(powr(_61.xyz * (((mix(float3(0.00999999977648258209228515625, 0.00999999977648258209228515625, 0.0030000000260770320892333984375), float3(0.0040000001899898052215576171875, 0.0040000001899898052215576171875, 0.0599999986588954925537109375), float3(in.in_var_TEXCOORD2.y)) * 5.0) + _119) + (Uniforms.directionalLightColor.xyz * precise::max(dot(Uniforms.directionalLight.xyz, in.in_var_TEXCOORD2), 0.0))), float3(0.4545454680919647216796875)), _62);
return out; return out;
} }

View File

@ -1,32 +0,0 @@
pub const shaderTypes = @import("shaderTypes");
pub const int = shaderTypes.int;
pub const uint = shaderTypes.uint;
pub const vec2 = shaderTypes.vec2;
pub const u8vec4 = shaderTypes.u8vec4;
pub const vec3 = shaderTypes.vec3;
pub const vec4 = shaderTypes.vec4;
pub const mat4 = shaderTypes.mat4;
pub const float = shaderTypes.float;
pub const BufferInfo = shaderTypes.BufferInfo;
pub const Scene = struct {
Model: mat4,
pub const Buffer: BufferInfo = .{ .storage = 0 };
};
pub const Uniforms = struct {
ViewProjection: mat4,
time: float,
pub const Buffer: BufferInfo = .{ .uniform = 0 };
};
pub const LoadArgs = shaderTypes.ShaderLoadArgs{
.num_samplers = 0, // The number of samplers defined in the shader.
.num_storage_textures = 0, // The number of storage textures defined in the shader.
.num_storage_buffers = 1, // The number of storage buffers defined in the shader.
.num_uniform_buffers = 1, // The number of uniform buffers defined in the shader.
};

View File

@ -1,26 +1,19 @@
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
camera: core.Entity = undefined,
cameraComponent: *rend.CameraComponent = undefined,
cameraSpeed: f32 = 10.0,
moveInput: *core.Axis2dBinding = undefined, moveInput: *core.Axis2dBinding = undefined,
cameraSpeed: f32 = 10.0,
moveVector: core.Vectorf = .{}, moveVector: core.Vectorf = .{},
mouseMove: core.Vector2f = .{}, mouseMove: core.Vector2f = .{},
rotateAxis: f32 = 0.0,
rotateAxisPitch: f32 = 0.0,
sensitivity: f32 = 5.0,
verticalMove: f32 = 0.0, verticalMove: f32 = 0.0,
centerDist: f32 = 2.0, centerDist: f32 = 2.0,
centerDistMove: f32 = 2.0, centerDistMove: f32 = 2.0,
yaw: f32 = 0.0,
pitch: f32 = 0.0,
mouseLook: bool = true, mouseLook: bool = true,
showWindow: bool = true,
fpcamera: *FpCamera = undefined,
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
@ -83,10 +76,9 @@ pub fn prepare(self: *@This()) !void {
inp.activate(); inp.activate();
} }
self.camera = try core.createEntity(); self.fpcamera = try FpCamera.create(self.allocator);
const cameraScene = self.camera.addComponent(core.Scene).?; self.fpcamera.setPosition(.{ .z = -15, .y = 20 });
cameraScene.setPosition(.{ .z = -15 }); self.fpcamera.activateCamera();
self.cameraComponent = self.camera.addComponent(rend.CameraComponent).?;
{ {
const lostEmpire = try core.createEntity(); const lostEmpire = try core.createEntity();
@ -98,13 +90,13 @@ pub fn prepare(self: *@This()) !void {
} }
{ {
const fox = try core.createEntity(); // const fox = try core.createEntity();
const scene = fox.addComponent(core.Scene).?; // const scene = fox.addComponent(core.Scene).?;
_ = scene; // _ = scene;
// scene.setScale(); // // scene.setScale();
const mesh = fox.addComponent(rend.MeshComponent).?; // const mesh = fox.addComponent(rend.MeshComponent).?;
mesh.setMesh("m_fox"); // mesh.setMesh("m_fox");
mesh.setTexture("t_fox"); // mesh.setTexture("t_fox");
} }
{ {
@ -117,17 +109,15 @@ pub fn prepare(self: *@This()) !void {
mesh.setTexture("t_default"); mesh.setTexture("t_default");
} }
rend.setActiveCamera(self.cameraComponent); const moveInput = try core.Axis2dBinding.create(core.MakeName("movement"));
self.moveInput = try core.Axis2dBinding.create(core.MakeName("movement")); moveInput.addKey(.w, 1.0, .y);
moveInput.addKey(.s, -1.0, .y);
moveInput.addKey(.d, 1.0, .x);
moveInput.addKey(.a, -1.0, .x);
self.moveInput.addKey(.w, 1.0, .y); _ = moveInput.data.addListener(self, onMove);
self.moveInput.addKey(.s, -1.0, .y); moveInput.activate();
self.moveInput.addKey(.d, 1.0, .x);
self.moveInput.addKey(.a, -1.0, .x);
_ = self.moveInput.data.addListener(self, onMove);
self.moveInput.activate();
{ {
const i = try core.Axis1dBinding.create(core.MakeName("rotPitch")); const i = try core.Axis1dBinding.create(core.MakeName("rotPitch"));
@ -173,8 +163,7 @@ pub fn prepare(self: *@This()) !void {
fn onMouseLook(ctx: ?*anyopaque, axis: core.Vector2f) void { fn onMouseLook(ctx: ?*anyopaque, axis: core.Vector2f) void {
const self: *@This() = @ptrCast(@alignCast(ctx)); const self: *@This() = @ptrCast(@alignCast(ctx));
if (self.mouseLook) self.fpcamera.addMouseMovement(axis);
self.mouseMove = axis;
} }
fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void { fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void {
@ -182,13 +171,16 @@ fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void {
_ = action; _ = action;
self.mouseLook = !self.mouseLook; self.mouseLook = !self.mouseLook;
if (!self.mouseLook)
self.showWindow = true;
self.updateMouseLook(); self.updateMouseLook();
} }
fn updateMouseLook(self: *@This()) void { fn updateMouseLook(self: *@This()) void {
self.fpcamera.mouseLookEnabled = self.mouseLook;
platform.setMouseRelativeMode(self.mouseLook); platform.setMouseRelativeMode(self.mouseLook);
platform.setImguiVisible(!self.mouseLook); // platform.setImguiVisible(!self.mouseLook);
} }
fn onShaderReload(ctx: ?*anyopaque, action: core.ActionEvent) void { fn onShaderReload(ctx: ?*anyopaque, action: core.ActionEvent) void {
@ -247,42 +239,35 @@ pub fn getMouseMovement(self: *@This()) core.Vector2f {
pub fn tick(self: *@This(), dt: f64) void { pub fn tick(self: *@This(), dt: f64) void {
const fdt: f32 = @floatCast(dt); const fdt: f32 = @floatCast(dt);
if (self.camera.fetch(core.Scene)) |scene| { self.fpcamera.tick(dt);
const vector = core.Vectorf{ .x = self.moveVector.x, .z = self.moveVector.z, .y = self.verticalMove };
const posRot = scene.getPosRot();
self.yaw += self.rotateAxis * fdt * 20; var movement = self.fpcamera.getForwardXZ().fmul(self.moveVector.z * fdt * self.cameraSpeed);
self.pitch += self.rotateAxisPitch * fdt * 20; movement = movement.add(self.fpcamera.getRightXZ().fmul(self.moveVector.x * fdt * self.cameraSpeed));
movement = movement.add(.{ .y = self.verticalMove * fdt * self.cameraSpeed });
const pos = self.fpcamera.getPosition().add(movement);
self.fpcamera.setPosition(pos);
self.centerDist += self.centerDistMove * fdt;
const mouseMovement = self.getMouseMovement(); self.fpcamera.resolve();
self.yaw += core.radians(mouseMovement.x * self.sensitivity); const forward = self.fpcamera.getForward();
self.pitch -= core.radians(mouseMovement.y * self.sensitivity); const debugCenter = self.fpcamera.getPosition().add(forward.fmul(self.centerDist));
self.pitch = std.math.clamp(self.pitch, -90.0, 90.0); core.debugSphere(debugCenter, 0.3, .{});
self.cameraComponent.pitch = core.radians(self.pitch); core.debugSphere(debugCenter, 0.1, .{ .color = .{ .x = 1.0 } });
posRot.rotation = core.Rotation.eulerY(core.radians(self.yaw));
const movement = posRot.rotation.rotateVector(vector.fmul(self.cameraSpeed * fdt));
posRot.position = posRot.position.add(movement); rend.context().lightPosition = debugCenter;
self.cameraComponent.resolve(); // show a window with the current camera's position
self.centerDist += self.centerDistMove * fdt;
const forward = self.cameraComponent.forward(); //posRot.rotation.forward();
const debugCenter = posRot.position.add(forward.fmul(self.centerDist));
core.debugSphere(debugCenter, 0.3, .{}); if (ig.begin("meh", &self.showWindow, .{})) {
core.debugSphere(debugCenter, 0.1, .{ .color = .{ .x = 1.0 } }); ig.textFmt("x:{d:.03} y:{d:.03} z:{d:.03}", .{ pos.x, pos.y, pos.z }) catch return;
ig.end();
rend.context().lightPosition = debugCenter;
} }
var show: bool = true;
ig.showDemoWindow(&show);
} }
pub fn deinit(self: *@This()) void { pub fn deinit(self: *@This()) void {
self.fpcamera.destroy();
self.allocator.destroy(self); self.allocator.destroy(self);
} }
@ -296,6 +281,7 @@ pub fn main() anyerror!void {
}); });
} }
const FpCamera = @import("gameExtras").FpCamera;
const std = @import("std"); const std = @import("std");
const backlog = @import("Backlog"); const backlog = @import("Backlog");
const assets = backlog.assets; const assets = backlog.assets;