/* * Decompiled with CFR 0.152. * * Could not load the following classes: * org.jspecify.annotations.Nullable */ package net.minecraft.world.entity; import java.util.Objects; import java.util.function.Consumer; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import org.jspecify.annotations.Nullable; public class InterpolationHandler { public static final int DEFAULT_INTERPOLATION_STEPS = 3; private final Entity entity; private int interpolationSteps; private final InterpolationData interpolationData = new InterpolationData(0, Vec3.ZERO, 0.0f, 0.0f); private @Nullable Vec3 previousTickPosition; private @Nullable Vec2 previousTickRot; private final @Nullable Consumer onInterpolationStart; public InterpolationHandler(Entity entity) { this(entity, 3, null); } public InterpolationHandler(Entity entity, int interpolationSteps) { this(entity, interpolationSteps, null); } public InterpolationHandler(Entity entity, @Nullable Consumer onInterpolationStart) { this(entity, 3, onInterpolationStart); } public InterpolationHandler(Entity entity, int interpolationSteps, @Nullable Consumer onInterpolationStart) { this.interpolationSteps = interpolationSteps; this.entity = entity; this.onInterpolationStart = onInterpolationStart; } public Vec3 position() { return this.interpolationData.steps > 0 ? this.interpolationData.position : this.entity.position(); } public float yRot() { return this.interpolationData.steps > 0 ? this.interpolationData.yRot : this.entity.getYRot(); } public float xRot() { return this.interpolationData.steps > 0 ? this.interpolationData.xRot : this.entity.getXRot(); } public void interpolateTo(Vec3 position, float yRot, float xRot) { if (this.interpolationSteps == 0) { this.entity.snapTo(position, yRot, xRot); this.cancel(); return; } if (this.hasActiveInterpolation() && Objects.equals(Float.valueOf(this.yRot()), Float.valueOf(yRot)) && Objects.equals(Float.valueOf(this.xRot()), Float.valueOf(xRot)) && Objects.equals(this.position(), position)) { return; } this.interpolationData.steps = this.interpolationSteps; this.interpolationData.position = position; this.interpolationData.yRot = yRot; this.interpolationData.xRot = xRot; this.previousTickPosition = this.entity.position(); this.previousTickRot = new Vec2(this.entity.getXRot(), this.entity.getYRot()); if (this.onInterpolationStart != null) { this.onInterpolationStart.accept(this); } } public boolean hasActiveInterpolation() { return this.interpolationData.steps > 0; } public void setInterpolationLength(int steps) { this.interpolationSteps = steps; } public void interpolate() { if (!this.hasActiveInterpolation()) { this.cancel(); return; } double alpha = 1.0 / (double)this.interpolationData.steps; if (this.previousTickPosition != null) { Vec3 deltaSinceLastInterpolation = this.entity.position().subtract(this.previousTickPosition); if (this.entity.level().noCollision(this.entity, this.entity.makeBoundingBox(this.interpolationData.position.add(deltaSinceLastInterpolation)))) { this.interpolationData.addDelta(deltaSinceLastInterpolation); } } if (this.previousTickRot != null) { float deltaYRotSinceLastInterpolation = this.entity.getYRot() - this.previousTickRot.y; float deltaXRotSinceLastInterpolation = this.entity.getXRot() - this.previousTickRot.x; this.interpolationData.addRotation(deltaYRotSinceLastInterpolation, deltaXRotSinceLastInterpolation); } double x = Mth.lerp(alpha, this.entity.getX(), this.interpolationData.position.x); double y = Mth.lerp(alpha, this.entity.getY(), this.interpolationData.position.y); double z = Mth.lerp(alpha, this.entity.getZ(), this.interpolationData.position.z); Vec3 newPosition = new Vec3(x, y, z); float newYRot = (float)Mth.rotLerp(alpha, (double)this.entity.getYRot(), (double)this.interpolationData.yRot); float newXRot = (float)Mth.lerp(alpha, (double)this.entity.getXRot(), (double)this.interpolationData.xRot); this.entity.setPos(newPosition); this.entity.setRot(newYRot, newXRot); this.interpolationData.decrease(); this.previousTickPosition = newPosition; this.previousTickRot = new Vec2(this.entity.getXRot(), this.entity.getYRot()); } public void cancel() { this.interpolationData.steps = 0; this.previousTickPosition = null; this.previousTickRot = null; } private static class InterpolationData { protected int steps; Vec3 position; float yRot; float xRot; private InterpolationData(int steps, Vec3 position, float yRot, float xRot) { this.steps = steps; this.position = position; this.yRot = yRot; this.xRot = xRot; } public void decrease() { --this.steps; } public void addDelta(Vec3 delta) { this.position = this.position.add(delta); } public void addRotation(float yRot, float xRot) { this.yRot += yRot; this.xRot += xRot; } } }