Skip to content
46 changes: 42 additions & 4 deletions src/itemdrop.zig
Original file line number Diff line number Diff line change
Expand Up @@ -543,27 +543,65 @@ pub const ClientItemDropManager = struct { // MARK: ClientItemDropManager
}
};

// Going to handle item animations and other things like - bobbing, interpolation, movement reactions
// Going to handle item animations and other things like - interpolation, movement reactions
pub const ItemDisplayManager = struct { // MARK: ItemDisplayManager
pub var showItem: bool = true;
var cameraFollow: Vec3f = @splat(0);
var cameraFollowVel: Vec3f = @splat(0);
const damping: Vec3f = @splat(130);
var bobPhase: f32 = 0;

pub fn update(deltaTime: f64) void {
if (deltaTime == 0) return;
const dt: f32 = @floatCast(deltaTime);

var playerVel: Vec3f = .{@floatCast((game.Player.super.vel[2]*0.009 + game.Player.eye.vel[2]*0.0075)), 0, 0};
playerVel = vec.clampMag(playerVel, 0.32);
const totalOffset = calculateAscentDescentOffset() + calculateBobOffset(dt);

// TODO: add *smooth* item sway
const n1: Vec3f = cameraFollowVel - (cameraFollow - playerVel)*damping*damping*@as(Vec3f, @splat(dt));
const n1: Vec3f = cameraFollowVel - (cameraFollow - totalOffset)*damping*damping*@as(Vec3f, @splat(dt));
const n2: Vec3f = @as(Vec3f, @splat(1)) + damping*@as(Vec3f, @splat(dt));
cameraFollowVel = n1/(n2*n2);

cameraFollow += cameraFollowVel*@as(Vec3f, @splat(dt));
}

fn calculateAscentDescentOffset() Vec3f {
const playerVel: Vec3f = .{@floatCast((game.Player.super.vel[2]*0.009 + game.Player.eye.vel[2]*0.0075)), 0, 0};
return vec.clampMag(playerVel, 0.32);
}

fn calculateBobOffset(dt: f32) Vec3f {
const bobSpeed: f32 = 1.2;
const bobAmountLateral: f32 = 0.007;
const bobAmountVertical: f32 = 0.006;
const bobSettle: f32 = 2.5;
const bobMovementScaleLimit: f32 = 10;

if (game.Player.isFlying.load(.monotonic) or game.Player.isGhost.load(.monotonic)) {
return @splat(0);
}

const horizontalVel: Vec3f = .{
@floatCast(game.Player.super.vel[0]),
@floatCast(game.Player.super.vel[1]),
0,
};

const movementScale = @min(vec.length(horizontalVel), bobMovementScaleLimit);

if (game.Player.onGround and movementScale > 0.01) {
bobPhase += dt*bobSpeed*movementScale;
bobPhase = std.math.mod(f32, bobPhase, 2*std.math.pi) catch unreachable;
} else {
bobPhase = std.math.lerp(bobPhase, 0, @min(dt*bobSettle, 1));
}

return .{
@abs(std.math.sin(bobPhase))*bobAmountVertical*movementScale,
0,
std.math.sin(bobPhase)*bobAmountLateral*movementScale,
};
}
};

pub const ItemDropRenderer = struct { // MARK: ItemDropRenderer
Expand Down