Real/World time

This commit is contained in:
duck
2025-06-16 00:07:20 +05:00
parent 2d010644c7
commit 3635712a53
3 changed files with 116 additions and 55 deletions

View File

@@ -1,56 +1,64 @@
const std = @import("std"); const std = @import("std");
const sdl = @import("sdl"); const sdl = @import("sdl");
const math = @import("math.zig"); const math = @import("math.zig");
const Time = @import("time.zig");
const Transform = @import("graphics/transform.zig"); const Transform = @import("graphics/transform.zig");
const Controller = @import("graph/controller.zig"); const Controller = @import("graph/controller.zig");
const Graphics = @import("graphics.zig"); const Graphics = @import("graphics.zig");
const Game = @import("game.zig"); const Game = @import("game.zig");
const CUBE_MESH_DATA = [_]f32{ const CUBE_MESH_DATA = [_]f32{
-1, 1, -1, -0.5, 0.5, -0.5,
1, 1, -1, 0.5, 0.5, -0.5,
-1, -1, -1, -0.5, -0.5, -0.5,
1, -1, -1, 0.5, -0.5, -0.5,
-1, -1, -1, -0.5, -0.5, -0.5,
1, 1, -1, 0.5, 0.5, -0.5,
1, 1, -1, 0.5, 0.5, -0.5,
1, 1, 1, 0.5, 0.5, 0.5,
1, -1, -1, 0.5, -0.5, -0.5,
1, -1, 1, 0.5, -0.5, 0.5,
1, -1, -1, 0.5, -0.5, -0.5,
1, 1, 1, 0.5, 0.5, 0.5,
1, 1, 1, 0.5, 0.5, 0.5,
-1, 1, 1, -0.5, 0.5, 0.5,
1, -1, 1, 0.5, -0.5, 0.5,
-1, -1, 1, -0.5, -0.5, 0.5,
1, -1, 1, 0.5, -0.5, 0.5,
-1, 1, 1, -0.5, 0.5, 0.5,
-1, 1, 1, -0.5, 0.5, 0.5,
-1, 1, -1, -0.5, 0.5, -0.5,
-1, -1, 1, -0.5, -0.5, 0.5,
-1, -1, -1, -0.5, -0.5, -0.5,
-1, -1, 1, -0.5, -0.5, 0.5,
-1, 1, -1, -0.5, 0.5, -0.5,
-1, 1, 1, -0.5, 0.5, 0.5,
1, 1, 1, 0.5, 0.5, 0.5,
-1, 1, -1, -0.5, 0.5, -0.5,
1, 1, -1, 0.5, 0.5, -0.5,
-1, 1, -1, -0.5, 0.5, -0.5,
1, 1, 1, 0.5, 0.5, 0.5,
-1, -1, -1, -0.5, -0.5, -0.5,
1, -1, -1, 0.5, -0.5, -0.5,
-1, -1, 1, -0.5, -0.5, 0.5,
1, -1, 1, 0.5, -0.5, 0.5,
-1, -1, 1, -0.5, -0.5, 0.5,
1, -1, -1, 0.5, -0.5, -0.5,
}; };
const PLANE_MESH_DATA = [_]f32{ const PLANE_MESH_DATA = [_]f32{
-1, -1, 0, -0.5, -0.5, 0,
1, 1, 0, 0.5, 0.5, 0,
-1, 1, 0, -0.5, 0.5, 0,
1, 1, 0, 0.5, 0.5, 0,
-1, -1, 0, -0.5, -0.5, 0,
1, -1, 0, 0.5, -0.5, 0,
};
pub const WorldTime = struct {
time: Time,
delta: f32,
view_unresolved: f32,
view_timescale: f32,
}; };
pub const Player = struct { pub const Player = struct {
@@ -74,6 +82,12 @@ pub fn init(controller: *Controller, graphics: *Graphics) !void {
controller.addResource(Environment{ controller.addResource(Environment{
.mesh = try graphics.loadMesh(@ptrCast(&PLANE_MESH_DATA)), .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 = .{ graphics.camera.transform = .{
.position = .{ 0, 0, 10 }, .position = .{ 0, 0, 10 },
}; };
@@ -81,14 +95,42 @@ pub fn init(controller: *Controller, graphics: *Graphics) !void {
pub fn deinit() 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( pub fn update(
player: *Player, player: *Player,
// mouse: *Game.Mouse, // mouse: *Game.Mouse,
keyboard: *Game.Keyboard, keyboard: *Game.Keyboard,
graphics: *Graphics, graphics: *Graphics,
time: *Game.Time, real_time: *Game.Time,
world_time: *WorldTime,
) void { ) void {
const MAX_VELOCITY = 16.0; const MAX_VELOCITY = 12.0;
const TIME_TO_REACH_MAX_VELOCITY = 1.0 / 8.0; const TIME_TO_REACH_MAX_VELOCITY = 1.0 / 8.0;
var velocity_target: @Vector(2, f32) = .{ 0, 0 }; var velocity_target: @Vector(2, f32) = .{ 0, 0 };
@@ -105,9 +147,9 @@ pub fn update(
velocity_target[0] -= MAX_VELOCITY; velocity_target[0] -= MAX_VELOCITY;
} }
velocity_target = math.limitLength(velocity_target, 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.velocity = math.stepVector(player.velocity, velocity_target, MAX_VELOCITY / TIME_TO_REACH_MAX_VELOCITY * world_time.delta);
player.transform.position[0] += player.velocity[0] * time.delta; player.transform.position[0] += player.velocity[0] * world_time.delta;
player.transform.position[1] += player.velocity[1] * time.delta; player.transform.position[1] += player.velocity[1] * world_time.delta;
const target_position = player.transform.position + const target_position = player.transform.position +
@Vector(3, f32){ player.velocity[0], player.velocity[1], 0 } * @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 = math.lerpTimeLn(
graphics.camera.transform.position, graphics.camera.transform.position,
target_position + @Vector(3, f32){ 0.0, -3.0, 10.0 }, target_position + @Vector(3, f32){ 0.0, -2.0, 5.0 },
time.delta, real_time.delta,
-25, -25,
); );
@@ -139,7 +181,7 @@ pub fn update(
graphics.camera.transform.rotation = Transform.normalizeRotation(math.slerpTimeLn( graphics.camera.transform.rotation = Transform.normalizeRotation(math.slerpTimeLn(
graphics.camera.transform.rotation, graphics.camera.transform.rotation,
target_rotation, target_rotation,
time.delta, real_time.delta,
-2, -2,
)); ));
} }

View File

@@ -12,7 +12,10 @@ const Graphics = @import("graphics.zig");
pub const RunInfo = struct { running: bool }; pub const RunInfo = struct { running: bool };
pub const Mouse = @import("mouse.zig"); pub const Mouse = @import("mouse.zig");
pub const Keyboard = @import("keyboard.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, alloc: std.mem.Allocator,
graph: Graph, graph: Graph,
@@ -72,7 +75,7 @@ pub fn run(self: *Self) GameError!void {
var controller = try self.graph.getController(); var controller = try self.graph.getController();
controller.queue(.{ controller.queue(.{
processEvents, processEvents,
debug_scene.update, debug_scene.updateReal,
beginDraw, beginDraw,
endDraw, endDraw,
Graph.Controller.Option.ordered, Graph.Controller.Option.ordered,

View File

@@ -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, clock: TimeType,
now: sdl.Time,
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);
}