const std = @import("std"); const Vector2Int = @import("math.zig").Vector2Int; pub const app_name = "voxel-game"; pub const app_version_string = @import("config").version; pub const app_version = std.SemanticVersion.parse(app_version_string) catch unreachable; pub const min_framerate = 30.0; pub const max_frametime = 1.0 / min_framerate; pub const default_window_width = 1280; pub const default_window_height = 720; pub const default_window_size = Vector2Int.init(default_window_width, default_window_height); pub const min_window_width = 640; pub const min_window_height = 360; pub const min_window_size = Vector2Int.init(default_window_width, default_window_height); pub const window_title = "Voxel Game"; pub const temp_allocator_capacity = 16 * 1024 * 1024; // Coordinate spaces: // - CS (clip space, as required by Vulkan) // - VS (view space, looking towards +Y, +X is right and +Z is up) // - WS (world space, origin at a corner of voxel (0, 0, 0), +Z is up) // Units: // - SV (subvoxel) | // - VX (voxels) | 1 [VX] = 4096 [SV] // - CK (chunks) | 1 [CK] = 16 [VX] // Relative units: // CKSV subvoxels relative to chunk | [0, 65536) // CKVX voxels relative to chunk | [0, 16) // VXSV subvoxels relative to voxel | [0, 4096) pub const sv_per_vx = 4096; pub const vx_per_ck = 16; pub const sv_per_ck = sv_per_vx * vx_per_ck; pub const RoundingMode = enum { border_down, border_up, }; /// SV to VX pub inline fn subvoxelsToVoxels(comptime rounding_mode: RoundingMode, sv: i32) i32 { return switch (rounding_mode) { .border_down => @divFloor(sv - 1, sv_per_vx), .border_up => @divFloor(sv, sv_per_vx), }; } /// SV to CK pub inline fn subvoxelsToChunks(comptime rounding_mode: RoundingMode, sv: i32) i32 { return switch (rounding_mode) { .border_down => @divFloor(sv - 1, sv_per_ck), .border_up => @divFloor(sv, sv_per_ck), }; } /// SV to CKSV pub inline fn subvoxelsToChunkSubvoxels(sv: i32) std.math.IntFittingRange(0, sv_per_ck - 1) { return @intCast(@mod(sv, sv_per_ck)); } /// SV to VXSV pub inline fn subvoxelsToVoxelSubvoxels(sv: i32) std.math.IntFittingRange(0, sv_per_vx - 1) { return @intCast(@mod(sv, sv_per_vx)); } /// VX to SV pub inline fn voxelsToSubvoxels(vx: i32) i32 { return vx * sv_per_vx; } /// VX to CK pub inline fn voxelsToChunks(comptime rounding_mode: RoundingMode, vx: i32) i32 { return switch (rounding_mode) { .border_down => @divFloor(vx - 1, vx_per_ck), .border_up => @divFloor(vx, vx_per_ck), }; } /// VX to CKVX pub inline fn voxelsToChunkVoxels(vx: i32) std.math.IntFittingRange(0, vx_per_ck) { return @intCast(@mod(vx, vx_per_ck)); } /// CK to SV pub inline fn chunksToSubvoxels(ck: i32) i32 { return ck * sv_per_ck; } /// CK to VX pub inline fn chunksToVoxels(ck: i32) i32 { return ck * vx_per_ck; }