diff --git a/build.zig b/build.zig index a26010e..1f180ad 100644 --- a/build.zig +++ b/build.zig @@ -99,7 +99,7 @@ pub const AddProgramOptions = struct { 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 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()); - return exe; + return mod; } 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; } +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 ======= // maybe it should be an engine launcher or something.. pub fn build(b: *std.Build) void { diff --git a/engine/core/src/ecs.zig b/engine/core/src/ecs.zig index 8b93988..a480ec5 100644 --- a/engine/core/src/ecs.zig +++ b/engine/core/src/ecs.zig @@ -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 EcsContainerRef = p2.Reference(EcsContainerInterface); pub fn makeEcsContainerRef(ptr: anytype) EcsContainerRef { diff --git a/engine/core/src/math.zig b/engine/core/src/math.zig index 2227a5d..1ec005c 100644 --- a/engine/core/src/math.zig +++ b/engine/core/src/math.zig @@ -575,8 +575,16 @@ pub const Rotation = struct { }; } - pub fn forward(self: *@This()) Vectorf { - return self.rotateVector(.{ .z = 1 }); + pub fn up(self: @This()) Vectorf { + 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 { diff --git a/engine/imgui/src/sgpu/backend_impl.zig b/engine/imgui/src/sgpu/backend_impl.zig index 7ccdab0..813069b 100644 --- a/engine/imgui/src/sgpu/backend_impl.zig +++ b/engine/imgui/src/sgpu/backend_impl.zig @@ -3,6 +3,7 @@ pub const Impl = struct { device: *gpu.GPUDevice = undefined, drawData: [*c]ig.DrawData = undefined, + rendererDebug: bool = true, 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.igNewFrame(); + + if (ig.begin("renderer debug", &self.rendererDebug, .{})) { + _ = ig.sliderFloat("directional light yaw", &rend.context().directionalLightYaw, 0, 360, null, .{}); + ig.end(); + } } // renderer plugin diff --git a/engine/rend/shaders/lit_mesh.frag.hlsl b/engine/rend/shaders/lit_mesh.frag.hlsl index 86c2ba7..3556204 100644 --- a/engine/rend/shaders/lit_mesh.frag.hlsl +++ b/engine/rend/shaders/lit_mesh.frag.hlsl @@ -5,6 +5,8 @@ cbuffer Uniforms : register(b0, space3) { float4 viewPos; float4 lightPosition; + float4 directionalLight; + float4 directionalLightColor; 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( float2 UV : TEXCOORD0, float3 WorldPos: TEXCOORD1, @@ -83,11 +102,11 @@ float4 main( float3 lightPos = lightPosition.xyz; //+ float3(0, 20, 0); 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 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); diff --git a/engine/rend/shaders/lit_mesh.frag.json b/engine/rend/shaders/lit_mesh.frag.json index bb4572c..f40582d 100644 --- a/engine/rend/shaders/lit_mesh.frag.json +++ b/engine/rend/shaders/lit_mesh.frag.json @@ -19,10 +19,20 @@ "type" : "vec4", "offset" : 16 }, + { + "name" : "directionalLight", + "type" : "vec4", + "offset" : 32 + }, + { + "name" : "directionalLightColor", + "type" : "vec4", + "offset" : 48 + }, { "name" : "time", "type" : "float", - "offset" : 32 + "offset" : 64 } ] } @@ -71,7 +81,7 @@ { "type" : "_11", "name" : "type.Uniforms", - "block_size" : 36, + "block_size" : 68, "set" : 3, "binding" : 0 } diff --git a/engine/rend/src/sgpu/renderer.zig b/engine/rend/src/sgpu/renderer.zig index 55512a9..6ba28e5 100644 --- a/engine/rend/src/sgpu/renderer.zig +++ b/engine/rend/src/sgpu/renderer.zig @@ -47,6 +47,10 @@ pub const Renderer = struct { 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 swapchainTexture: ?*gpu.GPUTexture = undefined, @@ -83,6 +87,7 @@ pub const Renderer = struct { try self.discoverFormats(); core.engine_log("sgpu device created, using shader format: {s}", .{self.shaderSuffix}); + core.engine_log("using renderer... scientist", .{}); try self.createMeshPipeline(); try self.createBuffers(); @@ -366,9 +371,12 @@ pub const Renderer = struct { if (self.activeCamera) |cam| { position = cam.finalPos; } + const resolved = core.Rotation.eulerY(core.radians(self.directionalLightYaw)).rotateVector(self.directionalLightDir); ptr.viewPos = @bitCast(position.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)); } } diff --git a/extras/gameExtras/build.zig b/extras/gameExtras/build.zig new file mode 100644 index 0000000..6bd324c --- /dev/null +++ b/extras/gameExtras/build.zig @@ -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")); +} diff --git a/extras/gameExtras/build.zig.zon b/extras/gameExtras/build.zig.zon new file mode 100644 index 0000000..5c4d98b --- /dev/null +++ b/extras/gameExtras/build.zig.zon @@ -0,0 +1,11 @@ +.{ + .name = .gameExtras, + .version = "0.0.0", + .dependencies = .{ + .Backlog = .{ .path = "../../" }, + }, + .paths = .{ + "", + }, + .fingerprint = 0x993cf5f438b86d4a, +} diff --git a/extras/gameExtras/readme.md b/extras/gameExtras/readme.md new file mode 100644 index 0000000..cd82755 --- /dev/null +++ b/extras/gameExtras/readme.md @@ -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 diff --git a/extras/gameExtras/src/FpCamera.zig b/extras/gameExtras/src/FpCamera.zig new file mode 100644 index 0000000..a5f5e89 --- /dev/null +++ b/extras/gameExtras/src/FpCamera.zig @@ -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; diff --git a/extras/gameExtras/src/gameExtras.zig b/extras/gameExtras/src/gameExtras.zig new file mode 100644 index 0000000..187bcd0 --- /dev/null +++ b/extras/gameExtras/src/gameExtras.zig @@ -0,0 +1 @@ +pub const FpCamera = @import("FpCamera.zig"); diff --git a/extras/readme.md b/extras/readme.md new file mode 100644 index 0000000..e69de29 diff --git a/projects/build.zig b/projects/build.zig index 71c10c4..324e41d 100644 --- a/projects/build.zig +++ b/projects/build.zig @@ -11,9 +11,11 @@ pub fn build(b: *std.Build) void { .backlogRoot = "../", }); - _ = blbuild.addProgram(.{ + const sampleGame = blbuild.addProgram(.{ .name = "sampleGame", .desc = "sdl3 project sample", .root_source_file = b.path("sampleGame/main.zig"), }); + + blbuild.addExtraModule(sampleGame, "gameExtras"); } diff --git a/projects/build.zig.zon b/projects/build.zig.zon index 3221a3e..ad21e89 100644 --- a/projects/build.zig.zon +++ b/projects/build.zig.zon @@ -14,6 +14,7 @@ // engine libraries .Backlog = .{ .path = "../" }, .SpirvReflect = .{ .path = "../lib/spirv-reflect-zig" }, + .gameExtras = .{.path = "../extras/gameExtras"} }, .paths = .{ "", diff --git a/projects/content/_shaders/dxil/lit_mesh.frag.dxil b/projects/content/_shaders/dxil/lit_mesh.frag.dxil index 8116920..87c9092 100644 Binary files a/projects/content/_shaders/dxil/lit_mesh.frag.dxil and b/projects/content/_shaders/dxil/lit_mesh.frag.dxil differ diff --git a/projects/content/_shaders/msl/lit_mesh.frag.msl b/projects/content/_shaders/msl/lit_mesh.frag.msl index 2b18586..3f54b53 100644 --- a/projects/content/_shaders/msl/lit_mesh.frag.msl +++ b/projects/content/_shaders/msl/lit_mesh.frag.msl @@ -7,6 +7,8 @@ struct type_Uniforms { float4 viewPos; float4 lightPosition; + float4 directionalLight; + float4 directionalLightColor; 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 Texture [[texture(0)]], sampler Sampler [[sampler(0)]]) { main0_out out = {}; - float4 _59 = Texture.sample(Sampler, in.in_var_TEXCOORD0); - float _60 = _59.w; - if (_60 < 0.00999999977648258209228515625) + float4 _61 = Texture.sample(Sampler, in.in_var_TEXCOORD0); + float _62 = _61.w; + if (_62 < 0.00999999977648258209228515625) { discard_fragment(); } - float3 _117; + float3 _119; do { - float3 _74 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1; - float _75 = length(_74); - float _76 = _75 * _75; - float _82; - if (_75 > 2.0) + float3 _76 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1; + float _77 = length(_76); + float _78 = _77 * _77; + float _84; + if (_77 > 2.0) { - _82 = 0.5 / _76; + _84 = 0.5 / _78; } else { - _82 = 1.0 / _76; + _84 = 1.0 / _78; } - float _87; - if (_75 > 4.0) + float _89; + if (_77 > 4.0) { - _87 = _82 * 0.5; + _89 = _84 * 0.5; } else { - _87 = _82; + _89 = _84; } - float _89 = (_75 > 15.0) ? 0.0 : _87; - float _91 = (_89 > 1.0) ? 1.0 : _89; + float _91 = (_77 > 15.0) ? 0.0 : _89; + float _93 = (_91 > 1.0) ? 1.0 : _91; 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; } - float3 _98 = fast::normalize(_74); - _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); + float3 _100 = fast::normalize(_76); + _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; } 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; } diff --git a/projects/content/_shaders/spv/lit_mesh.frag.spv b/projects/content/_shaders/spv/lit_mesh.frag.spv index 1ce9b94..a5e8b1c 100644 Binary files a/projects/content/_shaders/spv/lit_mesh.frag.spv and b/projects/content/_shaders/spv/lit_mesh.frag.spv differ diff --git a/projects/reflected.zig b/projects/reflected.zig deleted file mode 100644 index bd4cc27..0000000 --- a/projects/reflected.zig +++ /dev/null @@ -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. -}; diff --git a/projects/sampleGame/main.zig b/projects/sampleGame/main.zig index faefb60..1699277 100644 --- a/projects/sampleGame/main.zig +++ b/projects/sampleGame/main.zig @@ -1,26 +1,19 @@ allocator: std.mem.Allocator, -camera: core.Entity = undefined, -cameraComponent: *rend.CameraComponent = undefined, -cameraSpeed: f32 = 10.0, - moveInput: *core.Axis2dBinding = undefined, +cameraSpeed: f32 = 10.0, moveVector: core.Vectorf = .{}, mouseMove: core.Vector2f = .{}, - -rotateAxis: f32 = 0.0, -rotateAxisPitch: f32 = 0.0, - -sensitivity: f32 = 5.0, verticalMove: f32 = 0.0, centerDist: f32 = 2.0, centerDistMove: f32 = 2.0, -yaw: f32 = 0.0, -pitch: f32 = 0.0, mouseLook: bool = true, +showWindow: bool = true, + +fpcamera: *FpCamera = undefined, pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); @@ -83,10 +76,9 @@ pub fn prepare(self: *@This()) !void { inp.activate(); } - self.camera = try core.createEntity(); - const cameraScene = self.camera.addComponent(core.Scene).?; - cameraScene.setPosition(.{ .z = -15 }); - self.cameraComponent = self.camera.addComponent(rend.CameraComponent).?; + self.fpcamera = try FpCamera.create(self.allocator); + self.fpcamera.setPosition(.{ .z = -15, .y = 20 }); + self.fpcamera.activateCamera(); { const lostEmpire = try core.createEntity(); @@ -98,13 +90,13 @@ pub fn prepare(self: *@This()) !void { } { - const fox = try core.createEntity(); - const scene = fox.addComponent(core.Scene).?; - _ = scene; - // scene.setScale(); - const mesh = fox.addComponent(rend.MeshComponent).?; - mesh.setMesh("m_fox"); - mesh.setTexture("t_fox"); + // const fox = try core.createEntity(); + // const scene = fox.addComponent(core.Scene).?; + // _ = scene; + // // scene.setScale(); + // const mesh = fox.addComponent(rend.MeshComponent).?; + // mesh.setMesh("m_fox"); + // mesh.setTexture("t_fox"); } { @@ -117,17 +109,15 @@ pub fn prepare(self: *@This()) !void { 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); - self.moveInput.addKey(.s, -1.0, .y); - self.moveInput.addKey(.d, 1.0, .x); - self.moveInput.addKey(.a, -1.0, .x); - - _ = self.moveInput.data.addListener(self, onMove); - self.moveInput.activate(); + _ = moveInput.data.addListener(self, onMove); + moveInput.activate(); { 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 { const self: *@This() = @ptrCast(@alignCast(ctx)); - if (self.mouseLook) - self.mouseMove = axis; + self.fpcamera.addMouseMovement(axis); } fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void { @@ -182,13 +171,16 @@ fn toggleMouseLook(ctx: ?*anyopaque, action: core.ActionEvent) void { _ = action; self.mouseLook = !self.mouseLook; + if (!self.mouseLook) + self.showWindow = true; self.updateMouseLook(); } fn updateMouseLook(self: *@This()) void { + self.fpcamera.mouseLookEnabled = self.mouseLook; platform.setMouseRelativeMode(self.mouseLook); - platform.setImguiVisible(!self.mouseLook); + // platform.setImguiVisible(!self.mouseLook); } 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 { 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 }; - const posRot = scene.getPosRot(); + self.fpcamera.tick(dt); - self.yaw += self.rotateAxis * fdt * 20; - self.pitch += self.rotateAxisPitch * fdt * 20; + var movement = self.fpcamera.getForwardXZ().fmul(self.moveVector.z * fdt * self.cameraSpeed); + 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); - self.pitch -= core.radians(mouseMovement.y * self.sensitivity); + const forward = self.fpcamera.getForward(); + const debugCenter = self.fpcamera.getPosition().add(forward.fmul(self.centerDist)); - 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)); - const movement = posRot.rotation.rotateVector(vector.fmul(self.cameraSpeed * fdt)); + core.debugSphere(debugCenter, 0.3, .{}); + core.debugSphere(debugCenter, 0.1, .{ .color = .{ .x = 1.0 } }); - posRot.position = posRot.position.add(movement); + rend.context().lightPosition = debugCenter; - self.cameraComponent.resolve(); - self.centerDist += self.centerDistMove * fdt; - const forward = self.cameraComponent.forward(); //posRot.rotation.forward(); - const debugCenter = posRot.position.add(forward.fmul(self.centerDist)); + // show a window with the current camera's position - core.debugSphere(debugCenter, 0.3, .{}); - core.debugSphere(debugCenter, 0.1, .{ .color = .{ .x = 1.0 } }); - - rend.context().lightPosition = debugCenter; + if (ig.begin("meh", &self.showWindow, .{})) { + ig.textFmt("x:{d:.03} y:{d:.03} z:{d:.03}", .{ pos.x, pos.y, pos.z }) catch return; + ig.end(); } - - var show: bool = true; - - ig.showDemoWindow(&show); } pub fn deinit(self: *@This()) void { + self.fpcamera.destroy(); self.allocator.destroy(self); } @@ -296,6 +281,7 @@ pub fn main() anyerror!void { }); } +const FpCamera = @import("gameExtras").FpCamera; const std = @import("std"); const backlog = @import("Backlog"); const assets = backlog.assets;