From 3635712a539a08b7d47e0a09c99f4a2f0b64ce77 Mon Sep 17 00:00:00 2001 From: duck Date: Mon, 16 Jun 2025 00:07:20 +0500 Subject: [PATCH] Real/World time --- src/debug_scene.zig | 142 ++++++++++++++++++++++++++++---------------- src/game.zig | 7 ++- src/time.zig | 22 ++++++- 3 files changed, 116 insertions(+), 55 deletions(-) diff --git a/src/debug_scene.zig b/src/debug_scene.zig index e2cdb87..db1b7d2 100644 --- a/src/debug_scene.zig +++ b/src/debug_scene.zig @@ -1,56 +1,64 @@ const std = @import("std"); const sdl = @import("sdl"); const math = @import("math.zig"); +const Time = @import("time.zig"); const Transform = @import("graphics/transform.zig"); const Controller = @import("graph/controller.zig"); const Graphics = @import("graphics.zig"); const Game = @import("game.zig"); const CUBE_MESH_DATA = [_]f32{ - -1, 1, -1, - 1, 1, -1, - -1, -1, -1, - 1, -1, -1, - -1, -1, -1, - 1, 1, -1, - 1, 1, -1, - 1, 1, 1, - 1, -1, -1, - 1, -1, 1, - 1, -1, -1, - 1, 1, 1, - 1, 1, 1, - -1, 1, 1, - 1, -1, 1, - -1, -1, 1, - 1, -1, 1, - -1, 1, 1, - -1, 1, 1, - -1, 1, -1, - -1, -1, 1, - -1, -1, -1, - -1, -1, 1, - -1, 1, -1, - -1, 1, 1, - 1, 1, 1, - -1, 1, -1, - 1, 1, -1, - -1, 1, -1, - 1, 1, 1, - -1, -1, -1, - 1, -1, -1, - -1, -1, 1, - 1, -1, 1, - -1, -1, 1, - 1, -1, -1, + -0.5, 0.5, -0.5, + 0.5, 0.5, -0.5, + -0.5, -0.5, -0.5, + 0.5, -0.5, -0.5, + -0.5, -0.5, -0.5, + 0.5, 0.5, -0.5, + 0.5, 0.5, -0.5, + 0.5, 0.5, 0.5, + 0.5, -0.5, -0.5, + 0.5, -0.5, 0.5, + 0.5, -0.5, -0.5, + 0.5, 0.5, 0.5, + 0.5, 0.5, 0.5, + -0.5, 0.5, 0.5, + 0.5, -0.5, 0.5, + -0.5, -0.5, 0.5, + 0.5, -0.5, 0.5, + -0.5, 0.5, 0.5, + -0.5, 0.5, 0.5, + -0.5, 0.5, -0.5, + -0.5, -0.5, 0.5, + -0.5, -0.5, -0.5, + -0.5, -0.5, 0.5, + -0.5, 0.5, -0.5, + -0.5, 0.5, 0.5, + 0.5, 0.5, 0.5, + -0.5, 0.5, -0.5, + 0.5, 0.5, -0.5, + -0.5, 0.5, -0.5, + 0.5, 0.5, 0.5, + -0.5, -0.5, -0.5, + 0.5, -0.5, -0.5, + -0.5, -0.5, 0.5, + 0.5, -0.5, 0.5, + -0.5, -0.5, 0.5, + 0.5, -0.5, -0.5, }; const PLANE_MESH_DATA = [_]f32{ - -1, -1, 0, - 1, 1, 0, - -1, 1, 0, - 1, 1, 0, - -1, -1, 0, - 1, -1, 0, + -0.5, -0.5, 0, + 0.5, 0.5, 0, + -0.5, 0.5, 0, + 0.5, 0.5, 0, + -0.5, -0.5, 0, + 0.5, -0.5, 0, +}; + +pub const WorldTime = struct { + time: Time, + delta: f32, + view_unresolved: f32, + view_timescale: f32, }; pub const Player = struct { @@ -74,6 +82,12 @@ pub fn init(controller: *Controller, graphics: *Graphics) !void { controller.addResource(Environment{ .mesh = try graphics.loadMesh(@ptrCast(&PLANE_MESH_DATA)), }); + controller.addResource(WorldTime{ + .time = .{ .clock = 0 }, + .delta = 0.0, + .view_unresolved = 0.0, + .view_timescale = 1.0, + }); graphics.camera.transform = .{ .position = .{ 0, 0, 10 }, }; @@ -81,14 +95,42 @@ pub fn init(controller: *Controller, graphics: *Graphics) !void { pub fn deinit() void {} +pub fn updateReal( + real_time: *Game.Time, + world_time: *WorldTime, + controller: *Controller, +) void { + world_time.view_unresolved += real_time.delta; + controller.queue(updateWorld); +} + +pub fn updateWorld( + world_time: *WorldTime, + controller: *Controller, +) void { + if (world_time.view_unresolved <= 0.000001) { + return; + } + // This can later be clamped to schedule several updates per frame + const real_delta = world_time.view_unresolved; + const world_delta = real_delta * world_time.view_timescale; + + world_time.time.tick(real_delta); + world_time.view_unresolved -= real_delta; + world_time.delta = world_delta; + + controller.queue(update); +} + pub fn update( player: *Player, // mouse: *Game.Mouse, keyboard: *Game.Keyboard, graphics: *Graphics, - time: *Game.Time, + real_time: *Game.Time, + world_time: *WorldTime, ) void { - const MAX_VELOCITY = 16.0; + const MAX_VELOCITY = 12.0; const TIME_TO_REACH_MAX_VELOCITY = 1.0 / 8.0; var velocity_target: @Vector(2, f32) = .{ 0, 0 }; @@ -105,9 +147,9 @@ pub fn update( velocity_target[0] -= MAX_VELOCITY; } velocity_target = math.limitLength(velocity_target, MAX_VELOCITY); - player.velocity = math.stepVector(player.velocity, velocity_target, MAX_VELOCITY / TIME_TO_REACH_MAX_VELOCITY * time.delta); - player.transform.position[0] += player.velocity[0] * time.delta; - player.transform.position[1] += player.velocity[1] * time.delta; + player.velocity = math.stepVector(player.velocity, velocity_target, MAX_VELOCITY / TIME_TO_REACH_MAX_VELOCITY * world_time.delta); + player.transform.position[0] += player.velocity[0] * world_time.delta; + player.transform.position[1] += player.velocity[1] * world_time.delta; const target_position = player.transform.position + @Vector(3, f32){ player.velocity[0], player.velocity[1], 0 } * @@ -116,8 +158,8 @@ pub fn update( graphics.camera.transform.position = math.lerpTimeLn( graphics.camera.transform.position, - target_position + @Vector(3, f32){ 0.0, -3.0, 10.0 }, - time.delta, + target_position + @Vector(3, f32){ 0.0, -2.0, 5.0 }, + real_time.delta, -25, ); @@ -139,7 +181,7 @@ pub fn update( graphics.camera.transform.rotation = Transform.normalizeRotation(math.slerpTimeLn( graphics.camera.transform.rotation, target_rotation, - time.delta, + real_time.delta, -2, )); } diff --git a/src/game.zig b/src/game.zig index 34f6872..31ca101 100644 --- a/src/game.zig +++ b/src/game.zig @@ -12,7 +12,10 @@ const Graphics = @import("graphics.zig"); pub const RunInfo = struct { running: bool }; pub const Mouse = @import("mouse.zig"); pub const Keyboard = @import("keyboard.zig"); -pub const Time = @import("time.zig"); +pub const Time = struct { + delta: f32, + now: sdl.Time, +}; alloc: std.mem.Allocator, graph: Graph, @@ -72,7 +75,7 @@ pub fn run(self: *Self) GameError!void { var controller = try self.graph.getController(); controller.queue(.{ processEvents, - debug_scene.update, + debug_scene.updateReal, beginDraw, endDraw, Graph.Controller.Option.ordered, diff --git a/src/time.zig b/src/time.zig index b040cac..67c22cc 100644 --- a/src/time.zig +++ b/src/time.zig @@ -1,4 +1,20 @@ -const sdl = @import("sdl"); +const TimeType = u64; +const TIME_UNIT: TimeType = 1 << 32; +const TIME_MULT = 1.0 / @as(f32, @floatFromInt(TIME_UNIT)); -delta: f32, -now: sdl.Time, +clock: TimeType, + +const Time = @This(); + +pub fn tick(self: *Time, units: f32) void { + self.clock += durationFromUnits(units); +} + +pub fn unitsSince(self: *Time, from: Time) f32 { + if (from.clock > self.clock) return 0; + return @as(f32, @floatFromInt(self.clock - from.clock)) * TIME_MULT; +} + +pub fn durationFromUnits(units: f32) TimeType { + return @intFromFloat(@as(f32, @floatFromInt(TIME_UNIT)) * units); +}