minecraft-src/net/minecraft/util/Mth.java
2025-07-04 02:49:36 +03:00

878 lines
26 KiB
Java

package net.minecraft.util;
import java.util.Locale;
import java.util.UUID;
import java.util.function.IntPredicate;
import java.util.stream.IntStream;
import net.minecraft.Util;
import net.minecraft.core.Vec3i;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.apache.commons.lang3.math.Fraction;
import org.apache.commons.lang3.math.NumberUtils;
import org.joml.Quaternionf;
import org.joml.Vector3f;
public class Mth {
private static final long UUID_VERSION = 61440L;
private static final long UUID_VERSION_TYPE_4 = 16384L;
private static final long UUID_VARIANT = -4611686018427387904L;
private static final long UUID_VARIANT_2 = Long.MIN_VALUE;
public static final float PI = (float) Math.PI;
public static final float HALF_PI = (float) (Math.PI / 2);
public static final float TWO_PI = (float) (Math.PI * 2);
public static final float DEG_TO_RAD = (float) (Math.PI / 180.0);
public static final float RAD_TO_DEG = 180.0F / (float)Math.PI;
public static final float EPSILON = 1.0E-5F;
public static final float SQRT_OF_TWO = sqrt(2.0F);
private static final float SIN_SCALE = 10430.378F;
public static final Vector3f Y_AXIS = new Vector3f(0.0F, 1.0F, 0.0F);
public static final Vector3f X_AXIS = new Vector3f(1.0F, 0.0F, 0.0F);
public static final Vector3f Z_AXIS = new Vector3f(0.0F, 0.0F, 1.0F);
private static final float[] SIN = Util.make(new float[65536], fs -> {
for (int ix = 0; ix < fs.length; ix++) {
fs[ix] = (float)Math.sin(ix * Math.PI * 2.0 / 65536.0);
}
});
private static final RandomSource RANDOM = RandomSource.createThreadSafe();
/**
* Though it looks like an array, this is really more like a mapping. Key (index of this array) is the upper 5 bits of the result of multiplying a 32-bit unsigned integer by the B(2, 5) De Bruijn sequence 0x077CB531. Value (value stored in the array) is the unique index (from the right) of the leftmo
*/
private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
private static final double ONE_SIXTH = 0.16666666666666666;
private static final int FRAC_EXP = 8;
private static final int LUT_SIZE = 257;
private static final double FRAC_BIAS = Double.longBitsToDouble(4805340802404319232L);
private static final double[] ASIN_TAB = new double[257];
private static final double[] COS_TAB = new double[257];
/**
* sin looked up in a table
*/
public static float sin(float value) {
return SIN[(int)(value * 10430.378F) & 65535];
}
/**
* cos looked up in the sin table with the appropriate offset
*/
public static float cos(float value) {
return SIN[(int)(value * 10430.378F + 16384.0F) & 65535];
}
public static float sqrt(float value) {
return (float)Math.sqrt(value);
}
/**
* {@return the greatest integer less than or equal to the float argument}
*/
public static int floor(float value) {
int i = (int)value;
return value < i ? i - 1 : i;
}
/**
* {@return the greatest integer less than or equal to the double argument}
*/
public static int floor(double value) {
int i = (int)value;
return value < i ? i - 1 : i;
}
/**
* Long version of floor()
*/
public static long lfloor(double value) {
long l = (long)value;
return value < l ? l - 1L : l;
}
public static float abs(float value) {
return Math.abs(value);
}
/**
* {@return the unsigned value of an int}
*/
public static int abs(int value) {
return Math.abs(value);
}
public static int ceil(float value) {
int i = (int)value;
return value > i ? i + 1 : i;
}
public static int ceil(double value) {
int i = (int)value;
return value > i ? i + 1 : i;
}
/**
* {@return the given value if between the lower and the upper bound. If the value is less than the lower bound, returns the lower bound} If the value is greater than the upper bound, returns the upper bound.
*
* @param value The value that is clamped.
* @param min The lower bound for the clamp.
* @param max The upper bound for the clamp.
*/
public static int clamp(int value, int min, int max) {
return Math.min(Math.max(value, min), max);
}
public static long clamp(long value, long min, long max) {
return Math.min(Math.max(value, min), max);
}
/**
* {@return the given value if between the lower and the upper bound. If the value is less than the lower bound, returns the lower bound} If the value is greater than the upper bound, returns the upper bound.
*
* @param value The value that is clamped.
* @param min The lower bound for the clamp.
* @param max The upper bound for the clamp.
*/
public static float clamp(float value, float min, float max) {
return value < min ? min : Math.min(value, max);
}
/**
* {@return the given value if between the lower and the upper bound. If the value is less than the lower bound, returns the lower bound} If the value is greater than the upper bound, returns the upper bound.
*
* @param value The value that is clamped.
* @param min The lower bound for the clamp.
* @param max The upper bound for the clamp.
*/
public static double clamp(double value, double min, double max) {
return value < min ? min : Math.min(value, max);
}
/**
* Method for linear interpolation of doubles.
*
* @param start Start value for the lerp.
* @param end End value for the lerp.
* @param delta A value between 0 and 1 that indicates the percentage of the lerp. (0 will give the start value and 1 will give the end value) If the value is not between 0 and 1, it is clamped.
*/
public static double clampedLerp(double start, double end, double delta) {
if (delta < 0.0) {
return start;
} else {
return delta > 1.0 ? end : lerp(delta, start, end);
}
}
/**
* Method for linear interpolation of floats.
*
* @param start Start value for the lerp.
* @param end End value for the lerp.
* @param delta A value between 0 and 1 that indicates the percentage of the lerp. (0 will give the start value and 1 will give the end value) If the value is not between 0 and 1, it is clamped.
*/
public static float clampedLerp(float start, float end, float delta) {
if (delta < 0.0F) {
return start;
} else {
return delta > 1.0F ? end : lerp(delta, start, end);
}
}
/**
* {@return the maximum of the absolute value of two numbers}
*/
public static double absMax(double x, double y) {
if (x < 0.0) {
x = -x;
}
if (y < 0.0) {
y = -y;
}
return Math.max(x, y);
}
public static int floorDiv(int dividend, int divisor) {
return Math.floorDiv(dividend, divisor);
}
public static int nextInt(RandomSource random, int minimum, int maximum) {
return minimum >= maximum ? minimum : random.nextInt(maximum - minimum + 1) + minimum;
}
public static float nextFloat(RandomSource random, float minimum, float maximum) {
return minimum >= maximum ? minimum : random.nextFloat() * (maximum - minimum) + minimum;
}
public static double nextDouble(RandomSource random, double minimum, double maximum) {
return minimum >= maximum ? minimum : random.nextDouble() * (maximum - minimum) + minimum;
}
public static boolean equal(float x, float y) {
return Math.abs(y - x) < 1.0E-5F;
}
public static boolean equal(double x, double y) {
return Math.abs(y - x) < 1.0E-5F;
}
public static int positiveModulo(int x, int y) {
return Math.floorMod(x, y);
}
public static float positiveModulo(float numerator, float denominator) {
return (numerator % denominator + denominator) % denominator;
}
public static double positiveModulo(double numerator, double denominator) {
return (numerator % denominator + denominator) % denominator;
}
public static boolean isMultipleOf(int number, int multiple) {
return number % multiple == 0;
}
public static byte packDegrees(float degrees) {
return (byte)floor(degrees * 256.0F / 360.0F);
}
public static float unpackDegrees(byte degrees) {
return degrees * 360 / 256.0F;
}
/**
* Adjust the angle so that its value is in the range [-180;180)
*/
public static int wrapDegrees(int angle) {
int i = angle % 360;
if (i >= 180) {
i -= 360;
}
if (i < -180) {
i += 360;
}
return i;
}
public static float wrapDegrees(long angle) {
float f = (float)(angle % 360L);
if (f >= 180.0F) {
f -= 360.0F;
}
if (f < -180.0F) {
f += 360.0F;
}
return f;
}
/**
* The angle is reduced to an angle between -180 and +180 by mod, and a 360 check.
*/
public static float wrapDegrees(float value) {
float f = value % 360.0F;
if (f >= 180.0F) {
f -= 360.0F;
}
if (f < -180.0F) {
f += 360.0F;
}
return f;
}
/**
* The angle is reduced to an angle between -180 and +180 by mod, and a 360 check.
*/
public static double wrapDegrees(double value) {
double d = value % 360.0;
if (d >= 180.0) {
d -= 360.0;
}
if (d < -180.0) {
d += 360.0;
}
return d;
}
/**
* {@return the difference between two angles in degrees}
*/
public static float degreesDifference(float start, float end) {
return wrapDegrees(end - start);
}
/**
* {@return the absolute of the difference between two angles in degrees}
*/
public static float degreesDifferenceAbs(float start, float end) {
return abs(degreesDifference(start, end));
}
/**
* Takes a rotation and compares it to another rotation.
* If the difference is greater than a given maximum, clamps the original rotation between to have at most the given difference to the actual rotation.
* This is used to match the body rotation of entities to their head rotation.
* @return The new value for the rotation that was adjusted
*/
public static float rotateIfNecessary(float rotationToAdjust, float actualRotation, float maxDifference) {
float f = degreesDifference(rotationToAdjust, actualRotation);
float g = clamp(f, -maxDifference, maxDifference);
return actualRotation - g;
}
/**
* Changes value by stepSize towards the limit and returns the result.
* If value is smaller than limit, the result will never be bigger than limit.
* If value is bigger than limit, the result will never be smaller than limit.
*/
public static float approach(float value, float limit, float stepSize) {
stepSize = abs(stepSize);
return value < limit ? clamp(value + stepSize, value, limit) : clamp(value - stepSize, limit, value);
}
/**
* Changes the angle by stepSize towards the limit in the direction where the distance is smaller.
* {@see #approach(float, float, float)}
*/
public static float approachDegrees(float angle, float limit, float stepSize) {
float f = degreesDifference(angle, limit);
return approach(angle, angle + f, stepSize);
}
/**
* Parses the string as an integer or returns the second parameter if it fails.
*/
public static int getInt(String value, int defaultValue) {
return NumberUtils.toInt(value, defaultValue);
}
/**
* {@return the input value rounded up to the next highest power of two}
*/
public static int smallestEncompassingPowerOfTwo(int value) {
int i = value - 1;
i |= i >> 1;
i |= i >> 2;
i |= i >> 4;
i |= i >> 8;
i |= i >> 16;
return i + 1;
}
/**
* Is the given value a power of two? (1, 2, 4, 8, 16, ...)
*/
public static boolean isPowerOfTwo(int value) {
return value != 0 && (value & value - 1) == 0;
}
/**
* Uses a B(2, 5) De Bruijn sequence and a lookup table to efficiently calculate the log-base-two of the given value. Optimized for cases where the input value is a power-of-two. If the input value is not a power-of-two, then subtract 1 from the return value.
*/
public static int ceillog2(int value) {
value = isPowerOfTwo(value) ? value : smallestEncompassingPowerOfTwo(value);
return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int)(value * 125613361L >> 27) & 31];
}
/**
* Efficiently calculates the floor of the base-2 log of an integer value. This is effectively the index of the highest bit that is set. For example, if the number in binary is 0...100101, this will return 5.
*/
public static int log2(int value) {
return ceillog2(value) - (isPowerOfTwo(value) ? 0 : 1);
}
public static float frac(float number) {
return number - floor(number);
}
/**
* Gets the decimal portion of the given double. For instance, {@code frac(5.5)} returns {@code .5}.
*/
public static double frac(double number) {
return number - lfloor(number);
}
@Deprecated
public static long getSeed(Vec3i pos) {
return getSeed(pos.getX(), pos.getY(), pos.getZ());
}
@Deprecated
public static long getSeed(int x, int y, int z) {
long l = x * 3129871 ^ z * 116129781L ^ y;
l = l * l * 42317861L + l * 11L;
return l >> 16;
}
public static UUID createInsecureUUID(RandomSource random) {
long l = random.nextLong() & -61441L | 16384L;
long m = random.nextLong() & 4611686018427387903L | Long.MIN_VALUE;
return new UUID(l, m);
}
/**
* Generates a random UUID using the shared random
*/
public static UUID createInsecureUUID() {
return createInsecureUUID(RANDOM);
}
public static double inverseLerp(double delta, double start, double end) {
return (delta - start) / (end - start);
}
public static float inverseLerp(float delta, float start, float end) {
return (delta - start) / (end - start);
}
public static boolean rayIntersectsAABB(Vec3 start, Vec3 end, AABB boundingBox) {
double d = (boundingBox.minX + boundingBox.maxX) * 0.5;
double e = (boundingBox.maxX - boundingBox.minX) * 0.5;
double f = start.x - d;
if (Math.abs(f) > e && f * end.x >= 0.0) {
return false;
} else {
double g = (boundingBox.minY + boundingBox.maxY) * 0.5;
double h = (boundingBox.maxY - boundingBox.minY) * 0.5;
double i = start.y - g;
if (Math.abs(i) > h && i * end.y >= 0.0) {
return false;
} else {
double j = (boundingBox.minZ + boundingBox.maxZ) * 0.5;
double k = (boundingBox.maxZ - boundingBox.minZ) * 0.5;
double l = start.z - j;
if (Math.abs(l) > k && l * end.z >= 0.0) {
return false;
} else {
double m = Math.abs(end.x);
double n = Math.abs(end.y);
double o = Math.abs(end.z);
double p = end.y * l - end.z * i;
if (Math.abs(p) > h * o + k * n) {
return false;
} else {
p = end.z * f - end.x * l;
if (Math.abs(p) > e * o + k * m) {
return false;
} else {
p = end.x * i - end.y * f;
return Math.abs(p) < e * n + h * m;
}
}
}
}
}
}
public static double atan2(double y, double x) {
double d = x * x + y * y;
if (Double.isNaN(d)) {
return Double.NaN;
} else {
boolean bl = y < 0.0;
if (bl) {
y = -y;
}
boolean bl2 = x < 0.0;
if (bl2) {
x = -x;
}
boolean bl3 = y > x;
if (bl3) {
double e = x;
x = y;
y = e;
}
double e = fastInvSqrt(d);
x *= e;
y *= e;
double f = FRAC_BIAS + y;
int i = (int)Double.doubleToRawLongBits(f);
double g = ASIN_TAB[i];
double h = COS_TAB[i];
double j = f - FRAC_BIAS;
double k = y * h - x * j;
double l = (6.0 + k * k) * k * 0.16666666666666666;
double m = g + l;
if (bl3) {
m = (Math.PI / 2) - m;
}
if (bl2) {
m = Math.PI - m;
}
if (bl) {
m = -m;
}
return m;
}
}
public static float invSqrt(float number) {
return org.joml.Math.invsqrt(number);
}
public static double invSqrt(double number) {
return org.joml.Math.invsqrt(number);
}
/**
* Computes 1/sqrt(n) using <a href="https://en.wikipedia.org/wiki/Fast_inverse_square_root">the fast inverse square root</a> with a constant of 0x5FE6EB50C7B537AA.
*/
@Deprecated
public static double fastInvSqrt(double number) {
double d = 0.5 * number;
long l = Double.doubleToRawLongBits(number);
l = 6910469410427058090L - (l >> 1);
number = Double.longBitsToDouble(l);
return number * (1.5 - d * number * number);
}
public static float fastInvCubeRoot(float number) {
int i = Float.floatToIntBits(number);
i = 1419967116 - i / 3;
float f = Float.intBitsToFloat(i);
f = 0.6666667F * f + 1.0F / (3.0F * f * f * number);
return 0.6666667F * f + 1.0F / (3.0F * f * f * number);
}
public static int hsvToRgb(float hue, float saturation, float value) {
return hsvToArgb(hue, saturation, value, 0);
}
public static int hsvToArgb(float hue, float saturation, float value, int alpha) {
int i = (int)(hue * 6.0F) % 6;
float f = hue * 6.0F - i;
float g = value * (1.0F - saturation);
float h = value * (1.0F - f * saturation);
float j = value * (1.0F - (1.0F - f) * saturation);
float k;
float l;
float m;
switch (i) {
case 0:
k = value;
l = j;
m = g;
break;
case 1:
k = h;
l = value;
m = g;
break;
case 2:
k = g;
l = value;
m = j;
break;
case 3:
k = g;
l = h;
m = value;
break;
case 4:
k = j;
l = g;
m = value;
break;
case 5:
k = value;
l = g;
m = h;
break;
default:
throw new RuntimeException("Something went wrong when converting from HSV to RGB. Input was " + hue + ", " + saturation + ", " + value);
}
return ARGB.color(alpha, clamp((int)(k * 255.0F), 0, 255), clamp((int)(l * 255.0F), 0, 255), clamp((int)(m * 255.0F), 0, 255));
}
public static int murmurHash3Mixer(int input) {
input ^= input >>> 16;
input *= -2048144789;
input ^= input >>> 13;
input *= -1028477387;
return input ^ input >>> 16;
}
public static int binarySearch(int min, int max, IntPredicate isTargetBeforeOrAt) {
int i = max - min;
while (i > 0) {
int j = i / 2;
int k = min + j;
if (isTargetBeforeOrAt.test(k)) {
i = j;
} else {
min = k + 1;
i -= j + 1;
}
}
return min;
}
public static int lerpInt(float delta, int start, int end) {
return start + floor(delta * (end - start));
}
public static int lerpDiscrete(float delta, int start, int end) {
int i = end - start;
return start + floor(delta * (i - 1)) + (delta > 0.0F ? 1 : 0);
}
/**
* Method for linear interpolation of floats
*
* @param delta A value usually between 0 and 1 that indicates the percentage of the lerp. (0 will give the start value and 1 will give the end value)
* @param start Start value for the lerp
* @param end End value for the lerp
*/
public static float lerp(float delta, float start, float end) {
return start + delta * (end - start);
}
public static Vec3 lerp(double delta, Vec3 start, Vec3 end) {
return new Vec3(lerp(delta, start.x, end.x), lerp(delta, start.y, end.y), lerp(delta, start.z, end.z));
}
/**
* Method for linear interpolation of doubles
*
* @param delta A value usually between 0 and 1 that indicates the percentage of the lerp. (0 will give the start value and 1 will give the end value)
* @param start Start value for the lerp
* @param end End value for the lerp
*/
public static double lerp(double delta, double start, double end) {
return start + delta * (end - start);
}
public static double lerp2(double delta1, double delta2, double start1, double end1, double start2, double end2) {
return lerp(delta2, lerp(delta1, start1, end1), lerp(delta1, start2, end2));
}
public static double lerp3(
double delta1, double delta2, double delta3, double start1, double end1, double start2, double end2, double start3, double end3, double start4, double end4
) {
return lerp(delta3, lerp2(delta1, delta2, start1, end1, start2, end2), lerp2(delta1, delta2, start3, end3, start4, end4));
}
public static float catmullrom(float delta, float controlPoint1, float controlPoint2, float controlPoint3, float controlPoint4) {
return 0.5F
* (
2.0F * controlPoint2
+ (controlPoint3 - controlPoint1) * delta
+ (2.0F * controlPoint1 - 5.0F * controlPoint2 + 4.0F * controlPoint3 - controlPoint4) * delta * delta
+ (3.0F * controlPoint2 - controlPoint1 - 3.0F * controlPoint3 + controlPoint4) * delta * delta * delta
);
}
public static double smoothstep(double input) {
return input * input * input * (input * (input * 6.0 - 15.0) + 10.0);
}
public static double smoothstepDerivative(double input) {
return 30.0 * input * input * (input - 1.0) * (input - 1.0);
}
public static int sign(double x) {
if (x == 0.0) {
return 0;
} else {
return x > 0.0 ? 1 : -1;
}
}
/**
* Linearly interpolates an angle between the start between the start and end values given as degrees.
*
* @param delta A value between 0 and 1 that indicates the percentage of the lerp. (0 will give the start value and 1 will give the end value)
*/
public static float rotLerp(float delta, float start, float end) {
return start + delta * wrapDegrees(end - start);
}
public static double rotLerp(double delta, double start, double end) {
return start + delta * wrapDegrees(end - start);
}
public static float rotLerpRad(float delta, float start, float end) {
float f = end - start;
while (f < (float) -Math.PI) {
f += (float) (Math.PI * 2);
}
while (f >= (float) Math.PI) {
f -= (float) (Math.PI * 2);
}
return start + delta * f;
}
public static float triangleWave(float input, float period) {
return (Math.abs(input % period - period * 0.5F) - period * 0.25F) / (period * 0.25F);
}
public static float square(float value) {
return value * value;
}
public static double square(double value) {
return value * value;
}
public static int square(int value) {
return value * value;
}
public static long square(long value) {
return value * value;
}
public static double clampedMap(double input, double inputMin, double inputMax, double ouputMin, double outputMax) {
return clampedLerp(ouputMin, outputMax, inverseLerp(input, inputMin, inputMax));
}
public static float clampedMap(float input, float inputMin, float inputMax, float outputMin, float outputMax) {
return clampedLerp(outputMin, outputMax, inverseLerp(input, inputMin, inputMax));
}
public static double map(double input, double inputMin, double inputMax, double outputMin, double outputMax) {
return lerp(inverseLerp(input, inputMin, inputMax), outputMin, outputMax);
}
public static float map(float input, float inputMin, float inputMax, float outputMin, float outputMax) {
return lerp(inverseLerp(input, inputMin, inputMax), outputMin, outputMax);
}
public static double wobble(double input) {
return input + (2.0 * RandomSource.create(floor(input * 3000.0)).nextDouble() - 1.0) * 1.0E-7 / 2.0;
}
/**
* Rounds the given value up to a multiple of factor.
* @return The smallest integer multiple of factor that is greater than or equal to the value
*/
public static int roundToward(int value, int factor) {
return positiveCeilDiv(value, factor) * factor;
}
/**
* Returns the smallest (closest to negative infinity) int value that is greater than or equal to the algebraic quotient.
* @see java.lang.Math#floorDiv(int, int)
*/
public static int positiveCeilDiv(int x, int y) {
return -Math.floorDiv(-x, y);
}
public static int randomBetweenInclusive(RandomSource random, int minInclusive, int maxInclusive) {
return random.nextInt(maxInclusive - minInclusive + 1) + minInclusive;
}
public static float randomBetween(RandomSource random, float minInclusive, float maxExclusive) {
return random.nextFloat() * (maxExclusive - minInclusive) + minInclusive;
}
/**
* Generates a value from a normal distribution with the given mean and deviation.
*/
public static float normal(RandomSource random, float mean, float deviation) {
return mean + (float)random.nextGaussian() * deviation;
}
public static double lengthSquared(double xDistance, double yDistance) {
return xDistance * xDistance + yDistance * yDistance;
}
public static double length(double xDistance, double yDistance) {
return Math.sqrt(lengthSquared(xDistance, yDistance));
}
public static float length(float xDistance, float yDistance) {
return (float)Math.sqrt(lengthSquared(xDistance, yDistance));
}
public static double lengthSquared(double xDistance, double yDistance, double zDistance) {
return xDistance * xDistance + yDistance * yDistance + zDistance * zDistance;
}
public static double length(double xDistance, double yDistance, double zDistance) {
return Math.sqrt(lengthSquared(xDistance, yDistance, zDistance));
}
public static float lengthSquared(float xDistance, float yDistance, float zDistance) {
return xDistance * xDistance + yDistance * yDistance + zDistance * zDistance;
}
/**
* Gets the value closest to zero that is not closer to zero than the given value and is a multiple of the factor.
*/
public static int quantize(double value, int factor) {
return floor(value / factor) * factor;
}
public static IntStream outFromOrigin(int input, int lowerBound, int upperBound) {
return outFromOrigin(input, lowerBound, upperBound, 1);
}
public static IntStream outFromOrigin(int input, int lowerBound, int upperBound, int steps) {
if (lowerBound > upperBound) {
throw new IllegalArgumentException(String.format(Locale.ROOT, "upperbound %d expected to be > lowerBound %d", upperBound, lowerBound));
} else if (steps < 1) {
throw new IllegalArgumentException(String.format(Locale.ROOT, "steps expected to be >= 1, was %d", steps));
} else {
return input >= lowerBound && input <= upperBound ? IntStream.iterate(input, l -> {
int m = Math.abs(input - l);
return input - m >= lowerBound || input + m <= upperBound;
}, m -> {
boolean bl = m <= input;
int n = Math.abs(input - m);
boolean bl2 = input + n + steps <= upperBound;
if (!bl || !bl2) {
int o = input - n - (bl ? steps : 0);
if (o >= lowerBound) {
return o;
}
}
return input + n + steps;
}) : IntStream.empty();
}
}
public static Quaternionf rotationAroundAxis(Vector3f axis, Quaternionf cameraOrentation, Quaternionf output) {
float f = axis.dot(cameraOrentation.x, cameraOrentation.y, cameraOrentation.z);
return output.set(axis.x * f, axis.y * f, axis.z * f, cameraOrentation.w).normalize();
}
public static int mulAndTruncate(Fraction fraction, int factor) {
return fraction.getNumerator() * factor / fraction.getDenominator();
}
public static float easeInOutSine(float value) {
return -(cos((float) Math.PI * value) - 1.0F) / 2.0F;
}
static {
for (int i = 0; i < 257; i++) {
double d = i / 256.0;
double e = Math.asin(d);
COS_TAB[i] = Math.cos(e);
ASIN_TAB[i] = e;
}
}
}