270 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			270 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.core;
 | |
| 
 | |
| import com.google.common.base.MoreObjects;
 | |
| import com.mojang.serialization.Codec;
 | |
| import com.mojang.serialization.DataResult;
 | |
| import io.netty.buffer.ByteBuf;
 | |
| import java.util.stream.IntStream;
 | |
| import net.minecraft.Util;
 | |
| import net.minecraft.network.codec.ByteBufCodecs;
 | |
| import net.minecraft.network.codec.StreamCodec;
 | |
| import net.minecraft.util.Mth;
 | |
| import org.jetbrains.annotations.Unmodifiable;
 | |
| 
 | |
| @Unmodifiable
 | |
| public class Vec3i implements Comparable<Vec3i> {
 | |
| 	public static final Codec<Vec3i> CODEC = Codec.INT_STREAM
 | |
| 		.comapFlatMap(
 | |
| 			intStream -> Util.fixedSize(intStream, 3).map(is -> new Vec3i(is[0], is[1], is[2])),
 | |
| 			vec3i -> IntStream.of(new int[]{vec3i.getX(), vec3i.getY(), vec3i.getZ()})
 | |
| 		);
 | |
| 	public static final StreamCodec<ByteBuf, Vec3i> STREAM_CODEC = StreamCodec.composite(
 | |
| 		ByteBufCodecs.VAR_INT, Vec3i::getX, ByteBufCodecs.VAR_INT, Vec3i::getY, ByteBufCodecs.VAR_INT, Vec3i::getZ, Vec3i::new
 | |
| 	);
 | |
| 	/**
 | |
| 	 * An immutable vector with zero as all coordinates.
 | |
| 	 */
 | |
| 	public static final Vec3i ZERO = new Vec3i(0, 0, 0);
 | |
| 	private int x;
 | |
| 	private int y;
 | |
| 	private int z;
 | |
| 
 | |
| 	public static Codec<Vec3i> offsetCodec(int maxOffset) {
 | |
| 		return CODEC.validate(
 | |
| 			vec3i -> Math.abs(vec3i.getX()) < maxOffset && Math.abs(vec3i.getY()) < maxOffset && Math.abs(vec3i.getZ()) < maxOffset
 | |
| 				? DataResult.success(vec3i)
 | |
| 				: DataResult.error(() -> "Position out of range, expected at most " + maxOffset + ": " + vec3i)
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i(int x, int y, int z) {
 | |
| 		this.x = x;
 | |
| 		this.y = y;
 | |
| 		this.z = z;
 | |
| 	}
 | |
| 
 | |
| 	public boolean equals(Object object) {
 | |
| 		if (this == object) {
 | |
| 			return true;
 | |
| 		} else if (!(object instanceof Vec3i vec3i)) {
 | |
| 			return false;
 | |
| 		} else if (this.getX() != vec3i.getX()) {
 | |
| 			return false;
 | |
| 		} else {
 | |
| 			return this.getY() != vec3i.getY() ? false : this.getZ() == vec3i.getZ();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public int hashCode() {
 | |
| 		return (this.getY() + this.getZ() * 31) * 31 + this.getX();
 | |
| 	}
 | |
| 
 | |
| 	public int compareTo(Vec3i other) {
 | |
| 		if (this.getY() == other.getY()) {
 | |
| 			return this.getZ() == other.getZ() ? this.getX() - other.getX() : this.getZ() - other.getZ();
 | |
| 		} else {
 | |
| 			return this.getY() - other.getY();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public int getX() {
 | |
| 		return this.x;
 | |
| 	}
 | |
| 
 | |
| 	public int getY() {
 | |
| 		return this.y;
 | |
| 	}
 | |
| 
 | |
| 	public int getZ() {
 | |
| 		return this.z;
 | |
| 	}
 | |
| 
 | |
| 	protected Vec3i setX(int x) {
 | |
| 		this.x = x;
 | |
| 		return this;
 | |
| 	}
 | |
| 
 | |
| 	protected Vec3i setY(int y) {
 | |
| 		this.y = y;
 | |
| 		return this;
 | |
| 	}
 | |
| 
 | |
| 	protected Vec3i setZ(int z) {
 | |
| 		this.z = z;
 | |
| 		return this;
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i offset(int dx, int dy, int dz) {
 | |
| 		return dx == 0 && dy == 0 && dz == 0 ? this : new Vec3i(this.getX() + dx, this.getY() + dy, this.getZ() + dz);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i offset(Vec3i vector) {
 | |
| 		return this.offset(vector.getX(), vector.getY(), vector.getZ());
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i subtract(Vec3i vector) {
 | |
| 		return this.offset(-vector.getX(), -vector.getY(), -vector.getZ());
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i multiply(int scalar) {
 | |
| 		if (scalar == 1) {
 | |
| 			return this;
 | |
| 		} else {
 | |
| 			return scalar == 0 ? ZERO : new Vec3i(this.getX() * scalar, this.getY() * scalar, this.getZ() * scalar);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Offset this vector 1 unit up
 | |
| 	 */
 | |
| 	public Vec3i above() {
 | |
| 		return this.above(1);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Offset this vector upwards by the given distance.
 | |
| 	 */
 | |
| 	public Vec3i above(int distance) {
 | |
| 		return this.relative(Direction.UP, distance);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Offset this vector 1 unit down
 | |
| 	 */
 | |
| 	public Vec3i below() {
 | |
| 		return this.below(1);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Offset this vector downwards by the given distance.
 | |
| 	 */
 | |
| 	public Vec3i below(int distance) {
 | |
| 		return this.relative(Direction.DOWN, distance);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i north() {
 | |
| 		return this.north(1);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i north(int distance) {
 | |
| 		return this.relative(Direction.NORTH, distance);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i south() {
 | |
| 		return this.south(1);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i south(int distance) {
 | |
| 		return this.relative(Direction.SOUTH, distance);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i west() {
 | |
| 		return this.west(1);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i west(int distance) {
 | |
| 		return this.relative(Direction.WEST, distance);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i east() {
 | |
| 		return this.east(1);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i east(int distance) {
 | |
| 		return this.relative(Direction.EAST, distance);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i relative(Direction direction) {
 | |
| 		return this.relative(direction, 1);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Offsets this Vector by the given distance in the specified direction.
 | |
| 	 */
 | |
| 	public Vec3i relative(Direction direction, int distance) {
 | |
| 		return distance == 0
 | |
| 			? this
 | |
| 			: new Vec3i(this.getX() + direction.getStepX() * distance, this.getY() + direction.getStepY() * distance, this.getZ() + direction.getStepZ() * distance);
 | |
| 	}
 | |
| 
 | |
| 	public Vec3i relative(Direction.Axis axis, int amount) {
 | |
| 		if (amount == 0) {
 | |
| 			return this;
 | |
| 		} else {
 | |
| 			int i = axis == Direction.Axis.X ? amount : 0;
 | |
| 			int j = axis == Direction.Axis.Y ? amount : 0;
 | |
| 			int k = axis == Direction.Axis.Z ? amount : 0;
 | |
| 			return new Vec3i(this.getX() + i, this.getY() + j, this.getZ() + k);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calculate the cross product of this and the given Vector
 | |
| 	 */
 | |
| 	public Vec3i cross(Vec3i vector) {
 | |
| 		return new Vec3i(
 | |
| 			this.getY() * vector.getZ() - this.getZ() * vector.getY(),
 | |
| 			this.getZ() * vector.getX() - this.getX() * vector.getZ(),
 | |
| 			this.getX() * vector.getY() - this.getY() * vector.getX()
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	public boolean closerThan(Vec3i vector, double distance) {
 | |
| 		return this.distSqr(vector) < Mth.square(distance);
 | |
| 	}
 | |
| 
 | |
| 	public boolean closerToCenterThan(Position position, double distance) {
 | |
| 		return this.distToCenterSqr(position) < Mth.square(distance);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calculate squared distance to the given Vector
 | |
| 	 */
 | |
| 	public double distSqr(Vec3i vector) {
 | |
| 		return this.distToLowCornerSqr(vector.getX(), vector.getY(), vector.getZ());
 | |
| 	}
 | |
| 
 | |
| 	public double distToCenterSqr(Position position) {
 | |
| 		return this.distToCenterSqr(position.x(), position.y(), position.z());
 | |
| 	}
 | |
| 
 | |
| 	public double distToCenterSqr(double x, double y, double z) {
 | |
| 		double d = this.getX() + 0.5 - x;
 | |
| 		double e = this.getY() + 0.5 - y;
 | |
| 		double f = this.getZ() + 0.5 - z;
 | |
| 		return d * d + e * e + f * f;
 | |
| 	}
 | |
| 
 | |
| 	public double distToLowCornerSqr(double x, double y, double z) {
 | |
| 		double d = this.getX() - x;
 | |
| 		double e = this.getY() - y;
 | |
| 		double f = this.getZ() - z;
 | |
| 		return d * d + e * e + f * f;
 | |
| 	}
 | |
| 
 | |
| 	public int distManhattan(Vec3i vector) {
 | |
| 		float f = Math.abs(vector.getX() - this.getX());
 | |
| 		float g = Math.abs(vector.getY() - this.getY());
 | |
| 		float h = Math.abs(vector.getZ() - this.getZ());
 | |
| 		return (int)(f + g + h);
 | |
| 	}
 | |
| 
 | |
| 	public int distChessboard(Vec3i vector) {
 | |
| 		int i = Math.abs(this.getX() - vector.getX());
 | |
| 		int j = Math.abs(this.getY() - vector.getY());
 | |
| 		int k = Math.abs(this.getZ() - vector.getZ());
 | |
| 		return Math.max(Math.max(i, j), k);
 | |
| 	}
 | |
| 
 | |
| 	public int get(Direction.Axis axis) {
 | |
| 		return axis.choose(this.x, this.y, this.z);
 | |
| 	}
 | |
| 
 | |
| 	public String toString() {
 | |
| 		return MoreObjects.toStringHelper(this).add("x", this.getX()).add("y", this.getY()).add("z", this.getZ()).toString();
 | |
| 	}
 | |
| 
 | |
| 	public String toShortString() {
 | |
| 		return this.getX() + ", " + this.getY() + ", " + this.getZ();
 | |
| 	}
 | |
| }
 |