Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 65 additions & 4 deletions src/game.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ pub const camera = struct { // MARK: camera
pub var direction: Vec3f = Vec3f{0, 0, 0};
pub var viewMatrix: Mat4f = Mat4f.identity();
pub fn moveRotation(mouseX: f32, mouseY: f32) void {
const scale = std.math.lerp(1.0, zoom, settings.zoomRelativeSensitivity);
const scaledMouseX = mouseX/scale;
const scaledMouseY = mouseY/scale;
// Mouse movement along the y-axis rotates the image along the x-axis.
rotation[0] += mouseY;
rotation[0] += scaledMouseY;
const bound = std.math.pi/2.0 - 0.001;
rotation[0] = std.math.clamp(rotation[0], -bound, bound);
// Mouse movement along the x-axis rotates the image along the z-axis.
rotation[2] += mouseX;
rotation[2] += scaledMouseX;
}

pub fn updateViewMatrix() void {
Expand Down Expand Up @@ -518,6 +521,15 @@ pub const World = struct { // MARK: World
pub var testWorld: World = undefined; // TODO:
pub var world: ?*World = null;

var zoom: f32 = 1.0;
var zoomIsPressed: bool = false;
var zoomStartTime: ?std.Io.Timestamp = null;
var zoomNeededDurationSeconds: f32 = 0.0;
var zoomNeededDuration: std.Io.Duration = std.Io.Duration.zero;
var zoomStart: f32 = 1.0;
var zoomEnd: f32 = 1.0;
var zoomSScaled: f32 = 0.0;

pub var projectionMatrix: Mat4f = Mat4f.identity();

var nextBlockPlaceTime: ?std.Io.Timestamp = null;
Expand Down Expand Up @@ -579,6 +591,51 @@ pub fn getBlockWithSide(comptime side: main.sync.Side, x: i32, y: i32, z: i32) ?
}
}

fn updateZoom() void {
const maxZoom = 10_000.0;
const currentTime = main.timestamp();
var startTime = currentTime;
var newZoomEnd: f32 = 1.0;
if (KeyBoard.key("zoom").pressed) {
if (zoomIsPressed) { // key already held
newZoomEnd = zoomEnd;
} else { // key just pressed
newZoomEnd = settings.zoomInitial;
}
const change = @as(f32, @floatFromInt(main.Window.scrollOffsetInteger));
newZoomEnd *= std.math.pow(f32, settings.zoomIncrease, change);
newZoomEnd = std.math.clamp(newZoomEnd, 1.0, maxZoom);
zoomIsPressed = true;
} else {
newZoomEnd = 1.0;
zoomIsPressed = false;
}
if (zoomEnd != newZoomEnd) { // interrupting zoom
zoomEnd = newZoomEnd;
zoomStartTime = currentTime;
zoomStart = zoom;
// https://vanwijk.win.tue.nl/zoompan.pdf
zoomSScaled = @log(zoomEnd/zoomStart);
zoomNeededDurationSeconds = @abs(zoomSScaled)/settings.zoomSpeed;
zoomNeededDuration = std.Io.Duration.fromNanoseconds(@as(i96, @trunc(zoomNeededDurationSeconds*1e9)));
} else if (zoomStartTime) |time| { // zooming in without interruptions
startTime = time;
} else { // ended zooming in
return;
}
const zoomDuration = startTime.durationTo(currentTime);
if (zoomDuration.nanoseconds < zoomNeededDuration.nanoseconds) {
const zoomSeconds = @as(f32, @floatFromInt(zoomDuration.toNanoseconds()))/1.0e9;
const t = std.math.clamp(zoomSeconds/zoomNeededDurationSeconds, 0, 1);
zoom = zoomStart*std.math.exp(zoomSScaled*t);
zoom = @max(zoom, 1);
} else {
zoom = zoomEnd;
zoomStartTime = null;
}
renderer.updateZoom(zoom);
}

pub fn update(deltaTime: f64) void { // MARK: update()
if (world.?.shouldRestart.load(.acquire)) {
restart();
Expand Down Expand Up @@ -694,8 +751,12 @@ pub fn update(deltaTime: f64) void { // MARK: update()
acc += movementDir*@as(Vec3d, @splat(movementSpeed*fricMul));
}

const newSlot: i32 = @as(i32, @intCast(Player.selectedSlot)) -% main.Window.scrollOffsetInteger;
Player.selectedSlot = @intCast(@mod(newSlot, 12));
updateZoom();

if (!zoomIsPressed) {
const newSlot: i32 = @as(i32, @intCast(Player.selectedSlot)) -% main.Window.scrollOffsetInteger;
Player.selectedSlot = @intCast(@mod(newSlot, 12));
}

const newPos = Vec2f{
@floatCast(main.KeyBoard.key("cameraRight").value - main.KeyBoard.key("cameraLeft").value),
Expand Down
10 changes: 10 additions & 0 deletions src/gui/windows/controls.zig
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ fn updateSensitivity(sensitivity: f32) void {
main.settings.save();
}

fn zoomRelativeSensitivityCallback(newValue: f32) void {
main.settings.zoomRelativeSensitivity = newValue;
main.settings.save();
}

fn zoomRelativeSensitivityFormatter(allocator: main.heap.NeverFailingAllocator, value: f32) []const u8 {
return std.fmt.allocPrint(allocator.allocator, "Zoom relative sensitivity: {d:.0}%", .{value*100}) catch unreachable;
}

fn invertMouseYCallback(newValue: bool) void {
main.settings.invertMouseY = newValue;
main.settings.save();
Expand Down Expand Up @@ -112,6 +121,7 @@ fn initWindow() void {
const list = VerticalList.init(.{padding, 16 + padding}, 364, 8);
list.add(Button.initText(.{0, 0}, keybindButtonWidth, if (editingKeyboard) "Gamepad" else "Keyboard", .{.onAction = .init(toggleKeyboard)}));
list.add(ContinuousSlider.init(.{0, 0}, controlsListWidth, 0, 5, if (editingKeyboard) main.settings.mouseSensitivity else main.settings.controllerSensitivity, &updateSensitivity, &sensitivityFormatter));
list.add(ContinuousSlider.init(.{0, 0}, controlsListWidth, 0, 5, main.settings.zoomRelativeSensitivity, &zoomRelativeSensitivityCallback, &zoomRelativeSensitivityFormatter));
list.add(CheckBox.init(.{0, 0}, controlsListWidth, "Invert mouse Y", main.settings.invertMouseY, &invertMouseYCallback));
list.add(CheckBox.init(.{0, 0}, controlsListWidth, "Toggle sprint", main.KeyBoard.key("sprint").isToggling == .yes, &sprintIsToggleCallback));

Expand Down
30 changes: 30 additions & 0 deletions src/gui/windows/graphics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,33 @@ fn fovFormatter(allocator: main.heap.NeverFailingAllocator, value: f32) []const
return std.fmt.allocPrint(allocator.allocator, "#ffffffField Of View: {d:.0}°", .{value}) catch unreachable;
}

fn zoomSpeedCallback(newValue: f32) void {
settings.zoomSpeed = newValue;
settings.save();
}

fn zoomSpeedFormatter(allocator: main.heap.NeverFailingAllocator, value: f32) []const u8 {
return std.fmt.allocPrint(allocator.allocator, "#ffffffZoom speed: {d:.1}x", .{value}) catch unreachable;
}

fn zoomInitialCallback(newValue: f32) void {
settings.zoomInitial = newValue;
settings.save();
}

fn zoomInitialFormatter(allocator: main.heap.NeverFailingAllocator, value: f32) []const u8 {
return std.fmt.allocPrint(allocator.allocator, "#ffffffInitial zoom: {d:.1}x", .{value}) catch unreachable;
}

fn zoomIncreaseCallback(newValue: f32) void {
settings.zoomIncrease = newValue;
settings.save();
}

fn zoomIncreaseFormatter(allocator: main.heap.NeverFailingAllocator, value: f32) []const u8 {
return std.fmt.allocPrint(allocator.allocator, "#ffffffZoom increase: {d:.1}x", .{value}) catch unreachable;
}

fn lodDistanceFormatter(allocator: main.heap.NeverFailingAllocator, value: f32) []const u8 {
return std.fmt.allocPrint(allocator.allocator, "#ffffffOpaque leaves distance: {d:.0}", .{@round(value)}) catch unreachable;
}
Expand Down Expand Up @@ -140,6 +167,9 @@ pub fn onOpen() void {
list.add(ContinuousSlider.init(.{0, 0}, 128, 0.0, 0.5, settings.blockContrast, &contrastCallback, &contrastFormatter));
list.add(ContinuousSlider.init(.{0, 0}, 128, 0.0, 1.0, settings.nightBrightness, &nightBrightnessCallback, &nightBrightnessFormatter));
list.add(ContinuousSlider.init(.{0, 0}, 128, 40.0, 120.0, settings.fov, &fovCallback, &fovFormatter));
list.add(ContinuousSlider.init(.{0, 0}, 128, 1.0, 16.0, settings.zoomSpeed, &zoomSpeedCallback, &zoomSpeedFormatter));
list.add(ContinuousSlider.init(.{0, 0}, 128, 1.0, 16.0, settings.zoomInitial, &zoomInitialCallback, &zoomInitialFormatter));
list.add(ContinuousSlider.init(.{0, 0}, 128, 1.0, 4.0, settings.zoomIncrease, &zoomIncreaseCallback, &zoomIncreaseFormatter));
list.add(CheckBox.init(.{0, 0}, 128, "Bloom", settings.bloom, &bloomCallback));
list.add(CheckBox.init(.{0, 0}, 128, "Vertical Synchronization", settings.vsync, &vsyncCallback));
list.add(DiscreteSlider.init(.{0, 0}, 128, "#ffffffAnisotropic Filtering: ", "{}x", &anisotropy, switch (settings.anisotropicFiltering) {
Expand Down
1 change: 1 addition & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ pub const KeyBoard = struct { // MARK: KeyBoard
.{.name = "breakBlock", .mouseButton = c.GLFW_MOUSE_BUTTON_LEFT, .gamepadAxis = .{.axis = c.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER}, .pressAction = &game.pressBreak, .releaseAction = &game.releaseBreak, .notifyRequirement = .inGame},
.{.name = "acquireSelectedBlock", .mouseButton = c.GLFW_MOUSE_BUTTON_MIDDLE, .gamepadButton = c.GLFW_GAMEPAD_BUTTON_DPAD_LEFT, .pressAction = &game.pressAcquireSelectedBlock, .notifyRequirement = .inGame},
.{.name = "drop", .key = c.GLFW_KEY_Q, .repeatAction = &game.Player.dropFromHand, .notifyRequirement = .inGame},
.{.name = "zoom", .key = c.GLFW_KEY_Z},

.{.name = "takeBackgroundImage", .key = c.GLFW_KEY_PRINT_SCREEN, .pressAction = &takeBackgroundImageFn},
.{.name = "fullscreen", .key = c.GLFW_KEY_F11, .pressAction = &Window.toggleFullscreen},
Expand Down
17 changes: 15 additions & 2 deletions src/renderer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,26 @@ var worldFrameBuffer: graphics.FrameBuffer = undefined;
pub var lastWidth: u31 = 0;
pub var lastHeight: u31 = 0;
var lastFov: f32 = 0;
var lastZoom: f32 = 1;
pub fn updateProjectionMatrix() void {
game.projectionMatrix = Mat4f.scale(Vec3f{lastZoom, lastZoom, 1}).mul(Mat4f.perspective(std.math.degreesToRadians(lastFov), @as(f32, @floatFromInt(lastWidth))/@as(f32, @floatFromInt(lastHeight)), zNear, zFar));
}
pub fn updateFov(fov: f32) void {
if (lastFov != fov) {
lastFov = fov;
game.projectionMatrix = Mat4f.perspective(std.math.degreesToRadians(fov), @as(f32, @floatFromInt(lastWidth))/@as(f32, @floatFromInt(lastHeight)), zNear, zFar);
updateProjectionMatrix();
}
}
pub fn updateZoom(zoom: f32) void {
if (lastZoom != zoom) {
lastZoom = zoom;
updateProjectionMatrix();
}
}
pub fn updateViewport(width: u31, height: u31) void {
lastWidth = @trunc(@as(f32, @floatFromInt(width))*main.settings.resolutionScale);
lastHeight = @trunc(@as(f32, @floatFromInt(height))*main.settings.resolutionScale);
game.projectionMatrix = Mat4f.perspective(std.math.degreesToRadians(lastFov), @as(f32, @floatFromInt(lastWidth))/@as(f32, @floatFromInt(lastHeight)), zNear, zFar);
updateProjectionMatrix();
worldFrameBuffer.updateSize(lastWidth, lastHeight, c.GL_RGB16F);
worldFrameBuffer.unbind();
}
Expand Down Expand Up @@ -633,6 +643,9 @@ pub const MenuBackGround = struct {
updateViewport(size, size);
updateFov(90.0);
defer updateFov(main.settings.fov);
const prevZoom = lastZoom;
updateZoom(1.0);
defer updateZoom(prevZoom);
main.settings.resolutionScale = oldResolutionScale;
defer updateViewport(Window.width, Window.height);

Expand Down
5 changes: 5 additions & 0 deletions src/settings.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ pub var fpsCap: ?u32 = null;

pub var fov: f32 = 70;

pub var zoomSpeed: f32 = 5;
pub var zoomInitial: f32 = 3;
pub var zoomIncrease: f32 = 1.5;
pub var zoomRelativeSensitivity: f32 = 0.0;

pub var mouseSensitivity: f32 = 1;
pub var controllerSensitivity: f32 = 1;

Expand Down
Loading