|
|
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
|
|
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
|
|
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
|
|
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
|
|
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
|
|
|
// Magicbane Emulator Project © 2013 - 2022
|
|
|
|
// www.magicbane.com
|
|
|
|
|
|
|
|
package engine.math;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.ObjectInput;
|
|
|
|
import java.io.ObjectOutput;
|
|
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
|
|
|
|
|
|
import static engine.math.FastMath.sqr;
|
|
|
|
|
|
|
|
public class Vector3fImmutable {
|
|
|
|
|
|
|
|
public static final Vector3fImmutable ZERO = new Vector3fImmutable(0, 0, 0);
|
|
|
|
public final float x, y, z;
|
|
|
|
|
|
|
|
public Vector3fImmutable() {
|
|
|
|
x = y = z = 0.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable(float x, float y, float z) {
|
|
|
|
this.x = x;
|
|
|
|
this.y = y;
|
|
|
|
this.z = z;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable(Vector3f original) {
|
|
|
|
this.x = original.x;
|
|
|
|
this.y = original.y;
|
|
|
|
this.z = original.z;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable(Vector3fImmutable original) {
|
|
|
|
this.x = original.x;
|
|
|
|
this.y = original.y;
|
|
|
|
this.z = original.z;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector3fImmutable scaleAdd(float scalar, Vector3fImmutable mult,
|
|
|
|
Vector3fImmutable add) {
|
|
|
|
return new Vector3fImmutable(mult.x * scalar + add.x, mult.y * scalar
|
|
|
|
+ add.y, mult.z * scalar + add.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isValidVector(Vector3fImmutable vector) {
|
|
|
|
if (vector == null)
|
|
|
|
return false;
|
|
|
|
if (Float.isNaN(vector.x) || Float.isNaN(vector.y)
|
|
|
|
|| Float.isNaN(vector.z))
|
|
|
|
return false;
|
|
|
|
return !Float.isInfinite(vector.x) && !Float.isInfinite(vector.y)
|
|
|
|
&& !Float.isInfinite(vector.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector3fImmutable readExternal(ObjectInput in)
|
|
|
|
throws IOException, ClassNotFoundException {
|
|
|
|
return new Vector3fImmutable(in.readFloat(), in.readFloat(), in
|
|
|
|
.readFloat());
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String toString(Vector3fImmutable vector) {
|
|
|
|
|
|
|
|
return vector.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector3fImmutable ClosestPointOnLine(Vector3fImmutable lineStart, Vector3fImmutable lineEnd, Vector3fImmutable sourcePoint) {
|
|
|
|
|
|
|
|
Vector3fImmutable closestPoint;
|
|
|
|
Vector3fImmutable lineStartToTarget;
|
|
|
|
Vector3fImmutable lineDirection;
|
|
|
|
float lineLength;
|
|
|
|
float dotProduct;
|
|
|
|
|
|
|
|
lineStartToTarget = sourcePoint.subtract(lineStart);
|
|
|
|
lineDirection = lineEnd.subtract(lineStart).normalize();
|
|
|
|
lineLength = lineStart.distance2D(lineEnd);
|
|
|
|
|
|
|
|
dotProduct = lineDirection.dot(lineStartToTarget);
|
|
|
|
|
|
|
|
if (dotProduct <= 0)
|
|
|
|
return lineStart;
|
|
|
|
|
|
|
|
if (dotProduct >= lineLength)
|
|
|
|
return lineEnd;
|
|
|
|
|
|
|
|
// Project the point by advancing it along the line from
|
|
|
|
// the starting point.
|
|
|
|
|
|
|
|
closestPoint = lineDirection.mult(dotProduct);
|
|
|
|
closestPoint = lineStart.add(closestPoint);
|
|
|
|
|
|
|
|
return closestPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector3fImmutable rotateAroundPoint(Vector3fImmutable origin, Vector3fImmutable point, int angle) {
|
|
|
|
|
|
|
|
float angleRadians;
|
|
|
|
int modifiedAngle;
|
|
|
|
|
|
|
|
// Convert angle to radians
|
|
|
|
|
|
|
|
modifiedAngle = angle;
|
|
|
|
|
|
|
|
if (angle < 0)
|
|
|
|
modifiedAngle = 360 + modifiedAngle;
|
|
|
|
|
|
|
|
angleRadians = (float) Math.toRadians(modifiedAngle);
|
|
|
|
|
|
|
|
return rotateAroundPoint(origin, point, angleRadians);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector3fImmutable rotateAroundPoint(Vector3fImmutable origin, Vector3fImmutable point, float radians) {
|
|
|
|
|
|
|
|
Vector3fImmutable outVector;
|
|
|
|
Vector3f directionVector;
|
|
|
|
Quaternion angleRotation;
|
|
|
|
|
|
|
|
// Build direction vector relative to origin
|
|
|
|
|
|
|
|
directionVector = new Vector3f(point.subtract(origin));
|
|
|
|
|
|
|
|
// Build quaternion rotation
|
|
|
|
|
|
|
|
angleRotation = new Quaternion().fromAngleAxis(radians, new Vector3f(0, 1, 0));
|
|
|
|
// Apply rotation to direction vector
|
|
|
|
|
|
|
|
directionVector = angleRotation.mult(directionVector);
|
|
|
|
|
|
|
|
// Translate from origin back to new rotated point
|
|
|
|
|
|
|
|
outVector = origin.add(directionVector);
|
|
|
|
|
|
|
|
return outVector;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector3fImmutable rotateAroundPoint(Vector3fImmutable origin, Vector3fImmutable point, Quaternion angleRotation) {
|
|
|
|
|
|
|
|
Vector3fImmutable outVector;
|
|
|
|
Vector3f directionVector;
|
|
|
|
// Build direction vector relative to origin
|
|
|
|
directionVector = new Vector3f(point.subtract(origin));
|
|
|
|
|
|
|
|
// Build quaternion rotation
|
|
|
|
|
|
|
|
|
|
|
|
// Apply rotation to direction vector
|
|
|
|
|
|
|
|
|
|
|
|
directionVector = angleRotation.mult(directionVector);
|
|
|
|
|
|
|
|
// Translate from origin back to new rotated point
|
|
|
|
|
|
|
|
outVector = origin.add(directionVector);
|
|
|
|
|
|
|
|
return outVector;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector3fImmutable rotateAroundPoint(Vector3fImmutable origin, Vector3fImmutable point, float w, Vector3f axis) {
|
|
|
|
|
|
|
|
Vector3fImmutable outVector;
|
|
|
|
Vector3f directionVector;
|
|
|
|
Quaternion angleRotation;
|
|
|
|
|
|
|
|
// Build direction vector relative to origin
|
|
|
|
|
|
|
|
directionVector = new Vector3f(point.subtract(origin));
|
|
|
|
|
|
|
|
// Build quaternion rotation
|
|
|
|
|
|
|
|
angleRotation = new Quaternion().fromAngleAxis(w, axis);
|
|
|
|
// Apply rotation to direction vector
|
|
|
|
|
|
|
|
directionVector = angleRotation.mult(directionVector);
|
|
|
|
|
|
|
|
// Translate from origin back to new rotated point
|
|
|
|
|
|
|
|
outVector = origin.add(directionVector);
|
|
|
|
|
|
|
|
return outVector;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector3fImmutable getRandomPointInCircle(Vector3fImmutable origin, float radius) {
|
|
|
|
// Member variables
|
|
|
|
|
|
|
|
float targetAngle;
|
|
|
|
float targetRadius;
|
|
|
|
Vector3fImmutable targetPosition;
|
|
|
|
|
|
|
|
targetAngle = (float) (ThreadLocalRandom.current().nextFloat() * Math.PI * 2);
|
|
|
|
targetRadius = (float) (Math.sqrt(ThreadLocalRandom.current().nextFloat()) * radius);
|
|
|
|
targetPosition = new Vector3fImmutable((float) (origin.x + targetRadius * Math.cos(targetAngle)), origin.y, (float) (origin.z + targetRadius * Math.sin(targetAngle)));
|
|
|
|
return targetPosition;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector3fImmutable getLocBetween(Vector3fImmutable start, Vector3fImmutable end) {
|
|
|
|
// Member variables
|
|
|
|
|
|
|
|
Vector3fImmutable faceDirection = end.subtract(start).normalize();
|
|
|
|
float distance = end.distance(start) * .5f;
|
|
|
|
return faceDirection.scaleAdd(distance, start);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector3fImmutable getRandomPointOnCircle(Vector3fImmutable origin, float radius) {
|
|
|
|
|
|
|
|
// Member variables
|
|
|
|
|
|
|
|
int randomAngle;
|
|
|
|
Vector3fImmutable targetPosition;
|
|
|
|
|
|
|
|
randomAngle = ThreadLocalRandom.current().nextInt(360);
|
|
|
|
|
|
|
|
targetPosition = new Vector3fImmutable((float) (origin.x + radius * Math.cos(randomAngle)), origin.y, (float) (origin.z + radius * Math.sin(randomAngle)));
|
|
|
|
return targetPosition;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector3fImmutable transform(Vector3fImmutable origin, Vector3fImmutable point, float angle) {
|
|
|
|
|
|
|
|
//TRANSLATE TO ORIGIN
|
|
|
|
float x1 = point.x - origin.x;
|
|
|
|
float y1 = point.z - origin.z;
|
|
|
|
|
|
|
|
//APPLY ROTATION
|
|
|
|
float temp_x1 = (float) (x1 * Math.cos(angle) - y1 * Math.sin(angle));
|
|
|
|
float temp_z1 = (float) (x1 * Math.sin(angle) + y1 * Math.cos(angle));
|
|
|
|
|
|
|
|
temp_x1 += origin.x;
|
|
|
|
temp_z1 += origin.z;
|
|
|
|
|
|
|
|
return new Vector3fImmutable(temp_x1, point.y, temp_z1);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isInsideCircle(Vector3fImmutable circleCenter, float radius) {
|
|
|
|
|
|
|
|
return (circleCenter.distanceSquared2D(this) < sqr(radius));
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable add(Vector3f vec) {
|
|
|
|
if (null == vec)
|
|
|
|
return null;
|
|
|
|
return new Vector3fImmutable(x + vec.x, y + vec.y, z + vec.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable add(Vector3fImmutable vec) {
|
|
|
|
if (null == vec)
|
|
|
|
return null;
|
|
|
|
return new Vector3fImmutable(x + vec.x, y + vec.y, z + vec.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable add(float x, float y, float z) {
|
|
|
|
return new Vector3fImmutable(this.x + x, this.y + y, this.z + z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable scaleAdd(float scalar, Vector3fImmutable add) {
|
|
|
|
return new Vector3fImmutable(x * scalar + add.x, y * scalar + add.y, z
|
|
|
|
* scalar + add.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float dot(Vector3fImmutable vec) {
|
|
|
|
if (null == vec) {
|
|
|
|
return 0.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
return x * vec.x + y * vec.y + z * vec.z;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float dot2D(Vector3fImmutable vec) {
|
|
|
|
if (null == vec) {
|
|
|
|
return 0.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
return x * vec.x + z * vec.z;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable cross(Vector3fImmutable v) {
|
|
|
|
return cross(v.x, v.y, v.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable cross(float x, float y, float z) {
|
|
|
|
return new Vector3fImmutable(this.y * z - this.z * y, this.z * x
|
|
|
|
- this.x * z, this.x * y - this.y * x);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float length() {
|
|
|
|
return FastMath.sqrt(lengthSquared());
|
|
|
|
}
|
|
|
|
|
|
|
|
public float lengthSquared() {
|
|
|
|
return x * x + y * y + z * z;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float distanceSquared(Vector3fImmutable v) {
|
|
|
|
double dx = x - v.x;
|
|
|
|
double dy = y - v.y;
|
|
|
|
double dz = z - v.z;
|
|
|
|
return (float) (dx * dx + dy * dy + dz * dz);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float magnitude() {
|
|
|
|
return FastMath.sqrt(sqrMagnitude());
|
|
|
|
}
|
|
|
|
|
|
|
|
public float sqrMagnitude() {
|
|
|
|
return x * x + y * y + z * z;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable moveTowards(Vector3fImmutable target, float maxDistanceDelta) {
|
|
|
|
Vector3fImmutable outVector;
|
|
|
|
|
|
|
|
Vector3fImmutable direction = target.subtract2D(this);
|
|
|
|
float magnitude = direction.magnitude();
|
|
|
|
|
|
|
|
if (magnitude <= maxDistanceDelta || magnitude == 0f) {
|
|
|
|
return target;
|
|
|
|
}
|
|
|
|
|
|
|
|
outVector = direction.divide(magnitude).mult(maxDistanceDelta);
|
|
|
|
outVector = this.add(outVector);
|
|
|
|
return outVector;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float distanceSquared2D(Vector3fImmutable v) {
|
|
|
|
double dx = x - v.x;
|
|
|
|
double dz = z - v.z;
|
|
|
|
return (float) (dx * dx + dz * dz);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float distance(Vector3fImmutable v) {
|
|
|
|
return FastMath.sqrt(distanceSquared(v));
|
|
|
|
}
|
|
|
|
|
|
|
|
public float distance2D(Vector3fImmutable v) {
|
|
|
|
return FastMath.sqrt(distanceSquared2D(v));
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable mult(float scalar) {
|
|
|
|
return new Vector3fImmutable(x * scalar, y * scalar, z * scalar);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable mult(Vector3fImmutable vec) {
|
|
|
|
if (null == vec) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new Vector3fImmutable(x * vec.x, y * vec.y, z * vec.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable divide(float scalar) {
|
|
|
|
scalar = 1f / scalar;
|
|
|
|
return new Vector3fImmutable(x * scalar, y * scalar, z * scalar);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable divide(Vector3fImmutable scalar) {
|
|
|
|
return new Vector3fImmutable(x / scalar.x, y / scalar.y, z / scalar.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable negate() {
|
|
|
|
return new Vector3fImmutable(-x, -y, -z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable subtract(Vector3fImmutable vec) {
|
|
|
|
return new Vector3fImmutable(x - vec.x, y - vec.y, z - vec.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable subtract2D(Vector3fImmutable vec) {
|
|
|
|
return new Vector3fImmutable(x - vec.x, 0, z - vec.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable subtract(float x, float y, float z) {
|
|
|
|
return new Vector3fImmutable(this.x - x, this.y - y, this.z - z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable normalize() {
|
|
|
|
float length = length();
|
|
|
|
if (length != 0) {
|
|
|
|
return divide(length);
|
|
|
|
}
|
|
|
|
|
|
|
|
return divide(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float angleBetween(Vector3fImmutable otherVector) {
|
|
|
|
float dotProduct = dot(otherVector);
|
|
|
|
return FastMath.acos(dotProduct);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float angleBetween2D(Vector3fImmutable otherVector) {
|
|
|
|
float dotProduct = dot(otherVector);
|
|
|
|
return FastMath.acos(dotProduct);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable interpolate(Vector3f finalVec, float changeAmnt) {
|
|
|
|
return new Vector3fImmutable((1 - changeAmnt) * this.x + changeAmnt
|
|
|
|
* finalVec.x, (1 - changeAmnt) * this.y + changeAmnt
|
|
|
|
* finalVec.y, (1 - changeAmnt) * this.z + changeAmnt
|
|
|
|
* finalVec.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable interpolate(Vector3fImmutable finalVec, float changeAmnt) {
|
|
|
|
return new Vector3fImmutable((1 - changeAmnt) * this.x + changeAmnt
|
|
|
|
* finalVec.x, (1 - changeAmnt) * this.y + changeAmnt
|
|
|
|
* finalVec.y, (1 - changeAmnt) * this.z + changeAmnt
|
|
|
|
* finalVec.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Vector3fImmutable clone() throws CloneNotSupportedException {
|
|
|
|
return (Vector3fImmutable) super.clone();
|
|
|
|
}
|
|
|
|
|
|
|
|
public float[] toArray(float[] floats) {
|
|
|
|
if (floats == null) {
|
|
|
|
floats = new float[3];
|
|
|
|
}
|
|
|
|
floats[0] = x;
|
|
|
|
floats[1] = y;
|
|
|
|
floats[2] = z;
|
|
|
|
return floats;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object o) {
|
|
|
|
if (!(o instanceof Vector3fImmutable)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this == o) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector3fImmutable comp = (Vector3fImmutable) o;
|
|
|
|
if (Float.compare(x, comp.x) != 0)
|
|
|
|
return false;
|
|
|
|
if (Float.compare(y, comp.y) != 0)
|
|
|
|
return false;
|
|
|
|
return Float.compare(z, comp.z) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
int hash = 37;
|
|
|
|
hash += 37 * hash + Float.floatToIntBits(x);
|
|
|
|
hash += 37 * hash + Float.floatToIntBits(y);
|
|
|
|
hash += 37 * hash + Float.floatToIntBits(z);
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void writeExternal(ObjectOutput out) throws IOException {
|
|
|
|
out.writeFloat(x);
|
|
|
|
out.writeFloat(y);
|
|
|
|
out.writeFloat(z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable getOffset(float rotation, float xOffset, float yOffset, float zOffset, boolean invertZ) {
|
|
|
|
float sin = FastMath.sin(rotation);
|
|
|
|
float cos = FastMath.cos(rotation);
|
|
|
|
Vector3f faceDir = new Vector3f(sin, 0f, cos);
|
|
|
|
Vector3f crossDir = new Vector3f(cos, 0f, sin);
|
|
|
|
faceDir.multLocal(zOffset);
|
|
|
|
crossDir.multLocal(xOffset);
|
|
|
|
if (invertZ) {
|
|
|
|
faceDir.z = -faceDir.z;
|
|
|
|
crossDir.z = -crossDir.z;
|
|
|
|
}
|
|
|
|
Vector3f loc = new Vector3f(this);
|
|
|
|
loc.addLocal(faceDir);
|
|
|
|
loc.addLocal(crossDir);
|
|
|
|
loc.y += yOffset;
|
|
|
|
return new Vector3fImmutable(loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getX() {
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable setX(float x) {
|
|
|
|
return new Vector3fImmutable(x, y, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getY() {
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable setY(float y) {
|
|
|
|
return new Vector3fImmutable(x, y, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getZ() {
|
|
|
|
return z;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable setZ(float z) {
|
|
|
|
return new Vector3fImmutable(x, y, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float get(int index) {
|
|
|
|
switch (index) {
|
|
|
|
case 0:
|
|
|
|
return x;
|
|
|
|
case 1:
|
|
|
|
return y;
|
|
|
|
case 2:
|
|
|
|
return z;
|
|
|
|
}
|
|
|
|
throw new IllegalArgumentException("index must be either 0, 1 or 2");
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector2f getLatLong() {
|
|
|
|
return new Vector2f(this.x, this.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public synchronized float getLat() {
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
public synchronized float getLong() {
|
|
|
|
return z;
|
|
|
|
}
|
|
|
|
|
|
|
|
public synchronized float getAlt() {
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getRotation() {
|
|
|
|
return 3.14f + FastMath.atan2(-x, -z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean inRange2D(Vector3fImmutable otherVec, float range) {
|
|
|
|
float distance = this.distanceSquared2D(otherVec);
|
|
|
|
return !(distance > range * range);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
|
|
|
|
String outString;
|
|
|
|
|
|
|
|
outString = "(" + this.x + '/' + this.y + '/' + this.z;
|
|
|
|
return outString;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public String toString2D() {
|
|
|
|
|
|
|
|
String outString;
|
|
|
|
|
|
|
|
outString = "( " + (int) this.x + " , " + (int) (this.z * -1) + " )";
|
|
|
|
return outString;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public Vector3fImmutable ClosestPointOnLine(Vector3fImmutable lineStart, Vector3fImmutable lineEnd) {
|
|
|
|
|
|
|
|
Vector3fImmutable closestPoint;
|
|
|
|
Vector3fImmutable lineStartToTarget;
|
|
|
|
Vector3fImmutable lineDirection;
|
|
|
|
float lineLength;
|
|
|
|
float dotProduct;
|
|
|
|
|
|
|
|
lineStartToTarget = this.subtract(lineStart);
|
|
|
|
lineDirection = lineEnd.subtract(lineStart).normalize();
|
|
|
|
lineLength = lineStart.distance2D(lineEnd);
|
|
|
|
|
|
|
|
dotProduct = lineDirection.dot(lineStartToTarget);
|
|
|
|
|
|
|
|
if (dotProduct <= 0)
|
|
|
|
return lineStart;
|
|
|
|
|
|
|
|
if (dotProduct >= lineLength)
|
|
|
|
return lineEnd;
|
|
|
|
|
|
|
|
// Project the point by advancing it along the line from
|
|
|
|
// the starting point.
|
|
|
|
|
|
|
|
closestPoint = lineDirection.mult(dotProduct);
|
|
|
|
closestPoint = lineStart.add(closestPoint);
|
|
|
|
|
|
|
|
return closestPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float Lerp(Vector3fImmutable dest, float lerpFactor) {
|
|
|
|
return dest.subtract(this).mult(lerpFactor).add(this).y;
|
|
|
|
}
|
|
|
|
}
|