/* * Decompiled with CFR 0.152. * * Could not load the following classes: * org.joml.Quaternionf * org.joml.Quaternionfc * org.joml.Vector3f * org.joml.Vector3fc */ package net.minecraft.client; import java.util.Arrays; import java.util.List; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.tags.FluidTags; import net.minecraft.util.Mth; import net.minecraft.world.attribute.EnvironmentAttributeProbe; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.vehicle.Minecart; import net.minecraft.world.entity.vehicle.NewMinecartBehavior; import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FogType; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.waypoints.TrackedWaypoint; import org.joml.Quaternionf; import org.joml.Quaternionfc; import org.joml.Vector3f; import org.joml.Vector3fc; public class Camera implements TrackedWaypoint.Camera { private static final float DEFAULT_CAMERA_DISTANCE = 4.0f; private static final Vector3f FORWARDS = new Vector3f(0.0f, 0.0f, -1.0f); private static final Vector3f UP = new Vector3f(0.0f, 1.0f, 0.0f); private static final Vector3f LEFT = new Vector3f(-1.0f, 0.0f, 0.0f); private boolean initialized; private Level level; private Entity entity; private Vec3 position = Vec3.ZERO; private final BlockPos.MutableBlockPos blockPosition = new BlockPos.MutableBlockPos(); private final Vector3f forwards = new Vector3f((Vector3fc)FORWARDS); private final Vector3f up = new Vector3f((Vector3fc)UP); private final Vector3f left = new Vector3f((Vector3fc)LEFT); private float xRot; private float yRot; private final Quaternionf rotation = new Quaternionf(); private boolean detached; private float eyeHeight; private float eyeHeightOld; private float partialTickTime; private final EnvironmentAttributeProbe attributeProbe = new EnvironmentAttributeProbe(); public void setup(Level level, Entity entity, boolean detached, boolean mirror, float a) { NewMinecartBehavior behavior; Minecart minecart; Object object; this.initialized = true; this.level = level; this.entity = entity; this.detached = detached; this.partialTickTime = a; if (entity.isPassenger() && (object = entity.getVehicle()) instanceof Minecart && (object = (minecart = (Minecart)object).getBehavior()) instanceof NewMinecartBehavior && (behavior = (NewMinecartBehavior)object).cartHasPosRotLerp()) { Vec3 positionOffset = minecart.getPassengerRidingPosition(entity).subtract(minecart.position()).subtract(entity.getVehicleAttachmentPoint(minecart)).add(new Vec3(0.0, Mth.lerp(a, this.eyeHeightOld, this.eyeHeight), 0.0)); this.setRotation(entity.getViewYRot(a), entity.getViewXRot(a)); this.setPosition(behavior.getCartLerpPosition(a).add(positionOffset)); } else { this.setRotation(entity.getViewYRot(a), entity.getViewXRot(a)); this.setPosition(Mth.lerp((double)a, entity.xo, entity.getX()), Mth.lerp((double)a, entity.yo, entity.getY()) + (double)Mth.lerp(a, this.eyeHeightOld, this.eyeHeight), Mth.lerp((double)a, entity.zo, entity.getZ())); } if (detached) { Entity entity2; if (mirror) { this.setRotation(this.yRot + 180.0f, -this.xRot); } float cameraDistance = 4.0f; float cameraScale = 1.0f; if (entity instanceof LivingEntity) { LivingEntity living = (LivingEntity)entity; cameraScale = living.getScale(); cameraDistance = (float)living.getAttributeValue(Attributes.CAMERA_DISTANCE); } float mountScale = cameraScale; float mountDistance = cameraDistance; if (entity.isPassenger() && (entity2 = entity.getVehicle()) instanceof LivingEntity) { LivingEntity mount = (LivingEntity)entity2; mountScale = mount.getScale(); mountDistance = (float)mount.getAttributeValue(Attributes.CAMERA_DISTANCE); } this.move(-this.getMaxZoom(Math.max(cameraScale * cameraDistance, mountScale * mountDistance)), 0.0f, 0.0f); } else if (entity instanceof LivingEntity && ((LivingEntity)entity).isSleeping()) { Direction bedOrientation = ((LivingEntity)entity).getBedOrientation(); this.setRotation(bedOrientation != null ? bedOrientation.toYRot() - 180.0f : 0.0f, 0.0f); this.move(0.0f, 0.3f, 0.0f); } } public void tick() { if (this.entity != null) { this.eyeHeightOld = this.eyeHeight; this.eyeHeight += (this.entity.getEyeHeight() - this.eyeHeight) * 0.5f; this.attributeProbe.tick(this.level, this.position); } } private float getMaxZoom(float cameraDist) { float jitterScale = 0.1f; for (int i = 0; i < 8; ++i) { float distSq; Vec3 to; float offsetX = (i & 1) * 2 - 1; float offsetY = (i >> 1 & 1) * 2 - 1; float offsetZ = (i >> 2 & 1) * 2 - 1; Vec3 from = this.position.add(offsetX * 0.1f, offsetY * 0.1f, offsetZ * 0.1f); BlockHitResult hitResult = this.level.clip(new ClipContext(from, to = from.add(new Vec3((Vector3fc)this.forwards).scale(-cameraDist)), ClipContext.Block.VISUAL, ClipContext.Fluid.NONE, this.entity)); if (((HitResult)hitResult).getType() == HitResult.Type.MISS || !((distSq = (float)hitResult.getLocation().distanceToSqr(this.position)) < Mth.square(cameraDist))) continue; cameraDist = Mth.sqrt(distSq); } return cameraDist; } protected void move(float forwards, float up, float right) { Vector3f offset = new Vector3f(right, up, -forwards).rotate((Quaternionfc)this.rotation); this.setPosition(new Vec3(this.position.x + (double)offset.x, this.position.y + (double)offset.y, this.position.z + (double)offset.z)); } protected void setRotation(float yRot, float xRot) { this.xRot = xRot; this.yRot = yRot; this.rotation.rotationYXZ((float)Math.PI - yRot * ((float)Math.PI / 180), -xRot * ((float)Math.PI / 180), 0.0f); FORWARDS.rotate((Quaternionfc)this.rotation, this.forwards); UP.rotate((Quaternionfc)this.rotation, this.up); LEFT.rotate((Quaternionfc)this.rotation, this.left); } protected void setPosition(double x, double y, double z) { this.setPosition(new Vec3(x, y, z)); } protected void setPosition(Vec3 position) { this.position = position; this.blockPosition.set(position.x, position.y, position.z); } @Override public Vec3 position() { return this.position; } public BlockPos blockPosition() { return this.blockPosition; } public float xRot() { return this.xRot; } public float yRot() { return this.yRot; } @Override public float yaw() { return Mth.wrapDegrees(this.yRot()); } public Quaternionf rotation() { return this.rotation; } public Entity entity() { return this.entity; } public boolean isInitialized() { return this.initialized; } public boolean isDetached() { return this.detached; } public EnvironmentAttributeProbe attributeProbe() { return this.attributeProbe; } public NearPlane getNearPlane() { Minecraft minecraft = Minecraft.getInstance(); double aspectRatio = (double)minecraft.getWindow().getWidth() / (double)minecraft.getWindow().getHeight(); double planeHeight = Math.tan((double)((float)minecraft.options.fov().get().intValue() * ((float)Math.PI / 180)) / 2.0) * (double)0.05f; double planeWidth = planeHeight * aspectRatio; Vec3 forwardsVec3 = new Vec3((Vector3fc)this.forwards).scale(0.05f); Vec3 leftVec3 = new Vec3((Vector3fc)this.left).scale(planeWidth); Vec3 upVec3 = new Vec3((Vector3fc)this.up).scale(planeHeight); return new NearPlane(forwardsVec3, leftVec3, upVec3); } public FogType getFluidInCamera() { if (!this.initialized) { return FogType.NONE; } FluidState fluidState1 = this.level.getFluidState(this.blockPosition); if (fluidState1.is(FluidTags.WATER) && this.position.y < (double)((float)this.blockPosition.getY() + fluidState1.getHeight(this.level, this.blockPosition))) { return FogType.WATER; } NearPlane plane = this.getNearPlane(); List points = Arrays.asList(plane.forward, plane.getTopLeft(), plane.getTopRight(), plane.getBottomLeft(), plane.getBottomRight()); for (Vec3 point : points) { Vec3 offsetPos = this.position.add(point); BlockPos checkPos = BlockPos.containing(offsetPos); FluidState fluidState = this.level.getFluidState(checkPos); if (fluidState.is(FluidTags.LAVA)) { if (!(offsetPos.y <= (double)(fluidState.getHeight(this.level, checkPos) + (float)checkPos.getY()))) continue; return FogType.LAVA; } BlockState state = this.level.getBlockState(checkPos); if (!state.is(Blocks.POWDER_SNOW)) continue; return FogType.POWDER_SNOW; } return FogType.NONE; } public Vector3fc forwardVector() { return this.forwards; } public Vector3fc upVector() { return this.up; } public Vector3fc leftVector() { return this.left; } public void reset() { this.level = null; this.entity = null; this.attributeProbe.reset(); this.initialized = false; } public float getPartialTickTime() { return this.partialTickTime; } public static class NearPlane { private final Vec3 forward; private final Vec3 left; private final Vec3 up; private NearPlane(Vec3 forward, Vec3 left, Vec3 up) { this.forward = forward; this.left = left; this.up = up; } public Vec3 getTopLeft() { return this.forward.add(this.up).add(this.left); } public Vec3 getTopRight() { return this.forward.add(this.up).subtract(this.left); } public Vec3 getBottomLeft() { return this.forward.subtract(this.up).add(this.left); } public Vec3 getBottomRight() { return this.forward.subtract(this.up).subtract(this.left); } public Vec3 getPointOnPlane(float x, float y) { return this.forward.add(this.up.scale(y)).subtract(this.left.scale(x)); } } }