hytale-server/com/hypixel/hytale/procedurallib/condition/NoiseHeightThresholdInterpr...

132 lines
3.9 KiB
Java

package com.hypixel.hytale.procedurallib.condition;
import com.hypixel.hytale.procedurallib.property.NoiseProperty;
import java.util.Arrays;
import javax.annotation.Nonnull;
public class NoiseHeightThresholdInterpreter implements IHeightThresholdInterpreter {
protected final NoiseProperty noise;
@Nonnull
protected final float[] keys;
@Nonnull
protected final IHeightThresholdInterpreter[] values;
protected final int length;
protected final int lowestNonOne;
protected final int highestNonZero;
public NoiseHeightThresholdInterpreter(NoiseProperty noise, @Nonnull float[] keys, @Nonnull IHeightThresholdInterpreter[] values) {
if (keys.length != values.length) {
throw new IllegalStateException("Length of keys and values are different!");
} else {
checkInterpreterLength(values);
this.noise = noise;
this.keys = keys;
this.values = values;
this.length = values[0].getLength();
int lowestNonOne = 0;
for (IHeightThresholdInterpreter value : values) {
if (value.getLowestNonOne() < lowestNonOne) {
lowestNonOne = value.getLowestNonOne();
}
}
this.lowestNonOne = lowestNonOne;
int highestNonZero = this.length - 1;
for (IHeightThresholdInterpreter valuex : values) {
if (valuex.getHighestNonZero() > highestNonZero) {
highestNonZero = valuex.getHighestNonZero();
}
}
this.highestNonZero = highestNonZero;
}
}
@Override
public int getLowestNonOne() {
return this.lowestNonOne;
}
@Override
public int getHighestNonZero() {
return this.highestNonZero;
}
protected double noise(int seed, double x, double y) {
return this.noise.get(seed, x, y);
}
@Override
public double getContext(int seed, double x, double y) {
return this.noise(seed, x, y);
}
@Override
public int getLength() {
return this.length;
}
@Override
public float getThreshold(int seed, double x, double z, int height) {
return this.getThreshold(seed, x, z, height, this.getContext(seed, x, z));
}
@Override
public float getThreshold(int seed, double x, double z, int height, double context) {
if (height > this.highestNonZero) {
return 0.0F;
} else {
int length = this.keys.length;
for (int i = 0; i < length; i++) {
if (context <= this.keys[i]) {
if (i == 0) {
return this.values[0].getThreshold(seed, x, z, height);
}
float distance = ((float)context - this.keys[i - 1]) / (this.keys[i] - this.keys[i - 1]);
return IHeightThresholdInterpreter.lerp(
this.values[i - 1].getThreshold(seed, x, z, height), this.values[i].getThreshold(seed, x, z, height), distance
);
}
}
return this.values[length - 1].getThreshold(seed, x, z, height);
}
}
static float lerp(float from, float to, float t) {
return from + (to - from) * t;
}
private static void checkInterpreterLength(@Nonnull IHeightThresholdInterpreter[] values) {
int length = values[0].getLength();
for (int i = 1; i < values.length; i++) {
if (values[i].getLength() != length) {
throw new IllegalStateException("ThresholdKeyInterpreter have different size!");
}
}
}
@Nonnull
@Override
public String toString() {
return "NoiseHeightThresholdInterpreter{noise="
+ this.noise
+ ", keys="
+ Arrays.toString(this.keys)
+ ", values="
+ Arrays.toString((Object[])this.values)
+ ", length="
+ this.length
+ ", lowestNonOne="
+ this.lowestNonOne
+ ", highestNonZero="
+ this.highestNonZero
+ "}";
}
}