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();
|
|
}
|
|
}
|