All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.minestom.server.coordinate.Pos Maven / Gradle / Ivy

package net.minestom.server.coordinate;

import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.utils.MathUtils;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

import java.util.function.DoubleUnaryOperator;

/**
 * Represents a position containing coordinates and a view.
 * 

* To become a value then primitive type. */ public record Pos(double x, double y, double z, float yaw, float pitch) implements Point { public static final Pos ZERO = new Pos(0, 0, 0); public Pos { yaw = fixYaw(yaw); } public Pos(double x, double y, double z) { this(x, y, z, 0, 0); } public Pos(@NotNull Point point, float yaw, float pitch) { this(point.x(), point.y(), point.z(), yaw, pitch); } public Pos(@NotNull Point point) { this(point, 0, 0); } /** * Converts a {@link Point} into a {@link Pos}. * Will cast if possible, or instantiate a new object. * * @param point the point to convert * @return the converted position */ public static @NotNull Pos fromPoint(@NotNull Point point) { if (point instanceof Pos pos) return pos; return new Pos(point.x(), point.y(), point.z()); } /** * Changes the 3 coordinates of this position. * * @param x the X coordinate * @param y the Y coordinate * @param z the Z coordinate * @return a new position */ @Contract(pure = true) public @NotNull Pos withCoord(double x, double y, double z) { return new Pos(x, y, z, yaw, pitch); } @Contract(pure = true) public @NotNull Pos withCoord(@NotNull Point point) { return withCoord(point.x(), point.y(), point.z()); } @Contract(pure = true) public @NotNull Pos withView(float yaw, float pitch) { return new Pos(x, y, z, yaw, pitch); } @Contract(pure = true) public @NotNull Pos withView(@NotNull Pos pos) { return withView(pos.yaw(), pos.pitch()); } /** * Sets the yaw and pitch to point * in the direction of the point. */ @Contract(pure = true) public @NotNull Pos withDirection(@NotNull Point point) { /* * Sin = Opp / Hyp * Cos = Adj / Hyp * Tan = Opp / Adj * * x = -Opp * z = Adj */ final double x = point.x(); final double z = point.z(); if (x == 0 && z == 0) { return withPitch(point.y() > 0 ? -90f : 90f); } final double theta = Math.atan2(-x, z); final double xz = Math.sqrt(MathUtils.square(x) + MathUtils.square(z)); final double _2PI = 2 * Math.PI; return withView((float) Math.toDegrees((theta + _2PI) % _2PI), (float) Math.toDegrees(Math.atan(-point.y() / xz))); } @Contract(pure = true) public @NotNull Pos withYaw(float yaw) { return new Pos(x, y, z, yaw, pitch); } @Contract(pure = true) public @NotNull Pos withYaw(@NotNull DoubleUnaryOperator operator) { return withYaw((float) operator.applyAsDouble(yaw)); } @Contract(pure = true) public @NotNull Pos withPitch(float pitch) { return new Pos(x, y, z, yaw, pitch); } @Contract(pure = true) public @NotNull Pos withLookAt(@NotNull Point point) { if (samePoint(point)) return this; final Vec delta = Vec.fromPoint(point.sub(this)).normalize(); return withView(PositionUtils.getLookYaw(delta.x(), delta.z()), PositionUtils.getLookPitch(delta.x(), delta.y(), delta.z())); } @Contract(pure = true) public @NotNull Pos withPitch(@NotNull DoubleUnaryOperator operator) { return withPitch((float) operator.applyAsDouble(pitch)); } /** * Checks if two positions have a similar view (yaw/pitch). * * @param position the position to compare * @return true if the two positions have the same view */ public boolean sameView(@NotNull Pos position) { return sameView(position.yaw(), position.pitch()); } public boolean sameView(float yaw, float pitch) { return Float.compare(this.yaw, yaw) == 0 && Float.compare(this.pitch, pitch) == 0; } /** * Gets a unit-vector pointing in the direction that this Location is * facing. * * @return a vector pointing the direction of this location's {@link * #pitch() pitch} and {@link #yaw() yaw} */ public @NotNull Vec direction() { final float rotX = yaw; final float rotY = pitch; final double xz = Math.cos(Math.toRadians(rotY)); return new Vec(-xz * Math.sin(Math.toRadians(rotX)), -Math.sin(Math.toRadians(rotY)), xz * Math.cos(Math.toRadians(rotX))); } /** * Returns a new position based on this position fields. * * @param operator the operator deconstructing this object and providing a new position * @return the new position */ @Contract(pure = true) public @NotNull Pos apply(@NotNull Operator operator) { return operator.apply(x, y, z, yaw, pitch); } @Override @Contract(pure = true) public @NotNull Pos withX(@NotNull DoubleUnaryOperator operator) { return new Pos(operator.applyAsDouble(x), y, z, yaw, pitch); } @Override @Contract(pure = true) public @NotNull Pos withX(double x) { return new Pos(x, y, z, yaw, pitch); } @Override @Contract(pure = true) public @NotNull Pos withY(@NotNull DoubleUnaryOperator operator) { return new Pos(x, operator.applyAsDouble(y), z, yaw, pitch); } @Override @Contract(pure = true) public @NotNull Pos withY(double y) { return new Pos(x, y, z, yaw, pitch); } @Override @Contract(pure = true) public @NotNull Pos withZ(@NotNull DoubleUnaryOperator operator) { return new Pos(x, y, operator.applyAsDouble(z), yaw, pitch); } @Override @Contract(pure = true) public @NotNull Pos withZ(double z) { return new Pos(x, y, z, yaw, pitch); } @Override public @NotNull Pos add(double x, double y, double z) { return new Pos(this.x + x, this.y + y, this.z + z, yaw, pitch); } @Override public @NotNull Pos add(@NotNull Point point) { return add(point.x(), point.y(), point.z()); } @Override public @NotNull Pos add(double value) { return add(value, value, value); } @Override public @NotNull Pos sub(double x, double y, double z) { return new Pos(this.x - x, this.y - y, this.z - z, yaw, pitch); } @Override public @NotNull Pos sub(@NotNull Point point) { return sub(point.x(), point.y(), point.z()); } @Override public @NotNull Pos sub(double value) { return sub(value, value, value); } @Override public @NotNull Pos mul(double x, double y, double z) { return new Pos(this.x * x, this.y * y, this.z * z, yaw, pitch); } @Override public @NotNull Pos mul(@NotNull Point point) { return mul(point.x(), point.y(), point.z()); } @Override public @NotNull Pos mul(double value) { return mul(value, value, value); } @Override public @NotNull Pos div(double x, double y, double z) { return new Pos(this.x / x, this.y / y, this.z / z, yaw, pitch); } @Override public @NotNull Pos div(@NotNull Point point) { return div(point.x(), point.y(), point.z()); } @Override public @NotNull Pos div(double value) { return div(value, value, value); } @Override public @NotNull Pos relative(@NotNull BlockFace face) { return (Pos) Point.super.relative(face); } @Contract(pure = true) public @NotNull Vec asVec() { return new Vec(x, y, z); } @FunctionalInterface public interface Operator { @NotNull Pos apply(double x, double y, double z, float yaw, float pitch); } /** * Fixes a yaw value that is not between -180.0F and 180.0F * So for example -1355.0F becomes 85.0F and 225.0F becomes -135.0F * * @param yaw The possible "wrong" yaw * @return a fixed yaw */ private static float fixYaw(float yaw) { yaw = yaw % 360; if (yaw < -180.0F) { yaw += 360.0F; } else if (yaw > 180.0F) { yaw -= 360.0F; } return yaw; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy