mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-02-27 04:04:40 +01:00
Repack JOML
This commit is contained in:
parent
f4cdbb73f7
commit
6c40b8be0b
83 changed files with 155794 additions and 2 deletions
|
@ -101,8 +101,6 @@ repositories {
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||||
|
|
||||||
//implementation 'org.joml:joml:1.10.1'
|
|
||||||
|
|
||||||
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
||||||
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
||||||
// This allows 'Settings > Build, Execution, and Deployment > Build Tools > Gradle > Build and run using' set to IntelliJ to work correctly
|
// This allows 'Settings > Build, Execution, and Deployment > Build Tools > Gradle > Build and run using' set to IntelliJ to work correctly
|
||||||
|
|
906
src/main/java/com/jozufozu/flywheel/repack/joml/AxisAngle4d.java
Normal file
906
src/main/java/com/jozufozu/flywheel/repack/joml/AxisAngle4d.java
Normal file
|
@ -0,0 +1,906 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 Kai Burjack
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.io.Externalizable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a 3D rotation of a given radians about an axis represented as an
|
||||||
|
* unit 3D vector.
|
||||||
|
* <p>
|
||||||
|
* This class uses double-precision components.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class AxisAngle4d implements Externalizable, Cloneable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The angle in radians.
|
||||||
|
*/
|
||||||
|
public double angle;
|
||||||
|
/**
|
||||||
|
* The x-component of the rotation axis.
|
||||||
|
*/
|
||||||
|
public double x;
|
||||||
|
/**
|
||||||
|
* The y-component of the rotation axis.
|
||||||
|
*/
|
||||||
|
public double y;
|
||||||
|
/**
|
||||||
|
* The z-component of the rotation axis.
|
||||||
|
*/
|
||||||
|
public double z;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4d} with zero rotation about <code>(0, 0, 1)</code>.
|
||||||
|
*/
|
||||||
|
public AxisAngle4d() {
|
||||||
|
z = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4d} with the same values of <code>a</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the AngleAxis4d to copy the values from
|
||||||
|
*/
|
||||||
|
public AxisAngle4d(AxisAngle4d a) {
|
||||||
|
x = a.x;
|
||||||
|
y = a.y;
|
||||||
|
z = a.z;
|
||||||
|
angle = (a.angle < 0.0 ? Math.PI + Math.PI + a.angle % (Math.PI + Math.PI) : a.angle) % (Math.PI + Math.PI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4d} with the same values of <code>a</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the AngleAxis4f to copy the values from
|
||||||
|
*/
|
||||||
|
public AxisAngle4d(AxisAngle4f a) {
|
||||||
|
x = a.x;
|
||||||
|
y = a.y;
|
||||||
|
z = a.z;
|
||||||
|
angle = (a.angle < 0.0 ? Math.PI + Math.PI + a.angle % (Math.PI + Math.PI) : a.angle) % (Math.PI + Math.PI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4d} from the given {@link Quaternionfc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href=
|
||||||
|
* "http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/"
|
||||||
|
* >http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param q
|
||||||
|
* the quaternion from which to create the new AngleAxis4f
|
||||||
|
*/
|
||||||
|
public AxisAngle4d(Quaternionfc q) {
|
||||||
|
float acos = Math.safeAcos(q.w());
|
||||||
|
float invSqrt = Math.invsqrt(1.0f - q.w() * q.w());
|
||||||
|
if (Float.isInfinite(invSqrt)) {
|
||||||
|
this.x = 0.0;
|
||||||
|
this.y = 0.0;
|
||||||
|
this.z = 1.0;
|
||||||
|
} else {
|
||||||
|
this.x = q.x() * invSqrt;
|
||||||
|
this.y = q.y() * invSqrt;
|
||||||
|
this.z = q.z() * invSqrt;
|
||||||
|
}
|
||||||
|
this.angle = acos + acos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4d} from the given {@link Quaterniondc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href=
|
||||||
|
* "http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/"
|
||||||
|
* >http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param q
|
||||||
|
* the quaternion from which to create the new AngleAxis4d
|
||||||
|
*/
|
||||||
|
public AxisAngle4d(Quaterniondc q) {
|
||||||
|
double acos = Math.safeAcos(q.w());
|
||||||
|
double invSqrt = Math.invsqrt(1.0 - q.w() * q.w());
|
||||||
|
if (Double.isInfinite(invSqrt)) {
|
||||||
|
this.x = 0.0;
|
||||||
|
this.y = 0.0;
|
||||||
|
this.z = 1.0;
|
||||||
|
} else {
|
||||||
|
this.x = q.x() * invSqrt;
|
||||||
|
this.y = q.y() * invSqrt;
|
||||||
|
this.z = q.z() * invSqrt;
|
||||||
|
}
|
||||||
|
this.angle = acos + acos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4d} with the given values.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param x
|
||||||
|
* the x-coordinate of the rotation axis
|
||||||
|
* @param y
|
||||||
|
* the y-coordinate of the rotation axis
|
||||||
|
* @param z
|
||||||
|
* the z-coordinate of the rotation axis
|
||||||
|
*/
|
||||||
|
public AxisAngle4d(double angle, double x, double y, double z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.angle = (angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4d} with the given values.
|
||||||
|
*
|
||||||
|
* @param angle the angle in radians
|
||||||
|
* @param v the rotation axis as a {@link Vector3dc}
|
||||||
|
*/
|
||||||
|
public AxisAngle4d(double angle, Vector3dc v) {
|
||||||
|
this(angle, v.x(), v.y(), v.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4d} with the given values.
|
||||||
|
*
|
||||||
|
* @param angle the angle in radians
|
||||||
|
* @param v the rotation axis as a {@link Vector3f}
|
||||||
|
*/
|
||||||
|
public AxisAngle4d(double angle, Vector3f v) {
|
||||||
|
this(angle, v.x, v.y, v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to the values of <code>a</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the AngleAxis4f to copy the values from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(AxisAngle4d a) {
|
||||||
|
x = a.x;
|
||||||
|
y = a.y;
|
||||||
|
z = a.z;
|
||||||
|
angle = (a.angle < 0.0 ? Math.PI + Math.PI + a.angle % (Math.PI + Math.PI) : a.angle) % (Math.PI + Math.PI);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to the values of <code>a</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the AngleAxis4f to copy the values from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(AxisAngle4f a) {
|
||||||
|
x = a.x;
|
||||||
|
y = a.y;
|
||||||
|
z = a.z;
|
||||||
|
angle = (a.angle < 0.0 ? Math.PI + Math.PI + a.angle % (Math.PI + Math.PI) : a.angle) % (Math.PI + Math.PI);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to the given values.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param x
|
||||||
|
* the x-coordinate of the rotation axis
|
||||||
|
* @param y
|
||||||
|
* the y-coordinate of the rotation axis
|
||||||
|
* @param z
|
||||||
|
* the z-coordinate of the rotation axis
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(double angle, double x, double y, double z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.angle = (angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to the given values.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param v
|
||||||
|
* the rotation axis as a {@link Vector3dc}
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(double angle, Vector3dc v) {
|
||||||
|
return set(angle, v.x(), v.y(), v.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to the given values.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param v
|
||||||
|
* the rotation axis as a {@link Vector3f}
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(double angle, Vector3f v) {
|
||||||
|
return set(angle, v.x, v.y, v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to be equivalent to the given
|
||||||
|
* {@link Quaternionfc}.
|
||||||
|
*
|
||||||
|
* @param q
|
||||||
|
* the quaternion to set this AngleAxis4d from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(Quaternionfc q) {
|
||||||
|
float acos = Math.safeAcos(q.w());
|
||||||
|
float invSqrt = Math.invsqrt(1.0f - q.w() * q.w());
|
||||||
|
if (Float.isInfinite(invSqrt)) {
|
||||||
|
this.x = 0.0;
|
||||||
|
this.y = 0.0;
|
||||||
|
this.z = 1.0;
|
||||||
|
} else {
|
||||||
|
this.x = q.x() * invSqrt;
|
||||||
|
this.y = q.y() * invSqrt;
|
||||||
|
this.z = q.z() * invSqrt;
|
||||||
|
}
|
||||||
|
this.angle = acos + acos;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to be equivalent to the given
|
||||||
|
* {@link Quaterniondc}.
|
||||||
|
*
|
||||||
|
* @param q
|
||||||
|
* the quaternion to set this AngleAxis4d from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(Quaterniondc q) {
|
||||||
|
double acos = Math.safeAcos(q.w());
|
||||||
|
double invSqrt = Math.invsqrt(1.0f - q.w() * q.w());
|
||||||
|
if (Double.isInfinite(invSqrt)) {
|
||||||
|
this.x = 0.0;
|
||||||
|
this.y = 0.0;
|
||||||
|
this.z = 1.0;
|
||||||
|
} else {
|
||||||
|
this.x = q.x() * invSqrt;
|
||||||
|
this.y = q.y() * invSqrt;
|
||||||
|
this.z = q.z() * invSqrt;
|
||||||
|
}
|
||||||
|
this.angle = acos + acos;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to be equivalent to the rotation
|
||||||
|
* of the given {@link Matrix3fc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/">http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the Matrix3fc to set this AngleAxis4d from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(Matrix3fc m) {
|
||||||
|
double nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02();
|
||||||
|
double nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12();
|
||||||
|
double nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22();
|
||||||
|
double lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02());
|
||||||
|
double lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12());
|
||||||
|
double lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22());
|
||||||
|
nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
|
||||||
|
nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
|
||||||
|
nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
|
||||||
|
double epsilon = 1E-4, epsilon2 = 1E-3;
|
||||||
|
if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) {
|
||||||
|
if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2
|
||||||
|
&& Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
z = 1;
|
||||||
|
angle = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
angle = Math.PI;
|
||||||
|
double xx = (nm00 + 1) / 2;
|
||||||
|
double yy = (nm11 + 1) / 2;
|
||||||
|
double zz = (nm22 + 1) / 2;
|
||||||
|
double xy = (nm10 + nm01) / 4;
|
||||||
|
double xz = (nm20 + nm02) / 4;
|
||||||
|
double yz = (nm21 + nm12) / 4;
|
||||||
|
if ((xx > yy) && (xx > zz)) {
|
||||||
|
x = Math.sqrt(xx);
|
||||||
|
y = xy / x;
|
||||||
|
z = xz / x;
|
||||||
|
} else if (yy > zz) {
|
||||||
|
y = Math.sqrt(yy);
|
||||||
|
x = xy / y;
|
||||||
|
z = yz / y;
|
||||||
|
} else {
|
||||||
|
z = Math.sqrt(zz);
|
||||||
|
x = xz / z;
|
||||||
|
y = yz / z;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
double s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10));
|
||||||
|
angle = Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2);
|
||||||
|
x = (nm12 - nm21) / s;
|
||||||
|
y = (nm20 - nm02) / s;
|
||||||
|
z = (nm01 - nm10) / s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to be equivalent to the rotation
|
||||||
|
* of the given {@link Matrix3dc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/">http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the Matrix3dc to set this AngleAxis4d from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(Matrix3dc m) {
|
||||||
|
double nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02();
|
||||||
|
double nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12();
|
||||||
|
double nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22();
|
||||||
|
double lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02());
|
||||||
|
double lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12());
|
||||||
|
double lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22());
|
||||||
|
nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
|
||||||
|
nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
|
||||||
|
nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
|
||||||
|
double epsilon = 1E-4, epsilon2 = 1E-3;
|
||||||
|
if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) {
|
||||||
|
if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2
|
||||||
|
&& Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
z = 1;
|
||||||
|
angle = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
angle = Math.PI;
|
||||||
|
double xx = (nm00 + 1) / 2;
|
||||||
|
double yy = (nm11 + 1) / 2;
|
||||||
|
double zz = (nm22 + 1) / 2;
|
||||||
|
double xy = (nm10 + nm01) / 4;
|
||||||
|
double xz = (nm20 + nm02) / 4;
|
||||||
|
double yz = (nm21 + nm12) / 4;
|
||||||
|
if ((xx > yy) && (xx > zz)) {
|
||||||
|
x = Math.sqrt(xx);
|
||||||
|
y = xy / x;
|
||||||
|
z = xz / x;
|
||||||
|
} else if (yy > zz) {
|
||||||
|
y = Math.sqrt(yy);
|
||||||
|
x = xy / y;
|
||||||
|
z = yz / y;
|
||||||
|
} else {
|
||||||
|
z = Math.sqrt(zz);
|
||||||
|
x = xz / z;
|
||||||
|
y = yz / z;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
double s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10));
|
||||||
|
angle = Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2);
|
||||||
|
x = (nm12 - nm21) / s;
|
||||||
|
y = (nm20 - nm02) / s;
|
||||||
|
z = (nm01 - nm10) / s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to be equivalent to the rotational component
|
||||||
|
* of the given {@link Matrix4fc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/">http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the Matrix4fc to set this AngleAxis4d from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(Matrix4fc m) {
|
||||||
|
double nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02();
|
||||||
|
double nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12();
|
||||||
|
double nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22();
|
||||||
|
double lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02());
|
||||||
|
double lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12());
|
||||||
|
double lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22());
|
||||||
|
nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
|
||||||
|
nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
|
||||||
|
nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
|
||||||
|
double epsilon = 1E-4, epsilon2 = 1E-3;
|
||||||
|
if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) {
|
||||||
|
if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2
|
||||||
|
&& Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
z = 1;
|
||||||
|
angle = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
angle = Math.PI;
|
||||||
|
double xx = (nm00 + 1) / 2;
|
||||||
|
double yy = (nm11 + 1) / 2;
|
||||||
|
double zz = (nm22 + 1) / 2;
|
||||||
|
double xy = (nm10 + nm01) / 4;
|
||||||
|
double xz = (nm20 + nm02) / 4;
|
||||||
|
double yz = (nm21 + nm12) / 4;
|
||||||
|
if ((xx > yy) && (xx > zz)) {
|
||||||
|
x = Math.sqrt(xx);
|
||||||
|
y = xy / x;
|
||||||
|
z = xz / x;
|
||||||
|
} else if (yy > zz) {
|
||||||
|
y = Math.sqrt(yy);
|
||||||
|
x = xy / y;
|
||||||
|
z = yz / y;
|
||||||
|
} else {
|
||||||
|
z = Math.sqrt(zz);
|
||||||
|
x = xz / z;
|
||||||
|
y = yz / z;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
double s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10));
|
||||||
|
angle = Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2);
|
||||||
|
x = (nm12 - nm21) / s;
|
||||||
|
y = (nm20 - nm02) / s;
|
||||||
|
z = (nm01 - nm10) / s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to be equivalent to the rotational component
|
||||||
|
* of the given {@link Matrix4x3fc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/">http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the Matrix4x3fc to set this AngleAxis4d from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(Matrix4x3fc m) {
|
||||||
|
double nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02();
|
||||||
|
double nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12();
|
||||||
|
double nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22();
|
||||||
|
double lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02());
|
||||||
|
double lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12());
|
||||||
|
double lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22());
|
||||||
|
nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
|
||||||
|
nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
|
||||||
|
nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
|
||||||
|
double epsilon = 1E-4, epsilon2 = 1E-3;
|
||||||
|
if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) {
|
||||||
|
if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2
|
||||||
|
&& Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
z = 1;
|
||||||
|
angle = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
angle = Math.PI;
|
||||||
|
double xx = (nm00 + 1) / 2;
|
||||||
|
double yy = (nm11 + 1) / 2;
|
||||||
|
double zz = (nm22 + 1) / 2;
|
||||||
|
double xy = (nm10 + nm01) / 4;
|
||||||
|
double xz = (nm20 + nm02) / 4;
|
||||||
|
double yz = (nm21 + nm12) / 4;
|
||||||
|
if ((xx > yy) && (xx > zz)) {
|
||||||
|
x = Math.sqrt(xx);
|
||||||
|
y = xy / x;
|
||||||
|
z = xz / x;
|
||||||
|
} else if (yy > zz) {
|
||||||
|
y = Math.sqrt(yy);
|
||||||
|
x = xy / y;
|
||||||
|
z = yz / y;
|
||||||
|
} else {
|
||||||
|
z = Math.sqrt(zz);
|
||||||
|
x = xz / z;
|
||||||
|
y = yz / z;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
double s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10));
|
||||||
|
angle = Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2);
|
||||||
|
x = (nm12 - nm21) / s;
|
||||||
|
y = (nm20 - nm02) / s;
|
||||||
|
z = (nm01 - nm10) / s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4d} to be equivalent to the rotational component
|
||||||
|
* of the given {@link Matrix4dc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/">http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the Matrix4dc to set this AngleAxis4d from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d set(Matrix4dc m) {
|
||||||
|
double nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02();
|
||||||
|
double nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12();
|
||||||
|
double nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22();
|
||||||
|
double lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02());
|
||||||
|
double lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12());
|
||||||
|
double lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22());
|
||||||
|
nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
|
||||||
|
nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
|
||||||
|
nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
|
||||||
|
double epsilon = 1E-4, epsilon2 = 1E-3;
|
||||||
|
if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) {
|
||||||
|
if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2
|
||||||
|
&& Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
z = 1;
|
||||||
|
angle = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
angle = Math.PI;
|
||||||
|
double xx = (nm00 + 1) / 2;
|
||||||
|
double yy = (nm11 + 1) / 2;
|
||||||
|
double zz = (nm22 + 1) / 2;
|
||||||
|
double xy = (nm10 + nm01) / 4;
|
||||||
|
double xz = (nm20 + nm02) / 4;
|
||||||
|
double yz = (nm21 + nm12) / 4;
|
||||||
|
if ((xx > yy) && (xx > zz)) {
|
||||||
|
x = Math.sqrt(xx);
|
||||||
|
y = xy / x;
|
||||||
|
z = xz / x;
|
||||||
|
} else if (yy > zz) {
|
||||||
|
y = Math.sqrt(yy);
|
||||||
|
x = xy / y;
|
||||||
|
z = yz / y;
|
||||||
|
} else {
|
||||||
|
z = Math.sqrt(zz);
|
||||||
|
x = xz / z;
|
||||||
|
y = yz / z;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
double s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10));
|
||||||
|
angle = Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2);
|
||||||
|
x = (nm12 - nm21) / s;
|
||||||
|
y = (nm20 - nm02) / s;
|
||||||
|
z = (nm01 - nm10) / s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Quaternionf} to be equivalent to this {@link AxisAngle4d} rotation.
|
||||||
|
*
|
||||||
|
* @see Quaternionf#set(AxisAngle4d)
|
||||||
|
*
|
||||||
|
* @param q
|
||||||
|
* the quaternion to set
|
||||||
|
* @return q
|
||||||
|
*/
|
||||||
|
public Quaternionf get(Quaternionf q) {
|
||||||
|
return q.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Quaterniond} to be equivalent to this {@link AxisAngle4d} rotation.
|
||||||
|
*
|
||||||
|
* @see Quaterniond#set(AxisAngle4d)
|
||||||
|
*
|
||||||
|
* @param q
|
||||||
|
* the quaternion to set
|
||||||
|
* @return q
|
||||||
|
*/
|
||||||
|
public Quaterniond get(Quaterniond q) {
|
||||||
|
return q.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Matrix4f} to a rotation transformation equivalent to this {@link AxisAngle4d}.
|
||||||
|
*
|
||||||
|
* @see Matrix4f#set(AxisAngle4d)
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the matrix to set
|
||||||
|
* @return m
|
||||||
|
*/
|
||||||
|
public Matrix4f get(Matrix4f m) {
|
||||||
|
return m.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Matrix3f} to a rotation transformation equivalent to this {@link AxisAngle4d}.
|
||||||
|
*
|
||||||
|
* @see Matrix3f#set(AxisAngle4d)
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the matrix to set
|
||||||
|
* @return m
|
||||||
|
*/
|
||||||
|
public Matrix3f get(Matrix3f m) {
|
||||||
|
return m.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Matrix4d} to a rotation transformation equivalent to this {@link AxisAngle4d}.
|
||||||
|
*
|
||||||
|
* @see Matrix4f#set(AxisAngle4d)
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the matrix to set
|
||||||
|
* @return m
|
||||||
|
*/
|
||||||
|
public Matrix4d get(Matrix4d m) {
|
||||||
|
return m.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Matrix3d} to a rotation transformation equivalent to this {@link AxisAngle4d}.
|
||||||
|
*
|
||||||
|
* @see Matrix3f#set(AxisAngle4d)
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the matrix to set
|
||||||
|
* @return m
|
||||||
|
*/
|
||||||
|
public Matrix3d get(Matrix3d m) {
|
||||||
|
return m.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link AxisAngle4d} to this {@link AxisAngle4d}.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public AxisAngle4d get(AxisAngle4d dest) {
|
||||||
|
return dest.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link AxisAngle4f} to this {@link AxisAngle4d}.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public AxisAngle4f get(AxisAngle4f dest) {
|
||||||
|
return dest.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
|
out.writeDouble(angle);
|
||||||
|
out.writeDouble(x);
|
||||||
|
out.writeDouble(y);
|
||||||
|
out.writeDouble(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||||
|
angle = in.readDouble();
|
||||||
|
x = in.readDouble();
|
||||||
|
y = in.readDouble();
|
||||||
|
z = in.readDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize the axis vector.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d normalize() {
|
||||||
|
double invLength = Math.invsqrt(x * x + y * y + z * z);
|
||||||
|
x *= invLength;
|
||||||
|
y *= invLength;
|
||||||
|
z *= invLength;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase the rotation angle by the given amount.
|
||||||
|
* <p>
|
||||||
|
* This method also takes care of wrapping around.
|
||||||
|
*
|
||||||
|
* @param ang
|
||||||
|
* the angle increase
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4d rotate(double ang) {
|
||||||
|
angle += ang;
|
||||||
|
angle = (angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the rotation transformation described by this {@link AxisAngle4d}.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @return v
|
||||||
|
*/
|
||||||
|
public Vector3d transform(Vector3d v) {
|
||||||
|
return transform(v, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the rotation transformation described by this {@link AxisAngle4d}
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public Vector3d transform(Vector3dc v, Vector3d dest) {
|
||||||
|
double sin = Math.sin(angle);
|
||||||
|
double cos = Math.cosFromSin(sin, angle);
|
||||||
|
double dot = x * v.x() + y * v.y() + z * v.z();
|
||||||
|
dest.set(v.x() * cos + sin * (y * v.z() - z * v.y()) + (1.0 - cos) * dot * x,
|
||||||
|
v.y() * cos + sin * (z * v.x() - x * v.z()) + (1.0 - cos) * dot * y,
|
||||||
|
v.z() * cos + sin * (x * v.y() - y * v.x()) + (1.0 - cos) * dot * z);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the rotation transformation described by this {@link AxisAngle4d}.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @return v
|
||||||
|
*/
|
||||||
|
public Vector3f transform(Vector3f v) {
|
||||||
|
return transform(v, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the rotation transformation described by this {@link AxisAngle4d}
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public Vector3f transform(Vector3fc v, Vector3f dest) {
|
||||||
|
double sin = Math.sin(angle);
|
||||||
|
double cos = Math.cosFromSin(sin, angle);
|
||||||
|
double dot = x * v.x() + y * v.y() + z * v.z();
|
||||||
|
dest.set((float) (v.x() * cos + sin * (y * v.z() - z * v.y()) + (1.0 - cos) * dot * x),
|
||||||
|
(float) (v.y() * cos + sin * (z * v.x() - x * v.z()) + (1.0 - cos) * dot * y),
|
||||||
|
(float) (v.z() * cos + sin * (x * v.y() - y * v.x()) + (1.0 - cos) * dot * z));
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the rotation transformation described by this {@link AxisAngle4d}.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @return v
|
||||||
|
*/
|
||||||
|
public Vector4d transform(Vector4d v) {
|
||||||
|
return transform(v, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the rotation transformation described by this {@link AxisAngle4d}
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public Vector4d transform(Vector4dc v, Vector4d dest) {
|
||||||
|
double sin = Math.sin(angle);
|
||||||
|
double cos = Math.cosFromSin(sin, angle);
|
||||||
|
double dot = x * v.x() + y * v.y() + z * v.z();
|
||||||
|
dest.set(v.x() * cos + sin * (y * v.z() - z * v.y()) + (1.0 - cos) * dot * x,
|
||||||
|
v.y() * cos + sin * (z * v.x() - x * v.z()) + (1.0 - cos) * dot * y,
|
||||||
|
v.z() * cos + sin * (x * v.y() - y * v.x()) + (1.0 - cos) * dot * z,
|
||||||
|
dest.w);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string representation of this {@link AxisAngle4d}.
|
||||||
|
* <p>
|
||||||
|
* This method creates a new {@link DecimalFormat} on every invocation with the format string "<code> 0.000E0;-</code>".
|
||||||
|
*
|
||||||
|
* @return the string representation
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return Runtime.formatNumbers(toString(Options.NUMBER_FORMAT));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string representation of this {@link AxisAngle4d} by formatting the components with the given {@link NumberFormat}.
|
||||||
|
*
|
||||||
|
* @param formatter
|
||||||
|
* the {@link NumberFormat} used to format the vector components with
|
||||||
|
* @return the string representation
|
||||||
|
*/
|
||||||
|
public String toString(NumberFormat formatter) {
|
||||||
|
return "(" + Runtime.format(x, formatter) + " " + Runtime.format(y, formatter) + " " + Runtime.format(z, formatter) + " <| " + Runtime.format(angle, formatter) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
long temp;
|
||||||
|
temp = Double.doubleToLongBits((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
|
||||||
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
|
temp = Double.doubleToLongBits(x);
|
||||||
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
|
temp = Double.doubleToLongBits(y);
|
||||||
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
|
temp = Double.doubleToLongBits(z);
|
||||||
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
AxisAngle4d other = (AxisAngle4d) obj;
|
||||||
|
if (Double.doubleToLongBits((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI)) !=
|
||||||
|
Double.doubleToLongBits((other.angle < 0.0 ? Math.PI + Math.PI + other.angle % (Math.PI + Math.PI) : other.angle) % (Math.PI + Math.PI)))
|
||||||
|
return false;
|
||||||
|
if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x))
|
||||||
|
return false;
|
||||||
|
if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y))
|
||||||
|
return false;
|
||||||
|
if (Double.doubleToLongBits(z) != Double.doubleToLongBits(other.z))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
return super.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
813
src/main/java/com/jozufozu/flywheel/repack/joml/AxisAngle4f.java
Normal file
813
src/main/java/com/jozufozu/flywheel/repack/joml/AxisAngle4f.java
Normal file
|
@ -0,0 +1,813 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 Kai Burjack
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.io.Externalizable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a 3D rotation of a given radians about an axis represented as an
|
||||||
|
* unit 3D vector.
|
||||||
|
* <p>
|
||||||
|
* This class uses single-precision components.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class AxisAngle4f implements Externalizable, Cloneable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The angle in radians.
|
||||||
|
*/
|
||||||
|
public float angle;
|
||||||
|
/**
|
||||||
|
* The x-component of the rotation axis.
|
||||||
|
*/
|
||||||
|
public float x;
|
||||||
|
/**
|
||||||
|
* The y-component of the rotation axis.
|
||||||
|
*/
|
||||||
|
public float y;
|
||||||
|
/**
|
||||||
|
* The z-component of the rotation axis.
|
||||||
|
*/
|
||||||
|
public float z;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4f} with zero rotation about <code>(0, 0, 1)</code>.
|
||||||
|
*/
|
||||||
|
public AxisAngle4f() {
|
||||||
|
z = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4f} with the same values of <code>a</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the AngleAxis4f to copy the values from
|
||||||
|
*/
|
||||||
|
public AxisAngle4f(AxisAngle4f a) {
|
||||||
|
x = a.x;
|
||||||
|
y = a.y;
|
||||||
|
z = a.z;
|
||||||
|
angle = (float) ((a.angle < 0.0 ? Math.PI + Math.PI + a.angle % (Math.PI + Math.PI) : a.angle) % (Math.PI + Math.PI));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4f} from the given {@link Quaternionfc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href=
|
||||||
|
* "http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/"
|
||||||
|
* >http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param q
|
||||||
|
* the quaternion from which to create the new AngleAxis4f
|
||||||
|
*/
|
||||||
|
public AxisAngle4f(Quaternionfc q) {
|
||||||
|
float acos = Math.safeAcos(q.w());
|
||||||
|
float invSqrt = Math.invsqrt(1.0f - q.w() * q.w());
|
||||||
|
if (Float.isInfinite(invSqrt)) {
|
||||||
|
this.x = 0.0f;
|
||||||
|
this.y = 0.0f;
|
||||||
|
this.z = 1.0f;
|
||||||
|
} else {
|
||||||
|
this.x = q.x() * invSqrt;
|
||||||
|
this.y = q.y() * invSqrt;
|
||||||
|
this.z = q.z() * invSqrt;
|
||||||
|
}
|
||||||
|
this.angle = acos + acos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4f} with the given values.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param x
|
||||||
|
* the x-coordinate of the rotation axis
|
||||||
|
* @param y
|
||||||
|
* the y-coordinate of the rotation axis
|
||||||
|
* @param z
|
||||||
|
* the z-coordinate of the rotation axis
|
||||||
|
*/
|
||||||
|
public AxisAngle4f(float angle, float x, float y, float z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.angle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link AxisAngle4f} with the given values.
|
||||||
|
*
|
||||||
|
* @param angle the angle in radians
|
||||||
|
* @param v the rotation axis as a {@link Vector3f}
|
||||||
|
*/
|
||||||
|
public AxisAngle4f(float angle, Vector3fc v) {
|
||||||
|
this(angle, v.x(), v.y(), v.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4f} to the values of <code>a</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the AngleAxis4f to copy the values from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f set(AxisAngle4f a) {
|
||||||
|
x = a.x;
|
||||||
|
y = a.y;
|
||||||
|
z = a.z;
|
||||||
|
angle = a.angle;
|
||||||
|
angle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4f} to the values of <code>a</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the AngleAxis4d to copy the values from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f set(AxisAngle4d a) {
|
||||||
|
x = (float) a.x;
|
||||||
|
y = (float) a.y;
|
||||||
|
z = (float) a.z;
|
||||||
|
angle = (float) a.angle;
|
||||||
|
angle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4f} to the given values.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param x
|
||||||
|
* the x-coordinate of the rotation axis
|
||||||
|
* @param y
|
||||||
|
* the y-coordinate of the rotation axis
|
||||||
|
* @param z
|
||||||
|
* the z-coordinate of the rotation axis
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f set(float angle, float x, float y, float z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.angle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4f} to the given values.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param v
|
||||||
|
* the rotation axis as a {@link Vector3f}
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f set(float angle, Vector3fc v) {
|
||||||
|
return set(angle, v.x(), v.y(), v.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4f} to be equivalent to the given
|
||||||
|
* {@link Quaternionfc}.
|
||||||
|
*
|
||||||
|
* @param q
|
||||||
|
* the quaternion to set this AngleAxis4f from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f set(Quaternionfc q) {
|
||||||
|
float acos = Math.safeAcos(q.w());
|
||||||
|
float invSqrt = Math.invsqrt(1.0f - q.w() * q.w());
|
||||||
|
if (Float.isInfinite(invSqrt)) {
|
||||||
|
this.x = 0.0f;
|
||||||
|
this.y = 0.0f;
|
||||||
|
this.z = 1.0f;
|
||||||
|
} else {
|
||||||
|
this.x = q.x() * invSqrt;
|
||||||
|
this.y = q.y() * invSqrt;
|
||||||
|
this.z = q.z() * invSqrt;
|
||||||
|
}
|
||||||
|
this.angle = acos + acos;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4f} to be equivalent to the given
|
||||||
|
* {@link Quaterniondc}.
|
||||||
|
*
|
||||||
|
* @param q
|
||||||
|
* the quaternion to set this AngleAxis4f from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f set(Quaterniondc q) {
|
||||||
|
double acos = Math.safeAcos(q.w());
|
||||||
|
double invSqrt = Math.invsqrt(1.0 - q.w() * q.w());
|
||||||
|
if (Double.isInfinite(invSqrt)) {
|
||||||
|
this.x = 0.0f;
|
||||||
|
this.y = 0.0f;
|
||||||
|
this.z = 1.0f;
|
||||||
|
} else {
|
||||||
|
this.x = (float) (q.x() * invSqrt);
|
||||||
|
this.y = (float) (q.y() * invSqrt);
|
||||||
|
this.z = (float) (q.z() * invSqrt);
|
||||||
|
}
|
||||||
|
this.angle = (float) (acos + acos);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4f} to be equivalent to the rotation
|
||||||
|
* of the given {@link Matrix3fc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/">http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the Matrix3fc to set this AngleAxis4f from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f set(Matrix3fc m) {
|
||||||
|
float nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02();
|
||||||
|
float nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12();
|
||||||
|
float nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22();
|
||||||
|
float lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02());
|
||||||
|
float lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12());
|
||||||
|
float lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22());
|
||||||
|
nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
|
||||||
|
nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
|
||||||
|
nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
|
||||||
|
float epsilon = 1E-4f, epsilon2 = 1E-3f;
|
||||||
|
if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) {
|
||||||
|
if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2
|
||||||
|
&& Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
z = 1;
|
||||||
|
angle = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
angle = Math.PI_f;
|
||||||
|
float xx = (nm00 + 1) / 2;
|
||||||
|
float yy = (nm11 + 1) / 2;
|
||||||
|
float zz = (nm22 + 1) / 2;
|
||||||
|
float xy = (nm10 + nm01) / 4;
|
||||||
|
float xz = (nm20 + nm02) / 4;
|
||||||
|
float yz = (nm21 + nm12) / 4;
|
||||||
|
if ((xx > yy) && (xx > zz)) {
|
||||||
|
x = Math.sqrt(xx);
|
||||||
|
y = xy / x;
|
||||||
|
z = xz / x;
|
||||||
|
} else if (yy > zz) {
|
||||||
|
y = Math.sqrt(yy);
|
||||||
|
x = xy / y;
|
||||||
|
z = yz / y;
|
||||||
|
} else {
|
||||||
|
z = Math.sqrt(zz);
|
||||||
|
x = xz / z;
|
||||||
|
y = yz / z;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
float s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10));
|
||||||
|
angle = Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2);
|
||||||
|
x = (nm12 - nm21) / s;
|
||||||
|
y = (nm20 - nm02) / s;
|
||||||
|
z = (nm01 - nm10) / s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4f} to be equivalent to the rotation
|
||||||
|
* of the given {@link Matrix3dc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/">http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the Matrix3d to set this AngleAxis4f from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f set(Matrix3dc m) {
|
||||||
|
double nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02();
|
||||||
|
double nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12();
|
||||||
|
double nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22();
|
||||||
|
double lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02());
|
||||||
|
double lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12());
|
||||||
|
double lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22());
|
||||||
|
nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
|
||||||
|
nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
|
||||||
|
nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
|
||||||
|
double epsilon = 1E-4, epsilon2 = 1E-3;
|
||||||
|
if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) {
|
||||||
|
if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2
|
||||||
|
&& Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
z = 1;
|
||||||
|
angle = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
angle = (float) Math.PI;
|
||||||
|
double xx = (nm00 + 1) / 2;
|
||||||
|
double yy = (nm11 + 1) / 2;
|
||||||
|
double zz = (nm22 + 1) / 2;
|
||||||
|
double xy = (nm10 + nm01) / 4;
|
||||||
|
double xz = (nm20 + nm02) / 4;
|
||||||
|
double yz = (nm21 + nm12) / 4;
|
||||||
|
if ((xx > yy) && (xx > zz)) {
|
||||||
|
x = (float) Math.sqrt(xx);
|
||||||
|
y = (float) (xy / x);
|
||||||
|
z = (float) (xz / x);
|
||||||
|
} else if (yy > zz) {
|
||||||
|
y = (float) Math.sqrt(yy);
|
||||||
|
x = (float) (xy / y);
|
||||||
|
z = (float) (yz / y);
|
||||||
|
} else {
|
||||||
|
z = (float) Math.sqrt(zz);
|
||||||
|
x = (float) (xz / z);
|
||||||
|
y = (float) (yz / z);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
double s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10));
|
||||||
|
angle = (float) Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2);
|
||||||
|
x = (float) ((nm12 - nm21) / s);
|
||||||
|
y = (float) ((nm20 - nm02) / s);
|
||||||
|
z = (float) ((nm01 - nm10) / s);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4f} to be equivalent to the rotational component
|
||||||
|
* of the given {@link Matrix4fc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/">http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the Matrix4fc to set this AngleAxis4f from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f set(Matrix4fc m) {
|
||||||
|
float nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02();
|
||||||
|
float nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12();
|
||||||
|
float nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22();
|
||||||
|
float lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02());
|
||||||
|
float lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12());
|
||||||
|
float lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22());
|
||||||
|
nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
|
||||||
|
nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
|
||||||
|
nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
|
||||||
|
float epsilon = 1E-4f, epsilon2 = 1E-3f;
|
||||||
|
if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) {
|
||||||
|
if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2
|
||||||
|
&& Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
z = 1;
|
||||||
|
angle = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
angle = Math.PI_f;
|
||||||
|
float xx = (nm00 + 1) / 2;
|
||||||
|
float yy = (nm11 + 1) / 2;
|
||||||
|
float zz = (nm22 + 1) / 2;
|
||||||
|
float xy = (nm10 + nm01) / 4;
|
||||||
|
float xz = (nm20 + nm02) / 4;
|
||||||
|
float yz = (nm21 + nm12) / 4;
|
||||||
|
if ((xx > yy) && (xx > zz)) {
|
||||||
|
x = Math.sqrt(xx);
|
||||||
|
y = xy / x;
|
||||||
|
z = xz / x;
|
||||||
|
} else if (yy > zz) {
|
||||||
|
y = Math.sqrt(yy);
|
||||||
|
x = xy / y;
|
||||||
|
z = yz / y;
|
||||||
|
} else {
|
||||||
|
z = Math.sqrt(zz);
|
||||||
|
x = xz / z;
|
||||||
|
y = yz / z;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
float s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10));
|
||||||
|
angle = Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2);
|
||||||
|
x = (nm12 - nm21) / s;
|
||||||
|
y = (nm20 - nm02) / s;
|
||||||
|
z = (nm01 - nm10) / s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4f} to be equivalent to the rotational component
|
||||||
|
* of the given {@link Matrix4x3fc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/">http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the Matrix4x3fc to set this AngleAxis4f from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f set(Matrix4x3fc m) {
|
||||||
|
float nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02();
|
||||||
|
float nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12();
|
||||||
|
float nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22();
|
||||||
|
float lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02());
|
||||||
|
float lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12());
|
||||||
|
float lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22());
|
||||||
|
nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
|
||||||
|
nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
|
||||||
|
nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
|
||||||
|
float epsilon = 1E-4f, epsilon2 = 1E-3f;
|
||||||
|
if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) {
|
||||||
|
if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2
|
||||||
|
&& Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
z = 1;
|
||||||
|
angle = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
angle = Math.PI_f;
|
||||||
|
float xx = (nm00 + 1) / 2;
|
||||||
|
float yy = (nm11 + 1) / 2;
|
||||||
|
float zz = (nm22 + 1) / 2;
|
||||||
|
float xy = (nm10 + nm01) / 4;
|
||||||
|
float xz = (nm20 + nm02) / 4;
|
||||||
|
float yz = (nm21 + nm12) / 4;
|
||||||
|
if ((xx > yy) && (xx > zz)) {
|
||||||
|
x = Math.sqrt(xx);
|
||||||
|
y = xy / x;
|
||||||
|
z = xz / x;
|
||||||
|
} else if (yy > zz) {
|
||||||
|
y = Math.sqrt(yy);
|
||||||
|
x = xy / y;
|
||||||
|
z = yz / y;
|
||||||
|
} else {
|
||||||
|
z = Math.sqrt(zz);
|
||||||
|
x = xz / z;
|
||||||
|
y = yz / z;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
float s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10));
|
||||||
|
angle = Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2);
|
||||||
|
x = (nm12 - nm21) / s;
|
||||||
|
y = (nm20 - nm02) / s;
|
||||||
|
z = (nm01 - nm10) / s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link AxisAngle4f} to be equivalent to the rotational component
|
||||||
|
* of the given {@link Matrix4dc}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/">http://www.euclideanspace.com</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the Matrix4dc to set this AngleAxis4f from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f set(Matrix4dc m) {
|
||||||
|
double nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02();
|
||||||
|
double nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12();
|
||||||
|
double nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22();
|
||||||
|
double lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02());
|
||||||
|
double lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12());
|
||||||
|
double lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22());
|
||||||
|
nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
|
||||||
|
nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
|
||||||
|
nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
|
||||||
|
double epsilon = 1E-4, epsilon2 = 1E-3;
|
||||||
|
if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) {
|
||||||
|
if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2
|
||||||
|
&& Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
z = 1;
|
||||||
|
angle = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
angle = (float) Math.PI;
|
||||||
|
double xx = (nm00 + 1) / 2;
|
||||||
|
double yy = (nm11 + 1) / 2;
|
||||||
|
double zz = (nm22 + 1) / 2;
|
||||||
|
double xy = (nm10 + nm01) / 4;
|
||||||
|
double xz = (nm20 + nm02) / 4;
|
||||||
|
double yz = (nm21 + nm12) / 4;
|
||||||
|
if ((xx > yy) && (xx > zz)) {
|
||||||
|
x = (float) Math.sqrt(xx);
|
||||||
|
y = (float) (xy / x);
|
||||||
|
z = (float) (xz / x);
|
||||||
|
} else if (yy > zz) {
|
||||||
|
y = (float) Math.sqrt(yy);
|
||||||
|
x = (float) (xy / y);
|
||||||
|
z = (float) (yz / y);
|
||||||
|
} else {
|
||||||
|
z = (float) Math.sqrt(zz);
|
||||||
|
x = (float) (xz / z);
|
||||||
|
y = (float) (yz / z);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
double s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10));
|
||||||
|
angle = (float) Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2);
|
||||||
|
x = (float) ((nm12 - nm21) / s);
|
||||||
|
y = (float) ((nm20 - nm02) / s);
|
||||||
|
z = (float) ((nm01 - nm10) / s);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Quaternionf} to be equivalent to this {@link AxisAngle4f} rotation.
|
||||||
|
*
|
||||||
|
* @see Quaternionf#set(AxisAngle4f)
|
||||||
|
*
|
||||||
|
* @param q
|
||||||
|
* the quaternion to set
|
||||||
|
* @return q
|
||||||
|
*/
|
||||||
|
public Quaternionf get(Quaternionf q) {
|
||||||
|
return q.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Quaterniond} to be equivalent to this {@link AxisAngle4f} rotation.
|
||||||
|
*
|
||||||
|
* @see Quaterniond#set(AxisAngle4f)
|
||||||
|
*
|
||||||
|
* @param q
|
||||||
|
* the quaternion to set
|
||||||
|
* @return q
|
||||||
|
*/
|
||||||
|
public Quaterniond get(Quaterniond q) {
|
||||||
|
return q.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Matrix4f} to a rotation transformation equivalent to this {@link AxisAngle4f}.
|
||||||
|
*
|
||||||
|
* @see Matrix4f#set(AxisAngle4f)
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the matrix to set
|
||||||
|
* @return m
|
||||||
|
*/
|
||||||
|
public Matrix4f get(Matrix4f m) {
|
||||||
|
return m.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Matrix3f} to a rotation transformation equivalent to this {@link AxisAngle4f}.
|
||||||
|
*
|
||||||
|
* @see Matrix3f#set(AxisAngle4f)
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the matrix to set
|
||||||
|
* @return m
|
||||||
|
*/
|
||||||
|
public Matrix3f get(Matrix3f m) {
|
||||||
|
return m.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Matrix4d} to a rotation transformation equivalent to this {@link AxisAngle4f}.
|
||||||
|
*
|
||||||
|
* @see Matrix4f#set(AxisAngle4f)
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the matrix to set
|
||||||
|
* @return m
|
||||||
|
*/
|
||||||
|
public Matrix4d get(Matrix4d m) {
|
||||||
|
return m.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link Matrix3d} to a rotation transformation equivalent to this {@link AxisAngle4f}.
|
||||||
|
*
|
||||||
|
* @see Matrix3f#set(AxisAngle4f)
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the matrix to set
|
||||||
|
* @return m
|
||||||
|
*/
|
||||||
|
public Matrix3d get(Matrix3d m) {
|
||||||
|
return m.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link AxisAngle4d} to this {@link AxisAngle4f}.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public AxisAngle4d get(AxisAngle4d dest) {
|
||||||
|
return dest.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given {@link AxisAngle4f} to this {@link AxisAngle4f}.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public AxisAngle4f get(AxisAngle4f dest) {
|
||||||
|
return dest.set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
|
out.writeFloat(angle);
|
||||||
|
out.writeFloat(x);
|
||||||
|
out.writeFloat(y);
|
||||||
|
out.writeFloat(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||||
|
angle = in.readFloat();
|
||||||
|
x = in.readFloat();
|
||||||
|
y = in.readFloat();
|
||||||
|
z = in.readFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize the axis vector.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f normalize() {
|
||||||
|
float invLength = Math.invsqrt(x * x + y * y + z * z);
|
||||||
|
x *= invLength;
|
||||||
|
y *= invLength;
|
||||||
|
z *= invLength;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase the rotation angle by the given amount.
|
||||||
|
* <p>
|
||||||
|
* This method also takes care of wrapping around.
|
||||||
|
*
|
||||||
|
* @param ang
|
||||||
|
* the angle increase
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public AxisAngle4f rotate(float ang) {
|
||||||
|
angle += ang;
|
||||||
|
angle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the rotation transformation described by this {@link AxisAngle4f}.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @return v
|
||||||
|
*/
|
||||||
|
public Vector3f transform(Vector3f v) {
|
||||||
|
return transform(v, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the rotation transformation described by this {@link AxisAngle4f}
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public Vector3f transform(Vector3fc v, Vector3f dest) {
|
||||||
|
double sin = Math.sin(angle);
|
||||||
|
double cos = Math.cosFromSin(sin, angle);
|
||||||
|
float dot = x * v.x() + y * v.y() + z * v.z();
|
||||||
|
dest.set((float) (v.x() * cos + sin * (y * v.z() - z * v.y()) + (1.0 - cos) * dot * x),
|
||||||
|
(float) (v.y() * cos + sin * (z * v.x() - x * v.z()) + (1.0 - cos) * dot * y),
|
||||||
|
(float) (v.z() * cos + sin * (x * v.y() - y * v.x()) + (1.0 - cos) * dot * z));
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the rotation transformation described by this {@link AxisAngle4f}.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @return v
|
||||||
|
*/
|
||||||
|
public Vector4f transform(Vector4f v) {
|
||||||
|
return transform(v, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the rotation transformation described by this {@link AxisAngle4f}
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public Vector4f transform(Vector4fc v, Vector4f dest) {
|
||||||
|
double sin = Math.sin(angle);
|
||||||
|
double cos = Math.cosFromSin(sin, angle);
|
||||||
|
float dot = x * v.x() + y * v.y() + z * v.z();
|
||||||
|
dest.set((float) (v.x() * cos + sin * (y * v.z() - z * v.y()) + (1.0 - cos) * dot * x),
|
||||||
|
(float) (v.y() * cos + sin * (z * v.x() - x * v.z()) + (1.0 - cos) * dot * y),
|
||||||
|
(float) (v.z() * cos + sin * (x * v.y() - y * v.x()) + (1.0 - cos) * dot * z),
|
||||||
|
dest.w);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string representation of this {@link AxisAngle4f}.
|
||||||
|
* <p>
|
||||||
|
* This method creates a new {@link DecimalFormat} on every invocation with the format string "<code> 0.000E0;-</code>".
|
||||||
|
*
|
||||||
|
* @return the string representation
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return Runtime.formatNumbers(toString(Options.NUMBER_FORMAT));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string representation of this {@link AxisAngle4f} by formatting the components with the given {@link NumberFormat}.
|
||||||
|
*
|
||||||
|
* @param formatter
|
||||||
|
* the {@link NumberFormat} used to format the vector components with
|
||||||
|
* @return the string representation
|
||||||
|
*/
|
||||||
|
public String toString(NumberFormat formatter) {
|
||||||
|
return "(" + Runtime.format(x, formatter) + " " + Runtime.format(y, formatter) + " " + Runtime.format(z, formatter) + " <| " + Runtime.format(angle, formatter) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
float nangle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
|
||||||
|
result = prime * result + Float.floatToIntBits(nangle);
|
||||||
|
result = prime * result + Float.floatToIntBits(x);
|
||||||
|
result = prime * result + Float.floatToIntBits(y);
|
||||||
|
result = prime * result + Float.floatToIntBits(z);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
AxisAngle4f other = (AxisAngle4f) obj;
|
||||||
|
float nangle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
|
||||||
|
float nangleOther = (float) ((other.angle < 0.0 ? Math.PI + Math.PI + other.angle % (Math.PI + Math.PI) : other.angle) % (Math.PI + Math.PI));
|
||||||
|
if (Float.floatToIntBits(nangle) != Float.floatToIntBits(nangleOther))
|
||||||
|
return false;
|
||||||
|
if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x))
|
||||||
|
return false;
|
||||||
|
if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y))
|
||||||
|
return false;
|
||||||
|
if (Float.floatToIntBits(z) != Float.floatToIntBits(other.z))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
return super.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when using an invalid JOML runtime configuration.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class ConfigurationException extends RuntimeException {
|
||||||
|
private static final long serialVersionUID = -7832356906364070687L;
|
||||||
|
public ConfigurationException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,971 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 Kai Burjack
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Efficiently performs frustum intersection tests by caching the frustum planes of an arbitrary transformation {@link Matrix4fc matrix}.
|
||||||
|
* <p>
|
||||||
|
* This class is preferred over the frustum intersection methods in {@link Matrix4fc} when many objects need to be culled by the same static frustum.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class FrustumIntersection {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
|
||||||
|
* and its different overloads identifying the plane with equation <code>x=-1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_NX = 0;
|
||||||
|
/**
|
||||||
|
* Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
|
||||||
|
* and its different overloads identifying the plane with equation <code>x=1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_PX = 1;
|
||||||
|
/**
|
||||||
|
* Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
|
||||||
|
* and its different overloads identifying the plane with equation <code>y=-1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_NY= 2;
|
||||||
|
/**
|
||||||
|
* Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
|
||||||
|
* and its different overloads identifying the plane with equation <code>y=1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_PY = 3;
|
||||||
|
/**
|
||||||
|
* Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
|
||||||
|
* and its different overloads identifying the plane with equation <code>z=-1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_NZ = 4;
|
||||||
|
/**
|
||||||
|
* Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
|
||||||
|
* and its different overloads identifying the plane with equation <code>z=1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_PZ = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
|
||||||
|
* and its different overloads indicating that the axis-aligned box intersects the frustum.
|
||||||
|
*/
|
||||||
|
public static final int INTERSECT = -1;
|
||||||
|
/**
|
||||||
|
* Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
|
||||||
|
* and its different overloads indicating that the axis-aligned box is fully inside of the frustum.
|
||||||
|
*/
|
||||||
|
public static final int INSIDE = -2;
|
||||||
|
/**
|
||||||
|
* Return value of {@link #intersectSphere(Vector3fc, float)} or {@link #intersectSphere(float, float, float, float)}
|
||||||
|
* indicating that the sphere is completely outside of the frustum.
|
||||||
|
*/
|
||||||
|
public static final int OUTSIDE = -3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value in a bitmask for
|
||||||
|
* {@link #intersectAab(float, float, float, float, float, float, int) intersectAab()}
|
||||||
|
* that identifies the plane with equation <code>x=-1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_MASK_NX = 1<<PLANE_NX;
|
||||||
|
/**
|
||||||
|
* The value in a bitmask for
|
||||||
|
* {@link #intersectAab(float, float, float, float, float, float, int) intersectAab()}
|
||||||
|
* that identifies the plane with equation <code>x=1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_MASK_PX = 1<<PLANE_PX;
|
||||||
|
/**
|
||||||
|
* The value in a bitmask for
|
||||||
|
* {@link #intersectAab(float, float, float, float, float, float, int) intersectAab()}
|
||||||
|
* that identifies the plane with equation <code>y=-1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_MASK_NY = 1<<PLANE_NY;
|
||||||
|
/**
|
||||||
|
* The value in a bitmask for
|
||||||
|
* {@link #intersectAab(float, float, float, float, float, float, int) intersectAab()}
|
||||||
|
* that identifies the plane with equation <code>y=1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_MASK_PY = 1<<PLANE_PY;
|
||||||
|
/**
|
||||||
|
* The value in a bitmask for
|
||||||
|
* {@link #intersectAab(float, float, float, float, float, float, int) intersectAab()}
|
||||||
|
* that identifies the plane with equation <code>z=-1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_MASK_NZ = 1<<PLANE_NZ;
|
||||||
|
/**
|
||||||
|
* The value in a bitmask for
|
||||||
|
* {@link #intersectAab(float, float, float, float, float, float, int) intersectAab()}
|
||||||
|
* that identifies the plane with equation <code>z=1</code> when using the identity frustum.
|
||||||
|
*/
|
||||||
|
public static final int PLANE_MASK_PZ = 1<<PLANE_PZ;
|
||||||
|
|
||||||
|
private float nxX, nxY, nxZ, nxW;
|
||||||
|
private float pxX, pxY, pxZ, pxW;
|
||||||
|
private float nyX, nyY, nyZ, nyW;
|
||||||
|
private float pyX, pyY, pyZ, pyW;
|
||||||
|
private float nzX, nzY, nzZ, nzW;
|
||||||
|
private float pzX, pzY, pzZ, pzW;
|
||||||
|
|
||||||
|
private final Vector4f[] planes = new Vector4f[6];
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
planes[i] = new Vector4f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link FrustumIntersection} with undefined frustum planes.
|
||||||
|
* <p>
|
||||||
|
* Before using any of the frustum culling methods, make sure to define the frustum planes using {@link #set(Matrix4fc)}.
|
||||||
|
*/
|
||||||
|
public FrustumIntersection() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link FrustumIntersection} from the given {@link Matrix4fc matrix} by extracing the matrix's frustum planes.
|
||||||
|
* <p>
|
||||||
|
* In order to update the compute frustum planes later on, call {@link #set(Matrix4fc)}.
|
||||||
|
*
|
||||||
|
* @see #set(Matrix4fc)
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the {@link Matrix4fc} to create the frustum culler from
|
||||||
|
*/
|
||||||
|
public FrustumIntersection(Matrix4fc m) {
|
||||||
|
set(m, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link FrustumIntersection} from the given {@link Matrix4fc matrix} by extracing the matrix's frustum planes.
|
||||||
|
* <p>
|
||||||
|
* In order to update the compute frustum planes later on, call {@link #set(Matrix4fc)}.
|
||||||
|
*
|
||||||
|
* @see #set(Matrix4fc)
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the {@link Matrix4fc} to create the frustum culler from
|
||||||
|
* @param allowTestSpheres
|
||||||
|
* whether the methods {@link #testSphere(Vector3fc, float)}, {@link #testSphere(float, float, float, float)},
|
||||||
|
* {@link #intersectSphere(Vector3fc, float)} or {@link #intersectSphere(float, float, float, float)} will used.
|
||||||
|
* If no spheres need to be tested, then <code>false</code> should be used
|
||||||
|
*/
|
||||||
|
public FrustumIntersection(Matrix4fc m, boolean allowTestSpheres) {
|
||||||
|
set(m, allowTestSpheres);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the stored frustum planes of <code>this</code> {@link FrustumIntersection} with the given {@link Matrix4fc matrix}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://gamedevs.org/uploads/fast-extraction-viewing-frustum-planes-from-world-view-projection-matrix.pdf">
|
||||||
|
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the {@link Matrix4fc matrix} to update <code>this</code> frustum culler's frustum planes from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public FrustumIntersection set(Matrix4fc m) {
|
||||||
|
return set(m, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the stored frustum planes of <code>this</code> {@link FrustumIntersection} with the given {@link Matrix4fc matrix} and
|
||||||
|
* allow to optimize the frustum plane extraction in the case when no intersection test is needed for spheres.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://gamedevs.org/uploads/fast-extraction-viewing-frustum-planes-from-world-view-projection-matrix.pdf">
|
||||||
|
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the {@link Matrix4fc matrix} to update <code>this</code> frustum culler's frustum planes from
|
||||||
|
* @param allowTestSpheres
|
||||||
|
* whether the methods {@link #testSphere(Vector3fc, float)}, {@link #testSphere(float, float, float, float)},
|
||||||
|
* {@link #intersectSphere(Vector3fc, float)} or {@link #intersectSphere(float, float, float, float)} will be used.
|
||||||
|
* If no spheres need to be tested, then <code>false</code> should be used
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public FrustumIntersection set(Matrix4fc m, boolean allowTestSpheres) {
|
||||||
|
float invl;
|
||||||
|
nxX = m.m03() + m.m00(); nxY = m.m13() + m.m10(); nxZ = m.m23() + m.m20(); nxW = m.m33() + m.m30();
|
||||||
|
if (allowTestSpheres) {
|
||||||
|
invl = Math.invsqrt(nxX * nxX + nxY * nxY + nxZ * nxZ);
|
||||||
|
nxX *= invl; nxY *= invl; nxZ *= invl; nxW *= invl;
|
||||||
|
}
|
||||||
|
planes[0].set(nxX, nxY, nxZ, nxW);
|
||||||
|
pxX = m.m03() - m.m00(); pxY = m.m13() - m.m10(); pxZ = m.m23() - m.m20(); pxW = m.m33() - m.m30();
|
||||||
|
if (allowTestSpheres) {
|
||||||
|
invl = Math.invsqrt(pxX * pxX + pxY * pxY + pxZ * pxZ);
|
||||||
|
pxX *= invl; pxY *= invl; pxZ *= invl; pxW *= invl;
|
||||||
|
}
|
||||||
|
planes[1].set(pxX, pxY, pxZ, pxW);
|
||||||
|
nyX = m.m03() + m.m01(); nyY = m.m13() + m.m11(); nyZ = m.m23() + m.m21(); nyW = m.m33() + m.m31();
|
||||||
|
if (allowTestSpheres) {
|
||||||
|
invl = Math.invsqrt(nyX * nyX + nyY * nyY + nyZ * nyZ);
|
||||||
|
nyX *= invl; nyY *= invl; nyZ *= invl; nyW *= invl;
|
||||||
|
}
|
||||||
|
planes[2].set(nyX, nyY, nyZ, nyW);
|
||||||
|
pyX = m.m03() - m.m01(); pyY = m.m13() - m.m11(); pyZ = m.m23() - m.m21(); pyW = m.m33() - m.m31();
|
||||||
|
if (allowTestSpheres) {
|
||||||
|
invl = Math.invsqrt(pyX * pyX + pyY * pyY + pyZ * pyZ);
|
||||||
|
pyX *= invl; pyY *= invl; pyZ *= invl; pyW *= invl;
|
||||||
|
}
|
||||||
|
planes[3].set(pyX, pyY, pyZ, pyW);
|
||||||
|
nzX = m.m03() + m.m02(); nzY = m.m13() + m.m12(); nzZ = m.m23() + m.m22(); nzW = m.m33() + m.m32();
|
||||||
|
if (allowTestSpheres) {
|
||||||
|
invl = Math.invsqrt(nzX * nzX + nzY * nzY + nzZ * nzZ);
|
||||||
|
nzX *= invl; nzY *= invl; nzZ *= invl; nzW *= invl;
|
||||||
|
}
|
||||||
|
planes[4].set(nzX, nzY, nzZ, nzW);
|
||||||
|
pzX = m.m03() - m.m02(); pzY = m.m13() - m.m12(); pzZ = m.m23() - m.m22(); pzW = m.m33() - m.m32();
|
||||||
|
if (allowTestSpheres) {
|
||||||
|
invl = Math.invsqrt(pzX * pzX + pzY * pzY + pzZ * pzZ);
|
||||||
|
pzX *= invl; pzY *= invl; pzZ *= invl; pzW *= invl;
|
||||||
|
}
|
||||||
|
planes[5].set(pzX, pzY, pzZ, pzW);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given point is within the frustum defined by <code>this</code> frustum culler.
|
||||||
|
*
|
||||||
|
* @param point
|
||||||
|
* the point to test
|
||||||
|
* @return <code>true</code> if the given point is inside the frustum; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testPoint(Vector3fc point) {
|
||||||
|
return testPoint(point.x(), point.y(), point.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given point <code>(x, y, z)</code> is within the frustum defined by <code>this</code> frustum culler.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x-coordinate of the point
|
||||||
|
* @param y
|
||||||
|
* the y-coordinate of the point
|
||||||
|
* @param z
|
||||||
|
* the z-coordinate of the point
|
||||||
|
* @return <code>true</code> if the given point is inside the frustum; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testPoint(float x, float y, float z) {
|
||||||
|
return nxX * x + nxY * y + nxZ * z + nxW >= 0 &&
|
||||||
|
pxX * x + pxY * y + pxZ * z + pxW >= 0 &&
|
||||||
|
nyX * x + nyY * y + nyZ * z + nyW >= 0 &&
|
||||||
|
pyX * x + pyY * y + pyZ * z + pyW >= 0 &&
|
||||||
|
nzX * x + nzY * y + nzZ * z + nzW >= 0 &&
|
||||||
|
pzX * x + pzY * y + pzZ * z + pzW >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given sphere is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns <code>true</code> for spheres that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
*
|
||||||
|
* @param center
|
||||||
|
* the sphere's center
|
||||||
|
* @param radius
|
||||||
|
* the sphere's radius
|
||||||
|
* @return <code>true</code> if the given sphere is partly or completely inside the frustum;
|
||||||
|
* <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testSphere(Vector3fc center, float radius) {
|
||||||
|
return testSphere(center.x(), center.y(), center.z(), radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given sphere is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns <code>true</code> for spheres that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x-coordinate of the sphere's center
|
||||||
|
* @param y
|
||||||
|
* the y-coordinate of the sphere's center
|
||||||
|
* @param z
|
||||||
|
* the z-coordinate of the sphere's center
|
||||||
|
* @param r
|
||||||
|
* the sphere's radius
|
||||||
|
* @return <code>true</code> if the given sphere is partly or completely inside the frustum;
|
||||||
|
* <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testSphere(float x, float y, float z, float r) {
|
||||||
|
return nxX * x + nxY * y + nxZ * z + nxW >= -r &&
|
||||||
|
pxX * x + pxY * y + pxZ * z + pxW >= -r &&
|
||||||
|
nyX * x + nyY * y + nyZ * z + nyW >= -r &&
|
||||||
|
pyX * x + pyY * y + pyZ * z + pyW >= -r &&
|
||||||
|
nzX * x + nzY * y + nzZ * z + nzW >= -r &&
|
||||||
|
pzX * x + pzY * y + pzZ * z + pzW >= -r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given sphere is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns {@link #INTERSECT} for spheres that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
*
|
||||||
|
* @param center
|
||||||
|
* the sphere's center
|
||||||
|
* @param radius
|
||||||
|
* the sphere's radius
|
||||||
|
* @return {@link #INSIDE} if the given sphere is completely inside the frustum, or {@link #INTERSECT} if the sphere intersects
|
||||||
|
* the frustum, or {@link #OUTSIDE} if the sphere is outside of the frustum
|
||||||
|
*/
|
||||||
|
public int intersectSphere(Vector3fc center, float radius) {
|
||||||
|
return intersectSphere(center.x(), center.y(), center.z(), radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given sphere is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns {@link #INTERSECT} for spheres that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x-coordinate of the sphere's center
|
||||||
|
* @param y
|
||||||
|
* the y-coordinate of the sphere's center
|
||||||
|
* @param z
|
||||||
|
* the z-coordinate of the sphere's center
|
||||||
|
* @param r
|
||||||
|
* the sphere's radius
|
||||||
|
* @return {@link #INSIDE} if the given sphere is completely inside the frustum, or {@link #INTERSECT} if the sphere intersects
|
||||||
|
* the frustum, or {@link #OUTSIDE} if the sphere is outside of the frustum
|
||||||
|
*/
|
||||||
|
public int intersectSphere(float x, float y, float z, float r) {
|
||||||
|
boolean inside = true;
|
||||||
|
float dist;
|
||||||
|
dist = nxX * x + nxY * y + nxZ * z + nxW;
|
||||||
|
if (dist >= -r) {
|
||||||
|
inside &= dist >= r;
|
||||||
|
dist = pxX * x + pxY * y + pxZ * z + pxW;
|
||||||
|
if (dist >= -r) {
|
||||||
|
inside &= dist >= r;
|
||||||
|
dist = nyX * x + nyY * y + nyZ * z + nyW;
|
||||||
|
if (dist >= -r) {
|
||||||
|
inside &= dist >= r;
|
||||||
|
dist = pyX * x + pyY * y + pyZ * z + pyW;
|
||||||
|
if (dist >= -r) {
|
||||||
|
inside &= dist >= r;
|
||||||
|
dist = nzX * x + nzY * y + nzZ * z + nzW;
|
||||||
|
if (dist >= -r) {
|
||||||
|
inside &= dist >= r;
|
||||||
|
dist = pzX * x + pzY * y + pzZ * z + pzW;
|
||||||
|
if (dist >= -r) {
|
||||||
|
inside &= dist >= r;
|
||||||
|
return inside ? INSIDE : INTERSECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OUTSIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given axis-aligned box is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler.
|
||||||
|
* The box is specified via its <code>min</code> and <code>max</code> corner coordinates.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns <code>true</code> for boxes that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
*
|
||||||
|
* @param min
|
||||||
|
* the minimum corner coordinates of the axis-aligned box
|
||||||
|
* @param max
|
||||||
|
* the maximum corner coordinates of the axis-aligned box
|
||||||
|
* @return <code>true</code> if the axis-aligned box is completely or partly inside of the frustum; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testAab(Vector3fc min, Vector3fc max) {
|
||||||
|
return testAab(min.x(), min.y(), min.z(), max.x(), max.y(), max.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given axis-aligned box is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler.
|
||||||
|
* The box is specified via its min and max corner coordinates.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns <code>true</code> for boxes that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://old.cescg.org/CESCG-2002/DSykoraJJelinek/">Efficient View Frustum Culling</a>
|
||||||
|
*
|
||||||
|
* @param minX
|
||||||
|
* the x-coordinate of the minimum corner
|
||||||
|
* @param minY
|
||||||
|
* the y-coordinate of the minimum corner
|
||||||
|
* @param minZ
|
||||||
|
* the z-coordinate of the minimum corner
|
||||||
|
* @param maxX
|
||||||
|
* the x-coordinate of the maximum corner
|
||||||
|
* @param maxY
|
||||||
|
* the y-coordinate of the maximum corner
|
||||||
|
* @param maxZ
|
||||||
|
* the z-coordinate of the maximum corner
|
||||||
|
* @return <code>true</code> if the axis-aligned box is completely or partly inside of the frustum; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
/*
|
||||||
|
* This is an implementation of the "2.4 Basic intersection test" of the mentioned site.
|
||||||
|
* It does not distinguish between partially inside and fully inside, though, so the test with the 'p' vertex is omitted.
|
||||||
|
*/
|
||||||
|
return nxX * (nxX < 0 ? minX : maxX) + nxY * (nxY < 0 ? minY : maxY) + nxZ * (nxZ < 0 ? minZ : maxZ) >= -nxW &&
|
||||||
|
pxX * (pxX < 0 ? minX : maxX) + pxY * (pxY < 0 ? minY : maxY) + pxZ * (pxZ < 0 ? minZ : maxZ) >= -pxW &&
|
||||||
|
nyX * (nyX < 0 ? minX : maxX) + nyY * (nyY < 0 ? minY : maxY) + nyZ * (nyZ < 0 ? minZ : maxZ) >= -nyW &&
|
||||||
|
pyX * (pyX < 0 ? minX : maxX) + pyY * (pyY < 0 ? minY : maxY) + pyZ * (pyZ < 0 ? minZ : maxZ) >= -pyW &&
|
||||||
|
nzX * (nzX < 0 ? minX : maxX) + nzY * (nzY < 0 ? minY : maxY) + nzZ * (nzZ < 0 ? minZ : maxZ) >= -nzW &&
|
||||||
|
pzX * (pzX < 0 ? minX : maxX) + pzY * (pzY < 0 ? minY : maxY) + pzZ * (pzZ < 0 ? minZ : maxZ) >= -pzW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given XY-plane (at <code>Z = 0</code>) is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler.
|
||||||
|
* The plane is specified via its <code>min</code> and <code>max</code> corner coordinates.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns <code>true</code> for planes that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
*
|
||||||
|
* @param min
|
||||||
|
* the minimum corner coordinates of the XY-plane
|
||||||
|
* @param max
|
||||||
|
* the maximum corner coordinates of the XY-plane
|
||||||
|
* @return <code>true</code> if the XY-plane is completely or partly inside of the frustum; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testPlaneXY(Vector2fc min, Vector2fc max) {
|
||||||
|
return testPlaneXY(min.x(), min.y(), max.x(), max.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given XY-plane (at <code>Z = 0</code>) is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler.
|
||||||
|
* The plane is specified via its min and max corner coordinates.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns <code>true</code> for planes that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://old.cescg.org/CESCG-2002/DSykoraJJelinek/">Efficient View Frustum Culling</a>
|
||||||
|
*
|
||||||
|
* @param minX
|
||||||
|
* the x-coordinate of the minimum corner
|
||||||
|
* @param minY
|
||||||
|
* the y-coordinate of the minimum corner
|
||||||
|
* @param maxX
|
||||||
|
* the x-coordinate of the maximum corner
|
||||||
|
* @param maxY
|
||||||
|
* the y-coordinate of the maximum corner
|
||||||
|
* @return <code>true</code> if the XY-plane is completely or partly inside of the frustum; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testPlaneXY(float minX, float minY, float maxX, float maxY) {
|
||||||
|
/*
|
||||||
|
* This is an implementation of the "2.4 Basic intersection test" of the mentioned site.
|
||||||
|
* It does not distinguish between partially inside and fully inside, though, so the test with the 'p' vertex is omitted.
|
||||||
|
*/
|
||||||
|
return nxX * (nxX < 0 ? minX : maxX) + nxY * (nxY < 0 ? minY : maxY) >= -nxW &&
|
||||||
|
pxX * (pxX < 0 ? minX : maxX) + pxY * (pxY < 0 ? minY : maxY) >= -pxW &&
|
||||||
|
nyX * (nyX < 0 ? minX : maxX) + nyY * (nyY < 0 ? minY : maxY) >= -nyW &&
|
||||||
|
pyX * (pyX < 0 ? minX : maxX) + pyY * (pyY < 0 ? minY : maxY) >= -pyW &&
|
||||||
|
nzX * (nzX < 0 ? minX : maxX) + nzY * (nzY < 0 ? minY : maxY) >= -nzW &&
|
||||||
|
pzX * (pzX < 0 ? minX : maxX) + pzY * (pzY < 0 ? minY : maxY) >= -pzW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given XZ-plane (at <code>Y = 0</code>) is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler.
|
||||||
|
* The plane is specified via its min and max corner coordinates.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns <code>true</code> for planes that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://old.cescg.org/CESCG-2002/DSykoraJJelinek/">Efficient View Frustum Culling</a>
|
||||||
|
*
|
||||||
|
* @param minX
|
||||||
|
* the x-coordinate of the minimum corner
|
||||||
|
* @param minZ
|
||||||
|
* the z-coordinate of the minimum corner
|
||||||
|
* @param maxX
|
||||||
|
* the x-coordinate of the maximum corner
|
||||||
|
* @param maxZ
|
||||||
|
* the z-coordinate of the maximum corner
|
||||||
|
* @return <code>true</code> if the XZ-plane is completely or partly inside of the frustum; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testPlaneXZ(float minX, float minZ, float maxX, float maxZ) {
|
||||||
|
/*
|
||||||
|
* This is an implementation of the "2.4 Basic intersection test" of the mentioned site.
|
||||||
|
* It does not distinguish between partially inside and fully inside, though, so the test with the 'p' vertex is omitted.
|
||||||
|
*/
|
||||||
|
return nxX * (nxX < 0 ? minX : maxX) + nxZ * (nxZ < 0 ? minZ : maxZ) >= -nxW &&
|
||||||
|
pxX * (pxX < 0 ? minX : maxX) + pxZ * (pxZ < 0 ? minZ : maxZ) >= -pxW &&
|
||||||
|
nyX * (nyX < 0 ? minX : maxX) + nyZ * (nyZ < 0 ? minZ : maxZ) >= -nyW &&
|
||||||
|
pyX * (pyX < 0 ? minX : maxX) + pyZ * (pyZ < 0 ? minZ : maxZ) >= -pyW &&
|
||||||
|
nzX * (nzX < 0 ? minX : maxX) + nzZ * (nzZ < 0 ? minZ : maxZ) >= -nzW &&
|
||||||
|
pzX * (pzX < 0 ? minX : maxX) + pzZ * (pzZ < 0 ? minZ : maxZ) >= -pzW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler
|
||||||
|
* and, if the box is not inside this frustum, return the index of the plane that culled it.
|
||||||
|
* The box is specified via its <code>min</code> and <code>max</code> corner coordinates.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
*
|
||||||
|
* @param min
|
||||||
|
* the minimum corner coordinates of the axis-aligned box
|
||||||
|
* @param max
|
||||||
|
* the maximum corner coordinates of the axis-aligned box
|
||||||
|
* @return the index of the first plane that culled the box, if the box does not intersect the frustum;
|
||||||
|
* or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
|
||||||
|
* The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
|
||||||
|
*/
|
||||||
|
public int intersectAab(Vector3fc min, Vector3fc max) {
|
||||||
|
return intersectAab(min.x(), min.y(), min.z(), max.x(), max.y(), max.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler
|
||||||
|
* and, if the box is not inside this frustum, return the index of the plane that culled it.
|
||||||
|
* The box is specified via its min and max corner coordinates.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://old.cescg.org/CESCG-2002/DSykoraJJelinek/">Efficient View Frustum Culling</a>
|
||||||
|
*
|
||||||
|
* @param minX
|
||||||
|
* the x-coordinate of the minimum corner
|
||||||
|
* @param minY
|
||||||
|
* the y-coordinate of the minimum corner
|
||||||
|
* @param minZ
|
||||||
|
* the z-coordinate of the minimum corner
|
||||||
|
* @param maxX
|
||||||
|
* the x-coordinate of the maximum corner
|
||||||
|
* @param maxY
|
||||||
|
* the y-coordinate of the maximum corner
|
||||||
|
* @param maxZ
|
||||||
|
* the z-coordinate of the maximum corner
|
||||||
|
* @return the index of the first plane that culled the box, if the box does not intersect the frustum,
|
||||||
|
* or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
|
||||||
|
* The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
|
||||||
|
*/
|
||||||
|
public int intersectAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
/*
|
||||||
|
* This is an implementation of the "2.4 Basic intersection test" of the mentioned site.
|
||||||
|
*
|
||||||
|
* In addition to the algorithm in the paper, this method also returns the index of the first plane that culled the box.
|
||||||
|
*/
|
||||||
|
int plane = PLANE_NX;
|
||||||
|
boolean inside = true;
|
||||||
|
if (nxX * (nxX < 0 ? minX : maxX) + nxY * (nxY < 0 ? minY : maxY) + nxZ * (nxZ < 0 ? minZ : maxZ) >= -nxW) {
|
||||||
|
plane = PLANE_PX;
|
||||||
|
inside &= nxX * (nxX < 0 ? maxX : minX) + nxY * (nxY < 0 ? maxY : minY) + nxZ * (nxZ < 0 ? maxZ : minZ) >= -nxW;
|
||||||
|
if (pxX * (pxX < 0 ? minX : maxX) + pxY * (pxY < 0 ? minY : maxY) + pxZ * (pxZ < 0 ? minZ : maxZ) >= -pxW) {
|
||||||
|
plane = PLANE_NY;
|
||||||
|
inside &= pxX * (pxX < 0 ? maxX : minX) + pxY * (pxY < 0 ? maxY : minY) + pxZ * (pxZ < 0 ? maxZ : minZ) >= -pxW;
|
||||||
|
if (nyX * (nyX < 0 ? minX : maxX) + nyY * (nyY < 0 ? minY : maxY) + nyZ * (nyZ < 0 ? minZ : maxZ) >= -nyW) {
|
||||||
|
plane = PLANE_PY;
|
||||||
|
inside &= nyX * (nyX < 0 ? maxX : minX) + nyY * (nyY < 0 ? maxY : minY) + nyZ * (nyZ < 0 ? maxZ : minZ) >= -nyW;
|
||||||
|
if (pyX * (pyX < 0 ? minX : maxX) + pyY * (pyY < 0 ? minY : maxY) + pyZ * (pyZ < 0 ? minZ : maxZ) >= -pyW) {
|
||||||
|
plane = PLANE_NZ;
|
||||||
|
inside &= pyX * (pyX < 0 ? maxX : minX) + pyY * (pyY < 0 ? maxY : minY) + pyZ * (pyZ < 0 ? maxZ : minZ) >= -pyW;
|
||||||
|
if (nzX * (nzX < 0 ? minX : maxX) + nzY * (nzY < 0 ? minY : maxY) + nzZ * (nzZ < 0 ? minZ : maxZ) >= -nzW) {
|
||||||
|
plane = PLANE_PZ;
|
||||||
|
inside &= nzX * (nzX < 0 ? maxX : minX) + nzY * (nzY < 0 ? maxY : minY) + nzZ * (nzZ < 0 ? maxZ : minZ) >= -nzW;
|
||||||
|
if (pzX * (pzX < 0 ? minX : maxX) + pzY * (pzY < 0 ? minY : maxY) + pzZ * (pzZ < 0 ? minZ : maxZ) >= -pzW) {
|
||||||
|
inside &= pzX * (pzX < 0 ? maxX : minX) + pzY * (pzY < 0 ? maxY : minY) + pzZ * (pzZ < 0 ? maxZ : minZ) >= -pzW;
|
||||||
|
return inside ? INSIDE : INTERSECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return plane;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the signed distance from the given axis-aligned box to the <code>plane</code>.
|
||||||
|
*
|
||||||
|
* @param minX
|
||||||
|
* the x-coordinate of the minimum corner
|
||||||
|
* @param minY
|
||||||
|
* the y-coordinate of the minimum corner
|
||||||
|
* @param minZ
|
||||||
|
* the z-coordinate of the minimum corner
|
||||||
|
* @param maxX
|
||||||
|
* the x-coordinate of the maximum corner
|
||||||
|
* @param maxY
|
||||||
|
* the y-coordinate of the maximum corner
|
||||||
|
* @param maxZ
|
||||||
|
* the z-coordinate of the maximum corner
|
||||||
|
* @param plane
|
||||||
|
* one of
|
||||||
|
* {@link #PLANE_NX}, {@link #PLANE_PX},
|
||||||
|
* {@link #PLANE_NY}, {@link #PLANE_PY},
|
||||||
|
* {@link #PLANE_NZ} and {@link #PLANE_PZ}
|
||||||
|
* @return the signed distance of the axis-aligned box to the plane
|
||||||
|
*/
|
||||||
|
public float distanceToPlane(float minX, float minY, float minZ, float maxX, float maxY, float maxZ, int plane) {
|
||||||
|
return planes[plane].x * (planes[plane].x < 0 ? maxX : minX) + planes[plane].y * (planes[plane].y < 0 ? maxY : minY)
|
||||||
|
+ planes[plane].z * (planes[plane].z < 0 ? maxZ : minZ) + planes[plane].w;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler
|
||||||
|
* and, if the box is not inside this frustum, return the index of the plane that culled it.
|
||||||
|
* The box is specified via its <code>min</code> and <code>max</code> corner coordinates.
|
||||||
|
* <p>
|
||||||
|
* This method differs from {@link #intersectAab(Vector3fc, Vector3fc)} in that
|
||||||
|
* it allows to mask-off planes that should not be calculated. For example, in order to only test a box against the
|
||||||
|
* left frustum plane, use a mask of {@link #PLANE_MASK_NX}. Or in order to test all planes <i>except</i> the left plane, use
|
||||||
|
* a mask of <code>(~0 ^ PLANE_MASK_NX)</code>.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
*
|
||||||
|
* @param min
|
||||||
|
* the minimum corner coordinates of the axis-aligned box
|
||||||
|
* @param max
|
||||||
|
* the maximum corner coordinates of the axis-aligned box
|
||||||
|
* @param mask
|
||||||
|
* contains as bitset all the planes that should be tested.
|
||||||
|
* This value can be any combination of
|
||||||
|
* {@link #PLANE_MASK_NX}, {@link #PLANE_MASK_PX},
|
||||||
|
* {@link #PLANE_MASK_NY}, {@link #PLANE_MASK_PY},
|
||||||
|
* {@link #PLANE_MASK_NZ} and {@link #PLANE_MASK_PZ}
|
||||||
|
* @return the index of the first plane that culled the box, if the box does not intersect the frustum,
|
||||||
|
* or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
|
||||||
|
* The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
|
||||||
|
*/
|
||||||
|
public int intersectAab(Vector3fc min, Vector3fc max, int mask) {
|
||||||
|
return intersectAab(min.x(), min.y(), min.z(), max.x(), max.y(), max.z(), mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler
|
||||||
|
* and, if the box is not inside this frustum, return the index of the plane that culled it.
|
||||||
|
* The box is specified via its min and max corner coordinates.
|
||||||
|
* <p>
|
||||||
|
* This method differs from {@link #intersectAab(float, float, float, float, float, float)} in that
|
||||||
|
* it allows to mask-off planes that should not be calculated. For example, in order to only test a box against the
|
||||||
|
* left frustum plane, use a mask of {@link #PLANE_MASK_NX}. Or in order to test all planes <i>except</i> the left plane, use
|
||||||
|
* a mask of <code>(~0 ^ PLANE_MASK_NX)</code>.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://old.cescg.org/CESCG-2002/DSykoraJJelinek/">Efficient View Frustum Culling</a>
|
||||||
|
*
|
||||||
|
* @param minX
|
||||||
|
* the x-coordinate of the minimum corner
|
||||||
|
* @param minY
|
||||||
|
* the y-coordinate of the minimum corner
|
||||||
|
* @param minZ
|
||||||
|
* the z-coordinate of the minimum corner
|
||||||
|
* @param maxX
|
||||||
|
* the x-coordinate of the maximum corner
|
||||||
|
* @param maxY
|
||||||
|
* the y-coordinate of the maximum corner
|
||||||
|
* @param maxZ
|
||||||
|
* the z-coordinate of the maximum corner
|
||||||
|
* @param mask
|
||||||
|
* contains as bitset all the planes that should be tested.
|
||||||
|
* This value can be any combination of
|
||||||
|
* {@link #PLANE_MASK_NX}, {@link #PLANE_MASK_PX},
|
||||||
|
* {@link #PLANE_MASK_NY}, {@link #PLANE_MASK_PY},
|
||||||
|
* {@link #PLANE_MASK_NZ} and {@link #PLANE_MASK_PZ}
|
||||||
|
* @return the index of the first plane that culled the box, if the box does not intersect the frustum,
|
||||||
|
* or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
|
||||||
|
* The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
|
||||||
|
*/
|
||||||
|
public int intersectAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ, int mask) {
|
||||||
|
/*
|
||||||
|
* This is an implementation of the first algorithm in "2.5 Plane masking and coherency" of the mentioned site.
|
||||||
|
*
|
||||||
|
* In addition to the algorithm in the paper, this method also returns the index of the first plane that culled the box.
|
||||||
|
*/
|
||||||
|
int plane = PLANE_NX;
|
||||||
|
boolean inside = true;
|
||||||
|
if ((mask & PLANE_MASK_NX) == 0 || nxX * (nxX < 0 ? minX : maxX) + nxY * (nxY < 0 ? minY : maxY) + nxZ * (nxZ < 0 ? minZ : maxZ) >= -nxW) {
|
||||||
|
plane = PLANE_PX;
|
||||||
|
inside &= nxX * (nxX < 0 ? maxX : minX) + nxY * (nxY < 0 ? maxY : minY) + nxZ * (nxZ < 0 ? maxZ : minZ) >= -nxW;
|
||||||
|
if ((mask & PLANE_MASK_PX) == 0 || pxX * (pxX < 0 ? minX : maxX) + pxY * (pxY < 0 ? minY : maxY) + pxZ * (pxZ < 0 ? minZ : maxZ) >= -pxW) {
|
||||||
|
plane = PLANE_NY;
|
||||||
|
inside &= pxX * (pxX < 0 ? maxX : minX) + pxY * (pxY < 0 ? maxY : minY) + pxZ * (pxZ < 0 ? maxZ : minZ) >= -pxW;
|
||||||
|
if ((mask & PLANE_MASK_NY) == 0 || nyX * (nyX < 0 ? minX : maxX) + nyY * (nyY < 0 ? minY : maxY) + nyZ * (nyZ < 0 ? minZ : maxZ) >= -nyW) {
|
||||||
|
plane = PLANE_PY;
|
||||||
|
inside &= nyX * (nyX < 0 ? maxX : minX) + nyY * (nyY < 0 ? maxY : minY) + nyZ * (nyZ < 0 ? maxZ : minZ) >= -nyW;
|
||||||
|
if ((mask & PLANE_MASK_PY) == 0 || pyX * (pyX < 0 ? minX : maxX) + pyY * (pyY < 0 ? minY : maxY) + pyZ * (pyZ < 0 ? minZ : maxZ) >= -pyW) {
|
||||||
|
plane = PLANE_NZ;
|
||||||
|
inside &= pyX * (pyX < 0 ? maxX : minX) + pyY * (pyY < 0 ? maxY : minY) + pyZ * (pyZ < 0 ? maxZ : minZ) >= -pyW;
|
||||||
|
if ((mask & PLANE_MASK_NZ) == 0 || nzX * (nzX < 0 ? minX : maxX) + nzY * (nzY < 0 ? minY : maxY) + nzZ * (nzZ < 0 ? minZ : maxZ) >= -nzW) {
|
||||||
|
plane = PLANE_PZ;
|
||||||
|
inside &= nzX * (nzX < 0 ? maxX : minX) + nzY * (nzY < 0 ? maxY : minY) + nzZ * (nzZ < 0 ? maxZ : minZ) >= -nzW;
|
||||||
|
if ((mask & PLANE_MASK_PZ) == 0 || pzX * (pzX < 0 ? minX : maxX) + pzY * (pzY < 0 ? minY : maxY) + pzZ * (pzZ < 0 ? minZ : maxZ) >= -pzW) {
|
||||||
|
inside &= pzX * (pzX < 0 ? maxX : minX) + pzY * (pzY < 0 ? maxY : minY) + pzZ * (pzZ < 0 ? maxZ : minZ) >= -pzW;
|
||||||
|
return inside ? INSIDE : INTERSECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return plane;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler
|
||||||
|
* and, if the box is not inside this frustum, return the index of the plane that culled it.
|
||||||
|
* The box is specified via its <code>min</code> and <code>max</code> corner coordinates.
|
||||||
|
* <p>
|
||||||
|
* This method differs from {@link #intersectAab(Vector3fc, Vector3fc)} in that
|
||||||
|
* it allows to mask-off planes that should not be calculated. For example, in order to only test a box against the
|
||||||
|
* left frustum plane, use a mask of {@link #PLANE_MASK_NX}. Or in order to test all planes <i>except</i> the left plane, use
|
||||||
|
* a mask of <code>(~0 ^ PLANE_MASK_NX)</code>.
|
||||||
|
* <p>
|
||||||
|
* In addition, the <code>startPlane</code> denotes the first frustum plane to test the box against. To use this effectively means to store the
|
||||||
|
* plane that previously culled an axis-aligned box (as returned by <code>intersectAab()</code>) and in the next frame use the return value
|
||||||
|
* as the argument to the <code>startPlane</code> parameter of this method. The assumption is that the plane that culled the object previously will also
|
||||||
|
* cull it now (temporal coherency) and the culling computation is likely reduced in that case.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
*
|
||||||
|
* @param min
|
||||||
|
* the minimum corner coordinates of the axis-aligned box
|
||||||
|
* @param max
|
||||||
|
* the maximum corner coordinates of the axis-aligned box
|
||||||
|
* @param mask
|
||||||
|
* contains as bitset all the planes that should be tested.
|
||||||
|
* This value can be any combination of
|
||||||
|
* {@link #PLANE_MASK_NX}, {@link #PLANE_MASK_PX},
|
||||||
|
* {@link #PLANE_MASK_NY}, {@link #PLANE_MASK_PY},
|
||||||
|
* {@link #PLANE_MASK_NZ} and {@link #PLANE_MASK_PZ}
|
||||||
|
* @param startPlane
|
||||||
|
* the first frustum plane to test the axis-aligned box against. It is one of
|
||||||
|
* {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
|
||||||
|
* @return the index of the first plane that culled the box, if the box does not intersect the frustum,
|
||||||
|
* or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
|
||||||
|
* The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
|
||||||
|
*/
|
||||||
|
public int intersectAab(Vector3fc min, Vector3fc max, int mask, int startPlane) {
|
||||||
|
return intersectAab(min.x(), min.y(), min.z(), max.x(), max.y(), max.z(), mask, startPlane);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by <code>this</code> frustum culler
|
||||||
|
* and, if the box is not inside this frustum, return the index of the plane that culled it.
|
||||||
|
* The box is specified via its min and max corner coordinates.
|
||||||
|
* <p>
|
||||||
|
* This method differs from {@link #intersectAab(float, float, float, float, float, float)} in that
|
||||||
|
* it allows to mask-off planes that should not be calculated. For example, in order to only test a box against the
|
||||||
|
* left frustum plane, use a mask of {@link #PLANE_MASK_NX}. Or in order to test all planes <i>except</i> the left plane, use
|
||||||
|
* a mask of <code>(~0 ^ PLANE_MASK_NX)</code>.
|
||||||
|
* <p>
|
||||||
|
* In addition, the <code>startPlane</code> denotes the first frustum plane to test the box against. To use this effectively means to store the
|
||||||
|
* plane that previously culled an axis-aligned box (as returned by <code>intersectAab()</code>) and in the next frame use the return value
|
||||||
|
* as the argument to the <code>startPlane</code> parameter of this method. The assumption is that the plane that culled the object previously will also
|
||||||
|
* cull it now (temporal coherency) and the culling computation is likely reduced in that case.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented by this method is conservative. This means that in certain circumstances a <i>false positive</i>
|
||||||
|
* can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
|
||||||
|
* See <a href="http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm">iquilezles.org</a> for an examination of this problem.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://old.cescg.org/CESCG-2002/DSykoraJJelinek/">Efficient View Frustum Culling</a>
|
||||||
|
*
|
||||||
|
* @param minX
|
||||||
|
* the x-coordinate of the minimum corner
|
||||||
|
* @param minY
|
||||||
|
* the y-coordinate of the minimum corner
|
||||||
|
* @param minZ
|
||||||
|
* the z-coordinate of the minimum corner
|
||||||
|
* @param maxX
|
||||||
|
* the x-coordinate of the maximum corner
|
||||||
|
* @param maxY
|
||||||
|
* the y-coordinate of the maximum corner
|
||||||
|
* @param maxZ
|
||||||
|
* the z-coordinate of the maximum corner
|
||||||
|
* @param mask
|
||||||
|
* contains as bitset all the planes that should be tested.
|
||||||
|
* This value can be any combination of
|
||||||
|
* {@link #PLANE_MASK_NX}, {@link #PLANE_MASK_PX},
|
||||||
|
* {@link #PLANE_MASK_NY}, {@link #PLANE_MASK_PY},
|
||||||
|
* {@link #PLANE_MASK_NZ} and {@link #PLANE_MASK_PZ}
|
||||||
|
* @param startPlane
|
||||||
|
* the first frustum plane to test the axis-aligned box against. It is one of
|
||||||
|
* {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
|
||||||
|
* @return the index of the first plane that culled the box, if the box does not intersect the frustum,
|
||||||
|
* or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
|
||||||
|
* The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
|
||||||
|
*/
|
||||||
|
public int intersectAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ, int mask, int startPlane) {
|
||||||
|
/*
|
||||||
|
* This is an implementation of the second algorithm in "2.5 Plane masking and coherency" of the mentioned site.
|
||||||
|
*
|
||||||
|
* In addition to the algorithm in the paper, this method also returns the index of the first plane that culled the box.
|
||||||
|
*/
|
||||||
|
int plane = startPlane;
|
||||||
|
boolean inside = true;
|
||||||
|
Vector4f p = planes[startPlane];
|
||||||
|
if ((mask & 1<<startPlane) != 0 && p.x * (p.x < 0 ? minX : maxX) + p.y * (p.y < 0 ? minY : maxY) + p.z * (p.z < 0 ? minZ : maxZ) < -p.w) {
|
||||||
|
return plane;
|
||||||
|
}
|
||||||
|
if ((mask & PLANE_MASK_NX) == 0 || nxX * (nxX < 0 ? minX : maxX) + nxY * (nxY < 0 ? minY : maxY) + nxZ * (nxZ < 0 ? minZ : maxZ) >= -nxW) {
|
||||||
|
plane = PLANE_PX;
|
||||||
|
inside &= nxX * (nxX < 0 ? maxX : minX) + nxY * (nxY < 0 ? maxY : minY) + nxZ * (nxZ < 0 ? maxZ : minZ) >= -nxW;
|
||||||
|
if ((mask & PLANE_MASK_PX) == 0 || pxX * (pxX < 0 ? minX : maxX) + pxY * (pxY < 0 ? minY : maxY) + pxZ * (pxZ < 0 ? minZ : maxZ) >= -pxW) {
|
||||||
|
plane = PLANE_NY;
|
||||||
|
inside &= pxX * (pxX < 0 ? maxX : minX) + pxY * (pxY < 0 ? maxY : minY) + pxZ * (pxZ < 0 ? maxZ : minZ) >= -pxW;
|
||||||
|
if ((mask & PLANE_MASK_NY) == 0 || nyX * (nyX < 0 ? minX : maxX) + nyY * (nyY < 0 ? minY : maxY) + nyZ * (nyZ < 0 ? minZ : maxZ) >= -nyW) {
|
||||||
|
plane = PLANE_PY;
|
||||||
|
inside &= nyX * (nyX < 0 ? maxX : minX) + nyY * (nyY < 0 ? maxY : minY) + nyZ * (nyZ < 0 ? maxZ : minZ) >= -nyW;
|
||||||
|
if ((mask & PLANE_MASK_PY) == 0 || pyX * (pyX < 0 ? minX : maxX) + pyY * (pyY < 0 ? minY : maxY) + pyZ * (pyZ < 0 ? minZ : maxZ) >= -pyW) {
|
||||||
|
plane = PLANE_NZ;
|
||||||
|
inside &= pyX * (pyX < 0 ? maxX : minX) + pyY * (pyY < 0 ? maxY : minY) + pyZ * (pyZ < 0 ? maxZ : minZ) >= -pyW;
|
||||||
|
if ((mask & PLANE_MASK_NZ) == 0 || nzX * (nzX < 0 ? minX : maxX) + nzY * (nzY < 0 ? minY : maxY) + nzZ * (nzZ < 0 ? minZ : maxZ) >= -nzW) {
|
||||||
|
plane = PLANE_PZ;
|
||||||
|
inside &= nzX * (nzX < 0 ? maxX : minX) + nzY * (nzY < 0 ? maxY : minY) + nzZ * (nzZ < 0 ? maxZ : minZ) >= -nzW;
|
||||||
|
if ((mask & PLANE_MASK_PZ) == 0 || pzX * (pzX < 0 ? minX : maxX) + pzY * (pzY < 0 ? minY : maxY) + pzZ * (pzZ < 0 ? minZ : maxZ) >= -pzW) {
|
||||||
|
inside &= pzX * (pzX < 0 ? maxX : minX) + pzY * (pzY < 0 ? maxY : minY) + pzZ * (pzZ < 0 ? maxZ : minZ) >= -pzW;
|
||||||
|
return inside ? INSIDE : INTERSECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return plane;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given line segment, defined by the end points <code>a</code> and <code>b</code>,
|
||||||
|
* is partly or completely within the frustum defined by <code>this</code> frustum culler.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the line segment's first end point
|
||||||
|
* @param b
|
||||||
|
* the line segment's second end point
|
||||||
|
* @return <code>true</code> if the given line segment is partly or completely inside the frustum;
|
||||||
|
* <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testLineSegment(Vector3fc a, Vector3fc b) {
|
||||||
|
return testLineSegment(a.x(), a.y(), a.z(), b.x(), b.y(), b.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given line segment, defined by the end points <code>(aX, aY, aZ)</code> and <code>(bX, bY, bZ)</code>,
|
||||||
|
* is partly or completely within the frustum defined by <code>this</code> frustum culler.
|
||||||
|
*
|
||||||
|
* @param aX
|
||||||
|
* the x coordinate of the line segment's first end point
|
||||||
|
* @param aY
|
||||||
|
* the y coordinate of the line segment's first end point
|
||||||
|
* @param aZ
|
||||||
|
* the z coordinate of the line segment's first end point
|
||||||
|
* @param bX
|
||||||
|
* the x coordinate of the line segment's second end point
|
||||||
|
* @param bY
|
||||||
|
* the y coordinate of the line segment's second end point
|
||||||
|
* @param bZ
|
||||||
|
* the z coordinate of the line segment's second end point
|
||||||
|
* @return <code>true</code> if the given line segment is partly or completely inside the frustum;
|
||||||
|
* <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testLineSegment(float aX, float aY, float aZ, float bX, float bY, float bZ) {
|
||||||
|
float da, db;
|
||||||
|
da = Math.fma(nxX, aX, Math.fma(nxY, aY, Math.fma(nxZ, aZ, nxW)));
|
||||||
|
db = Math.fma(nxX, bX, Math.fma(nxY, bY, Math.fma(nxZ, bZ, nxW)));
|
||||||
|
if (da < 0.0f && db < 0.0f)
|
||||||
|
return false;
|
||||||
|
if (da * db < 0.0f) {
|
||||||
|
float p = Math.abs(da) / Math.abs(db - da);
|
||||||
|
float dx = Math.fma(bX - aX, p, aX), dy = Math.fma(bY - aY, p, aY), dz = Math.fma(bZ - aZ, p, aZ);
|
||||||
|
if (da < 0.0f) {
|
||||||
|
aX = dx; aY = dy; aZ = dz;
|
||||||
|
} else {
|
||||||
|
bX = dx; bY = dy; bZ = dz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
da = Math.fma(pxX, aX, Math.fma(pxY, aY, Math.fma(pxZ, aZ, pxW)));
|
||||||
|
db = Math.fma(pxX, bX, Math.fma(pxY, bY, Math.fma(pxZ, bZ, pxW)));
|
||||||
|
if (da < 0.0f && db < 0.0f)
|
||||||
|
return false;
|
||||||
|
if (da * db < 0.0f) {
|
||||||
|
float p = Math.abs(da) / Math.abs(db - da);
|
||||||
|
float dx = Math.fma(bX - aX, p, aX), dy = Math.fma(bY - aY, p, aY), dz = Math.fma(bZ - aZ, p, aZ);
|
||||||
|
if (da < 0.0f) {
|
||||||
|
aX = dx; aY = dy; aZ = dz;
|
||||||
|
} else {
|
||||||
|
bX = dx; bY = dy; bZ = dz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
da = Math.fma(nyX, aX, Math.fma(nyY, aY, Math.fma(nyZ, aZ, nyW)));
|
||||||
|
db = Math.fma(nyX, bX, Math.fma(nyY, bY, Math.fma(nyZ, bZ, nyW)));
|
||||||
|
if (da < 0.0f && db < 0.0f)
|
||||||
|
return false;
|
||||||
|
if (da * db < 0.0f) {
|
||||||
|
float p = Math.abs(da) / Math.abs(db - da);
|
||||||
|
float dx = Math.fma(bX - aX, p, aX), dy = Math.fma(bY - aY, p, aY), dz = Math.fma(bZ - aZ, p, aZ);
|
||||||
|
if (da < 0.0f) {
|
||||||
|
aX = dx; aY = dy; aZ = dz;
|
||||||
|
} else {
|
||||||
|
bX = dx; bY = dy; bZ = dz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
da = Math.fma(pyX, aX, Math.fma(pyY, aY, Math.fma(pyZ, aZ, pyW)));
|
||||||
|
db = Math.fma(pyX, bX, Math.fma(pyY, bY, Math.fma(pyZ, bZ, pyW)));
|
||||||
|
if (da < 0.0f && db < 0.0f)
|
||||||
|
return false;
|
||||||
|
if (da * db < 0.0f) {
|
||||||
|
float p = Math.abs(da) / Math.abs(db - da);
|
||||||
|
float dx = Math.fma(bX - aX, p, aX), dy = Math.fma(bY - aY, p, aY), dz = Math.fma(bZ - aZ, p, aZ);
|
||||||
|
if (da < 0.0f) {
|
||||||
|
aX = dx; aY = dy; aZ = dz;
|
||||||
|
} else {
|
||||||
|
bX = dx; bY = dy; bZ = dz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
da = Math.fma(nzX, aX, Math.fma(nzY, aY, Math.fma(nzZ, aZ, nzW)));
|
||||||
|
db = Math.fma(nzX, bX, Math.fma(nzY, bY, Math.fma(nzZ, bZ, nzW)));
|
||||||
|
if (da < 0.0f && db < 0.0f)
|
||||||
|
return false;
|
||||||
|
if (da * db < 0.0f) {
|
||||||
|
float p = Math.abs(da) / Math.abs(db - da);
|
||||||
|
float dx = Math.fma(bX - aX, p, aX), dy = Math.fma(bY - aY, p, aY), dz = Math.fma(bZ - aZ, p, aZ);
|
||||||
|
if (da < 0.0f) {
|
||||||
|
aX = dx; aY = dy; aZ = dz;
|
||||||
|
} else {
|
||||||
|
bX = dx; bY = dy; bZ = dz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
da = Math.fma(pzX, aX, Math.fma(pzY, aY, Math.fma(pzZ, aZ, pzW)));
|
||||||
|
db = Math.fma(pzX, bX, Math.fma(pzY, bY, Math.fma(pzZ, bZ, pzW)));
|
||||||
|
return da >= 0.0f || db >= 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 Kai Burjack
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides methods to compute rays through an arbitrary perspective transformation defined by a {@link Matrix4fc}.
|
||||||
|
* <p>
|
||||||
|
* This can be used to compute the eye-rays in simple software-based raycasting/raytracing.
|
||||||
|
* <p>
|
||||||
|
* To obtain the origin of the rays call {@link #origin(Vector3f)}.
|
||||||
|
* Then to compute the directions of subsequent rays use {@link #dir(float, float, Vector3f)}.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class FrustumRayBuilder {
|
||||||
|
|
||||||
|
private float nxnyX, nxnyY, nxnyZ;
|
||||||
|
private float pxnyX, pxnyY, pxnyZ;
|
||||||
|
private float pxpyX, pxpyY, pxpyZ;
|
||||||
|
private float nxpyX, nxpyY, nxpyZ;
|
||||||
|
private float cx, cy, cz;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link FrustumRayBuilder} with an undefined frustum.
|
||||||
|
* <p>
|
||||||
|
* Before obtaining ray directions, make sure to define the frustum using {@link #set(Matrix4fc)}.
|
||||||
|
*/
|
||||||
|
public FrustumRayBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link FrustumRayBuilder} from the given {@link Matrix4fc matrix} by extracing the matrix's frustum.
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the {@link Matrix4fc} to create the frustum from
|
||||||
|
*/
|
||||||
|
public FrustumRayBuilder(Matrix4fc m) {
|
||||||
|
set(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the stored frustum corner rays and origin of <code>this</code> {@link FrustumRayBuilder} with the given {@link Matrix4fc matrix}.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://gamedevs.org/uploads/fast-extraction-viewing-frustum-planes-from-world-view-projection-matrix.pdf">
|
||||||
|
* Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix</a>
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://geomalgorithms.com/a05-_intersect-1.html">http://geomalgorithms.com</a>
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the {@link Matrix4fc matrix} to update the frustum corner rays and origin with
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public FrustumRayBuilder set(Matrix4fc m) {
|
||||||
|
float nxX = m.m03() + m.m00(), nxY = m.m13() + m.m10(), nxZ = m.m23() + m.m20(), d1 = m.m33() + m.m30();
|
||||||
|
float pxX = m.m03() - m.m00(), pxY = m.m13() - m.m10(), pxZ = m.m23() - m.m20(), d2 = m.m33() - m.m30();
|
||||||
|
float nyX = m.m03() + m.m01(), nyY = m.m13() + m.m11(), nyZ = m.m23() + m.m21();
|
||||||
|
float pyX = m.m03() - m.m01(), pyY = m.m13() - m.m11(), pyZ = m.m23() - m.m21(), d3 = m.m33() - m.m31();
|
||||||
|
// bottom left
|
||||||
|
nxnyX = nyY * nxZ - nyZ * nxY;
|
||||||
|
nxnyY = nyZ * nxX - nyX * nxZ;
|
||||||
|
nxnyZ = nyX * nxY - nyY * nxX;
|
||||||
|
// bottom right
|
||||||
|
pxnyX = pxY * nyZ - pxZ * nyY;
|
||||||
|
pxnyY = pxZ * nyX - pxX * nyZ;
|
||||||
|
pxnyZ = pxX * nyY - pxY * nyX;
|
||||||
|
// top left
|
||||||
|
nxpyX = nxY * pyZ - nxZ * pyY;
|
||||||
|
nxpyY = nxZ * pyX - nxX * pyZ;
|
||||||
|
nxpyZ = nxX * pyY - nxY * pyX;
|
||||||
|
// top right
|
||||||
|
pxpyX = pyY * pxZ - pyZ * pxY;
|
||||||
|
pxpyY = pyZ * pxX - pyX * pxZ;
|
||||||
|
pxpyZ = pyX * pxY - pyY * pxX;
|
||||||
|
// compute origin
|
||||||
|
float pxnxX, pxnxY, pxnxZ;
|
||||||
|
pxnxX = pxY * nxZ - pxZ * nxY;
|
||||||
|
pxnxY = pxZ * nxX - pxX * nxZ;
|
||||||
|
pxnxZ = pxX * nxY - pxY * nxX;
|
||||||
|
float invDot = 1.0f / (nxX * pxpyX + nxY * pxpyY + nxZ * pxpyZ);
|
||||||
|
cx = (-pxpyX * d1 - nxpyX * d2 - pxnxX * d3) * invDot;
|
||||||
|
cy = (-pxpyY * d1 - nxpyY * d2 - pxnxY * d3) * invDot;
|
||||||
|
cz = (-pxpyZ * d1 - nxpyZ * d2 - pxnxZ * d3) * invDot;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the eye/origin of the perspective frustum in the given <code>origin</code>.
|
||||||
|
*
|
||||||
|
* @param origin
|
||||||
|
* will hold the perspective origin
|
||||||
|
* @return the <code>origin</code> vector
|
||||||
|
*/
|
||||||
|
public Vector3fc origin(Vector3f origin) {
|
||||||
|
origin.x = cx;
|
||||||
|
origin.y = cy;
|
||||||
|
origin.z = cz;
|
||||||
|
return origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the normalized direction of a ray starting at the center of the coordinate system and going
|
||||||
|
* through the near frustum plane.
|
||||||
|
* <p>
|
||||||
|
* The parameters <code>x</code> and <code>y</code> are used to interpolate the generated ray direction
|
||||||
|
* from the bottom-left to the top-right frustum corners.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the interpolation factor along the left-to-right frustum planes, within <code>[0..1]</code>
|
||||||
|
* @param y
|
||||||
|
* the interpolation factor along the bottom-to-top frustum planes, within <code>[0..1]</code>
|
||||||
|
* @param dir
|
||||||
|
* will hold the normalized ray direction
|
||||||
|
* @return the <code>dir</code> vector
|
||||||
|
*/
|
||||||
|
public Vector3fc dir(float x, float y, Vector3f dir) {
|
||||||
|
float y1x = nxnyX + (nxpyX - nxnyX) * y;
|
||||||
|
float y1y = nxnyY + (nxpyY - nxnyY) * y;
|
||||||
|
float y1z = nxnyZ + (nxpyZ - nxnyZ) * y;
|
||||||
|
float y2x = pxnyX + (pxpyX - pxnyX) * y;
|
||||||
|
float y2y = pxnyY + (pxpyY - pxnyY) * y;
|
||||||
|
float y2z = pxnyZ + (pxpyZ - pxnyZ) * y;
|
||||||
|
float dx = y1x + (y2x - y1x) * x;
|
||||||
|
float dy = y1y + (y2y - y1y) * x;
|
||||||
|
float dz = y1z + (y2z - y1z) * x;
|
||||||
|
// normalize the vector
|
||||||
|
float invLen = Math.invsqrt(dx * dx + dy * dy + dz * dz);
|
||||||
|
dir.x = dx * invLen;
|
||||||
|
dir.y = dy * invLen;
|
||||||
|
dir.z = dz * invLen;
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,247 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 Kai Burjack
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Useful geometry methods.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
* @author Richard Greenlees
|
||||||
|
*/
|
||||||
|
public class GeometryUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute two arbitrary vectors perpendicular to the given normalized vector <code>(x, y, z)</code>, and store them in <code>dest1</code> and <code>dest2</code>,
|
||||||
|
* respectively.
|
||||||
|
* <p>
|
||||||
|
* The computed vectors will themselves be perpendicular to each another and normalized. So the tree vectors <code>(x, y, z)</code>, <code>dest1</code> and
|
||||||
|
* <code>dest2</code> form an orthonormal basis.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the normalized input vector
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the normalized input vector
|
||||||
|
* @param z
|
||||||
|
* the z coordinate of the normalized input vector
|
||||||
|
* @param dest1
|
||||||
|
* will hold the first perpendicular vector
|
||||||
|
* @param dest2
|
||||||
|
* will hold the second perpendicular vector
|
||||||
|
*/
|
||||||
|
public static void perpendicular(float x, float y, float z, Vector3f dest1, Vector3f dest2) {
|
||||||
|
float magX = z * z + y * y;
|
||||||
|
float magY = z * z + x * x;
|
||||||
|
float magZ = y * y + x * x;
|
||||||
|
float mag;
|
||||||
|
if (magX > magY && magX > magZ) {
|
||||||
|
dest1.x = 0;
|
||||||
|
dest1.y = z;
|
||||||
|
dest1.z = -y;
|
||||||
|
mag = magX;
|
||||||
|
} else if (magY > magZ) {
|
||||||
|
dest1.x = -z;
|
||||||
|
dest1.y = 0;
|
||||||
|
dest1.z = x;
|
||||||
|
mag = magY;
|
||||||
|
} else {
|
||||||
|
dest1.x = y;
|
||||||
|
dest1.y = -x;
|
||||||
|
dest1.z = 0;
|
||||||
|
mag = magZ;
|
||||||
|
}
|
||||||
|
float len = Math.invsqrt(mag);
|
||||||
|
dest1.x *= len;
|
||||||
|
dest1.y *= len;
|
||||||
|
dest1.z *= len;
|
||||||
|
dest2.x = y * dest1.z - z * dest1.y;
|
||||||
|
dest2.y = z * dest1.x - x * dest1.z;
|
||||||
|
dest2.z = x * dest1.y - y * dest1.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute two arbitrary vectors perpendicular to the given normalized vector <code>v</code>, and store them in <code>dest1</code> and <code>dest2</code>,
|
||||||
|
* respectively.
|
||||||
|
* <p>
|
||||||
|
* The computed vectors will themselves be perpendicular to each another and normalized. So the tree vectors <code>v</code>, <code>dest1</code> and
|
||||||
|
* <code>dest2</code> form an orthonormal basis.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the {@link Vector3f#normalize() normalized} input vector
|
||||||
|
* @param dest1
|
||||||
|
* will hold the first perpendicular vector
|
||||||
|
* @param dest2
|
||||||
|
* will hold the second perpendicular vector
|
||||||
|
*/
|
||||||
|
public static void perpendicular(Vector3fc v, Vector3f dest1, Vector3f dest2) {
|
||||||
|
perpendicular(v.x(), v.y(), v.z(), dest1, dest2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the normal of a surface defined by points <code>v1</code>, <code>v2</code> and <code>v3</code> and store it in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v0
|
||||||
|
* the first position
|
||||||
|
* @param v1
|
||||||
|
* the second position
|
||||||
|
* @param v2
|
||||||
|
* the third position
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
*/
|
||||||
|
public static void normal(Vector3fc v0, Vector3fc v1, Vector3fc v2, Vector3f dest) {
|
||||||
|
normal(v0.x(), v0.y(), v0.z(), v1.x(), v1.y(), v1.z(), v2.x(), v2.y(), v2.z(), dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the normal of a surface defined by points <code>(v1X, v1Y, v1Z)</code>, <code>(v2X, v2Y, v2Z)</code> and <code>(v3X, v3Y, v3Z)</code>
|
||||||
|
* and store it in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first position
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first position
|
||||||
|
* @param v0Z
|
||||||
|
* the z coordinate of the first position
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second position
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second position
|
||||||
|
* @param v1Z
|
||||||
|
* the z coordinate of the second position
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third position
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third position
|
||||||
|
* @param v2Z
|
||||||
|
* the z coordinate of the third position
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
*/
|
||||||
|
public static void normal(float v0X, float v0Y, float v0Z, float v1X, float v1Y, float v1Z, float v2X, float v2Y, float v2Z, Vector3f dest) {
|
||||||
|
dest.x = ((v1Y - v0Y) * (v2Z - v0Z)) - ((v1Z - v0Z) * (v2Y - v0Y));
|
||||||
|
dest.y = ((v1Z - v0Z) * (v2X - v0X)) - ((v1X - v0X) * (v2Z - v0Z));
|
||||||
|
dest.z = ((v1X - v0X) * (v2Y - v0Y)) - ((v1Y - v0Y) * (v2X - v0X));
|
||||||
|
dest.normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the surface tangent for the three supplied vertices and UV coordinates and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v1
|
||||||
|
* XYZ of first vertex
|
||||||
|
* @param uv1
|
||||||
|
* UV of first vertex
|
||||||
|
* @param v2
|
||||||
|
* XYZ of second vertex
|
||||||
|
* @param uv2
|
||||||
|
* UV of second vertex
|
||||||
|
* @param v3
|
||||||
|
* XYZ of third vertex
|
||||||
|
* @param uv3
|
||||||
|
* UV of third vertex
|
||||||
|
* @param dest
|
||||||
|
* the tangent will be stored here
|
||||||
|
*/
|
||||||
|
public static void tangent(Vector3fc v1, Vector2fc uv1, Vector3fc v2, Vector2fc uv2, Vector3fc v3, Vector2fc uv3, Vector3f dest) {
|
||||||
|
float DeltaV1 = uv2.y() - uv1.y();
|
||||||
|
float DeltaV2 = uv3.y() - uv1.y();
|
||||||
|
|
||||||
|
float f = 1.0f / ((uv2.x() - uv1.x()) * DeltaV2 - (uv3.x() - uv1.x()) * DeltaV1);
|
||||||
|
|
||||||
|
dest.x = f * (DeltaV2 * (v2.x() - v1.x()) - DeltaV1 * (v3.x() - v1.x()));
|
||||||
|
dest.y = f * (DeltaV2 * (v2.y() - v1.y()) - DeltaV1 * (v3.y() - v1.y()));
|
||||||
|
dest.z = f * (DeltaV2 * (v2.z() - v1.z()) - DeltaV1 * (v3.z() - v1.z()));
|
||||||
|
dest.normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the surface bitangent for the three supplied vertices and UV coordinates and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v1
|
||||||
|
* XYZ of first vertex
|
||||||
|
* @param uv1
|
||||||
|
* UV of first vertex
|
||||||
|
* @param v2
|
||||||
|
* XYZ of second vertex
|
||||||
|
* @param uv2
|
||||||
|
* UV of second vertex
|
||||||
|
* @param v3
|
||||||
|
* XYZ of third vertex
|
||||||
|
* @param uv3
|
||||||
|
* UV of third vertex
|
||||||
|
* @param dest
|
||||||
|
* the binormal will be stored here
|
||||||
|
*/
|
||||||
|
public static void bitangent(Vector3fc v1, Vector2fc uv1, Vector3fc v2, Vector2fc uv2, Vector3fc v3, Vector2fc uv3, Vector3f dest) {
|
||||||
|
float DeltaU1 = uv2.x() - uv1.x();
|
||||||
|
float DeltaU2 = uv3.x() - uv1.x();
|
||||||
|
|
||||||
|
float f = 1.0f / (DeltaU1 * (uv3.y() - uv1.y()) - DeltaU2 * (uv2.y() - uv1.y()));
|
||||||
|
|
||||||
|
dest.x = f * (-DeltaU2 * (v2.x() - v1.x()) + DeltaU1 * (v3.x() - v1.x()));
|
||||||
|
dest.y = f * (-DeltaU2 * (v2.y() - v1.y()) + DeltaU1 * (v3.y() - v1.y()));
|
||||||
|
dest.z = f * (-DeltaU2 * (v2.z() - v1.z()) + DeltaU1 * (v3.z() - v1.z()));
|
||||||
|
dest.normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the surface tangent and bitangent for the three supplied vertices and UV coordinates and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v1
|
||||||
|
* XYZ of first vertex
|
||||||
|
* @param uv1
|
||||||
|
* UV of first vertex
|
||||||
|
* @param v2
|
||||||
|
* XYZ of second vertex
|
||||||
|
* @param uv2
|
||||||
|
* UV of second vertex
|
||||||
|
* @param v3
|
||||||
|
* XYZ of third vertex
|
||||||
|
* @param uv3
|
||||||
|
* UV of third vertex
|
||||||
|
* @param destTangent
|
||||||
|
* the tangent will be stored here
|
||||||
|
* @param destBitangent
|
||||||
|
* the bitangent will be stored here
|
||||||
|
*/
|
||||||
|
public static void tangentBitangent(Vector3fc v1, Vector2fc uv1, Vector3fc v2, Vector2fc uv2, Vector3fc v3, Vector2fc uv3, Vector3f destTangent, Vector3f destBitangent) {
|
||||||
|
float DeltaV1 = uv2.y() - uv1.y();
|
||||||
|
float DeltaV2 = uv3.y() - uv1.y();
|
||||||
|
float DeltaU1 = uv2.x() - uv1.x();
|
||||||
|
float DeltaU2 = uv3.x() - uv1.x();
|
||||||
|
|
||||||
|
float f = 1.0f / (DeltaU1 * DeltaV2 - DeltaU2 * DeltaV1);
|
||||||
|
|
||||||
|
destTangent.x = f * (DeltaV2 * (v2.x() - v1.x()) - DeltaV1 * (v3.x() - v1.x()));
|
||||||
|
destTangent.y = f * (DeltaV2 * (v2.y() - v1.y()) - DeltaV1 * (v3.y() - v1.y()));
|
||||||
|
destTangent.z = f * (DeltaV2 * (v2.z() - v1.z()) - DeltaV1 * (v3.z() - v1.z()));
|
||||||
|
destTangent.normalize();
|
||||||
|
|
||||||
|
destBitangent.x = f * (-DeltaU2 * (v2.x() - v1.x()) + DeltaU1 * (v3.x() - v1.x()));
|
||||||
|
destBitangent.y = f * (-DeltaU2 * (v2.y() - v1.y()) + DeltaU1 * (v3.y() - v1.y()));
|
||||||
|
destBitangent.z = f * (-DeltaU2 * (v2.z() - v1.z()) + DeltaU1 * (v3.z() - v1.z()));
|
||||||
|
destBitangent.normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,337 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 Kai Burjack
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains various interpolation functions.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Interpolationd {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bilinearly interpolate the single scalar value <i>f</i> over the given triangle.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="https://en.wikipedia.org/wiki/Barycentric_coordinate_system">https://en.wikipedia.org/</a>
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param f0
|
||||||
|
* the value of <i>f</i> at the first vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param f1
|
||||||
|
* the value of <i>f</i> at the second vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param f2
|
||||||
|
* the value of <i>f</i> at the third vertex
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @return the interpolated value of <i>f</i>
|
||||||
|
*/
|
||||||
|
public static double interpolateTriangle(
|
||||||
|
double v0X, double v0Y, double f0,
|
||||||
|
double v1X, double v1Y, double f1,
|
||||||
|
double v2X, double v2Y, double f2,
|
||||||
|
double x, double y) {
|
||||||
|
double v12Y = v1Y - v2Y;
|
||||||
|
double v21X = v2X - v1X;
|
||||||
|
double v02X = v0X - v2X;
|
||||||
|
double yv2Y = y - v2Y;
|
||||||
|
double xv2X = x - v2X;
|
||||||
|
double v02Y = v0Y - v2Y;
|
||||||
|
double invDen = 1.0 / (v12Y * v02X + v21X * v02Y);
|
||||||
|
double l1 = (v12Y * xv2X + v21X * yv2Y) * invDen;
|
||||||
|
double l2 = (v02X * yv2Y - v02Y * xv2X) * invDen;
|
||||||
|
return l1 * f0 + l2 * f1 + (1.0f - l1 - l2) * f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bilinearly interpolate the two-dimensional vector <i>f</i> over the given triangle and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="https://en.wikipedia.org/wiki/Barycentric_coordinate_system">https://en.wikipedia.org/</a>
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param f0X
|
||||||
|
* the x component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param f0Y
|
||||||
|
* the y component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param f1X
|
||||||
|
* the x component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param f1Y
|
||||||
|
* the y component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param f2X
|
||||||
|
* the x component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param f2Y
|
||||||
|
* the y component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @param dest
|
||||||
|
* will hold the interpolation result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public static Vector2d interpolateTriangle(
|
||||||
|
double v0X, double v0Y, double f0X, double f0Y,
|
||||||
|
double v1X, double v1Y, double f1X, double f1Y,
|
||||||
|
double v2X, double v2Y, double f2X, double f2Y,
|
||||||
|
double x, double y, Vector2d dest) {
|
||||||
|
double v12Y = v1Y - v2Y;
|
||||||
|
double v21X = v2X - v1X;
|
||||||
|
double v02X = v0X - v2X;
|
||||||
|
double yv2Y = y - v2Y;
|
||||||
|
double xv2X = x - v2X;
|
||||||
|
double v02Y = v0Y - v2Y;
|
||||||
|
double invDen = 1.0 / (v12Y * v02X + v21X * v02Y);
|
||||||
|
double l1 = (v12Y * xv2X + v21X * yv2Y) * invDen;
|
||||||
|
double l2 = (v02X * yv2Y - v02Y * xv2X) * invDen;
|
||||||
|
double l3 = 1.0 - l1 - l2;
|
||||||
|
dest.x = l1 * f0X + l2 * f1X + l3 * f2X;
|
||||||
|
dest.y = l1 * f0Y + l2 * f1Y + l3 * f2Y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the first-order derivative of a linear two-dimensional function <i>f</i> with respect to X
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* This method computes the constant rate of change for <i>f</i> given the three values of <i>f</i>
|
||||||
|
* at the specified three inputs <code>(v0X, v0Y)</code>, <code>(v1X, v1Y)</code> and <code>(v2X, v2Y)</code>.
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param f0X
|
||||||
|
* the x component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param f0Y
|
||||||
|
* the y component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param f1X
|
||||||
|
* the x component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param f1Y
|
||||||
|
* the y component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param f2X
|
||||||
|
* the x component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param f2Y
|
||||||
|
* the y component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public static Vector2d dFdxLinear(
|
||||||
|
double v0X, double v0Y, double f0X, double f0Y,
|
||||||
|
double v1X, double v1Y, double f1X, double f1Y,
|
||||||
|
double v2X, double v2Y, double f2X, double f2Y, Vector2d dest) {
|
||||||
|
double v12Y = v1Y - v2Y;
|
||||||
|
double v02Y = v0Y - v2Y;
|
||||||
|
double den = v12Y * (v0X - v2X) + (v2X - v1X) * v02Y;
|
||||||
|
double l3_1 = den - v12Y + v02Y;
|
||||||
|
double invDen = 1.0f / den;
|
||||||
|
dest.x = invDen * (v12Y * f0X - v02Y * f1X + l3_1 * f2X) - f2X;
|
||||||
|
dest.y = invDen * (v12Y * f0Y - v02Y * f1Y + l3_1 * f2Y) - f2Y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the first-order derivative of a linear two-dimensional function <i>f</i> with respect to Y
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* This method computes the constant rate of change for <i>f</i> given the three values of <i>f</i>
|
||||||
|
* at the specified three inputs <code>(v0X, v0Y)</code>, <code>(v1X, v1Y)</code> and <code>(v2X, v2Y)</code>.
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param f0X
|
||||||
|
* the x component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param f0Y
|
||||||
|
* the y component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param f1X
|
||||||
|
* the x component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param f1Y
|
||||||
|
* the y component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param f2X
|
||||||
|
* the x component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param f2Y
|
||||||
|
* the y component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public static Vector2d dFdyLinear(
|
||||||
|
double v0X, double v0Y, double f0X, double f0Y,
|
||||||
|
double v1X, double v1Y, double f1X, double f1Y,
|
||||||
|
double v2X, double v2Y, double f2X, double f2Y,
|
||||||
|
Vector2d dest) {
|
||||||
|
double v21X = v2X - v1X;
|
||||||
|
double v02X = v0X - v2X;
|
||||||
|
double den = (v1Y - v2Y) * v02X + v21X * (v0Y - v2Y);
|
||||||
|
double l3_1 = den - v21X - v02X;
|
||||||
|
double invDen = 1.0f / den;
|
||||||
|
dest.x = invDen * (v21X * f0X + v02X * f1X + l3_1 * f2X) - f2X;
|
||||||
|
dest.y = invDen * (v21X * f0Y + v02X * f1Y + l3_1 * f2Y) - f2Y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bilinearly interpolate the three-dimensional vector <i>f</i> over the given triangle and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="https://en.wikipedia.org/wiki/Barycentric_coordinate_system">https://en.wikipedia.org/</a>
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param f0X
|
||||||
|
* the x component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param f0Y
|
||||||
|
* the y component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param f0Z
|
||||||
|
* the z component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param f1X
|
||||||
|
* the x component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param f1Y
|
||||||
|
* the y component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param f1Z
|
||||||
|
* the z component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param f2X
|
||||||
|
* the x component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param f2Y
|
||||||
|
* the y component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param f2Z
|
||||||
|
* the z component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @param dest
|
||||||
|
* will hold the interpolation result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public static Vector3d interpolateTriangle(
|
||||||
|
double v0X, double v0Y, double f0X, double f0Y, double f0Z,
|
||||||
|
double v1X, double v1Y, double f1X, double f1Y, double f1Z,
|
||||||
|
double v2X, double v2Y, double f2X, double f2Y, double f2Z,
|
||||||
|
double x, double y, Vector3d dest) {
|
||||||
|
// compute interpolation factors
|
||||||
|
Vector3d t = dest;
|
||||||
|
interpolationFactorsTriangle(v0X, v0Y, v1X, v1Y, v2X, v2Y, x, y, t);
|
||||||
|
// interpolate using these factors
|
||||||
|
return dest.set(t.x * f0X + t.y * f1X + t.z * f2X,
|
||||||
|
t.x * f0Y + t.y * f1Y + t.z * f2Y,
|
||||||
|
t.x * f0Z + t.y * f1Z + t.z * f2Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the interpolation factors <code>(t0, t1, t2)</code> in order to interpolate an arbitrary value over a given
|
||||||
|
* triangle at the given point <code>(x, y)</code>.
|
||||||
|
* <p>
|
||||||
|
* This method takes in the 2D vertex positions of the three vertices of a triangle and stores in <code>dest</code> the
|
||||||
|
* factors <code>(t0, t1, t2)</code> in the equation <code>v' = v0 * t0 + v1 * t1 + v2 * t2</code> where <code>(v0, v1, v2)</code> are
|
||||||
|
* arbitrary (scalar or vector) values associated with the respective vertices of the triangle. The computed value <code>v'</code>
|
||||||
|
* is the interpolated value at the given position <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the point to interpolate at
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the point to interpolate at
|
||||||
|
* @param dest
|
||||||
|
* will hold the interpolation factors <code>(t0, t1, t2)</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public static Vector3d interpolationFactorsTriangle(
|
||||||
|
double v0X, double v0Y, double v1X, double v1Y, double v2X, double v2Y,
|
||||||
|
double x, double y, Vector3d dest) {
|
||||||
|
double v12Y = v1Y - v2Y;
|
||||||
|
double v21X = v2X - v1X;
|
||||||
|
double v02X = v0X - v2X;
|
||||||
|
double yv2Y = y - v2Y;
|
||||||
|
double xv2X = x - v2X;
|
||||||
|
double v02Y = v0Y - v2Y;
|
||||||
|
double invDen = 1.0 / (v12Y * v02X + v21X * v02Y);
|
||||||
|
dest.x = (v12Y * xv2X + v21X * yv2Y) * invDen;
|
||||||
|
dest.y = (v02X * yv2Y - v02Y * xv2X) * invDen;
|
||||||
|
dest.z = 1.0 - dest.x - dest.y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,337 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 Kai Burjack
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains various interpolation functions.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Interpolationf {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bilinearly interpolate the single scalar value <i>f</i> over the given triangle.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="https://en.wikipedia.org/wiki/Barycentric_coordinate_system">https://en.wikipedia.org/</a>
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param f0
|
||||||
|
* the value of <i>f</i> at the first vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param f1
|
||||||
|
* the value of <i>f</i> at the second vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param f2
|
||||||
|
* the value of <i>f</i> at the third vertex
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @return the interpolated value of <i>f</i>
|
||||||
|
*/
|
||||||
|
public static float interpolateTriangle(
|
||||||
|
float v0X, float v0Y, float f0,
|
||||||
|
float v1X, float v1Y, float f1,
|
||||||
|
float v2X, float v2Y, float f2,
|
||||||
|
float x, float y) {
|
||||||
|
float v12Y = v1Y - v2Y;
|
||||||
|
float v21X = v2X - v1X;
|
||||||
|
float v02X = v0X - v2X;
|
||||||
|
float yv2Y = y - v2Y;
|
||||||
|
float xv2X = x - v2X;
|
||||||
|
float v02Y = v0Y - v2Y;
|
||||||
|
float invDen = 1.0f / (v12Y * v02X + v21X * v02Y);
|
||||||
|
float l1 = (v12Y * xv2X + v21X * yv2Y) * invDen;
|
||||||
|
float l2 = (v02X * yv2Y - v02Y * xv2X) * invDen;
|
||||||
|
return l1 * f0 + l2 * f1 + (1.0f - l1 - l2) * f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bilinearly interpolate the two-dimensional vector <i>f</i> over the given triangle and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="https://en.wikipedia.org/wiki/Barycentric_coordinate_system">https://en.wikipedia.org/</a>
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param f0X
|
||||||
|
* the x component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param f0Y
|
||||||
|
* the y component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param f1X
|
||||||
|
* the x component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param f1Y
|
||||||
|
* the y component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param f2X
|
||||||
|
* the x component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param f2Y
|
||||||
|
* the y component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @param dest
|
||||||
|
* will hold the interpolation result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public static Vector2f interpolateTriangle(
|
||||||
|
float v0X, float v0Y, float f0X, float f0Y,
|
||||||
|
float v1X, float v1Y, float f1X, float f1Y,
|
||||||
|
float v2X, float v2Y, float f2X, float f2Y,
|
||||||
|
float x, float y, Vector2f dest) {
|
||||||
|
float v12Y = v1Y - v2Y;
|
||||||
|
float v21X = v2X - v1X;
|
||||||
|
float v02X = v0X - v2X;
|
||||||
|
float yv2Y = y - v2Y;
|
||||||
|
float xv2X = x - v2X;
|
||||||
|
float v02Y = v0Y - v2Y;
|
||||||
|
float invDen = 1.0f / (v12Y * v02X + v21X * v02Y);
|
||||||
|
float l1 = (v12Y * xv2X + v21X * yv2Y) * invDen;
|
||||||
|
float l2 = (v02X * yv2Y - v02Y * xv2X) * invDen;
|
||||||
|
float l3 = 1.0f - l1 - l2;
|
||||||
|
dest.x = l1 * f0X + l2 * f1X + l3 * f2X;
|
||||||
|
dest.y = l1 * f0Y + l2 * f1Y + l3 * f2Y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the first-order derivative of a linear two-dimensional function <i>f</i> with respect to X
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* This method computes the constant rate of change for <i>f</i> given the three values of <i>f</i>
|
||||||
|
* at the specified three inputs <code>(v0X, v0Y)</code>, <code>(v1X, v1Y)</code> and <code>(v2X, v2Y)</code>.
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param f0X
|
||||||
|
* the x component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param f0Y
|
||||||
|
* the y component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param f1X
|
||||||
|
* the x component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param f1Y
|
||||||
|
* the y component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param f2X
|
||||||
|
* the x component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param f2Y
|
||||||
|
* the y component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public static Vector2f dFdxLinear(
|
||||||
|
float v0X, float v0Y, float f0X, float f0Y,
|
||||||
|
float v1X, float v1Y, float f1X, float f1Y,
|
||||||
|
float v2X, float v2Y, float f2X, float f2Y, Vector2f dest) {
|
||||||
|
float v12Y = v1Y - v2Y;
|
||||||
|
float v02Y = v0Y - v2Y;
|
||||||
|
float den = v12Y * (v0X - v2X) + (v2X - v1X) * v02Y;
|
||||||
|
float l3_1 = den - v12Y + v02Y;
|
||||||
|
float invDen = 1.0f / den;
|
||||||
|
dest.x = invDen * (v12Y * f0X - v02Y * f1X + l3_1 * f2X) - f2X;
|
||||||
|
dest.y = invDen * (v12Y * f0Y - v02Y * f1Y + l3_1 * f2Y) - f2Y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the first-order derivative of a linear two-dimensional function <i>f</i> with respect to Y
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* This method computes the constant rate of change for <i>f</i> given the three values of <i>f</i>
|
||||||
|
* at the specified three inputs <code>(v0X, v0Y)</code>, <code>(v1X, v1Y)</code> and <code>(v2X, v2Y)</code>.
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param f0X
|
||||||
|
* the x component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param f0Y
|
||||||
|
* the y component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param f1X
|
||||||
|
* the x component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param f1Y
|
||||||
|
* the y component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param f2X
|
||||||
|
* the x component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param f2Y
|
||||||
|
* the y component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public static Vector2f dFdyLinear(
|
||||||
|
float v0X, float v0Y, float f0X, float f0Y,
|
||||||
|
float v1X, float v1Y, float f1X, float f1Y,
|
||||||
|
float v2X, float v2Y, float f2X, float f2Y,
|
||||||
|
Vector2f dest) {
|
||||||
|
float v21X = v2X - v1X;
|
||||||
|
float v02X = v0X - v2X;
|
||||||
|
float den = (v1Y - v2Y) * v02X + v21X * (v0Y - v2Y);
|
||||||
|
float l3_1 = den - v21X - v02X;
|
||||||
|
float invDen = 1.0f / den;
|
||||||
|
dest.x = invDen * (v21X * f0X + v02X * f1X + l3_1 * f2X) - f2X;
|
||||||
|
dest.y = invDen * (v21X * f0Y + v02X * f1Y + l3_1 * f2Y) - f2Y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bilinearly interpolate the three-dimensional vector <i>f</i> over the given triangle and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="https://en.wikipedia.org/wiki/Barycentric_coordinate_system">https://en.wikipedia.org/</a>
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param f0X
|
||||||
|
* the x component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param f0Y
|
||||||
|
* the y component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param f0Z
|
||||||
|
* the z component of the value of <i>f</i> at the first vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param f1X
|
||||||
|
* the x component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param f1Y
|
||||||
|
* the y component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param f1Z
|
||||||
|
* the z component of the value of <i>f</i> at the second vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param f2X
|
||||||
|
* the x component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param f2Y
|
||||||
|
* the y component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param f2Z
|
||||||
|
* the z component of the value of <i>f</i> at the third vertex
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the point to interpolate <i>f</i> at
|
||||||
|
* @param dest
|
||||||
|
* will hold the interpolation result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public static Vector3f interpolateTriangle(
|
||||||
|
float v0X, float v0Y, float f0X, float f0Y, float f0Z,
|
||||||
|
float v1X, float v1Y, float f1X, float f1Y, float f1Z,
|
||||||
|
float v2X, float v2Y, float f2X, float f2Y, float f2Z,
|
||||||
|
float x, float y, Vector3f dest) {
|
||||||
|
// compute interpolation factors
|
||||||
|
Vector3f t = dest;
|
||||||
|
interpolationFactorsTriangle(v0X, v0Y, v1X, v1Y, v2X, v2Y, x, y, t);
|
||||||
|
// interpolate using these factors
|
||||||
|
return dest.set(t.x * f0X + t.y * f1X + t.z * f2X,
|
||||||
|
t.x * f0Y + t.y * f1Y + t.z * f2Y,
|
||||||
|
t.x * f0Z + t.y * f1Z + t.z * f2Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the interpolation factors <code>(t0, t1, t2)</code> in order to interpolate an arbitrary value over a given
|
||||||
|
* triangle at the given point <code>(x, y)</code>.
|
||||||
|
* <p>
|
||||||
|
* This method takes in the 2D vertex positions of the three vertices of a triangle and stores in <code>dest</code> the
|
||||||
|
* factors <code>(t0, t1, t2)</code> in the equation <code>v' = v0 * t0 + v1 * t1 + v2 * t2</code> where <code>(v0, v1, v2)</code> are
|
||||||
|
* arbitrary (scalar or vector) values associated with the respective vertices of the triangle. The computed value <code>v'</code>
|
||||||
|
* is the interpolated value at the given position <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param v0X
|
||||||
|
* the x coordinate of the first triangle vertex
|
||||||
|
* @param v0Y
|
||||||
|
* the y coordinate of the first triangle vertex
|
||||||
|
* @param v1X
|
||||||
|
* the x coordinate of the second triangle vertex
|
||||||
|
* @param v1Y
|
||||||
|
* the y coordinate of the second triangle vertex
|
||||||
|
* @param v2X
|
||||||
|
* the x coordinate of the third triangle vertex
|
||||||
|
* @param v2Y
|
||||||
|
* the y coordinate of the third triangle vertex
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the point to interpolate at
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the point to interpolate at
|
||||||
|
* @param dest
|
||||||
|
* will hold the interpolation factors <code>(t0, t1, t2)</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public static Vector3f interpolationFactorsTriangle(
|
||||||
|
float v0X, float v0Y, float v1X, float v1Y, float v2X, float v2Y,
|
||||||
|
float x, float y, Vector3f dest) {
|
||||||
|
float v12Y = v1Y - v2Y;
|
||||||
|
float v21X = v2X - v1X;
|
||||||
|
float v02X = v0X - v2X;
|
||||||
|
float yv2Y = y - v2Y;
|
||||||
|
float xv2X = x - v2X;
|
||||||
|
float v02Y = v0Y - v2Y;
|
||||||
|
float invDen = 1.0f / (v12Y * v02X + v21X * v02Y);
|
||||||
|
dest.x = (v12Y * xv2X + v21X * yv2Y) * invDen;
|
||||||
|
dest.y = (v02X * yv2Y - v02Y * xv2X) * invDen;
|
||||||
|
dest.z = 1.0f - dest.x - dest.y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
4789
src/main/java/com/jozufozu/flywheel/repack/joml/Intersectiond.java
Normal file
4789
src/main/java/com/jozufozu/flywheel/repack/joml/Intersectiond.java
Normal file
File diff suppressed because it is too large
Load diff
4789
src/main/java/com/jozufozu/flywheel/repack/joml/Intersectionf.java
Normal file
4789
src/main/java/com/jozufozu/flywheel/repack/joml/Intersectionf.java
Normal file
File diff suppressed because it is too large
Load diff
566
src/main/java/com/jozufozu/flywheel/repack/joml/Math.java
Normal file
566
src/main/java/com/jozufozu/flywheel/repack/joml/Math.java
Normal file
|
@ -0,0 +1,566 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains fast approximations of some {@link java.lang.Math} operations.
|
||||||
|
* <p>
|
||||||
|
* By default, {@link java.lang.Math} methods will be used by all other JOML classes. In order to use the approximations in this class, start the JVM with the parameter <code>-Djoml.fastmath</code>.
|
||||||
|
* <p>
|
||||||
|
* There are two algorithms for approximating sin/cos:
|
||||||
|
* <ol>
|
||||||
|
* <li>arithmetic <a href="http://www.java-gaming.org/topics/joml-1-8-0-release/37491/msg/361815/view.html#msg361815">polynomial approximation</a> contributed by roquendm
|
||||||
|
* <li>theagentd's <a href="http://www.java-gaming.org/topics/extremely-fast-sine-cosine/36469/msg/346213/view.html#msg346213">linear interpolation</a> variant of Riven's algorithm from
|
||||||
|
* <a href="http://www.java-gaming.org/topics/extremely-fast-sine-cosine/36469/view.html">http://www.java-gaming.org/</a>
|
||||||
|
* </ol>
|
||||||
|
* By default, the first algorithm is being used. In order to use the second one, start the JVM with <code>-Djoml.sinLookup</code>. The lookup table bit length of the second algorithm can also be adjusted
|
||||||
|
* for improved accuracy via <code>-Djoml.sinLookup.bits=<n></code>, where <n> is the number of bits of the lookup table.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Math {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following implementation of an approximation of sine and cosine was
|
||||||
|
* thankfully donated by Riven from http://java-gaming.org/.
|
||||||
|
*
|
||||||
|
* The code for linear interpolation was gratefully donated by theagentd
|
||||||
|
* from the same site.
|
||||||
|
*/
|
||||||
|
public static final double PI = java.lang.Math.PI;
|
||||||
|
static final double PI2 = PI * 2.0;
|
||||||
|
static final float PI_f = (float) java.lang.Math.PI;
|
||||||
|
static final float PI2_f = PI_f * 2.0f;
|
||||||
|
static final double PIHalf = PI * 0.5;
|
||||||
|
static final float PIHalf_f = (float) (PI * 0.5);
|
||||||
|
static final double PI_4 = PI * 0.25;
|
||||||
|
static final double PI_INV = 1.0 / PI;
|
||||||
|
private static final int lookupBits = Options.SIN_LOOKUP_BITS;
|
||||||
|
private static final int lookupTableSize = 1 << lookupBits;
|
||||||
|
private static final int lookupTableSizeMinus1 = lookupTableSize - 1;
|
||||||
|
private static final int lookupTableSizeWithMargin = lookupTableSize + 1;
|
||||||
|
private static final float pi2OverLookupSize = PI2_f / lookupTableSize;
|
||||||
|
private static final float lookupSizeOverPi2 = lookupTableSize / PI2_f;
|
||||||
|
private static final float sinTable[];
|
||||||
|
static {
|
||||||
|
if (Options.FASTMATH && Options.SIN_LOOKUP) {
|
||||||
|
sinTable = new float[lookupTableSizeWithMargin];
|
||||||
|
for (int i = 0; i < lookupTableSizeWithMargin; i++) {
|
||||||
|
double d = i * pi2OverLookupSize;
|
||||||
|
sinTable[i] = (float) java.lang.Math.sin(d);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sinTable = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final double c1 = Double.longBitsToDouble(-4628199217061079772L);
|
||||||
|
private static final double c2 = Double.longBitsToDouble(4575957461383582011L);
|
||||||
|
private static final double c3 = Double.longBitsToDouble(-4671919876300759001L);
|
||||||
|
private static final double c4 = Double.longBitsToDouble(4523617214285661942L);
|
||||||
|
private static final double c5 = Double.longBitsToDouble(-4730215272828025532L);
|
||||||
|
private static final double c6 = Double.longBitsToDouble(4460272573143870633L);
|
||||||
|
private static final double c7 = Double.longBitsToDouble(-4797767418267846529L);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author theagentd
|
||||||
|
*/
|
||||||
|
static double sin_theagentd_arith(double x){
|
||||||
|
double xi = floor((x + PI_4) * PI_INV);
|
||||||
|
double x_ = x - xi * PI;
|
||||||
|
double sign = ((int)xi & 1) * -2 + 1;
|
||||||
|
double x2 = x_ * x_;
|
||||||
|
double sin = x_;
|
||||||
|
double tx = x_ * x2;
|
||||||
|
sin += tx * c1; tx *= x2;
|
||||||
|
sin += tx * c2; tx *= x2;
|
||||||
|
sin += tx * c3; tx *= x2;
|
||||||
|
sin += tx * c4; tx *= x2;
|
||||||
|
sin += tx * c5; tx *= x2;
|
||||||
|
sin += tx * c6; tx *= x2;
|
||||||
|
sin += tx * c7;
|
||||||
|
return sign * sin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference: <a href="http://www.java-gaming.org/topics/joml-1-8-0-release/37491/msg/361718/view.html#msg361718">http://www.java-gaming.org/</a>
|
||||||
|
*/
|
||||||
|
static double sin_roquen_arith(double x) {
|
||||||
|
double xi = Math.floor((x + PI_4) * PI_INV);
|
||||||
|
double x_ = x - xi * PI;
|
||||||
|
double sign = ((int)xi & 1) * -2 + 1;
|
||||||
|
double x2 = x_ * x_;
|
||||||
|
|
||||||
|
// code from sin_theagentd_arith:
|
||||||
|
// double sin = x_;
|
||||||
|
// double tx = x_ * x2;
|
||||||
|
// sin += tx * c1; tx *= x2;
|
||||||
|
// sin += tx * c2; tx *= x2;
|
||||||
|
// sin += tx * c3; tx *= x2;
|
||||||
|
// sin += tx * c4; tx *= x2;
|
||||||
|
// sin += tx * c5; tx *= x2;
|
||||||
|
// sin += tx * c6; tx *= x2;
|
||||||
|
// sin += tx * c7;
|
||||||
|
// return sign * sin;
|
||||||
|
|
||||||
|
double sin;
|
||||||
|
x_ = sign*x_;
|
||||||
|
sin = c7;
|
||||||
|
sin = sin*x2 + c6;
|
||||||
|
sin = sin*x2 + c5;
|
||||||
|
sin = sin*x2 + c4;
|
||||||
|
sin = sin*x2 + c3;
|
||||||
|
sin = sin*x2 + c2;
|
||||||
|
sin = sin*x2 + c1;
|
||||||
|
return x_ + x_*x2*sin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final double s5 = Double.longBitsToDouble(4523227044276562163L);
|
||||||
|
private static final double s4 = Double.longBitsToDouble(-4671934770969572232L);
|
||||||
|
private static final double s3 = Double.longBitsToDouble(4575957211482072852L);
|
||||||
|
private static final double s2 = Double.longBitsToDouble(-4628199223918090387L);
|
||||||
|
private static final double s1 = Double.longBitsToDouble(4607182418589157889L);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference: <a href="http://www.java-gaming.org/topics/joml-1-8-0-release/37491/msg/361815/view.html#msg361815">http://www.java-gaming.org/</a>
|
||||||
|
*/
|
||||||
|
static double sin_roquen_9(double v) {
|
||||||
|
double i = java.lang.Math.rint(v*PI_INV);
|
||||||
|
double x = v - i * Math.PI;
|
||||||
|
double qs = 1-2*((int)i & 1);
|
||||||
|
double x2 = x*x;
|
||||||
|
double r;
|
||||||
|
x = qs*x;
|
||||||
|
r = s5;
|
||||||
|
r = r*x2 + s4;
|
||||||
|
r = r*x2 + s3;
|
||||||
|
r = r*x2 + s2;
|
||||||
|
r = r*x2 + s1;
|
||||||
|
return x*r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final double k1 = Double.longBitsToDouble(-4628199217061079959L);
|
||||||
|
private static final double k2 = Double.longBitsToDouble(4575957461383549981L);
|
||||||
|
private static final double k3 = Double.longBitsToDouble(-4671919876307284301L);
|
||||||
|
private static final double k4 = Double.longBitsToDouble(4523617213632129738L);
|
||||||
|
private static final double k5 = Double.longBitsToDouble(-4730215344060517252L);
|
||||||
|
private static final double k6 = Double.longBitsToDouble(4460268259291226124L);
|
||||||
|
private static final double k7 = Double.longBitsToDouble(-4798040743777455072L);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference: <a href="http://www.java-gaming.org/topics/joml-1-8-0-release/37491/msg/361815/view.html#msg361815">http://www.java-gaming.org/</a>
|
||||||
|
*/
|
||||||
|
static double sin_roquen_newk(double v) {
|
||||||
|
double i = java.lang.Math.rint(v*PI_INV);
|
||||||
|
double x = v - i * Math.PI;
|
||||||
|
double qs = 1-2*((int)i & 1);
|
||||||
|
double x2 = x*x;
|
||||||
|
double r;
|
||||||
|
x = qs*x;
|
||||||
|
r = k7;
|
||||||
|
r = r*x2 + k6;
|
||||||
|
r = r*x2 + k5;
|
||||||
|
r = r*x2 + k4;
|
||||||
|
r = r*x2 + k3;
|
||||||
|
r = r*x2 + k2;
|
||||||
|
r = r*x2 + k1;
|
||||||
|
return x + x*x2*r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference: <a href="http://www.java-gaming.org/topics/extremely-fast-sine-cosine/36469/msg/349515/view.html#msg349515">http://www.java-gaming.org/</a>
|
||||||
|
*/
|
||||||
|
static float sin_theagentd_lookup(float rad) {
|
||||||
|
float index = rad * lookupSizeOverPi2;
|
||||||
|
int ii = (int)java.lang.Math.floor(index);
|
||||||
|
float alpha = index - ii;
|
||||||
|
int i = ii & lookupTableSizeMinus1;
|
||||||
|
float sin1 = sinTable[i];
|
||||||
|
float sin2 = sinTable[i + 1];
|
||||||
|
return sin1 + (sin2 - sin1) * alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float sin(float rad) {
|
||||||
|
return (float) java.lang.Math.sin(rad);
|
||||||
|
}
|
||||||
|
public static double sin(double rad) {
|
||||||
|
if (Options.FASTMATH) {
|
||||||
|
if (Options.SIN_LOOKUP)
|
||||||
|
return sin_theagentd_lookup((float) rad);
|
||||||
|
return sin_roquen_newk(rad);
|
||||||
|
}
|
||||||
|
return java.lang.Math.sin(rad);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float cos(float rad) {
|
||||||
|
if (Options.FASTMATH)
|
||||||
|
return sin(rad + PIHalf_f);
|
||||||
|
return (float) java.lang.Math.cos(rad);
|
||||||
|
}
|
||||||
|
public static double cos(double rad) {
|
||||||
|
if (Options.FASTMATH)
|
||||||
|
return sin(rad + PIHalf);
|
||||||
|
return java.lang.Math.cos(rad);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float cosFromSin(float sin, float angle) {
|
||||||
|
if (Options.FASTMATH)
|
||||||
|
return sin(angle + PIHalf_f);
|
||||||
|
return cosFromSinInternal(sin, angle);
|
||||||
|
}
|
||||||
|
private static float cosFromSinInternal(float sin, float angle) {
|
||||||
|
// sin(x)^2 + cos(x)^2 = 1
|
||||||
|
float cos = sqrt(1.0f - sin * sin);
|
||||||
|
float a = angle + PIHalf_f;
|
||||||
|
float b = a - (int)(a / PI2_f) * PI2_f;
|
||||||
|
if (b < 0.0)
|
||||||
|
b = PI2_f + b;
|
||||||
|
if (b >= PI_f)
|
||||||
|
return -cos;
|
||||||
|
return cos;
|
||||||
|
}
|
||||||
|
public static double cosFromSin(double sin, double angle) {
|
||||||
|
if (Options.FASTMATH)
|
||||||
|
return sin(angle + PIHalf);
|
||||||
|
// sin(x)^2 + cos(x)^2 = 1
|
||||||
|
double cos = sqrt(1.0 - sin * sin);
|
||||||
|
double a = angle + PIHalf;
|
||||||
|
double b = a - (int)(a / PI2) * PI2;
|
||||||
|
if (b < 0.0)
|
||||||
|
b = PI2 + b;
|
||||||
|
if (b >= PI)
|
||||||
|
return -cos;
|
||||||
|
return cos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Other math functions not yet approximated */
|
||||||
|
|
||||||
|
public static float sqrt(float r) {
|
||||||
|
return (float) java.lang.Math.sqrt(r);
|
||||||
|
}
|
||||||
|
public static double sqrt(double r) {
|
||||||
|
return java.lang.Math.sqrt(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float invsqrt(float r) {
|
||||||
|
return 1.0f / (float) java.lang.Math.sqrt(r);
|
||||||
|
}
|
||||||
|
public static double invsqrt(double r) {
|
||||||
|
return 1.0 / java.lang.Math.sqrt(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float tan(float r) {
|
||||||
|
return (float) java.lang.Math.tan(r);
|
||||||
|
}
|
||||||
|
public static double tan(double r) {
|
||||||
|
return java.lang.Math.tan(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float acos(float r) {
|
||||||
|
return (float) java.lang.Math.acos(r);
|
||||||
|
}
|
||||||
|
public static double acos(double r) {
|
||||||
|
return java.lang.Math.acos(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float safeAcos(float v) {
|
||||||
|
if (v < -1.0f)
|
||||||
|
return Math.PI_f;
|
||||||
|
else if (v > +1.0f)
|
||||||
|
return 0.0f;
|
||||||
|
else
|
||||||
|
return acos(v);
|
||||||
|
}
|
||||||
|
public static double safeAcos(double v) {
|
||||||
|
if (v < -1.0)
|
||||||
|
return Math.PI;
|
||||||
|
else if (v > +1.0)
|
||||||
|
return 0.0;
|
||||||
|
else
|
||||||
|
return acos(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://math.stackexchange.com/questions/1098487/atan2-faster-approximation/1105038#answer-1105038
|
||||||
|
*/
|
||||||
|
private static double fastAtan2(double y, double x) {
|
||||||
|
double ax = x >= 0.0 ? x : -x, ay = y >= 0.0 ? y : -y;
|
||||||
|
double a = min(ax, ay) / max(ax, ay);
|
||||||
|
double s = a * a;
|
||||||
|
double r = ((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a;
|
||||||
|
if (ay > ax)
|
||||||
|
r = 1.57079637 - r;
|
||||||
|
if (x < 0.0)
|
||||||
|
r = 3.14159274 - r;
|
||||||
|
return y >= 0 ? r : -r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float atan2(float y, float x) {
|
||||||
|
return (float) java.lang.Math.atan2(y, x);
|
||||||
|
}
|
||||||
|
public static double atan2(double y, double x) {
|
||||||
|
if (Options.FASTMATH)
|
||||||
|
return fastAtan2(y, x);
|
||||||
|
return java.lang.Math.atan2(y, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float asin(float r) {
|
||||||
|
return (float) java.lang.Math.asin(r);
|
||||||
|
}
|
||||||
|
public static double asin(double r) {
|
||||||
|
return java.lang.Math.asin(r);
|
||||||
|
}
|
||||||
|
public static float safeAsin(float r) {
|
||||||
|
return r <= -1.0f ? -PIHalf_f : r >= 1.0f ? PIHalf_f : asin(r);
|
||||||
|
}
|
||||||
|
public static double safeAsin(double r) {
|
||||||
|
return r <= -1.0 ? -PIHalf : r >= 1.0 ? PIHalf : asin(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float abs(float r) {
|
||||||
|
return java.lang.Math.abs(r);
|
||||||
|
}
|
||||||
|
public static double abs(double r) {
|
||||||
|
return java.lang.Math.abs(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean absEqualsOne(float r) {
|
||||||
|
return (Float.floatToRawIntBits(r) & 0x7FFFFFFF) == 0x3F800000;
|
||||||
|
}
|
||||||
|
static boolean absEqualsOne(double r) {
|
||||||
|
return (Double.doubleToRawLongBits(r) & 0x7FFFFFFFFFFFFFFFL) == 0x3FF0000000000000L;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int abs(int r) {
|
||||||
|
return java.lang.Math.abs(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int max(int x, int y) {
|
||||||
|
return java.lang.Math.max(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int min(int x, int y) {
|
||||||
|
return java.lang.Math.min(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double min(double a, double b) {
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
public static float min(float a, float b) {
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float max(float a, float b) {
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
public static double max(double a, double b) {
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float clamp(float a, float b, float val){
|
||||||
|
return max(a,min(b,val));
|
||||||
|
}
|
||||||
|
public static double clamp(double a, double b, double val) {
|
||||||
|
return max(a,min(b,val));
|
||||||
|
}
|
||||||
|
public static int clamp(int a, int b, int val) {
|
||||||
|
return max(a, min(b, val));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float toRadians(float angles) {
|
||||||
|
return (float) java.lang.Math.toRadians(angles);
|
||||||
|
}
|
||||||
|
public static double toRadians(double angles) {
|
||||||
|
return java.lang.Math.toRadians(angles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double toDegrees(double angles) {
|
||||||
|
return java.lang.Math.toDegrees(angles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double floor(double v) {
|
||||||
|
return java.lang.Math.floor(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float floor(float v) {
|
||||||
|
return (float) java.lang.Math.floor(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double ceil(double v) {
|
||||||
|
return java.lang.Math.ceil(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float ceil(float v) {
|
||||||
|
return (float) java.lang.Math.ceil(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long round(double v) {
|
||||||
|
return java.lang.Math.round(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int round(float v) {
|
||||||
|
return java.lang.Math.round(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double exp(double a) {
|
||||||
|
return java.lang.Math.exp(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isFinite(double d) {
|
||||||
|
return abs(d) <= Double.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isFinite(float f) {
|
||||||
|
return abs(f) <= Float.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float fma(float a, float b, float c) {
|
||||||
|
if (Runtime.HAS_Math_fma)
|
||||||
|
return java.lang.Math.fma(a, b, c);
|
||||||
|
return a * b + c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double fma(double a, double b, double c) {
|
||||||
|
if (Runtime.HAS_Math_fma)
|
||||||
|
return java.lang.Math.fma(a, b, c);
|
||||||
|
return a * b + c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int roundUsing(float v, int mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case RoundingMode.TRUNCATE:
|
||||||
|
return (int) v;
|
||||||
|
case RoundingMode.CEILING:
|
||||||
|
return (int) java.lang.Math.ceil(v);
|
||||||
|
case RoundingMode.FLOOR:
|
||||||
|
return (int) java.lang.Math.floor(v);
|
||||||
|
case RoundingMode.HALF_DOWN:
|
||||||
|
return roundHalfDown(v);
|
||||||
|
case RoundingMode.HALF_UP:
|
||||||
|
return roundHalfUp(v);
|
||||||
|
case RoundingMode.HALF_EVEN:
|
||||||
|
return roundHalfEven(v);
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static int roundUsing(double v, int mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case RoundingMode.TRUNCATE:
|
||||||
|
return (int) v;
|
||||||
|
case RoundingMode.CEILING:
|
||||||
|
return (int) java.lang.Math.ceil(v);
|
||||||
|
case RoundingMode.FLOOR:
|
||||||
|
return (int) java.lang.Math.floor(v);
|
||||||
|
case RoundingMode.HALF_DOWN:
|
||||||
|
return roundHalfDown(v);
|
||||||
|
case RoundingMode.HALF_UP:
|
||||||
|
return roundHalfUp(v);
|
||||||
|
case RoundingMode.HALF_EVEN:
|
||||||
|
return roundHalfEven(v);
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float lerp(float a, float b, float t){
|
||||||
|
return Math.fma(b - a, t, a);
|
||||||
|
}
|
||||||
|
public static double lerp(double a, double b, double t) {
|
||||||
|
return Math.fma(b - a, t, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float biLerp(float q00, float q10, float q01, float q11, float tx, float ty) {
|
||||||
|
float lerpX1 = lerp(q00, q10, tx);
|
||||||
|
float lerpX2 = lerp(q01, q11, tx);
|
||||||
|
return lerp(lerpX1, lerpX2, ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double biLerp(double q00, double q10, double q01, double q11, double tx, double ty) {
|
||||||
|
double lerpX1 = lerp(q00, q10, tx);
|
||||||
|
double lerpX2 = lerp(q01, q11, tx);
|
||||||
|
return lerp(lerpX1, lerpX2, ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float triLerp(float q000, float q100, float q010, float q110, float q001, float q101, float q011, float q111, float tx, float ty, float tz) {
|
||||||
|
float x00 = lerp(q000, q100, tx);
|
||||||
|
float x10 = lerp(q010, q110, tx);
|
||||||
|
float x01 = lerp(q001, q101, tx);
|
||||||
|
float x11 = lerp(q011, q111, tx);
|
||||||
|
float y0 = lerp(x00, x10, ty);
|
||||||
|
float y1 = lerp(x01, x11, ty);
|
||||||
|
return lerp(y0, y1, tz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double triLerp(double q000, double q100, double q010, double q110, double q001, double q101, double q011, double q111, double tx, double ty, double tz) {
|
||||||
|
double x00 = lerp(q000, q100, tx);
|
||||||
|
double x10 = lerp(q010, q110, tx);
|
||||||
|
double x01 = lerp(q001, q101, tx);
|
||||||
|
double x11 = lerp(q011, q111, tx);
|
||||||
|
double y0 = lerp(x00, x10, ty);
|
||||||
|
double y1 = lerp(x01, x11, ty);
|
||||||
|
return lerp(y0, y1, tz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int roundHalfEven(float v) {
|
||||||
|
return (int) java.lang.Math.rint(v);
|
||||||
|
}
|
||||||
|
public static int roundHalfDown(float v) {
|
||||||
|
return (v > 0) ? (int) java.lang.Math.ceil(v - 0.5d) : (int) java.lang.Math.floor(v + 0.5d);
|
||||||
|
}
|
||||||
|
public static int roundHalfUp(float v) {
|
||||||
|
return (v > 0) ? (int) java.lang.Math.floor(v + 0.5d) : (int) java.lang.Math.ceil(v - 0.5d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int roundHalfEven(double v) {
|
||||||
|
return (int) java.lang.Math.rint(v);
|
||||||
|
}
|
||||||
|
public static int roundHalfDown(double v) {
|
||||||
|
return (v > 0) ? (int) java.lang.Math.ceil(v - 0.5d) : (int) java.lang.Math.floor(v + 0.5d);
|
||||||
|
}
|
||||||
|
public static int roundHalfUp(double v) {
|
||||||
|
return (v > 0) ? (int) java.lang.Math.floor(v + 0.5d) : (int) java.lang.Math.ceil(v - 0.5d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double random() {
|
||||||
|
return java.lang.Math.random();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double signum(double v) {
|
||||||
|
return java.lang.Math.signum(v);
|
||||||
|
}
|
||||||
|
public static float signum(float v) {
|
||||||
|
return java.lang.Math.signum(v);
|
||||||
|
}
|
||||||
|
public static int signum(int v) {
|
||||||
|
int r;
|
||||||
|
r = Integer.signum(v);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
public static int signum(long v) {
|
||||||
|
int r;
|
||||||
|
r = Long.signum(v);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
1536
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2d.java
Normal file
1536
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2d.java
Normal file
File diff suppressed because it is too large
Load diff
725
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2dc.java
Normal file
725
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2dc.java
Normal file
|
@ -0,0 +1,725 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.DoubleBuffer;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to a read-only view of a 2x2 matrix of double-precision floats.
|
||||||
|
*
|
||||||
|
* @author Joseph Burton
|
||||||
|
*/
|
||||||
|
public interface Matrix2dc {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of the matrix element at column 0 and row 0.
|
||||||
|
*
|
||||||
|
* @return the value of the matrix element
|
||||||
|
*/
|
||||||
|
double m00();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of the matrix element at column 0 and row 1.
|
||||||
|
*
|
||||||
|
* @return the value of the matrix element
|
||||||
|
*/
|
||||||
|
double m01();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of the matrix element at column 1 and row 0.
|
||||||
|
*
|
||||||
|
* @return the value of the matrix element
|
||||||
|
*/
|
||||||
|
double m10();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of the matrix element at column 1 and row 1.
|
||||||
|
*
|
||||||
|
* @return the value of the matrix element
|
||||||
|
*/
|
||||||
|
double m11();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply this matrix by the supplied <code>right</code> matrix and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>R</code> the <code>right</code> matrix,
|
||||||
|
* then the new matrix will be <code>M * R</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>M * R * v</code>, the
|
||||||
|
* transformation of the right matrix will be applied first!
|
||||||
|
*
|
||||||
|
* @param right
|
||||||
|
* the right operand of the matrix multiplication
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d mul(Matrix2dc right, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply this matrix by the supplied <code>right</code> matrix and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>R</code> the <code>right</code> matrix,
|
||||||
|
* then the new matrix will be <code>M * R</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>M * R * v</code>, the
|
||||||
|
* transformation of the right matrix will be applied first!
|
||||||
|
*
|
||||||
|
* @param right
|
||||||
|
* the right operand of the matrix multiplication
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d mul(Matrix2fc right, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-multiply this matrix by the supplied <code>left</code> matrix and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>L</code> the <code>left</code> matrix,
|
||||||
|
* then the new matrix will be <code>L * M</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>L * M * v</code>, the
|
||||||
|
* transformation of <code>this</code> matrix will be applied first!
|
||||||
|
*
|
||||||
|
* @param left
|
||||||
|
* the left operand of the matrix multiplication
|
||||||
|
* @param dest
|
||||||
|
* the destination matrix, which will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d mulLocal(Matrix2dc left, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the determinant of this matrix.
|
||||||
|
*
|
||||||
|
* @return the determinant
|
||||||
|
*/
|
||||||
|
double determinant();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invert the <code>this</code> matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d invert(Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transpose <code>this</code> matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d transpose(Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current values of <code>this</code> matrix and store them into
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* the destination matrix
|
||||||
|
* @return the passed in destination
|
||||||
|
*/
|
||||||
|
Matrix2d get(Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current values of <code>this</code> matrix and store them as
|
||||||
|
* the rotational component of <code>dest</code>. All other values of <code>dest</code> will
|
||||||
|
* be set to 0.
|
||||||
|
*
|
||||||
|
* @see Matrix3x2d#set(Matrix2dc)
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* the destination matrix
|
||||||
|
* @return the passed in destination
|
||||||
|
*/
|
||||||
|
Matrix3x2d get(Matrix3x2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current values of <code>this</code> matrix and store them as
|
||||||
|
* the rotational component of <code>dest</code>. All other values of <code>dest</code> will
|
||||||
|
* be set to identity.
|
||||||
|
*
|
||||||
|
* @see Matrix3d#set(Matrix2dc)
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* the destination matrix
|
||||||
|
* @return the passed in destination
|
||||||
|
*/
|
||||||
|
Matrix3d get(Matrix3d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the angle of the rotation component of <code>this</code> matrix.
|
||||||
|
* <p>
|
||||||
|
* This method assumes that there is a valid rotation to be returned, i.e. that
|
||||||
|
* <code>atan2(-m10, m00) == atan2(m01, m11)</code>.
|
||||||
|
*
|
||||||
|
* @return the angle
|
||||||
|
*/
|
||||||
|
double getRotation();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix in column-major order into the supplied {@link DoubleBuffer} at the current
|
||||||
|
* buffer {@link DoubleBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given DoubleBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the DoubleBuffer at which
|
||||||
|
* the matrix is stored, use {@link #get(int, DoubleBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @see #get(int, DoubleBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order at its current position
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
DoubleBuffer get(DoubleBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix in column-major order into the supplied {@link DoubleBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given DoubleBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the DoubleBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
DoubleBuffer get(int index, DoubleBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix in column-major order into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which
|
||||||
|
* the matrix is stored, use {@link #get(int, ByteBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @see #get(int, ByteBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order at its current position
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the transpose of this matrix in column-major order into the supplied {@link DoubleBuffer} at the current
|
||||||
|
* buffer {@link DoubleBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given DoubleBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the DoubleBuffer at which
|
||||||
|
* the matrix is stored, use {@link #getTransposed(int, DoubleBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @see #getTransposed(int, DoubleBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order at its current position
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
DoubleBuffer getTransposed(DoubleBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the transpose of this matrix in column-major order into the supplied {@link DoubleBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given DoubleBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the DoubleBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
DoubleBuffer getTransposed(int index, DoubleBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which
|
||||||
|
* the matrix is stored, use {@link #getTransposed(int, ByteBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @see #getTransposed(int, ByteBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order at its current position
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer getTransposed(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer getTransposed(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix in column-major order at the given off-heap address.
|
||||||
|
* <p>
|
||||||
|
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
|
||||||
|
* <p>
|
||||||
|
* <em>This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.</em>
|
||||||
|
*
|
||||||
|
* @param address
|
||||||
|
* the off-heap address where to store this matrix
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
Matrix2dc getToAddress(long address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix into the supplied double array in column-major order at the given offset.
|
||||||
|
*
|
||||||
|
* @param arr
|
||||||
|
* the array to write the matrix values into
|
||||||
|
* @param offset
|
||||||
|
* the offset into the array
|
||||||
|
* @return the passed in array
|
||||||
|
*/
|
||||||
|
double[] get(double[] arr, int offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix into the supplied double array in column-major order.
|
||||||
|
* <p>
|
||||||
|
* In order to specify an explicit offset into the array, use the method {@link #get(double[], int)}.
|
||||||
|
*
|
||||||
|
* @see #get(double[], int)
|
||||||
|
*
|
||||||
|
* @param arr
|
||||||
|
* the array to write the matrix values into
|
||||||
|
* @return the passed in array
|
||||||
|
*/
|
||||||
|
double[] get(double[] arr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply scaling to <code>this</code> matrix by scaling the base axes by the given <code>xy.x</code> and
|
||||||
|
* <code>xy.y</code> factors, respectively and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>S</code> the scaling matrix,
|
||||||
|
* then the new matrix will be <code>M * S</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>M * S * v</code>
|
||||||
|
* , the scaling will be applied first!
|
||||||
|
*
|
||||||
|
* @param xy
|
||||||
|
* the factors of the x and y component, respectively
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d scale(Vector2dc xy, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply scaling to this matrix by scaling the base axes by the given x and
|
||||||
|
* y factors and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>S</code> the scaling matrix,
|
||||||
|
* then the new matrix will be <code>M * S</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>M * S * v</code>
|
||||||
|
* , the scaling will be applied first!
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the factor of the x component
|
||||||
|
* @param y
|
||||||
|
* the factor of the y component
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d scale(double x, double y, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply scaling to this matrix by uniformly scaling all base axes by the given <code>xy</code> factor
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>S</code> the scaling matrix,
|
||||||
|
* then the new matrix will be <code>M * S</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>M * S * v</code>
|
||||||
|
* , the scaling will be applied first!
|
||||||
|
*
|
||||||
|
* @see #scale(double, double, Matrix2d)
|
||||||
|
*
|
||||||
|
* @param xy
|
||||||
|
* the factor for all components
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d scale(double xy, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-multiply scaling to <code>this</code> matrix by scaling the base axes by the given x and
|
||||||
|
* y factors and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>S</code> the scaling matrix,
|
||||||
|
* then the new matrix will be <code>S * M</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>S * M * v</code>
|
||||||
|
* , the scaling will be applied last!
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the factor of the x component
|
||||||
|
* @param y
|
||||||
|
* the factor of the y component
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d scaleLocal(double x, double y, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by this matrix.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @return v
|
||||||
|
*/
|
||||||
|
Vector2d transform(Vector2d v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by this matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d transform(Vector2dc v, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the vector <code>(x, y)</code> by this matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the vector to transform
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d transform(double x, double y, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the transpose of this matrix.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @return v
|
||||||
|
*/
|
||||||
|
Vector2d transformTranspose(Vector2d v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the transpose of this matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d transformTranspose(Vector2dc v, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the vector <code>(x, y)</code> by the transpose of this matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the vector to transform
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d transformTranspose(double x, double y, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply rotation to this matrix by rotating the given amount of radians
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* The produced rotation will rotate a vector counter-clockwise around the origin.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>R</code> the rotation matrix,
|
||||||
|
* then the new matrix will be <code>M * R</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>M * R * v</code>
|
||||||
|
* , the rotation will be applied first!
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="https://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions">http://en.wikipedia.org</a>
|
||||||
|
*
|
||||||
|
* @param ang
|
||||||
|
* the angle in radians
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d rotate(double ang, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-multiply a rotation to this matrix by rotating the given amount of radians
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* The produced rotation will rotate a vector counter-clockwise around the origin.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>R</code> the rotation matrix,
|
||||||
|
* then the new matrix will be <code>R * M</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>R * M * v</code>, the
|
||||||
|
* rotation will be applied last!
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="https://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions">http://en.wikipedia.org</a>
|
||||||
|
*
|
||||||
|
* @param ang
|
||||||
|
* the angle in radians
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d rotateLocal(double ang, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the row at the given <code>row</code> index, starting with <code>0</code>.
|
||||||
|
*
|
||||||
|
* @param row
|
||||||
|
* the row index in <code>[0..1]</code>
|
||||||
|
* @param dest
|
||||||
|
* will hold the row components
|
||||||
|
* @return the passed in destination
|
||||||
|
* @throws IndexOutOfBoundsException if <code>row</code> is not in <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
Vector2d getRow(int row, Vector2d dest) throws IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the column at the given <code>column</code> index, starting with <code>0</code>.
|
||||||
|
*
|
||||||
|
* @param column
|
||||||
|
* the column index in <code>[0..1]</code>
|
||||||
|
* @param dest
|
||||||
|
* will hold the column components
|
||||||
|
* @return the passed in destination
|
||||||
|
* @throws IndexOutOfBoundsException if <code>column</code> is not in <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
Vector2d getColumn(int column, Vector2d dest) throws IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the matrix element value at the given column and row.
|
||||||
|
*
|
||||||
|
* @param column
|
||||||
|
* the colum index in <code>[0..1]</code>
|
||||||
|
* @param row
|
||||||
|
* the row index in <code>[0..1]</code>
|
||||||
|
* @return the element value
|
||||||
|
*/
|
||||||
|
double get(int column, int row);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a normal matrix from <code>this</code> matrix and store it into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d normal(Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the scaling factors of <code>this</code> matrix for the three base axes.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the scaling factors for <code>x</code> and <code>y</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d getScale(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the direction of <code>+X</code> before the transformation represented by <code>this</code> matrix is applied.
|
||||||
|
* <p>
|
||||||
|
* This method is equivalent to the following code:
|
||||||
|
* <pre>
|
||||||
|
* Matrix2d inv = new Matrix2d(this).invert();
|
||||||
|
* inv.transform(dir.set(1, 0)).normalize();
|
||||||
|
* </pre>
|
||||||
|
* If <code>this</code> is already an orthogonal matrix, then consider using {@link #normalizedPositiveX(Vector2d)} instead.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the direction of <code>+X</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d positiveX(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the direction of <code>+X</code> before the transformation represented by <code>this</code> <i>orthogonal</i> matrix is applied.
|
||||||
|
* This method only produces correct results if <code>this</code> is an <i>orthogonal</i> matrix.
|
||||||
|
* <p>
|
||||||
|
* This method is equivalent to the following code:
|
||||||
|
* <pre>
|
||||||
|
* Matrix2d inv = new Matrix2d(this).transpose();
|
||||||
|
* inv.transform(dir.set(1, 0));
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the direction of <code>+X</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d normalizedPositiveX(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the direction of <code>+Y</code> before the transformation represented by <code>this</code> matrix is applied.
|
||||||
|
* <p>
|
||||||
|
* This method is equivalent to the following code:
|
||||||
|
* <pre>
|
||||||
|
* Matrix2d inv = new Matrix2d(this).invert();
|
||||||
|
* inv.transform(dir.set(0, 1)).normalize();
|
||||||
|
* </pre>
|
||||||
|
* If <code>this</code> is already an orthogonal matrix, then consider using {@link #normalizedPositiveY(Vector2d)} instead.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the direction of <code>+Y</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d positiveY(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the direction of <code>+Y</code> before the transformation represented by <code>this</code> <i>orthogonal</i> matrix is applied.
|
||||||
|
* This method only produces correct results if <code>this</code> is an <i>orthogonal</i> matrix.
|
||||||
|
* <p>
|
||||||
|
* This method is equivalent to the following code:
|
||||||
|
* <pre>
|
||||||
|
* Matrix2d inv = new Matrix2d(this).transpose();
|
||||||
|
* inv.transform(dir.set(0, 1));
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the direction of <code>+Y</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d normalizedPositiveY(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component-wise add <code>this</code> and <code>other</code> and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* the other addend
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d add(Matrix2dc other, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component-wise subtract <code>subtrahend</code> from <code>this</code> and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param subtrahend
|
||||||
|
* the subtrahend
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d sub(Matrix2dc subtrahend, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component-wise multiply <code>this</code> by <code>other</code> and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* the other matrix
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d mulComponentWise(Matrix2dc other, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linearly interpolate <code>this</code> and <code>other</code> using the given interpolation factor <code>t</code>
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>t</code> is <code>0.0</code> then the result is <code>this</code>. If the interpolation factor is <code>1.0</code>
|
||||||
|
* then the result is <code>other</code>.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* the other matrix
|
||||||
|
* @param t
|
||||||
|
* the interpolation factor between 0.0 and 1.0
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2d lerp(Matrix2dc other, double t, Matrix2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the matrix elements of <code>this</code> matrix with the given matrix using the given <code>delta</code>
|
||||||
|
* and return whether all of them are equal within a maximum difference of <code>delta</code>.
|
||||||
|
* <p>
|
||||||
|
* Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
|
||||||
|
* and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
|
||||||
|
* data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the other matrix
|
||||||
|
* @param delta
|
||||||
|
* the allowed maximum difference
|
||||||
|
* @return <code>true</code> whether all of the matrix elements are equal; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
boolean equals(Matrix2dc m, double delta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether all matrix elements are finite floating-point values, that
|
||||||
|
* is, they are not {@link Double#isNaN() NaN} and not
|
||||||
|
* {@link Double#isInfinite() infinity}.
|
||||||
|
*
|
||||||
|
* @return {@code true} if all components are finite floating-point values;
|
||||||
|
* {@code false} otherwise
|
||||||
|
*/
|
||||||
|
boolean isFinite();
|
||||||
|
|
||||||
|
}
|
1429
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2f.java
Normal file
1429
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2f.java
Normal file
File diff suppressed because it is too large
Load diff
709
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2fc.java
Normal file
709
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2fc.java
Normal file
|
@ -0,0 +1,709 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to a read-only view of a 2x2 matrix of single-precision floats.
|
||||||
|
*
|
||||||
|
* @author Joseph Burton
|
||||||
|
*/
|
||||||
|
public interface Matrix2fc {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of the matrix element at column 0 and row 0.
|
||||||
|
*
|
||||||
|
* @return the value of the matrix element
|
||||||
|
*/
|
||||||
|
float m00();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of the matrix element at column 0 and row 1.
|
||||||
|
*
|
||||||
|
* @return the value of the matrix element
|
||||||
|
*/
|
||||||
|
float m01();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of the matrix element at column 1 and row 0.
|
||||||
|
*
|
||||||
|
* @return the value of the matrix element
|
||||||
|
*/
|
||||||
|
float m10();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of the matrix element at column 1 and row 1.
|
||||||
|
*
|
||||||
|
* @return the value of the matrix element
|
||||||
|
*/
|
||||||
|
float m11();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply this matrix by the supplied <code>right</code> matrix and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>R</code> the <code>right</code> matrix,
|
||||||
|
* then the new matrix will be <code>M * R</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>M * R * v</code>, the
|
||||||
|
* transformation of the right matrix will be applied first!
|
||||||
|
*
|
||||||
|
* @param right
|
||||||
|
* the right operand of the matrix multiplication
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f mul(Matrix2fc right, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-multiply this matrix by the supplied <code>left</code> matrix and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>L</code> the <code>left</code> matrix,
|
||||||
|
* then the new matrix will be <code>L * M</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>L * M * v</code>, the
|
||||||
|
* transformation of <code>this</code> matrix will be applied first!
|
||||||
|
*
|
||||||
|
* @param left
|
||||||
|
* the left operand of the matrix multiplication
|
||||||
|
* @param dest
|
||||||
|
* the destination matrix, which will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f mulLocal(Matrix2fc left, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the determinant of this matrix.
|
||||||
|
*
|
||||||
|
* @return the determinant
|
||||||
|
*/
|
||||||
|
float determinant();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invert the <code>this</code> matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f invert(Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transpose <code>this</code> matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f transpose(Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current values of <code>this</code> matrix and store them into
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* the destination matrix
|
||||||
|
* @return the passed in destination
|
||||||
|
*/
|
||||||
|
Matrix2f get(Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current values of <code>this</code> matrix and store them as
|
||||||
|
* the rotational component of <code>dest</code>. All other values of <code>dest</code> will
|
||||||
|
* be set to 0.
|
||||||
|
*
|
||||||
|
* @see Matrix3x2f#set(Matrix2fc)
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* the destination matrix
|
||||||
|
* @return the passed in destination
|
||||||
|
*/
|
||||||
|
Matrix3x2f get(Matrix3x2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current values of <code>this</code> matrix and store them as
|
||||||
|
* the rotational component of <code>dest</code>. All other values of <code>dest</code> will
|
||||||
|
* be set to identity.
|
||||||
|
*
|
||||||
|
* @see Matrix3f#set(Matrix2fc)
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* the destination matrix
|
||||||
|
* @return the passed in destination
|
||||||
|
*/
|
||||||
|
Matrix3f get(Matrix3f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the angle of the rotation component of <code>this</code> matrix.
|
||||||
|
* <p>
|
||||||
|
* This method assumes that there is a valid rotation to be returned, i.e. that
|
||||||
|
* <code>atan2(-m10, m00) == atan2(m01, m11)</code>.
|
||||||
|
*
|
||||||
|
* @return the angle
|
||||||
|
*/
|
||||||
|
float getRotation();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix in column-major order into the supplied {@link FloatBuffer} at the current
|
||||||
|
* buffer {@link FloatBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given FloatBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the FloatBuffer at which
|
||||||
|
* the matrix is stored, use {@link #get(int, FloatBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @see #get(int, FloatBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order at its current position
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
FloatBuffer get(FloatBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given FloatBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the FloatBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
FloatBuffer get(int index, FloatBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix in column-major order into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which
|
||||||
|
* the matrix is stored, use {@link #get(int, ByteBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @see #get(int, ByteBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order at its current position
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the transpose of this matrix in column-major order into the supplied {@link FloatBuffer} at the current
|
||||||
|
* buffer {@link FloatBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given FloatBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the FloatBuffer at which
|
||||||
|
* the matrix is stored, use {@link #getTransposed(int, FloatBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @see #getTransposed(int, FloatBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order at its current position
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
FloatBuffer getTransposed(FloatBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the transpose of this matrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given FloatBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the FloatBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
FloatBuffer getTransposed(int index, FloatBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which
|
||||||
|
* the matrix is stored, use {@link #getTransposed(int, ByteBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @see #getTransposed(int, ByteBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order at its current position
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer getTransposed(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this matrix in column-major order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer getTransposed(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix in column-major order at the given off-heap address.
|
||||||
|
* <p>
|
||||||
|
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
|
||||||
|
* <p>
|
||||||
|
* <em>This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.</em>
|
||||||
|
*
|
||||||
|
* @param address
|
||||||
|
* the off-heap address where to store this matrix
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
Matrix2fc getToAddress(long address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix into the supplied float array in column-major order at the given offset.
|
||||||
|
*
|
||||||
|
* @param arr
|
||||||
|
* the array to write the matrix values into
|
||||||
|
* @param offset
|
||||||
|
* the offset into the array
|
||||||
|
* @return the passed in array
|
||||||
|
*/
|
||||||
|
float[] get(float[] arr, int offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this matrix into the supplied float array in column-major order.
|
||||||
|
* <p>
|
||||||
|
* In order to specify an explicit offset into the array, use the method {@link #get(float[], int)}.
|
||||||
|
*
|
||||||
|
* @see #get(float[], int)
|
||||||
|
*
|
||||||
|
* @param arr
|
||||||
|
* the array to write the matrix values into
|
||||||
|
* @return the passed in array
|
||||||
|
*/
|
||||||
|
float[] get(float[] arr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply scaling to <code>this</code> matrix by scaling the base axes by the given <code>xy.x</code> and
|
||||||
|
* <code>xy.y</code> factors, respectively and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>S</code> the scaling matrix,
|
||||||
|
* then the new matrix will be <code>M * S</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>M * S * v</code>
|
||||||
|
* , the scaling will be applied first!
|
||||||
|
*
|
||||||
|
* @param xy
|
||||||
|
* the factors of the x and y component, respectively
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f scale(Vector2fc xy, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply scaling to this matrix by scaling the base axes by the given x and
|
||||||
|
* y factors and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>S</code> the scaling matrix,
|
||||||
|
* then the new matrix will be <code>M * S</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>M * S * v</code>
|
||||||
|
* , the scaling will be applied first!
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the factor of the x component
|
||||||
|
* @param y
|
||||||
|
* the factor of the y component
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f scale(float x, float y, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply scaling to this matrix by uniformly scaling all base axes by the given <code>xy</code> factor
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>S</code> the scaling matrix,
|
||||||
|
* then the new matrix will be <code>M * S</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>M * S * v</code>
|
||||||
|
* , the scaling will be applied first!
|
||||||
|
*
|
||||||
|
* @see #scale(float, float, Matrix2f)
|
||||||
|
*
|
||||||
|
* @param xy
|
||||||
|
* the factor for all components
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f scale(float xy, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-multiply scaling to <code>this</code> matrix by scaling the base axes by the given x and
|
||||||
|
* y factors and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>S</code> the scaling matrix,
|
||||||
|
* then the new matrix will be <code>S * M</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>S * M * v</code>
|
||||||
|
* , the scaling will be applied last!
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the factor of the x component
|
||||||
|
* @param y
|
||||||
|
* the factor of the y component
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f scaleLocal(float x, float y, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by this matrix.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @return v
|
||||||
|
*/
|
||||||
|
Vector2f transform(Vector2f v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by this matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f transform(Vector2fc v, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the vector <code>(x, y)</code> by this matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the vector to transform
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f transform(float x, float y, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the transpose of this matrix.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @return v
|
||||||
|
*/
|
||||||
|
Vector2f transformTranspose(Vector2f v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given vector by the transpose of this matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f transformTranspose(Vector2fc v, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the vector <code>(x, y)</code> by the transpose of this matrix and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the vector to transform
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the vector to transform
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f transformTranspose(float x, float y, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply rotation to this matrix by rotating the given amount of radians
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* The produced rotation will rotate a vector counter-clockwise around the origin.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>R</code> the rotation matrix,
|
||||||
|
* then the new matrix will be <code>M * R</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>M * R * v</code>
|
||||||
|
* , the rotation will be applied first!
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="https://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions">http://en.wikipedia.org</a>
|
||||||
|
*
|
||||||
|
* @param ang
|
||||||
|
* the angle in radians
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f rotate(float ang, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-multiply a rotation to this matrix by rotating the given amount of radians
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* The produced rotation will rotate a vector counter-clockwise around the origin.
|
||||||
|
* <p>
|
||||||
|
* If <code>M</code> is <code>this</code> matrix and <code>R</code> the rotation matrix,
|
||||||
|
* then the new matrix will be <code>R * M</code>. So when transforming a
|
||||||
|
* vector <code>v</code> with the new matrix by using <code>R * M * v</code>, the
|
||||||
|
* rotation will be applied last!
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="https://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions">http://en.wikipedia.org</a>
|
||||||
|
*
|
||||||
|
* @param ang
|
||||||
|
* the angle in radians
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f rotateLocal(float ang, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the row at the given <code>row</code> index, starting with <code>0</code>.
|
||||||
|
*
|
||||||
|
* @param row
|
||||||
|
* the row index in <code>[0..1]</code>
|
||||||
|
* @param dest
|
||||||
|
* will hold the row components
|
||||||
|
* @return the passed in destination
|
||||||
|
* @throws IndexOutOfBoundsException if <code>row</code> is not in <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
Vector2f getRow(int row, Vector2f dest) throws IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the column at the given <code>column</code> index, starting with <code>0</code>.
|
||||||
|
*
|
||||||
|
* @param column
|
||||||
|
* the column index in <code>[0..1]</code>
|
||||||
|
* @param dest
|
||||||
|
* will hold the column components
|
||||||
|
* @return the passed in destination
|
||||||
|
* @throws IndexOutOfBoundsException if <code>column</code> is not in <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
Vector2f getColumn(int column, Vector2f dest) throws IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the matrix element value at the given column and row.
|
||||||
|
*
|
||||||
|
* @param column
|
||||||
|
* the colum index in <code>[0..1]</code>
|
||||||
|
* @param row
|
||||||
|
* the row index in <code>[0..1]</code>
|
||||||
|
* @return the element value
|
||||||
|
*/
|
||||||
|
float get(int column, int row);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a normal matrix from <code>this</code> matrix and store it into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f normal(Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the scaling factors of <code>this</code> matrix for the three base axes.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the scaling factors for <code>x</code> and <code>y</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f getScale(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the direction of <code>+X</code> before the transformation represented by <code>this</code> matrix is applied.
|
||||||
|
* <p>
|
||||||
|
* This method is equivalent to the following code:
|
||||||
|
* <pre>
|
||||||
|
* Matrix2f inv = new Matrix2f(this).invert();
|
||||||
|
* inv.transform(dir.set(1, 0)).normalize();
|
||||||
|
* </pre>
|
||||||
|
* If <code>this</code> is already an orthogonal matrix, then consider using {@link #normalizedPositiveX(Vector2f)} instead.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the direction of <code>+X</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f positiveX(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the direction of <code>+X</code> before the transformation represented by <code>this</code> <i>orthogonal</i> matrix is applied.
|
||||||
|
* This method only produces correct results if <code>this</code> is an <i>orthogonal</i> matrix.
|
||||||
|
* <p>
|
||||||
|
* This method is equivalent to the following code:
|
||||||
|
* <pre>
|
||||||
|
* Matrix2f inv = new Matrix2f(this).transpose();
|
||||||
|
* inv.transform(dir.set(1, 0));
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the direction of <code>+X</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f normalizedPositiveX(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the direction of <code>+Y</code> before the transformation represented by <code>this</code> matrix is applied.
|
||||||
|
* <p>
|
||||||
|
* This method is equivalent to the following code:
|
||||||
|
* <pre>
|
||||||
|
* Matrix2f inv = new Matrix2f(this).invert();
|
||||||
|
* inv.transform(dir.set(0, 1)).normalize();
|
||||||
|
* </pre>
|
||||||
|
* If <code>this</code> is already an orthogonal matrix, then consider using {@link #normalizedPositiveY(Vector2f)} instead.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the direction of <code>+Y</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f positiveY(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the direction of <code>+Y</code> before the transformation represented by <code>this</code> <i>orthogonal</i> matrix is applied.
|
||||||
|
* This method only produces correct results if <code>this</code> is an <i>orthogonal</i> matrix.
|
||||||
|
* <p>
|
||||||
|
* This method is equivalent to the following code:
|
||||||
|
* <pre>
|
||||||
|
* Matrix2f inv = new Matrix2f(this).transpose();
|
||||||
|
* inv.transform(dir.set(0, 1));
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the direction of <code>+Y</code>
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f normalizedPositiveY(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component-wise add <code>this</code> and <code>other</code> and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* the other addend
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f add(Matrix2fc other, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component-wise subtract <code>subtrahend</code> from <code>this</code> and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param subtrahend
|
||||||
|
* the subtrahend
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f sub(Matrix2fc subtrahend, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component-wise multiply <code>this</code> by <code>other</code> and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* the other matrix
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f mulComponentWise(Matrix2fc other, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linearly interpolate <code>this</code> and <code>other</code> using the given interpolation factor <code>t</code>
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>t</code> is <code>0.0</code> then the result is <code>this</code>. If the interpolation factor is <code>1.0</code>
|
||||||
|
* then the result is <code>other</code>.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* the other matrix
|
||||||
|
* @param t
|
||||||
|
* the interpolation factor between 0.0 and 1.0
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Matrix2f lerp(Matrix2fc other, float t, Matrix2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the matrix elements of <code>this</code> matrix with the given matrix using the given <code>delta</code>
|
||||||
|
* and return whether all of them are equal within a maximum difference of <code>delta</code>.
|
||||||
|
* <p>
|
||||||
|
* Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
|
||||||
|
* and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
|
||||||
|
* data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* the other matrix
|
||||||
|
* @param delta
|
||||||
|
* the allowed maximum difference
|
||||||
|
* @return <code>true</code> whether all of the matrix elements are equal; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
boolean equals(Matrix2fc m, float delta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether all matrix elements are finite floating-point values, that
|
||||||
|
* is, they are not {@link Float#isNaN() NaN} and not
|
||||||
|
* {@link Float#isInfinite() infinity}.
|
||||||
|
*
|
||||||
|
* @return {@code true} if all components are finite floating-point values;
|
||||||
|
* {@code false} otherwise
|
||||||
|
*/
|
||||||
|
boolean isFinite();
|
||||||
|
|
||||||
|
}
|
5582
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3d.java
Normal file
5582
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3d.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stack of many {@link Matrix3d} instances. This resembles the matrix stack known from legacy OpenGL.
|
||||||
|
* <p>
|
||||||
|
* This {@link Matrix3dStack} class inherits from {@link Matrix3d}, so the current/top matrix is always the
|
||||||
|
* {@link Matrix3dStack}/{@link Matrix3d} itself. This affects all operations in {@link Matrix3d} that take another
|
||||||
|
* {@link Matrix3d} as parameter. If a {@link Matrix3dStack} is used as argument to those methods, the effective
|
||||||
|
* argument will always be the <i>current</i> matrix of the matrix stack.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Matrix3dStack extends Matrix3d {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The matrix stack as a non-growable array. The size of the stack must be specified in the {@link #Matrix3dStack(int) constructor}.
|
||||||
|
*/
|
||||||
|
private Matrix3d[] mats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the "current" matrix within {@link #mats}.
|
||||||
|
*/
|
||||||
|
private int curr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Matrix3dStack} of the given size.
|
||||||
|
* <p>
|
||||||
|
* Initially the stack pointer is at zero and the current matrix is set to identity.
|
||||||
|
*
|
||||||
|
* @param stackSize
|
||||||
|
* the size of the stack. This must be at least 1, in which case the {@link Matrix3dStack} simply only consists of <code>this</code>
|
||||||
|
* {@link Matrix3d}
|
||||||
|
*/
|
||||||
|
public Matrix3dStack(int stackSize) {
|
||||||
|
if (stackSize < 1) {
|
||||||
|
throw new IllegalArgumentException("stackSize must be >= 1"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
mats = new Matrix3d[stackSize - 1];
|
||||||
|
// Allocate all matrices up front to keep the promise of being "allocation-free"
|
||||||
|
for (int i = 0; i < mats.length; i++) {
|
||||||
|
mats[i] = new Matrix3d();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not invoke manually! Only meant for serialization.
|
||||||
|
* <p>
|
||||||
|
* Invoking this constructor from client code will result in an inconsistent state of the
|
||||||
|
* created {@link Matrix3dStack} instance.
|
||||||
|
*/
|
||||||
|
public Matrix3dStack() {
|
||||||
|
/* Empty! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the stack pointer to zero and set the current/bottom matrix to {@link #identity() identity}.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3dStack clear() {
|
||||||
|
curr = 0;
|
||||||
|
identity();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the stack pointer by one and set the values of the new current matrix to the one directly below it.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3dStack pushMatrix() {
|
||||||
|
if (curr == mats.length) {
|
||||||
|
throw new IllegalStateException("max stack size of " + (curr + 1) + " reached"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
mats[curr++].set(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the stack pointer by one.
|
||||||
|
* <p>
|
||||||
|
* This will effectively dispose of the current matrix.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3dStack popMatrix() {
|
||||||
|
if (curr == 0) {
|
||||||
|
throw new IllegalStateException("already at the bottom of the stack"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
set(mats[--curr]);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + curr;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
result = prime * result + mats[i].hashCode();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contract between Matrix3d and Matrix3dStack:
|
||||||
|
*
|
||||||
|
* - Matrix3d.equals(Matrix3dStack) is true iff all the 9 matrix elements are equal
|
||||||
|
* - Matrix3dStack.equals(Matrix3d) is true iff all the 9 matrix elements are equal
|
||||||
|
* - Matrix3dStack.equals(Matrix3dStack) is true iff all 9 matrix elements are equal AND the matrix arrays as well as the stack pointer are equal
|
||||||
|
* - everything else is inequal
|
||||||
|
*/
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!super.equals(obj))
|
||||||
|
return false;
|
||||||
|
if (obj instanceof Matrix3dStack) {
|
||||||
|
Matrix3dStack other = (Matrix3dStack) obj;
|
||||||
|
if (curr != other.curr)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
if (!mats[i].equals(other.mats[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
|
super.writeExternal(out);
|
||||||
|
out.writeInt(curr);
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
out.writeObject(mats[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readExternal(ObjectInput in) throws IOException {
|
||||||
|
super.readExternal(in);
|
||||||
|
curr = in.readInt();
|
||||||
|
mats = new Matrix3dStack[curr];
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
Matrix3d m = new Matrix3d();
|
||||||
|
m.readExternal(in);
|
||||||
|
mats[i] = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
Matrix3dStack cloned = (Matrix3dStack) super.clone();
|
||||||
|
Matrix3d[] clonedMats = new Matrix3d[mats.length];
|
||||||
|
for (int i = 0; i < mats.length; i++)
|
||||||
|
clonedMats[i] = (Matrix3d) mats[i].clone();
|
||||||
|
cloned.mats = clonedMats;
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
2310
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3dc.java
Normal file
2310
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3dc.java
Normal file
File diff suppressed because it is too large
Load diff
4920
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3f.java
Normal file
4920
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3f.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stack of many {@link Matrix3f} instances. This resembles the matrix stack known from legacy OpenGL.
|
||||||
|
* <p>
|
||||||
|
* This {@link Matrix3fStack} class inherits from {@link Matrix3f}, so the current/top matrix is always the
|
||||||
|
* {@link Matrix3fStack}/{@link Matrix3f} itself. This affects all operations in {@link Matrix3f} that take another
|
||||||
|
* {@link Matrix3f} as parameter. If a {@link Matrix3fStack} is used as argument to those methods, the effective
|
||||||
|
* argument will always be the <i>current</i> matrix of the matrix stack.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Matrix3fStack extends Matrix3f {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The matrix stack as a non-growable array. The size of the stack must be specified in the {@link #Matrix3fStack(int) constructor}.
|
||||||
|
*/
|
||||||
|
private Matrix3f[] mats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the "current" matrix within {@link #mats}.
|
||||||
|
*/
|
||||||
|
private int curr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Matrix3fStack} of the given size.
|
||||||
|
* <p>
|
||||||
|
* Initially the stack pointer is at zero and the current matrix is set to identity.
|
||||||
|
*
|
||||||
|
* @param stackSize
|
||||||
|
* the size of the stack. This must be at least 1, in which case the {@link Matrix3fStack} simply only consists of <code>this</code>
|
||||||
|
* {@link Matrix3f}
|
||||||
|
*/
|
||||||
|
public Matrix3fStack(int stackSize) {
|
||||||
|
if (stackSize < 1) {
|
||||||
|
throw new IllegalArgumentException("stackSize must be >= 1"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
mats = new Matrix3f[stackSize - 1];
|
||||||
|
// Allocate all matrices up front to keep the promise of being "allocation-free"
|
||||||
|
for (int i = 0; i < mats.length; i++) {
|
||||||
|
mats[i] = new Matrix3f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not invoke manually! Only meant for serialization.
|
||||||
|
* <p>
|
||||||
|
* Invoking this constructor from client code will result in an inconsistent state of the
|
||||||
|
* created {@link Matrix3fStack} instance.
|
||||||
|
*/
|
||||||
|
public Matrix3fStack() {
|
||||||
|
/* Empty! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the stack pointer to zero and set the current/bottom matrix to {@link #identity() identity}.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3fStack clear() {
|
||||||
|
curr = 0;
|
||||||
|
identity();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the stack pointer by one and set the values of the new current matrix to the one directly below it.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3fStack pushMatrix() {
|
||||||
|
if (curr == mats.length) {
|
||||||
|
throw new IllegalStateException("max stack size of " + (curr + 1) + " reached"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
mats[curr++].set(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the stack pointer by one.
|
||||||
|
* <p>
|
||||||
|
* This will effectively dispose of the current matrix.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3fStack popMatrix() {
|
||||||
|
if (curr == 0) {
|
||||||
|
throw new IllegalStateException("already at the bottom of the stack"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
set(mats[--curr]);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + curr;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
result = prime * result + mats[i].hashCode();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contract between Matrix3f and Matrix3fStack:
|
||||||
|
*
|
||||||
|
* - Matrix3f.equals(Matrix3fStack) is true iff all the 9 matrix elements are equal
|
||||||
|
* - Matrix3fStack.equals(Matrix3f) is true iff all the 9 matrix elements are equal
|
||||||
|
* - Matrix3fStack.equals(Matrix3fStack) is true iff all 9 matrix elements are equal AND the matrix arrays as well as the stack pointer are equal
|
||||||
|
* - everything else is inequal
|
||||||
|
*/
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!super.equals(obj))
|
||||||
|
return false;
|
||||||
|
if (obj instanceof Matrix3fStack) {
|
||||||
|
Matrix3fStack other = (Matrix3fStack) obj;
|
||||||
|
if (curr != other.curr)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
if (!mats[i].equals(other.mats[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
|
super.writeExternal(out);
|
||||||
|
out.writeInt(curr);
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
out.writeObject(mats[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readExternal(ObjectInput in) throws IOException {
|
||||||
|
super.readExternal(in);
|
||||||
|
curr = in.readInt();
|
||||||
|
mats = new Matrix3fStack[curr];
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
Matrix3f m = new Matrix3f();
|
||||||
|
m.readExternal(in);
|
||||||
|
mats[i] = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
Matrix3fStack cloned = (Matrix3fStack) super.clone();
|
||||||
|
Matrix3f[] clonedMats = new Matrix3f[mats.length];
|
||||||
|
for (int i = 0; i < mats.length; i++)
|
||||||
|
clonedMats[i] = (Matrix3f) mats[i].clone();
|
||||||
|
cloned.mats = clonedMats;
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
2199
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3fc.java
Normal file
2199
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3fc.java
Normal file
File diff suppressed because it is too large
Load diff
2497
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2d.java
Normal file
2497
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2d.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stack of many {@link Matrix3x2d} instances. This resembles the matrix stack known from legacy OpenGL.
|
||||||
|
* <p>
|
||||||
|
* This {@link Matrix3x2dStack} class inherits from {@link Matrix3x2d}, so the current/top matrix is always the
|
||||||
|
* {@link Matrix3x2dStack}/{@link Matrix3x2d} itself. This affects all operations in {@link Matrix3x2d} that take
|
||||||
|
* another {@link Matrix3x2d} as parameter. If a {@link Matrix3x2dStack} is used as argument to those methods, the
|
||||||
|
* effective argument will always be the <i>current</i> matrix of the matrix stack.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Matrix3x2dStack extends Matrix3x2d implements Cloneable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The matrix stack as a non-growable array. The size of the stack must be specified in the {@link #Matrix3x2dStack(int) constructor}.
|
||||||
|
*/
|
||||||
|
private Matrix3x2d[] mats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the "current" matrix within {@link #mats}.
|
||||||
|
*/
|
||||||
|
private int curr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Matrix3x2dStack} of the given size.
|
||||||
|
* <p>
|
||||||
|
* Initially the stack pointer is at zero and the current matrix is set to identity.
|
||||||
|
*
|
||||||
|
* @param stackSize
|
||||||
|
* the size of the stack. This must be at least 1, in which case the {@link Matrix3x2dStack} simply only consists of <code>this</code>
|
||||||
|
* {@link Matrix3x2d}
|
||||||
|
*/
|
||||||
|
public Matrix3x2dStack(int stackSize) {
|
||||||
|
if (stackSize < 1) {
|
||||||
|
throw new IllegalArgumentException("stackSize must be >= 1"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
mats = new Matrix3x2d[stackSize - 1];
|
||||||
|
// Allocate all matrices up front to keep the promise of being "allocation-free"
|
||||||
|
for (int i = 0; i < mats.length; i++) {
|
||||||
|
mats[i] = new Matrix3x2d();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not invoke manually! Only meant for serialization.
|
||||||
|
* <p>
|
||||||
|
* Invoking this constructor from client code will result in an inconsistent state of the
|
||||||
|
* created {@link Matrix3x2dStack} instance.
|
||||||
|
*/
|
||||||
|
public Matrix3x2dStack() {
|
||||||
|
/* Empty! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the stack pointer to zero and set the current/bottom matrix to {@link #identity() identity}.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3x2dStack clear() {
|
||||||
|
curr = 0;
|
||||||
|
identity();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the stack pointer by one and set the values of the new current matrix to the one directly below it.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3x2dStack pushMatrix() {
|
||||||
|
if (curr == mats.length) {
|
||||||
|
throw new IllegalStateException("max stack size of " + (curr + 1) + " reached"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
mats[curr++].set(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the stack pointer by one.
|
||||||
|
* <p>
|
||||||
|
* This will effectively dispose of the current matrix.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3x2dStack popMatrix() {
|
||||||
|
if (curr == 0) {
|
||||||
|
throw new IllegalStateException("already at the bottom of the stack"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
set(mats[--curr]);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + curr;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
result = prime * result + mats[i].hashCode();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contract between Matrix3x2d and Matrix3x2dStack:
|
||||||
|
*
|
||||||
|
* - Matrix3x2d.equals(Matrix3x2dStack) is true iff all the 6 matrix elements are equal
|
||||||
|
* - Matrix3x2dStack.equals(Matrix3x2d) is true iff all the 6 matrix elements are equal
|
||||||
|
* - Matrix3x2dStack.equals(Matrix3x2dStack) is true iff all 6 matrix elements are equal AND the matrix arrays as well as the stack pointer are equal
|
||||||
|
* - everything else is inequal
|
||||||
|
*/
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!super.equals(obj))
|
||||||
|
return false;
|
||||||
|
if (obj instanceof Matrix3x2dStack) {
|
||||||
|
Matrix3x2dStack other = (Matrix3x2dStack) obj;
|
||||||
|
if (curr != other.curr)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
if (!mats[i].equals(other.mats[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
|
super.writeExternal(out);
|
||||||
|
out.writeInt(curr);
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
out.writeObject(mats[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readExternal(ObjectInput in) throws IOException {
|
||||||
|
super.readExternal(in);
|
||||||
|
curr = in.readInt();
|
||||||
|
mats = new Matrix3x2dStack[curr];
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
Matrix3x2d m = new Matrix3x2d();
|
||||||
|
m.readExternal(in);
|
||||||
|
mats[i] = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
Matrix3x2dStack cloned = (Matrix3x2dStack) super.clone();
|
||||||
|
Matrix3x2d[] clonedMats = new Matrix3x2d[mats.length];
|
||||||
|
for (int i = 0; i < mats.length; i++)
|
||||||
|
clonedMats[i] = (Matrix3x2d) mats[i].clone();
|
||||||
|
cloned.mats = clonedMats;
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1196
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2dc.java
Normal file
1196
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2dc.java
Normal file
File diff suppressed because it is too large
Load diff
2492
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2f.java
Normal file
2492
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2f.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stack of many {@link Matrix3x2f} instances. This resembles the matrix stack known from legacy OpenGL.
|
||||||
|
* <p>
|
||||||
|
* This {@link Matrix3x2fStack} class inherits from {@link Matrix3x2f}, so the current/top matrix is always the
|
||||||
|
* {@link Matrix3x2fStack}/{@link Matrix3x2f} itself. This affects all operations in {@link Matrix3x2f} that take
|
||||||
|
* another {@link Matrix3x2f} as parameter. If a {@link Matrix3x2fStack} is used as argument to those methods, the
|
||||||
|
* effective argument will always be the <i>current</i> matrix of the matrix stack.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Matrix3x2fStack extends Matrix3x2f {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The matrix stack as a non-growable array. The size of the stack must be specified in the {@link #Matrix3x2fStack(int) constructor}.
|
||||||
|
*/
|
||||||
|
private Matrix3x2f[] mats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the "current" matrix within {@link #mats}.
|
||||||
|
*/
|
||||||
|
private int curr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Matrix3x2fStack} of the given size.
|
||||||
|
* <p>
|
||||||
|
* Initially the stack pointer is at zero and the current matrix is set to identity.
|
||||||
|
*
|
||||||
|
* @param stackSize
|
||||||
|
* the size of the stack. This must be at least 1, in which case the {@link Matrix3x2fStack} simply only consists of <code>this</code>
|
||||||
|
* {@link Matrix3x2f}
|
||||||
|
*/
|
||||||
|
public Matrix3x2fStack(int stackSize) {
|
||||||
|
if (stackSize < 1) {
|
||||||
|
throw new IllegalArgumentException("stackSize must be >= 1"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
mats = new Matrix3x2f[stackSize - 1];
|
||||||
|
// Allocate all matrices up front to keep the promise of being "allocation-free"
|
||||||
|
for (int i = 0; i < mats.length; i++) {
|
||||||
|
mats[i] = new Matrix3x2f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not invoke manually! Only meant for serialization.
|
||||||
|
* <p>
|
||||||
|
* Invoking this constructor from client code will result in an inconsistent state of the
|
||||||
|
* created {@link Matrix3x2fStack} instance.
|
||||||
|
*/
|
||||||
|
public Matrix3x2fStack() {
|
||||||
|
/* Empty! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the stack pointer to zero and set the current/bottom matrix to {@link #identity() identity}.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3x2fStack clear() {
|
||||||
|
curr = 0;
|
||||||
|
identity();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the stack pointer by one and set the values of the new current matrix to the one directly below it.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3x2fStack pushMatrix() {
|
||||||
|
if (curr == mats.length) {
|
||||||
|
throw new IllegalStateException("max stack size of " + (curr + 1) + " reached"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
mats[curr++].set(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the stack pointer by one.
|
||||||
|
* <p>
|
||||||
|
* This will effectively dispose of the current matrix.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix3x2fStack popMatrix() {
|
||||||
|
if (curr == 0) {
|
||||||
|
throw new IllegalStateException("already at the bottom of the stack"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
set(mats[--curr]);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + curr;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
result = prime * result + mats[i].hashCode();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contract between Matrix3x2f and Matrix3x2fStack:
|
||||||
|
*
|
||||||
|
* - Matrix3x2f.equals(Matrix3x2fStack) is true iff all the 6 matrix elements are equal
|
||||||
|
* - Matrix3x2fStack.equals(Matrix3x2f) is true iff all the 6 matrix elements are equal
|
||||||
|
* - Matrix3x2fStack.equals(Matrix3x2fStack) is true iff all 6 matrix elements are equal AND the matrix arrays as well as the stack pointer are equal
|
||||||
|
* - everything else is inequal
|
||||||
|
*/
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!super.equals(obj))
|
||||||
|
return false;
|
||||||
|
if (obj instanceof Matrix3x2fStack) {
|
||||||
|
Matrix3x2fStack other = (Matrix3x2fStack) obj;
|
||||||
|
if (curr != other.curr)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
if (!mats[i].equals(other.mats[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
|
super.writeExternal(out);
|
||||||
|
out.writeInt(curr);
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
out.writeObject(mats[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readExternal(ObjectInput in) throws IOException {
|
||||||
|
super.readExternal(in);
|
||||||
|
curr = in.readInt();
|
||||||
|
mats = new Matrix3x2fStack[curr];
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
Matrix3x2f m = new Matrix3x2f();
|
||||||
|
m.readExternal(in);
|
||||||
|
mats[i] = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
Matrix3x2fStack cloned = (Matrix3x2fStack) super.clone();
|
||||||
|
Matrix3x2f[] clonedMats = new Matrix3x2f[mats.length];
|
||||||
|
for (int i = 0; i < mats.length; i++)
|
||||||
|
clonedMats[i] = (Matrix3x2f) mats[i].clone();
|
||||||
|
cloned.mats = clonedMats;
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1180
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2fc.java
Normal file
1180
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2fc.java
Normal file
File diff suppressed because it is too large
Load diff
16604
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4d.java
Normal file
16604
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4d.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,185 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 Kai Burjack
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stack of many {@link Matrix4d} instances. This resembles the matrix stack known from legacy OpenGL.
|
||||||
|
* <p>
|
||||||
|
* This {@link Matrix4dStack} class inherits from {@link Matrix4d}, so the current/top matrix is always the {@link Matrix4dStack}/{@link Matrix4d} itself. This
|
||||||
|
* affects all operations in {@link Matrix4d} that take another {@link Matrix4d} as parameter. If a {@link Matrix4dStack} is used as argument to those methods,
|
||||||
|
* the effective argument will always be the <i>current</i> matrix of the matrix stack.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Matrix4dStack extends Matrix4d {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The matrix stack as a non-growable array. The size of the stack must be specified in the {@link #Matrix4dStack(int) constructor}.
|
||||||
|
*/
|
||||||
|
private Matrix4d[] mats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the "current" matrix within {@link #mats}.
|
||||||
|
*/
|
||||||
|
private int curr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Matrix4dStack} of the given size.
|
||||||
|
* <p>
|
||||||
|
* Initially the stack pointer is at zero and the current matrix is set to identity.
|
||||||
|
*
|
||||||
|
* @param stackSize
|
||||||
|
* the size of the stack. This must be at least 1, in which case the {@link Matrix4dStack} simply only consists of <code>this</code>
|
||||||
|
* {@link Matrix4d}
|
||||||
|
*/
|
||||||
|
public Matrix4dStack(int stackSize) {
|
||||||
|
if (stackSize < 1) {
|
||||||
|
throw new IllegalArgumentException("stackSize must be >= 1"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
mats = new Matrix4d[stackSize - 1];
|
||||||
|
// Allocate all matrices up front to keep the promise of being "allocation-free"
|
||||||
|
for (int i = 0; i < mats.length; i++) {
|
||||||
|
mats[i] = new Matrix4d();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not invoke manually! Only meant for serialization.
|
||||||
|
* <p>
|
||||||
|
* Invoking this constructor from client code will result in an inconsistent state of the
|
||||||
|
* created {@link Matrix4dStack} instance.
|
||||||
|
*/
|
||||||
|
public Matrix4dStack() {
|
||||||
|
/* Empty! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the stack pointer to zero and set the current/bottom matrix to {@link #identity() identity}.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4dStack clear() {
|
||||||
|
curr = 0;
|
||||||
|
identity();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the stack pointer by one and set the values of the new current matrix to the one directly below it.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4dStack pushMatrix() {
|
||||||
|
if (curr == mats.length) {
|
||||||
|
throw new IllegalStateException("max stack size of " + (curr + 1) + " reached"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
mats[curr++].set(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the stack pointer by one.
|
||||||
|
* <p>
|
||||||
|
* This will effectively dispose of the current matrix.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4dStack popMatrix() {
|
||||||
|
if (curr == 0) {
|
||||||
|
throw new IllegalStateException("already at the bottom of the stack"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
set(mats[--curr]);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + curr;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
result = prime * result + mats[i].hashCode();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contract between Matrix4d and Matrix4dStack:
|
||||||
|
*
|
||||||
|
* - Matrix4d.equals(Matrix4dStack) is true iff all the 16 matrix elements are equal
|
||||||
|
* - Matrix4dStack.equals(Matrix4d) is true iff all the 16 matrix elements are equal
|
||||||
|
* - Matrix4dStack.equals(Matrix4dStack) is true iff all 16 matrix elements are equal AND the matrix arrays as well as the stack pointer are equal
|
||||||
|
* - everything else is inequal
|
||||||
|
*/
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!super.equals(obj))
|
||||||
|
return false;
|
||||||
|
if (obj instanceof Matrix4dStack) {
|
||||||
|
Matrix4dStack other = (Matrix4dStack) obj;
|
||||||
|
if (curr != other.curr)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
if (!mats[i].equals(other.mats[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
|
super.writeExternal(out);
|
||||||
|
out.writeInt(curr);
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
out.writeObject(mats[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readExternal(ObjectInput in) throws IOException {
|
||||||
|
super.readExternal(in);
|
||||||
|
curr = in.readInt();
|
||||||
|
mats = new Matrix4dStack[curr];
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
Matrix4d m = new Matrix4d();
|
||||||
|
m.readExternal(in);
|
||||||
|
mats[i] = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
Matrix4dStack cloned = (Matrix4dStack) super.clone();
|
||||||
|
Matrix4d[] clonedMats = new Matrix4d[mats.length];
|
||||||
|
for (int i = 0; i < mats.length; i++)
|
||||||
|
clonedMats[i] = (Matrix4d) mats[i].clone();
|
||||||
|
cloned.mats = clonedMats;
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
6289
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4dc.java
Normal file
6289
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4dc.java
Normal file
File diff suppressed because it is too large
Load diff
15355
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4f.java
Normal file
15355
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4f.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,185 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 Kai Burjack
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stack of many {@link Matrix4f} instances. This resembles the matrix stack known from legacy OpenGL.
|
||||||
|
* <p>
|
||||||
|
* This {@link Matrix4fStack} class inherits from {@link Matrix4f}, so the current/top matrix is always the {@link Matrix4fStack}/{@link Matrix4f} itself. This
|
||||||
|
* affects all operations in {@link Matrix4f} that take another {@link Matrix4f} as parameter. If a {@link Matrix4fStack} is used as argument to those methods,
|
||||||
|
* the effective argument will always be the <i>current</i> matrix of the matrix stack.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Matrix4fStack extends Matrix4f {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The matrix stack as a non-growable array. The size of the stack must be specified in the {@link #Matrix4fStack(int) constructor}.
|
||||||
|
*/
|
||||||
|
private Matrix4f[] mats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the "current" matrix within {@link #mats}.
|
||||||
|
*/
|
||||||
|
private int curr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Matrix4fStack} of the given size.
|
||||||
|
* <p>
|
||||||
|
* Initially the stack pointer is at zero and the current matrix is set to identity.
|
||||||
|
*
|
||||||
|
* @param stackSize
|
||||||
|
* the size of the stack. This must be at least 1, in which case the {@link Matrix4fStack} simply only consists of <code>this</code>
|
||||||
|
* {@link Matrix4f}
|
||||||
|
*/
|
||||||
|
public Matrix4fStack(int stackSize) {
|
||||||
|
if (stackSize < 1) {
|
||||||
|
throw new IllegalArgumentException("stackSize must be >= 1"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
mats = new Matrix4f[stackSize - 1];
|
||||||
|
// Allocate all matrices up front to keep the promise of being "allocation-free"
|
||||||
|
for (int i = 0; i < mats.length; i++) {
|
||||||
|
mats[i] = new Matrix4f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not invoke manually! Only meant for serialization.
|
||||||
|
* <p>
|
||||||
|
* Invoking this constructor from client code will result in an inconsistent state of the
|
||||||
|
* created {@link Matrix4fStack} instance.
|
||||||
|
*/
|
||||||
|
public Matrix4fStack() {
|
||||||
|
/* Empty! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the stack pointer to zero and set the current/bottom matrix to {@link #identity() identity}.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4fStack clear() {
|
||||||
|
curr = 0;
|
||||||
|
identity();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the stack pointer by one and set the values of the new current matrix to the one directly below it.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4fStack pushMatrix() {
|
||||||
|
if (curr == mats.length) {
|
||||||
|
throw new IllegalStateException("max stack size of " + (curr + 1) + " reached"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
mats[curr++].set(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the stack pointer by one.
|
||||||
|
* <p>
|
||||||
|
* This will effectively dispose of the current matrix.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4fStack popMatrix() {
|
||||||
|
if (curr == 0) {
|
||||||
|
throw new IllegalStateException("already at the bottom of the stack"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
set(mats[--curr]);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + curr;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
result = prime * result + mats[i].hashCode();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contract between Matrix4f and Matrix4fStack:
|
||||||
|
*
|
||||||
|
* - Matrix4f.equals(Matrix4fStack) is true iff all the 16 matrix elements are equal
|
||||||
|
* - Matrix4fStack.equals(Matrix4f) is true iff all the 16 matrix elements are equal
|
||||||
|
* - Matrix4fStack.equals(Matrix4fStack) is true iff all 16 matrix elements are equal AND the matrix arrays as well as the stack pointer are equal
|
||||||
|
* - everything else is inequal
|
||||||
|
*/
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!super.equals(obj))
|
||||||
|
return false;
|
||||||
|
if (obj instanceof Matrix4fStack) {
|
||||||
|
Matrix4fStack other = (Matrix4fStack) obj;
|
||||||
|
if (curr != other.curr)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
if (!mats[i].equals(other.mats[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
|
super.writeExternal(out);
|
||||||
|
out.writeInt(curr);
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
out.writeObject(mats[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readExternal(ObjectInput in) throws IOException {
|
||||||
|
super.readExternal(in);
|
||||||
|
curr = in.readInt();
|
||||||
|
mats = new Matrix4fStack[curr];
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
Matrix4f m = new Matrix4f();
|
||||||
|
m.readExternal(in);
|
||||||
|
mats[i] = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
Matrix4fStack cloned = (Matrix4fStack) super.clone();
|
||||||
|
Matrix4f[] clonedMats = new Matrix4f[mats.length];
|
||||||
|
for (int i = 0; i < mats.length; i++)
|
||||||
|
clonedMats[i] = (Matrix4f) mats[i].clone();
|
||||||
|
cloned.mats = clonedMats;
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
6082
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4fc.java
Normal file
6082
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4fc.java
Normal file
File diff suppressed because it is too large
Load diff
10698
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3d.java
Normal file
10698
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3d.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stack of many {@link Matrix4x3d} instances. This resembles the matrix stack known from legacy OpenGL.
|
||||||
|
* <p>
|
||||||
|
* This {@link Matrix4x3dStack} class inherits from {@link Matrix4x3d}, so the current/top matrix is always the
|
||||||
|
* {@link Matrix4x3dStack}/{@link Matrix4x3d} itself. This affects all operations in {@link Matrix4x3d} that take
|
||||||
|
* another {@link Matrix4x3d} as parameter. If a {@link Matrix4x3dStack} is used as argument to those methods, the
|
||||||
|
* effective argument will always be the <i>current</i> matrix of the matrix stack.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Matrix4x3dStack extends Matrix4x3d {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The matrix stack as a non-growable array. The size of the stack must be specified in the {@link #Matrix4x3dStack(int) constructor}.
|
||||||
|
*/
|
||||||
|
private Matrix4x3d[] mats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the "current" matrix within {@link #mats}.
|
||||||
|
*/
|
||||||
|
private int curr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Matrix4x3dStack} of the given size.
|
||||||
|
* <p>
|
||||||
|
* Initially the stack pointer is at zero and the current matrix is set to identity.
|
||||||
|
*
|
||||||
|
* @param stackSize
|
||||||
|
* the size of the stack. This must be at least 1, in which case the {@link Matrix4x3dStack} simply only consists of <code>this</code>
|
||||||
|
* {@link Matrix4x3d}
|
||||||
|
*/
|
||||||
|
public Matrix4x3dStack(int stackSize) {
|
||||||
|
if (stackSize < 1) {
|
||||||
|
throw new IllegalArgumentException("stackSize must be >= 1"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
mats = new Matrix4x3d[stackSize - 1];
|
||||||
|
// Allocate all matrices up front to keep the promise of being "allocation-free"
|
||||||
|
for (int i = 0; i < mats.length; i++) {
|
||||||
|
mats[i] = new Matrix4x3d();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not invoke manually! Only meant for serialization.
|
||||||
|
* <p>
|
||||||
|
* Invoking this constructor from client code will result in an inconsistent state of the
|
||||||
|
* created {@link Matrix4x3dStack} instance.
|
||||||
|
*/
|
||||||
|
public Matrix4x3dStack() {
|
||||||
|
/* Empty! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the stack pointer to zero and set the current/bottom matrix to {@link #identity() identity}.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4x3dStack clear() {
|
||||||
|
curr = 0;
|
||||||
|
identity();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the stack pointer by one and set the values of the new current matrix to the one directly below it.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4x3dStack pushMatrix() {
|
||||||
|
if (curr == mats.length) {
|
||||||
|
throw new IllegalStateException("max stack size of " + (curr + 1) + " reached"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
mats[curr++].set(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the stack pointer by one.
|
||||||
|
* <p>
|
||||||
|
* This will effectively dispose of the current matrix.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4x3dStack popMatrix() {
|
||||||
|
if (curr == 0) {
|
||||||
|
throw new IllegalStateException("already at the bottom of the stack"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
set(mats[--curr]);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + curr;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
result = prime * result + mats[i].hashCode();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contract between Matrix4x3d and Matrix4x3dStack:
|
||||||
|
*
|
||||||
|
* - Matrix4x3d.equals(Matrix4x3dStack) is true iff all the 12 matrix elements are equal
|
||||||
|
* - Matrix4x3dStack.equals(Matrix4x3d) is true iff all the 12 matrix elements are equal
|
||||||
|
* - Matrix4x3dStack.equals(Matrix4x3dStack) is true iff all 12 matrix elements are equal AND the matrix arrays as well as the stack pointer are equal
|
||||||
|
* - everything else is inequal
|
||||||
|
*/
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!super.equals(obj))
|
||||||
|
return false;
|
||||||
|
if (obj instanceof Matrix4x3dStack) {
|
||||||
|
Matrix4x3dStack other = (Matrix4x3dStack) obj;
|
||||||
|
if (curr != other.curr)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
if (!mats[i].equals(other.mats[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
|
super.writeExternal(out);
|
||||||
|
out.writeInt(curr);
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
out.writeObject(mats[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readExternal(ObjectInput in) throws IOException {
|
||||||
|
super.readExternal(in);
|
||||||
|
curr = in.readInt();
|
||||||
|
mats = new Matrix4x3dStack[curr];
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
Matrix4x3d m = new Matrix4x3d();
|
||||||
|
m.readExternal(in);
|
||||||
|
mats[i] = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
Matrix4x3dStack cloned = (Matrix4x3dStack) super.clone();
|
||||||
|
Matrix4x3d[] clonedMats = new Matrix4x3d[mats.length];
|
||||||
|
for (int i = 0; i < mats.length; i++)
|
||||||
|
clonedMats[i] = (Matrix4x3d) mats[i].clone();
|
||||||
|
cloned.mats = clonedMats;
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
3821
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3dc.java
Normal file
3821
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3dc.java
Normal file
File diff suppressed because it is too large
Load diff
9838
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3f.java
Normal file
9838
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3f.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stack of many {@link Matrix4x3f} instances. This resembles the matrix stack known from legacy OpenGL.
|
||||||
|
* <p>
|
||||||
|
* This {@link Matrix4x3fStack} class inherits from {@link Matrix4x3f}, so the current/top matrix is always the
|
||||||
|
* {@link Matrix4x3fStack}/{@link Matrix4x3f} itself. This affects all operations in {@link Matrix4x3f} that take
|
||||||
|
* another {@link Matrix4x3f} as parameter. If a {@link Matrix4x3fStack} is used as argument to those methods, the
|
||||||
|
* effective argument will always be the <i>current</i> matrix of the matrix stack.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Matrix4x3fStack extends Matrix4x3f {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The matrix stack as a non-growable array. The size of the stack must be specified in the {@link #Matrix4x3fStack(int) constructor}.
|
||||||
|
*/
|
||||||
|
private Matrix4x3f[] mats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the "current" matrix within {@link #mats}.
|
||||||
|
*/
|
||||||
|
private int curr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Matrix4x3fStack} of the given size.
|
||||||
|
* <p>
|
||||||
|
* Initially the stack pointer is at zero and the current matrix is set to identity.
|
||||||
|
*
|
||||||
|
* @param stackSize
|
||||||
|
* the size of the stack. This must be at least 1, in which case the {@link Matrix4x3fStack} simply only consists of <code>this</code>
|
||||||
|
* {@link Matrix4x3f}
|
||||||
|
*/
|
||||||
|
public Matrix4x3fStack(int stackSize) {
|
||||||
|
if (stackSize < 1) {
|
||||||
|
throw new IllegalArgumentException("stackSize must be >= 1"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
mats = new Matrix4x3f[stackSize - 1];
|
||||||
|
// Allocate all matrices up front to keep the promise of being "allocation-free"
|
||||||
|
for (int i = 0; i < mats.length; i++) {
|
||||||
|
mats[i] = new Matrix4x3f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not invoke manually! Only meant for serialization.
|
||||||
|
* <p>
|
||||||
|
* Invoking this constructor from client code will result in an inconsistent state of the
|
||||||
|
* created {@link Matrix4x3fStack} instance.
|
||||||
|
*/
|
||||||
|
public Matrix4x3fStack() {
|
||||||
|
/* Empty! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the stack pointer to zero and set the current/bottom matrix to {@link #identity() identity}.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4x3fStack clear() {
|
||||||
|
curr = 0;
|
||||||
|
identity();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the stack pointer by one and set the values of the new current matrix to the one directly below it.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4x3fStack pushMatrix() {
|
||||||
|
if (curr == mats.length) {
|
||||||
|
throw new IllegalStateException("max stack size of " + (curr + 1) + " reached"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
mats[curr++].set(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the stack pointer by one.
|
||||||
|
* <p>
|
||||||
|
* This will effectively dispose of the current matrix.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Matrix4x3fStack popMatrix() {
|
||||||
|
if (curr == 0) {
|
||||||
|
throw new IllegalStateException("already at the bottom of the stack"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
set(mats[--curr]);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + curr;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
result = prime * result + mats[i].hashCode();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contract between Matrix4x3f and Matrix4x3fStack:
|
||||||
|
*
|
||||||
|
* - Matrix4x3f.equals(Matrix4x3fStack) is true iff all the 12 matrix elements are equal
|
||||||
|
* - Matrix4x3fStack.equals(Matrix4x3f) is true iff all the 12 matrix elements are equal
|
||||||
|
* - Matrix4x3fStack.equals(Matrix4x3fStack) is true iff all 12 matrix elements are equal AND the matrix arrays as well as the stack pointer are equal
|
||||||
|
* - everything else is inequal
|
||||||
|
*/
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!super.equals(obj))
|
||||||
|
return false;
|
||||||
|
if (obj instanceof Matrix4x3fStack) {
|
||||||
|
Matrix4x3fStack other = (Matrix4x3fStack) obj;
|
||||||
|
if (curr != other.curr)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
if (!mats[i].equals(other.mats[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
|
super.writeExternal(out);
|
||||||
|
out.writeInt(curr);
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
out.writeObject(mats[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readExternal(ObjectInput in) throws IOException {
|
||||||
|
super.readExternal(in);
|
||||||
|
curr = in.readInt();
|
||||||
|
mats = new Matrix4x3fStack[curr];
|
||||||
|
for (int i = 0; i < curr; i++) {
|
||||||
|
Matrix4x3f m = new Matrix4x3f();
|
||||||
|
m.readExternal(in);
|
||||||
|
mats[i] = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
Matrix4x3fStack cloned = (Matrix4x3fStack) super.clone();
|
||||||
|
Matrix4x3f[] clonedMats = new Matrix4x3f[mats.length];
|
||||||
|
for (int i = 0; i < mats.length; i++)
|
||||||
|
clonedMats[i] = (Matrix4x3f) mats[i].clone();
|
||||||
|
cloned.mats = clonedMats;
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
3544
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3fc.java
Normal file
3544
src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3fc.java
Normal file
File diff suppressed because it is too large
Load diff
5572
src/main/java/com/jozufozu/flywheel/repack/joml/MemUtil.java
Normal file
5572
src/main/java/com/jozufozu/flywheel/repack/joml/MemUtil.java
Normal file
File diff suppressed because it is too large
Load diff
116
src/main/java/com/jozufozu/flywheel/repack/joml/Options.java
Normal file
116
src/main/java/com/jozufozu/flywheel/repack/joml/Options.java
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for reading system properties.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public final class Options {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether certain debugging checks should be made, such as that only direct NIO Buffers are used when Unsafe is active,
|
||||||
|
* and a proxy should be created on calls to readOnlyView().
|
||||||
|
*/
|
||||||
|
public static final boolean DEBUG = hasOption(System.getProperty("joml.debug", "false"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether <i>not</i> to use sun.misc.Unsafe when copying memory with MemUtil.
|
||||||
|
*/
|
||||||
|
public static final boolean NO_UNSAFE = hasOption(System.getProperty("joml.nounsafe", "false"));
|
||||||
|
/**
|
||||||
|
* Whether to <i>force</i> the use of sun.misc.Unsafe when copying memory with MemUtil.
|
||||||
|
*/
|
||||||
|
public static final boolean FORCE_UNSAFE = hasOption(System.getProperty("joml.forceUnsafe", "false"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether fast approximations of some java.lang.Math operations should be used.
|
||||||
|
*/
|
||||||
|
public static final boolean FASTMATH = hasOption(System.getProperty("joml.fastmath", "false"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When {@link #FASTMATH} is <code>true</code>, whether to use a lookup table for sin/cos.
|
||||||
|
*/
|
||||||
|
public static final boolean SIN_LOOKUP = hasOption(System.getProperty("joml.sinLookup", "false"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When {@link #SIN_LOOKUP} is <code>true</code>, this determines the table size.
|
||||||
|
*/
|
||||||
|
public static final int SIN_LOOKUP_BITS = Integer.parseInt(System.getProperty("joml.sinLookup.bits", "14"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to use a {@link NumberFormat} producing scientific notation output when formatting matrix,
|
||||||
|
* vector and quaternion components to strings.
|
||||||
|
*/
|
||||||
|
public static final boolean useNumberFormat = hasOption(System.getProperty("joml.format", "true"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to try using java.lang.Math.fma() in most matrix/vector/quaternion operations if it is available.
|
||||||
|
* If the CPU does <i>not</i> support it, it will be a lot slower than `a*b+c` and potentially generate a lot of memory allocations
|
||||||
|
* for the emulation with `java.util.BigDecimal`, though.
|
||||||
|
*/
|
||||||
|
public static final boolean USE_MATH_FMA = hasOption(System.getProperty("joml.useMathFma", "false"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When {@link #useNumberFormat} is <code>true</code> then this determines the number of decimal digits
|
||||||
|
* produced in the formatted numbers.
|
||||||
|
*/
|
||||||
|
public static final int numberFormatDecimals = Integer.parseInt(System.getProperty("joml.format.decimals", "3"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link NumberFormat} used to format all numbers throughout all JOML classes.
|
||||||
|
*/
|
||||||
|
public static final NumberFormat NUMBER_FORMAT = decimalFormat();
|
||||||
|
|
||||||
|
private Options() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NumberFormat decimalFormat() {
|
||||||
|
NumberFormat df;
|
||||||
|
if (useNumberFormat) {
|
||||||
|
char[] prec = new char[numberFormatDecimals];
|
||||||
|
Arrays.fill(prec, '0');
|
||||||
|
df = new DecimalFormat(" 0." + new String(prec) + "E0;-");
|
||||||
|
} else {
|
||||||
|
df = NumberFormat.getNumberInstance(Locale.ENGLISH);
|
||||||
|
df.setGroupingUsed(false);
|
||||||
|
}
|
||||||
|
return df;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasOption(String v) {
|
||||||
|
if (v == null)
|
||||||
|
return false;
|
||||||
|
if (v.trim().length() == 0)
|
||||||
|
return true;
|
||||||
|
return Boolean.valueOf(v).booleanValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,328 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 Kai Burjack
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.BitSet;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for polygon/point intersection tests when testing many points against one or many static concave or convex, simple polygons.
|
||||||
|
* <p>
|
||||||
|
* This is an implementation of the algorithm described in <a href="http://alienryderflex.com/polygon/">http://alienryderflex.com</a> and augmented with using a
|
||||||
|
* custom interval tree to avoid testing all polygon edges against a point, but only those that intersect the imaginary ray along the same y co-ordinate of the
|
||||||
|
* search point. This algorithm additionally also supports multiple polygons.
|
||||||
|
* <p>
|
||||||
|
* This class is thread-safe and can be used in a multithreaded environment when testing many points against the same polygon concurrently.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://alienryderflex.com/polygon/">http://alienryderflex.com</a>
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class PolygonsIntersection {
|
||||||
|
|
||||||
|
static class ByStartComparator implements Comparator {
|
||||||
|
public int compare(Object o1, Object o2) {
|
||||||
|
Interval i1 = (Interval) o1;
|
||||||
|
Interval i2 = (Interval) o2;
|
||||||
|
return Float.compare(i1.start, i2.start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ByEndComparator implements Comparator {
|
||||||
|
public int compare(Object o1, Object o2) {
|
||||||
|
Interval i1 = (Interval) o1;
|
||||||
|
Interval i2 = (Interval) o2;
|
||||||
|
return Float.compare(i2.end, i1.end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Interval {
|
||||||
|
float start, end;
|
||||||
|
int i, j, polyIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class IntervalTreeNode {
|
||||||
|
float center;
|
||||||
|
float childrenMinMax;
|
||||||
|
IntervalTreeNode left;
|
||||||
|
IntervalTreeNode right;
|
||||||
|
List/* <Interval> */ byBeginning;
|
||||||
|
List/* <Interval> */ byEnding;
|
||||||
|
|
||||||
|
static boolean computeEvenOdd(float[] verticesXY, Interval ival, float x, float y, boolean evenOdd, BitSet inPolys) {
|
||||||
|
boolean newEvenOdd = evenOdd;
|
||||||
|
int i = ival.i;
|
||||||
|
int j = ival.j;
|
||||||
|
float yi = verticesXY[2 * i + 1];
|
||||||
|
float yj = verticesXY[2 * j + 1];
|
||||||
|
float xi = verticesXY[2 * i + 0];
|
||||||
|
float xj = verticesXY[2 * j + 0];
|
||||||
|
if ((yi < y && yj >= y || yj < y && yi >= y) && (xi <= x || xj <= x)) {
|
||||||
|
float xDist = xi + (y - yi) / (yj - yi) * (xj - xi) - x;
|
||||||
|
newEvenOdd ^= xDist < 0.0f;
|
||||||
|
if (newEvenOdd != evenOdd && inPolys != null) {
|
||||||
|
inPolys.flip(ival.polyIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newEvenOdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean traverse(float[] verticesXY, float x, float y, boolean evenOdd, BitSet inPolys) {
|
||||||
|
boolean newEvenOdd = evenOdd;
|
||||||
|
if (y == center && byBeginning != null) {
|
||||||
|
int size = byBeginning.size();
|
||||||
|
for (int b = 0; b < size; b++) {
|
||||||
|
Interval ival = (Interval) byBeginning.get(b);
|
||||||
|
newEvenOdd = computeEvenOdd(verticesXY, ival, x, y, newEvenOdd, inPolys);
|
||||||
|
}
|
||||||
|
} else if (y < center) {
|
||||||
|
if (left != null && left.childrenMinMax >= y)
|
||||||
|
newEvenOdd = left.traverse(verticesXY, x, y, newEvenOdd, inPolys);
|
||||||
|
if (byBeginning != null) {
|
||||||
|
int size = byBeginning.size();
|
||||||
|
for (int b = 0; b < size; b++) {
|
||||||
|
Interval ival = (Interval) byBeginning.get(b);
|
||||||
|
if (ival.start > y)
|
||||||
|
break;
|
||||||
|
newEvenOdd = computeEvenOdd(verticesXY, ival, x, y, newEvenOdd, inPolys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (y > center) {
|
||||||
|
if (right != null && right.childrenMinMax <= y)
|
||||||
|
newEvenOdd = right.traverse(verticesXY, x, y, newEvenOdd, inPolys);
|
||||||
|
if (byEnding != null) {
|
||||||
|
int size = byEnding.size();
|
||||||
|
for (int b = 0; b < size; b++) {
|
||||||
|
Interval ival = (Interval) byEnding.get(b);
|
||||||
|
if (ival.end < y)
|
||||||
|
break;
|
||||||
|
newEvenOdd = computeEvenOdd(verticesXY, ival, x, y, newEvenOdd, inPolys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newEvenOdd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ByStartComparator byStartComparator = new ByStartComparator();
|
||||||
|
private static final ByEndComparator byEndComparator = new ByEndComparator();
|
||||||
|
|
||||||
|
protected final float[] verticesXY;
|
||||||
|
private float minX, minY, maxX, maxY;
|
||||||
|
private float centerX, centerY, radiusSquared;
|
||||||
|
private IntervalTreeNode tree;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link PolygonsIntersection} object with the given polygon vertices.
|
||||||
|
* <p>
|
||||||
|
* The <code>verticesXY</code> array contains the x and y coordinates of all vertices. This array will not be copied so its content must remain constant for
|
||||||
|
* as long as the PolygonPointIntersection is used with it.
|
||||||
|
*
|
||||||
|
* @param verticesXY
|
||||||
|
* contains the x and y coordinates of all vertices
|
||||||
|
* @param polygons
|
||||||
|
* defines the start vertices of a new polygon. The first vertex of the first polygon is always the
|
||||||
|
* vertex with index 0. In order to define a hole simply define a polygon that is completely inside another polygon
|
||||||
|
* @param count
|
||||||
|
* the number of vertices to use from the <code>verticesXY</code> array, staring with index 0
|
||||||
|
*/
|
||||||
|
public PolygonsIntersection(float[] verticesXY, int[] polygons, int count) {
|
||||||
|
this.verticesXY = verticesXY;
|
||||||
|
// Do all the allocations and initializations during this constructor
|
||||||
|
preprocess(count, polygons);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IntervalTreeNode buildNode(List intervals, float center) {
|
||||||
|
List left = null;
|
||||||
|
List right = null;
|
||||||
|
List byStart = null;
|
||||||
|
List byEnd = null;
|
||||||
|
float leftMin = 1E38f, leftMax = -1E38f, rightMin = 1E38f, rightMax = -1E38f;
|
||||||
|
float thisMin = 1E38f, thisMax = -1E38f;
|
||||||
|
for (int i = 0; i < intervals.size(); i++) {
|
||||||
|
Interval ival = (Interval) intervals.get(i);
|
||||||
|
if (ival.start < center && ival.end < center) {
|
||||||
|
if (left == null)
|
||||||
|
left = new ArrayList();
|
||||||
|
left.add(ival);
|
||||||
|
leftMin = leftMin < ival.start ? leftMin : ival.start;
|
||||||
|
leftMax = leftMax > ival.end ? leftMax : ival.end;
|
||||||
|
} else if (ival.start > center && ival.end > center) {
|
||||||
|
if (right == null)
|
||||||
|
right = new ArrayList();
|
||||||
|
right.add(ival);
|
||||||
|
rightMin = rightMin < ival.start ? rightMin : ival.start;
|
||||||
|
rightMax = rightMax > ival.end ? rightMax : ival.end;
|
||||||
|
} else {
|
||||||
|
if (byStart == null || byEnd == null) {
|
||||||
|
byStart = new ArrayList();
|
||||||
|
byEnd = new ArrayList();
|
||||||
|
}
|
||||||
|
thisMin = ival.start < thisMin ? ival.start : thisMin;
|
||||||
|
thisMax = ival.end > thisMax ? ival.end : thisMax;
|
||||||
|
byStart.add(ival);
|
||||||
|
byEnd.add(ival);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (byStart != null) {
|
||||||
|
Collections.sort(byStart, byStartComparator);
|
||||||
|
Collections.sort(byEnd, byEndComparator);
|
||||||
|
}
|
||||||
|
IntervalTreeNode tree = new IntervalTreeNode();
|
||||||
|
tree.byBeginning = byStart;
|
||||||
|
tree.byEnding = byEnd;
|
||||||
|
tree.center = center;
|
||||||
|
if (left != null) {
|
||||||
|
tree.left = buildNode(left, (leftMin + leftMax) / 2.0f);
|
||||||
|
tree.left.childrenMinMax = leftMax;
|
||||||
|
}
|
||||||
|
if (right != null) {
|
||||||
|
tree.right = buildNode(right, (rightMin + rightMax) / 2.0f);
|
||||||
|
tree.right.childrenMinMax = rightMin;
|
||||||
|
}
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void preprocess(int count, int[] polygons) {
|
||||||
|
int i, j = 0;
|
||||||
|
minX = minY = 1E38f;
|
||||||
|
maxX = maxY = -1E38f;
|
||||||
|
List intervals = new ArrayList(count);
|
||||||
|
int first = 0;
|
||||||
|
int currPoly = 0;
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
if (polygons != null && polygons.length > currPoly && polygons[currPoly] == i) {
|
||||||
|
/* New polygon starts. End the current. */
|
||||||
|
float prevy = verticesXY[2 * (i - 1) + 1];
|
||||||
|
float firsty = verticesXY[2 * first + 1];
|
||||||
|
Interval ival = new Interval();
|
||||||
|
ival.start = prevy < firsty ? prevy : firsty;
|
||||||
|
ival.end = firsty > prevy ? firsty : prevy;
|
||||||
|
ival.i = i - 1;
|
||||||
|
ival.j = first;
|
||||||
|
ival.polyIndex = currPoly;
|
||||||
|
intervals.add(ival);
|
||||||
|
first = i;
|
||||||
|
currPoly++;
|
||||||
|
i++;
|
||||||
|
j = i - 1;
|
||||||
|
}
|
||||||
|
float yi = verticesXY[2 * i + 1];
|
||||||
|
float xi = verticesXY[2 * i + 0];
|
||||||
|
float yj = verticesXY[2 * j + 1];
|
||||||
|
minX = xi < minX ? xi : minX;
|
||||||
|
minY = yi < minY ? yi : minY;
|
||||||
|
maxX = xi > maxX ? xi : maxX;
|
||||||
|
maxY = yi > maxY ? yi : maxY;
|
||||||
|
Interval ival = new Interval();
|
||||||
|
ival.start = yi < yj ? yi : yj;
|
||||||
|
ival.end = yj > yi ? yj : yi;
|
||||||
|
ival.i = i;
|
||||||
|
ival.j = j;
|
||||||
|
ival.polyIndex = currPoly;
|
||||||
|
intervals.add(ival);
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
// Close current polygon
|
||||||
|
float yi = verticesXY[2 * (i - 1) + 1];
|
||||||
|
float xi = verticesXY[2 * (i - 1) + 0];
|
||||||
|
float yj = verticesXY[2 * first + 1];
|
||||||
|
minX = xi < minX ? xi : minX;
|
||||||
|
minY = yi < minY ? yi : minY;
|
||||||
|
maxX = xi > maxX ? xi : maxX;
|
||||||
|
maxY = yi > maxY ? yi : maxY;
|
||||||
|
Interval ival = new Interval();
|
||||||
|
ival.start = yi < yj ? yi : yj;
|
||||||
|
ival.end = yj > yi ? yj : yi;
|
||||||
|
ival.i = i - 1;
|
||||||
|
ival.j = first;
|
||||||
|
ival.polyIndex = currPoly;
|
||||||
|
intervals.add(ival);
|
||||||
|
// compute bounding sphere and rectangle
|
||||||
|
centerX = (maxX + minX) * 0.5f;
|
||||||
|
centerY = (maxY + minY) * 0.5f;
|
||||||
|
float dx = maxX - centerX;
|
||||||
|
float dy = maxY - centerY;
|
||||||
|
radiusSquared = dx * dx + dy * dy;
|
||||||
|
// build interval tree
|
||||||
|
tree = buildNode(intervals, centerY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given point <code>(x, y)</code> lies inside any polygon stored in this {@link PolygonsIntersection} object.
|
||||||
|
* <p>
|
||||||
|
* This method is thread-safe and can be used to test many points concurrently.
|
||||||
|
* <p>
|
||||||
|
* In order to obtain the index of the polygon the point is inside of, use {@link #testPoint(float, float, BitSet)}
|
||||||
|
*
|
||||||
|
* @see #testPoint(float, float, BitSet)
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the point to test
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the point to test
|
||||||
|
* @return <code>true</code> iff the point lies inside any polygon; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testPoint(float x, float y) {
|
||||||
|
return testPoint(x, y, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given point <code>(x, y)</code> lies inside any polygon stored in this {@link PolygonsIntersection} object.
|
||||||
|
* <p>
|
||||||
|
* This method is thread-safe and can be used to test many points concurrently.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the point to test
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the point to test
|
||||||
|
* @param inPolys
|
||||||
|
* if not <code>null</code> then the <i>i</i>-th bit is set if the given point is inside the <i>i</i>-th polygon
|
||||||
|
* @return <code>true</code> iff the point lies inside the polygon and not inside a hole; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean testPoint(float x, float y, BitSet inPolys) {
|
||||||
|
// check bounding sphere first
|
||||||
|
float dx = (x - centerX);
|
||||||
|
float dy = (y - centerY);
|
||||||
|
if (inPolys != null)
|
||||||
|
inPolys.clear();
|
||||||
|
if (dx * dx + dy * dy > radiusSquared)
|
||||||
|
return false;
|
||||||
|
// check bounding box next
|
||||||
|
if (maxX < x || maxY < y || minX > x || minY > y)
|
||||||
|
return false;
|
||||||
|
// ask interval tree for all polygon edges intersecting 'y' and perform
|
||||||
|
// the even/odd/crosscutting/raycast algorithm on them and also return
|
||||||
|
// the polygon index of the polygon the point is in by setting the appropriate
|
||||||
|
// bit in the given BitSet.
|
||||||
|
boolean res = tree.traverse(verticesXY, x, y, false, inPolys);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
2985
src/main/java/com/jozufozu/flywheel/repack/joml/Quaterniond.java
Normal file
2985
src/main/java/com/jozufozu/flywheel/repack/joml/Quaterniond.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,354 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the weighted average of multiple rotations represented as {@link Quaterniond} instances.
|
||||||
|
* <p>
|
||||||
|
* Instances of this class are <i>not</i> thread-safe.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class QuaterniondInterpolator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs singular value decomposition on {@link Matrix3d}.
|
||||||
|
* <p>
|
||||||
|
* This code was adapted from <a href="http://www.public.iastate.edu/~dicook/JSS/paper/code/svd.c">http://www.public.iastate.edu/</a>.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
private static class SvdDecomposition3d {
|
||||||
|
private final double rv1[];
|
||||||
|
private final double w[];
|
||||||
|
private final double v[];
|
||||||
|
|
||||||
|
SvdDecomposition3d() {
|
||||||
|
this.rv1 = new double[3];
|
||||||
|
this.w = new double[3];
|
||||||
|
this.v = new double[9];
|
||||||
|
}
|
||||||
|
|
||||||
|
private double SIGN(double a, double b) {
|
||||||
|
return (b) >= 0.0 ? Math.abs(a) : -Math.abs(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void svd(double[] a, int maxIterations, Matrix3d destU, Matrix3d destV) {
|
||||||
|
int flag, i, its, j, jj, k, l = 0, nm = 0;
|
||||||
|
double c, f, h, s, x, y, z;
|
||||||
|
double anorm = 0.0, g = 0.0, scale = 0.0;
|
||||||
|
/* Householder reduction to bidiagonal form */
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
/* left-hand reduction */
|
||||||
|
l = i + 1;
|
||||||
|
rv1[i] = scale * g;
|
||||||
|
g = s = scale = 0.0;
|
||||||
|
for (k = i; k < 3; k++)
|
||||||
|
scale += Math.abs(a[k + 3 * i]);
|
||||||
|
if (scale != 0.0) {
|
||||||
|
for (k = i; k < 3; k++) {
|
||||||
|
a[k + 3 * i] = (a[k + 3 * i] / scale);
|
||||||
|
s += (a[k + 3 * i] * a[k + 3 * i]);
|
||||||
|
}
|
||||||
|
f = a[i + 3 * i];
|
||||||
|
g = -SIGN(Math.sqrt(s), f);
|
||||||
|
h = f * g - s;
|
||||||
|
a[i + 3 * i] = f - g;
|
||||||
|
if (i != 3 - 1) {
|
||||||
|
for (j = l; j < 3; j++) {
|
||||||
|
for (s = 0.0, k = i; k < 3; k++)
|
||||||
|
s += a[k + 3 * i] * a[k + 3 * j];
|
||||||
|
f = s / h;
|
||||||
|
for (k = i; k < 3; k++)
|
||||||
|
a[k + 3 * j] += f * a[k + 3 * i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (k = i; k < 3; k++)
|
||||||
|
a[k + 3 * i] = a[k + 3 * i] * scale;
|
||||||
|
}
|
||||||
|
w[i] = (scale * g);
|
||||||
|
|
||||||
|
/* right-hand reduction */
|
||||||
|
g = s = scale = 0.0;
|
||||||
|
if (i < 3 && i != 3 - 1) {
|
||||||
|
for (k = l; k < 3; k++)
|
||||||
|
scale += Math.abs(a[i + 3 * k]);
|
||||||
|
if (scale != 0.0) {
|
||||||
|
for (k = l; k < 3; k++) {
|
||||||
|
a[i + 3 * k] = a[i + 3 * k] / scale;
|
||||||
|
s += a[i + 3 * k] * a[i + 3 * k];
|
||||||
|
}
|
||||||
|
f = a[i + 3 * l];
|
||||||
|
g = -SIGN(Math.sqrt(s), f);
|
||||||
|
h = f * g - s;
|
||||||
|
a[i + 3 * l] = f - g;
|
||||||
|
for (k = l; k < 3; k++)
|
||||||
|
rv1[k] = a[i + 3 * k] / h;
|
||||||
|
if (i != 3 - 1) {
|
||||||
|
for (j = l; j < 3; j++) {
|
||||||
|
for (s = 0.0, k = l; k < 3; k++)
|
||||||
|
s += a[j + 3 * k] * a[i + 3 * k];
|
||||||
|
for (k = l; k < 3; k++)
|
||||||
|
a[j + 3 * k] += s * rv1[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (k = l; k < 3; k++)
|
||||||
|
a[i + 3 * k] = a[i + 3 * k] * scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
anorm = Math.max(anorm, (Math.abs(w[i]) + Math.abs(rv1[i])));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* accumulate the right-hand transformation */
|
||||||
|
for (i = 3 - 1; i >= 0; i--) {
|
||||||
|
if (i < 3 - 1) {
|
||||||
|
if (g != 0.0) {
|
||||||
|
for (j = l; j < 3; j++)
|
||||||
|
v[j + 3 * i] = (a[i + 3 * j] / a[i + 3 * l]) / g;
|
||||||
|
/* double division to avoid underflow */
|
||||||
|
for (j = l; j < 3; j++) {
|
||||||
|
for (s = 0.0, k = l; k < 3; k++)
|
||||||
|
s += a[i + 3 * k] * v[k + 3 * j];
|
||||||
|
for (k = l; k < 3; k++)
|
||||||
|
v[k + 3 * j] += s * v[k + 3 * i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (j = l; j < 3; j++)
|
||||||
|
v[i + 3 * j] = v[j + 3 * i] = 0.0;
|
||||||
|
}
|
||||||
|
v[i + 3 * i] = 1.0;
|
||||||
|
g = rv1[i];
|
||||||
|
l = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* accumulate the left-hand transformation */
|
||||||
|
for (i = 3 - 1; i >= 0; i--) {
|
||||||
|
l = i + 1;
|
||||||
|
g = w[i];
|
||||||
|
if (i < 3 - 1)
|
||||||
|
for (j = l; j < 3; j++)
|
||||||
|
a[i + 3 * j] = 0.0;
|
||||||
|
if (g != 0.0) {
|
||||||
|
g = 1.0 / g;
|
||||||
|
if (i != 3 - 1) {
|
||||||
|
for (j = l; j < 3; j++) {
|
||||||
|
for (s = 0.0, k = l; k < 3; k++)
|
||||||
|
s += a[k + 3 * i] * a[k + 3 * j];
|
||||||
|
f = s / a[i + 3 * i] * g;
|
||||||
|
for (k = i; k < 3; k++)
|
||||||
|
a[k + 3 * j] += f * a[k + 3 * i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (j = i; j < 3; j++)
|
||||||
|
a[j + 3 * i] = a[j + 3 * i] * g;
|
||||||
|
} else {
|
||||||
|
for (j = i; j < 3; j++)
|
||||||
|
a[j + 3 * i] = 0.0;
|
||||||
|
}
|
||||||
|
++a[i + 3 * i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* diagonalize the bidiagonal form */
|
||||||
|
for (k = 3 - 1; k >= 0; k--) { /* loop over singular values */
|
||||||
|
for (its = 0; its < maxIterations; its++) { /* loop over allowed iterations */
|
||||||
|
flag = 1;
|
||||||
|
for (l = k; l >= 0; l--) { /* test for splitting */
|
||||||
|
nm = l - 1;
|
||||||
|
if (Math.abs(rv1[l]) + anorm == anorm) {
|
||||||
|
flag = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (Math.abs(w[nm]) + anorm == anorm)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (flag != 0) {
|
||||||
|
c = 0.0;
|
||||||
|
s = 1.0;
|
||||||
|
for (i = l; i <= k; i++) {
|
||||||
|
f = s * rv1[i];
|
||||||
|
if (Math.abs(f) + anorm != anorm) {
|
||||||
|
g = w[i];
|
||||||
|
h = PYTHAG(f, g);
|
||||||
|
w[i] = h;
|
||||||
|
h = 1.0 / h;
|
||||||
|
c = g * h;
|
||||||
|
s = (-f * h);
|
||||||
|
for (j = 0; j < 3; j++) {
|
||||||
|
y = a[j + 3 * nm];
|
||||||
|
z = a[j + 3 * i];
|
||||||
|
a[j + 3 * nm] = y * c + z * s;
|
||||||
|
a[j + 3 * i] = z * c - y * s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
z = w[k];
|
||||||
|
if (l == k) { /* convergence */
|
||||||
|
if (z < 0.0) { /* make singular value nonnegative */
|
||||||
|
w[k] = -z;
|
||||||
|
for (j = 0; j < 3; j++)
|
||||||
|
v[j + 3 * k] = (-v[j + 3 * k]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (its == maxIterations - 1) {
|
||||||
|
throw new RuntimeException("No convergence after " + maxIterations + " iterations");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* shift from bottom 2 x 2 minor */
|
||||||
|
x = w[l];
|
||||||
|
nm = k - 1;
|
||||||
|
y = w[nm];
|
||||||
|
g = rv1[nm];
|
||||||
|
h = rv1[k];
|
||||||
|
f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
|
||||||
|
g = PYTHAG(f, 1.0);
|
||||||
|
f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
|
||||||
|
|
||||||
|
/* next QR transformation */
|
||||||
|
c = s = 1.0;
|
||||||
|
for (j = l; j <= nm; j++) {
|
||||||
|
i = j + 1;
|
||||||
|
g = rv1[i];
|
||||||
|
y = w[i];
|
||||||
|
h = s * g;
|
||||||
|
g = c * g;
|
||||||
|
z = PYTHAG(f, h);
|
||||||
|
rv1[j] = z;
|
||||||
|
c = f / z;
|
||||||
|
s = h / z;
|
||||||
|
f = x * c + g * s;
|
||||||
|
g = g * c - x * s;
|
||||||
|
h = y * s;
|
||||||
|
y = y * c;
|
||||||
|
for (jj = 0; jj < 3; jj++) {
|
||||||
|
x = v[jj + 3 * j];
|
||||||
|
z = v[jj + 3 * i];
|
||||||
|
v[jj + 3 * j] = x * c + z * s;
|
||||||
|
v[jj + 3 * i] = z * c - x * s;
|
||||||
|
}
|
||||||
|
z = PYTHAG(f, h);
|
||||||
|
w[j] = z;
|
||||||
|
if (z != 0.0) {
|
||||||
|
z = 1.0 / z;
|
||||||
|
c = f * z;
|
||||||
|
s = h * z;
|
||||||
|
}
|
||||||
|
f = (c * g) + (s * y);
|
||||||
|
x = (c * y) - (s * g);
|
||||||
|
for (jj = 0; jj < 3; jj++) {
|
||||||
|
y = a[jj + 3 * j];
|
||||||
|
z = a[jj + 3 * i];
|
||||||
|
a[jj + 3 * j] = y * c + z * s;
|
||||||
|
a[jj + 3 * i] = z * c - y * s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rv1[l] = 0.0;
|
||||||
|
rv1[k] = f;
|
||||||
|
w[k] = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
destU.set(a);
|
||||||
|
destV.set(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double PYTHAG(double a, double b) {
|
||||||
|
double at = Math.abs(a), bt = Math.abs(b), ct, result;
|
||||||
|
if (at > bt) {
|
||||||
|
ct = bt / at;
|
||||||
|
result = at * Math.sqrt(1.0 + ct * ct);
|
||||||
|
} else if (bt > 0.0) {
|
||||||
|
ct = at / bt;
|
||||||
|
result = bt * Math.sqrt(1.0 + ct * ct);
|
||||||
|
} else
|
||||||
|
result = 0.0;
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final SvdDecomposition3d svdDecomposition3d = new SvdDecomposition3d();
|
||||||
|
private final double[] m = new double[9];
|
||||||
|
private final Matrix3d u = new Matrix3d();
|
||||||
|
private final Matrix3d v = new Matrix3d();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the weighted average of all of the quaternions given in <code>qs</code> using the specified interpolation factors <code>weights</code>, and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param qs
|
||||||
|
* the quaternions to interpolate over
|
||||||
|
* @param weights
|
||||||
|
* the weights of each individual quaternion in <code>qs</code>
|
||||||
|
* @param maxSvdIterations
|
||||||
|
* the maximum number of iterations in the Singular Value Decomposition step used by this method
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public Quaterniond computeWeightedAverage(Quaterniond[] qs, double[] weights, int maxSvdIterations, Quaterniond dest) {
|
||||||
|
double m00 = 0.0, m01 = 0.0, m02 = 0.0;
|
||||||
|
double m10 = 0.0, m11 = 0.0, m12 = 0.0;
|
||||||
|
double m20 = 0.0, m21 = 0.0, m22 = 0.0;
|
||||||
|
// Sum the rotation matrices of qs
|
||||||
|
for (int i = 0; i < qs.length; i++) {
|
||||||
|
Quaterniond q = qs[i];
|
||||||
|
double dx = q.x + q.x;
|
||||||
|
double dy = q.y + q.y;
|
||||||
|
double dz = q.z + q.z;
|
||||||
|
double q00 = dx * q.x;
|
||||||
|
double q11 = dy * q.y;
|
||||||
|
double q22 = dz * q.z;
|
||||||
|
double q01 = dx * q.y;
|
||||||
|
double q02 = dx * q.z;
|
||||||
|
double q03 = dx * q.w;
|
||||||
|
double q12 = dy * q.z;
|
||||||
|
double q13 = dy * q.w;
|
||||||
|
double q23 = dz * q.w;
|
||||||
|
m00 += weights[i] * (1.0 - q11 - q22);
|
||||||
|
m01 += weights[i] * (q01 + q23);
|
||||||
|
m02 += weights[i] * (q02 - q13);
|
||||||
|
m10 += weights[i] * (q01 - q23);
|
||||||
|
m11 += weights[i] * (1.0 - q22 - q00);
|
||||||
|
m12 += weights[i] * (q12 + q03);
|
||||||
|
m20 += weights[i] * (q02 + q13);
|
||||||
|
m21 += weights[i] * (q12 - q03);
|
||||||
|
m22 += weights[i] * (1.0 - q11 - q00);
|
||||||
|
}
|
||||||
|
m[0] = m00;
|
||||||
|
m[1] = m01;
|
||||||
|
m[2] = m02;
|
||||||
|
m[3] = m10;
|
||||||
|
m[4] = m11;
|
||||||
|
m[5] = m12;
|
||||||
|
m[6] = m20;
|
||||||
|
m[7] = m21;
|
||||||
|
m[8] = m22;
|
||||||
|
// Compute the Singular Value Decomposition of 'm'
|
||||||
|
svdDecomposition3d.svd(m, maxSvdIterations, u, v);
|
||||||
|
// Compute rotation matrix
|
||||||
|
u.mul(v.transpose());
|
||||||
|
// Build quaternion from it
|
||||||
|
return dest.setFromNormalized(u).normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1966
src/main/java/com/jozufozu/flywheel/repack/joml/Quaterniondc.java
Normal file
1966
src/main/java/com/jozufozu/flywheel/repack/joml/Quaterniondc.java
Normal file
File diff suppressed because it is too large
Load diff
3066
src/main/java/com/jozufozu/flywheel/repack/joml/Quaternionf.java
Normal file
3066
src/main/java/com/jozufozu/flywheel/repack/joml/Quaternionf.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,354 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the weighted average of multiple rotations represented as {@link Quaternionf} instances.
|
||||||
|
* <p>
|
||||||
|
* Instances of this class are <i>not</i> thread-safe.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class QuaternionfInterpolator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs singular value decomposition on {@link Matrix3f}.
|
||||||
|
* <p>
|
||||||
|
* This code was adapted from <a href="http://www.public.iastate.edu/~dicook/JSS/paper/code/svd.c">http://www.public.iastate.edu/</a>.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
private static class SvdDecomposition3f {
|
||||||
|
private final float rv1[];
|
||||||
|
private final float w[];
|
||||||
|
private final float v[];
|
||||||
|
|
||||||
|
SvdDecomposition3f() {
|
||||||
|
this.rv1 = new float[3];
|
||||||
|
this.w = new float[3];
|
||||||
|
this.v = new float[9];
|
||||||
|
}
|
||||||
|
|
||||||
|
private float SIGN(float a, float b) {
|
||||||
|
return ((b) >= 0.0 ? Math.abs(a) : -Math.abs(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
void svd(float[] a, int maxIterations, Matrix3f destU, Matrix3f destV) {
|
||||||
|
int flag, i, its, j, jj, k, l = 0, nm = 0;
|
||||||
|
float c, f, h, s, x, y, z;
|
||||||
|
float anorm = 0.0f, g = 0.0f, scale = 0.0f;
|
||||||
|
/* Householder reduction to bidiagonal form */
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
/* left-hand reduction */
|
||||||
|
l = i + 1;
|
||||||
|
rv1[i] = scale * g;
|
||||||
|
g = s = scale = 0.0f;
|
||||||
|
for (k = i; k < 3; k++)
|
||||||
|
scale += Math.abs(a[k + 3 * i]);
|
||||||
|
if (scale != 0.0f) {
|
||||||
|
for (k = i; k < 3; k++) {
|
||||||
|
a[k + 3 * i] = (a[k + 3 * i] / scale);
|
||||||
|
s += (a[k + 3 * i] * a[k + 3 * i]);
|
||||||
|
}
|
||||||
|
f = a[i + 3 * i];
|
||||||
|
g = -SIGN((float) Math.sqrt(s), f);
|
||||||
|
h = f * g - s;
|
||||||
|
a[i + 3 * i] = f - g;
|
||||||
|
if (i != 3 - 1) {
|
||||||
|
for (j = l; j < 3; j++) {
|
||||||
|
for (s = 0.0f, k = i; k < 3; k++)
|
||||||
|
s += a[k + 3 * i] * a[k + 3 * j];
|
||||||
|
f = s / h;
|
||||||
|
for (k = i; k < 3; k++)
|
||||||
|
a[k + 3 * j] += f * a[k + 3 * i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (k = i; k < 3; k++)
|
||||||
|
a[k + 3 * i] = a[k + 3 * i] * scale;
|
||||||
|
}
|
||||||
|
w[i] = scale * g;
|
||||||
|
|
||||||
|
/* right-hand reduction */
|
||||||
|
g = s = scale = 0.0f;
|
||||||
|
if (i < 3 && i != 3 - 1) {
|
||||||
|
for (k = l; k < 3; k++)
|
||||||
|
scale += Math.abs(a[i + 3 * k]);
|
||||||
|
if (scale != 0.0f) {
|
||||||
|
for (k = l; k < 3; k++) {
|
||||||
|
a[i + 3 * k] = a[i + 3 * k] / scale;
|
||||||
|
s += a[i + 3 * k] * a[i + 3 * k];
|
||||||
|
}
|
||||||
|
f = a[i + 3 * l];
|
||||||
|
g = -SIGN((float) Math.sqrt(s), f);
|
||||||
|
h = f * g - s;
|
||||||
|
a[i + 3 * l] = f - g;
|
||||||
|
for (k = l; k < 3; k++)
|
||||||
|
rv1[k] = a[i + 3 * k] / h;
|
||||||
|
if (i != 3 - 1) {
|
||||||
|
for (j = l; j < 3; j++) {
|
||||||
|
for (s = 0.0f, k = l; k < 3; k++)
|
||||||
|
s += a[j + 3 * k] * a[i + 3 * k];
|
||||||
|
for (k = l; k < 3; k++)
|
||||||
|
a[j + 3 * k] += s * rv1[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (k = l; k < 3; k++)
|
||||||
|
a[i + 3 * k] = a[i + 3 * k] * scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
anorm = Math.max(anorm, (Math.abs(w[i]) + Math.abs(rv1[i])));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* accumulate the right-hand transformation */
|
||||||
|
for (i = 3 - 1; i >= 0; i--) {
|
||||||
|
if (i < 3 - 1) {
|
||||||
|
if (g != 0.0f) {
|
||||||
|
for (j = l; j < 3; j++)
|
||||||
|
v[j + 3 * i] = (a[i + 3 * j] / a[i + 3 * l]) / g;
|
||||||
|
/* double division to avoid underflow */
|
||||||
|
for (j = l; j < 3; j++) {
|
||||||
|
for (s = 0.0f, k = l; k < 3; k++)
|
||||||
|
s += a[i + 3 * k] * v[k + 3 * j];
|
||||||
|
for (k = l; k < 3; k++)
|
||||||
|
v[k + 3 * j] += s * v[k + 3 * i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (j = l; j < 3; j++)
|
||||||
|
v[i + 3 * j] = v[j + 3 * i] = 0.0f;
|
||||||
|
}
|
||||||
|
v[i + 3 * i] = 1.0f;
|
||||||
|
g = rv1[i];
|
||||||
|
l = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* accumulate the left-hand transformation */
|
||||||
|
for (i = 3 - 1; i >= 0; i--) {
|
||||||
|
l = i + 1;
|
||||||
|
g = w[i];
|
||||||
|
if (i < 3 - 1)
|
||||||
|
for (j = l; j < 3; j++)
|
||||||
|
a[i + 3 * j] = 0.0f;
|
||||||
|
if (g != 0.0f) {
|
||||||
|
g = 1.0f / g;
|
||||||
|
if (i != 3 - 1) {
|
||||||
|
for (j = l; j < 3; j++) {
|
||||||
|
for (s = 0.0f, k = l; k < 3; k++)
|
||||||
|
s += a[k + 3 * i] * a[k + 3 * j];
|
||||||
|
f = s / a[i + 3 * i] * g;
|
||||||
|
for (k = i; k < 3; k++)
|
||||||
|
a[k + 3 * j] += f * a[k + 3 * i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (j = i; j < 3; j++)
|
||||||
|
a[j + 3 * i] = a[j + 3 * i] * g;
|
||||||
|
} else {
|
||||||
|
for (j = i; j < 3; j++)
|
||||||
|
a[j + 3 * i] = 0.0f;
|
||||||
|
}
|
||||||
|
++a[i + 3 * i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* diagonalize the bidiagonal form */
|
||||||
|
for (k = 3 - 1; k >= 0; k--) { /* loop over singular values */
|
||||||
|
for (its = 0; its < maxIterations; its++) { /* loop over allowed iterations */
|
||||||
|
flag = 1;
|
||||||
|
for (l = k; l >= 0; l--) { /* test for splitting */
|
||||||
|
nm = l - 1;
|
||||||
|
if (Math.abs(rv1[l]) + anorm == anorm) {
|
||||||
|
flag = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (Math.abs(w[nm]) + anorm == anorm)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (flag != 0) {
|
||||||
|
c = 0.0f;
|
||||||
|
s = 1.0f;
|
||||||
|
for (i = l; i <= k; i++) {
|
||||||
|
f = s * rv1[i];
|
||||||
|
if (Math.abs(f) + anorm != anorm) {
|
||||||
|
g = w[i];
|
||||||
|
h = PYTHAG(f, g);
|
||||||
|
w[i] = h;
|
||||||
|
h = 1.0f / h;
|
||||||
|
c = g * h;
|
||||||
|
s = (-f * h);
|
||||||
|
for (j = 0; j < 3; j++) {
|
||||||
|
y = a[j + 3 * nm];
|
||||||
|
z = a[j + 3 * i];
|
||||||
|
a[j + 3 * nm] = y * c + z * s;
|
||||||
|
a[j + 3 * i] = z * c - y * s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
z = w[k];
|
||||||
|
if (l == k) { /* convergence */
|
||||||
|
if (z < 0.0f) { /* make singular value nonnegative */
|
||||||
|
w[k] = -z;
|
||||||
|
for (j = 0; j < 3; j++)
|
||||||
|
v[j + 3 * k] = (-v[j + 3 * k]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (its == maxIterations - 1) {
|
||||||
|
throw new RuntimeException("No convergence after " + maxIterations + " iterations");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* shift from bottom 2 x 2 minor */
|
||||||
|
x = w[l];
|
||||||
|
nm = k - 1;
|
||||||
|
y = w[nm];
|
||||||
|
g = rv1[nm];
|
||||||
|
h = rv1[k];
|
||||||
|
f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0f * h * y);
|
||||||
|
g = PYTHAG(f, 1.0f);
|
||||||
|
f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
|
||||||
|
|
||||||
|
/* next QR transformation */
|
||||||
|
c = s = 1.0f;
|
||||||
|
for (j = l; j <= nm; j++) {
|
||||||
|
i = j + 1;
|
||||||
|
g = rv1[i];
|
||||||
|
y = w[i];
|
||||||
|
h = s * g;
|
||||||
|
g = c * g;
|
||||||
|
z = PYTHAG(f, h);
|
||||||
|
rv1[j] = z;
|
||||||
|
c = f / z;
|
||||||
|
s = h / z;
|
||||||
|
f = x * c + g * s;
|
||||||
|
g = g * c - x * s;
|
||||||
|
h = y * s;
|
||||||
|
y = y * c;
|
||||||
|
for (jj = 0; jj < 3; jj++) {
|
||||||
|
x = v[jj + 3 * j];
|
||||||
|
z = v[jj + 3 * i];
|
||||||
|
v[jj + 3 * j] = x * c + z * s;
|
||||||
|
v[jj + 3 * i] = z * c - x * s;
|
||||||
|
}
|
||||||
|
z = PYTHAG(f, h);
|
||||||
|
w[j] = z;
|
||||||
|
if (z != 0.0f) {
|
||||||
|
z = 1.0f / z;
|
||||||
|
c = f * z;
|
||||||
|
s = h * z;
|
||||||
|
}
|
||||||
|
f = (c * g) + (s * y);
|
||||||
|
x = (c * y) - (s * g);
|
||||||
|
for (jj = 0; jj < 3; jj++) {
|
||||||
|
y = a[jj + 3 * j];
|
||||||
|
z = a[jj + 3 * i];
|
||||||
|
a[jj + 3 * j] = y * c + z * s;
|
||||||
|
a[jj + 3 * i] = z * c - y * s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rv1[l] = 0.0f;
|
||||||
|
rv1[k] = f;
|
||||||
|
w[k] = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
destU.set(a);
|
||||||
|
destV.set(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float PYTHAG(float a, float b) {
|
||||||
|
float at = Math.abs(a), bt = Math.abs(b), ct, result;
|
||||||
|
if (at > bt) {
|
||||||
|
ct = bt / at;
|
||||||
|
result = at * (float) Math.sqrt(1.0 + ct * ct);
|
||||||
|
} else if (bt > 0.0f) {
|
||||||
|
ct = at / bt;
|
||||||
|
result = bt * (float) Math.sqrt(1.0 + ct * ct);
|
||||||
|
} else
|
||||||
|
result = 0.0f;
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final SvdDecomposition3f svdDecomposition3f = new SvdDecomposition3f();
|
||||||
|
private final float[] m = new float[9];
|
||||||
|
private final Matrix3f u = new Matrix3f();
|
||||||
|
private final Matrix3f v = new Matrix3f();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the weighted average of all of the quaternions given in <code>qs</code> using the specified interpolation factors <code>weights</code>, and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param qs
|
||||||
|
* the quaternions to interpolate over
|
||||||
|
* @param weights
|
||||||
|
* the weights of each individual quaternion in <code>qs</code>
|
||||||
|
* @param maxSvdIterations
|
||||||
|
* the maximum number of iterations in the Singular Value Decomposition step used by this method
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
public Quaternionf computeWeightedAverage(Quaternionfc[] qs, float[] weights, int maxSvdIterations, Quaternionf dest) {
|
||||||
|
float m00 = 0.0f, m01 = 0.0f, m02 = 0.0f;
|
||||||
|
float m10 = 0.0f, m11 = 0.0f, m12 = 0.0f;
|
||||||
|
float m20 = 0.0f, m21 = 0.0f, m22 = 0.0f;
|
||||||
|
// Sum the rotation matrices of qs
|
||||||
|
for (int i = 0; i < qs.length; i++) {
|
||||||
|
Quaternionfc q = qs[i];
|
||||||
|
float dx = q.x() + q.x();
|
||||||
|
float dy = q.y() + q.y();
|
||||||
|
float dz = q.z() + q.z();
|
||||||
|
float q00 = dx * q.x();
|
||||||
|
float q11 = dy * q.y();
|
||||||
|
float q22 = dz * q.z();
|
||||||
|
float q01 = dx * q.y();
|
||||||
|
float q02 = dx * q.z();
|
||||||
|
float q03 = dx * q.w();
|
||||||
|
float q12 = dy * q.z();
|
||||||
|
float q13 = dy * q.w();
|
||||||
|
float q23 = dz * q.w();
|
||||||
|
m00 += weights[i] * (1.0f - q11 - q22);
|
||||||
|
m01 += weights[i] * (q01 + q23);
|
||||||
|
m02 += weights[i] * (q02 - q13);
|
||||||
|
m10 += weights[i] * (q01 - q23);
|
||||||
|
m11 += weights[i] * (1.0f - q22 - q00);
|
||||||
|
m12 += weights[i] * (q12 + q03);
|
||||||
|
m20 += weights[i] * (q02 + q13);
|
||||||
|
m21 += weights[i] * (q12 - q03);
|
||||||
|
m22 += weights[i] * (1.0f - q11 - q00);
|
||||||
|
}
|
||||||
|
m[0] = m00;
|
||||||
|
m[1] = m01;
|
||||||
|
m[2] = m02;
|
||||||
|
m[3] = m10;
|
||||||
|
m[4] = m11;
|
||||||
|
m[5] = m12;
|
||||||
|
m[6] = m20;
|
||||||
|
m[7] = m21;
|
||||||
|
m[8] = m22;
|
||||||
|
// Compute the Singular Value Decomposition of 'm'
|
||||||
|
svdDecomposition3f.svd(m, maxSvdIterations, u, v);
|
||||||
|
// Compute rotation matrix
|
||||||
|
u.mul(v.transpose());
|
||||||
|
// Build quaternion from it
|
||||||
|
return dest.setFromNormalized(u).normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
2105
src/main/java/com/jozufozu/flywheel/repack/joml/Quaternionfc.java
Normal file
2105
src/main/java/com/jozufozu/flywheel/repack/joml/Quaternionfc.java
Normal file
File diff suppressed because it is too large
Load diff
169
src/main/java/com/jozufozu/flywheel/repack/joml/Random.java
Normal file
169
src/main/java/com/jozufozu/flywheel/repack/joml/Random.java
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pseudo-random number generator.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Random {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference <a href="http://xoroshiro.di.unimi.it/xoroshiro128plus.c">http://xoroshiro.di.unimi.it/</a>
|
||||||
|
*/
|
||||||
|
private static final class Xorshiro128 {
|
||||||
|
/**
|
||||||
|
* = 0x1p-24f
|
||||||
|
*/
|
||||||
|
private static final float INT_TO_FLOAT = Float.intBitsToFloat(864026624);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Xorshiro128 state
|
||||||
|
*/
|
||||||
|
private long _s0;
|
||||||
|
private long _s1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SplitMix64 State
|
||||||
|
*/
|
||||||
|
private long state;
|
||||||
|
|
||||||
|
Xorshiro128(long seed) {
|
||||||
|
this.state = seed;
|
||||||
|
this._s0 = nextSplitMix64();
|
||||||
|
this._s1 = nextSplitMix64();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long nextSplitMix64() {
|
||||||
|
long z = state += 0x9e3779b97f4a7c15L;
|
||||||
|
z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
|
||||||
|
z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
|
||||||
|
return z ^ (z >>> 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference: <a href="https://github.com/roquendm/JGO-Grabbag/blob/master/src/roquen/math/rng/PRNG.java">https://github.com/roquendm/</a>
|
||||||
|
*
|
||||||
|
* @author roquendm
|
||||||
|
*/
|
||||||
|
final float nextFloat() {
|
||||||
|
return (nextInt() >>> 8) * INT_TO_FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int nextInt() {
|
||||||
|
long s0 = _s0;
|
||||||
|
long s1 = _s1;
|
||||||
|
long result = s0 + s1;
|
||||||
|
s1 ^= s0;
|
||||||
|
rotateLeft(s0, s1);
|
||||||
|
return (int) (result & 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
private static long rotl_JDK4(final long x, final int k) {
|
||||||
|
return (x << k) | (x >>> (64 - k));
|
||||||
|
}
|
||||||
|
private static long rotl_JDK5(final long x, final int k) {
|
||||||
|
return Long.rotateLeft(x, k);
|
||||||
|
}
|
||||||
|
private static long rotl(final long x, final int k) {
|
||||||
|
if (Runtime.HAS_Long_rotateLeft)
|
||||||
|
return rotl_JDK5(x, k);
|
||||||
|
return rotl_JDK4(x, k);
|
||||||
|
}
|
||||||
|
private void rotateLeft(long s0, long s1) {
|
||||||
|
_s0 = rotl(s0, 55) ^ s1 ^ (s1 << 14);
|
||||||
|
_s1 = rotl(s1, 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference: <a href="https://github.com/roquendm/JGO-Grabbag/blob/master/src/roquen/math/rng/PRNG.java">https://github.com/roquendm/</a>
|
||||||
|
*
|
||||||
|
* @author roquendm
|
||||||
|
*/
|
||||||
|
final int nextInt(int n) {
|
||||||
|
// See notes in nextInt. This is
|
||||||
|
// (on average) a better choice for
|
||||||
|
// 64-bit VMs.
|
||||||
|
long r = nextInt() >>> 1;
|
||||||
|
// sign doesn't matter here
|
||||||
|
r = (r * n) >> 31;
|
||||||
|
return (int) r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Xorshiro128 rnd;
|
||||||
|
|
||||||
|
//8020463840 is from "Case File n_221: Kabukicho"
|
||||||
|
private static long seedHalf = 8020463840L;
|
||||||
|
|
||||||
|
public static long newSeed() {
|
||||||
|
// 3512401965023503517 is from L'Ecuyer, "Tables of Linear Congruential Generators of
|
||||||
|
// Different Sizes and Good Lattice Structure", 1999
|
||||||
|
long oldSeedHalf, newSeedHalf;
|
||||||
|
synchronized (Random.class) {
|
||||||
|
oldSeedHalf = seedHalf;
|
||||||
|
newSeedHalf = oldSeedHalf * 3512401965023503517L;
|
||||||
|
seedHalf = newSeedHalf;
|
||||||
|
}
|
||||||
|
return newSeedHalf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of {@link Random} and initialize it with a random seed.
|
||||||
|
*/
|
||||||
|
public Random() {
|
||||||
|
this(newSeed() ^ System.nanoTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of {@link Random} and initialize it with the given <code>seed</code>.
|
||||||
|
*
|
||||||
|
* @param seed
|
||||||
|
* the seed number
|
||||||
|
*/
|
||||||
|
public Random(long seed) {
|
||||||
|
this.rnd = new Xorshiro128(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a uniformly distributed floating-point number in the half-open range [0, 1).
|
||||||
|
*
|
||||||
|
* @return a random float in the range [0..1)
|
||||||
|
*/
|
||||||
|
public float nextFloat() {
|
||||||
|
return rnd.nextFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a uniformly distributed integer in the half-open range [0, n).
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* the upper limit (exclusive) of the generated integer
|
||||||
|
* @return a random integer in the range [0..n)
|
||||||
|
*/
|
||||||
|
public int nextInt(int n) {
|
||||||
|
return rnd.nextInt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,399 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 Kai Burjack
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an implementation of the <a
|
||||||
|
* href="http://www.cg.cs.tu-bs.de/media/publications/fast-rayaxis-aligned-bounding-box-overlap-tests-using-ray-slopes.pdf">Fast Ray/Axis-Aligned Bounding Box
|
||||||
|
* Overlap Tests using Ray Slopes</a> paper.
|
||||||
|
* <p>
|
||||||
|
* It is an efficient implementation when testing many axis-aligned boxes against the same ray.
|
||||||
|
* <p>
|
||||||
|
* This class is thread-safe and can be used in a multithreaded environment when testing many axis-aligned boxes against the same ray concurrently.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class RayAabIntersection {
|
||||||
|
private float originX, originY, originZ;
|
||||||
|
private float dirX, dirY, dirZ;
|
||||||
|
|
||||||
|
/* Needed for ray slope intersection method */
|
||||||
|
private float c_xy, c_yx, c_zy, c_yz, c_xz, c_zx;
|
||||||
|
private float s_xy, s_yx, s_zy, s_yz, s_xz, s_zx;
|
||||||
|
private byte classification;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link RayAabIntersection} without initializing a ray.
|
||||||
|
* <p>
|
||||||
|
* Before using the {@link #test(float, float, float, float, float, float) intersect()} method,
|
||||||
|
* the method {@link #set(float, float, float, float, float, float) set()} must be called in order to
|
||||||
|
* initialize the created RayAabIntersection instance with a ray.
|
||||||
|
*
|
||||||
|
* @see #set(float, float, float, float, float, float)
|
||||||
|
*/
|
||||||
|
public RayAabIntersection() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link RayAabIntersection} and initialize it with a ray with origin <code>(originX, originY, originZ)</code>
|
||||||
|
* and direction <code>(dirX, dirY, dirZ)</code>.
|
||||||
|
* <p>
|
||||||
|
* In order to change the direction and/or origin of the ray later, use {@link #set(float, float, float, float, float, float) set()}.
|
||||||
|
*
|
||||||
|
* @see #set(float, float, float, float, float, float)
|
||||||
|
*
|
||||||
|
* @param originX
|
||||||
|
* the x coordinate of the origin
|
||||||
|
* @param originY
|
||||||
|
* the y coordinate of the origin
|
||||||
|
* @param originZ
|
||||||
|
* the z coordinate of the origin
|
||||||
|
* @param dirX
|
||||||
|
* the x coordinate of the direction
|
||||||
|
* @param dirY
|
||||||
|
* the y coordinate of the direction
|
||||||
|
* @param dirZ
|
||||||
|
* the z coordinate of the direction
|
||||||
|
*/
|
||||||
|
public RayAabIntersection(float originX, float originY, float originZ, float dirX, float dirY, float dirZ) {
|
||||||
|
set(originX, originY, originZ, dirX, dirY, dirZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the ray stored by this {@link RayAabIntersection} with the new origin <code>(originX, originY, originZ)</code>
|
||||||
|
* and direction <code>(dirX, dirY, dirZ)</code>.
|
||||||
|
*
|
||||||
|
* @param originX
|
||||||
|
* the x coordinate of the ray origin
|
||||||
|
* @param originY
|
||||||
|
* the y coordinate of the ray origin
|
||||||
|
* @param originZ
|
||||||
|
* the z coordinate of the ray origin
|
||||||
|
* @param dirX
|
||||||
|
* the x coordinate of the ray direction
|
||||||
|
* @param dirY
|
||||||
|
* the y coordinate of the ray direction
|
||||||
|
* @param dirZ
|
||||||
|
* the z coordinate of the ray direction
|
||||||
|
*/
|
||||||
|
public void set(float originX, float originY, float originZ, float dirX, float dirY, float dirZ) {
|
||||||
|
this.originX = originX;
|
||||||
|
this.originY = originY;
|
||||||
|
this.originZ = originZ;
|
||||||
|
this.dirX = dirX;
|
||||||
|
this.dirY = dirY;
|
||||||
|
this.dirZ = dirZ;
|
||||||
|
precomputeSlope();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int signum(float f) {
|
||||||
|
return (f == 0.0f || Float.isNaN(f)) ? 0 : ((1 - Float.floatToIntBits(f) >>> 31) << 1) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Precompute the values necessary for the ray slope algorithm.
|
||||||
|
*/
|
||||||
|
private void precomputeSlope() {
|
||||||
|
float invDirX = 1.0f / dirX;
|
||||||
|
float invDirY = 1.0f / dirY;
|
||||||
|
float invDirZ = 1.0f / dirZ;
|
||||||
|
s_yx = dirX * invDirY;
|
||||||
|
s_xy = dirY * invDirX;
|
||||||
|
s_zy = dirY * invDirZ;
|
||||||
|
s_yz = dirZ * invDirY;
|
||||||
|
s_xz = dirZ * invDirX;
|
||||||
|
s_zx = dirX * invDirZ;
|
||||||
|
c_xy = originY - s_xy * originX;
|
||||||
|
c_yx = originX - s_yx * originY;
|
||||||
|
c_zy = originY - s_zy * originZ;
|
||||||
|
c_yz = originZ - s_yz * originY;
|
||||||
|
c_xz = originZ - s_xz * originX; // <- original paper had a bug here. It switched originZ/originX
|
||||||
|
c_zx = originX - s_zx * originZ; // <- original paper had a bug here. It switched originZ/originX
|
||||||
|
int sgnX = signum(dirX);
|
||||||
|
int sgnY = signum(dirY);
|
||||||
|
int sgnZ = signum(dirZ);
|
||||||
|
classification = (byte) ((sgnZ+1) << 4 | (sgnY+1) << 2 | (sgnX+1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the ray stored in this {@link RayAabIntersection} intersect the axis-aligned box
|
||||||
|
* given via its minimum corner <code>(minX, minY, minZ)</code> and its maximum corner <code>(maxX, maxY, maxZ)</code>.
|
||||||
|
* <p>
|
||||||
|
* This implementation uses a tableswitch to dispatch to the correct intersection method.
|
||||||
|
* <p>
|
||||||
|
* This method is thread-safe and can be used to test many axis-aligned boxes concurrently.
|
||||||
|
*
|
||||||
|
* @param minX
|
||||||
|
* the x coordinate of the minimum corner
|
||||||
|
* @param minY
|
||||||
|
* the y coordinate of the minimum corner
|
||||||
|
* @param minZ
|
||||||
|
* the z coordinate of the minimum corner
|
||||||
|
* @param maxX
|
||||||
|
* the x coordinate of the maximum corner
|
||||||
|
* @param maxY
|
||||||
|
* the y coordinate of the maximum corner
|
||||||
|
* @param maxZ
|
||||||
|
* the z coordinate of the maximum corner
|
||||||
|
* @return <code>true</code> iff the ray intersects the given axis-aligned box; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean test(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
// tableswitch with dense and consecutive cases (will be a simple jump based on the switch argument)
|
||||||
|
switch (classification) {
|
||||||
|
case 0: // 0b000000: // MMM
|
||||||
|
return MMM(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 1: // 0b000001: // OMM
|
||||||
|
return OMM(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 2: // 0b000010: // PMM
|
||||||
|
return PMM(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 3: // 0b000011: // not used
|
||||||
|
return false;
|
||||||
|
case 4: // 0b000100: // MOM
|
||||||
|
return MOM(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 5: // 0b000101: // OOM
|
||||||
|
return OOM(minX, minY, minZ, maxX, maxY);
|
||||||
|
case 6: // 0b000110: // POM
|
||||||
|
return POM(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 7: // 0b000111: // not used
|
||||||
|
return false;
|
||||||
|
case 8: // 0b001000: // MPM
|
||||||
|
return MPM(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 9: // 0b001001: // OPM
|
||||||
|
return OPM(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 10: // 0b001010: // PPM
|
||||||
|
return PPM(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 11: // 0b001011: // not used
|
||||||
|
case 12: // 0b001100: // not used
|
||||||
|
case 13: // 0b001101: // not used
|
||||||
|
case 14: // 0b001110: // not used
|
||||||
|
case 15: // 0b001111: // not used
|
||||||
|
return false;
|
||||||
|
case 16: // 0b010000: // MMO
|
||||||
|
return MMO(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 17: // 0b010001: // OMO
|
||||||
|
return OMO(minX, minY, minZ, maxX, maxZ);
|
||||||
|
case 18: // 0b010010: // PMO
|
||||||
|
return PMO(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 19: // 0b010011: // not used
|
||||||
|
return false;
|
||||||
|
case 20: // 0b010100: // MOO
|
||||||
|
return MOO(minX, minY, minZ, maxY, maxZ);
|
||||||
|
case 21: // 0b010101: // OOO
|
||||||
|
return false; // <- degenerate case
|
||||||
|
case 22: // 0b010110: // POO
|
||||||
|
return POO(minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 23: // 0b010111: // not used
|
||||||
|
return false;
|
||||||
|
case 24: // 0b011000: // MPO
|
||||||
|
return MPO(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 25: // 0b011001: // OPO
|
||||||
|
return OPO(minX, minZ, maxX, maxY, maxZ);
|
||||||
|
case 26: // 0b011010: // PPO
|
||||||
|
return PPO(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 27: // 0b011011: // not used
|
||||||
|
case 28: // 0b011100: // not used
|
||||||
|
case 29: // 0b011101: // not used
|
||||||
|
case 30: // 0b011110: // not used
|
||||||
|
case 31: // 0b011111: // not used
|
||||||
|
return false;
|
||||||
|
case 32: // 0b100000: // MMP
|
||||||
|
return MMP(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 33: // 0b100001: // OMP
|
||||||
|
return OMP(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 34: // 0b100010: // PMP
|
||||||
|
return PMP(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 35: // 0b100011: // not used
|
||||||
|
return false;
|
||||||
|
case 36: // 0b100100: // MOP
|
||||||
|
return MOP(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 37: // 0b100101: // OOP
|
||||||
|
return OOP(minX, minY, maxX, maxY, maxZ);
|
||||||
|
case 38: // 0b100110: // POP
|
||||||
|
return POP(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 39: // 0b100111: // not used
|
||||||
|
return false;
|
||||||
|
case 40: // 0b101000: // MPP
|
||||||
|
return MPP(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 41: // 0b101001: // OPP
|
||||||
|
return OPP(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
case 42: // 0b101010: // PPP
|
||||||
|
return PPP(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Intersection tests for all possible ray direction cases */
|
||||||
|
|
||||||
|
private boolean MMM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX >= minX && originY >= minY && originZ >= minZ
|
||||||
|
&& s_xy * minX - maxY + c_xy <= 0.0f
|
||||||
|
&& s_yx * minY - maxX + c_yx <= 0.0f
|
||||||
|
&& s_zy * minZ - maxY + c_zy <= 0.0f
|
||||||
|
&& s_yz * minY - maxZ + c_yz <= 0.0f
|
||||||
|
&& s_xz * minX - maxZ + c_xz <= 0.0f
|
||||||
|
&& s_zx * minZ - maxX + c_zx <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean OMM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX >= minX && originX <= maxX && originY >= minY && originZ >= minZ
|
||||||
|
&& s_zy * minZ - maxY + c_zy <= 0.0f
|
||||||
|
&& s_yz * minY - maxZ + c_yz <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean PMM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX <= maxX && originY >= minY && originZ >= minZ
|
||||||
|
&& s_xy * maxX - maxY + c_xy <= 0.0f
|
||||||
|
&& s_yx * minY - minX + c_yx >= 0.0f
|
||||||
|
&& s_zy * minZ - maxY + c_zy <= 0.0f
|
||||||
|
&& s_yz * minY - maxZ + c_yz <= 0.0f
|
||||||
|
&& s_xz * maxX - maxZ + c_xz <= 0.0f
|
||||||
|
&& s_zx * minZ - minX + c_zx >= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean MOM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originY >= minY && originY <= maxY && originX >= minX && originZ >= minZ
|
||||||
|
&& s_xz * minX - maxZ + c_xz <= 0.0f
|
||||||
|
&& s_zx * minZ - maxX + c_zx <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean OOM(float minX, float minY, float minZ, float maxX, float maxY) {
|
||||||
|
return originZ >= minZ && originX >= minX && originX <= maxX && originY >= minY && originY <= maxY;
|
||||||
|
}
|
||||||
|
private boolean POM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originY >= minY && originY <= maxY && originX <= maxX && originZ >= minZ
|
||||||
|
&& s_xz * maxX - maxZ + c_xz <= 0.0f
|
||||||
|
&& s_zx * minZ - minX + c_zx >= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean MPM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX >= minX && originY <= maxY && originZ >= minZ
|
||||||
|
&& s_xy * minX - minY + c_xy >= 0.0f
|
||||||
|
&& s_yx * maxY - maxX + c_yx <= 0.0f
|
||||||
|
&& s_zy * minZ - minY + c_zy >= 0.0f
|
||||||
|
&& s_yz * maxY - maxZ + c_yz <= 0.0f
|
||||||
|
&& s_xz * minX - maxZ + c_xz <= 0.0f
|
||||||
|
&& s_zx * minZ - maxX + c_zx <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean OPM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX >= minX && originX <= maxX && originY <= maxY && originZ >= minZ
|
||||||
|
&& s_zy * minZ - minY + c_zy >= 0.0f
|
||||||
|
&& s_yz * maxY - maxZ + c_yz <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean PPM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX <= maxX && originY <= maxY && originZ >= minZ
|
||||||
|
&& s_xy * maxX - minY + c_xy >= 0.0f
|
||||||
|
&& s_yx * maxY - minX + c_yx >= 0.0f
|
||||||
|
&& s_zy * minZ - minY + c_zy >= 0.0f
|
||||||
|
&& s_yz * maxY - maxZ + c_yz <= 0.0f
|
||||||
|
&& s_xz * maxX - maxZ + c_xz <= 0.0f
|
||||||
|
&& s_zx * minZ - minX + c_zx >= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean MMO(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originZ >= minZ && originZ <= maxZ && originX >= minX && originY >= minY
|
||||||
|
&& s_xy * minX - maxY + c_xy <= 0.0f
|
||||||
|
&& s_yx * minY - maxX + c_yx <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean OMO(float minX, float minY, float minZ, float maxX, float maxZ) {
|
||||||
|
return originY >= minY && originX >= minX && originX <= maxX && originZ >= minZ && originZ <= maxZ;
|
||||||
|
}
|
||||||
|
private boolean PMO(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originZ >= minZ && originZ <= maxZ && originX <= maxX && originY >= minY
|
||||||
|
&& s_xy * maxX - maxY + c_xy <= 0.0f
|
||||||
|
&& s_yx * minY - minX + c_yx >= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean MOO(float minX, float minY, float minZ, float maxY, float maxZ) {
|
||||||
|
return originX >= minX && originY >= minY && originY <= maxY && originZ >= minZ && originZ <= maxZ;
|
||||||
|
}
|
||||||
|
private boolean POO(float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX <= maxX && originY >= minY && originY <= maxY && originZ >= minZ && originZ <= maxZ;
|
||||||
|
}
|
||||||
|
private boolean MPO(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originZ >= minZ && originZ <= maxZ && originX >= minX && originY <= maxY
|
||||||
|
&& s_xy * minX - minY + c_xy >= 0.0f
|
||||||
|
&& s_yx * maxY - maxX + c_yx <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean OPO(float minX, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originY <= maxY && originX >= minX && originX <= maxX && originZ >= minZ && originZ <= maxZ;
|
||||||
|
}
|
||||||
|
private boolean PPO(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originZ >= minZ && originZ <= maxZ && originX <= maxX && originY <= maxY
|
||||||
|
&& s_xy * maxX - minY + c_xy >= 0.0f
|
||||||
|
&& s_yx * maxY - minX + c_yx >= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean MMP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX >= minX && originY >= minY && originZ <= maxZ
|
||||||
|
&& s_xy * minX - maxY + c_xy <= 0.0f
|
||||||
|
&& s_yx * minY - maxX + c_yx <= 0.0f
|
||||||
|
&& s_zy * maxZ - maxY + c_zy <= 0.0f
|
||||||
|
&& s_yz * minY - minZ + c_yz >= 0.0f
|
||||||
|
&& s_xz * minX - minZ + c_xz >= 0.0f
|
||||||
|
&& s_zx * maxZ - maxX + c_zx <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean OMP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX >= minX && originX <= maxX && originY >= minY && originZ <= maxZ
|
||||||
|
&& s_zy * maxZ - maxY + c_zy <= 0.0f
|
||||||
|
&& s_yz * minY - minZ + c_yz >= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean PMP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX <= maxX && originY >= minY && originZ <= maxZ
|
||||||
|
&& s_xy * maxX - maxY + c_xy <= 0.0f
|
||||||
|
&& s_yx * minY - minX + c_yx >= 0.0f
|
||||||
|
&& s_zy * maxZ - maxY + c_zy <= 0.0f
|
||||||
|
&& s_yz * minY - minZ + c_yz >= 0.0f
|
||||||
|
&& s_xz * maxX - minZ + c_xz >= 0.0f
|
||||||
|
&& s_zx * maxZ - minX + c_zx >= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean MOP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originY >= minY && originY <= maxY && originX >= minX && originZ <= maxZ
|
||||||
|
&& s_xz * minX - minZ + c_xz >= 0.0f
|
||||||
|
&& s_zx * maxZ - maxX + c_zx <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean OOP(float minX, float minY, float maxX, float maxY, float maxZ) {
|
||||||
|
return originZ <= maxZ && originX >= minX && originX <= maxX && originY >= minY && originY <= maxY;
|
||||||
|
}
|
||||||
|
private boolean POP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originY >= minY && originY <= maxY && originX <= maxX && originZ <= maxZ
|
||||||
|
&& s_xz * maxX - minZ + c_xz >= 0.0f
|
||||||
|
&& s_zx * maxZ - minX + c_zx <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean MPP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX >= minX && originY <= maxY && originZ <= maxZ
|
||||||
|
&& s_xy * minX - minY + c_xy >= 0.0f
|
||||||
|
&& s_yx * maxY - maxX + c_yx <= 0.0f
|
||||||
|
&& s_zy * maxZ - minY + c_zy >= 0.0f
|
||||||
|
&& s_yz * maxY - minZ + c_yz >= 0.0f
|
||||||
|
&& s_xz * minX - minZ + c_xz >= 0.0f
|
||||||
|
&& s_zx * maxZ - maxX + c_zx <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean OPP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX >= minX && originX <= maxX && originY <= maxY && originZ <= maxZ
|
||||||
|
&& s_zy * maxZ - minY + c_zy <= 0.0f
|
||||||
|
&& s_yz * maxY - minZ + c_yz <= 0.0f;
|
||||||
|
}
|
||||||
|
private boolean PPP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
|
||||||
|
return originX <= maxX && originY <= maxY && originZ <= maxZ
|
||||||
|
&& s_xy * maxX - minY + c_xy >= 0.0f
|
||||||
|
&& s_yx * maxY - minX + c_yx >= 0.0f
|
||||||
|
&& s_zy * maxZ - minY + c_zy >= 0.0f
|
||||||
|
&& s_yz * maxY - minZ + c_yz >= 0.0f
|
||||||
|
&& s_xz * maxX - minZ + c_xz >= 0.0f
|
||||||
|
&& s_zx * maxZ - minX + c_zx >= 0.0f;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rounding modes.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class RoundingMode {
|
||||||
|
private RoundingMode() {}
|
||||||
|
/**
|
||||||
|
* Discards the fractional part.
|
||||||
|
*/
|
||||||
|
public static final int TRUNCATE = 0;
|
||||||
|
/**
|
||||||
|
* Round towards positive infinity.
|
||||||
|
*/
|
||||||
|
public static final int CEILING = 1;
|
||||||
|
/**
|
||||||
|
* Round towards negative infinity.
|
||||||
|
*/
|
||||||
|
public static final int FLOOR = 2;
|
||||||
|
/**
|
||||||
|
* Round towards the nearest neighbor. If both neighbors are equidistant, round
|
||||||
|
* towards the even neighbor.
|
||||||
|
*/
|
||||||
|
public static final int HALF_EVEN = 3;
|
||||||
|
/**
|
||||||
|
* Round towards the nearest neighbor. If both neighbors are equidistant, round
|
||||||
|
* down.
|
||||||
|
*/
|
||||||
|
public static final int HALF_DOWN = 4;
|
||||||
|
/**
|
||||||
|
* Round towards the nearest neighbor. If both neighbors are equidistant, round
|
||||||
|
* up.
|
||||||
|
*/
|
||||||
|
public static final int HALF_UP = 5;
|
||||||
|
}
|
148
src/main/java/com/jozufozu/flywheel/repack/joml/Runtime.java
Normal file
148
src/main/java/com/jozufozu/flywheel/repack/joml/Runtime.java
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal class to detect features of the runtime.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public final class Runtime {
|
||||||
|
|
||||||
|
public static final boolean HAS_floatToRawIntBits = hasFloatToRawIntBits();
|
||||||
|
public static final boolean HAS_doubleToRawLongBits = hasDoubleToRawLongBits();
|
||||||
|
public static final boolean HAS_Long_rotateLeft = hasLongRotateLeft();
|
||||||
|
public static final boolean HAS_Math_fma = Options.USE_MATH_FMA && hasMathFma();
|
||||||
|
|
||||||
|
private static boolean hasMathFma() {
|
||||||
|
try {
|
||||||
|
java.lang.Math.class.getDeclaredMethod("fma", new Class[] { float.class, float.class, float.class });
|
||||||
|
return true;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Runtime() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasFloatToRawIntBits() {
|
||||||
|
try {
|
||||||
|
Float.class.getDeclaredMethod("floatToRawIntBits", new Class[] { float.class });
|
||||||
|
return true;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasDoubleToRawLongBits() {
|
||||||
|
try {
|
||||||
|
Double.class.getDeclaredMethod("doubleToRawLongBits", new Class[] { double.class });
|
||||||
|
return true;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasLongRotateLeft() {
|
||||||
|
try {
|
||||||
|
Long.class.getDeclaredMethod("rotateLeft", new Class[] { long.class, int.class });
|
||||||
|
return true;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int floatToIntBits(float flt) {
|
||||||
|
if (HAS_floatToRawIntBits)
|
||||||
|
return floatToIntBits1_3(flt);
|
||||||
|
return floatToIntBits1_2(flt);
|
||||||
|
}
|
||||||
|
private static int floatToIntBits1_3(float flt) {
|
||||||
|
return Float.floatToRawIntBits(flt);
|
||||||
|
}
|
||||||
|
private static int floatToIntBits1_2(float flt) {
|
||||||
|
return Float.floatToIntBits(flt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long doubleToLongBits(double dbl) {
|
||||||
|
if (HAS_doubleToRawLongBits)
|
||||||
|
return doubleToLongBits1_3(dbl);
|
||||||
|
return doubleToLongBits1_2(dbl);
|
||||||
|
}
|
||||||
|
private static long doubleToLongBits1_3(double dbl) {
|
||||||
|
return Double.doubleToRawLongBits(dbl);
|
||||||
|
}
|
||||||
|
private static long doubleToLongBits1_2(double dbl) {
|
||||||
|
return Double.doubleToLongBits(dbl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatNumbers(String str) {
|
||||||
|
StringBuffer res = new StringBuffer();
|
||||||
|
int eIndex = Integer.MIN_VALUE;
|
||||||
|
for (int i = 0; i < str.length(); i++) {
|
||||||
|
char c = str.charAt(i);
|
||||||
|
if (c == 'E') {
|
||||||
|
eIndex = i;
|
||||||
|
} else if (c == ' ' && eIndex == i - 1) {
|
||||||
|
// workaround Java 1.4 DecimalFormat bug
|
||||||
|
res.append('+');
|
||||||
|
continue;
|
||||||
|
} else if (Character.isDigit(c) && eIndex == i - 1) {
|
||||||
|
res.append('+');
|
||||||
|
}
|
||||||
|
res.append(c);
|
||||||
|
}
|
||||||
|
return res.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String format(double number, NumberFormat format) {
|
||||||
|
if (Double.isNaN(number)) {
|
||||||
|
return padLeft(format, " NaN");
|
||||||
|
} else if (Double.isInfinite(number)) {
|
||||||
|
return padLeft(format, number > 0.0 ? " +Inf" : " -Inf");
|
||||||
|
}
|
||||||
|
return format.format(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String padLeft(NumberFormat format, String str) {
|
||||||
|
int len = format.format(0.0).length();
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
for (int i = 0; i < len - str.length() + 1; i++) {
|
||||||
|
sb.append(" ");
|
||||||
|
}
|
||||||
|
return sb.append(str).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean equals(float a, float b, float delta) {
|
||||||
|
return Float.floatToIntBits(a) == Float.floatToIntBits(b) || Math.abs(a - b) <= delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean equals(double a, double b, double delta) {
|
||||||
|
return Double.doubleToLongBits(a) == Double.doubleToLongBits(b) || Math.abs(a - b) <= delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,485 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simplex noise algorithm for 2D, 3D and 4D input.
|
||||||
|
* <p>
|
||||||
|
* It was originally authored by Stefan Gustavson.
|
||||||
|
* <p>
|
||||||
|
* The original implementation can be found here: <a
|
||||||
|
* href="http://staffwww.itn.liu.se/~stegu/simplexnoise/SimplexNoise.java">http://http://staffwww.itn.liu.se/</a>.
|
||||||
|
*/
|
||||||
|
public class SimplexNoise {
|
||||||
|
private static class Vector3b {
|
||||||
|
byte x, y, z;
|
||||||
|
Vector3b(int x, int y, int z) {
|
||||||
|
super();
|
||||||
|
this.x = (byte) x;
|
||||||
|
this.y = (byte) y;
|
||||||
|
this.z = (byte) z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static class Vector4b {
|
||||||
|
byte x, y, z, w;
|
||||||
|
Vector4b(int x, int y, int z, int w) {
|
||||||
|
super();
|
||||||
|
this.x = (byte) x;
|
||||||
|
this.y = (byte) y;
|
||||||
|
this.z = (byte) z;
|
||||||
|
this.w = (byte) w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kai Burjack:
|
||||||
|
// Use a three-component vector here to save memory. (instead of using 4-component 'Grad' class)
|
||||||
|
// And as the original author mentioned on the 'Grad' class, using a class to store the gradient components
|
||||||
|
// is indeed faster compared to using a simple int[] array...
|
||||||
|
private static final Vector3b[] grad3 = { new Vector3b(1, 1, 0), new Vector3b(-1, 1, 0), new Vector3b(1, -1, 0), new Vector3b(-1, -1, 0),
|
||||||
|
new Vector3b(1, 0, 1), new Vector3b(-1, 0, 1), new Vector3b(1, 0, -1), new Vector3b(-1, 0, -1), new Vector3b(0, 1, 1), new Vector3b(0, -1, 1),
|
||||||
|
new Vector3b(0, 1, -1), new Vector3b(0, -1, -1) };
|
||||||
|
|
||||||
|
// Kai Burjack:
|
||||||
|
// As the original author mentioned on the 'Grad' class, using a class to store the gradient components
|
||||||
|
// is indeed faster compared to using a simple int[] array...
|
||||||
|
private static final Vector4b[] grad4 = { new Vector4b(0, 1, 1, 1), new Vector4b(0, 1, 1, -1), new Vector4b(0, 1, -1, 1), new Vector4b(0, 1, -1, -1),
|
||||||
|
new Vector4b(0, -1, 1, 1), new Vector4b(0, -1, 1, -1), new Vector4b(0, -1, -1, 1), new Vector4b(0, -1, -1, -1), new Vector4b(1, 0, 1, 1),
|
||||||
|
new Vector4b(1, 0, 1, -1), new Vector4b(1, 0, -1, 1), new Vector4b(1, 0, -1, -1), new Vector4b(-1, 0, 1, 1), new Vector4b(-1, 0, 1, -1),
|
||||||
|
new Vector4b(-1, 0, -1, 1), new Vector4b(-1, 0, -1, -1), new Vector4b(1, 1, 0, 1), new Vector4b(1, 1, 0, -1), new Vector4b(1, -1, 0, 1),
|
||||||
|
new Vector4b(1, -1, 0, -1), new Vector4b(-1, 1, 0, 1), new Vector4b(-1, 1, 0, -1), new Vector4b(-1, -1, 0, 1), new Vector4b(-1, -1, 0, -1),
|
||||||
|
new Vector4b(1, 1, 1, 0), new Vector4b(1, 1, -1, 0), new Vector4b(1, -1, 1, 0), new Vector4b(1, -1, -1, 0), new Vector4b(-1, 1, 1, 0),
|
||||||
|
new Vector4b(-1, 1, -1, 0), new Vector4b(-1, -1, 1, 0), new Vector4b(-1, -1, -1, 0) };
|
||||||
|
|
||||||
|
// Kai Burjack:
|
||||||
|
// Use a byte[] instead of a short[] to save memory
|
||||||
|
private static final byte[] p = { -105, -96, -119, 91, 90, 15, -125, 13, -55, 95, 96, 53, -62, -23, 7, -31, -116, 36, 103, 30, 69, -114, 8, 99, 37, -16,
|
||||||
|
21, 10, 23, -66, 6, -108, -9, 120, -22, 75, 0, 26, -59, 62, 94, -4, -37, -53, 117, 35, 11, 32, 57, -79, 33, 88, -19, -107, 56, 87, -82, 20, 125,
|
||||||
|
-120, -85, -88, 68, -81, 74, -91, 71, -122, -117, 48, 27, -90, 77, -110, -98, -25, 83, 111, -27, 122, 60, -45, -123, -26, -36, 105, 92, 41, 55, 46,
|
||||||
|
-11, 40, -12, 102, -113, 54, 65, 25, 63, -95, 1, -40, 80, 73, -47, 76, -124, -69, -48, 89, 18, -87, -56, -60, -121, -126, 116, -68, -97, 86, -92,
|
||||||
|
100, 109, -58, -83, -70, 3, 64, 52, -39, -30, -6, 124, 123, 5, -54, 38, -109, 118, 126, -1, 82, 85, -44, -49, -50, 59, -29, 47, 16, 58, 17, -74,
|
||||||
|
-67, 28, 42, -33, -73, -86, -43, 119, -8, -104, 2, 44, -102, -93, 70, -35, -103, 101, -101, -89, 43, -84, 9, -127, 22, 39, -3, 19, 98, 108, 110,
|
||||||
|
79, 113, -32, -24, -78, -71, 112, 104, -38, -10, 97, -28, -5, 34, -14, -63, -18, -46, -112, 12, -65, -77, -94, -15, 81, 51, -111, -21, -7, 14, -17,
|
||||||
|
107, 49, -64, -42, 31, -75, -57, 106, -99, -72, 84, -52, -80, 115, 121, 50, 45, 127, 4, -106, -2, -118, -20, -51, 93, -34, 114, 67, 29, 24, 72,
|
||||||
|
-13, -115, -128, -61, 78, 66, -41, 61, -100, -76 };
|
||||||
|
// To remove the need for index wrapping, float the permutation table length
|
||||||
|
private static final byte[] perm = new byte[512];
|
||||||
|
private static final byte[] permMod12 = new byte[512];
|
||||||
|
static {
|
||||||
|
for (int i = 0; i < 512; i++) {
|
||||||
|
perm[i] = p[i & 255];
|
||||||
|
permMod12[i] = (byte) ((perm[i]&0xFF) % 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skewing and unskewing factors for 2, 3, and 4 dimensions
|
||||||
|
private static final float F2 = 0.3660254037844386f; // <- (float) (0.5f * (Math.sqrt(3.0f) - 1.0f));
|
||||||
|
private static final float G2 = 0.21132486540518713f; // <- (float) ((3.0f - Math.sqrt(3.0f)) / 6.0f);
|
||||||
|
private static final float F3 = 1.0f / 3.0f;
|
||||||
|
private static final float G3 = 1.0f / 6.0f;
|
||||||
|
private static final float F4 = 0.30901699437494745f; // <- (float) ((Math.sqrt(5.0f) - 1.0f) / 4.0f);
|
||||||
|
private static final float G4 = 0.1381966011250105f; // <- (float) ((5.0f - Math.sqrt(5.0f)) / 20.0f);
|
||||||
|
|
||||||
|
// This method is a *lot* faster than using (int)Math.floor(x)
|
||||||
|
private static int fastfloor(float x) {
|
||||||
|
int xi = (int) x;
|
||||||
|
return x < xi ? xi - 1 : xi;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float dot(Vector3b g, float x, float y) {
|
||||||
|
return g.x * x + g.y * y;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float dot(Vector3b g, float x, float y, float z) {
|
||||||
|
return g.x * x + g.y * y + g.z * z;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float dot(Vector4b g, float x, float y, float z, float w) {
|
||||||
|
return g.x * x + g.y * y + g.z * z + g.w * w;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute 2D simplex noise for the given input vector <code>(x, y)</code>.
|
||||||
|
* <p>
|
||||||
|
* The result is in the range <code>[-1..+1]</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate
|
||||||
|
* @param y
|
||||||
|
* the y coordinate
|
||||||
|
* @return the noise value (within <code>[-1..+1]</code>)
|
||||||
|
*/
|
||||||
|
public static float noise(float x, float y) {
|
||||||
|
float n0, n1, n2; // Noise contributions from the three corners
|
||||||
|
// Skew the input space to determine which simplex cell we're in
|
||||||
|
float s = (x + y) * F2; // Hairy factor for 2D
|
||||||
|
int i = fastfloor(x + s);
|
||||||
|
int j = fastfloor(y + s);
|
||||||
|
float t = (i + j) * G2;
|
||||||
|
float X0 = i - t; // Unskew the cell origin back to (x,y) space
|
||||||
|
float Y0 = j - t;
|
||||||
|
float x0 = x - X0; // The x,y distances from the cell origin
|
||||||
|
float y0 = y - Y0;
|
||||||
|
// For the 2D case, the simplex shape is an equilateral triangle.
|
||||||
|
// Determine which simplex we are in.
|
||||||
|
int i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
|
||||||
|
if (x0 > y0) {
|
||||||
|
i1 = 1;
|
||||||
|
j1 = 0;
|
||||||
|
} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
|
||||||
|
else {
|
||||||
|
i1 = 0;
|
||||||
|
j1 = 1;
|
||||||
|
} // upper triangle, YX order: (0,0)->(0,1)->(1,1)
|
||||||
|
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
|
||||||
|
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
|
||||||
|
// c = (3-sqrt(3))/6
|
||||||
|
float x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
|
||||||
|
float y1 = y0 - j1 + G2;
|
||||||
|
float x2 = x0 - 1.0f + 2.0f * G2; // Offsets for last corner in (x,y) unskewed coords
|
||||||
|
float y2 = y0 - 1.0f + 2.0f * G2;
|
||||||
|
// Work out the hashed gradient indices of the three simplex corners
|
||||||
|
int ii = i & 255;
|
||||||
|
int jj = j & 255;
|
||||||
|
int gi0 = permMod12[ii + perm[jj]&0xFF]&0xFF;
|
||||||
|
int gi1 = permMod12[ii + i1 + perm[jj + j1]&0xFF]&0xFF;
|
||||||
|
int gi2 = permMod12[ii + 1 + perm[jj + 1]&0xFF]&0xFF;
|
||||||
|
// Calculate the contribution from the three corners
|
||||||
|
float t0 = 0.5f - x0 * x0 - y0 * y0;
|
||||||
|
if (t0 < 0.0f)
|
||||||
|
n0 = 0.0f;
|
||||||
|
else {
|
||||||
|
t0 *= t0;
|
||||||
|
n0 = t0 * t0 * dot(grad3[gi0], x0, y0); // (x,y) of grad3 used for 2D gradient
|
||||||
|
}
|
||||||
|
float t1 = 0.5f - x1 * x1 - y1 * y1;
|
||||||
|
if (t1 < 0.0f)
|
||||||
|
n1 = 0.0f;
|
||||||
|
else {
|
||||||
|
t1 *= t1;
|
||||||
|
n1 = t1 * t1 * dot(grad3[gi1], x1, y1);
|
||||||
|
}
|
||||||
|
float t2 = 0.5f - x2 * x2 - y2 * y2;
|
||||||
|
if (t2 < 0.0f)
|
||||||
|
n2 = 0.0f;
|
||||||
|
else {
|
||||||
|
t2 *= t2;
|
||||||
|
n2 = t2 * t2 * dot(grad3[gi2], x2, y2);
|
||||||
|
}
|
||||||
|
// Add contributions from each corner to get the final noise value.
|
||||||
|
// The result is scaled to return values in the interval [-1,1].
|
||||||
|
return 70.0f * (n0 + n1 + n2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute 3D simplex noise for the given input vector <code>(x, y, z)</code>.
|
||||||
|
* <p>
|
||||||
|
* The result is in the range <code>[-1..+1]</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate
|
||||||
|
* @param y
|
||||||
|
* the y coordinate
|
||||||
|
* @param z
|
||||||
|
* the z coordinate
|
||||||
|
* @return the noise value (within <code>[-1..+1]</code>)
|
||||||
|
*/
|
||||||
|
public static float noise(float x, float y, float z) {
|
||||||
|
float n0, n1, n2, n3; // Noise contributions from the four corners
|
||||||
|
// Skew the input space to determine which simplex cell we're in
|
||||||
|
float s = (x + y + z) * F3; // Very nice and simple skew factor for 3D
|
||||||
|
int i = fastfloor(x + s);
|
||||||
|
int j = fastfloor(y + s);
|
||||||
|
int k = fastfloor(z + s);
|
||||||
|
float t = (i + j + k) * G3;
|
||||||
|
float X0 = i - t; // Unskew the cell origin back to (x,y,z) space
|
||||||
|
float Y0 = j - t;
|
||||||
|
float Z0 = k - t;
|
||||||
|
float x0 = x - X0; // The x,y,z distances from the cell origin
|
||||||
|
float y0 = y - Y0;
|
||||||
|
float z0 = z - Z0;
|
||||||
|
// For the 3D case, the simplex shape is a slightly irregular tetrahedron.
|
||||||
|
// Determine which simplex we are in.
|
||||||
|
int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
|
||||||
|
int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
|
||||||
|
if (x0 >= y0) {
|
||||||
|
if (y0 >= z0) {
|
||||||
|
i1 = 1;
|
||||||
|
j1 = 0;
|
||||||
|
k1 = 0;
|
||||||
|
i2 = 1;
|
||||||
|
j2 = 1;
|
||||||
|
k2 = 0;
|
||||||
|
} // X Y Z order
|
||||||
|
else if (x0 >= z0) {
|
||||||
|
i1 = 1;
|
||||||
|
j1 = 0;
|
||||||
|
k1 = 0;
|
||||||
|
i2 = 1;
|
||||||
|
j2 = 0;
|
||||||
|
k2 = 1;
|
||||||
|
} // X Z Y order
|
||||||
|
else {
|
||||||
|
i1 = 0;
|
||||||
|
j1 = 0;
|
||||||
|
k1 = 1;
|
||||||
|
i2 = 1;
|
||||||
|
j2 = 0;
|
||||||
|
k2 = 1;
|
||||||
|
} // Z X Y order
|
||||||
|
} else { // x0<y0
|
||||||
|
if (y0 < z0) {
|
||||||
|
i1 = 0;
|
||||||
|
j1 = 0;
|
||||||
|
k1 = 1;
|
||||||
|
i2 = 0;
|
||||||
|
j2 = 1;
|
||||||
|
k2 = 1;
|
||||||
|
} // Z Y X order
|
||||||
|
else if (x0 < z0) {
|
||||||
|
i1 = 0;
|
||||||
|
j1 = 1;
|
||||||
|
k1 = 0;
|
||||||
|
i2 = 0;
|
||||||
|
j2 = 1;
|
||||||
|
k2 = 1;
|
||||||
|
} // Y Z X order
|
||||||
|
else {
|
||||||
|
i1 = 0;
|
||||||
|
j1 = 1;
|
||||||
|
k1 = 0;
|
||||||
|
i2 = 1;
|
||||||
|
j2 = 1;
|
||||||
|
k2 = 0;
|
||||||
|
} // Y X Z order
|
||||||
|
}
|
||||||
|
// A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
|
||||||
|
// a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
|
||||||
|
// a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
|
||||||
|
// c = 1/6.
|
||||||
|
float x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords
|
||||||
|
float y1 = y0 - j1 + G3;
|
||||||
|
float z1 = z0 - k1 + G3;
|
||||||
|
float x2 = x0 - i2 + 2.0f * G3; // Offsets for third corner in (x,y,z) coords
|
||||||
|
float y2 = y0 - j2 + 2.0f * G3;
|
||||||
|
float z2 = z0 - k2 + 2.0f * G3;
|
||||||
|
float x3 = x0 - 1.0f + 3.0f * G3; // Offsets for last corner in (x,y,z) coords
|
||||||
|
float y3 = y0 - 1.0f + 3.0f * G3;
|
||||||
|
float z3 = z0 - 1.0f + 3.0f * G3;
|
||||||
|
// Work out the hashed gradient indices of the four simplex corners
|
||||||
|
int ii = i & 255;
|
||||||
|
int jj = j & 255;
|
||||||
|
int kk = k & 255;
|
||||||
|
int gi0 = permMod12[ii + perm[jj + perm[kk]&0xFF]&0xFF]&0xFF;
|
||||||
|
int gi1 = permMod12[ii + i1 + perm[jj + j1 + perm[kk + k1]&0xFF]&0xFF]&0xFF;
|
||||||
|
int gi2 = permMod12[ii + i2 + perm[jj + j2 + perm[kk + k2]&0xFF]&0xFF]&0xFF;
|
||||||
|
int gi3 = permMod12[ii + 1 + perm[jj + 1 + perm[kk + 1]&0xFF]&0xFF]&0xFF;
|
||||||
|
// Calculate the contribution from the four corners
|
||||||
|
float t0 = 0.6f - x0 * x0 - y0 * y0 - z0 * z0;
|
||||||
|
if (t0 < 0.0f)
|
||||||
|
n0 = 0.0f;
|
||||||
|
else {
|
||||||
|
t0 *= t0;
|
||||||
|
n0 = t0 * t0 * dot(grad3[gi0], x0, y0, z0);
|
||||||
|
}
|
||||||
|
float t1 = 0.6f - x1 * x1 - y1 * y1 - z1 * z1;
|
||||||
|
if (t1 < 0.0f)
|
||||||
|
n1 = 0.0f;
|
||||||
|
else {
|
||||||
|
t1 *= t1;
|
||||||
|
n1 = t1 * t1 * dot(grad3[gi1], x1, y1, z1);
|
||||||
|
}
|
||||||
|
float t2 = 0.6f - x2 * x2 - y2 * y2 - z2 * z2;
|
||||||
|
if (t2 < 0.0f)
|
||||||
|
n2 = 0.0f;
|
||||||
|
else {
|
||||||
|
t2 *= t2;
|
||||||
|
n2 = t2 * t2 * dot(grad3[gi2], x2, y2, z2);
|
||||||
|
}
|
||||||
|
float t3 = 0.6f - x3 * x3 - y3 * y3 - z3 * z3;
|
||||||
|
if (t3 < 0.0f)
|
||||||
|
n3 = 0.0f;
|
||||||
|
else {
|
||||||
|
t3 *= t3;
|
||||||
|
n3 = t3 * t3 * dot(grad3[gi3], x3, y3, z3);
|
||||||
|
}
|
||||||
|
// Add contributions from each corner to get the final noise value.
|
||||||
|
// The result is scaled to stay just inside [-1,1]
|
||||||
|
return 32.0f * (n0 + n1 + n2 + n3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute 4D simplex noise for the given input vector <code>(x, y, z, w)</code>.
|
||||||
|
* <p>
|
||||||
|
* The result is in the range <code>[-1..+1]</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate
|
||||||
|
* @param y
|
||||||
|
* the y coordinate
|
||||||
|
* @param z
|
||||||
|
* the z coordinate
|
||||||
|
* @param w
|
||||||
|
* the w coordinate
|
||||||
|
* @return the noise value (within <code>[-1..+1]</code>)
|
||||||
|
*/
|
||||||
|
public static float noise(float x, float y, float z, float w) {
|
||||||
|
float n0, n1, n2, n3, n4; // Noise contributions from the five corners
|
||||||
|
// Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in
|
||||||
|
float s = (x + y + z + w) * F4; // Factor for 4D skewing
|
||||||
|
int i = fastfloor(x + s);
|
||||||
|
int j = fastfloor(y + s);
|
||||||
|
int k = fastfloor(z + s);
|
||||||
|
int l = fastfloor(w + s);
|
||||||
|
float t = (i + j + k + l) * G4; // Factor for 4D unskewing
|
||||||
|
float X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space
|
||||||
|
float Y0 = j - t;
|
||||||
|
float Z0 = k - t;
|
||||||
|
float W0 = l - t;
|
||||||
|
float x0 = x - X0; // The x,y,z,w distances from the cell origin
|
||||||
|
float y0 = y - Y0;
|
||||||
|
float z0 = z - Z0;
|
||||||
|
float w0 = w - W0;
|
||||||
|
// For the 4D case, the simplex is a 4D shape I won't even try to describe.
|
||||||
|
// To find out which of the 24 possible simplices we're in, we need to
|
||||||
|
// determine the magnitude ordering of x0, y0, z0 and w0.
|
||||||
|
// Six pair-wise comparisons are performed between each possible pair
|
||||||
|
// of the four coordinates, and the results are used to rank the numbers.
|
||||||
|
int rankx = 0;
|
||||||
|
int ranky = 0;
|
||||||
|
int rankz = 0;
|
||||||
|
int rankw = 0;
|
||||||
|
if (x0 > y0)
|
||||||
|
rankx++;
|
||||||
|
else
|
||||||
|
ranky++;
|
||||||
|
if (x0 > z0)
|
||||||
|
rankx++;
|
||||||
|
else
|
||||||
|
rankz++;
|
||||||
|
if (x0 > w0)
|
||||||
|
rankx++;
|
||||||
|
else
|
||||||
|
rankw++;
|
||||||
|
if (y0 > z0)
|
||||||
|
ranky++;
|
||||||
|
else
|
||||||
|
rankz++;
|
||||||
|
if (y0 > w0)
|
||||||
|
ranky++;
|
||||||
|
else
|
||||||
|
rankw++;
|
||||||
|
if (z0 > w0)
|
||||||
|
rankz++;
|
||||||
|
else
|
||||||
|
rankw++;
|
||||||
|
int i1, j1, k1, l1; // The integer offsets for the second simplex corner
|
||||||
|
int i2, j2, k2, l2; // The integer offsets for the third simplex corner
|
||||||
|
int i3, j3, k3, l3; // The integer offsets for the fourth simplex corner
|
||||||
|
// simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
|
||||||
|
// Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
|
||||||
|
// impossible. Only the 24 indices which have non-zero entries make any sense.
|
||||||
|
// We use a thresholding to set the coordinates in turn from the largest magnitude.
|
||||||
|
// Rank 3 denotes the largest coordinate.
|
||||||
|
i1 = rankx >= 3 ? 1 : 0;
|
||||||
|
j1 = ranky >= 3 ? 1 : 0;
|
||||||
|
k1 = rankz >= 3 ? 1 : 0;
|
||||||
|
l1 = rankw >= 3 ? 1 : 0;
|
||||||
|
// Rank 2 denotes the second largest coordinate.
|
||||||
|
i2 = rankx >= 2 ? 1 : 0;
|
||||||
|
j2 = ranky >= 2 ? 1 : 0;
|
||||||
|
k2 = rankz >= 2 ? 1 : 0;
|
||||||
|
l2 = rankw >= 2 ? 1 : 0;
|
||||||
|
// Rank 1 denotes the second smallest coordinate.
|
||||||
|
i3 = rankx >= 1 ? 1 : 0;
|
||||||
|
j3 = ranky >= 1 ? 1 : 0;
|
||||||
|
k3 = rankz >= 1 ? 1 : 0;
|
||||||
|
l3 = rankw >= 1 ? 1 : 0;
|
||||||
|
// The fifth corner has all coordinate offsets = 1, so no need to compute that.
|
||||||
|
float x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords
|
||||||
|
float y1 = y0 - j1 + G4;
|
||||||
|
float z1 = z0 - k1 + G4;
|
||||||
|
float w1 = w0 - l1 + G4;
|
||||||
|
float x2 = x0 - i2 + 2.0f * G4; // Offsets for third corner in (x,y,z,w) coords
|
||||||
|
float y2 = y0 - j2 + 2.0f * G4;
|
||||||
|
float z2 = z0 - k2 + 2.0f * G4;
|
||||||
|
float w2 = w0 - l2 + 2.0f * G4;
|
||||||
|
float x3 = x0 - i3 + 3.0f * G4; // Offsets for fourth corner in (x,y,z,w) coords
|
||||||
|
float y3 = y0 - j3 + 3.0f * G4;
|
||||||
|
float z3 = z0 - k3 + 3.0f * G4;
|
||||||
|
float w3 = w0 - l3 + 3.0f * G4;
|
||||||
|
float x4 = x0 - 1.0f + 4.0f * G4; // Offsets for last corner in (x,y,z,w) coords
|
||||||
|
float y4 = y0 - 1.0f + 4.0f * G4;
|
||||||
|
float z4 = z0 - 1.0f + 4.0f * G4;
|
||||||
|
float w4 = w0 - 1.0f + 4.0f * G4;
|
||||||
|
// Work out the hashed gradient indices of the five simplex corners
|
||||||
|
int ii = i & 255;
|
||||||
|
int jj = j & 255;
|
||||||
|
int kk = k & 255;
|
||||||
|
int ll = l & 255;
|
||||||
|
int gi0 = (perm[ii + perm[jj + perm[kk + perm[ll]&0xFF]&0xFF]&0xFF]&0xFF) % 32;
|
||||||
|
int gi1 = (perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]&0xFF]&0xFF]&0xFF]&0xFF) % 32;
|
||||||
|
int gi2 = (perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]&0xFF]&0xFF]&0xFF]&0xFF) % 32;
|
||||||
|
int gi3 = (perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]&0xFF]&0xFF]&0xFF]&0xFF) % 32;
|
||||||
|
int gi4 = (perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]&0xFF]&0xFF]&0xFF]&0xFF) % 32;
|
||||||
|
// Calculate the contribution from the five corners
|
||||||
|
float t0 = 0.6f - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
|
||||||
|
if (t0 < 0.0f)
|
||||||
|
n0 = 0.0f;
|
||||||
|
else {
|
||||||
|
t0 *= t0;
|
||||||
|
n0 = t0 * t0 * dot(grad4[gi0], x0, y0, z0, w0);
|
||||||
|
}
|
||||||
|
float t1 = 0.6f - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
|
||||||
|
if (t1 < 0.0f)
|
||||||
|
n1 = 0.0f;
|
||||||
|
else {
|
||||||
|
t1 *= t1;
|
||||||
|
n1 = t1 * t1 * dot(grad4[gi1], x1, y1, z1, w1);
|
||||||
|
}
|
||||||
|
float t2 = 0.6f - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
|
||||||
|
if (t2 < 0.0f)
|
||||||
|
n2 = 0.0f;
|
||||||
|
else {
|
||||||
|
t2 *= t2;
|
||||||
|
n2 = t2 * t2 * dot(grad4[gi2], x2, y2, z2, w2);
|
||||||
|
}
|
||||||
|
float t3 = 0.6f - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
|
||||||
|
if (t3 < 0.0f)
|
||||||
|
n3 = 0.0f;
|
||||||
|
else {
|
||||||
|
t3 *= t3;
|
||||||
|
n3 = t3 * t3 * dot(grad4[gi3], x3, y3, z3, w3);
|
||||||
|
}
|
||||||
|
float t4 = 0.6f - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
|
||||||
|
if (t4 < 0.0f)
|
||||||
|
n4 = 0.0f;
|
||||||
|
else {
|
||||||
|
t4 *= t4;
|
||||||
|
n4 = t4 * t4 * dot(grad4[gi4], x4, y4, z4, w4);
|
||||||
|
}
|
||||||
|
// Sum up and scale the result to cover the range [-1,1]
|
||||||
|
return 27.0f * (n0 + n1 + n2 + n3 + n4);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1364
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2d.java
Normal file
1364
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2d.java
Normal file
File diff suppressed because it is too large
Load diff
670
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2dc.java
Normal file
670
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2dc.java
Normal file
|
@ -0,0 +1,670 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.DoubleBuffer;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to a read-only view of a 2-dimensional vector of double-precision floats.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public interface Vector2dc {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the x component
|
||||||
|
*/
|
||||||
|
double x();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the y component
|
||||||
|
*/
|
||||||
|
double y();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which
|
||||||
|
* the vector is stored, use {@link #get(int, ByteBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
* @see #get(int, ByteBuffer)
|
||||||
|
*/
|
||||||
|
ByteBuffer get(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link DoubleBuffer} at the current
|
||||||
|
* buffer {@link DoubleBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given DoubleBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the DoubleBuffer at which
|
||||||
|
* the vector is stored, use {@link #get(int, DoubleBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
* @see #get(int, DoubleBuffer)
|
||||||
|
*/
|
||||||
|
DoubleBuffer get(DoubleBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link DoubleBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given DoubleBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the DoubleBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
DoubleBuffer get(int index, DoubleBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector at the given off-heap memory address.
|
||||||
|
* <p>
|
||||||
|
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
|
||||||
|
* <p>
|
||||||
|
* <em>This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.</em>
|
||||||
|
*
|
||||||
|
* @param address
|
||||||
|
* the off-heap address where to store this vector
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
Vector2dc getToAddress(long address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract <code>(x, y)</code> from this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to subtract
|
||||||
|
* @param y
|
||||||
|
* the y component to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d sub(double x, double y, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract <code>v</code> from <code>this</code> vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d sub(Vector2dc v, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract <code>v</code> from <code>this</code> vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d sub(Vector2fc v, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the components of this vector by the given scalar and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the value to multiply this vector's components by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d mul(double scalar, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the components of this Vector2d by the given scalar values and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to multiply this vector by
|
||||||
|
* @param y
|
||||||
|
* the y component to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d mul(double x, double y, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply this Vector2d component-wise by another Vector2d and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to multiply by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d mul(Vector2dc v, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide this Vector2d by the given scalar value and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to divide this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d div(double scalar, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide the components of this Vector3f by the given scalar values and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to divide this vector by
|
||||||
|
* @param y
|
||||||
|
* the y component to divide this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d div(double x, double y, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide this Vector2d component-wise by another Vector2f and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d div(Vector2fc v, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide this by <code>v</code> component-wise and store the result into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d div(Vector2dc v, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix <code>mat</code> with <code>this</code> and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d mul(Matrix2dc mat, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix <code>mat</code> with <code>this</code> and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d mul(Matrix2fc mat, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the transpose of the given matrix with this Vector2f and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d mulTranspose(Matrix2dc mat, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the transpose of the given matrix with this Vector2f and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d mulTranspose(Matrix2fc mat, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given 3x2 matrix <code>mat</code> with <code>this</code> and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* This method assumes the <code>z</code> component of <code>this</code> to be <code>1.0</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d mulPosition(Matrix3x2dc mat, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given 3x2 matrix <code>mat</code> with <code>this</code> and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* This method assumes the <code>z</code> component of <code>this</code> to be <code>0.0</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d mulDirection(Matrix3x2dc mat, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the dot product of this vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the dot product
|
||||||
|
*/
|
||||||
|
double dot(Vector2dc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the angle between this vector and the supplied vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the angle, in radians
|
||||||
|
*/
|
||||||
|
double angle(Vector2dc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length squared of this vector.
|
||||||
|
*
|
||||||
|
* @return the length squared
|
||||||
|
*/
|
||||||
|
double lengthSquared();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length of this vector.
|
||||||
|
*
|
||||||
|
* @return the length
|
||||||
|
*/
|
||||||
|
double length();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between this and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the distance
|
||||||
|
*/
|
||||||
|
double distance(Vector2dc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance squared between this and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the distance squared
|
||||||
|
*/
|
||||||
|
double distanceSquared(Vector2dc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between this and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the distance
|
||||||
|
*/
|
||||||
|
double distance(Vector2fc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance squared between this and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the distance squared
|
||||||
|
*/
|
||||||
|
double distanceSquared(Vector2fc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between <code>this</code> vector and <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @return the euclidean distance
|
||||||
|
*/
|
||||||
|
double distance(double x, double y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance squared between <code>this</code> vector and <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @return the euclidean distance squared
|
||||||
|
*/
|
||||||
|
double distanceSquared(double x, double y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d normalize(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale this vector to have the given length and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param length
|
||||||
|
* the desired length
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d normalize(double length, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add <code>(x, y)</code> to this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to add
|
||||||
|
* @param y
|
||||||
|
* the y component to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d add(double x, double y, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add <code>v</code> to this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d add(Vector2dc v, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add <code>v</code> to this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d add(Vector2fc v, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Negate this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d negate(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linearly interpolate <code>this</code> and <code>other</code> using the given interpolation factor <code>t</code>
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>t</code> is <code>0.0</code> then the result is <code>this</code>. If the interpolation factor is <code>1.0</code>
|
||||||
|
* then the result is <code>other</code>.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* the other vector
|
||||||
|
* @param t
|
||||||
|
* the interpolation factor between 0.0 and 1.0
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d lerp(Vector2dc other, double t, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>a * b</code> to this vector
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the first multiplicand
|
||||||
|
* @param b
|
||||||
|
* the second multiplicand
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d fma(Vector2dc a, Vector2dc b, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>a * b</code> to this vector
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the first multiplicand
|
||||||
|
* @param b
|
||||||
|
* the second multiplicand
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d fma(double a, Vector2dc b, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise minimum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d min(Vector2dc v, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise maximum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d max(Vector2dc v, Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the biggest absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
int maxComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the smallest (towards zero) absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
int minComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the specified component of this vector.
|
||||||
|
*
|
||||||
|
* @param component
|
||||||
|
* the component, within <code>[0..1]</code>
|
||||||
|
* @return the value
|
||||||
|
* @throws IllegalArgumentException if <code>component</code> is not within <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
double get(int component) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector
|
||||||
|
* using the given {@link RoundingMode}.
|
||||||
|
*
|
||||||
|
* @param mode
|
||||||
|
* the {@link RoundingMode} to use
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i get(int mode, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f get(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d get(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the largest (closest to positive
|
||||||
|
* infinity) {@code double} value that is less than or equal to that
|
||||||
|
* component and is equal to a mathematical integer and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d floor(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the smallest (closest to negative
|
||||||
|
* infinity) {@code double} value that is greater than or equal to that
|
||||||
|
* component and is equal to a mathematical integer and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d ceil(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the closest double that is equal to
|
||||||
|
* a mathematical integer, with ties rounding to positive infinity and store
|
||||||
|
* the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d round(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether all components are finite floating-point values, that
|
||||||
|
* is, they are not {@link Double#isNaN() NaN} and not
|
||||||
|
* {@link Double#isInfinite() infinity}.
|
||||||
|
*
|
||||||
|
* @return {@code true} if all components are finite floating-point values;
|
||||||
|
* {@code false} otherwise
|
||||||
|
*/
|
||||||
|
boolean isFinite();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the absolute of each of this vector's components
|
||||||
|
* and store the result into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d absolute(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the vector components of <code>this</code> vector with the given vector using the given <code>delta</code>
|
||||||
|
* and return whether all of them are equal within a maximum difference of <code>delta</code>.
|
||||||
|
* <p>
|
||||||
|
* Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
|
||||||
|
* and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
|
||||||
|
* data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param delta
|
||||||
|
* the allowed maximum difference
|
||||||
|
* @return <code>true</code> whether all of the vector components are equal; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
boolean equals(Vector2dc v, double delta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the vector components of <code>this</code> vector with the given <code>(x, y)</code>
|
||||||
|
* and return whether all of them are equal.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to compare to
|
||||||
|
* @param y
|
||||||
|
* the y component to compare to
|
||||||
|
* @return <code>true</code> if all the vector components are equal
|
||||||
|
*/
|
||||||
|
boolean equals(double x, double y);
|
||||||
|
|
||||||
|
}
|
1252
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2f.java
Normal file
1252
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2f.java
Normal file
File diff suppressed because it is too large
Load diff
609
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2fc.java
Normal file
609
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2fc.java
Normal file
|
@ -0,0 +1,609 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to a read-only view of a 2-dimensional vector of single-precision floats.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public interface Vector2fc {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the x component
|
||||||
|
*/
|
||||||
|
float x();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the y component
|
||||||
|
*/
|
||||||
|
float y();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which
|
||||||
|
* the vector is stored, use {@link #get(int, ByteBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
* @see #get(int, ByteBuffer)
|
||||||
|
*/
|
||||||
|
ByteBuffer get(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link FloatBuffer} at the current
|
||||||
|
* buffer {@link FloatBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given FloatBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the FloatBuffer at which
|
||||||
|
* the vector is stored, use {@link #get(int, FloatBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
* @see #get(int, FloatBuffer)
|
||||||
|
*/
|
||||||
|
FloatBuffer get(FloatBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link FloatBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given FloatBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the FloatBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
FloatBuffer get(int index, FloatBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector at the given off-heap memory address.
|
||||||
|
* <p>
|
||||||
|
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
|
||||||
|
* <p>
|
||||||
|
* <em>This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.</em>
|
||||||
|
*
|
||||||
|
* @param address
|
||||||
|
* the off-heap address where to store this vector
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
Vector2fc getToAddress(long address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract <code>v</code> from <code>this</code> vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f sub(Vector2fc v, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract <code>(x, y)</code> from this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to subtract
|
||||||
|
* @param y
|
||||||
|
* the y component to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f sub(float x, float y, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the dot product of this vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the dot product
|
||||||
|
*/
|
||||||
|
float dot(Vector2fc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the angle between this vector and the supplied vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the angle, in radians
|
||||||
|
*/
|
||||||
|
float angle(Vector2fc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length squared of this vector.
|
||||||
|
*
|
||||||
|
* @return the length squared
|
||||||
|
*/
|
||||||
|
float lengthSquared();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length of this vector.
|
||||||
|
*
|
||||||
|
* @return the length
|
||||||
|
*/
|
||||||
|
float length();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between this and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the distance
|
||||||
|
*/
|
||||||
|
float distance(Vector2fc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance squared between this and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the distance squared
|
||||||
|
*/
|
||||||
|
float distanceSquared(Vector2fc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between <code>this</code> vector and <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @return the euclidean distance
|
||||||
|
*/
|
||||||
|
float distance(float x, float y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance squared between <code>this</code> vector and <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @return the euclidean distance squared
|
||||||
|
*/
|
||||||
|
float distanceSquared(float x, float y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f normalize(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale this vector to have the given length and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param length
|
||||||
|
* the desired length
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f normalize(float length, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the supplied vector to this one and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f add(Vector2fc v, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the components of this vector by the given values and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to add
|
||||||
|
* @param y
|
||||||
|
* the y component to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f add(float x, float y, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Negate this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f negate(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the components of this vector by the given scalar and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the value to multiply this vector's components by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f mul(float scalar, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the components of this Vector2f by the given scalar values and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to multiply this vector by
|
||||||
|
* @param y
|
||||||
|
* the y component to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f mul(float x, float y, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply this Vector2f component-wise by another Vector2f and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to multiply by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f mul(Vector2fc v, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide all components of this {@link Vector2f} by the given scalar
|
||||||
|
* value and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f div(float scalar, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide this Vector2f component-wise by another Vector2fc
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f div(Vector2fc v, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide the components of this Vector2f by the given scalar values and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to divide this vector by
|
||||||
|
* @param y
|
||||||
|
* the y component to divide this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f div(float x, float y, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix with this Vector2f and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f mul(Matrix2fc mat, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix with this Vector2f and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f mul(Matrix2dc mat, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the transpose of the given matrix with this Vector3f and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f mulTranspose(Matrix2fc mat, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given 3x2 matrix <code>mat</code> with <code>this</code> and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* This method assumes the <code>z</code> component of <code>this</code> to be <code>1.0</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f mulPosition(Matrix3x2fc mat, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given 3x2 matrix <code>mat</code> with <code>this</code> and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* This method assumes the <code>z</code> component of <code>this</code> to be <code>0.0</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f mulDirection(Matrix3x2fc mat, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linearly interpolate <code>this</code> and <code>other</code> using the given interpolation factor <code>t</code>
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>t</code> is <code>0.0</code> then the result is <code>this</code>. If the interpolation factor is <code>1.0</code>
|
||||||
|
* then the result is <code>other</code>.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* the other vector
|
||||||
|
* @param t
|
||||||
|
* the interpolation factor between 0.0 and 1.0
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f lerp(Vector2fc other, float t, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>a * b</code> to this vector
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the first multiplicand
|
||||||
|
* @param b
|
||||||
|
* the second multiplicand
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f fma(Vector2fc a, Vector2fc b, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>a * b</code> to this vector
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the first multiplicand
|
||||||
|
* @param b
|
||||||
|
* the second multiplicand
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f fma(float a, Vector2fc b, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise minimum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f min(Vector2fc v, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise maximum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f max(Vector2fc v, Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the biggest absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
int maxComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the smallest (towards zero) absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
int minComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the specified component of this vector.
|
||||||
|
*
|
||||||
|
* @param component
|
||||||
|
* the component, within <code>[0..1]</code>
|
||||||
|
* @return the value
|
||||||
|
* @throws IllegalArgumentException if <code>component</code> is not within <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
float get(int component) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector
|
||||||
|
* using the given {@link RoundingMode}.
|
||||||
|
*
|
||||||
|
* @param mode
|
||||||
|
* the {@link RoundingMode} to use
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i get(int mode, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f get(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2d get(Vector2d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the largest (closest to positive
|
||||||
|
* infinity) {@code float} value that is less than or equal to that
|
||||||
|
* component and is equal to a mathematical integer and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f floor(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the smallest (closest to negative
|
||||||
|
* infinity) {@code float} value that is greater than or equal to that
|
||||||
|
* component and is equal to a mathematical integer and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f ceil(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the closest float that is equal to
|
||||||
|
* a mathematical integer, with ties rounding to positive infinity and store
|
||||||
|
* the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f round(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether all components are finite floating-point values, that
|
||||||
|
* is, they are not {@link Float#isNaN() NaN} and not
|
||||||
|
* {@link Float#isInfinite() infinity}.
|
||||||
|
*
|
||||||
|
* @return {@code true} if all components are finite floating-point values;
|
||||||
|
* {@code false} otherwise
|
||||||
|
*/
|
||||||
|
boolean isFinite();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the absolute of each of this vector's components
|
||||||
|
* and store the result into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2f absolute(Vector2f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the vector components of <code>this</code> vector with the given vector using the given <code>delta</code>
|
||||||
|
* and return whether all of them are equal within a maximum difference of <code>delta</code>.
|
||||||
|
* <p>
|
||||||
|
* Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
|
||||||
|
* and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
|
||||||
|
* data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param delta
|
||||||
|
* the allowed maximum difference
|
||||||
|
* @return <code>true</code> whether all of the vector components are equal; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
boolean equals(Vector2fc v, float delta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the vector components of <code>this</code> vector with the given <code>(x, y)</code>
|
||||||
|
* and return whether all of them are equal.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to compare to
|
||||||
|
* @param y
|
||||||
|
* the y component to compare to
|
||||||
|
* @return <code>true</code> if all the vector components are equal
|
||||||
|
*/
|
||||||
|
boolean equals(float x, float y);
|
||||||
|
|
||||||
|
}
|
965
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2i.java
Normal file
965
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2i.java
Normal file
|
@ -0,0 +1,965 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 Richard Greenlees
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.io.Externalizable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a 2D vector with single-precision.
|
||||||
|
*
|
||||||
|
* @author RGreenlees
|
||||||
|
* @author Kai Burjack
|
||||||
|
* @author Hans Uhlig
|
||||||
|
*/
|
||||||
|
public class Vector2i implements Externalizable, Cloneable, Vector2ic {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The x component of the vector.
|
||||||
|
*/
|
||||||
|
public int x;
|
||||||
|
/**
|
||||||
|
* The y component of the vector.
|
||||||
|
*/
|
||||||
|
public int y;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and initialize its components to zero.
|
||||||
|
*/
|
||||||
|
public Vector2i() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and initialize both of its components with
|
||||||
|
* the given value.
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
* the value of both components
|
||||||
|
*/
|
||||||
|
public Vector2i(int s) {
|
||||||
|
this.x = s;
|
||||||
|
this.y = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and initialize its components to the given values.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component
|
||||||
|
* @param y
|
||||||
|
* the y component
|
||||||
|
*/
|
||||||
|
public Vector2i(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and initialize its component values and
|
||||||
|
* round using the given {@link RoundingMode}.
|
||||||
|
* @param x
|
||||||
|
* the x component
|
||||||
|
* @param y
|
||||||
|
* the y component
|
||||||
|
* @param mode
|
||||||
|
* the {@link RoundingMode} to use
|
||||||
|
*/
|
||||||
|
public Vector2i(float x, float y, int mode) {
|
||||||
|
this.x = Math.roundUsing(x, mode);
|
||||||
|
this.y = Math.roundUsing(y, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and initialize its component values and
|
||||||
|
* round using the given {@link RoundingMode}.
|
||||||
|
* @param x
|
||||||
|
* the x component
|
||||||
|
* @param y
|
||||||
|
* the y component
|
||||||
|
* @param mode
|
||||||
|
* the {@link RoundingMode} to use
|
||||||
|
*/
|
||||||
|
public Vector2i(double x, double y, int mode) {
|
||||||
|
this.x = Math.roundUsing(x, mode);
|
||||||
|
this.y = Math.roundUsing(y, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and initialize its components to the one of
|
||||||
|
* the given vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the {@link Vector2ic} to copy the values from
|
||||||
|
*/
|
||||||
|
public Vector2i(Vector2ic v) {
|
||||||
|
x = v.x();
|
||||||
|
y = v.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and initialize its components to the rounded value of
|
||||||
|
* the given vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the {@link Vector2fc} to round and copy the values from
|
||||||
|
* @param mode
|
||||||
|
* the {@link RoundingMode} to use
|
||||||
|
*/
|
||||||
|
public Vector2i(Vector2fc v, int mode) {
|
||||||
|
x = Math.roundUsing(v.x(), mode);
|
||||||
|
y = Math.roundUsing(v.y(), mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and initialize its components to the rounded value of
|
||||||
|
* the given vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the {@link Vector2dc} to round and copy the values from
|
||||||
|
* @param mode
|
||||||
|
* the {@link RoundingMode} to use
|
||||||
|
*/
|
||||||
|
public Vector2i(Vector2dc v, int mode) {
|
||||||
|
x = Math.roundUsing(v.x(), mode);
|
||||||
|
y = Math.roundUsing(v.y(), mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and initialize its two components from the first
|
||||||
|
* two elements of the given array.
|
||||||
|
*
|
||||||
|
* @param xy
|
||||||
|
* the array containing at least three elements
|
||||||
|
*/
|
||||||
|
public Vector2i(int[] xy) {
|
||||||
|
this.x = xy[0];
|
||||||
|
this.y = xy[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and read this vector from the supplied
|
||||||
|
* {@link ByteBuffer} at the current buffer
|
||||||
|
* {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which the vector is
|
||||||
|
* read, use {@link #Vector2i(int, ByteBuffer)}, taking the absolute
|
||||||
|
* position as parameter.
|
||||||
|
*
|
||||||
|
* @see #Vector2i(int, ByteBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* values will be read in <code>x, y</code> order
|
||||||
|
*/
|
||||||
|
public Vector2i(ByteBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.get(this, buffer.position(), buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and read this vector from the supplied
|
||||||
|
* {@link ByteBuffer} starting at the specified absolute buffer
|
||||||
|
* position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* values will be read in <code>x, y</code> order
|
||||||
|
*/
|
||||||
|
public Vector2i(int index, ByteBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.get(this, index, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and read this vector from the supplied
|
||||||
|
* {@link IntBuffer} at the current buffer
|
||||||
|
* {@link IntBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given IntBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the IntBuffer at which the vector is
|
||||||
|
* read, use {@link #Vector2i(int, IntBuffer)}, taking the absolute position
|
||||||
|
* as parameter.
|
||||||
|
*
|
||||||
|
* @see #Vector2i(int, IntBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* values will be read in <code>x, y</code> order
|
||||||
|
*/
|
||||||
|
public Vector2i(IntBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.get(this, buffer.position(), buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Vector2i} and read this vector from the supplied
|
||||||
|
* {@link IntBuffer} starting at the specified absolute buffer
|
||||||
|
* position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given IntBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the IntBuffer
|
||||||
|
* @param buffer
|
||||||
|
* values will be read in <code>x, y</code> order
|
||||||
|
*/
|
||||||
|
public Vector2i(int index, IntBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.get(this, index, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int x() {
|
||||||
|
return this.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int y() {
|
||||||
|
return this.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the x and y components to the supplied value.
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
* scalar value of both components
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i set(int s) {
|
||||||
|
this.x = s;
|
||||||
|
this.y = s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the x and y components to the supplied values.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component
|
||||||
|
* @param y
|
||||||
|
* the y component
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i set(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link Vector2i} to the values of v.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to copy from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i set(Vector2ic v) {
|
||||||
|
this.x = v.x();
|
||||||
|
this.y = v.y();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link Vector2i} to the values of v using {@link RoundingMode#TRUNCATE} rounding.
|
||||||
|
* <p>
|
||||||
|
* Note that due to the given vector <code>v</code> storing the components
|
||||||
|
* in double-precision, there is the possibility to lose precision.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to copy from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i set(Vector2dc v) {
|
||||||
|
this.x = (int) v.x();
|
||||||
|
this.y = (int) v.y();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link Vector2i} to the values of v using the given {@link RoundingMode}.
|
||||||
|
* <p>
|
||||||
|
* Note that due to the given vector <code>v</code> storing the components
|
||||||
|
* in double-precision, there is the possibility to lose precision.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to copy from
|
||||||
|
* @param mode
|
||||||
|
* the {@link RoundingMode} to use
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i set(Vector2dc v, int mode) {
|
||||||
|
this.x = Math.roundUsing(v.x(), mode);
|
||||||
|
this.y = Math.roundUsing(v.y(), mode);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this {@link Vector2i} to the values of v using the given {@link RoundingMode}.
|
||||||
|
* <p>
|
||||||
|
* Note that due to the given vector <code>v</code> storing the components
|
||||||
|
* in double-precision, there is the possibility to lose precision.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to copy from
|
||||||
|
* @param mode
|
||||||
|
* the {@link RoundingMode} to use
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i set(Vector2fc v, int mode) {
|
||||||
|
this.x = Math.roundUsing(v.x(), mode);
|
||||||
|
this.y = Math.roundUsing(v.y(), mode);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the two components of this vector to the first two elements of the given array.
|
||||||
|
*
|
||||||
|
* @param xy
|
||||||
|
* the array containing at least two elements
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i set(int[] xy) {
|
||||||
|
this.x = xy[0];
|
||||||
|
this.y = xy[1];
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read this vector from the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which the vector is
|
||||||
|
* read, use {@link #set(int, ByteBuffer)}, taking the absolute position as
|
||||||
|
* parameter.
|
||||||
|
*
|
||||||
|
* @see #set(int, ByteBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* values will be read in <code>x, y</code> order
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i set(ByteBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.get(this, buffer.position(), buffer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read this vector from the supplied {@link ByteBuffer} starting at the
|
||||||
|
* specified absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* values will be read in <code>x, y</code> order
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i set(int index, ByteBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.get(this, index, buffer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read this vector from the supplied {@link IntBuffer} at the current
|
||||||
|
* buffer {@link IntBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given IntBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the IntBuffer at which the vector is
|
||||||
|
* read, use {@link #set(int, IntBuffer)}, taking the absolute position as
|
||||||
|
* parameter.
|
||||||
|
*
|
||||||
|
* @see #set(int, IntBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* values will be read in <code>x, y</code> order
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i set(IntBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.get(this, buffer.position(), buffer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read this vector from the supplied {@link IntBuffer} starting at the
|
||||||
|
* specified absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given IntBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the IntBuffer
|
||||||
|
* @param buffer
|
||||||
|
* values will be read in <code>x, y</code> order
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i set(int index, IntBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.get(this, index, buffer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the values of this vector by reading 2 integer values from off-heap memory,
|
||||||
|
* starting at the given address.
|
||||||
|
* <p>
|
||||||
|
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
|
||||||
|
* <p>
|
||||||
|
* <em>This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.</em>
|
||||||
|
*
|
||||||
|
* @param address
|
||||||
|
* the off-heap memory address to read the vector values from
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i setFromAddress(long address) {
|
||||||
|
if (Options.NO_UNSAFE)
|
||||||
|
throw new UnsupportedOperationException("Not supported when using joml.nounsafe");
|
||||||
|
MemUtil.MemUtilUnsafe.get(this, address);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int get(int component) throws IllegalArgumentException {
|
||||||
|
switch (component) {
|
||||||
|
case 0:
|
||||||
|
return x;
|
||||||
|
case 1:
|
||||||
|
return y;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of the specified component of this vector.
|
||||||
|
*
|
||||||
|
* @param component
|
||||||
|
* the component whose value to set, within <code>[0..1]</code>
|
||||||
|
* @param value
|
||||||
|
* the value to set
|
||||||
|
* @return this
|
||||||
|
* @throws IllegalArgumentException if <code>component</code> is not within <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
public Vector2i setComponent(int component, int value) throws IllegalArgumentException {
|
||||||
|
switch (component) {
|
||||||
|
case 0:
|
||||||
|
x = value;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
y = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer get(ByteBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.put(this, buffer.position(), buffer);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer get(int index, ByteBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.put(this, index, buffer);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntBuffer get(IntBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.put(this, buffer.position(), buffer);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntBuffer get(int index, IntBuffer buffer) {
|
||||||
|
MemUtil.INSTANCE.put(this, index, buffer);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2ic getToAddress(long address) {
|
||||||
|
if (Options.NO_UNSAFE)
|
||||||
|
throw new UnsupportedOperationException("Not supported when using joml.nounsafe");
|
||||||
|
MemUtil.MemUtilUnsafe.put(this, address);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract the supplied vector from this one and store the result in
|
||||||
|
* <code>this</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to subtract
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i sub(Vector2ic v) {
|
||||||
|
this.x = x - v.x();
|
||||||
|
this.y = y - v.y();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i sub(Vector2ic v, Vector2i dest) {
|
||||||
|
dest.x = x - v.x();
|
||||||
|
dest.y = y - v.y();
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the components of this vector by the given values.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to subtract
|
||||||
|
* @param y
|
||||||
|
* the y component to subtract
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i sub(int x, int y) {
|
||||||
|
this.x = this.x - x;
|
||||||
|
this.y = this.y - y;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i sub(int x, int y, Vector2i dest) {
|
||||||
|
dest.x = this.x - x;
|
||||||
|
dest.y = this.y - y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long lengthSquared() {
|
||||||
|
return x * x + y * y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the length squared of a 2-dimensional single-precision vector.
|
||||||
|
*
|
||||||
|
* @param x The vector's x component
|
||||||
|
* @param y The vector's y component
|
||||||
|
*
|
||||||
|
* @return the length squared of the given vector
|
||||||
|
*/
|
||||||
|
public static long lengthSquared(int x, int y) {
|
||||||
|
return x * x + y * y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double length() {
|
||||||
|
return Math.sqrt(x * x + y * y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the length of a 2-dimensional single-precision vector.
|
||||||
|
*
|
||||||
|
* @param x The vector's x component
|
||||||
|
* @param y The vector's y component
|
||||||
|
*
|
||||||
|
* @return the length squared of the given vector
|
||||||
|
*/
|
||||||
|
public static double length(int x, int y) {
|
||||||
|
return Math.sqrt(x * x + y * y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double distance(Vector2ic v) {
|
||||||
|
int dx = this.x - v.x();
|
||||||
|
int dy = this.y - v.y();
|
||||||
|
return Math.sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double distance(int x, int y) {
|
||||||
|
int dx = this.x - x;
|
||||||
|
int dy = this.y - y;
|
||||||
|
return Math.sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long distanceSquared(Vector2ic v) {
|
||||||
|
int dx = this.x - v.x();
|
||||||
|
int dy = this.y - v.y();
|
||||||
|
return dx * dx + dy * dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long distanceSquared(int x, int y) {
|
||||||
|
int dx = this.x - x;
|
||||||
|
int dy = this.y - y;
|
||||||
|
return dx * dx + dy * dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long gridDistance(Vector2ic v) {
|
||||||
|
return Math.abs(v.x() - x()) + Math.abs(v.y() - y());
|
||||||
|
}
|
||||||
|
|
||||||
|
public long gridDistance(int x, int y) {
|
||||||
|
return Math.abs(x - x()) + Math.abs(y - y());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between <code>(x1, y1)</code> and <code>(x2, y2)</code>.
|
||||||
|
*
|
||||||
|
* @param x1
|
||||||
|
* the x component of the first vector
|
||||||
|
* @param y1
|
||||||
|
* the y component of the first vector
|
||||||
|
* @param x2
|
||||||
|
* the x component of the second vector
|
||||||
|
* @param y2
|
||||||
|
* the y component of the second vector
|
||||||
|
* @return the euclidean distance
|
||||||
|
*/
|
||||||
|
public static double distance(int x1, int y1, int x2, int y2) {
|
||||||
|
int dx = x1 - x2;
|
||||||
|
int dy = y1 - y2;
|
||||||
|
return Math.sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the squared distance between <code>(x1, y1)</code> and <code>(x2, y2)</code>.
|
||||||
|
*
|
||||||
|
* @param x1
|
||||||
|
* the x component of the first vector
|
||||||
|
* @param y1
|
||||||
|
* the y component of the first vector
|
||||||
|
* @param x2
|
||||||
|
* the x component of the second vector
|
||||||
|
* @param y2
|
||||||
|
* the y component of the second vector
|
||||||
|
* @return the euclidean distance squared
|
||||||
|
*/
|
||||||
|
public static long distanceSquared(int x1, int y1, int x2, int y2) {
|
||||||
|
int dx = x1 - x2;
|
||||||
|
int dy = y1 - y2;
|
||||||
|
return dx * dx + dy * dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add <code>v</code> to this vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to add
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i add(Vector2ic v) {
|
||||||
|
this.x = x + v.x();
|
||||||
|
this.y = y + v.y();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i add(Vector2ic v, Vector2i dest) {
|
||||||
|
dest.x = x + v.x();
|
||||||
|
dest.y = y + v.y();
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the components of this vector by the given values.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to add
|
||||||
|
* @param y
|
||||||
|
* the y component to add
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i add(int x, int y) {
|
||||||
|
this.x = this.x + x;
|
||||||
|
this.y = this.y + y;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i add(int x, int y, Vector2i dest) {
|
||||||
|
dest.x = this.x + x;
|
||||||
|
dest.y = this.y + y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply all components of this {@link Vector2i} by the given scalar
|
||||||
|
* value.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to multiply this vector by
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i mul(int scalar) {
|
||||||
|
this.x = x * scalar;
|
||||||
|
this.y = y * scalar;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i mul(int scalar, Vector2i dest) {
|
||||||
|
dest.x = x * scalar;
|
||||||
|
dest.y = y * scalar;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the supplied vector by this one.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to multiply
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i mul(Vector2ic v) {
|
||||||
|
this.x = x * v.x();
|
||||||
|
this.y = y * v.y();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i mul(Vector2ic v, Vector2i dest) {
|
||||||
|
dest.x = x * v.x();
|
||||||
|
dest.y = y * v.y();
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the components of this vector by the given values.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to multiply
|
||||||
|
* @param y
|
||||||
|
* the y component to multiply
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i mul(int x, int y) {
|
||||||
|
this.x = this.x * x;
|
||||||
|
this.y = this.y * y;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i mul(int x, int y, Vector2i dest) {
|
||||||
|
dest.x = this.x * x;
|
||||||
|
dest.y = this.y * y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide all components of this {@link Vector2i} by the given scalar value.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to divide by
|
||||||
|
* @return a vector holding the result
|
||||||
|
*/
|
||||||
|
public Vector2i div(float scalar) {
|
||||||
|
float invscalar = 1.0f / scalar;
|
||||||
|
this.x = (int) (x * invscalar);
|
||||||
|
this.y = (int) (y * invscalar);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i div(float scalar, Vector2i dest) {
|
||||||
|
float invscalar = 1.0f / scalar;
|
||||||
|
dest.x = (int) (x * invscalar);
|
||||||
|
dest.y = (int) (y * invscalar);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide all components of this {@link Vector2i} by the given scalar value.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to divide by
|
||||||
|
* @return a vector holding the result
|
||||||
|
*/
|
||||||
|
public Vector2i div(int scalar) {
|
||||||
|
this.x = x / scalar;
|
||||||
|
this.y = y / scalar;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i div(int scalar, Vector2i dest) {
|
||||||
|
dest.x = x / scalar;
|
||||||
|
dest.y = y / scalar;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set all components to zero.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i zero() {
|
||||||
|
this.x = 0;
|
||||||
|
this.y = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
|
out.writeInt(x);
|
||||||
|
out.writeInt(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||||
|
x = in.readInt();
|
||||||
|
y = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Negate this vector.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i negate() {
|
||||||
|
this.x = -x;
|
||||||
|
this.y = -y;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i negate(Vector2i dest) {
|
||||||
|
dest.x = -x;
|
||||||
|
dest.y = -y;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of this vector to be the component-wise minimum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i min(Vector2ic v) {
|
||||||
|
this.x = x < v.x() ? x : v.x();
|
||||||
|
this.y = y < v.y() ? y : v.y();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i min(Vector2ic v, Vector2i dest) {
|
||||||
|
dest.x = x < v.x() ? x : v.x();
|
||||||
|
dest.y = y < v.y() ? y : v.y();
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of this vector to be the component-wise maximum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i max(Vector2ic v) {
|
||||||
|
this.x = x > v.x() ? x : v.x();
|
||||||
|
this.y = y > v.y() ? y : v.y();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i max(Vector2ic v, Vector2i dest) {
|
||||||
|
dest.x = x > v.x() ? x : v.x();
|
||||||
|
dest.y = y > v.y() ? y : v.y();
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int maxComponent() {
|
||||||
|
int absX = Math.abs(x);
|
||||||
|
int absY = Math.abs(y);
|
||||||
|
if (absX >= absY)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int minComponent() {
|
||||||
|
int absX = Math.abs(x);
|
||||||
|
int absY = Math.abs(y);
|
||||||
|
if (absX < absY)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set <code>this</code> vector's components to their respective absolute values.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Vector2i absolute() {
|
||||||
|
this.x = Math.abs(this.x);
|
||||||
|
this.y = Math.abs(this.y);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i absolute(Vector2i dest) {
|
||||||
|
dest.x = Math.abs(this.x);
|
||||||
|
dest.y = Math.abs(this.y);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + x;
|
||||||
|
result = prime * result + y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Vector2i other = (Vector2i) obj;
|
||||||
|
if (x != other.x) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (y != other.y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(int x, int y) {
|
||||||
|
if (this.x != x)
|
||||||
|
return false;
|
||||||
|
if (this.y != y)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string representation of this vector.
|
||||||
|
* <p>
|
||||||
|
* This method creates a new {@link DecimalFormat} on every invocation with the format string "<code>0.000E0;-</code>".
|
||||||
|
*
|
||||||
|
* @return the string representation
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return Runtime.formatNumbers(toString(Options.NUMBER_FORMAT));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string representation of this vector by formatting the vector components with the given {@link NumberFormat}.
|
||||||
|
*
|
||||||
|
* @param formatter
|
||||||
|
* the {@link NumberFormat} used to format the vector components with
|
||||||
|
* @return the string representation
|
||||||
|
*/
|
||||||
|
public String toString(NumberFormat formatter) {
|
||||||
|
return "(" + formatter.format(x) + " " + formatter.format(y) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
return super.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
391
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2ic.java
Normal file
391
src/main/java/com/jozufozu/flywheel/repack/joml/Vector2ic.java
Normal file
|
@ -0,0 +1,391 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to a read-only view of a 2-dimensional vector of integers.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public interface Vector2ic {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the x component
|
||||||
|
*/
|
||||||
|
int x();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the y component
|
||||||
|
*/
|
||||||
|
int y();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which the vector is
|
||||||
|
* stored, use {@link #get(int, ByteBuffer)}, taking the absolute position
|
||||||
|
* as parameter.
|
||||||
|
*
|
||||||
|
* @see #get(int, ByteBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} starting at the
|
||||||
|
* specified absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link IntBuffer} at the current
|
||||||
|
* buffer {@link IntBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given IntBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the IntBuffer at which the vector is
|
||||||
|
* stored, use {@link #get(int, IntBuffer)}, taking the absolute position as
|
||||||
|
* parameter.
|
||||||
|
*
|
||||||
|
* @see #get(int, IntBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
IntBuffer get(IntBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link IntBuffer} starting at the
|
||||||
|
* specified absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given IntBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the IntBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
IntBuffer get(int index, IntBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector at the given off-heap memory address.
|
||||||
|
* <p>
|
||||||
|
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
|
||||||
|
* <p>
|
||||||
|
* <em>This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.</em>
|
||||||
|
*
|
||||||
|
* @param address
|
||||||
|
* the off-heap address where to store this vector
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
Vector2ic getToAddress(long address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract the supplied vector from this one and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i sub(Vector2ic v, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the components of this vector by the given values and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to subtract
|
||||||
|
* @param y
|
||||||
|
* the y component to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i sub(int x, int y, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length squared of this vector.
|
||||||
|
*
|
||||||
|
* @return the length squared
|
||||||
|
*/
|
||||||
|
long lengthSquared();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length of this vector.
|
||||||
|
*
|
||||||
|
* @return the length
|
||||||
|
*/
|
||||||
|
double length();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between this Vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the distance
|
||||||
|
*/
|
||||||
|
double distance(Vector2ic v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between <code>this</code> vector and <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @return the euclidean distance
|
||||||
|
*/
|
||||||
|
double distance(int x, int y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the square of the distance between this vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the squared of the distance
|
||||||
|
*/
|
||||||
|
long distanceSquared(Vector2ic v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the square of the distance between <code>this</code> vector and
|
||||||
|
* <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @return the square of the distance
|
||||||
|
*/
|
||||||
|
long distanceSquared(int x, int y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the grid distance in between (aka 1-Norm, Minkowski or Manhattan distance)
|
||||||
|
* <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the grid distance
|
||||||
|
*/
|
||||||
|
long gridDistance(Vector2ic v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the grid distance in between (aka 1-Norm, Minkowski or Manhattan distance)
|
||||||
|
* <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @return the grid distance
|
||||||
|
*/
|
||||||
|
long gridDistance(int x, int y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the supplied vector to this one and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i add(Vector2ic v, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the components of this vector by the given values and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to add
|
||||||
|
* @param y
|
||||||
|
* the y component to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i add(int x, int y, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply all components of this {@link Vector2ic} by the given scalar
|
||||||
|
* value and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i mul(int scalar, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the supplied vector by this one and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to multiply
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i mul(Vector2ic v, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the components of this vector by the given values and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to multiply
|
||||||
|
* @param y
|
||||||
|
* the y component to multiply
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i mul(int x, int y, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide all components of this {@link Vector2i} by the given scalar value
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i div(float scalar, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide all components of this {@link Vector2i} by the given scalar value
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i div(int scalar, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Negate this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i negate(Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise minimum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i min(Vector2ic v, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise maximum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i max(Vector2ic v, Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the biggest absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
int maxComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the smallest (towards zero) absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
int minComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the absolute of each of this vector's components
|
||||||
|
* and store the result into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector2i absolute(Vector2i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the specified component of this vector.
|
||||||
|
*
|
||||||
|
* @param component
|
||||||
|
* the component, within <code>[0..1]</code>
|
||||||
|
* @return the value
|
||||||
|
* @throws IllegalArgumentException if <code>component</code> is not within <code>[0..1]</code>
|
||||||
|
*/
|
||||||
|
int get(int component) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the vector components of <code>this</code> vector with the given <code>(x, y)</code>
|
||||||
|
* and return whether all of them are equal.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to compare to
|
||||||
|
* @param y
|
||||||
|
* the y component to compare to
|
||||||
|
* @return <code>true</code> if all the vector components are equal
|
||||||
|
*/
|
||||||
|
boolean equals(int x, int y);
|
||||||
|
|
||||||
|
}
|
2613
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3d.java
Normal file
2613
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3d.java
Normal file
File diff suppressed because it is too large
Load diff
1392
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3dc.java
Normal file
1392
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3dc.java
Normal file
File diff suppressed because it is too large
Load diff
2086
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3f.java
Normal file
2086
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3f.java
Normal file
File diff suppressed because it is too large
Load diff
1089
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3fc.java
Normal file
1089
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3fc.java
Normal file
File diff suppressed because it is too large
Load diff
1131
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3i.java
Normal file
1131
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3i.java
Normal file
File diff suppressed because it is too large
Load diff
409
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3ic.java
Normal file
409
src/main/java/com/jozufozu/flywheel/repack/joml/Vector3ic.java
Normal file
|
@ -0,0 +1,409 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to a read-only view of a 3-dimensional vector of integers.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public interface Vector3ic {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the x component
|
||||||
|
*/
|
||||||
|
int x();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the y component
|
||||||
|
*/
|
||||||
|
int y();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the z component
|
||||||
|
*/
|
||||||
|
int z();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link IntBuffer} at the current
|
||||||
|
* buffer {@link IntBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given IntBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the IntBuffer at which the vector is
|
||||||
|
* stored, use {@link #get(int, IntBuffer)}, taking the absolute position as
|
||||||
|
* parameter.
|
||||||
|
*
|
||||||
|
* @see #get(int, IntBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
IntBuffer get(IntBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link IntBuffer} starting at the
|
||||||
|
* specified absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given IntBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the IntBuffer
|
||||||
|
* @param
|
||||||
|
* buffer will receive the values of this vector in <code>x, y, z</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
IntBuffer get(int index, IntBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which the vector is
|
||||||
|
* stored, use {@link #get(int, ByteBuffer)}, taking the absolute position
|
||||||
|
* as parameter.
|
||||||
|
*
|
||||||
|
* @see #get(int, ByteBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} starting at the
|
||||||
|
* specified absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector at the given off-heap memory address.
|
||||||
|
* <p>
|
||||||
|
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
|
||||||
|
* <p>
|
||||||
|
* <em>This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.</em>
|
||||||
|
*
|
||||||
|
* @param address
|
||||||
|
* the off-heap address where to store this vector
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
Vector3ic getToAddress(long address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract the supplied vector from this one and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i sub(Vector3ic v, Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the components of this vector by the given values and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to subtract
|
||||||
|
* @param y
|
||||||
|
* the y component to subtract
|
||||||
|
* @param z
|
||||||
|
* the z component to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i sub(int x, int y, int z, Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the supplied vector to this one and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i add(Vector3ic v, Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the components of this vector by the given values and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to add
|
||||||
|
* @param y
|
||||||
|
* the y component to add
|
||||||
|
* @param z
|
||||||
|
* the z component to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i add(int x, int y, int z, Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the components of this vector by the given scalar and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the value to multiply this vector's components by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i mul(int scalar, Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the supplied vector by this one and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to multiply
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i mul(Vector3ic v, Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the components of this vector by the given values and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to multiply
|
||||||
|
* @param y
|
||||||
|
* the y component to multiply
|
||||||
|
* @param z
|
||||||
|
* the z component to multiply
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i mul(int x, int y, int z, Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide all components of this {@link Vector3i} by the given scalar value
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i div(float scalar, Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide all components of this {@link Vector3i} by the given scalar value
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i div(int scalar, Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length squared of this vector.
|
||||||
|
*
|
||||||
|
* @return the length squared
|
||||||
|
*/
|
||||||
|
long lengthSquared();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length of this vector.
|
||||||
|
*
|
||||||
|
* @return the length
|
||||||
|
*/
|
||||||
|
double length();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between this Vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the distance
|
||||||
|
*/
|
||||||
|
double distance(Vector3ic v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between <code>this</code> vector and <code>(x, y, z)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the z component of the other vector
|
||||||
|
* @return the euclidean distance
|
||||||
|
*/
|
||||||
|
double distance(int x, int y, int z);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the grid distance in between (aka 1-Norm, Minkowski or Manhattan distance)
|
||||||
|
* <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the grid distance
|
||||||
|
*/
|
||||||
|
long gridDistance(Vector3ic v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the grid distance in between (aka 1-Norm, Minkowski or Manhattan distance)
|
||||||
|
* <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the y component of the other vector
|
||||||
|
* @return the grid distance
|
||||||
|
*/
|
||||||
|
long gridDistance(int x, int y, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the square of the distance between this vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the squared of the distance
|
||||||
|
*/
|
||||||
|
long distanceSquared(Vector3ic v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the square of the distance between <code>this</code> vector and <code>(x, y, z)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the z component of the other vector
|
||||||
|
* @return the square of the distance
|
||||||
|
*/
|
||||||
|
long distanceSquared(int x, int y, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Negate this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i negate(Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise minimum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i min(Vector3ic v, Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise maximum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i max(Vector3ic v, Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the specified component of this vector.
|
||||||
|
*
|
||||||
|
* @param component
|
||||||
|
* the component, within <code>[0..2]</code>
|
||||||
|
* @return the value
|
||||||
|
* @throws IllegalArgumentException if <code>component</code> is not within <code>[0..2]</code>
|
||||||
|
*/
|
||||||
|
int get(int component) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the biggest absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..2]</code>
|
||||||
|
*/
|
||||||
|
int maxComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the smallest (towards zero) absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..2]</code>
|
||||||
|
*/
|
||||||
|
int minComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the absolute of each of this vector's components
|
||||||
|
* and store the result into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3i absolute(Vector3i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the vector components of <code>this</code> vector with the given <code>(x, y, z)</code>
|
||||||
|
* and return whether all of them are equal.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to compare to
|
||||||
|
* @param y
|
||||||
|
* the y component to compare to
|
||||||
|
* @param z
|
||||||
|
* the z component to compare to
|
||||||
|
* @return <code>true</code> if all the vector components are equal
|
||||||
|
*/
|
||||||
|
boolean equals(int x, int y, int z);
|
||||||
|
|
||||||
|
}
|
2129
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4d.java
Normal file
2129
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4d.java
Normal file
File diff suppressed because it is too large
Load diff
933
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4dc.java
Normal file
933
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4dc.java
Normal file
|
@ -0,0 +1,933 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.DoubleBuffer;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to a read-only view of a 4-dimensional vector of double-precision floats.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public interface Vector4dc {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the x component
|
||||||
|
*/
|
||||||
|
double x();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the y component
|
||||||
|
*/
|
||||||
|
double y();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the z component
|
||||||
|
*/
|
||||||
|
double z();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the w component
|
||||||
|
*/
|
||||||
|
double w();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which
|
||||||
|
* the vector is stored, use {@link #get(int, ByteBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
* @see #get(int, ByteBuffer)
|
||||||
|
*/
|
||||||
|
ByteBuffer get(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link DoubleBuffer} at the current
|
||||||
|
* buffer {@link DoubleBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given DoubleBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the DoubleBuffer at which
|
||||||
|
* the vector is stored, use {@link #get(int, DoubleBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
* @see #get(int, DoubleBuffer)
|
||||||
|
*/
|
||||||
|
DoubleBuffer get(DoubleBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link DoubleBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given DoubleBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the DoubleBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
DoubleBuffer get(int index, DoubleBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link FloatBuffer} at the current
|
||||||
|
* buffer {@link FloatBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given FloatBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the FloatBuffer at which
|
||||||
|
* the vector is stored, use {@link #get(int, FloatBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
* <p>
|
||||||
|
* Please note that due to this vector storing double values those values will potentially
|
||||||
|
* lose precision when they are converted to float values before being put into the given FloatBuffer.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
* @see #get(int, DoubleBuffer)
|
||||||
|
*/
|
||||||
|
FloatBuffer get(FloatBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link FloatBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given FloatBuffer.
|
||||||
|
* <p>
|
||||||
|
* Please note that due to this vector storing double values those values will potentially
|
||||||
|
* lose precision when they are converted to float values before being put into the given FloatBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the FloatBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
FloatBuffer get(int index, FloatBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which
|
||||||
|
* the vector is stored, use {@link #get(int, ByteBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
* <p>
|
||||||
|
* Please note that due to this vector storing double values those values will potentially
|
||||||
|
* lose precision when they are converted to float values before being put into the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
* @see #get(int, ByteBuffer)
|
||||||
|
*/
|
||||||
|
ByteBuffer getf(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* Please note that due to this vector storing double values those values will potentially
|
||||||
|
* lose precision when they are converted to float values before being put into the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer getf(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector at the given off-heap memory address.
|
||||||
|
* <p>
|
||||||
|
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
|
||||||
|
* <p>
|
||||||
|
* <em>This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.</em>
|
||||||
|
*
|
||||||
|
* @param address
|
||||||
|
* the off-heap address where to store this vector
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
Vector4dc getToAddress(long address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract the supplied vector from this one and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d sub(Vector4dc v, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract the supplied vector from this one and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d sub(Vector4fc v, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract <code>(x, y, z, w)</code> from this and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to subtract
|
||||||
|
* @param y
|
||||||
|
* the y component to subtract
|
||||||
|
* @param z
|
||||||
|
* the z component to subtract
|
||||||
|
* @param w
|
||||||
|
* the w component to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d sub(double x, double y, double z, double w, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the supplied vector to this one and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d add(Vector4dc v, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the supplied vector to this one and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d add(Vector4fc v, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add <code>(x, y, z, w)</code> to this and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to subtract
|
||||||
|
* @param y
|
||||||
|
* the y component to subtract
|
||||||
|
* @param z
|
||||||
|
* the z component to subtract
|
||||||
|
* @param w
|
||||||
|
* the w component to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d add(double x, double y, double z, double w, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>a * b</code> to this vector
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the first multiplicand
|
||||||
|
* @param b
|
||||||
|
* the second multiplicand
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d fma(Vector4dc a, Vector4dc b, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>a * b</code> to this vector
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the first multiplicand
|
||||||
|
* @param b
|
||||||
|
* the second multiplicand
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d fma(double a, Vector4dc b, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply this {@link Vector4d} component-wise by the given {@link Vector4dc} and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to multiply this by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mul(Vector4dc v, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply this {@link Vector4d} component-wise by the given {@link Vector4fc} and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to multiply this by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mul(Vector4fc v, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide this {@link Vector4d} component-wise by the given {@link Vector4dc} and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to divide this by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d div(Vector4dc v, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix mat with this {@link Vector4d} and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply <code>this</code> by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mul(Matrix4dc mat, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix mat with this Vector4d and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply the vector with
|
||||||
|
* @param dest
|
||||||
|
* the destination vector to hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mul(Matrix4x3dc mat, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix mat with this Vector4d and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply the vector with
|
||||||
|
* @param dest
|
||||||
|
* the destination vector to hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mul(Matrix4x3fc mat, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix mat with this Vector4d and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply <code>this</code> by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mul(Matrix4fc mat, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the transpose of the given matrix <code>mat</code> with this Vector4d and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix whose transpose to multiply the vector with
|
||||||
|
* @param dest
|
||||||
|
* the destination vector to hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mulTranspose(Matrix4dc mat, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given affine matrix mat with this Vector4d and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the affine matrix to multiply the vector with
|
||||||
|
* @param dest
|
||||||
|
* the destination vector to hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mulAffine(Matrix4dc mat, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the transpose of the given affine matrix <code>mat</code> with this Vector4d and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the affine matrix whose transpose to multiply the vector with
|
||||||
|
* @param dest
|
||||||
|
* the destination vector to hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mulAffineTranspose(Matrix4dc mat, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix <code>mat</code> with this Vector4d, perform perspective division
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mulProject(Matrix4dc mat, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix <code>mat</code> with this Vector4d, perform perspective division
|
||||||
|
* and store the <code>(x, y, z)</code> result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3d mulProject(Matrix4dc mat, Vector3d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>this * a</code> to <code>b</code>
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the multiplicand
|
||||||
|
* @param b
|
||||||
|
* the addend
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mulAdd(Vector4dc a, Vector4dc b, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>this * a</code> to <code>b</code>
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the multiplicand
|
||||||
|
* @param b
|
||||||
|
* the addend
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mulAdd(double a, Vector4dc b, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply this Vector4d by the given scalar value and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the factor to multiply by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d mul(double scalar, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide this Vector4d by the given scalar value and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the factor to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d div(double scalar, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform this vector by the given quaternion <code>quat</code> and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @see Quaterniond#transform(Vector4d)
|
||||||
|
*
|
||||||
|
* @param quat
|
||||||
|
* the quaternion to transform this vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d rotate(Quaterniondc quat, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate this vector the specified radians around the given rotation axis and store the result
|
||||||
|
* into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param aX
|
||||||
|
* the x component of the rotation axis
|
||||||
|
* @param aY
|
||||||
|
* the y component of the rotation axis
|
||||||
|
* @param aZ
|
||||||
|
* the z component of the rotation axis
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d rotateAxis(double angle, double aX, double aY, double aZ, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate this vector the specified radians around the X axis and store the result
|
||||||
|
* into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d rotateX(double angle, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate this vector the specified radians around the Y axis and store the result
|
||||||
|
* into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d rotateY(double angle, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate this vector the specified radians around the Z axis and store the result
|
||||||
|
* into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d rotateZ(double angle, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length squared of this vector.
|
||||||
|
*
|
||||||
|
* @return the length squared
|
||||||
|
*/
|
||||||
|
double lengthSquared();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length of this vector.
|
||||||
|
*
|
||||||
|
* @return the length
|
||||||
|
*/
|
||||||
|
double length();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d normalize(Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale this vector to have the given length and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param length
|
||||||
|
* the desired length
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d normalize(double length, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize this vector by computing only the norm of <code>(x, y, z)</code> and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d normalize3(Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between this Vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the distance
|
||||||
|
*/
|
||||||
|
double distance(Vector4dc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between <code>this</code> vector and <code>(x, y, z, w)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the z component of the other vector
|
||||||
|
* @param w
|
||||||
|
* the w component of the other vector
|
||||||
|
* @return the euclidean distance
|
||||||
|
*/
|
||||||
|
double distance(double x, double y, double z, double w);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the square of the distance between this vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the squared of the distance
|
||||||
|
*/
|
||||||
|
double distanceSquared(Vector4dc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the square of the distance between <code>this</code> vector and
|
||||||
|
* <code>(x, y, z, w)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the z component of the other vector
|
||||||
|
* @param w
|
||||||
|
* the w component of the other vector
|
||||||
|
* @return the square of the distance
|
||||||
|
*/
|
||||||
|
double distanceSquared(double x, double y, double z, double w);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the dot product (inner product) of this vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the dot product
|
||||||
|
*/
|
||||||
|
double dot(Vector4dc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the dot product (inner product) of this vector and <code>(x, y, z, w)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the z component of the other vector
|
||||||
|
* @param w
|
||||||
|
* the w component of the other vector
|
||||||
|
* @return the dot product
|
||||||
|
*/
|
||||||
|
double dot(double x, double y, double z, double w);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the cosine of the angle between this vector and the supplied vector.
|
||||||
|
* <p>
|
||||||
|
* Use this instead of <code>Math.cos(angle(v))</code>.
|
||||||
|
*
|
||||||
|
* @see #angle(Vector4dc)
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the cosine of the angle
|
||||||
|
*/
|
||||||
|
double angleCos(Vector4dc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the angle between this vector and the supplied vector.
|
||||||
|
*
|
||||||
|
* @see #angleCos(Vector4dc)
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the angle, in radians
|
||||||
|
*/
|
||||||
|
double angle(Vector4dc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Negate this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d negate(Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise minimum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d min(Vector4dc v, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise maximum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d max(Vector4dc v, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a smooth-step (i.e. hermite with zero tangents) interpolation
|
||||||
|
* between <code>this</code> vector and the given vector <code>v</code> and
|
||||||
|
* store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param t
|
||||||
|
* the interpolation factor, within <code>[0..1]</code>
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d smoothStep(Vector4dc v, double t, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a hermite interpolation between <code>this</code> vector and its
|
||||||
|
* associated tangent <code>t0</code> and the given vector <code>v</code>
|
||||||
|
* with its tangent <code>t1</code> and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param t0
|
||||||
|
* the tangent of <code>this</code> vector
|
||||||
|
* @param v1
|
||||||
|
* the other vector
|
||||||
|
* @param t1
|
||||||
|
* the tangent of the other vector
|
||||||
|
* @param t
|
||||||
|
* the interpolation factor, within <code>[0..1]</code>
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d hermite(Vector4dc t0, Vector4dc v1, Vector4dc t1, double t, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linearly interpolate <code>this</code> and <code>other</code> using the given interpolation factor <code>t</code>
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>t</code> is <code>0.0</code> then the result is <code>this</code>. If the interpolation factor is <code>1.0</code>
|
||||||
|
* then the result is <code>other</code>.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* the other vector
|
||||||
|
* @param t
|
||||||
|
* the interpolation factor between 0.0 and 1.0
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d lerp(Vector4dc other, double t, Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the specified component of this vector.
|
||||||
|
*
|
||||||
|
* @param component
|
||||||
|
* the component, within <code>[0..3]</code>
|
||||||
|
* @return the value
|
||||||
|
* @throws IllegalArgumentException if <code>component</code> is not within <code>[0..3]</code>
|
||||||
|
*/
|
||||||
|
double get(int component) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector
|
||||||
|
* using the given {@link RoundingMode}.
|
||||||
|
*
|
||||||
|
* @param mode
|
||||||
|
* the {@link RoundingMode} to use
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i get(int mode, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f get(Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d get(Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the biggest absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..3]</code>
|
||||||
|
*/
|
||||||
|
int maxComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the smallest (towards zero) absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..3]</code>
|
||||||
|
*/
|
||||||
|
int minComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the largest (closest to positive
|
||||||
|
* infinity) {@code double} value that is less than or equal to that
|
||||||
|
* component and is equal to a mathematical integer and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d floor(Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the smallest (closest to negative
|
||||||
|
* infinity) {@code double} value that is greater than or equal to that
|
||||||
|
* component and is equal to a mathematical integer and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d ceil(Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the closest double that is equal to
|
||||||
|
* a mathematical integer, with ties rounding to positive infinity and store
|
||||||
|
* the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d round(Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether all components are finite floating-point values, that
|
||||||
|
* is, they are not {@link Double#isNaN() NaN} and not
|
||||||
|
* {@link Double#isInfinite() infinity}.
|
||||||
|
*
|
||||||
|
* @return {@code true} if all components are finite floating-point values;
|
||||||
|
* {@code false} otherwise
|
||||||
|
*/
|
||||||
|
boolean isFinite();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the absolute of each of this vector's components
|
||||||
|
* and store the result into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d absolute(Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the vector components of <code>this</code> vector with the given vector using the given <code>delta</code>
|
||||||
|
* and return whether all of them are equal within a maximum difference of <code>delta</code>.
|
||||||
|
* <p>
|
||||||
|
* Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
|
||||||
|
* and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
|
||||||
|
* data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param delta
|
||||||
|
* the allowed maximum difference
|
||||||
|
* @return <code>true</code> whether all of the vector components are equal; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
boolean equals(Vector4dc v, double delta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the vector components of <code>this</code> vector with the given <code>(x, y, z, w)</code>
|
||||||
|
* and return whether all of them are equal.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to compare to
|
||||||
|
* @param y
|
||||||
|
* the y component to compare to
|
||||||
|
* @param z
|
||||||
|
* the z component to compare to
|
||||||
|
* @param w
|
||||||
|
* the w component to compare to
|
||||||
|
* @return <code>true</code> if all the vector components are equal
|
||||||
|
*/
|
||||||
|
boolean equals(double x, double y, double z, double w);
|
||||||
|
|
||||||
|
}
|
1939
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4f.java
Normal file
1939
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4f.java
Normal file
File diff suppressed because it is too large
Load diff
838
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4fc.java
Normal file
838
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4fc.java
Normal file
|
@ -0,0 +1,838 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to a read-only view of a 4-dimensional vector of single-precision floats.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public interface Vector4fc {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the x component
|
||||||
|
*/
|
||||||
|
float x();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the y component
|
||||||
|
*/
|
||||||
|
float y();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the z component
|
||||||
|
*/
|
||||||
|
float z();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the w component
|
||||||
|
*/
|
||||||
|
float w();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link FloatBuffer} at the current
|
||||||
|
* buffer {@link FloatBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given FloatBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the FloatBuffer at which
|
||||||
|
* the vector is stored, use {@link #get(int, FloatBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
* @see #get(int, FloatBuffer)
|
||||||
|
*/
|
||||||
|
FloatBuffer get(FloatBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link FloatBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given FloatBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the FloatBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
FloatBuffer get(int index, FloatBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which
|
||||||
|
* the vector is stored, use {@link #get(int, ByteBuffer)}, taking
|
||||||
|
* the absolute position as parameter.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
* @see #get(int, ByteBuffer)
|
||||||
|
*/
|
||||||
|
ByteBuffer get(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} starting at the specified
|
||||||
|
* absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector at the given off-heap memory address.
|
||||||
|
* <p>
|
||||||
|
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
|
||||||
|
* <p>
|
||||||
|
* <em>This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.</em>
|
||||||
|
*
|
||||||
|
* @param address
|
||||||
|
* the off-heap address where to store this vector
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
Vector4fc getToAddress(long address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract the supplied vector from this one and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to subtract from <code>this</code>
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f sub(Vector4fc v, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract <code>(x, y, z, w)</code> from this and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to subtract
|
||||||
|
* @param y
|
||||||
|
* the y component to subtract
|
||||||
|
* @param z
|
||||||
|
* the z component to subtract
|
||||||
|
* @param w
|
||||||
|
* the w component to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f sub(float x, float y, float z, float w, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the supplied vector to this one and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f add(Vector4fc v, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the components of this vector by the given values and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to add
|
||||||
|
* @param y
|
||||||
|
* the y component to add
|
||||||
|
* @param z
|
||||||
|
* the z component to add
|
||||||
|
* @param w
|
||||||
|
* the w component to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f add(float x, float y, float z, float w, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>a * b</code> to this vector
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the first multiplicand
|
||||||
|
* @param b
|
||||||
|
* the second multiplicand
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f fma(Vector4fc a, Vector4fc b, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>a * b</code> to this vector
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the first multiplicand
|
||||||
|
* @param b
|
||||||
|
* the second multiplicand
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f fma(float a, Vector4fc b, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>this * a</code> to <code>b</code>
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the multiplicand
|
||||||
|
* @param b
|
||||||
|
* the addend
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f mulAdd(Vector4fc a, Vector4fc b, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component-wise multiplication of <code>this * a</code> to <code>b</code>
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* the multiplicand
|
||||||
|
* @param b
|
||||||
|
* the addend
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f mulAdd(float a, Vector4fc b, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply this Vector4f component-wise by another Vector4f and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f mul(Vector4fc v, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide this Vector4f component-wise by another Vector4f and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f div(Vector4fc v, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix mat with this Vector4f and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply the vector with
|
||||||
|
* @param dest
|
||||||
|
* the destination vector to hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f mul(Matrix4fc mat, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the transpose of the given matrix <code>mat</code> with this Vector4f and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix whose transpose to multiply the vector with
|
||||||
|
* @param dest
|
||||||
|
* the destination vector to hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f mulTranspose(Matrix4fc mat, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given affine matrix mat with this Vector4f and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the affine matrix to multiply the vector with
|
||||||
|
* @param dest
|
||||||
|
* the destination vector to hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f mulAffine(Matrix4fc mat, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the transpose of the given affine matrix <code>mat</code> with this Vector4f and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the affine matrix whose transpose to multiply the vector with
|
||||||
|
* @param dest
|
||||||
|
* the destination vector to hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f mulAffineTranspose(Matrix4fc mat, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix mat with this Vector4f and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply the vector with
|
||||||
|
* @param dest
|
||||||
|
* the destination vector to hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f mul(Matrix4x3fc mat, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix <code>mat</code> with this Vector4f, perform perspective division
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f mulProject(Matrix4fc mat, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the given matrix <code>mat</code> with this Vector4f, perform perspective division
|
||||||
|
* and store the <code>(x, y, z)</code> result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param mat
|
||||||
|
* the matrix to multiply this vector by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector3f mulProject(Matrix4fc mat, Vector3f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply all components of this {@link Vector4f} by the given scalar
|
||||||
|
* value and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to multiply by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f mul(float scalar, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply the components of this Vector4f by the given scalar values and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to multiply by
|
||||||
|
* @param y
|
||||||
|
* the y component to multiply by
|
||||||
|
* @param z
|
||||||
|
* the z component to multiply by
|
||||||
|
* @param w
|
||||||
|
* the w component to multiply by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f mul(float x, float y, float z, float w, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide all components of this {@link Vector4f} by the given scalar
|
||||||
|
* value and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f div(float scalar, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide the components of this Vector4f by the given scalar values and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to divide by
|
||||||
|
* @param y
|
||||||
|
* the y component to divide by
|
||||||
|
* @param z
|
||||||
|
* the z component to divide by
|
||||||
|
* @param w
|
||||||
|
* the w component to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f div(float x, float y, float z, float w, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate this vector by the given quaternion <code>quat</code> and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @see Quaternionf#transform(Vector4f)
|
||||||
|
*
|
||||||
|
* @param quat
|
||||||
|
* the quaternion to rotate this vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f rotate(Quaternionfc quat, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate this vector the specified radians around the given rotation axis and store the result
|
||||||
|
* into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param aX
|
||||||
|
* the x component of the rotation axis
|
||||||
|
* @param aY
|
||||||
|
* the y component of the rotation axis
|
||||||
|
* @param aZ
|
||||||
|
* the z component of the rotation axis
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f rotateAxis(float angle, float aX, float aY, float aZ, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate this vector the specified radians around the X axis and store the result
|
||||||
|
* into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f rotateX(float angle, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate this vector the specified radians around the Y axis and store the result
|
||||||
|
* into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f rotateY(float angle, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate this vector the specified radians around the Z axis and store the result
|
||||||
|
* into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* the angle in radians
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f rotateZ(float angle, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length squared of this vector.
|
||||||
|
*
|
||||||
|
* @return the length squared
|
||||||
|
*/
|
||||||
|
float lengthSquared();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length of this vector.
|
||||||
|
*
|
||||||
|
* @return the length
|
||||||
|
*/
|
||||||
|
float length();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f normalize(Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale this vector to have the given length and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param length
|
||||||
|
* the desired length
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f normalize(float length, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize this vector by computing only the norm of <code>(x, y, z)</code> and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f normalize3(Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between this Vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the distance
|
||||||
|
*/
|
||||||
|
float distance(Vector4fc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between <code>this</code> vector and <code>(x, y, z, w)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the z component of the other vector
|
||||||
|
* @param w
|
||||||
|
* the w component of the other vector
|
||||||
|
* @return the euclidean distance
|
||||||
|
*/
|
||||||
|
float distance(float x, float y, float z, float w);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the square of the distance between this vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the squared of the distance
|
||||||
|
*/
|
||||||
|
float distanceSquared(Vector4fc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the square of the distance between <code>this</code> vector and
|
||||||
|
* <code>(x, y, z, w)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the z component of the other vector
|
||||||
|
* @param w
|
||||||
|
* the w component of the other vector
|
||||||
|
* @return the square of the distance
|
||||||
|
*/
|
||||||
|
float distanceSquared(float x, float y, float z, float w);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the dot product (inner product) of this vector and <code>v</code>
|
||||||
|
* .
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the dot product
|
||||||
|
*/
|
||||||
|
float dot(Vector4fc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the dot product (inner product) of this vector and <code>(x, y, z, w)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the z component of the other vector
|
||||||
|
* @param w
|
||||||
|
* the w component of the other vector
|
||||||
|
* @return the dot product
|
||||||
|
*/
|
||||||
|
float dot(float x, float y, float z, float w);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the cosine of the angle between this vector and the supplied vector. Use this instead of <code>Math.cos(angle(v))</code>.
|
||||||
|
*
|
||||||
|
* @see #angle(Vector4fc)
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the cosine of the angle
|
||||||
|
*/
|
||||||
|
float angleCos(Vector4fc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the angle between this vector and the supplied vector.
|
||||||
|
*
|
||||||
|
* @see #angleCos(Vector4fc)
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the angle, in radians
|
||||||
|
*/
|
||||||
|
float angle(Vector4fc v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Negate this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f negate(Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise minimum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f min(Vector4fc v, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise maximum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f max(Vector4fc v, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linearly interpolate <code>this</code> and <code>other</code> using the given interpolation factor <code>t</code>
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
* <p>
|
||||||
|
* If <code>t</code> is <code>0.0</code> then the result is <code>this</code>. If the interpolation factor is <code>1.0</code>
|
||||||
|
* then the result is <code>other</code>.
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* the other vector
|
||||||
|
* @param t
|
||||||
|
* the interpolation factor between 0.0 and 1.0
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f lerp(Vector4fc other, float t, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a smooth-step (i.e. hermite with zero tangents) interpolation
|
||||||
|
* between <code>this</code> vector and the given vector <code>v</code> and
|
||||||
|
* store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param t
|
||||||
|
* the interpolation factor, within <code>[0..1]</code>
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f smoothStep(Vector4fc v, float t, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a hermite interpolation between <code>this</code> vector and its
|
||||||
|
* associated tangent <code>t0</code> and the given vector <code>v</code>
|
||||||
|
* with its tangent <code>t1</code> and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param t0
|
||||||
|
* the tangent of <code>this</code> vector
|
||||||
|
* @param v1
|
||||||
|
* the other vector
|
||||||
|
* @param t1
|
||||||
|
* the tangent of the other vector
|
||||||
|
* @param t
|
||||||
|
* the interpolation factor, within <code>[0..1]</code>
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f hermite(Vector4fc t0, Vector4fc v1, Vector4fc t1, float t, Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the specified component of this vector.
|
||||||
|
*
|
||||||
|
* @param component
|
||||||
|
* the component, within <code>[0..3]</code>
|
||||||
|
* @return the value
|
||||||
|
* @throws IllegalArgumentException if <code>component</code> is not within <code>[0..3]</code>
|
||||||
|
*/
|
||||||
|
float get(int component) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector
|
||||||
|
* using the given {@link RoundingMode}.
|
||||||
|
*
|
||||||
|
* @param mode
|
||||||
|
* the {@link RoundingMode} to use
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i get(int mode, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f get(Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of the given vector <code>dest</code> to those of <code>this</code> vector.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4d get(Vector4d dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the biggest absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..3]</code>
|
||||||
|
*/
|
||||||
|
int maxComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the smallest (towards zero) absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..3]</code>
|
||||||
|
*/
|
||||||
|
int minComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the largest (closest to positive
|
||||||
|
* infinity) {@code float} value that is less than or equal to that
|
||||||
|
* component and is equal to a mathematical integer and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f floor(Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the smallest (closest to negative
|
||||||
|
* infinity) {@code float} value that is greater than or equal to that
|
||||||
|
* component and is equal to a mathematical integer and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f ceil(Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute for each component of this vector the closest float that is equal to
|
||||||
|
* a mathematical integer, with ties rounding to positive infinity and store
|
||||||
|
* the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f round(Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether all components are finite floating-point values, that
|
||||||
|
* is, they are not {@link Float#isNaN() NaN} and not
|
||||||
|
* {@link Float#isInfinite() infinity}.
|
||||||
|
*
|
||||||
|
* @return {@code true} if all components are finite floating-point values;
|
||||||
|
* {@code false} otherwise
|
||||||
|
*/
|
||||||
|
boolean isFinite();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the absolute of each of this vector's components
|
||||||
|
* and store the result into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4f absolute(Vector4f dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the vector components of <code>this</code> vector with the given vector using the given <code>delta</code>
|
||||||
|
* and return whether all of them are equal within a maximum difference of <code>delta</code>.
|
||||||
|
* <p>
|
||||||
|
* Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
|
||||||
|
* and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
|
||||||
|
* data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param delta
|
||||||
|
* the allowed maximum difference
|
||||||
|
* @return <code>true</code> whether all of the vector components are equal; <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
boolean equals(Vector4fc v, float delta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the vector components of <code>this</code> vector with the given <code>(x, y, z, w)</code>
|
||||||
|
* and return whether all of them are equal.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to compare to
|
||||||
|
* @param y
|
||||||
|
* the y component to compare to
|
||||||
|
* @param z
|
||||||
|
* the z component to compare to
|
||||||
|
* @param w
|
||||||
|
* the w component to compare to
|
||||||
|
* @return <code>true</code> if all the vector components are equal
|
||||||
|
*/
|
||||||
|
boolean equals(float x, float y, float z, float w);
|
||||||
|
|
||||||
|
}
|
1212
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4i.java
Normal file
1212
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4i.java
Normal file
File diff suppressed because it is too large
Load diff
432
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4ic.java
Normal file
432
src/main/java/com/jozufozu/flywheel/repack/joml/Vector4ic.java
Normal file
|
@ -0,0 +1,432 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to a read-only view of a 4-dimensional vector of integers.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public interface Vector4ic {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the x component
|
||||||
|
*/
|
||||||
|
int x();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the y component
|
||||||
|
*/
|
||||||
|
int y();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the z component
|
||||||
|
*/
|
||||||
|
int z();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the w component
|
||||||
|
*/
|
||||||
|
int w();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link IntBuffer} at the current
|
||||||
|
* buffer {@link IntBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given IntBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the IntBuffer at which the vector is
|
||||||
|
* stored, use {@link #get(int, IntBuffer)}, taking the absolute position as
|
||||||
|
* parameter.
|
||||||
|
*
|
||||||
|
* @see #get(int, IntBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
IntBuffer get(IntBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link IntBuffer} starting at the
|
||||||
|
* specified absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given IntBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the IntBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
IntBuffer get(int index, IntBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} at the current
|
||||||
|
* buffer {@link ByteBuffer#position() position}.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
* <p>
|
||||||
|
* In order to specify the offset into the ByteBuffer at which the vector is
|
||||||
|
* stored, use {@link #get(int, ByteBuffer)}, taking the absolute position
|
||||||
|
* as parameter.
|
||||||
|
*
|
||||||
|
* @see #get(int, ByteBuffer)
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector into the supplied {@link ByteBuffer} starting at the
|
||||||
|
* specified absolute buffer position/index.
|
||||||
|
* <p>
|
||||||
|
* This method will not increment the position of the given ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the absolute position into the ByteBuffer
|
||||||
|
* @param buffer
|
||||||
|
* will receive the values of this vector in <code>x, y, z, w</code> order
|
||||||
|
* @return the passed in buffer
|
||||||
|
*/
|
||||||
|
ByteBuffer get(int index, ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store this vector at the given off-heap memory address.
|
||||||
|
* <p>
|
||||||
|
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
|
||||||
|
* <p>
|
||||||
|
* <em>This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.</em>
|
||||||
|
*
|
||||||
|
* @param address
|
||||||
|
* the off-heap address where to store this vector
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
Vector4ic getToAddress(long address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract the supplied vector from this one and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to subtract from <code>this</code>
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i sub(Vector4ic v, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract <code>(x, y, z, w)</code> from this and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to subtract
|
||||||
|
* @param y
|
||||||
|
* the y component to subtract
|
||||||
|
* @param z
|
||||||
|
* the z component to subtract
|
||||||
|
* @param w
|
||||||
|
* the w component to subtract
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i sub(int x, int y, int z, int w, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the supplied vector to this one and store the result in
|
||||||
|
* <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i add(Vector4ic v, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the components of this vector by the given values and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to add
|
||||||
|
* @param y
|
||||||
|
* the y component to add
|
||||||
|
* @param z
|
||||||
|
* the z component to add
|
||||||
|
* @param w
|
||||||
|
* the w component to add
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i add(int x, int y, int z, int w, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply this Vector4i component-wise by another Vector4ic and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i mul(Vector4ic v, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide this Vector4i component-wise by another Vector4ic and store the
|
||||||
|
* result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the vector to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i div(Vector4ic v, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply all components of this {@link Vector4i} by the given scalar
|
||||||
|
* value and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to multiply by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i mul(int scalar, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide all components of this {@link Vector4i} by the given scalar value
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i div(float scalar, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide all components of this {@link Vector4i} by the given scalar value
|
||||||
|
* and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param scalar
|
||||||
|
* the scalar to divide by
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i div(int scalar, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length squared of this vector.
|
||||||
|
*
|
||||||
|
* @return the length squared
|
||||||
|
*/
|
||||||
|
long lengthSquared();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length of this vector.
|
||||||
|
*
|
||||||
|
* @return the length
|
||||||
|
*/
|
||||||
|
double length();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between this Vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the distance
|
||||||
|
*/
|
||||||
|
double distance(Vector4ic v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance between <code>this</code> vector and <code>(x, y, z, w)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the z component of the other vector
|
||||||
|
* @param w
|
||||||
|
* the w component of the other vector
|
||||||
|
* @return the euclidean distance
|
||||||
|
*/
|
||||||
|
double distance(int x, int y, int z, int w);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the grid distance in between (aka 1-Norm, Minkowski or Manhattan distance)
|
||||||
|
* <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the grid distance
|
||||||
|
*/
|
||||||
|
long gridDistance(Vector4ic v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the grid distance in between (aka 1-Norm, Minkowski or Manhattan distance)
|
||||||
|
* <code>(x, y)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the z component of the other vector
|
||||||
|
* @param w
|
||||||
|
* the w component of the other vector
|
||||||
|
* @return the grid distance
|
||||||
|
*/
|
||||||
|
long gridDistance(int x, int y, int z, int w);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the square of the distance between this vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the squared of the distance
|
||||||
|
*/
|
||||||
|
int distanceSquared(Vector4ic v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the square of the distance between <code>this</code> vector and
|
||||||
|
* <code>(x, y, z, w)</code>.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component of the other vector
|
||||||
|
* @param y
|
||||||
|
* the y component of the other vector
|
||||||
|
* @param z
|
||||||
|
* the z component of the other vector
|
||||||
|
* @param w
|
||||||
|
* the w component of the other vector
|
||||||
|
* @return the square of the distance
|
||||||
|
*/
|
||||||
|
int distanceSquared(int x, int y, int z, int w);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the dot product (inner product) of this vector and <code>v</code>.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @return the dot product
|
||||||
|
*/
|
||||||
|
int dot(Vector4ic v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Negate this vector and store the result in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i negate(Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise minimum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i min(Vector4ic v, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the components of <code>dest</code> to be the component-wise maximum of this and the other vector.
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
* the other vector
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i max(Vector4ic v, Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the specified component of this vector.
|
||||||
|
*
|
||||||
|
* @param component
|
||||||
|
* the component, within <code>[0..3]</code>
|
||||||
|
* @return the value
|
||||||
|
* @throws IllegalArgumentException if <code>component</code> is not within <code>[0..3]</code>
|
||||||
|
*/
|
||||||
|
int get(int component) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the biggest absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..3]</code>
|
||||||
|
*/
|
||||||
|
int maxComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the component with the smallest (towards zero) absolute value.
|
||||||
|
*
|
||||||
|
* @return the component index, within <code>[0..3]</code>
|
||||||
|
*/
|
||||||
|
int minComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the absolute of each of this vector's components
|
||||||
|
* and store the result into <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* will hold the result
|
||||||
|
* @return dest
|
||||||
|
*/
|
||||||
|
Vector4i absolute(Vector4i dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the vector components of <code>this</code> vector with the given <code>(x, y, z, w)</code>
|
||||||
|
* and return whether all of them are equal.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x component to compare to
|
||||||
|
* @param y
|
||||||
|
* the y component to compare to
|
||||||
|
* @param z
|
||||||
|
* the z component to compare to
|
||||||
|
* @param w
|
||||||
|
* the w component to compare to
|
||||||
|
* @return <code>true</code> if all the vector components are equal
|
||||||
|
*/
|
||||||
|
boolean equals(int x, int y, int z, int w);
|
||||||
|
|
||||||
|
}
|
14
src/main/java/com/jozufozu/flywheel/repack/joml/package.html
Normal file
14
src/main/java/com/jozufozu/flywheel/repack/joml/package.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body bgcolor="white">
|
||||||
|
<p>Contains all classes of JOML.</p>
|
||||||
|
<p>If you like to know more about JOML, please visit:</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://github.com/JOML-CI/JOML">Its GitHub project page</a></li>
|
||||||
|
<li><a href="http://joml-ci.github.io/JOML">Its site on GitHub Pages</a></li>
|
||||||
|
<li><a href="http://joml-ci.github.io/JOML/apidocs/index.html">The HTML version of this JavaDoc</a></li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml.sampling;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback used for notifying about a new generated 2D sample.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public interface Callback2d {
|
||||||
|
/**
|
||||||
|
* Will be called whenever a new sample with the given coordinates <code>(x, y)</code> is generated.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the new sample point
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the new sample point
|
||||||
|
*/
|
||||||
|
void onNewSample(float x, float y);
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml.sampling;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback used for notifying about a new generated 3D sample.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public interface Callback3d {
|
||||||
|
/**
|
||||||
|
* Will be called whenever a new sample with the given coordinates <code>(x, y, z)</code> is generated.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* the x coordinate of the new sample point
|
||||||
|
* @param y
|
||||||
|
* the y coordinate of the new sample point
|
||||||
|
* @param z
|
||||||
|
* the z coordinate of the new sample point
|
||||||
|
*/
|
||||||
|
void onNewSample(float x, float y, float z);
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml.sampling;
|
||||||
|
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.repack.joml.Math;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates various convolution kernels.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class Convolution {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a Gaussian convolution kernel with the given number of rows and columns, and store
|
||||||
|
* the factors in row-major order in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param rows
|
||||||
|
* the number of rows (must be an odd number)
|
||||||
|
* @param cols
|
||||||
|
* the number of columns (must be an odd number)
|
||||||
|
* @param sigma
|
||||||
|
* the standard deviation of the filter kernel values
|
||||||
|
* @param dest
|
||||||
|
* will hold the kernel factors in row-major order
|
||||||
|
*/
|
||||||
|
public static void gaussianKernel(int rows, int cols, float sigma, FloatBuffer dest) {
|
||||||
|
if ((rows & 1) == 0) {
|
||||||
|
throw new IllegalArgumentException("rows must be an odd number");
|
||||||
|
}
|
||||||
|
if ((cols & 1) == 0) {
|
||||||
|
throw new IllegalArgumentException("cols must be an odd number");
|
||||||
|
}
|
||||||
|
if (dest == null) {
|
||||||
|
throw new IllegalArgumentException("dest must not be null");
|
||||||
|
}
|
||||||
|
if (dest.remaining() < rows * cols) {
|
||||||
|
throw new IllegalArgumentException("dest must have at least " + (rows * cols) + " remaining values");
|
||||||
|
}
|
||||||
|
float sum = 0.0f;
|
||||||
|
int pos = dest.position();
|
||||||
|
for (int i = 0, y = -(rows - 1) / 2; y <= (rows - 1) / 2; y++) {
|
||||||
|
for (int x = -(cols - 1) / 2; x <= (cols - 1) / 2; x++, i++) {
|
||||||
|
float k = (float) Math.exp(-(y * y + x * x) / (2.0 * sigma * sigma));
|
||||||
|
dest.put(pos + i, k);
|
||||||
|
sum += k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < rows * cols; i++) {
|
||||||
|
dest.put(pos + i, dest.get(pos + i) / sum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a Gaussian convolution kernel with the given number of rows and columns, and store
|
||||||
|
* the factors in row-major order in <code>dest</code>.
|
||||||
|
*
|
||||||
|
* @param rows
|
||||||
|
* the number of rows (must be an odd number)
|
||||||
|
* @param cols
|
||||||
|
* the number of columns (must be an odd number)
|
||||||
|
* @param sigma
|
||||||
|
* the standard deviation of the filter kernel values
|
||||||
|
* @param dest
|
||||||
|
* will hold the kernel factors in row-major order
|
||||||
|
*/
|
||||||
|
public static void gaussianKernel(int rows, int cols, float sigma, float[] dest) {
|
||||||
|
if ((rows & 1) == 0) {
|
||||||
|
throw new IllegalArgumentException("rows must be an odd number");
|
||||||
|
}
|
||||||
|
if ((cols & 1) == 0) {
|
||||||
|
throw new IllegalArgumentException("cols must be an odd number");
|
||||||
|
}
|
||||||
|
if (dest == null) {
|
||||||
|
throw new IllegalArgumentException("dest must not be null");
|
||||||
|
}
|
||||||
|
if (dest.length < rows * cols) {
|
||||||
|
throw new IllegalArgumentException("dest must have a size of at least " + (rows * cols));
|
||||||
|
}
|
||||||
|
float sum = 0.0f;
|
||||||
|
for (int i = 0, y = -(rows - 1) / 2; y <= (rows - 1) / 2; y++) {
|
||||||
|
for (int x = -(cols - 1) / 2; x <= (cols - 1) / 2; x++, i++) {
|
||||||
|
float k = (float) Math.exp(-(y * y + x * x) / (2.0 * sigma * sigma));
|
||||||
|
dest[i] = k;
|
||||||
|
sum += k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < rows * cols; i++) {
|
||||||
|
dest[i] = dest[i] / sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml.sampling;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal Math class used by the sampling package.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
class Math extends com.jozufozu.flywheel.repack.joml.Math {
|
||||||
|
|
||||||
|
static final double PI = java.lang.Math.PI;
|
||||||
|
static final double PI2 = PI * 2.0;
|
||||||
|
static final double PIHalf = PI * 0.5;
|
||||||
|
private static final double ONE_OVER_PI = 1.0 / PI;
|
||||||
|
private static final double s5 = Double.longBitsToDouble(4523227044276562163L);
|
||||||
|
private static final double s4 = Double.longBitsToDouble(-4671934770969572232L);
|
||||||
|
private static final double s3 = Double.longBitsToDouble(4575957211482072852L);
|
||||||
|
private static final double s2 = Double.longBitsToDouble(-4628199223918090387L);
|
||||||
|
private static final double s1 = Double.longBitsToDouble(4607182418589157889L);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference: <a href=
|
||||||
|
* "http://www.java-gaming.org/topics/joml-1-8-0-release/37491/msg/361815/view.html#msg361815">http://www.java-gaming.org/</a>
|
||||||
|
*
|
||||||
|
* @author roquendm
|
||||||
|
*/
|
||||||
|
static double sin_roquen_9(double v) {
|
||||||
|
double i = java.lang.Math.rint(v * ONE_OVER_PI);
|
||||||
|
double x = v - i * Math.PI;
|
||||||
|
double qs = 1 - 2 * ((int) i & 1);
|
||||||
|
double x2 = x * x;
|
||||||
|
double r;
|
||||||
|
x = qs * x;
|
||||||
|
r = s5;
|
||||||
|
r = r * x2 + s4;
|
||||||
|
r = r * x2 + s3;
|
||||||
|
r = r * x2 + s2;
|
||||||
|
r = r * x2 + s1;
|
||||||
|
return x * r;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml.sampling;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.repack.joml.Random;
|
||||||
|
import com.jozufozu.flywheel.repack.joml.Vector2f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates Poisson samples.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented here is based on <a href= "http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf">Fast Poisson Disk Sampling in Arbitrary
|
||||||
|
* Dimensions</a>.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class PoissonSampling {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates Poisson samples on a disk.
|
||||||
|
* <p>
|
||||||
|
* The algorithm implemented here is based on <a href= "http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf">Fast Poisson Disk Sampling in Arbitrary
|
||||||
|
* Dimensions</a>.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public static class Disk {
|
||||||
|
|
||||||
|
private final Vector2f[] grid;
|
||||||
|
private final float diskRadius;
|
||||||
|
private final float diskRadiusSquared;
|
||||||
|
private final float minDist;
|
||||||
|
private final float minDistSquared;
|
||||||
|
private final float cellSize;
|
||||||
|
private final int numCells;
|
||||||
|
private final Random rnd;
|
||||||
|
private final ArrayList processList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of {@link Disk} which computes poisson-distributed samples on a disk with the given radius <code>diskRadius</code> and notifies the given
|
||||||
|
* <code>callback</code> for each found sample point.
|
||||||
|
* <p>
|
||||||
|
* The samples are distributed evenly on the disk with a minimum distance to one another of at least <code>minDist</code>.
|
||||||
|
*
|
||||||
|
* @param seed
|
||||||
|
* the seed to initialize the random number generator with
|
||||||
|
* @param diskRadius
|
||||||
|
* the disk radius
|
||||||
|
* @param minDist
|
||||||
|
* the minimum distance between any two generated samples
|
||||||
|
* @param k
|
||||||
|
* determines how many samples are tested before rejection. Higher values produce better results. Typical values are 20 to 30
|
||||||
|
* @param callback
|
||||||
|
* will be notified about each sample point
|
||||||
|
*/
|
||||||
|
public Disk(long seed, float diskRadius, float minDist, int k, Callback2d callback) {
|
||||||
|
this.diskRadius = diskRadius;
|
||||||
|
this.diskRadiusSquared = diskRadius * diskRadius;
|
||||||
|
this.minDist = minDist;
|
||||||
|
this.minDistSquared = minDist * minDist;
|
||||||
|
this.rnd = new Random(seed);
|
||||||
|
this.cellSize = minDist / (float) Math.sqrt(2.0);
|
||||||
|
this.numCells = (int) ((diskRadius * 2) / cellSize) + 1;
|
||||||
|
this.grid = new Vector2f[numCells * numCells];
|
||||||
|
this.processList = new ArrayList();
|
||||||
|
compute(k, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void compute(int k, Callback2d callback) {
|
||||||
|
float x, y;
|
||||||
|
do {
|
||||||
|
x = rnd.nextFloat() * 2.0f - 1.0f;
|
||||||
|
y = rnd.nextFloat() * 2.0f - 1.0f;
|
||||||
|
} while (x * x + y * y > 1.0f);
|
||||||
|
Vector2f initial = new Vector2f(x, y);
|
||||||
|
processList.add(initial);
|
||||||
|
callback.onNewSample(initial.x, initial.y);
|
||||||
|
insert(initial);
|
||||||
|
while (!processList.isEmpty()) {
|
||||||
|
int i = rnd.nextInt(processList.size());
|
||||||
|
Vector2f sample = (Vector2f) processList.get(i);
|
||||||
|
boolean found = false;
|
||||||
|
search: for (int s = 0; s < k; s++) {
|
||||||
|
float angle = rnd.nextFloat() * (float) Math.PI2;
|
||||||
|
float radius = minDist * (rnd.nextFloat() + 1.0f);
|
||||||
|
x = (float) (radius * Math.sin_roquen_9(angle + Math.PIHalf));
|
||||||
|
y = (float) (radius * Math.sin_roquen_9(angle));
|
||||||
|
x += sample.x;
|
||||||
|
y += sample.y;
|
||||||
|
if (x * x + y * y > diskRadiusSquared)
|
||||||
|
continue search;
|
||||||
|
if (!searchNeighbors(x, y)) {
|
||||||
|
found = true;
|
||||||
|
callback.onNewSample(x, y);
|
||||||
|
Vector2f f = new Vector2f(x, y);
|
||||||
|
processList.add(f);
|
||||||
|
insert(f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
processList.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean searchNeighbors(float px, float py) {
|
||||||
|
int row = (int) ((py + diskRadius) / cellSize);
|
||||||
|
int col = (int) ((px + diskRadius) / cellSize);
|
||||||
|
if (grid[row * numCells + col] != null)
|
||||||
|
return true;
|
||||||
|
int minX = Math.max(0, col - 1);
|
||||||
|
int minY = Math.max(0, row - 1);
|
||||||
|
int maxX = Math.min(col + 1, numCells - 1);
|
||||||
|
int maxY = Math.min(row + 1, numCells - 1);
|
||||||
|
for (int y = minY; y <= maxY; y++) {
|
||||||
|
for (int x = minX; x <= maxX; x++) {
|
||||||
|
Vector2f v = grid[y * numCells + x];
|
||||||
|
if (v != null) {
|
||||||
|
float dx = v.x - px;
|
||||||
|
float dy = v.y - py;
|
||||||
|
if (dx * dx + dy * dy < minDistSquared) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insert(Vector2f p) {
|
||||||
|
int row = (int) ((p.y + diskRadius) / cellSize);
|
||||||
|
int col = (int) ((p.x + diskRadius) / cellSize);
|
||||||
|
grid[row * numCells + col] = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml.sampling;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.repack.joml.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates samples on a spiral around a center point.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class SpiralSampling {
|
||||||
|
private final Random rnd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of {@link SpiralSampling} and initialize the random number generator with the given <code>seed</code>.
|
||||||
|
*
|
||||||
|
* @param seed
|
||||||
|
* the seed to initialize the random number generator with
|
||||||
|
*/
|
||||||
|
public SpiralSampling(long seed) {
|
||||||
|
rnd = new Random(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create <code>numSamples</code> number of samples on a spiral with maximum radius <code>radius</code> around the center using <code>numRotations</code> number of rotations
|
||||||
|
* along the spiral, and call the given <code>callback</code> for each sample generated.
|
||||||
|
* <p>
|
||||||
|
* The generated sample points are distributed with equal angle differences around the spiral, so they concentrate towards the center.
|
||||||
|
*
|
||||||
|
* @param radius
|
||||||
|
* the maximum radius of the spiral
|
||||||
|
* @param numRotations
|
||||||
|
* the number of rotations of the spiral
|
||||||
|
* @param numSamples
|
||||||
|
* the number of samples to generate
|
||||||
|
* @param callback
|
||||||
|
* will be called for each sample generated
|
||||||
|
*/
|
||||||
|
public void createEquiAngle(float radius, int numRotations, int numSamples, Callback2d callback) {
|
||||||
|
for (int sample = 0; sample < numSamples; sample++) {
|
||||||
|
float angle = 2.0f * (float) Math.PI * (sample * numRotations) / numSamples;
|
||||||
|
float r = radius * sample / (numSamples - 1);
|
||||||
|
float x = (float) Math.sin_roquen_9(angle + 0.5f * (float) Math.PI) * r;
|
||||||
|
float y = (float) Math.sin_roquen_9(angle) * r;
|
||||||
|
callback.onNewSample(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create <code>numSamples</code> number of samples on a spiral with maximum radius <code>radius</code> around the center using <code>numRotations</code> number of rotations
|
||||||
|
* along the spiral, and call the given <code>callback</code> for each sample generated.
|
||||||
|
* <p>
|
||||||
|
* The generated sample points are distributed with equal angle differences around the spiral, so they concentrate towards the center.
|
||||||
|
* <p>
|
||||||
|
* Additionally, the radius of each sample point is jittered by the given <code>jitter</code> factor.
|
||||||
|
*
|
||||||
|
* @param radius
|
||||||
|
* the maximum radius of the spiral
|
||||||
|
* @param numRotations
|
||||||
|
* the number of rotations of the spiral
|
||||||
|
* @param numSamples
|
||||||
|
* the number of samples to generate
|
||||||
|
* @param jitter
|
||||||
|
* the factor by which the radius of each sample point is jittered. Possible values are <code>[0..1]</code>
|
||||||
|
* @param callback
|
||||||
|
* will be called for each sample generated
|
||||||
|
*/
|
||||||
|
public void createEquiAngle(float radius, int numRotations, int numSamples, float jitter, Callback2d callback) {
|
||||||
|
float spacing = radius / numRotations;
|
||||||
|
for (int sample = 0; sample < numSamples; sample++) {
|
||||||
|
float angle = 2.0f * (float) Math.PI * (sample * numRotations) / numSamples;
|
||||||
|
float r = radius * sample / (numSamples - 1) + (rnd.nextFloat() * 2.0f - 1.0f) * spacing * jitter;
|
||||||
|
float x = (float) Math.sin_roquen_9(angle + 0.5f * (float) Math.PI) * r;
|
||||||
|
float y = (float) Math.sin_roquen_9(angle) * r;
|
||||||
|
callback.onNewSample(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml.sampling;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.repack.joml.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates samples on a unit quad using an NxN strata grid.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class StratifiedSampling {
|
||||||
|
|
||||||
|
private final Random rnd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of {@link StratifiedSampling} and initialize the random number generator with the given
|
||||||
|
* <code>seed</code>.
|
||||||
|
*
|
||||||
|
* @param seed
|
||||||
|
* the seed to initialize the random number generator with
|
||||||
|
*/
|
||||||
|
public StratifiedSampling(long seed) {
|
||||||
|
this.rnd = new Random(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate <code>n * n</code> random sample positions in the unit square of <code>x, y = [-1..+1]</code>.
|
||||||
|
* <p>
|
||||||
|
* Each sample within its stratum is distributed randomly.
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* the number of strata in each dimension
|
||||||
|
* @param callback
|
||||||
|
* will be called for each generated sample position
|
||||||
|
*/
|
||||||
|
public void generateRandom(int n, Callback2d callback) {
|
||||||
|
for (int y = 0; y < n; y++) {
|
||||||
|
for (int x = 0; x < n; x++) {
|
||||||
|
float sampleX = (rnd.nextFloat() / n + (float) x / n) * 2.0f - 1.0f;
|
||||||
|
float sampleY = (rnd.nextFloat() / n + (float) y / n) * 2.0f - 1.0f;
|
||||||
|
callback.onNewSample(sampleX, sampleY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate <code>n * n</code> random sample positions in the unit square of <code>x, y = [-1..+1]</code>.
|
||||||
|
* <p>
|
||||||
|
* Each sample within its stratum is confined to be within <code>[-centering/2..1-centering]</code> of its stratum.
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* the number of strata in each dimension
|
||||||
|
* @param centering
|
||||||
|
* determines how much the random samples in each stratum are confined to be near the center of the
|
||||||
|
* stratum. Possible values are <code>[0..1]</code>
|
||||||
|
* @param callback
|
||||||
|
* will be called for each generated sample position
|
||||||
|
*/
|
||||||
|
public void generateCentered(int n, float centering, Callback2d callback) {
|
||||||
|
float start = centering * 0.5f;
|
||||||
|
float end = 1.0f - centering;
|
||||||
|
for (int y = 0; y < n; y++) {
|
||||||
|
for (int x = 0; x < n; x++) {
|
||||||
|
float sampleX = ((start + rnd.nextFloat() * end) / n + (float) x / n) * 2.0f - 1.0f;
|
||||||
|
float sampleY = ((start + rnd.nextFloat() * end) / n + (float) y / n) * 2.0f - 1.0f;
|
||||||
|
callback.onNewSample(sampleX, sampleY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2021 JOML
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.jozufozu.flywheel.repack.joml.sampling;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.repack.joml.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates uniform samples.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public class UniformSampling {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates uniform samples on a unit disk.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public static class Disk {
|
||||||
|
private final Random rnd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of {@link Disk}, initialize the random number generator with the given <code>seed</code> and generate <code>numSamples</code> number of sample
|
||||||
|
* positions on the unit disk, and call the given <code>callback</code> for each sample generate.
|
||||||
|
*
|
||||||
|
* @param seed
|
||||||
|
* the seed to initialize the random number generator with
|
||||||
|
* @param numSamples
|
||||||
|
* the number of samples to generate
|
||||||
|
* @param callback
|
||||||
|
* will be called for each sample generated
|
||||||
|
*/
|
||||||
|
public Disk(long seed, int numSamples, Callback2d callback) {
|
||||||
|
this.rnd = new Random(seed);
|
||||||
|
generate(numSamples, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generate(int numSamples, Callback2d callback) {
|
||||||
|
for (int i = 0; i < numSamples; i++) {
|
||||||
|
float r = rnd.nextFloat();
|
||||||
|
float a = rnd.nextFloat() * 2.0f * (float) Math.PI;
|
||||||
|
float sqrtR = (float) Math.sqrt(r);
|
||||||
|
float x = sqrtR * (float) Math.sin_roquen_9(a + 0.5 * Math.PI);
|
||||||
|
float y = sqrtR * (float) Math.sin_roquen_9(a);
|
||||||
|
callback.onNewSample(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates uniform samples on a unit sphere.
|
||||||
|
*
|
||||||
|
* @author Kai Burjack
|
||||||
|
*/
|
||||||
|
public static class Sphere {
|
||||||
|
private final Random rnd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of {@link Sphere}, initialize the random number generator with the given <code>seed</code> and generate <code>numSamples</code> number of sample
|
||||||
|
* positions on the unit sphere, and call the given <code>callback</code> for each sample generate.
|
||||||
|
*
|
||||||
|
* @param seed
|
||||||
|
* the seed to initialize the random number generator with
|
||||||
|
* @param numSamples
|
||||||
|
* the number of samples to generate
|
||||||
|
* @param callback
|
||||||
|
* will be called for each sample generated
|
||||||
|
*/
|
||||||
|
public Sphere(long seed, int numSamples, Callback3d callback) {
|
||||||
|
this.rnd = new Random(seed);
|
||||||
|
generate(numSamples, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create <code>numSamples</code> number of samples which are uniformly distributed on a unit sphere, and call the given <code>callback</code> for each sample generated.
|
||||||
|
* <p>
|
||||||
|
* Reference: <a href="http://mathworld.wolfram.com/SpherePointPicking.html">http://mathworld.wolfram.com/</a>
|
||||||
|
*
|
||||||
|
* @param numSamples
|
||||||
|
* the number of samples to generate
|
||||||
|
* @param callback
|
||||||
|
* will be called for each sample generated
|
||||||
|
*/
|
||||||
|
public void generate(int numSamples, Callback3d callback) {
|
||||||
|
for (int i = 0; i < numSamples;) {
|
||||||
|
float x1 = rnd.nextFloat() * 2.0f - 1.0f;
|
||||||
|
float x2 = rnd.nextFloat() * 2.0f - 1.0f;
|
||||||
|
if (x1 * x1 + x2 * x2 >= 1.0f)
|
||||||
|
continue;
|
||||||
|
float sqrt = (float) Math.sqrt(1.0 - x1 * x1 - x2 * x2);
|
||||||
|
float x = 2 * x1 * sqrt;
|
||||||
|
float y = 2 * x2 * sqrt;
|
||||||
|
float z = 1.0f - 2.0f * (x1 * x1 + x2 * x2);
|
||||||
|
callback.onNewSample(x, y, z);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body bgcolor="white">
|
||||||
|
<p>Contains classes for generating sampling patterns.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Reference in a new issue