diff --git a/src/game.zig b/src/game.zig index 71ba4b369..3b517de9e 100644 --- a/src/game.zig +++ b/src/game.zig @@ -752,7 +752,7 @@ var biomeFog = Fog{.skyColor = .{0.8, 0.8, 1}, .fogColor = .{0.8, 0.8, 1}, .dens pub var fog = Fog{.skyColor = .{0.8, 0.8, 1}, .fogColor = .{0.8, 0.8, 1}, .density = 1.0/15.0/128.0, .fogLower = 100, .fogHigher = 1000}; var nextBlockPlaceTime: ?i64 = null; -var nextBlockBreakTime: ?i64 = null; +pub var nextBlockBreakTime: ?i64 = null; pub fn pressPlace() void { const time = std.time.milliTimestamp(); diff --git a/src/itemdrop.zig b/src/itemdrop.zig index 1f770cef7..9e90242be 100644 --- a/src/itemdrop.zig +++ b/src/itemdrop.zig @@ -791,7 +791,7 @@ pub const ItemDropRenderer = struct { // MARK: ItemDropRenderer return result; } - pub fn renderDisplayItems(ambientLight: Vec3f, playerPos: Vec3d) void { + pub fn renderDisplayItems(ambientLight: Vec3f, playerPos: Vec3d, swingProgress: f32, swingTime: f32) void { if(!ItemDisplayManager.showItem) return; const projMatrix: Mat4f = Mat4f.perspective(std.math.degreesToRadians(65), @as(f32, @floatFromInt(main.renderer.lastWidth))/@as(f32, @floatFromInt(main.renderer.lastHeight)), 0.01, 3); @@ -800,7 +800,7 @@ pub const ItemDropRenderer = struct { // MARK: ItemDropRenderer const selectedItem = game.Player.inventory.getItem(game.Player.selectedSlot); if(selectedItem) |item| { - var pos: Vec3d = Vec3d{0, 0, 0}; + var pos: Vec3f = Vec3f{0, 0, 0}; const rot: Vec3f = ItemDisplayManager.cameraFollow; const lightPos = @as(Vec3d, @floatCast(playerPos)) - @as(Vec3f, @splat(0.5)); @@ -852,26 +852,46 @@ pub const ItemDropRenderer = struct { // MARK: ItemDropRenderer blockType = item.baseItem.block().?; vertices = model.len/2*6; scale = 0.3; - pos = Vec3d{0.4, 0.55, -0.32}; + pos = Vec3f{0.4, 0.40, -0.32}; } else { scale = 0.57; - pos = Vec3d{0.4, 0.65, -0.3}; + pos = Vec3f{0.4, 0.50, -0.3}; } bindModelUniforms(model.index, blockType); - var modelMatrix = Mat4f.rotationZ(-rot[2]); - modelMatrix = modelMatrix.mul(Mat4f.rotationY(-rot[1])); - modelMatrix = modelMatrix.mul(Mat4f.rotationX(-rot[0])); - modelMatrix = modelMatrix.mul(Mat4f.translation(@floatCast(pos))); + // Item swing animation + const startPos: Vec3f = pos; + const swingPosOffset: Vec3f = Vec3f{-0.1, 0.0, 0.2}; + const startRot: Vec3f = Vec3f{0.0, 0.0, 0.0}; + const swingRotOffset: Vec3f = Vec3f{-0.2, -0.1, 0.0}; + var swingPhase: f32 = 0.0; + if(swingTime <= 0) { + swingPhase = 0.0; + } else { + swingPhase = std.math.sin((swingProgress/swingTime)*std.math.pi); + } + const lerpedPos: Vec3f = startPos + swingPosOffset*@as(Vec3f, @splat(swingPhase)); + const lerpedRot: Vec3f = startRot + swingRotOffset*@as(Vec3f, @splat(swingPhase)); + + var modelMatrix = Mat4f.rotationX(-rot[0] + lerpedRot[0]); + modelMatrix = modelMatrix.mul(Mat4f.rotationY(-rot[1] + lerpedRot[1])); + modelMatrix = modelMatrix.mul(Mat4f.rotationZ(-rot[2] + lerpedRot[2])); + modelMatrix = modelMatrix.mul(Mat4f.translation(lerpedPos)); + + const TOOL_ROT_Z: f32 = -std.math.pi*0.47; + const TOOL_ROT_Y: f32 = std.math.pi*0.25; + const ITEM_ROT_Z: f32 = -std.math.pi*0.45; + const BLOCK_ROT_Z: f32 = -std.math.pi*0.2; + if(!isBlock) { if(item == .tool) { - modelMatrix = modelMatrix.mul(Mat4f.rotationZ(-std.math.pi*0.47)); - modelMatrix = modelMatrix.mul(Mat4f.rotationY(std.math.pi*0.25)); + modelMatrix = modelMatrix.mul(Mat4f.rotationZ(TOOL_ROT_Z)); + modelMatrix = modelMatrix.mul(Mat4f.rotationY(TOOL_ROT_Y)); } else { - modelMatrix = modelMatrix.mul(Mat4f.rotationZ(-std.math.pi*0.45)); + modelMatrix = modelMatrix.mul(Mat4f.rotationZ(ITEM_ROT_Z)); } } else { - modelMatrix = modelMatrix.mul(Mat4f.rotationZ(-std.math.pi*0.2)); + modelMatrix = modelMatrix.mul(Mat4f.rotationZ(BLOCK_ROT_Z)); } modelMatrix = modelMatrix.mul(Mat4f.scale(@splat(scale))); modelMatrix = modelMatrix.mul(Mat4f.translation(@splat(-0.5))); diff --git a/src/renderer.zig b/src/renderer.zig index a1c25aa72..2b7dd9a36 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -147,6 +147,10 @@ pub fn render(playerPosition: Vec3d, deltaTime: f64) void { ambient[1] = @max(0.1, world.ambientLight); ambient[2] = @max(0.1, world.ambientLight); + // Reset swing animation if not mining (input released) + if(game.nextBlockBreakTime == null) { + MeshSelection.currentSwingProgress = 0; + } itemdrop.ItemDisplayManager.update(deltaTime); renderWorld(world, ambient, game.fog.skyColor, playerPosition); const startTime = std.time.milliTimestamp(); @@ -277,7 +281,7 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo } c.glDepthRange(0, 0.001); - itemdrop.ItemDropRenderer.renderDisplayItems(ambientLight, playerPos); + itemdrop.ItemDropRenderer.renderDisplayItems(ambientLight, playerPos, MeshSelection.currentSwingProgress, MeshSelection.currentSwingTime); c.glDepthRange(0.001, 1); chunk_meshing.endRender();