288 lines
11 KiB
Java
288 lines
11 KiB
Java
/*
|
|
* 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<Vec3> 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));
|
|
}
|
|
}
|
|
}
|
|
|