mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-05-20 08:40:26 +00:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 839f429806 | |||
| e533180dab | |||
| 40b9c6c08c | |||
| c8c9247dfe | |||
| 7f8749239f | |||
| 2b84967e05 | |||
| 6446f9b4a7 | |||
| 5933f97f93 | |||
| d670fc904f | |||
| 33371675e1 | |||
| bd91506069 | |||
| 393a92730f | |||
| 5ff016ea1f | |||
| 84b8df6d96 | |||
| 353999aa45 | |||
| 4a4e7e42cc | |||
| 06cd1dc562 | |||
| 48296fb14a | |||
| b3a4c3af19 | |||
| c0773be780 | |||
| 79df7eed21 | |||
| 14ce12f08e | |||
| 7cfa96f925 | |||
| 4131b45c6f | |||
| 4bf31d863e | |||
| 92db30e181 | |||
| 0f152f9281 | |||
| 7ca779f845 | |||
| 76a2d08906 | |||
| 161b047c39 | |||
| 8309ad665e | |||
| b6e414f944 | |||
| 36db83b253 | |||
| c4e641069d | |||
| 5e40fbbf07 | |||
| 8a47a01dd8 | |||
| e41587dbd9 | |||
| d5de91a864 | |||
| f8cf61e281 | |||
| 7323b051db | |||
| 72f86e68e8 | |||
| 5f9b21ea09 | |||
| dd44839bd3 | |||
| b8cec40317 | |||
| 19f781af31 | |||
| af825761c7 | |||
| 490fed8c2c | |||
| 85efa44673 | |||
| 985443e228 | |||
| a2f3752c31 | |||
| 7418d67b09 | |||
| 565266992f | |||
| d05fdeb94c | |||
| 01d0d4c00a | |||
| d65c700bb9 |
+1
-1
@@ -1,6 +1,6 @@
|
||||
import com.dfsek.terra.getGitHash
|
||||
|
||||
val versionObj = Version("4", "0", "0", true)
|
||||
val versionObj = Version("4", "3", "0", true)
|
||||
|
||||
allprojects {
|
||||
version = versionObj
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.gradle.kotlin.dsl.repositories
|
||||
fun Project.configureDependencies() {
|
||||
|
||||
repositories {
|
||||
maven { url = uri("https://papermc.io/repo/repository/maven-public/") }
|
||||
maven { url = uri("http://maven.enginehub.org/repo/") }
|
||||
maven { url = uri("https://repo.codemc.org/repository/maven-public") }
|
||||
maven { url = uri("https://papermc.io/repo/repository/maven-public/") }
|
||||
|
||||
@@ -13,10 +13,11 @@ dependencies {
|
||||
"shadedApi"("org.apache.commons:commons-rng-core:1.3")
|
||||
"shadedApi"("commons-io:commons-io:2.4")
|
||||
|
||||
"shadedApi"("com.scireum:parsii:1.2.1")
|
||||
"shadedApi"("com.dfsek:Paralithic:0.3.2")
|
||||
"shadedApi"("com.dfsek:Tectonic:1.2.3")
|
||||
"shadedApi"("net.jafama:jafama:2.3.2")
|
||||
"shadedApi"("org.yaml:snakeyaml:1.27")
|
||||
"shadedApi"("org.ow2.asm:asm:9.0")
|
||||
|
||||
"compileOnly"("com.googlecode.json-simple:json-simple:1.1")
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.dfsek.terra.api.core;
|
||||
|
||||
import com.dfsek.terra.api.LoaderRegistrar;
|
||||
import com.dfsek.terra.api.core.event.EventManager;
|
||||
import com.dfsek.terra.api.platform.handle.ItemHandle;
|
||||
import com.dfsek.terra.api.platform.handle.WorldHandle;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.config.PluginConfig;
|
||||
import com.dfsek.terra.config.lang.Language;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.debug.DebugLogger;
|
||||
import com.dfsek.terra.registry.ConfigRegistry;
|
||||
import com.dfsek.terra.world.TerraWorld;
|
||||
@@ -41,13 +41,8 @@ public interface TerraPlugin extends LoaderRegistrar {
|
||||
|
||||
String platformName();
|
||||
|
||||
default void packPreLoadCallback(ConfigPack pack) {
|
||||
|
||||
}
|
||||
|
||||
default void packPostLoadCallback(ConfigPack pack) {
|
||||
|
||||
}
|
||||
|
||||
DebugLogger getDebugLogger();
|
||||
|
||||
EventManager getEventManager();
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
package com.dfsek.terra.api.core.event;
|
||||
|
||||
public interface Event {
|
||||
}
|
||||
@@ -1,7 +1,14 @@
|
||||
package com.dfsek.terra.api.core.event;
|
||||
|
||||
import com.dfsek.terra.api.core.event.events.Event;
|
||||
|
||||
public interface EventManager {
|
||||
void callEvent(Event event);
|
||||
/**
|
||||
* Call an event, and return the execution status.
|
||||
* @param event Event to pass to all registered EventListeners.
|
||||
* @return False if the event is cancellable and has been cancelled, otherwise true.
|
||||
*/
|
||||
boolean callEvent(Event event);
|
||||
|
||||
void registerListener(EventListener listener);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.dfsek.terra.api.core.event;
|
||||
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.core.event.annotations.Priority;
|
||||
import com.dfsek.terra.api.core.event.events.Cancellable;
|
||||
import com.dfsek.terra.api.core.event.events.Event;
|
||||
import com.dfsek.terra.api.util.ReflectionUtil;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TerraEventManager implements EventManager {
|
||||
private final Map<Class<? extends Event>, List<ListenerHolder>> listeners = new HashMap<>();
|
||||
private final TerraPlugin main;
|
||||
|
||||
public TerraEventManager(TerraPlugin main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean callEvent(Event event) {
|
||||
listeners.getOrDefault(event.getClass(), Collections.emptyList()).forEach(listenerHolder -> {
|
||||
try {
|
||||
listenerHolder.method.invoke(listenerHolder.listener, event);
|
||||
} catch(InvocationTargetException e) {
|
||||
StringWriter writer = new StringWriter();
|
||||
e.getTargetException().printStackTrace(new PrintWriter(writer));
|
||||
main.getLogger().warning("Exception occurred during event handling:");
|
||||
main.getLogger().warning(writer.toString());
|
||||
main.getLogger().warning("Report this to the maintainers of " + listenerHolder.method.getName());
|
||||
} catch(Exception e) {
|
||||
StringWriter writer = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(writer));
|
||||
main.getLogger().warning("Exception occurred during event handling:");
|
||||
main.getLogger().warning(writer.toString());
|
||||
main.getLogger().warning("Report this to the maintainers of " + listenerHolder.method.getName());
|
||||
}
|
||||
}
|
||||
);
|
||||
if(event instanceof Cancellable) return !((Cancellable) event).isCancelled();
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void registerListener(EventListener listener) {
|
||||
Class<? extends EventListener> listenerClass = listener.getClass();
|
||||
Method[] methods = ReflectionUtil.getMethods(listenerClass);
|
||||
|
||||
for(Method method : methods) {
|
||||
if(method.getParameterCount() != 1) continue; // Check that parameter count is only 1.
|
||||
Class<?> eventParam = method.getParameterTypes()[0];
|
||||
if(!Event.class.isAssignableFrom(eventParam)) continue; // Check that parameter is an Event.
|
||||
|
||||
Priority p = method.getAnnotation(Priority.class);
|
||||
|
||||
int priority = p == null ? 0 : p.value();
|
||||
|
||||
method.setAccessible(true);
|
||||
|
||||
List<ListenerHolder> holders = listeners.computeIfAbsent((Class<? extends Event>) eventParam, e -> new ArrayList<>());
|
||||
|
||||
holders.add(new ListenerHolder(method, listener, priority));
|
||||
|
||||
holders.sort(Comparator.comparingInt(ListenerHolder::getPriority)); // Sort priorities.
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ListenerHolder {
|
||||
private final Method method;
|
||||
private final EventListener listener;
|
||||
private final int priority;
|
||||
|
||||
private ListenerHolder(Method method, EventListener listener, int priority) {
|
||||
this.method = method;
|
||||
this.listener = listener;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public int getPriority() {
|
||||
return priority;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.dfsek.terra.api.core.event.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotated listener methods will have a specific priority set.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Priority {
|
||||
/**
|
||||
* Highest possible priority. Listeners with this priority will always be invoked first.
|
||||
*/
|
||||
int HIGHEST = Integer.MAX_VALUE;
|
||||
/**
|
||||
* Lowest possible priority. Listeners with this priority will always be invoked last.
|
||||
*/
|
||||
int LOWEST = Integer.MIN_VALUE;
|
||||
/**
|
||||
* Default priority.
|
||||
*/
|
||||
int NORMAL = 0;
|
||||
/**
|
||||
* High priority.
|
||||
*/
|
||||
int HIGH = 1;
|
||||
/**
|
||||
* Low Priority.
|
||||
*/
|
||||
int LOW = -1;
|
||||
/**
|
||||
* @return Priority of this event. Events are executed from lowest to highest priorities.
|
||||
*/
|
||||
int value();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.dfsek.terra.api.core.event.events;
|
||||
|
||||
/**
|
||||
* Events that implement this interface may be cancelled.
|
||||
*
|
||||
* Cancelling an event is assumed to stop the execution of whatever action triggered the event.
|
||||
*/
|
||||
public interface Cancellable extends Event {
|
||||
boolean isCancelled();
|
||||
void setCancelled();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.dfsek.terra.api.core.event.events;
|
||||
|
||||
public interface Event {
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.dfsek.terra.api.core.event.events.config;
|
||||
|
||||
import com.dfsek.terra.api.core.event.events.Event;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
|
||||
public abstract class ConfigPackLoadEvent implements Event {
|
||||
private final ConfigPack pack;
|
||||
|
||||
public ConfigPackLoadEvent(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
public ConfigPack getPack() {
|
||||
return pack;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.dfsek.terra.api.core.event.events.config;
|
||||
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
|
||||
/**
|
||||
* Called when a config pack has finished loading.
|
||||
*/
|
||||
public class ConfigPackPostLoadEvent extends ConfigPackLoadEvent {
|
||||
public ConfigPackPostLoadEvent(ConfigPack pack) {
|
||||
super(pack);
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.dfsek.terra.api.core.event.events.config;
|
||||
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
|
||||
/**
|
||||
* Called before a config pack's registries are filled. At this point, the pack manifest has been loaded, and all registries are empty.
|
||||
*/
|
||||
public class ConfigPackPreLoadEvent extends ConfigPackLoadEvent {
|
||||
public ConfigPackPreLoadEvent(ConfigPack pack) {
|
||||
super(pack);
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.dfsek.terra.api.core.event.events.world;
|
||||
|
||||
import com.dfsek.terra.api.core.event.events.Event;
|
||||
import com.dfsek.terra.world.TerraWorld;
|
||||
|
||||
/**
|
||||
* Called upon initialization of a TerraWorld.
|
||||
*/
|
||||
public class TerraWorldLoadEvent implements Event {
|
||||
private final TerraWorld world;
|
||||
|
||||
public TerraWorldLoadEvent(TerraWorld world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public TerraWorld getWorld() {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.dfsek.terra.api.math.noise.normalizer;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
public class ClampNormalizer extends Normalizer {
|
||||
private final double min;
|
||||
private final double max;
|
||||
|
||||
public ClampNormalizer(NoiseSampler sampler, double min, double max) {
|
||||
super(sampler);
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double normalize(double in) {
|
||||
return FastMath.max(FastMath.min(in, max), min);
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,4 @@ public abstract class Normalizer implements NoiseSampler {
|
||||
public double getNoiseSeeded(int seed, double x, double y, double z) {
|
||||
return normalize(sampler.getNoiseSeeded(seed, x, y, z));
|
||||
}
|
||||
|
||||
public enum NormalType {
|
||||
LINEAR, NORMAL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
|
||||
/**
|
||||
* Sampler implementation that returns a constant.
|
||||
*/
|
||||
public class ConstantSampler implements NoiseSampler {
|
||||
private final double constant;
|
||||
|
||||
public ConstantSampler(double constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoise(double x, double y) {
|
||||
return constant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoise(double x, double y, double z) {
|
||||
return constant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseSeeded(int seed, double x, double y) {
|
||||
return constant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseSeeded(int seed, double x, double y, double z) {
|
||||
return constant;
|
||||
}
|
||||
}
|
||||
+17
-32
@@ -1,73 +1,58 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers;
|
||||
|
||||
import com.dfsek.paralithic.Expression;
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.parsii.defined.UserDefinedFunction;
|
||||
import com.dfsek.terra.api.math.parsii.noise.NoiseFunction2;
|
||||
import com.dfsek.terra.api.math.parsii.noise.NoiseFunction3;
|
||||
import com.dfsek.terra.api.math.paralithic.defined.UserDefinedFunction;
|
||||
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction2;
|
||||
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction3;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Parser;
|
||||
import parsii.eval.Scope;
|
||||
import parsii.eval.Variable;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Sampler implementation using parsii expression
|
||||
* Sampler implementation using Paralithic expression
|
||||
*/
|
||||
public class ExpressionSampler implements NoiseSampler {
|
||||
private final Expression expression;
|
||||
private final Variable x;
|
||||
private final Variable y;
|
||||
private final Variable z;
|
||||
|
||||
public ExpressionSampler(String equation, Scope parent, long seed, Map<String, NoiseSeeded> functions, Map<String, FunctionTemplate> definedFunctions) throws ParseException {
|
||||
Parser parser = new Parser();
|
||||
Scope scope = new Scope().withParent(parent);
|
||||
|
||||
this.x = scope.create("x");
|
||||
this.y = scope.create("y");
|
||||
this.z = scope.create("z");
|
||||
scope.addInvocationVariable("x");
|
||||
scope.addInvocationVariable("y");
|
||||
scope.addInvocationVariable("z");
|
||||
|
||||
functions.forEach((id, noise) -> {
|
||||
switch(noise.getDimensions()) {
|
||||
case 2:
|
||||
parser.registerFunction(id, new NoiseFunction2(seed, noise));
|
||||
parser.registerFunction(id, new NoiseFunction2(noise.apply(seed)));
|
||||
break;
|
||||
case 3:
|
||||
parser.registerFunction(id, new NoiseFunction3(seed, noise));
|
||||
parser.registerFunction(id, new NoiseFunction3(noise.apply(seed)));
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
for(Map.Entry<String, FunctionTemplate> entry : definedFunctions.entrySet()) {
|
||||
String id = entry.getKey();
|
||||
FunctionTemplate fun = entry.getValue();
|
||||
|
||||
Scope functionScope = new Scope().withParent(parent);
|
||||
List<Variable> variables = fun.getArgs().stream().map(functionScope::create).collect(Collectors.toList());
|
||||
|
||||
parser.registerFunction(id, new UserDefinedFunction(parser.parse(fun.getFunction(), functionScope), variables));
|
||||
parser.registerFunction(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), parser, parent));
|
||||
}
|
||||
|
||||
this.expression = parser.parse(equation, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double getNoise(double x, double y) {
|
||||
public double getNoise(double x, double y) {
|
||||
return getNoise(x, 0, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double getNoise(double x, double y, double z) {
|
||||
this.x.setValue(x);
|
||||
this.y.setValue(y);
|
||||
this.z.setValue(z);
|
||||
return expression.evaluate();
|
||||
public double getNoise(double x, double y, double z) {
|
||||
return expression.evaluate(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
|
||||
public class KernelSampler implements NoiseSampler {
|
||||
private final double[][] kernel;
|
||||
private final NoiseSampler in;
|
||||
private double frequency = 1;
|
||||
|
||||
public KernelSampler(double[][] kernel, NoiseSampler in) {
|
||||
this.kernel = kernel;
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoise(double x, double y) {
|
||||
return getNoiseSeeded(0, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoise(double x, double y, double z) {
|
||||
return getNoiseSeeded(0, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseSeeded(int seed, double x, double y) {
|
||||
x *= frequency;
|
||||
y *= frequency;
|
||||
double accumulator = 0;
|
||||
|
||||
for(int kx = 0; kx < kernel.length; kx++) {
|
||||
for(int ky = 0; ky < kernel[kx].length; ky++) {
|
||||
accumulator += in.getNoise(x + kx, y + ky) * kernel[kx][ky];
|
||||
}
|
||||
}
|
||||
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseSeeded(int seed, double x, double y, double z) {
|
||||
x *= frequency;
|
||||
y *= frequency;
|
||||
z *= frequency;
|
||||
double accumulator = 0;
|
||||
|
||||
for(int kx = 0; kx < kernel.length; kx++) {
|
||||
for(int ky = 0; ky < kernel[kx].length; ky++) {
|
||||
accumulator += in.getNoise(x + kx, y, z + ky) * kernel[kx][ky];
|
||||
}
|
||||
}
|
||||
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
public void setFrequency(double frequency) {
|
||||
this.frequency = frequency;
|
||||
}
|
||||
}
|
||||
+565
@@ -0,0 +1,565 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.simplex.OpenSimplex2Sampler;
|
||||
import com.dfsek.terra.api.math.vector.Vector2;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
|
||||
/**
|
||||
* NoiseSampler implementation for Cellular (Voronoi/Worley) Noise.
|
||||
*/
|
||||
public class CellularSampler extends NoiseFunction {
|
||||
private static final double[] RAND_VECS_3D = {
|
||||
-0.7292736885d, -0.6618439697d, 0.1735581948d, 0, 0.790292081d, -0.5480887466d, -0.2739291014d, 0, 0.7217578935d, 0.6226212466d,
|
||||
-0.3023380997d, 0, 0.565683137d, -0.8208298145d, -0.0790000257d, 0, 0.760049034d, -0.5555979497d, -0.3370999617d, 0,
|
||||
0.3713945616d, 0.5011264475d, 0.7816254623d, 0, -0.1277062463d, -0.4254438999d, -0.8959289049d, 0, -0.2881560924d,
|
||||
-0.5815838982d, 0.7607405838d, 0, 0.5849561111d, -0.662820239d, -0.4674352136d, 0, 0.3307171178d, 0.0391653737d, 0.94291689d, 0,
|
||||
0.8712121778d, -0.4113374369d, -0.2679381538d, 0, 0.580981015d, 0.7021915846d, 0.4115677815d, 0, 0.503756873d, 0.6330056931d,
|
||||
-0.5878203852d, 0, 0.4493712205d, 0.601390195d, 0.6606022552d, 0, -0.6878403724d, 0.09018890807d, -0.7202371714d, 0,
|
||||
-0.5958956522d, -0.6469350577d, 0.475797649d, 0, -0.5127052122d, 0.1946921978d, -0.8361987284d, 0, -0.9911507142d,
|
||||
-0.05410276466d, -0.1212153153d, 0, -0.2149721042d, 0.9720882117d, -0.09397607749d, 0, -0.7518650936d, -0.5428057603d,
|
||||
0.3742469607d, 0, 0.5237068895d, 0.8516377189d, -0.02107817834d, 0, 0.6333504779d, 0.1926167129d, -0.7495104896d, 0,
|
||||
-0.06788241606d, 0.3998305789d, 0.9140719259d, 0, -0.5538628599d, -0.4729896695d, -0.6852128902d, 0, -0.7261455366d,
|
||||
-0.5911990757d, 0.3509933228d, 0, -0.9229274737d, -0.1782808786d, 0.3412049336d, 0, -0.6968815002d, 0.6511274338d,
|
||||
0.3006480328d, 0, 0.9608044783d, -0.2098363234d, -0.1811724921d, 0, 0.06817146062d, -0.9743405129d, 0.2145069156d, 0,
|
||||
-0.3577285196d, -0.6697087264d, -0.6507845481d, 0, -0.1868621131d, 0.7648617052d, -0.6164974636d, 0, -0.6541697588d,
|
||||
0.3967914832d, 0.6439087246d, 0, 0.6993340405d, -0.6164538506d, 0.3618239211d, 0, -0.1546665739d, 0.6291283928d, 0.7617583057d,
|
||||
0, -0.6841612949d, -0.2580482182d, -0.6821542638d, 0, 0.5383980957d, 0.4258654885d, 0.7271630328d, 0, -0.5026987823d,
|
||||
-0.7939832935d, -0.3418836993d, 0, 0.3202971715d, 0.2834415347d, 0.9039195862d, 0, 0.8683227101d, -0.0003762656404d,
|
||||
-0.4959995258d, 0, 0.791120031d, -0.08511045745d, 0.6057105799d, 0, -0.04011016052d, -0.4397248749d, 0.8972364289d, 0,
|
||||
0.9145119872d, 0.3579346169d, -0.1885487608d, 0, -0.9612039066d, -0.2756484276d, 0.01024666929d, 0, 0.6510361721d,
|
||||
-0.2877799159d, -0.7023778346d, 0, -0.2041786351d, 0.7365237271d, 0.644859585d, 0, -0.7718263711d, 0.3790626912d, 0.5104855816d,
|
||||
0, -0.3060082741d, -0.7692987727d, 0.5608371729d, 0, 0.454007341d, -0.5024843065d, 0.7357899537d, 0, 0.4816795475d,
|
||||
0.6021208291d, -0.6367380315d, 0, 0.6961980369d, -0.3222197429d, 0.641469197d, 0, -0.6532160499d, -0.6781148932d, 0.3368515753d,
|
||||
0, 0.5089301236d, -0.6154662304d, -0.6018234363d, 0, -0.1635919754d, -0.9133604627d, -0.372840892d, 0, 0.52408019d,
|
||||
-0.8437664109d, 0.1157505864d, 0, 0.5902587356d, 0.4983817807d, -0.6349883666d, 0, 0.5863227872d, 0.494764745d, 0.6414307729d,
|
||||
0, 0.6779335087d, 0.2341345225d, 0.6968408593d, 0, 0.7177054546d, -0.6858979348d, 0.120178631d, 0, -0.5328819713d,
|
||||
-0.5205125012d, 0.6671608058d, 0, -0.8654874251d, -0.0700727088d, -0.4960053754d, 0, -0.2861810166d, 0.7952089234d,
|
||||
0.5345495242d, 0, -0.04849529634d, 0.9810836427d, -0.1874115585d, 0, -0.6358521667d, 0.6058348682d, 0.4781800233d, 0,
|
||||
0.6254794696d, -0.2861619734d, 0.7258696564d, 0, -0.2585259868d, 0.5061949264d, -0.8227581726d, 0, 0.02136306781d,
|
||||
0.5064016808d, -0.8620330371d, 0, 0.200111773d, 0.8599263484d, 0.4695550591d, 0, 0.4743561372d, 0.6014985084d, -0.6427953014d,
|
||||
0, 0.6622993731d, -0.5202474575d, -0.5391679918d, 0, 0.08084972818d, -0.6532720452d, 0.7527940996d, 0, -0.6893687501d,
|
||||
0.0592860349d, 0.7219805347d, 0, -0.1121887082d, -0.9673185067d, 0.2273952515d, 0, 0.7344116094d, 0.5979668656d, -0.3210532909d,
|
||||
0, 0.5789393465d, -0.2488849713d, 0.7764570201d, 0, 0.6988182827d, 0.3557169806d, -0.6205791146d, 0, -0.8636845529d,
|
||||
-0.2748771249d, -0.4224826141d, 0, -0.4247027957d, -0.4640880967d, 0.777335046d, 0, 0.5257722489d, -0.8427017621d,
|
||||
0.1158329937d, 0, 0.9343830603d, 0.316302472d, -0.1639543925d, 0, -0.1016836419d, -0.8057303073d, -0.5834887393d, 0,
|
||||
-0.6529238969d, 0.50602126d, -0.5635892736d, 0, -0.2465286165d, -0.9668205684d, -0.06694497494d, 0, -0.9776897119d,
|
||||
-0.2099250524d, -0.007368825344d, 0, 0.7736893337d, 0.5734244712d, 0.2694238123d, 0, -0.6095087895d, 0.4995678998d,
|
||||
0.6155736747d, 0, 0.5794535482d, 0.7434546771d, 0.3339292269d, 0, -0.8226211154d, 0.08142581855d, 0.5627293636d, 0,
|
||||
-0.510385483d, 0.4703667658d, 0.7199039967d, 0, -0.5764971849d, -0.07231656274d, -0.8138926898d, 0, 0.7250628871d,
|
||||
0.3949971505d, -0.5641463116d, 0, -0.1525424005d, 0.4860840828d, -0.8604958341d, 0, -0.5550976208d, -0.4957820792d,
|
||||
0.667882296d, 0, -0.1883614327d, 0.9145869398d, 0.357841725d, 0, 0.7625556724d, -0.5414408243d, -0.3540489801d, 0,
|
||||
-0.5870231946d, -0.3226498013d, -0.7424963803d, 0, 0.3051124198d, 0.2262544068d, -0.9250488391d, 0, 0.6379576059d, 0.577242424d,
|
||||
-0.5097070502d, 0, -0.5966775796d, 0.1454852398d, -0.7891830656d, 0, -0.658330573d, 0.6555487542d, -0.3699414651d, 0,
|
||||
0.7434892426d, 0.2351084581d, 0.6260573129d, 0, 0.5562114096d, 0.8264360377d, -0.0873632843d, 0, -0.3028940016d, -0.8251527185d,
|
||||
0.4768419182d, 0, 0.1129343818d, -0.985888439d, -0.1235710781d, 0, 0.5937652891d, -0.5896813806d, 0.5474656618d, 0,
|
||||
0.6757964092d, -0.5835758614d, -0.4502648413d, 0, 0.7242302609d, -0.1152719764d, 0.6798550586d, 0, -0.9511914166d,
|
||||
0.0753623979d, -0.2992580792d, 0, 0.2539470961d, -0.1886339355d, 0.9486454084d, 0, 0.571433621d, -0.1679450851d, -0.8032795685d,
|
||||
0, -0.06778234979d, 0.3978269256d, 0.9149531629d, 0, 0.6074972649d, 0.733060024d, -0.3058922593d, 0, -0.5435478392d,
|
||||
0.1675822484d, 0.8224791405d, 0, -0.5876678086d, -0.3380045064d, -0.7351186982d, 0, -0.7967562402d, 0.04097822706d,
|
||||
-0.6029098428d, 0, -0.1996350917d, 0.8706294745d, 0.4496111079d, 0, -0.02787660336d, -0.9106232682d, -0.4122962022d, 0,
|
||||
-0.7797625996d, -0.6257634692d, 0.01975775581d, 0, -0.5211232846d, 0.7401644346d, -0.4249554471d, 0, 0.8575424857d,
|
||||
0.4053272873d, -0.3167501783d, 0, 0.1045223322d, 0.8390195772d, -0.5339674439d, 0, 0.3501822831d, 0.9242524096d, -0.1520850155d,
|
||||
0, 0.1987849858d, 0.07647613266d, 0.9770547224d, 0, 0.7845996363d, 0.6066256811d, -0.1280964233d, 0, 0.09006737436d,
|
||||
-0.9750989929d, -0.2026569073d, 0, -0.8274343547d, -0.542299559d, 0.1458203587d, 0, -0.3485797732d, -0.415802277d, 0.840000362d,
|
||||
0, -0.2471778936d, -0.7304819962d, -0.6366310879d, 0, -0.3700154943d, 0.8577948156d, 0.3567584454d, 0, 0.5913394901d,
|
||||
-0.548311967d, -0.5913303597d, 0, 0.1204873514d, -0.7626472379d, -0.6354935001d, 0, 0.616959265d, 0.03079647928d, 0.7863922953d,
|
||||
0, 0.1258156836d, -0.6640829889d, -0.7369967419d, 0, -0.6477565124d, -0.1740147258d, -0.7417077429d, 0, 0.6217889313d,
|
||||
-0.7804430448d, -0.06547655076d, 0, 0.6589943422d, -0.6096987708d, 0.4404473475d, 0, -0.2689837504d, -0.6732403169d,
|
||||
-0.6887635427d, 0, -0.3849775103d, 0.5676542638d, 0.7277093879d, 0, 0.5754444408d, 0.8110471154d, -0.1051963504d, 0,
|
||||
0.9141593684d, 0.3832947817d, 0.131900567d, 0, -0.107925319d, 0.9245493968d, 0.3654593525d, 0, 0.377977089d, 0.3043148782d,
|
||||
0.8743716458d, 0, -0.2142885215d, -0.8259286236d, 0.5214617324d, 0, 0.5802544474d, 0.4148098596d, -0.7008834116d, 0,
|
||||
-0.1982660881d, 0.8567161266d, -0.4761596756d, 0, -0.03381553704d, 0.3773180787d, -0.9254661404d, 0, -0.6867922841d,
|
||||
-0.6656597827d, 0.2919133642d, 0, 0.7731742607d, -0.2875793547d, -0.5652430251d, 0, -0.09655941928d, 0.9193708367d,
|
||||
-0.3813575004d, 0, 0.2715702457d, -0.9577909544d, -0.09426605581d, 0, 0.2451015704d, -0.6917998565d, -0.6792188003d, 0,
|
||||
0.977700782d, -0.1753855374d, 0.1155036542d, 0, -0.5224739938d, 0.8521606816d, 0.02903615945d, 0, -0.7734880599d,
|
||||
-0.5261292347d, 0.3534179531d, 0, -0.7134492443d, -0.269547243d, 0.6467878011d, 0, 0.1644037271d, 0.5105846203d, -0.8439637196d,
|
||||
0, 0.6494635788d, 0.05585611296d, 0.7583384168d, 0, -0.4711970882d, 0.5017280509d, -0.7254255765d, 0, -0.6335764307d,
|
||||
-0.2381686273d, -0.7361091029d, 0, -0.9021533097d, -0.270947803d, -0.3357181763d, 0, -0.3793711033d, 0.872258117d,
|
||||
0.3086152025d, 0, -0.6855598966d, -0.3250143309d, 0.6514394162d, 0, 0.2900942212d, -0.7799057743d, -0.5546100667d, 0,
|
||||
-0.2098319339d, 0.85037073d, 0.4825351604d, 0, -0.4592603758d, 0.6598504336d, -0.5947077538d, 0, 0.8715945488d, 0.09616365406d,
|
||||
-0.4807031248d, 0, -0.6776666319d, 0.7118504878d, -0.1844907016d, 0, 0.7044377633d, 0.312427597d, 0.637304036d, 0,
|
||||
-0.7052318886d, -0.2401093292d, -0.6670798253d, 0, 0.081921007d, -0.7207336136d, -0.6883545647d, 0, -0.6993680906d,
|
||||
-0.5875763221d, -0.4069869034d, 0, -0.1281454481d, 0.6419895885d, 0.7559286424d, 0, -0.6337388239d, -0.6785471501d,
|
||||
-0.3714146849d, 0, 0.5565051903d, -0.2168887573d, -0.8020356851d, 0, -0.5791554484d, 0.7244372011d, -0.3738578718d, 0,
|
||||
0.1175779076d, -0.7096451073d, 0.6946792478d, 0, -0.6134619607d, 0.1323631078d, 0.7785527795d, 0, 0.6984635305d,
|
||||
-0.02980516237d, -0.715024719d, 0, 0.8318082963d, -0.3930171956d, 0.3919597455d, 0, 0.1469576422d, 0.05541651717d,
|
||||
-0.9875892167d, 0, 0.708868575d, -0.2690503865d, 0.6520101478d, 0, 0.2726053183d, 0.67369766d, -0.68688995d, 0, -0.6591295371d,
|
||||
0.3035458599d, -0.6880466294d, 0, 0.4815131379d, -0.7528270071d, 0.4487723203d, 0, 0.9430009463d, 0.1675647412d, -0.2875261255d,
|
||||
0, 0.434802957d, 0.7695304522d, -0.4677277752d, 0, 0.3931996188d, 0.594473625d, 0.7014236729d, 0, 0.7254336655d, -0.603925654d,
|
||||
0.3301814672d, 0, 0.7590235227d, -0.6506083235d, 0.02433313207d, 0, -0.8552768592d, -0.3430042733d, 0.3883935666d, 0,
|
||||
-0.6139746835d, 0.6981725247d, 0.3682257648d, 0, -0.7465905486d, -0.5752009504d, 0.3342849376d, 0, 0.5730065677d, 0.810555537d,
|
||||
-0.1210916791d, 0, -0.9225877367d, -0.3475211012d, -0.167514036d, 0, -0.7105816789d, -0.4719692027d, -0.5218416899d, 0,
|
||||
-0.08564609717d, 0.3583001386d, 0.929669703d, 0, -0.8279697606d, -0.2043157126d, 0.5222271202d, 0, 0.427944023d, 0.278165994d,
|
||||
0.8599346446d, 0, 0.5399079671d, -0.7857120652d, -0.3019204161d, 0, 0.5678404253d, -0.5495413974d, -0.6128307303d, 0,
|
||||
-0.9896071041d, 0.1365639107d, -0.04503418428d, 0, -0.6154342638d, -0.6440875597d, 0.4543037336d, 0, 0.1074204368d,
|
||||
-0.7946340692d, 0.5975094525d, 0, -0.3595449969d, -0.8885529948d, 0.28495784d, 0, -0.2180405296d, 0.1529888965d, 0.9638738118d,
|
||||
0, -0.7277432317d, -0.6164050508d, -0.3007234646d, 0, 0.7249729114d, -0.00669719484d, 0.6887448187d, 0, -0.5553659455d,
|
||||
-0.5336586252d, 0.6377908264d, 0, 0.5137558015d, 0.7976208196d, -0.3160000073d, 0, -0.3794024848d, 0.9245608561d,
|
||||
-0.03522751494d, 0, 0.8229248658d, 0.2745365933d, -0.4974176556d, 0, -0.5404114394d, 0.6091141441d, 0.5804613989d, 0,
|
||||
0.8036581901d, -0.2703029469d, 0.5301601931d, 0, 0.6044318879d, 0.6832968393d, 0.4095943388d, 0, 0.06389988817d, 0.9658208605d,
|
||||
-0.2512108074d, 0, 0.1087113286d, 0.7402471173d, -0.6634877936d, 0, -0.713427712d, -0.6926784018d, 0.1059128479d, 0,
|
||||
0.6458897819d, -0.5724548511d, -0.5050958653d, 0, -0.6553931414d, 0.7381471625d, 0.159995615d, 0, 0.3910961323d, 0.9188871375d,
|
||||
-0.05186755998d, 0, -0.4879022471d, -0.5904376907d, 0.6429111375d, 0, 0.6014790094d, 0.7707441366d, -0.2101820095d, 0,
|
||||
-0.5677173047d, 0.7511360995d, 0.3368851762d, 0, 0.7858573506d, 0.226674665d, 0.5753666838d, 0, -0.4520345543d, -0.604222686d,
|
||||
-0.6561857263d, 0, 0.002272116345d, 0.4132844051d, -0.9105991643d, 0, -0.5815751419d, -0.5162925989d, 0.6286591339d, 0,
|
||||
-0.03703704785d, 0.8273785755d, 0.5604221175d, 0, -0.5119692504d, 0.7953543429d, -0.3244980058d, 0, -0.2682417366d,
|
||||
-0.9572290247d, -0.1084387619d, 0, -0.2322482736d, -0.9679131102d, -0.09594243324d, 0, 0.3554328906d, -0.8881505545d,
|
||||
0.2913006227d, 0, 0.7346520519d, -0.4371373164d, 0.5188422971d, 0, 0.9985120116d, 0.04659011161d, -0.02833944577d, 0,
|
||||
-0.3727687496d, -0.9082481361d, 0.1900757285d, 0, 0.91737377d, -0.3483642108d, 0.1925298489d, 0, 0.2714911074d, 0.4147529736d,
|
||||
-0.8684886582d, 0, 0.5131763485d, -0.7116334161d, 0.4798207128d, 0, -0.8737353606d, 0.18886992d, -0.4482350644d, 0,
|
||||
0.8460043821d, -0.3725217914d, 0.3814499973d, 0, 0.8978727456d, -0.1780209141d, -0.4026575304d, 0, 0.2178065647d,
|
||||
-0.9698322841d, -0.1094789531d, 0, -0.1518031304d, -0.7788918132d, -0.6085091231d, 0, -0.2600384876d, -0.4755398075d,
|
||||
-0.8403819825d, 0, 0.572313509d, -0.7474340931d, -0.3373418503d, 0, -0.7174141009d, 0.1699017182d, -0.6756111411d, 0,
|
||||
-0.684180784d, 0.02145707593d, -0.7289967412d, 0, -0.2007447902d, 0.06555605789d, -0.9774476623d, 0, -0.1148803697d,
|
||||
-0.8044887315d, 0.5827524187d, 0, -0.7870349638d, 0.03447489231d, 0.6159443543d, 0, -0.2015596421d, 0.6859872284d,
|
||||
0.6991389226d, 0, -0.08581082512d, -0.10920836d, -0.9903080513d, 0, 0.5532693395d, 0.7325250401d, -0.396610771d, 0,
|
||||
-0.1842489331d, -0.9777375055d, -0.1004076743d, 0, 0.0775473789d, -0.9111505856d, 0.4047110257d, 0, 0.1399838409d,
|
||||
0.7601631212d, -0.6344734459d, 0, 0.4484419361d, -0.845289248d, 0.2904925424d, 0
|
||||
};
|
||||
|
||||
private static final double[] RAND_VECS_2D = {
|
||||
-0.2700222198d, -0.9628540911d, 0.3863092627d, -0.9223693152d, 0.04444859006d, -0.999011673d, -0.5992523158d, -0.8005602176d,
|
||||
-0.7819280288d, 0.6233687174d, 0.9464672271d, 0.3227999196d, -0.6514146797d, -0.7587218957d, 0.9378472289d, 0.347048376d,
|
||||
-0.8497875957d, -0.5271252623d, -0.879042592d, 0.4767432447d, -0.892300288d, -0.4514423508d, -0.379844434d, -0.9250503802d,
|
||||
-0.9951650832d, 0.0982163789d, 0.7724397808d, -0.6350880136d, 0.7573283322d, -0.6530343002d, -0.9928004525d, -0.119780055d,
|
||||
-0.0532665713d, 0.9985803285d, 0.9754253726d, -0.2203300762d, -0.7665018163d, 0.6422421394d, 0.991636706d, 0.1290606184d,
|
||||
-0.994696838d, 0.1028503788d, -0.5379205513d, -0.84299554d, 0.5022815471d, -0.8647041387d, 0.4559821461d, -0.8899889226d,
|
||||
-0.8659131224d, -0.5001944266d, 0.0879458407d, -0.9961252577d, -0.5051684983d, 0.8630207346d, 0.7753185226d, -0.6315704146d,
|
||||
-0.6921944612d, 0.7217110418d, -0.5191659449d, -0.8546734591d, 0.8978622882d, -0.4402764035d, -0.1706774107d, 0.9853269617d,
|
||||
-0.9353430106d, -0.3537420705d, -0.9992404798d, 0.03896746794d, -0.2882064021d, -0.9575683108d, -0.9663811329d, 0.2571137995d,
|
||||
-0.8759714238d, -0.4823630009d, -0.8303123018d, -0.5572983775d, 0.05110133755d, -0.9986934731d, -0.8558373281d, -0.5172450752d,
|
||||
0.09887025282d, 0.9951003332d, 0.9189016087d, 0.3944867976d, -0.2439375892d, -0.9697909324d, -0.8121409387d, -0.5834613061d,
|
||||
-0.9910431363d, 0.1335421355d, 0.8492423985d, -0.5280031709d, -0.9717838994d, -0.2358729591d, 0.9949457207d, 0.1004142068d,
|
||||
0.6241065508d, -0.7813392434d, 0.662910307d, 0.7486988212d, -0.7197418176d, 0.6942418282d, -0.8143370775d, -0.5803922158d,
|
||||
0.104521054d, -0.9945226741d, -0.1065926113d, -0.9943027784d, 0.445799684d, -0.8951327509d, 0.105547406d, 0.9944142724d,
|
||||
-0.992790267d, 0.1198644477d, -0.8334366408d, 0.552615025d, 0.9115561563d, -0.4111755999d, 0.8285544909d, -0.5599084351d,
|
||||
0.7217097654d, -0.6921957921d, 0.4940492677d, -0.8694339084d, -0.3652321272d, -0.9309164803d, -0.9696606758d, 0.2444548501d,
|
||||
0.08925509731d, -0.996008799d, 0.5354071276d, -0.8445941083d, -0.1053576186d, 0.9944343981d, -0.9890284586d, 0.1477251101d,
|
||||
0.004856104961d, 0.9999882091d, 0.9885598478d, 0.1508291331d, 0.9286129562d, -0.3710498316d, -0.5832393863d, -0.8123003252d,
|
||||
0.3015207509d, 0.9534596146d, -0.9575110528d, 0.2883965738d, 0.9715802154d, -0.2367105511d, 0.229981792d, 0.9731949318d,
|
||||
0.955763816d, -0.2941352207d, 0.740956116d, 0.6715534485d, -0.9971513787d, -0.07542630764d, 0.6905710663d, -0.7232645452d,
|
||||
-0.290713703d, -0.9568100872d, 0.5912777791d, -0.8064679708d, -0.9454592212d, -0.325740481d, 0.6664455681d, 0.74555369d,
|
||||
0.6236134912d, 0.7817328275d, 0.9126993851d, -0.4086316587d, -0.8191762011d, 0.5735419353d, -0.8812745759d, -0.4726046147d,
|
||||
0.9953313627d, 0.09651672651d, 0.9855650846d, -0.1692969699d, -0.8495980887d, 0.5274306472d, 0.6174853946d, -0.7865823463d,
|
||||
0.8508156371d, 0.52546432d, 0.9985032451d, -0.05469249926d, 0.1971371563d, -0.9803759185d, 0.6607855748d, -0.7505747292d,
|
||||
-0.03097494063d, 0.9995201614d, -0.6731660801d, 0.739491331d, -0.7195018362d, -0.6944905383d, 0.9727511689d, 0.2318515979d,
|
||||
0.9997059088d, -0.0242506907d, 0.4421787429d, -0.8969269532d, 0.9981350961d, -0.061043673d, -0.9173660799d, -0.3980445648d,
|
||||
-0.8150056635d, -0.5794529907d, -0.8789331304d, 0.4769450202d, 0.0158605829d, 0.999874213d, -0.8095464474d, 0.5870558317d,
|
||||
-0.9165898907d, -0.3998286786d, -0.8023542565d, 0.5968480938d, -0.5176737917d, 0.8555780767d, -0.8154407307d, -0.5788405779d,
|
||||
0.4022010347d, -0.9155513791d, -0.9052556868d, -0.4248672045d, 0.7317445619d, 0.6815789728d, -0.5647632201d, -0.8252529947d,
|
||||
-0.8403276335d, -0.5420788397d, -0.9314281527d, 0.363925262d, 0.5238198472d, 0.8518290719d, 0.7432803869d, -0.6689800195d,
|
||||
-0.985371561d, -0.1704197369d, 0.4601468731d, 0.88784281d, 0.825855404d, 0.5638819483d, 0.6182366099d, 0.7859920446d,
|
||||
0.8331502863d, -0.553046653d, 0.1500307506d, 0.9886813308d, -0.662330369d, -0.7492119075d, -0.668598664d, 0.743623444d,
|
||||
0.7025606278d, 0.7116238924d, -0.5419389763d, -0.8404178401d, -0.3388616456d, 0.9408362159d, 0.8331530315d, 0.5530425174d,
|
||||
-0.2989720662d, -0.9542618632d, 0.2638522993d, 0.9645630949d, 0.124108739d, -0.9922686234d, -0.7282649308d, -0.6852956957d,
|
||||
0.6962500149d, 0.7177993569d, -0.9183535368d, 0.3957610156d, -0.6326102274d, -0.7744703352d, -0.9331891859d, -0.359385508d,
|
||||
-0.1153779357d, -0.9933216659d, 0.9514974788d, -0.3076565421d, -0.08987977445d, -0.9959526224d, 0.6678496916d, 0.7442961705d,
|
||||
0.7952400393d, -0.6062947138d, -0.6462007402d, -0.7631674805d, -0.2733598753d, 0.9619118351d, 0.9669590226d, -0.254931851d,
|
||||
-0.9792894595d, 0.2024651934d, -0.5369502995d, -0.8436138784d, -0.270036471d, -0.9628500944d, -0.6400277131d, 0.7683518247d,
|
||||
-0.7854537493d, -0.6189203566d, 0.06005905383d, -0.9981948257d, -0.02455770378d, 0.9996984141d, -0.65983623d, 0.751409442d,
|
||||
-0.6253894466d, -0.7803127835d, -0.6210408851d, -0.7837781695d, 0.8348888491d, 0.5504185768d, -0.1592275245d, 0.9872419133d,
|
||||
0.8367622488d, 0.5475663786d, -0.8675753916d, -0.4973056806d, -0.2022662628d, -0.9793305667d, 0.9399189937d, 0.3413975472d,
|
||||
0.9877404807d, -0.1561049093d, -0.9034455656d, 0.4287028224d, 0.1269804218d, -0.9919052235d, -0.3819600854d, 0.924178821d,
|
||||
0.9754625894d, 0.2201652486d, -0.3204015856d, -0.9472818081d, -0.9874760884d, 0.1577687387d, 0.02535348474d, -0.9996785487d,
|
||||
0.4835130794d, -0.8753371362d, -0.2850799925d, -0.9585037287d, -0.06805516006d, -0.99768156d, -0.7885244045d, -0.6150034663d,
|
||||
0.3185392127d, -0.9479096845d, 0.8880043089d, 0.4598351306d, 0.6476921488d, -0.7619021462d, 0.9820241299d, 0.1887554194d,
|
||||
0.9357275128d, -0.3527237187d, -0.8894895414d, 0.4569555293d, 0.7922791302d, 0.6101588153d, 0.7483818261d, 0.6632681526d,
|
||||
-0.7288929755d, -0.6846276581d, 0.8729032783d, -0.4878932944d, 0.8288345784d, 0.5594937369d, 0.08074567077d, 0.9967347374d,
|
||||
0.9799148216d, -0.1994165048d, -0.580730673d, -0.8140957471d, -0.4700049791d, -0.8826637636d, 0.2409492979d, 0.9705377045d,
|
||||
0.9437816757d, -0.3305694308d, -0.8927998638d, -0.4504535528d, -0.8069622304d, 0.5906030467d, 0.06258973166d, 0.9980393407d,
|
||||
-0.9312597469d, 0.3643559849d, 0.5777449785d, 0.8162173362d, -0.3360095855d, -0.941858566d, 0.697932075d, -0.7161639607d,
|
||||
-0.002008157227d, -0.9999979837d, -0.1827294312d, -0.9831632392d, -0.6523911722d, 0.7578824173d, -0.4302626911d, -0.9027037258d,
|
||||
-0.9985126289d, -0.05452091251d, -0.01028102172d, -0.9999471489d, -0.4946071129d, 0.8691166802d, -0.2999350194d, 0.9539596344d,
|
||||
0.8165471961d, 0.5772786819d, 0.2697460475d, 0.962931498d, -0.7306287391d, -0.6827749597d, -0.7590952064d, -0.6509796216d,
|
||||
-0.907053853d, 0.4210146171d, -0.5104861064d, -0.8598860013d, 0.8613350597d, 0.5080373165d, 0.5007881595d, -0.8655698812d,
|
||||
-0.654158152d, 0.7563577938d, -0.8382755311d, -0.545246856d, 0.6940070834d, 0.7199681717d, 0.06950936031d, 0.9975812994d,
|
||||
0.1702942185d, -0.9853932612d, 0.2695973274d, 0.9629731466d, 0.5519612192d, -0.8338697815d, 0.225657487d, -0.9742067022d,
|
||||
0.4215262855d, -0.9068161835d, 0.4881873305d, -0.8727388672d, -0.3683854996d, -0.9296731273d, -0.9825390578d, 0.1860564427d,
|
||||
0.81256471d, 0.5828709909d, 0.3196460933d, -0.9475370046d, 0.9570913859d, 0.2897862643d, -0.6876655497d, -0.7260276109d,
|
||||
-0.9988770922d, -0.047376731d, -0.1250179027d, 0.992154486d, -0.8280133617d, 0.560708367d, 0.9324863769d, -0.3612051451d,
|
||||
0.6394653183d, 0.7688199442d, -0.01623847064d, -0.9998681473d, -0.9955014666d, -0.09474613458d, -0.81453315d, 0.580117012d,
|
||||
0.4037327978d, -0.9148769469d, 0.9944263371d, 0.1054336766d, -0.1624711654d, 0.9867132919d, -0.9949487814d, -0.100383875d,
|
||||
-0.6995302564d, 0.7146029809d, 0.5263414922d, -0.85027327d, -0.5395221479d, 0.841971408d, 0.6579370318d, 0.7530729462d,
|
||||
0.01426758847d, -0.9998982128d, -0.6734383991d, 0.7392433447d, 0.639412098d, -0.7688642071d, 0.9211571421d, 0.3891908523d,
|
||||
-0.146637214d, -0.9891903394d, -0.782318098d, 0.6228791163d, -0.5039610839d, -0.8637263605d, -0.7743120191d, -0.6328039957d,
|
||||
};
|
||||
|
||||
|
||||
private DistanceFunction distanceFunction = DistanceFunction.EuclideanSq;
|
||||
private ReturnType returnType = ReturnType.Distance;
|
||||
private double jitterModifier = 1.0;
|
||||
|
||||
private NoiseSampler noiseLookup;
|
||||
|
||||
public CellularSampler(int seed) {
|
||||
super(seed);
|
||||
noiseLookup = new OpenSimplex2Sampler(seed);
|
||||
}
|
||||
|
||||
public void setDistanceFunction(DistanceFunction distanceFunction) {
|
||||
this.distanceFunction = distanceFunction;
|
||||
}
|
||||
|
||||
public void setJitterModifier(double jitterModifier) {
|
||||
this.jitterModifier = jitterModifier;
|
||||
}
|
||||
|
||||
public void setNoiseLookup(NoiseSampler noiseLookup) {
|
||||
this.noiseLookup = noiseLookup;
|
||||
}
|
||||
|
||||
public void setReturnType(ReturnType returnType) {
|
||||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
int xr = fastRound(x);
|
||||
int yr = fastRound(y);
|
||||
|
||||
double distance0 = Double.MAX_VALUE;
|
||||
double distance1 = Double.MAX_VALUE;
|
||||
double distance2 = Double.MAX_VALUE;
|
||||
|
||||
int closestHash = 0;
|
||||
|
||||
double cellularJitter = 0.43701595 * jitterModifier;
|
||||
|
||||
int xPrimed = (xr - 1) * PRIME_X;
|
||||
int yPrimedBase = (yr - 1) * PRIME_Y;
|
||||
|
||||
Vector2 center = new Vector2(x, y);
|
||||
|
||||
switch(distanceFunction) {
|
||||
default:
|
||||
case Euclidean:
|
||||
case EuclideanSq:
|
||||
for(int xi = xr - 1; xi <= xr + 1; xi++) {
|
||||
int yPrimed = yPrimedBase;
|
||||
|
||||
for(int yi = yr - 1; yi <= yr + 1; yi++) {
|
||||
int hash = hash(seed, xPrimed, yPrimed);
|
||||
int idx = hash & (255 << 1);
|
||||
|
||||
double vecX = (xi - x) + RAND_VECS_2D[idx] * cellularJitter;
|
||||
double vecY = (yi - y) + RAND_VECS_2D[idx | 1] * cellularJitter;
|
||||
|
||||
double newDistance = vecX * vecX + vecY * vecY;
|
||||
|
||||
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
|
||||
if(newDistance < distance0) {
|
||||
distance0 = newDistance;
|
||||
closestHash = hash;
|
||||
center.setX((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
|
||||
center.setZ((yi + RAND_VECS_2D[idx | 1] * cellularJitter) / frequency);
|
||||
} else if(newDistance < distance1) {
|
||||
distance2 = distance1;
|
||||
distance1 = newDistance;
|
||||
} else if(newDistance < distance2) {
|
||||
distance2 = newDistance;
|
||||
}
|
||||
yPrimed += PRIME_Y;
|
||||
}
|
||||
xPrimed += PRIME_X;
|
||||
}
|
||||
break;
|
||||
case Manhattan:
|
||||
for(int xi = xr - 1; xi <= xr + 1; xi++) {
|
||||
int yPrimed = yPrimedBase;
|
||||
|
||||
for(int yi = yr - 1; yi <= yr + 1; yi++) {
|
||||
int hash = hash(seed, xPrimed, yPrimed);
|
||||
int idx = hash & (255 << 1);
|
||||
|
||||
double vecX = (xi - x) + RAND_VECS_2D[idx] * cellularJitter;
|
||||
double vecY = (yi - y) + RAND_VECS_2D[idx | 1] * cellularJitter;
|
||||
|
||||
double newDistance = fastAbs(vecX) + fastAbs(vecY);
|
||||
|
||||
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
|
||||
if(newDistance < distance0) {
|
||||
distance0 = newDistance;
|
||||
closestHash = hash;
|
||||
center.setX((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
|
||||
center.setZ((yi + RAND_VECS_2D[idx | 1] * cellularJitter) / frequency);
|
||||
} else if(newDistance < distance1) {
|
||||
distance2 = distance1;
|
||||
distance1 = newDistance;
|
||||
} else if(newDistance < distance2) {
|
||||
distance2 = newDistance;
|
||||
}
|
||||
yPrimed += PRIME_Y;
|
||||
}
|
||||
xPrimed += PRIME_X;
|
||||
}
|
||||
break;
|
||||
case Hybrid:
|
||||
for(int xi = xr - 1; xi <= xr + 1; xi++) {
|
||||
int yPrimed = yPrimedBase;
|
||||
|
||||
for(int yi = yr - 1; yi <= yr + 1; yi++) {
|
||||
int hash = hash(seed, xPrimed, yPrimed);
|
||||
int idx = hash & (255 << 1);
|
||||
|
||||
double vecX = (xi - x) + RAND_VECS_2D[idx] * cellularJitter;
|
||||
double vecY = (yi - y) + RAND_VECS_2D[idx | 1] * cellularJitter;
|
||||
|
||||
double newDistance = (fastAbs(vecX) + fastAbs(vecY)) + (vecX * vecX + vecY * vecY);
|
||||
|
||||
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
|
||||
if(newDistance < distance0) {
|
||||
distance0 = newDistance;
|
||||
closestHash = hash;
|
||||
center.setX((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
|
||||
center.setZ((yi + RAND_VECS_2D[idx | 1] * cellularJitter) / frequency);
|
||||
} else if(newDistance < distance1) {
|
||||
distance2 = distance1;
|
||||
distance1 = newDistance;
|
||||
} else if(newDistance < distance2) {
|
||||
distance2 = newDistance;
|
||||
}
|
||||
yPrimed += PRIME_Y;
|
||||
}
|
||||
xPrimed += PRIME_X;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(distanceFunction == DistanceFunction.Euclidean && returnType != ReturnType.CellValue) {
|
||||
distance0 = fastSqrt(distance0);
|
||||
if(returnType != ReturnType.CellValue) {
|
||||
distance1 = fastSqrt(distance1);
|
||||
}
|
||||
}
|
||||
|
||||
switch(returnType) {
|
||||
case CellValue:
|
||||
return closestHash * (1 / 2147483648.0);
|
||||
case Distance:
|
||||
return distance0 - 1;
|
||||
case Distance2:
|
||||
return distance1 - 1;
|
||||
case Distance2Add:
|
||||
return (distance1 + distance0) * 0.5 - 1;
|
||||
case Distance2Sub:
|
||||
return distance1 - distance0 - 1;
|
||||
case Distance2Mul:
|
||||
return distance1 * distance0 * 0.5 - 1;
|
||||
case Distance2Div:
|
||||
return distance0 / distance1 - 1;
|
||||
case NoiseLookup:
|
||||
return noiseLookup.getNoise(center.getX(), center.getZ());
|
||||
case Distance3:
|
||||
return distance2 - 1;
|
||||
case Distance3Add:
|
||||
return (distance2 + distance0) * 0.5 - 1;
|
||||
case Distance3Sub:
|
||||
return distance2 - distance0 - 1;
|
||||
case Distance3Mul:
|
||||
return distance2 * distance0 - 1;
|
||||
case Distance3Div:
|
||||
return distance0 / distance2 - 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
int xr = fastRound(x);
|
||||
int yr = fastRound(y);
|
||||
int zr = fastRound(z);
|
||||
|
||||
double distance0 = Double.MAX_VALUE;
|
||||
double distance1 = Double.MAX_VALUE;
|
||||
double distance2 = Double.MAX_VALUE;
|
||||
int closestHash = 0;
|
||||
|
||||
double cellularJitter = 0.39614353 * jitterModifier;
|
||||
|
||||
int xPrimed = (xr - 1) * PRIME_X;
|
||||
int yPrimedBase = (yr - 1) * PRIME_Y;
|
||||
int zPrimedBase = (zr - 1) * PRIME_Z;
|
||||
|
||||
Vector3 center = new Vector3(x, y, z);
|
||||
|
||||
switch(distanceFunction) {
|
||||
case Euclidean:
|
||||
case EuclideanSq:
|
||||
for(int xi = xr - 1; xi <= xr + 1; xi++) {
|
||||
int yPrimed = yPrimedBase;
|
||||
|
||||
for(int yi = yr - 1; yi <= yr + 1; yi++) {
|
||||
int zPrimed = zPrimedBase;
|
||||
|
||||
for(int zi = zr - 1; zi <= zr + 1; zi++) {
|
||||
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
|
||||
int idx = hash & (255 << 2);
|
||||
|
||||
double vecX = (xi - x) + RAND_VECS_3D[idx] * cellularJitter;
|
||||
double vecY = (yi - y) + RAND_VECS_3D[idx | 1] * cellularJitter;
|
||||
double vecZ = (zi - z) + RAND_VECS_3D[idx | 2] * cellularJitter;
|
||||
|
||||
double newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ;
|
||||
|
||||
if(newDistance < distance0) {
|
||||
distance0 = newDistance;
|
||||
closestHash = hash;
|
||||
center.setX((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
|
||||
center.setY((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
|
||||
center.setZ((zi + RAND_VECS_3D[idx | 2] * cellularJitter) / frequency);
|
||||
} else if(newDistance < distance1) {
|
||||
distance2 = distance1;
|
||||
distance1 = newDistance;
|
||||
} else if(newDistance < distance2) {
|
||||
distance2 = newDistance;
|
||||
}
|
||||
zPrimed += PRIME_Z;
|
||||
}
|
||||
yPrimed += PRIME_Y;
|
||||
}
|
||||
xPrimed += PRIME_X;
|
||||
}
|
||||
break;
|
||||
case Manhattan:
|
||||
for(int xi = xr - 1; xi <= xr + 1; xi++) {
|
||||
int yPrimed = yPrimedBase;
|
||||
|
||||
for(int yi = yr - 1; yi <= yr + 1; yi++) {
|
||||
int zPrimed = zPrimedBase;
|
||||
|
||||
for(int zi = zr - 1; zi <= zr + 1; zi++) {
|
||||
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
|
||||
int idx = hash & (255 << 2);
|
||||
|
||||
double vecX = (xi - x) + RAND_VECS_3D[idx] * cellularJitter;
|
||||
double vecY = (yi - y) + RAND_VECS_3D[idx | 1] * cellularJitter;
|
||||
double vecZ = (zi - z) + RAND_VECS_3D[idx | 2] * cellularJitter;
|
||||
|
||||
double newDistance = fastAbs(vecX) + fastAbs(vecY) + fastAbs(vecZ);
|
||||
|
||||
if(newDistance < distance0) {
|
||||
distance0 = newDistance;
|
||||
closestHash = hash;
|
||||
center.setX((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
|
||||
center.setY((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
|
||||
center.setZ((zi + RAND_VECS_3D[idx | 2] * cellularJitter) / frequency);
|
||||
} else if(newDistance < distance1) {
|
||||
distance2 = distance1;
|
||||
distance1 = newDistance;
|
||||
} else if(newDistance < distance2) {
|
||||
distance2 = newDistance;
|
||||
}
|
||||
zPrimed += PRIME_Z;
|
||||
}
|
||||
yPrimed += PRIME_Y;
|
||||
}
|
||||
xPrimed += PRIME_X;
|
||||
}
|
||||
break;
|
||||
case Hybrid:
|
||||
for(int xi = xr - 1; xi <= xr + 1; xi++) {
|
||||
int yPrimed = yPrimedBase;
|
||||
|
||||
for(int yi = yr - 1; yi <= yr + 1; yi++) {
|
||||
int zPrimed = zPrimedBase;
|
||||
|
||||
for(int zi = zr - 1; zi <= zr + 1; zi++) {
|
||||
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
|
||||
int idx = hash & (255 << 2);
|
||||
|
||||
double vecX = (xi - x) + RAND_VECS_3D[idx] * cellularJitter;
|
||||
double vecY = (yi - y) + RAND_VECS_3D[idx | 1] * cellularJitter;
|
||||
double vecZ = (zi - z) + RAND_VECS_3D[idx | 2] * cellularJitter;
|
||||
|
||||
double newDistance = (fastAbs(vecX) + fastAbs(vecY) + fastAbs(vecZ)) +
|
||||
(vecX * vecX + vecY * vecY + vecZ * vecZ);
|
||||
|
||||
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
|
||||
if(newDistance < distance0) {
|
||||
distance0 = newDistance;
|
||||
closestHash = hash;
|
||||
center.setX((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
|
||||
center.setY((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
|
||||
center.setZ((zi + RAND_VECS_3D[idx | 2] * cellularJitter) / frequency);
|
||||
} else if(newDistance < distance1) {
|
||||
distance2 = distance1;
|
||||
distance1 = newDistance;
|
||||
} else if(newDistance < distance2) {
|
||||
distance2 = newDistance;
|
||||
}
|
||||
zPrimed += PRIME_Z;
|
||||
}
|
||||
yPrimed += PRIME_Y;
|
||||
}
|
||||
xPrimed += PRIME_X;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(distanceFunction == DistanceFunction.Euclidean && returnType != ReturnType.CellValue) {
|
||||
distance0 = fastSqrt(distance0);
|
||||
if(returnType != ReturnType.CellValue) {
|
||||
distance1 = fastSqrt(distance1);
|
||||
}
|
||||
}
|
||||
|
||||
switch(returnType) {
|
||||
case CellValue:
|
||||
return closestHash * (1 / 2147483648.0);
|
||||
case Distance:
|
||||
return distance0 - 1;
|
||||
case Distance2:
|
||||
return distance1 - 1;
|
||||
case Distance2Add:
|
||||
return (distance1 + distance0) * 0.5 - 1;
|
||||
case Distance2Sub:
|
||||
return distance1 - distance0 - 1;
|
||||
case Distance2Mul:
|
||||
return distance1 * distance0 * 0.5 - 1;
|
||||
case Distance2Div:
|
||||
return distance0 / distance1 - 1;
|
||||
case NoiseLookup:
|
||||
return noiseLookup.getNoise(center.getX(), center.getY(), center.getZ());
|
||||
case Distance3:
|
||||
return distance2 - 1;
|
||||
case Distance3Add:
|
||||
return (distance2 + distance0) * 0.5 - 1;
|
||||
case Distance3Sub:
|
||||
return distance2 - distance0 - 1;
|
||||
case Distance3Mul:
|
||||
return distance2 * distance0 - 1;
|
||||
case Distance3Div:
|
||||
return distance0 / distance2 - 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public enum DistanceFunction {
|
||||
Euclidean,
|
||||
EuclideanSq,
|
||||
Manhattan,
|
||||
Hybrid
|
||||
}
|
||||
|
||||
|
||||
public enum ReturnType {
|
||||
CellValue,
|
||||
Distance,
|
||||
Distance2,
|
||||
Distance2Add,
|
||||
Distance2Sub,
|
||||
Distance2Mul,
|
||||
Distance2Div,
|
||||
NoiseLookup,
|
||||
Distance3,
|
||||
Distance3Add,
|
||||
Distance3Sub,
|
||||
Distance3Mul,
|
||||
Distance3Div
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise;
|
||||
|
||||
/**
|
||||
* Sampler implementation that returns a constant.
|
||||
*/
|
||||
public class ConstantSampler extends NoiseFunction {
|
||||
private final double constant;
|
||||
|
||||
public ConstantSampler(double constant) {
|
||||
super(0);
|
||||
this.constant = constant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
return constant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
return constant;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise;
|
||||
|
||||
import com.dfsek.paralithic.Expression;
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.paralithic.functions.Function;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* NoiseSampler implementation using a Paralithic expression.
|
||||
*/
|
||||
public class ExpressionFunction extends NoiseFunction {
|
||||
private final Expression expression;
|
||||
|
||||
public ExpressionFunction(Map<String, Function> functions, String eq, Map<String, Double> vars) throws ParseException {
|
||||
super(0);
|
||||
Parser p = new Parser();
|
||||
Scope scope = new Scope();
|
||||
|
||||
scope.addInvocationVariable("x");
|
||||
scope.addInvocationVariable("y");
|
||||
scope.addInvocationVariable("z");
|
||||
|
||||
vars.forEach(scope::create);
|
||||
|
||||
functions.forEach(p::registerFunction);
|
||||
|
||||
expression = p.parse(eq, scope);
|
||||
frequency = 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
return expression.evaluate(x, 0, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
return expression.evaluate(x, y, z);
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
@SuppressWarnings("ManualMinMaxCalculation")
|
||||
public abstract class NoiseFunction implements NoiseSampler {
|
||||
// Hashing
|
||||
protected static final int PRIME_X = 501125321;
|
||||
protected static final int PRIME_Y = 1136930381;
|
||||
protected static final int PRIME_Z = 1720413743;
|
||||
|
||||
|
||||
protected double frequency = 0.02d;
|
||||
protected int seed;
|
||||
|
||||
public NoiseFunction(int seed) {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
protected static int fastFloor(double f) {
|
||||
return f >= 0 ? (int) f : (int) f - 1;
|
||||
}
|
||||
|
||||
protected static int hash(int seed, int xPrimed, int yPrimed, int zPrimed) {
|
||||
int hash = seed ^ xPrimed ^ yPrimed ^ zPrimed;
|
||||
|
||||
hash *= 0x27d4eb2d;
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected static int hash(int seed, int xPrimed, int yPrimed) {
|
||||
int hash = seed ^ xPrimed ^ yPrimed;
|
||||
|
||||
hash *= 0x27d4eb2d;
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected static int fastRound(double f) {
|
||||
return f >= 0 ? (int) (f + 0.5f) : (int) (f - 0.5);
|
||||
}
|
||||
|
||||
protected static double lerp(double a, double b, double t) {
|
||||
return a + t * (b - a);
|
||||
}
|
||||
|
||||
protected static double interpHermite(double t) {
|
||||
return t * t * (3 - 2 * t);
|
||||
}
|
||||
|
||||
protected static double interpQuintic(double t) {
|
||||
return t * t * t * (t * (t * 6 - 15) + 10);
|
||||
}
|
||||
|
||||
protected static double cubicLerp(double a, double b, double c, double d, double t) {
|
||||
double p = (d - c) - (a - b);
|
||||
return t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b;
|
||||
}
|
||||
|
||||
protected static double fastMin(double a, double b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
protected static double fastMax(double a, double b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
protected static double fastAbs(double f) {
|
||||
return f < 0 ? -f : f;
|
||||
}
|
||||
|
||||
protected static double fastSqrt(double f) {
|
||||
return FastMath.sqrt(f);
|
||||
}
|
||||
|
||||
public void setSeed(int seed) {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public double getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public void setFrequency(double frequency) {
|
||||
this.frequency = frequency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoise(double x, double y) {
|
||||
return getNoiseSeeded(seed, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoise(double x, double y, double z) {
|
||||
return getNoiseSeeded(seed, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseSeeded(int seed, double x, double y) {
|
||||
return getNoiseRaw(seed, x * frequency, y * frequency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseSeeded(int seed, double x, double y, double z) {
|
||||
return getNoiseRaw(seed, x * frequency, y * frequency, z * frequency);
|
||||
}
|
||||
|
||||
public abstract double getNoiseRaw(int seed, double x, double y);
|
||||
|
||||
public abstract double getNoiseRaw(int seed, double x, double y, double z);
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.fractal;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
|
||||
public class BrownianMotionSampler extends FractalNoiseFunction {
|
||||
public BrownianMotionSampler(int seed, NoiseSampler input) {
|
||||
super(seed, input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
double sum = 0;
|
||||
double amp = fractalBounding;
|
||||
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = input.getNoiseSeeded(seed++, x, y);
|
||||
sum += noise * amp;
|
||||
amp *= lerp(1.0, fastMin(noise + 1, 2) * 0.5, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
amp *= gain;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
double sum = 0;
|
||||
double amp = fractalBounding;
|
||||
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = input.getNoiseSeeded(seed++, x, y, z);
|
||||
sum += noise * amp;
|
||||
amp *= lerp(1.0, (noise + 1) * 0.5, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
z *= lacunarity;
|
||||
amp *= gain;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.fractal;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction;
|
||||
|
||||
public abstract class FractalNoiseFunction extends NoiseFunction {
|
||||
protected final NoiseSampler input;
|
||||
protected double fractalBounding = 1 / 1.75;
|
||||
protected int octaves = 3;
|
||||
protected double gain = 0.5;
|
||||
protected double lacunarity = 2.0d;
|
||||
protected double weightedStrength = 0.0d;
|
||||
|
||||
public FractalNoiseFunction(int seed, NoiseSampler input) {
|
||||
super(seed);
|
||||
this.input = input;
|
||||
frequency = 1;
|
||||
}
|
||||
|
||||
public void setWeightedStrength(double weightedStrength) {
|
||||
this.weightedStrength = weightedStrength;
|
||||
}
|
||||
|
||||
protected void calculateFractalBounding() {
|
||||
double gain = fastAbs(this.gain);
|
||||
double amp = gain;
|
||||
double ampFractal = 1.0;
|
||||
for(int i = 1; i < octaves; i++) {
|
||||
ampFractal += amp;
|
||||
amp *= gain;
|
||||
}
|
||||
fractalBounding = 1 / ampFractal;
|
||||
}
|
||||
|
||||
public void setOctaves(int octaves) {
|
||||
this.octaves = octaves;
|
||||
calculateFractalBounding();
|
||||
}
|
||||
|
||||
public void setGain(double gain) {
|
||||
this.gain = gain;
|
||||
calculateFractalBounding();
|
||||
}
|
||||
|
||||
public void setLacunarity(double lacunarity) {
|
||||
this.lacunarity = lacunarity;
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.fractal;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
|
||||
public class PingPongSampler extends FractalNoiseFunction {
|
||||
private double pingPongStrength = 2.0;
|
||||
|
||||
public PingPongSampler(int seed, NoiseSampler input) {
|
||||
super(seed, input);
|
||||
}
|
||||
|
||||
|
||||
private static double pingPong(double t) {
|
||||
t -= (int) (t * 0.5f) << 1;
|
||||
return t < 1 ? t : 2 - t;
|
||||
}
|
||||
|
||||
public void setPingPongStrength(double strength) {
|
||||
this.pingPongStrength = strength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
double sum = 0;
|
||||
double amp = fractalBounding;
|
||||
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = pingPong((input.getNoiseSeeded(seed++, x, y) + 1) * pingPongStrength);
|
||||
sum += (noise - 0.5) * 2 * amp;
|
||||
amp *= lerp(1.0, noise, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
amp *= gain;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
double sum = 0;
|
||||
double amp = fractalBounding;
|
||||
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = pingPong((input.getNoiseSeeded(seed++, x, y, z) + 1) * pingPongStrength);
|
||||
sum += (noise - 0.5) * 2 * amp;
|
||||
amp *= lerp(1.0, noise, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
z *= lacunarity;
|
||||
amp *= gain;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.fractal;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
|
||||
public class RidgedFractalSampler extends FractalNoiseFunction {
|
||||
|
||||
public RidgedFractalSampler(int seed, NoiseSampler input) {
|
||||
super(seed, input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
double sum = 0;
|
||||
double amp = fractalBounding;
|
||||
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = fastAbs(input.getNoiseSeeded(seed++, x, y));
|
||||
sum += (noise * -2 + 1) * amp;
|
||||
amp *= lerp(1.0, 1 - noise, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
amp *= gain;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
double sum = 0;
|
||||
double amp = fractalBounding;
|
||||
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = fastAbs(input.getNoiseSeeded(seed++, x, y, z));
|
||||
sum += (noise * -2 + 1) * amp;
|
||||
amp *= lerp(1.0, 1 - noise, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
z *= lacunarity;
|
||||
amp *= gain;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.random;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction;
|
||||
|
||||
/**
|
||||
* NoiseSampler implementation to provide random, normally distributed (Gaussian) noise.
|
||||
*/
|
||||
public class GaussianNoiseSampler extends NoiseFunction {
|
||||
private final WhiteNoiseSampler whiteNoiseSampler; // Back with a white noise sampler.
|
||||
|
||||
public GaussianNoiseSampler(int seed) {
|
||||
super(seed);
|
||||
whiteNoiseSampler = new WhiteNoiseSampler(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
double v1, v2, s;
|
||||
do {
|
||||
v1 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y);
|
||||
v2 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y);
|
||||
s = v1 * v1 + v2 * v2;
|
||||
} while(s >= 1 || s == 0);
|
||||
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s);
|
||||
return v1 * multiplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
double v1, v2, s;
|
||||
do {
|
||||
v1 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y, z);
|
||||
v2 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y, z);
|
||||
s = v1 * v1 + v2 * v2;
|
||||
} while(s >= 1 || s == 0);
|
||||
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s);
|
||||
return v1 * multiplier;
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.random;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction;
|
||||
|
||||
/**
|
||||
* NoiseSampler implementation to produce random, uniformly distributed (white) noise.
|
||||
*/
|
||||
public class WhiteNoiseSampler extends NoiseFunction {
|
||||
private static final long POSITIVE_POW1 = 0b01111111111L << 52; // Bits that when applied to the exponent/sign section of a double, produce a positive number with a power of 1.
|
||||
|
||||
public WhiteNoiseSampler(int seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
long hashX = Double.doubleToRawLongBits(x) ^ seed;
|
||||
long hashZ = Double.doubleToRawLongBits(y) ^ seed;
|
||||
long hash = ((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed;
|
||||
long base = (murmur64(hash) & 0x000fffffffffffffL)
|
||||
| POSITIVE_POW1; // Sign and exponent
|
||||
return (Double.longBitsToDouble(base) - 1.5) * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
long hashX = Double.doubleToRawLongBits(x) ^ seed;
|
||||
long hashZ = Double.doubleToRawLongBits(y) ^ seed;
|
||||
long hash = (((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed) + Double.doubleToRawLongBits(z);
|
||||
long base = ((murmur64(hash)) & 0x000fffffffffffffL)
|
||||
| POSITIVE_POW1; // Sign and exponent
|
||||
return (Double.longBitsToDouble(base) - 1.5) * 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Murmur64 hashing function
|
||||
*
|
||||
* @param h Input value
|
||||
* @return Hashed value
|
||||
*/
|
||||
private static long murmur64(long h) {
|
||||
h ^= h >>> 33;
|
||||
h *= 0xff51afd7ed558ccdL;
|
||||
h ^= h >>> 33;
|
||||
h *= 0xc4ceb9fe1a85ec53L;
|
||||
h ^= h >>> 33;
|
||||
return h;
|
||||
}
|
||||
}
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.simplex;
|
||||
|
||||
/**
|
||||
* NoiseSampler implementation to provide OpenSimplex2 (Smooth Variant) noise.
|
||||
*/
|
||||
public class OpenSimplex2SSampler extends SimplexStyleSampler {
|
||||
public OpenSimplex2SSampler(int seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NumericOverflow")
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
// 2D OpenSimplex2S case is a modified 2D simplex noise.
|
||||
|
||||
final double SQRT3 = 1.7320508075688772935274463415059;
|
||||
final double G2 = (3 - SQRT3) / 6;
|
||||
|
||||
final double F2 = 0.5f * (SQRT3 - 1);
|
||||
double s = (x + y) * F2;
|
||||
x += s;
|
||||
y += s;
|
||||
|
||||
|
||||
int i = fastFloor(x);
|
||||
int j = fastFloor(y);
|
||||
double xi = x - i;
|
||||
double yi = y - j;
|
||||
|
||||
i *= PRIME_X;
|
||||
j *= PRIME_Y;
|
||||
int i1 = i + PRIME_X;
|
||||
int j1 = j + PRIME_Y;
|
||||
|
||||
double t = (xi + yi) * G2;
|
||||
double x0 = xi - t;
|
||||
double y0 = yi - t;
|
||||
|
||||
double a0 = (2.0 / 3.0) - x0 * x0 - y0 * y0;
|
||||
double value = (a0 * a0) * (a0 * a0) * gradCoord(seed, i, j, x0, y0);
|
||||
|
||||
double a1 = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a0);
|
||||
double x1 = x0 - (1 - 2 * G2);
|
||||
double y1 = y0 - (1 - 2 * G2);
|
||||
value += (a1 * a1) * (a1 * a1) * gradCoord(seed, i1, j1, x1, y1);
|
||||
|
||||
// Nested conditionals were faster than compact bit logic/arithmetic.
|
||||
double xmyi = xi - yi;
|
||||
if(t > G2) {
|
||||
if(xi + xmyi > 1) {
|
||||
double x2 = x0 + (3 * G2 - 2);
|
||||
double y2 = y0 + (3 * G2 - 1);
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i + (PRIME_X << 1), j + PRIME_Y, x2, y2);
|
||||
}
|
||||
} else {
|
||||
double x2 = x0 + G2;
|
||||
double y2 = y0 + (G2 - 1);
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i, j + PRIME_Y, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
if(yi - xmyi > 1) {
|
||||
double x3 = x0 + (3 * G2 - 1);
|
||||
double y3 = y0 + (3 * G2 - 2);
|
||||
double a3 = (2.0 / 3.0) - x3 * x3 - y3 * y3;
|
||||
if(a3 > 0) {
|
||||
value += (a3 * a3) * (a3 * a3) * gradCoord(seed, i + PRIME_X, j + (PRIME_Y << 1), x3, y3);
|
||||
}
|
||||
} else {
|
||||
double x3 = x0 + (G2 - 1);
|
||||
double y3 = y0 + G2;
|
||||
double a3 = (2.0 / 3.0) - x3 * x3 - y3 * y3;
|
||||
if(a3 > 0) {
|
||||
value += (a3 * a3) * (a3 * a3) * gradCoord(seed, i + PRIME_X, j, x3, y3);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(xi + xmyi < 0) {
|
||||
double x2 = x0 + (1 - G2);
|
||||
double y2 = y0 - G2;
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i - PRIME_X, j, x2, y2);
|
||||
}
|
||||
} else {
|
||||
double x2 = x0 + (G2 - 1);
|
||||
double y2 = y0 + G2;
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i + PRIME_X, j, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
if(yi < xmyi) {
|
||||
double x2 = x0 - G2;
|
||||
double y2 = y0 - (G2 - 1);
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i, j - PRIME_Y, x2, y2);
|
||||
}
|
||||
} else {
|
||||
double x2 = x0 + G2;
|
||||
double y2 = y0 + (G2 - 1);
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i, j + PRIME_Y, x2, y2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value * 18.24196194486065;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NumericOverflow")
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
// 3D OpenSimplex2S case uses two offset rotated cube grids.
|
||||
final double R3 = (2.0 / 3.0);
|
||||
double r = (x + y + z) * R3; // Rotation, not skew
|
||||
x = r - x;
|
||||
y = r - y;
|
||||
z = r - z;
|
||||
|
||||
|
||||
int i = fastFloor(x);
|
||||
int j = fastFloor(y);
|
||||
int k = fastFloor(z);
|
||||
double xi = x - i;
|
||||
double yi = y - j;
|
||||
double zi = z - k;
|
||||
|
||||
i *= PRIME_X;
|
||||
j *= PRIME_Y;
|
||||
k *= PRIME_Z;
|
||||
int seed2 = seed + 1293373;
|
||||
|
||||
int xNMask = (int) (-0.5 - xi);
|
||||
int yNMask = (int) (-0.5 - yi);
|
||||
int zNMask = (int) (-0.5 - zi);
|
||||
|
||||
double x0 = xi + xNMask;
|
||||
double y0 = yi + yNMask;
|
||||
double z0 = zi + zNMask;
|
||||
double a0 = 0.75 - x0 * x0 - y0 * y0 - z0 * z0;
|
||||
double value = (a0 * a0) * (a0 * a0) * gradCoord(seed, i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z), x0, y0,
|
||||
z0);
|
||||
|
||||
double x1 = xi - 0.5;
|
||||
double y1 = yi - 0.5;
|
||||
double z1 = zi - 0.5;
|
||||
double a1 = 0.75 - x1 * x1 - y1 * y1 - z1 * z1;
|
||||
value += (a1 * a1) * (a1 * a1) * gradCoord(seed2, i + PRIME_X, j + PRIME_Y, k + PRIME_Z, x1, y1, z1);
|
||||
|
||||
double xAFlipMask0 = ((xNMask | 1) << 1) * x1;
|
||||
double yAFlipMask0 = ((yNMask | 1) << 1) * y1;
|
||||
double zAFlipMask0 = ((zNMask | 1) << 1) * z1;
|
||||
double xAFlipMask1 = (-2 - (xNMask << 2)) * x1 - 1.0;
|
||||
double yAFlipMask1 = (-2 - (yNMask << 2)) * y1 - 1.0;
|
||||
double zAFlipMask1 = (-2 - (zNMask << 2)) * z1 - 1.0;
|
||||
|
||||
boolean skip5 = false;
|
||||
double a2 = xAFlipMask0 + a0;
|
||||
if(a2 > 0) {
|
||||
double x2 = x0 - (xNMask | 1);
|
||||
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i + (~xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z), x2, y0,
|
||||
z0);
|
||||
} else {
|
||||
double a3 = yAFlipMask0 + zAFlipMask0 + a0;
|
||||
if(a3 > 0) {
|
||||
double y3 = y0 - (yNMask | 1);
|
||||
double z3 = z0 - (zNMask | 1);
|
||||
value += (a3 * a3) * (a3 * a3) * gradCoord(seed, i + (xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (~zNMask & PRIME_Z), x0,
|
||||
y3, z3);
|
||||
}
|
||||
|
||||
double a4 = xAFlipMask1 + a1;
|
||||
if(a4 > 0) {
|
||||
double x4 = (xNMask | 1) + x1;
|
||||
value += (a4 * a4) * (a4 * a4) * gradCoord(seed2, i + (xNMask & (PRIME_X << 1)), j + PRIME_Y, k + PRIME_Z, x4, y1, z1);
|
||||
skip5 = true;
|
||||
}
|
||||
}
|
||||
|
||||
boolean skip9 = false;
|
||||
double a6 = yAFlipMask0 + a0;
|
||||
if(a6 > 0) {
|
||||
double y6 = y0 - (yNMask | 1);
|
||||
value += (a6 * a6) * (a6 * a6) * gradCoord(seed, i + (xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (zNMask & PRIME_Z), x0, y6,
|
||||
z0);
|
||||
} else {
|
||||
double a7 = xAFlipMask0 + zAFlipMask0 + a0;
|
||||
if(a7 > 0) {
|
||||
double x7 = x0 - (xNMask | 1);
|
||||
double z7 = z0 - (zNMask | 1);
|
||||
value += (a7 * a7) * (a7 * a7) * gradCoord(seed, i + (~xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (~zNMask & PRIME_Z), x7,
|
||||
y0, z7);
|
||||
}
|
||||
|
||||
double a8 = yAFlipMask1 + a1;
|
||||
if(a8 > 0) {
|
||||
double y8 = (yNMask | 1) + y1;
|
||||
value += (a8 * a8) * (a8 * a8) * gradCoord(seed2, i + PRIME_X, j + (yNMask & (PRIME_Y << 1)), k + PRIME_Z, x1, y8, z1);
|
||||
skip9 = true;
|
||||
}
|
||||
}
|
||||
|
||||
boolean skipD = false;
|
||||
double aA = zAFlipMask0 + a0;
|
||||
if(aA > 0) {
|
||||
double zA = z0 - (zNMask | 1);
|
||||
value += (aA * aA) * (aA * aA) * gradCoord(seed, i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (~zNMask & PRIME_Z), x0, y0,
|
||||
zA);
|
||||
} else {
|
||||
double aB = xAFlipMask0 + yAFlipMask0 + a0;
|
||||
if(aB > 0) {
|
||||
double xB = x0 - (xNMask | 1);
|
||||
double yB = y0 - (yNMask | 1);
|
||||
value += (aB * aB) * (aB * aB) * gradCoord(seed, i + (~xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (zNMask & PRIME_Z), xB,
|
||||
yB, z0);
|
||||
}
|
||||
|
||||
double aC = zAFlipMask1 + a1;
|
||||
if(aC > 0) {
|
||||
double zC = (zNMask | 1) + z1;
|
||||
value += (aC * aC) * (aC * aC) * gradCoord(seed2, i + PRIME_X, j + PRIME_Y, k + (zNMask & (PRIME_Z << 1)), x1, y1, zC);
|
||||
skipD = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!skip5) {
|
||||
double a5 = yAFlipMask1 + zAFlipMask1 + a1;
|
||||
if(a5 > 0) {
|
||||
double y5 = (yNMask | 1) + y1;
|
||||
double z5 = (zNMask | 1) + z1;
|
||||
value += (a5 * a5) * (a5 * a5) * gradCoord(seed2, i + PRIME_X, j + (yNMask & (PRIME_Y << 1)), k + (zNMask & (PRIME_Z << 1)),
|
||||
x1, y5, z5);
|
||||
}
|
||||
}
|
||||
|
||||
if(!skip9) {
|
||||
double a9 = xAFlipMask1 + zAFlipMask1 + a1;
|
||||
if(a9 > 0) {
|
||||
double x9 = (xNMask | 1) + x1;
|
||||
double z9 = (zNMask | 1) + z1;
|
||||
value += (a9 * a9) * (a9 * a9) * gradCoord(seed2, i + (xNMask & (PRIME_X << 1)), j + PRIME_Y, k + (zNMask & (PRIME_Z << 1)), x9,
|
||||
y1, z9);
|
||||
}
|
||||
}
|
||||
|
||||
if(!skipD) {
|
||||
double aD = xAFlipMask1 + yAFlipMask1 + a1;
|
||||
if(aD > 0) {
|
||||
double xD = (xNMask | 1) + x1;
|
||||
double yD = (yNMask | 1) + y1;
|
||||
value += (aD * aD) * (aD * aD) * gradCoord(seed2, i + (xNMask & (PRIME_X << 1)), j + (yNMask & (PRIME_Y << 1)), k + PRIME_Z,
|
||||
xD, yD, z1);
|
||||
}
|
||||
}
|
||||
|
||||
return value * 9.046026385208288;
|
||||
}
|
||||
}
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.simplex;
|
||||
|
||||
/**
|
||||
* NoiseSampler implementation to provide OpenSimplex2 noise.
|
||||
*/
|
||||
public class OpenSimplex2Sampler extends SimplexStyleSampler {
|
||||
private static final double SQRT3 = 1.7320508075688772935274463415059;
|
||||
|
||||
public OpenSimplex2Sampler(int seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
// 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex.
|
||||
final double G2 = (3 - SQRT3) / 6;
|
||||
|
||||
final double F2 = 0.5f * (SQRT3 - 1);
|
||||
double s = (x + y) * F2;
|
||||
x += s;
|
||||
y += s;
|
||||
|
||||
|
||||
int i = fastFloor(x);
|
||||
int j = fastFloor(y);
|
||||
double xi = x - i;
|
||||
double yi = y - j;
|
||||
|
||||
double t = (xi + yi) * G2;
|
||||
double x0 = xi - t;
|
||||
double y0 = yi - t;
|
||||
|
||||
i *= PRIME_X;
|
||||
j *= PRIME_Y;
|
||||
|
||||
double n0, n1, n2;
|
||||
|
||||
double a = 0.5 - x0 * x0 - y0 * y0;
|
||||
if(a <= 0) n0 = 0;
|
||||
else {
|
||||
n0 = (a * a) * (a * a) * gradCoord(seed, i, j, x0, y0);
|
||||
}
|
||||
|
||||
double c = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
|
||||
if(c <= 0) n2 = 0;
|
||||
else {
|
||||
double x2 = x0 + (2 * G2 - 1);
|
||||
double y2 = y0 + (2 * G2 - 1);
|
||||
n2 = (c * c) * (c * c) * gradCoord(seed, i + PRIME_X, j + PRIME_Y, x2, y2);
|
||||
}
|
||||
|
||||
if(y0 > x0) {
|
||||
double x1 = x0 + G2;
|
||||
double y1 = y0 + (G2 - 1);
|
||||
double b = 0.5 - x1 * x1 - y1 * y1;
|
||||
if(b <= 0) n1 = 0;
|
||||
else {
|
||||
n1 = (b * b) * (b * b) * gradCoord(seed, i, j + PRIME_Y, x1, y1);
|
||||
}
|
||||
} else {
|
||||
double x1 = x0 + (G2 - 1);
|
||||
double y1 = y0 + G2;
|
||||
double b = 0.5 - x1 * x1 - y1 * y1;
|
||||
if(b <= 0) n1 = 0;
|
||||
else {
|
||||
n1 = (b * b) * (b * b) * gradCoord(seed, i + PRIME_X, j, x1, y1);
|
||||
}
|
||||
}
|
||||
|
||||
return (n0 + n1 + n2) * 99.83685446303647f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
// 3D OpenSimplex2Sampler case uses two offset rotated cube grids.
|
||||
final double R3 = (2.0 / 3.0);
|
||||
double r = (x + y + z) * R3; // Rotation, not skew
|
||||
x = r - x;
|
||||
y = r - y;
|
||||
z = r - z;
|
||||
|
||||
|
||||
int i = fastRound(x);
|
||||
int j = fastRound(y);
|
||||
int k = fastRound(z);
|
||||
double x0 = x - i;
|
||||
double y0 = y - j;
|
||||
double z0 = z - k;
|
||||
|
||||
int xNSign = (int) (-1.0 - x0) | 1;
|
||||
int yNSign = (int) (-1.0 - y0) | 1;
|
||||
int zNSign = (int) (-1.0 - z0) | 1;
|
||||
|
||||
double ax0 = xNSign * -x0;
|
||||
double ay0 = yNSign * -y0;
|
||||
double az0 = zNSign * -z0;
|
||||
|
||||
i *= PRIME_X;
|
||||
j *= PRIME_Y;
|
||||
k *= PRIME_Z;
|
||||
|
||||
double value = 0;
|
||||
double a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0);
|
||||
|
||||
for(int l = 0; ; l++) {
|
||||
if(a > 0) {
|
||||
value += (a * a) * (a * a) * gradCoord(seed, i, j, k, x0, y0, z0);
|
||||
}
|
||||
|
||||
if(ax0 >= ay0 && ax0 >= az0) {
|
||||
double b = a + ax0 + ax0;
|
||||
if(b > 1) {
|
||||
b -= 1;
|
||||
value += (b * b) * (b * b) * gradCoord(seed, i - xNSign * PRIME_X, j, k, x0 + xNSign, y0, z0);
|
||||
}
|
||||
} else if(ay0 > ax0 && ay0 >= az0) {
|
||||
double b = a + ay0 + ay0;
|
||||
if(b > 1) {
|
||||
b -= 1;
|
||||
value += (b * b) * (b * b) * gradCoord(seed, i, j - yNSign * PRIME_Y, k, x0, y0 + yNSign, z0);
|
||||
}
|
||||
} else {
|
||||
double b = a + az0 + az0;
|
||||
if(b > 1) {
|
||||
b -= 1;
|
||||
value += (b * b) * (b * b) * gradCoord(seed, i, j, k - zNSign * PRIME_Z, x0, y0, z0 + zNSign);
|
||||
}
|
||||
}
|
||||
|
||||
if(l == 1) break;
|
||||
|
||||
ax0 = 0.5 - ax0;
|
||||
ay0 = 0.5 - ay0;
|
||||
az0 = 0.5 - az0;
|
||||
|
||||
x0 = xNSign * ax0;
|
||||
y0 = yNSign * ay0;
|
||||
z0 = zNSign * az0;
|
||||
|
||||
a += (0.75 - ax0) - (ay0 + az0);
|
||||
|
||||
i += (xNSign >> 1) & PRIME_X;
|
||||
j += (yNSign >> 1) & PRIME_Y;
|
||||
k += (zNSign >> 1) & PRIME_Z;
|
||||
|
||||
xNSign = -xNSign;
|
||||
yNSign = -yNSign;
|
||||
zNSign = -zNSign;
|
||||
|
||||
seed = ~seed;
|
||||
}
|
||||
|
||||
return value * 32.69428253173828125;
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.simplex;
|
||||
|
||||
/**
|
||||
* NoiseSampler implementation to provide Perlin Noise.
|
||||
*/
|
||||
public class PerlinSampler extends SimplexStyleSampler {
|
||||
public PerlinSampler(int seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
int x0 = fastFloor(x);
|
||||
int y0 = fastFloor(y);
|
||||
|
||||
double xd0 = x - x0;
|
||||
double yd0 = y - y0;
|
||||
double xd1 = xd0 - 1;
|
||||
double yd1 = yd0 - 1;
|
||||
|
||||
double xs = interpQuintic(xd0);
|
||||
double ys = interpQuintic(yd0);
|
||||
|
||||
x0 *= PRIME_X;
|
||||
y0 *= PRIME_Y;
|
||||
int x1 = x0 + PRIME_X;
|
||||
int y1 = y0 + PRIME_Y;
|
||||
|
||||
double xf0 = lerp(gradCoord(seed, x0, y0, xd0, yd0), gradCoord(seed, x1, y0, xd1, yd0), xs);
|
||||
double xf1 = lerp(gradCoord(seed, x0, y1, xd0, yd1), gradCoord(seed, x1, y1, xd1, yd1), xs);
|
||||
|
||||
return lerp(xf0, xf1, ys) * 1.4247691104677813;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
int x0 = fastFloor(x);
|
||||
int y0 = fastFloor(y);
|
||||
int z0 = fastFloor(z);
|
||||
|
||||
double xd0 = x - x0;
|
||||
double yd0 = y - y0;
|
||||
double zd0 = z - z0;
|
||||
double xd1 = xd0 - 1;
|
||||
double yd1 = yd0 - 1;
|
||||
double zd1 = zd0 - 1;
|
||||
|
||||
double xs = interpQuintic(xd0);
|
||||
double ys = interpQuintic(yd0);
|
||||
double zs = interpQuintic(zd0);
|
||||
|
||||
x0 *= PRIME_X;
|
||||
y0 *= PRIME_Y;
|
||||
z0 *= PRIME_Z;
|
||||
int x1 = x0 + PRIME_X;
|
||||
int y1 = y0 + PRIME_Y;
|
||||
int z1 = z0 + PRIME_Z;
|
||||
|
||||
double xf00 = lerp(gradCoord(seed, x0, y0, z0, xd0, yd0, zd0), gradCoord(seed, x1, y0, z0, xd1, yd0, zd0), xs);
|
||||
double xf10 = lerp(gradCoord(seed, x0, y1, z0, xd0, yd1, zd0), gradCoord(seed, x1, y1, z0, xd1, yd1, zd0), xs);
|
||||
double xf01 = lerp(gradCoord(seed, x0, y0, z1, xd0, yd0, zd1), gradCoord(seed, x1, y0, z1, xd1, yd0, zd1), xs);
|
||||
double xf11 = lerp(gradCoord(seed, x0, y1, z1, xd0, yd1, zd1), gradCoord(seed, x1, y1, z1, xd1, yd1, zd1), xs);
|
||||
|
||||
double yf0 = lerp(xf00, xf10, ys);
|
||||
double yf1 = lerp(xf01, xf11, ys);
|
||||
|
||||
return lerp(yf0, yf1, zs) * 0.964921414852142333984375;
|
||||
}
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.simplex;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction;
|
||||
|
||||
/**
|
||||
* Abstract NoiseSampler implementation for simplex-style noise functions.
|
||||
*/
|
||||
public abstract class SimplexStyleSampler extends NoiseFunction {
|
||||
protected static final double[] GRADIENTS_2_D = {
|
||||
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
|
||||
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
|
||||
0.99144486137381d, -0.130526192220051d, 0.923879532511287d, -0.38268343236509d, 0.793353340291235d, -0.60876142900872d,
|
||||
0.608761429008721d, -0.793353340291235d, 0.38268343236509d, -0.923879532511287d, 0.130526192220052d, -0.99144486137381d,
|
||||
-0.130526192220052d, -0.99144486137381d, -0.38268343236509d, -0.923879532511287d, -0.608761429008721d, -0.793353340291235d,
|
||||
-0.793353340291235d, -0.608761429008721d, -0.923879532511287d, -0.38268343236509d, -0.99144486137381d, -0.130526192220052d,
|
||||
-0.99144486137381d, 0.130526192220051d, -0.923879532511287d, 0.38268343236509d, -0.793353340291235d, 0.608761429008721d,
|
||||
-0.608761429008721d, 0.793353340291235d, -0.38268343236509d, 0.923879532511287d, -0.130526192220052d, 0.99144486137381d,
|
||||
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
|
||||
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
|
||||
0.99144486137381d, -0.130526192220051d, 0.923879532511287d, -0.38268343236509d, 0.793353340291235d, -0.60876142900872d,
|
||||
0.608761429008721d, -0.793353340291235d, 0.38268343236509d, -0.923879532511287d, 0.130526192220052d, -0.99144486137381d,
|
||||
-0.130526192220052d, -0.99144486137381d, -0.38268343236509d, -0.923879532511287d, -0.608761429008721d, -0.793353340291235d,
|
||||
-0.793353340291235d, -0.608761429008721d, -0.923879532511287d, -0.38268343236509d, -0.99144486137381d, -0.130526192220052d,
|
||||
-0.99144486137381d, 0.130526192220051d, -0.923879532511287d, 0.38268343236509d, -0.793353340291235d, 0.608761429008721d,
|
||||
-0.608761429008721d, 0.793353340291235d, -0.38268343236509d, 0.923879532511287d, -0.130526192220052d, 0.99144486137381d,
|
||||
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
|
||||
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
|
||||
0.99144486137381d, -0.130526192220051d, 0.923879532511287d, -0.38268343236509d, 0.793353340291235d, -0.60876142900872d,
|
||||
0.608761429008721d, -0.793353340291235d, 0.38268343236509d, -0.923879532511287d, 0.130526192220052d, -0.99144486137381d,
|
||||
-0.130526192220052d, -0.99144486137381d, -0.38268343236509d, -0.923879532511287d, -0.608761429008721d, -0.793353340291235d,
|
||||
-0.793353340291235d, -0.608761429008721d, -0.923879532511287d, -0.38268343236509d, -0.99144486137381d, -0.130526192220052d,
|
||||
-0.99144486137381d, 0.130526192220051d, -0.923879532511287d, 0.38268343236509d, -0.793353340291235d, 0.608761429008721d,
|
||||
-0.608761429008721d, 0.793353340291235d, -0.38268343236509d, 0.923879532511287d, -0.130526192220052d, 0.99144486137381d,
|
||||
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
|
||||
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
|
||||
0.99144486137381d, -0.130526192220051d, 0.923879532511287d, -0.38268343236509d, 0.793353340291235d, -0.60876142900872d,
|
||||
0.608761429008721d, -0.793353340291235d, 0.38268343236509d, -0.923879532511287d, 0.130526192220052d, -0.99144486137381d,
|
||||
-0.130526192220052d, -0.99144486137381d, -0.38268343236509d, -0.923879532511287d, -0.608761429008721d, -0.793353340291235d,
|
||||
-0.793353340291235d, -0.608761429008721d, -0.923879532511287d, -0.38268343236509d, -0.99144486137381d, -0.130526192220052d,
|
||||
-0.99144486137381d, 0.130526192220051d, -0.923879532511287d, 0.38268343236509d, -0.793353340291235d, 0.608761429008721d,
|
||||
-0.608761429008721d, 0.793353340291235d, -0.38268343236509d, 0.923879532511287d, -0.130526192220052d, 0.99144486137381d,
|
||||
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
|
||||
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
|
||||
0.99144486137381d, -0.130526192220051d, 0.923879532511287d, -0.38268343236509d, 0.793353340291235d, -0.60876142900872d,
|
||||
0.608761429008721d, -0.793353340291235d, 0.38268343236509d, -0.923879532511287d, 0.130526192220052d, -0.99144486137381d,
|
||||
-0.130526192220052d, -0.99144486137381d, -0.38268343236509d, -0.923879532511287d, -0.608761429008721d, -0.793353340291235d,
|
||||
-0.793353340291235d, -0.608761429008721d, -0.923879532511287d, -0.38268343236509d, -0.99144486137381d, -0.130526192220052d,
|
||||
-0.99144486137381d, 0.130526192220051d, -0.923879532511287d, 0.38268343236509d, -0.793353340291235d, 0.608761429008721d,
|
||||
-0.608761429008721d, 0.793353340291235d, -0.38268343236509d, 0.923879532511287d, -0.130526192220052d, 0.99144486137381d,
|
||||
0.38268343236509d, 0.923879532511287d, 0.923879532511287d, 0.38268343236509d, 0.923879532511287d, -0.38268343236509d,
|
||||
0.38268343236509d, -0.923879532511287d, -0.38268343236509d, -0.923879532511287d, -0.923879532511287d, -0.38268343236509d,
|
||||
-0.923879532511287d, 0.38268343236509d, -0.38268343236509d, 0.923879532511287d,
|
||||
};
|
||||
|
||||
protected static final double[] GRADIENTS_3D = {
|
||||
0, 1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0,
|
||||
1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0, -1, 0, -1, 0,
|
||||
1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0, 0,
|
||||
0, 1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0,
|
||||
1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0, -1, 0, -1, 0,
|
||||
1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0, 0,
|
||||
0, 1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0,
|
||||
1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0, -1, 0, -1, 0,
|
||||
1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0, 0,
|
||||
0, 1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0,
|
||||
1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0, -1, 0, -1, 0,
|
||||
1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0, 0,
|
||||
0, 1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0,
|
||||
1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0, -1, 0, -1, 0,
|
||||
1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0, 0,
|
||||
1, 1, 0, 0, 0, -1, 1, 0, -1, 1, 0, 0, 0, -1, -1, 0
|
||||
};
|
||||
|
||||
public SimplexStyleSampler(int seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
protected static double gradCoord(int seed, int xPrimed, int yPrimed, double xd, double yd) {
|
||||
int hash = hash(seed, xPrimed, yPrimed);
|
||||
hash ^= hash >> 15;
|
||||
hash &= 127 << 1;
|
||||
|
||||
double xg = GRADIENTS_2_D[hash];
|
||||
double yg = GRADIENTS_2_D[hash | 1];
|
||||
|
||||
return xd * xg + yd * yg;
|
||||
}
|
||||
|
||||
protected static double gradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, double xd, double yd, double zd) {
|
||||
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
|
||||
hash ^= hash >> 15;
|
||||
hash &= 63 << 2;
|
||||
|
||||
double xg = GRADIENTS_3D[hash];
|
||||
double yg = GRADIENTS_3D[hash | 1];
|
||||
double zg = GRADIENTS_3D[hash | 2];
|
||||
|
||||
return xd * xg + yd * yg + zd * zg;
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.value;
|
||||
|
||||
public class ValueCubicSampler extends ValueStyleNoise {
|
||||
public ValueCubicSampler(int seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
int x1 = fastFloor(x);
|
||||
int y1 = fastFloor(y);
|
||||
|
||||
double xs = x - x1;
|
||||
double ys = y - y1;
|
||||
|
||||
x1 *= PRIME_X;
|
||||
y1 *= PRIME_Y;
|
||||
int x0 = x1 - PRIME_X;
|
||||
int y0 = y1 - PRIME_Y;
|
||||
int x2 = x1 + PRIME_X;
|
||||
int y2 = y1 + PRIME_Y;
|
||||
int x3 = x1 + (PRIME_X << 1);
|
||||
int y3 = y1 + (PRIME_Y << 1);
|
||||
|
||||
return cubicLerp(
|
||||
cubicLerp(valCoord(seed, x0, y0), valCoord(seed, x1, y0), valCoord(seed, x2, y0), valCoord(seed, x3, y0),
|
||||
xs),
|
||||
cubicLerp(valCoord(seed, x0, y1), valCoord(seed, x1, y1), valCoord(seed, x2, y1), valCoord(seed, x3, y1),
|
||||
xs),
|
||||
cubicLerp(valCoord(seed, x0, y2), valCoord(seed, x1, y2), valCoord(seed, x2, y2), valCoord(seed, x3, y2),
|
||||
xs),
|
||||
cubicLerp(valCoord(seed, x0, y3), valCoord(seed, x1, y3), valCoord(seed, x2, y3), valCoord(seed, x3, y3),
|
||||
xs),
|
||||
ys) * (1 / (1.5 * 1.5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
int x1 = fastFloor(x);
|
||||
int y1 = fastFloor(y);
|
||||
int z1 = fastFloor(z);
|
||||
|
||||
double xs = x - x1;
|
||||
double ys = y - y1;
|
||||
double zs = z - z1;
|
||||
|
||||
x1 *= PRIME_X;
|
||||
y1 *= PRIME_Y;
|
||||
z1 *= PRIME_Z;
|
||||
|
||||
int x0 = x1 - PRIME_X;
|
||||
int y0 = y1 - PRIME_Y;
|
||||
int z0 = z1 - PRIME_Z;
|
||||
int x2 = x1 + PRIME_X;
|
||||
int y2 = y1 + PRIME_Y;
|
||||
int z2 = z1 + PRIME_Z;
|
||||
int x3 = x1 + (PRIME_X << 1);
|
||||
int y3 = y1 + (PRIME_Y << 1);
|
||||
int z3 = z1 + (PRIME_Z << 1);
|
||||
|
||||
return cubicLerp(
|
||||
cubicLerp(
|
||||
cubicLerp(valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0), valCoord(seed, x2, y0, z0),
|
||||
valCoord(seed, x3, y0, z0), xs),
|
||||
cubicLerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), valCoord(seed, x2, y1, z0),
|
||||
valCoord(seed, x3, y1, z0), xs),
|
||||
cubicLerp(valCoord(seed, x0, y2, z0), valCoord(seed, x1, y2, z0), valCoord(seed, x2, y2, z0),
|
||||
valCoord(seed, x3, y2, z0), xs),
|
||||
cubicLerp(valCoord(seed, x0, y3, z0), valCoord(seed, x1, y3, z0), valCoord(seed, x2, y3, z0),
|
||||
valCoord(seed, x3, y3, z0), xs),
|
||||
ys),
|
||||
cubicLerp(
|
||||
cubicLerp(valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1), valCoord(seed, x2, y0, z1),
|
||||
valCoord(seed, x3, y0, z1), xs),
|
||||
cubicLerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), valCoord(seed, x2, y1, z1),
|
||||
valCoord(seed, x3, y1, z1), xs),
|
||||
cubicLerp(valCoord(seed, x0, y2, z1), valCoord(seed, x1, y2, z1), valCoord(seed, x2, y2, z1),
|
||||
valCoord(seed, x3, y2, z1), xs),
|
||||
cubicLerp(valCoord(seed, x0, y3, z1), valCoord(seed, x1, y3, z1), valCoord(seed, x2, y3, z1),
|
||||
valCoord(seed, x3, y3, z1), xs),
|
||||
ys),
|
||||
cubicLerp(
|
||||
cubicLerp(valCoord(seed, x0, y0, z2), valCoord(seed, x1, y0, z2), valCoord(seed, x2, y0, z2),
|
||||
valCoord(seed, x3, y0, z2), xs),
|
||||
cubicLerp(valCoord(seed, x0, y1, z2), valCoord(seed, x1, y1, z2), valCoord(seed, x2, y1, z2),
|
||||
valCoord(seed, x3, y1, z2), xs),
|
||||
cubicLerp(valCoord(seed, x0, y2, z2), valCoord(seed, x1, y2, z2), valCoord(seed, x2, y2, z2),
|
||||
valCoord(seed, x3, y2, z2), xs),
|
||||
cubicLerp(valCoord(seed, x0, y3, z2), valCoord(seed, x1, y3, z2), valCoord(seed, x2, y3, z2),
|
||||
valCoord(seed, x3, y3, z2), xs),
|
||||
ys),
|
||||
cubicLerp(
|
||||
cubicLerp(valCoord(seed, x0, y0, z3), valCoord(seed, x1, y0, z3), valCoord(seed, x2, y0, z3),
|
||||
valCoord(seed, x3, y0, z3), xs),
|
||||
cubicLerp(valCoord(seed, x0, y1, z3), valCoord(seed, x1, y1, z3), valCoord(seed, x2, y1, z3),
|
||||
valCoord(seed, x3, y1, z3), xs),
|
||||
cubicLerp(valCoord(seed, x0, y2, z3), valCoord(seed, x1, y2, z3), valCoord(seed, x2, y2, z3),
|
||||
valCoord(seed, x3, y2, z3), xs),
|
||||
cubicLerp(valCoord(seed, x0, y3, z3), valCoord(seed, x1, y3, z3), valCoord(seed, x2, y3, z3),
|
||||
valCoord(seed, x3, y3, z3), xs),
|
||||
ys),
|
||||
zs) * (1 / (1.5 * 1.5 * 1.5));
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.value;
|
||||
|
||||
public class ValueSampler extends ValueStyleNoise {
|
||||
public ValueSampler(int seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y) {
|
||||
int x0 = fastFloor(x);
|
||||
int y0 = fastFloor(y);
|
||||
|
||||
double xs = interpHermite(x - x0);
|
||||
double ys = interpHermite(y - y0);
|
||||
|
||||
x0 *= PRIME_X;
|
||||
y0 *= PRIME_Y;
|
||||
int x1 = x0 + PRIME_X;
|
||||
int y1 = y0 + PRIME_Y;
|
||||
|
||||
double xf0 = lerp(valCoord(seed, x0, y0), valCoord(seed, x1, y0), xs);
|
||||
double xf1 = lerp(valCoord(seed, x0, y1), valCoord(seed, x1, y1), xs);
|
||||
|
||||
return lerp(xf0, xf1, ys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(int seed, double x, double y, double z) {
|
||||
int x0 = fastFloor(x);
|
||||
int y0 = fastFloor(y);
|
||||
int z0 = fastFloor(z);
|
||||
|
||||
double xs = interpHermite(x - x0);
|
||||
double ys = interpHermite(y - y0);
|
||||
double zs = interpHermite(z - z0);
|
||||
|
||||
x0 *= PRIME_X;
|
||||
y0 *= PRIME_Y;
|
||||
z0 *= PRIME_Z;
|
||||
int x1 = x0 + PRIME_X;
|
||||
int y1 = y0 + PRIME_Y;
|
||||
int z1 = z0 + PRIME_Z;
|
||||
|
||||
double xf00 = lerp(valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0), xs);
|
||||
double xf10 = lerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), xs);
|
||||
double xf01 = lerp(valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1), xs);
|
||||
double xf11 = lerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), xs);
|
||||
|
||||
double yf0 = lerp(xf00, xf10, ys);
|
||||
double yf1 = lerp(xf01, xf11, ys);
|
||||
|
||||
return lerp(yf0, yf1, zs);
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.dfsek.terra.api.math.noise.samplers.noise.value;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction;
|
||||
|
||||
public abstract class ValueStyleNoise extends NoiseFunction {
|
||||
public ValueStyleNoise(int seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
protected static double valCoord(int seed, int xPrimed, int yPrimed) {
|
||||
int hash = hash(seed, xPrimed, yPrimed);
|
||||
|
||||
hash *= hash;
|
||||
hash ^= hash << 19;
|
||||
return hash * (1 / 2147483648.0);
|
||||
}
|
||||
|
||||
protected static double valCoord(int seed, int xPrimed, int yPrimed, int zPrimed) {
|
||||
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
|
||||
|
||||
hash *= hash;
|
||||
hash ^= hash << 19;
|
||||
return hash * (1 / 2147483648.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.dfsek.terra.api.math.paralithic;
|
||||
|
||||
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
|
||||
public class BlankFunction implements DynamicFunction {
|
||||
private final int args;
|
||||
|
||||
public BlankFunction(int args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArgNumber() {
|
||||
return args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double... d) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStateless() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.dfsek.terra.api.math.paralithic.defined;
|
||||
|
||||
import com.dfsek.paralithic.Expression;
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
|
||||
|
||||
public class UserDefinedFunction implements DynamicFunction {
|
||||
private final Expression expression;
|
||||
private final int args;
|
||||
|
||||
protected UserDefinedFunction(Expression expression, int args) {
|
||||
this.expression = expression;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double eval(double... args) {
|
||||
return expression.evaluate(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStateless() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArgNumber() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public static UserDefinedFunction newInstance(FunctionTemplate template, Parser parser, Scope parent) throws ParseException {
|
||||
|
||||
Scope functionScope = new Scope().withParent(parent);
|
||||
|
||||
template.getArgs().forEach(functionScope::addInvocationVariable);
|
||||
|
||||
return new UserDefinedFunction(parser.parse(template.getFunction(), functionScope), template.getArgs().size());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.dfsek.terra.api.math.paralithic.noise;
|
||||
|
||||
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
|
||||
public interface NoiseFunction extends DynamicFunction {
|
||||
}
|
||||
+13
-21
@@ -1,42 +1,30 @@
|
||||
package com.dfsek.terra.api.math.parsii.noise;
|
||||
package com.dfsek.terra.api.math.paralithic.noise;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.util.hash.HashMapDoubleDouble;
|
||||
import parsii.eval.Expression;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class NoiseFunction2 implements NoiseFunction {
|
||||
private final NoiseSampler gen;
|
||||
private final Cache cache = new Cache();
|
||||
|
||||
public NoiseFunction2(long seed, NoiseSeeded builder) {
|
||||
this.gen = builder.apply(seed);
|
||||
public NoiseFunction2(NoiseSampler gen) {
|
||||
this.gen = gen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfArguments() {
|
||||
public int getArgNumber() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(List<Expression> list) {
|
||||
return cache.get(gen, list.get(0).evaluate(), list.get(1).evaluate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate without cache. For testing.
|
||||
*
|
||||
* @param list Parameters.
|
||||
* @return Result.
|
||||
*/
|
||||
public double evalNoCache(List<Expression> list) {
|
||||
return gen.getNoise(list.get(0).evaluate(), list.get(1).evaluate());
|
||||
public double eval(double... args) {
|
||||
return cache.get(gen, args[0], args[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNaturalFunction() {
|
||||
public boolean isStateless() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,6 +32,10 @@ public class NoiseFunction2 implements NoiseFunction {
|
||||
private static final long serialVersionUID = 8915092734723467010L;
|
||||
private static final int cacheSize = 384;
|
||||
|
||||
public Cache() {
|
||||
super(cacheSize);
|
||||
}
|
||||
|
||||
public double get(NoiseSampler noise, double x, double z) {
|
||||
double xx = x >= 0 ? x * 2 : x * -2 - 1;
|
||||
double zz = z >= 0 ? z * 2 : z * -2 - 1;
|
||||
@@ -55,7 +47,7 @@ public class NoiseFunction2 implements NoiseFunction {
|
||||
return (value == 4.9E-324D ? addAndReturn(noise.getNoise(x, z), key) : value);
|
||||
}
|
||||
|
||||
private double addAndReturn(double value, double key) {
|
||||
private synchronized double addAndReturn(double value, double key) {
|
||||
this.put(key, value);
|
||||
return value;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.dfsek.terra.api.math.paralithic.noise;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
|
||||
public class NoiseFunction3 implements NoiseFunction {
|
||||
private final NoiseSampler gen;
|
||||
|
||||
public NoiseFunction3(NoiseSampler gen) {
|
||||
this.gen = gen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArgNumber() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double... args) {
|
||||
return gen.getNoise(args[0], args[1], args[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStateless() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.dfsek.terra.api.math.parsii;
|
||||
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BlankFunction implements Function {
|
||||
private final int args;
|
||||
|
||||
public BlankFunction(int args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfArguments() {
|
||||
return args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(List<Expression> list) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNaturalFunction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
package com.dfsek.terra.api.math.parsii.defined;
|
||||
|
||||
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
||||
|
||||
public class DefinedFunctionTemplate implements SeededBuilder<UserDefinedFunction> {
|
||||
@Override
|
||||
public UserDefinedFunction apply(Long aLong) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.dfsek.terra.api.math.parsii.defined;
|
||||
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Function;
|
||||
import parsii.eval.Variable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserDefinedFunction implements Function {
|
||||
private final Expression expression;
|
||||
private final List<Variable> variables;
|
||||
|
||||
public UserDefinedFunction(Expression expression, List<Variable> variables) {
|
||||
this.expression = expression;
|
||||
this.variables = variables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfArguments() {
|
||||
return variables.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double eval(List<Expression> args) {
|
||||
for(int i = 0; i < variables.size(); i++) {
|
||||
variables.get(i).setValue(args.get(i).evaluate());
|
||||
}
|
||||
return expression.evaluate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNaturalFunction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package com.dfsek.terra.api.math.parsii.noise;
|
||||
|
||||
import parsii.eval.Function;
|
||||
|
||||
public interface NoiseFunction extends Function {
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.dfsek.terra.api.math.parsii.noise;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import parsii.eval.Expression;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NoiseFunction3 implements NoiseFunction {
|
||||
private final NoiseSampler gen;
|
||||
|
||||
public NoiseFunction3(long seed, NoiseSeeded builder) {
|
||||
this.gen = builder.apply(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfArguments() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(List<Expression> list) {
|
||||
return gen.getNoise(list.get(0).evaluate(), list.get(1).evaluate(), list.get(2).evaluate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNaturalFunction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import net.jafama.FastMath;
|
||||
/**
|
||||
* oh yeah
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class Vector2 implements Cloneable {
|
||||
private double x;
|
||||
private double z;
|
||||
@@ -65,7 +64,7 @@ public class Vector2 implements Cloneable {
|
||||
/**
|
||||
* Add this vector to another.
|
||||
*
|
||||
* @param other Vector to increment
|
||||
* @param other Vector to add
|
||||
* @return Mutated vector, for chaining.
|
||||
*/
|
||||
public Vector2 add(Vector2 other) {
|
||||
|
||||
@@ -5,6 +5,9 @@ import com.dfsek.terra.api.platform.world.World;
|
||||
import net.jafama.FastMath;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* 3D Mutable Vector
|
||||
*/
|
||||
public class Vector3 implements Cloneable {
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ public interface BiomeGrid extends Handle {
|
||||
*
|
||||
* @param x - 0-15
|
||||
* @param z - 0-15
|
||||
* @return TerraBiome value
|
||||
* @return Biome value
|
||||
*/
|
||||
@NotNull
|
||||
Biome getBiome(int x, int z);
|
||||
@@ -20,7 +20,7 @@ public interface BiomeGrid extends Handle {
|
||||
* @param x - 0-15
|
||||
* @param y - 0-255
|
||||
* @param z - 0-15
|
||||
* @return TerraBiome value
|
||||
* @return Biome value
|
||||
*/
|
||||
@NotNull
|
||||
Biome getBiome(int x, int y, int z);
|
||||
@@ -30,7 +30,7 @@ public interface BiomeGrid extends Handle {
|
||||
*
|
||||
* @param x - 0-15
|
||||
* @param z - 0-15
|
||||
* @param bio - TerraBiome value
|
||||
* @param bio - Biome value
|
||||
*/
|
||||
void setBiome(int x, int z, @NotNull Biome bio);
|
||||
|
||||
@@ -40,7 +40,7 @@ public interface BiomeGrid extends Handle {
|
||||
* @param x - 0-15
|
||||
* @param y - 0-255
|
||||
* @param z - 0-15
|
||||
* @param bio - TerraBiome value
|
||||
* @param bio - Biome value
|
||||
*/
|
||||
void setBiome(int x, int y, int z, @NotNull Biome bio);
|
||||
}
|
||||
|
||||
+1
@@ -3,6 +3,7 @@ package com.dfsek.terra.api.structures.parser.exceptions;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
public class ParseException extends Exception {
|
||||
private static final long serialVersionUID = 6744390543046766386L;
|
||||
private final Position position;
|
||||
|
||||
public ParseException(String message, Position position) {
|
||||
|
||||
@@ -28,8 +28,9 @@ import com.dfsek.terra.api.structures.structure.Rotation;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.Buffer;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.DirectBuffer;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.StructureBuffer;
|
||||
import com.dfsek.terra.registry.LootRegistry;
|
||||
import com.dfsek.terra.registry.ScriptRegistry;
|
||||
import com.dfsek.terra.registry.FunctionRegistry;
|
||||
import com.dfsek.terra.registry.config.LootRegistry;
|
||||
import com.dfsek.terra.registry.config.ScriptRegistry;
|
||||
import com.dfsek.terra.world.generation.math.SamplerCache;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
@@ -44,11 +45,11 @@ import java.util.concurrent.ExecutionException;
|
||||
public class StructureScript {
|
||||
private final Block block;
|
||||
private final String id;
|
||||
String tempID;
|
||||
private final Cache<Location, StructureBuffer> cache;
|
||||
private final TerraPlugin main;
|
||||
String tempID;
|
||||
|
||||
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, SamplerCache cache) throws ParseException {
|
||||
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, SamplerCache cache, FunctionRegistry functionRegistry) throws ParseException {
|
||||
Parser parser;
|
||||
try {
|
||||
parser = new Parser(IOUtils.toString(inputStream));
|
||||
@@ -85,6 +86,8 @@ public class StructureScript {
|
||||
.registerFunction("max", new BinaryNumberFunctionBuilder((number, number2) -> FastMath.max(number.doubleValue(), number2.doubleValue())))
|
||||
.registerFunction("min", new BinaryNumberFunctionBuilder((number, number2) -> FastMath.min(number.doubleValue(), number2.doubleValue())));
|
||||
|
||||
functionRegistry.forEach(parser::registerFunction); // Register registry functions.
|
||||
|
||||
block = parser.parse();
|
||||
this.id = parser.getID();
|
||||
tempID = id;
|
||||
@@ -143,14 +146,12 @@ public class StructureScript {
|
||||
}
|
||||
|
||||
private boolean applyBlock(TerraImplementationArguments arguments) {
|
||||
synchronized(block) {
|
||||
try {
|
||||
return !block.apply(arguments).getLevel().equals(Block.ReturnLevel.FAIL);
|
||||
} catch(RuntimeException e) {
|
||||
main.getLogger().severe("Failed to generate structure at " + arguments.getBuffer().getOrigin() + ": " + e.getMessage());
|
||||
main.getDebugLogger().stack(e);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return !block.apply(arguments).getLevel().equals(Block.ReturnLevel.FAIL);
|
||||
} catch(RuntimeException e) {
|
||||
main.getLogger().severe("Failed to generate structure at " + arguments.getBuffer().getOrigin() + ": " + e.getMessage());
|
||||
main.getDebugLogger().stack(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.functions.LootFunction;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.registry.LootRegistry;
|
||||
import com.dfsek.terra.registry.config.LootRegistry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.functions.StructureFunction;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.registry.ScriptRegistry;
|
||||
import com.dfsek.terra.registry.config.ScriptRegistry;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedLootApplication;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.registry.LootRegistry;
|
||||
import com.dfsek.terra.registry.config.LootRegistry;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import com.dfsek.terra.api.structures.structure.Rotation;
|
||||
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.IntermediateBuffer;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.registry.ScriptRegistry;
|
||||
import com.dfsek.terra.registry.config.ScriptRegistry;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
+2
@@ -4,6 +4,8 @@ import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
public class EOFException extends TokenizerException {
|
||||
|
||||
private static final long serialVersionUID = 3980047409902809440L;
|
||||
|
||||
public EOFException(String message, Position position) {
|
||||
super(message, position);
|
||||
}
|
||||
|
||||
+2
@@ -4,6 +4,8 @@ import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
public class FormatException extends TokenizerException {
|
||||
|
||||
private static final long serialVersionUID = -791308012940744455L;
|
||||
|
||||
public FormatException(String message, Position position) {
|
||||
super(message, position);
|
||||
}
|
||||
|
||||
+2
@@ -5,6 +5,8 @@ import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
public abstract class TokenizerException extends ParseException {
|
||||
|
||||
private static final long serialVersionUID = 2792384010083575420L;
|
||||
|
||||
public TokenizerException(String message, Position position) {
|
||||
super(message, position);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.dfsek.terra.api.util.GlueList;
|
||||
import java.util.List;
|
||||
|
||||
public class AttemptsFailedException extends RuntimeException {
|
||||
private static final long serialVersionUID = -1160459550006067137L;
|
||||
private final List<Throwable> causes;
|
||||
|
||||
public AttemptsFailedException(String message, List<Throwable> causes) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.dfsek.terra.api.transform;
|
||||
|
||||
public class TransformException extends Exception {
|
||||
private static final long serialVersionUID = -6661338369581162084L;
|
||||
|
||||
public TransformException() {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class Transformer<F, T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Transformer<F, T> build() {
|
||||
public Transformer<F, T> build() {
|
||||
return new Transformer<>(transforms);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.SplittableRandom;
|
||||
|
||||
public class FastRandom extends Random {
|
||||
|
||||
private static final long serialVersionUID = 4571946470190183260L;
|
||||
private XoRoShiRo128PlusPlus random;
|
||||
|
||||
public FastRandom() {
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.dfsek.terra.api.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
@@ -76,14 +78,16 @@ import static net.jafama.FastMath.*;
|
||||
* @see ArrayList
|
||||
* @param <T> the type of elements held in this collection
|
||||
*/
|
||||
@SuppressWarnings({"ManualMinMaxCalculation", "ConstantConditions", "ManualArrayToCollectionCopy"})
|
||||
public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable, Serializable {
|
||||
|
||||
transient Node<T> first;
|
||||
transient Node<T> last;
|
||||
private static final long serialVersionUID = -4339173882660322249L;
|
||||
private transient Node<T> first;
|
||||
private transient Node<T> last;
|
||||
|
||||
int size;
|
||||
private int size;
|
||||
|
||||
int initialCapacity;
|
||||
private int initialCapacity;
|
||||
|
||||
private static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
@@ -236,7 +240,7 @@ public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable,
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends T> c) {
|
||||
public boolean addAll(@NotNull Collection<? extends T> c) {
|
||||
|
||||
Objects.requireNonNull(c);
|
||||
|
||||
@@ -244,7 +248,7 @@ public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable,
|
||||
|
||||
int len = collection.length;
|
||||
|
||||
if (len == 0) {
|
||||
if(len == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -426,7 +430,6 @@ public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable,
|
||||
return indexOf(o) != -1;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T remove(int index) {
|
||||
|
||||
@@ -499,12 +502,12 @@ public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable,
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
public boolean removeAll(@NotNull Collection<?> c) {
|
||||
|
||||
Objects.requireNonNull(c);
|
||||
|
||||
Object[] arr = c.toArray();
|
||||
if (arr.length == 0) {
|
||||
if(arr.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -518,12 +521,12 @@ public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable,
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
public boolean retainAll(@NotNull Collection<?> c) {
|
||||
|
||||
Objects.requireNonNull(c);
|
||||
|
||||
Object[] arr = c.toArray();
|
||||
if (arr.length == 0) {
|
||||
if(arr.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -663,7 +666,7 @@ public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable,
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> subList(int fromIndex, int toIndex) {
|
||||
public @NotNull List<T> subList(int fromIndex, int toIndex) {
|
||||
return super.subList(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
@@ -689,8 +692,8 @@ public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable,
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
return (T[]) Arrays.copyOf(toArray(), size, a.getClass());
|
||||
public <E> E[] toArray(E[] a) {
|
||||
return (E[]) Arrays.copyOf(toArray(), size, a.getClass());
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
@@ -698,7 +701,7 @@ public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable,
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
public @NotNull Iterator<T> iterator() {
|
||||
return new Itr();
|
||||
}
|
||||
|
||||
@@ -736,7 +739,7 @@ public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable,
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<T> listIterator(int index) {
|
||||
public @NotNull ListIterator<T> listIterator(int index) {
|
||||
|
||||
checkPositionIndex(index);
|
||||
|
||||
@@ -751,89 +754,65 @@ public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable,
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<T> listIterator() {
|
||||
public @NotNull ListIterator<T> listIterator() {
|
||||
return new ListItr(0);
|
||||
}
|
||||
|
||||
private class Itr implements Iterator<T> {
|
||||
protected static class Node<T> {
|
||||
|
||||
Node<T> node = first;
|
||||
protected Node<T> pre;
|
||||
protected Node<T> next;
|
||||
|
||||
int i = 0;//inner-array index
|
||||
int j = 0;//total index -> cursor
|
||||
protected int listSize;
|
||||
|
||||
int lastReturn = -1;
|
||||
protected int startingIndex;
|
||||
protected int endingIndex;
|
||||
|
||||
int expectedModCount = modCount;
|
||||
int elementDataPointer = node.elementDataPointer;
|
||||
protected T[] elementData;
|
||||
protected int elementDataPointer;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return j != size;
|
||||
@SuppressWarnings("unchecked")
|
||||
Node(Node<T> pre, Node<T> next, int listSize) {
|
||||
this.pre = pre;
|
||||
this.next = next;
|
||||
this.listSize = listSize;
|
||||
this.elementData = (T[]) new Object[listSize >>> 1];
|
||||
this.startingIndex = listSize;
|
||||
this.endingIndex = listSize + elementData.length - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
|
||||
checkForComodification();
|
||||
|
||||
if (j >= size) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
if (j >= last.endingIndex + 1) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
if (j == 0) {// it's for listIterator.when node becomes null.
|
||||
node = first;
|
||||
elementDataPointer = node.elementDataPointer;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
T val = node.elementData[i++];
|
||||
|
||||
if (i >= elementDataPointer) {
|
||||
node = node.next;
|
||||
i = 0;
|
||||
elementDataPointer = (node != null) ? node.elementDataPointer : 0;
|
||||
}
|
||||
|
||||
lastReturn = j++;
|
||||
|
||||
return val;
|
||||
Node(Node<T> pre, Node<T> next, int listSize, int initialCapacity) {
|
||||
this.pre = pre;
|
||||
this.next = next;
|
||||
this.listSize = listSize;
|
||||
this.elementData = createElementData(initialCapacity);
|
||||
this.startingIndex = listSize;
|
||||
this.endingIndex = listSize + elementData.length - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
@SuppressWarnings("unchecked")
|
||||
T[] createElementData(int capacity) {
|
||||
|
||||
if (lastReturn < 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
checkForComodification();
|
||||
|
||||
try {
|
||||
com.dfsek.terra.api.util.GlueList.this.remove(lastReturn);
|
||||
|
||||
j = lastReturn;
|
||||
|
||||
lastReturn = -1;
|
||||
|
||||
i = (--i < 0) ? 0 : i;
|
||||
|
||||
elementDataPointer = (node != null) ? node.elementDataPointer : 0;
|
||||
|
||||
expectedModCount = modCount;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
throw new ConcurrentModificationException();
|
||||
if(capacity == 0 || capacity == 1) {
|
||||
return (T[]) new Object[DEFAULT_CAPACITY];
|
||||
} else if(capacity > 1) {
|
||||
return (T[]) new Object[capacity];
|
||||
} else {
|
||||
throw new IllegalArgumentException("Illegal Capacity: " + capacity);
|
||||
}
|
||||
}
|
||||
|
||||
void checkForComodification() {
|
||||
if (modCount != expectedModCount) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
boolean isAddable() {
|
||||
return elementDataPointer < elementData.length;
|
||||
}
|
||||
|
||||
void add(T element) {
|
||||
elementData[elementDataPointer++] = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("[sIndex: %d - eIndex: %d | elementDataPointer: %d | elementDataLength: %d]", startingIndex, endingIndex, elementDataPointer, elementData.length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -988,61 +967,85 @@ public class GlueList<T> extends AbstractList<T> implements List<T>, Cloneable,
|
||||
}
|
||||
}
|
||||
|
||||
static class Node<T> {
|
||||
private class Itr implements Iterator<T> {
|
||||
|
||||
Node<T> pre;
|
||||
Node<T> next;
|
||||
protected Node<T> node = first;
|
||||
|
||||
int listSize;
|
||||
protected int i = 0;//inner-array index
|
||||
protected int j = 0;//total index -> cursor
|
||||
|
||||
int startingIndex;
|
||||
int endingIndex;
|
||||
protected int lastReturn = -1;
|
||||
|
||||
T[] elementData;
|
||||
int elementDataPointer;
|
||||
protected int expectedModCount = modCount;
|
||||
protected int elementDataPointer = node.elementDataPointer;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Node(Node<T> pre, Node<T> next, int listSize) {
|
||||
this.pre = pre;
|
||||
this.next = next;
|
||||
this.listSize = listSize;
|
||||
this.elementData = (T[]) new Object[listSize >>> 1];
|
||||
this.startingIndex = listSize;
|
||||
this.endingIndex = listSize + elementData.length - 1;
|
||||
}
|
||||
|
||||
Node(Node<T> pre, Node<T> next, int listSize, int initialCapacity) {
|
||||
this.pre = pre;
|
||||
this.next = next;
|
||||
this.listSize = listSize;
|
||||
this.elementData = createElementData(initialCapacity);
|
||||
this.startingIndex = listSize;
|
||||
this.endingIndex = listSize + elementData.length - 1;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
T[] createElementData(int capacity) {
|
||||
|
||||
if (capacity == 0 || capacity == 1) {
|
||||
return (T[]) new Object[DEFAULT_CAPACITY];
|
||||
} else if (capacity > 1) {
|
||||
return (T[]) new Object[capacity];
|
||||
} else {
|
||||
throw new IllegalArgumentException("Illegal Capacity: " + capacity);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isAddable() {
|
||||
return elementDataPointer < elementData.length;
|
||||
}
|
||||
|
||||
void add(T element) {
|
||||
elementData[elementDataPointer++] = element;
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return j != size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("[sIndex: %d - eIndex: %d | elementDataPointer: %d | elementDataLength: %d]", startingIndex, endingIndex, elementDataPointer, elementData.length);
|
||||
public T next() {
|
||||
|
||||
checkForComodification();
|
||||
|
||||
if(j >= size) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
if(j >= last.endingIndex + 1) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
if(j == 0) {// it's for listIterator.when node becomes null.
|
||||
node = first;
|
||||
elementDataPointer = node.elementDataPointer;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
T val = node.elementData[i++];
|
||||
|
||||
if(i >= elementDataPointer) {
|
||||
node = node.next;
|
||||
i = 0;
|
||||
elementDataPointer = (node != null) ? node.elementDataPointer : 0;
|
||||
}
|
||||
|
||||
lastReturn = j++;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
|
||||
if(lastReturn < 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
checkForComodification();
|
||||
|
||||
try {
|
||||
com.dfsek.terra.api.util.GlueList.this.remove(lastReturn);
|
||||
|
||||
j = lastReturn;
|
||||
|
||||
lastReturn = -1;
|
||||
|
||||
i = (--i < 0) ? 0 : i;
|
||||
|
||||
elementDataPointer = (node != null) ? node.elementDataPointer : 0;
|
||||
|
||||
expectedModCount = modCount;
|
||||
} catch(IndexOutOfBoundsException e) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
void checkForComodification() {
|
||||
if(modCount != expectedModCount) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.dfsek.terra.api.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ReflectionUtil {
|
||||
public static Field[] getFields(@NotNull Class<?> type) {
|
||||
Field[] result = type.getDeclaredFields();
|
||||
Class<?> parentClass = type.getSuperclass();
|
||||
if(parentClass != null) {
|
||||
result = Stream.concat(Arrays.stream(result), Arrays.stream(getFields(parentClass))).toArray(Field[]::new);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Method[] getMethods(@NotNull Class<?> type) {
|
||||
Method[] result = type.getDeclaredMethods();
|
||||
Class<?> parentClass = type.getSuperclass();
|
||||
if(parentClass != null) {
|
||||
result = Stream.concat(Arrays.stream(result), Arrays.stream(getMethods(parentClass))).toArray(Method[]::new);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.dfsek.terra.api.util.mutable;
|
||||
|
||||
public class MutableDouble extends MutableNumber<Double> {
|
||||
private static final long serialVersionUID = -2218110876763640053L;
|
||||
|
||||
public MutableDouble(Double value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.dfsek.terra.api.util.mutable;
|
||||
|
||||
public class MutableInteger extends MutableNumber<Integer> {
|
||||
private static final long serialVersionUID = -4427935901819632745L;
|
||||
|
||||
public MutableInteger(Integer value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.dfsek.terra.api.util.mutable;
|
||||
|
||||
public abstract class MutableNumber<T extends Number> extends Number implements MutablePrimitive<T> {
|
||||
|
||||
private static final long serialVersionUID = 8619508342781664393L;
|
||||
protected T value;
|
||||
|
||||
public MutableNumber(T value) {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.dfsek.terra.api.util.seeded;
|
||||
|
||||
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
|
||||
|
||||
public interface SourceSeeded extends SeededBuilder<BiomeSource> {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.dfsek.terra.api.util.seeded;
|
||||
|
||||
import com.dfsek.terra.biome.pipeline.stages.Stage;
|
||||
|
||||
public interface StageSeeded extends SeededBuilder<Stage> {
|
||||
}
|
||||
@@ -9,8 +9,7 @@ import com.dfsek.terra.api.world.biome.Generator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Interface to be implemented by a custom generator's TerraBiome enum.<br>
|
||||
* Represents a custom biome, and contains methods to retrieve information about each type.
|
||||
* Represents a custom biome
|
||||
*/
|
||||
public interface TerraBiome {
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@ public class UserDefinedBiome implements TerraBiome {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Vanilla biome to represent the custom biome.
|
||||
* Gets the Vanilla biomes to represent the custom biome.
|
||||
*
|
||||
* @return TerraBiome - The Vanilla biome.
|
||||
* @return Collection of biomes to represent the custom biome.
|
||||
*/
|
||||
@Override
|
||||
public ProbabilityCollection<Biome> getVanillaBiomes() {
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.dfsek.terra.biome.pipeline;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Vector2;
|
||||
import com.dfsek.terra.api.util.GlueList;
|
||||
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
||||
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.biome.pipeline.stages.Stage;
|
||||
|
||||
@@ -42,7 +42,7 @@ public class BiomePipeline {
|
||||
|
||||
public static final class BiomePipelineBuilder {
|
||||
private final int init;
|
||||
List<SeededBuilder<Stage>> stages = new GlueList<>();
|
||||
List<StageSeeded> stages = new GlueList<>();
|
||||
private int expand;
|
||||
|
||||
public BiomePipelineBuilder(int init) {
|
||||
@@ -60,7 +60,7 @@ public class BiomePipeline {
|
||||
return new BiomePipeline(source, stagesBuilt, expand, init);
|
||||
}
|
||||
|
||||
public BiomePipelineBuilder addStage(SeededBuilder<Stage> stage) {
|
||||
public BiomePipelineBuilder addStage(StageSeeded stage) {
|
||||
stages.add(stage);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -23,4 +23,8 @@ public interface BiomeProvider {
|
||||
interface BiomeProviderBuilder {
|
||||
BiomeProvider build(long seed);
|
||||
}
|
||||
|
||||
enum Type {
|
||||
IMAGE, PIPELINE, SINGLE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,16 @@ import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ImageBiomeProvider implements BiomeProvider {
|
||||
public class ImageBiomeProvider implements BiomeProvider, BiomeProvider.BiomeProviderBuilder { // This provider does not need a seed, so it is its own builder.
|
||||
private final Map<Color, TerraBiome> colorBiomeMap = new HashMap<>();
|
||||
private final BufferedImage image;
|
||||
private final int resolution;
|
||||
private final Align align;
|
||||
|
||||
public ImageBiomeProvider(TerraRegistry<TerraBiome> registry, BufferedImage image, int resolution) {
|
||||
public ImageBiomeProvider(TerraRegistry<TerraBiome> registry, BufferedImage image, int resolution, Align align) {
|
||||
this.image = image;
|
||||
this.resolution = resolution;
|
||||
this.align = align;
|
||||
registry.forEach(biome -> colorBiomeMap.put(new Color(biome.getColor()), biome));
|
||||
}
|
||||
|
||||
@@ -26,7 +28,9 @@ public class ImageBiomeProvider implements BiomeProvider {
|
||||
|
||||
@Override
|
||||
public TerraBiome getBiome(int x, int z) {
|
||||
Color color = new Color(image.getRGB(FastMath.floorMod(x / resolution, image.getWidth()), FastMath.floorMod(z / resolution, image.getHeight())));
|
||||
x /= resolution;
|
||||
z /= resolution;
|
||||
Color color = align.getColor(image, x, z);
|
||||
return colorBiomeMap.get(colorBiomeMap.keySet().stream().reduce(colorBiomeMap.keySet().stream().findAny().orElseThrow(IllegalStateException::new), (running, element) -> {
|
||||
int d1 = distance(color, running);
|
||||
int d2 = distance(color, element);
|
||||
@@ -34,20 +38,24 @@ public class ImageBiomeProvider implements BiomeProvider {
|
||||
}));
|
||||
}
|
||||
|
||||
public static class ImageBiomeProviderBuilder implements BiomeProviderBuilder {
|
||||
private final BufferedImage image;
|
||||
private final int resolution;
|
||||
private final TerraRegistry<TerraBiome> registry;
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ImageBiomeProviderBuilder(BufferedImage image, int resolution, TerraRegistry<TerraBiome> registry) {
|
||||
this.image = image;
|
||||
this.resolution = resolution;
|
||||
this.registry = registry;
|
||||
}
|
||||
public enum Align {
|
||||
CENTER {
|
||||
@Override
|
||||
public Color getColor(BufferedImage image, int x, int z) {
|
||||
return new Color(image.getRGB(FastMath.floorMod(x - image.getWidth() / 2, image.getWidth()), FastMath.floorMod(z - image.getHeight() / 2, image.getHeight())));
|
||||
}
|
||||
}, NONE {
|
||||
@Override
|
||||
public Color getColor(BufferedImage image, int x, int z) {
|
||||
return new Color(image.getRGB(FastMath.floorMod(x, image.getWidth()), FastMath.floorMod(z, image.getHeight())));
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
return new ImageBiomeProvider(registry, image, resolution);
|
||||
}
|
||||
public abstract Color getColor(BufferedImage image, int x, int z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.dfsek.terra.biome.provider;
|
||||
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
|
||||
public class SingleBiomeProvider implements BiomeProvider {
|
||||
public class SingleBiomeProvider implements BiomeProvider, BiomeProvider.BiomeProviderBuilder {
|
||||
private final TerraBiome biome;
|
||||
|
||||
public SingleBiomeProvider(TerraBiome biome) {
|
||||
@@ -14,5 +14,8 @@ public class SingleBiomeProvider implements BiomeProvider {
|
||||
return biome;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.dfsek.terra.biome.provider;
|
||||
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.vector.Vector2;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.pipeline.BiomeHolder;
|
||||
import com.dfsek.terra.biome.pipeline.BiomePipeline;
|
||||
@@ -17,12 +15,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class StandardBiomeProvider implements BiomeProvider {
|
||||
private final LoadingCache<Vector2, BiomeHolder> holderCache;
|
||||
private final BiomePipeline pipeline;
|
||||
private int resolution = 1;
|
||||
private final int resolution;
|
||||
private final NoiseSampler mutator;
|
||||
private final double noiseAmp;
|
||||
private final int seed;
|
||||
|
||||
protected StandardBiomeProvider(BiomePipeline pipeline, TerraPlugin main, NoiseSampler mutator, double noiseAmp, int seed) {
|
||||
public StandardBiomeProvider(BiomePipeline pipeline, TerraPlugin main, int resolution, NoiseSampler mutator, double noiseAmp, int seed) {
|
||||
this.resolution = resolution;
|
||||
this.mutator = mutator;
|
||||
this.noiseAmp = noiseAmp;
|
||||
this.seed = seed;
|
||||
@@ -53,52 +52,4 @@ public class StandardBiomeProvider implements BiomeProvider {
|
||||
int fdZ = FastMath.floorDiv(z, pipeline.getSize());
|
||||
return holderCache.getUnchecked(new Vector2(fdX, fdZ)).getBiome(x - fdX * pipeline.getSize(), z - fdZ * pipeline.getSize());
|
||||
}
|
||||
|
||||
public int getResolution() {
|
||||
return resolution;
|
||||
}
|
||||
|
||||
public void setResolution(int resolution) {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
public interface ExceptionalFunction<I, O> {
|
||||
O apply(I in) throws ConfigException;
|
||||
}
|
||||
|
||||
public static final class StandardBiomeProviderBuilder implements BiomeProviderBuilder {
|
||||
private final ExceptionalFunction<Long, BiomePipeline> pipelineBuilder;
|
||||
private final TerraPlugin main;
|
||||
private int resolution = 1;
|
||||
private double noiseAmp = 2;
|
||||
private NoiseSeeded builder;
|
||||
|
||||
public StandardBiomeProviderBuilder(ExceptionalFunction<Long, BiomePipeline> pipelineBuilder, TerraPlugin main) {
|
||||
this.pipelineBuilder = pipelineBuilder;
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
public void setResolution(int resolution) {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
public void setBlender(NoiseSeeded builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
public void setNoiseAmp(double noiseAmp) {
|
||||
this.noiseAmp = noiseAmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StandardBiomeProvider build(long seed) {
|
||||
try {
|
||||
StandardBiomeProvider provider = new StandardBiomeProvider(pipelineBuilder.apply(seed), main, builder.apply(seed), noiseAmp, (int) seed);
|
||||
provider.setResolution(resolution);
|
||||
return provider;
|
||||
} catch(ConfigException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ public class CarverCache {
|
||||
BiomeProvider provider = main.getWorld(w).getBiomeProvider();
|
||||
if(CarverCache.this.carver.isChunkCarved(w, chunkX, chunkZ, new FastRandom(MathUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed() + CarverCache.this.carver.hashCode())))) {
|
||||
long seed = MathUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed());
|
||||
CarverCache.this.carver.getSeedVar().setValue(seed);
|
||||
Random r = new FastRandom(seed);
|
||||
Worm carving = CarverCache.this.carver.getWorm(seed, new Vector3((chunkX << 4) + r.nextInt(16), CarverCache.this.carver.getConfig().getHeight().get(r), (chunkZ << 4) + r.nextInt(16)));
|
||||
List<Worm.WormPoint> points = new GlueList<>();
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package com.dfsek.terra.carving;
|
||||
|
||||
import com.dfsek.paralithic.Expression;
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.Range;
|
||||
import com.dfsek.terra.api.math.parsii.defined.UserDefinedFunction;
|
||||
import com.dfsek.terra.api.math.parsii.noise.NoiseFunction2;
|
||||
import com.dfsek.terra.api.math.parsii.noise.NoiseFunction3;
|
||||
import com.dfsek.terra.api.math.paralithic.defined.UserDefinedFunction;
|
||||
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction2;
|
||||
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction3;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.api.util.FastRandom;
|
||||
@@ -16,18 +20,12 @@ import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
||||
import net.jafama.FastMath;
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Parser;
|
||||
import parsii.eval.Scope;
|
||||
import parsii.eval.Variable;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UserDefinedCarver extends Carver {
|
||||
private final double[] start; // 0, 1, 2 = x, y, z.
|
||||
@@ -40,13 +38,6 @@ public class UserDefinedCarver extends Carver {
|
||||
private final Expression xRad;
|
||||
private final Expression yRad;
|
||||
private final Expression zRad;
|
||||
private final Variable lengthVar;
|
||||
private final Variable position;
|
||||
private final Variable seedVar;
|
||||
|
||||
private final Variable xOrigin;
|
||||
private final Variable yOrigin;
|
||||
private final Variable zOrigin;
|
||||
|
||||
private final Map<World, CarverCache> cacheMap = new ConcurrentHashMap<>();
|
||||
private final TerraPlugin main;
|
||||
@@ -70,33 +61,28 @@ public class UserDefinedCarver extends Carver {
|
||||
functions.forEach((id, noise) -> {
|
||||
switch(noise.getDimensions()) {
|
||||
case 2:
|
||||
p.registerFunction(id, new NoiseFunction2(hash, noise));
|
||||
p.registerFunction(id, new NoiseFunction2(noise.apply(hash)));
|
||||
break;
|
||||
case 3:
|
||||
p.registerFunction(id, new NoiseFunction3(hash, noise));
|
||||
p.registerFunction(id, new NoiseFunction3(noise.apply(hash)));
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
for(Map.Entry<String, FunctionTemplate> entry : definedFunctions.entrySet()) {
|
||||
String id = entry.getKey();
|
||||
FunctionTemplate fun = entry.getValue();
|
||||
|
||||
Scope functionScope = new Scope().withParent(parent);
|
||||
List<Variable> variables = fun.getArgs().stream().map(functionScope::create).collect(Collectors.toList());
|
||||
|
||||
p.registerFunction(id, new UserDefinedFunction(p.parse(fun.getFunction(), functionScope), variables));
|
||||
p.registerFunction(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), p, parent));
|
||||
}
|
||||
|
||||
Scope s = new Scope().withParent(parent);
|
||||
|
||||
lengthVar = s.create("length");
|
||||
position = s.create("position");
|
||||
seedVar = s.create("seed");
|
||||
|
||||
xOrigin = s.create("x");
|
||||
yOrigin = s.create("y");
|
||||
zOrigin = s.create("z");
|
||||
s.addInvocationVariable("x");
|
||||
s.addInvocationVariable("y");
|
||||
s.addInvocationVariable("z");
|
||||
|
||||
s.addInvocationVariable("length");
|
||||
s.addInvocationVariable("position");
|
||||
s.addInvocationVariable("seed");
|
||||
|
||||
|
||||
xRad = p.parse(radii.get(0), s);
|
||||
@@ -108,19 +94,7 @@ public class UserDefinedCarver extends Carver {
|
||||
@Override
|
||||
public Worm getWorm(long l, Vector3 vector) {
|
||||
Random r = new FastRandom(l + hash);
|
||||
return new UserDefinedWorm(length.get(r) / 2, r, vector, topCut, bottomCut);
|
||||
}
|
||||
|
||||
protected Variable getSeedVar() {
|
||||
return seedVar;
|
||||
}
|
||||
|
||||
protected Variable getLengthVar() {
|
||||
return lengthVar;
|
||||
}
|
||||
|
||||
protected Variable getPosition() {
|
||||
return position;
|
||||
return new UserDefinedWorm(length.get(r) / 2, r, vector, topCut, bottomCut, l);
|
||||
}
|
||||
|
||||
public void setStep(double step) {
|
||||
@@ -168,21 +142,21 @@ public class UserDefinedCarver extends Carver {
|
||||
|
||||
private class UserDefinedWorm extends Worm {
|
||||
private final Vector3 direction;
|
||||
private final Vector3 origin;
|
||||
private int steps;
|
||||
private int nextDirection = 0;
|
||||
private double[] currentRotation = new double[3];
|
||||
private final long seed;
|
||||
|
||||
public UserDefinedWorm(int length, Random r, Vector3 origin, int topCut, int bottomCut) {
|
||||
public UserDefinedWorm(int length, Random r, Vector3 origin, int topCut, int bottomCut, long seed) {
|
||||
super(length, r, origin);
|
||||
this.origin = origin;
|
||||
this.seed = seed;
|
||||
super.setTopCut(topCut);
|
||||
super.setBottomCut(bottomCut);
|
||||
direction = new Vector3((r.nextDouble() - 0.5D) * start[0], (r.nextDouble() - 0.5D) * start[1], (r.nextDouble() - 0.5D) * start[2]).normalize().multiply(step);
|
||||
position.setValue(0);
|
||||
lengthVar.setValue(length);
|
||||
xOrigin.setValue(origin.getX());
|
||||
yOrigin.setValue(origin.getY());
|
||||
zOrigin.setValue(origin.getZ());
|
||||
setRadius(new int[] {(int) (xRad.evaluate()), (int) (yRad.evaluate()), (int) (zRad.evaluate())});
|
||||
double[] args = {origin.getX(), origin.getY(), origin.getZ(), length, 0, seed};
|
||||
setRadius(new int[] {(int) (xRad.evaluate(args)), (int) (yRad.evaluate(args)), (int) (zRad.evaluate(args))});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -191,7 +165,7 @@ public class UserDefinedCarver extends Carver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void step() {
|
||||
public void step() {
|
||||
if(steps == nextDirection) {
|
||||
direction.rotateAroundX(FastMath.toRadians((getRandom().nextGaussian()) * mutate[0] * recalcMagnitude));
|
||||
direction.rotateAroundY(FastMath.toRadians((getRandom().nextGaussian()) * mutate[1] * recalcMagnitude));
|
||||
@@ -202,8 +176,8 @@ public class UserDefinedCarver extends Carver {
|
||||
nextDirection += recalc.get(getRandom());
|
||||
}
|
||||
steps++;
|
||||
position.setValue(steps);
|
||||
setRadius(new int[] {(int) (xRad.evaluate()), (int) (yRad.evaluate()), (int) (zRad.evaluate())});
|
||||
double[] args = {origin.getX(), origin.getY(), origin.getZ(), getLength(), steps, seed};
|
||||
setRadius(new int[] {(int) (xRad.evaluate(args)), (int) (yRad.evaluate(args)), (int) (zRad.evaluate(args))});
|
||||
direction.rotateAroundX(FastMath.toRadians(currentRotation[0] * mutate[0]));
|
||||
direction.rotateAroundY(FastMath.toRadians(currentRotation[1] * mutate[1]));
|
||||
direction.rotateAroundZ(FastMath.toRadians(currentRotation[2] * mutate[2]));
|
||||
|
||||
@@ -6,14 +6,16 @@ import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.GridSpawn;
|
||||
import com.dfsek.terra.api.math.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.math.Range;
|
||||
import com.dfsek.terra.api.math.noise.normalizer.Normalizer;
|
||||
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
|
||||
import com.dfsek.terra.api.math.noise.samplers.ImageSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.CellularSampler;
|
||||
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
||||
import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
|
||||
import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder;
|
||||
import com.dfsek.terra.biome.pipeline.stages.ExpanderStage;
|
||||
import com.dfsek.terra.biome.pipeline.stages.MutatorStage;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.ImageBiomeProvider;
|
||||
import com.dfsek.terra.carving.CarverPalette;
|
||||
import com.dfsek.terra.config.loaders.LinkedHashMapLoader;
|
||||
import com.dfsek.terra.config.loaders.MaterialSetLoader;
|
||||
@@ -24,6 +26,9 @@ import com.dfsek.terra.config.loaders.config.GridSpawnLoader;
|
||||
import com.dfsek.terra.config.loaders.config.OreConfigLoader;
|
||||
import com.dfsek.terra.config.loaders.config.OreHolderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.TreeLayerLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.BiomeProviderBuilderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.SourceBuilderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.StageBuilderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.expander.ExpanderStageTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.BorderListMutatorTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.BorderMutatorTemplate;
|
||||
@@ -31,10 +36,9 @@ import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.Repla
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.ReplaceMutatorTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.SmoothMutatorTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.NoiseSamplerBuilderLoader;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.DomainWarpTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.FastNoiseTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.ImageSamplerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.ClampNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.LinearNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.NormalNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.palette.CarverPaletteLoader;
|
||||
@@ -70,13 +74,11 @@ public class GenericLoaders implements LoaderRegistrar {
|
||||
.registerLoader(TreeLayer.class, new TreeLayerLoader())
|
||||
.registerLoader(MaterialSet.class, new MaterialSetLoader())
|
||||
.registerLoader(OreHolder.class, new OreHolderLoader())
|
||||
.registerLoader(FastNoiseTemplate.class, FastNoiseTemplate::new)
|
||||
.registerLoader(ImageSamplerTemplate.class, ImageSamplerTemplate::new)
|
||||
.registerLoader(DomainWarpTemplate.class, DomainWarpTemplate::new)
|
||||
.registerLoader(LinearNormalizerTemplate.class, LinearNormalizerTemplate::new)
|
||||
.registerLoader(NormalNormalizerTemplate.class, NormalNormalizerTemplate::new)
|
||||
.registerLoader(FastNoiseTemplate.class, FastNoiseTemplate::new)
|
||||
.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader())
|
||||
.registerLoader(ClampNormalizerTemplate.class, ClampNormalizerTemplate::new)
|
||||
.registerLoader(ReplaceMutatorTemplate.class, ReplaceMutatorTemplate::new)
|
||||
.registerLoader(ExpanderStageTemplate.class, ExpanderStageTemplate::new)
|
||||
.registerLoader(SmoothMutatorTemplate.class, SmoothMutatorTemplate::new)
|
||||
@@ -86,17 +88,16 @@ public class GenericLoaders implements LoaderRegistrar {
|
||||
.registerLoader(FunctionTemplate.class, FunctionTemplate::new)
|
||||
.registerLoader(LinkedHashMap.class, new LinkedHashMapLoader())
|
||||
.registerLoader(CarverPalette.class, new CarverPaletteLoader())
|
||||
.registerLoader(SourceSeeded.class, new SourceBuilderLoader())
|
||||
.registerLoader(StageSeeded.class, new StageBuilderLoader())
|
||||
.registerLoader(BiomeProvider.BiomeProviderBuilder.class, new BiomeProviderBuilderLoader())
|
||||
.registerLoader(ImageSampler.Channel.class, (t, object, cf) -> ImageSampler.Channel.valueOf((String) object))
|
||||
.registerLoader(BiomeProvider.Type.class, (t, object, cf) -> BiomeProvider.Type.valueOf((String) object))
|
||||
.registerLoader(ImageBiomeProvider.Align.class, (t, object, cf) -> ImageBiomeProvider.Align.valueOf((String) object))
|
||||
.registerLoader(ExpanderStage.Type.class, (t, object, cf) -> ExpanderStage.Type.valueOf((String) object))
|
||||
.registerLoader(MutatorStage.Type.class, (t, object, cf) -> MutatorStage.Type.valueOf((String) object))
|
||||
.registerLoader(FastNoiseLite.NoiseType.class, (t, object, cf) -> FastNoiseLite.NoiseType.valueOf((String) object))
|
||||
.registerLoader(FastNoiseLite.FractalType.class, (t, object, cf) -> FastNoiseLite.FractalType.valueOf((String) object))
|
||||
.registerLoader(FastNoiseLite.DomainWarpType.class, (t, object, cf) -> FastNoiseLite.DomainWarpType.valueOf((String) object))
|
||||
.registerLoader(FastNoiseLite.RotationType3D.class, (t, object, cf) -> FastNoiseLite.RotationType3D.valueOf((String) object))
|
||||
.registerLoader(FastNoiseLite.CellularReturnType.class, (t, object, cf) -> FastNoiseLite.CellularReturnType.valueOf((String) object))
|
||||
.registerLoader(FastNoiseLite.CellularDistanceFunction.class, (t, object, cf) -> FastNoiseLite.CellularDistanceFunction.valueOf((String) object))
|
||||
.registerLoader(Normalizer.NormalType.class, (t, o, l) -> Normalizer.NormalType.valueOf(o.toString().toUpperCase()))
|
||||
.registerLoader(TerraFlora.Search.class, (t, o, l) -> TerraFlora.Search.valueOf(o.toString()))
|
||||
.registerLoader(Normalizer.NormalType.class, (t, o, l) -> Normalizer.NormalType.valueOf(o.toString().toUpperCase()));
|
||||
.registerLoader(CellularSampler.ReturnType.class, (t, object, cf) -> CellularSampler.ReturnType.valueOf((String) object))
|
||||
.registerLoader(CellularSampler.DistanceFunction.class, (t, object, cf) -> CellularSampler.DistanceFunction.valueOf((String) object))
|
||||
.registerLoader(TerraFlora.Search.class, (t, o, l) -> TerraFlora.Search.valueOf(o.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.dfsek.terra.config.builder;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.ConstantSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.ExpressionSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.ConstantSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
|
||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
import com.dfsek.terra.world.generation.WorldGenerator;
|
||||
import parsii.eval.Scope;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
@@ -7,7 +8,6 @@ import com.dfsek.terra.config.builder.GeneratorBuilder;
|
||||
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import parsii.eval.Scope;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@@ -35,7 +35,7 @@ public class BiomeFactory implements TerraFactory<BiomeTemplate, TerraBiome> {
|
||||
generatorBuilder.setSlantPalettes(template.getSlantPalette());
|
||||
|
||||
Scope vars = new Scope().withParent(pack.getVarScope());
|
||||
template.getVariables().forEach((id, val) -> vars.create(id).setValue(val));
|
||||
template.getVariables().forEach(vars::create);
|
||||
generatorBuilder.setVarScope(vars);
|
||||
|
||||
generatorBuilder.setInterpolateElevation(template.interpolateElevation());
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.MathUtil;
|
||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
||||
import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.random.WhiteNoiseSampler;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.world.flora.Flora;
|
||||
import com.dfsek.terra.api.world.palette.NoisePalette;
|
||||
@@ -13,9 +13,7 @@ import com.dfsek.terra.world.population.items.flora.TerraFlora;
|
||||
public class FloraFactory implements TerraFactory<FloraTemplate, Flora> {
|
||||
@Override
|
||||
public TerraFlora build(FloraTemplate config, TerraPlugin main) {
|
||||
FastNoiseLite whiteNoise = new FastNoiseLite();
|
||||
whiteNoise.setNoiseType(FastNoiseLite.NoiseType.WhiteNoise);
|
||||
Palette<BlockData> palette = new NoisePalette<>(whiteNoise, false);
|
||||
Palette<BlockData> palette = new NoisePalette<>(new WhiteNoiseSampler(2403), false);
|
||||
for(PaletteLayerHolder layer : config.getFloraPalette()) {
|
||||
palette.add(layer.getLayer(), layer.getSize(), layer.getSampler());
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.lang.reflect.Type;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class LinkedHashMapLoader implements TypeLoader<LinkedHashMap<Object, Object>> {
|
||||
@Override
|
||||
public LinkedHashMap<Object, Object> load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
||||
|
||||
@@ -6,11 +6,10 @@ import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.api.math.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.math.Range;
|
||||
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.random.WhiteNoiseSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.world.flora.Flora;
|
||||
import com.dfsek.terra.config.loaders.Types;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.FastNoiseTemplate;
|
||||
import com.dfsek.terra.world.population.items.flora.FloraLayer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
@@ -35,10 +34,7 @@ public class FloraLayerLoader implements TypeLoader<FloraLayer> {
|
||||
}
|
||||
return new FloraLayer(density, range, items, sampler.apply(2403L));
|
||||
}
|
||||
FastNoiseTemplate def = new FastNoiseTemplate();
|
||||
def.setType(FastNoiseLite.NoiseType.WhiteNoise);
|
||||
def.setDimensions(3);
|
||||
|
||||
return new FloraLayer(density, range, items, def.apply(2403L));
|
||||
return new FloraLayer(density, range, items, new WhiteNoiseSampler(2403));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
package com.dfsek.terra.config.loaders.config;
|
||||
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.api.math.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.math.Range;
|
||||
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.random.WhiteNoiseSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.world.tree.Tree;
|
||||
import com.dfsek.terra.config.loaders.Types;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.FastNoiseTemplate;
|
||||
import com.dfsek.terra.world.population.items.tree.TreeLayer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
@@ -26,19 +24,11 @@ public class TreeLayerLoader implements TypeLoader<TreeLayer> {
|
||||
if(range == null) throw new LoadException("Tree range unspecified");
|
||||
ProbabilityCollection<Tree> items = (ProbabilityCollection<Tree>) configLoader.loadType(Types.TREE_PROBABILITY_COLLECTION_TYPE, map.get("items"));
|
||||
|
||||
FastNoiseTemplate sampler = new FastNoiseTemplate();
|
||||
if(map.containsKey("distribution")) {
|
||||
try {
|
||||
configLoader.load(sampler, new Configuration((Map<String, Object>) map.get("distribution")));
|
||||
} catch(ConfigException e) {
|
||||
throw new LoadException("Unable to load noise", e);
|
||||
}
|
||||
return new TreeLayer(density, range, items, sampler.apply(2403L));
|
||||
NoiseSeeded noise = configLoader.loadClass(NoiseSeeded.class, map.get("distribution"));
|
||||
return new TreeLayer(density, range, items, noise.apply(2403L));
|
||||
}
|
||||
|
||||
sampler.setType(FastNoiseLite.NoiseType.WhiteNoise);
|
||||
sampler.setDimensions(3);
|
||||
|
||||
return new TreeLayer(density, range, items, sampler.apply(2403L));
|
||||
return new TreeLayer(density, range, items, new WhiteNoiseSampler(2403));
|
||||
}
|
||||
}
|
||||
|
||||
+11
-74
@@ -3,94 +3,31 @@ package com.dfsek.terra.config.loaders.config.biome;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.pipeline.BiomePipeline;
|
||||
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.ImageBiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.SingleBiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.StandardBiomeProvider;
|
||||
import com.dfsek.terra.config.fileloaders.Loader;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.BiomePipelineTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.ImageProviderTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.source.SingleBiomeProviderTemplate;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class BiomeProviderBuilderLoader implements TypeLoader<BiomeProvider.BiomeProviderBuilder> {
|
||||
private final TerraPlugin main;
|
||||
private final TerraRegistry<TerraBiome> biomeRegistry;
|
||||
private final Loader fileLoader;
|
||||
|
||||
public BiomeProviderBuilderLoader(TerraPlugin main, TerraRegistry<TerraBiome> biomeRegistry, Loader fileLoader) {
|
||||
this.main = main;
|
||||
this.biomeRegistry = biomeRegistry;
|
||||
this.fileLoader = fileLoader;
|
||||
public BiomeProviderBuilderLoader() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider.BiomeProviderBuilder load(Type t, Object c, ConfigLoader loader) throws LoadException { // TODO: clean this up
|
||||
Map<String, Object> map = (Map<String, Object>) c;
|
||||
int resolution = (Integer) map.getOrDefault("resolution", 1);
|
||||
|
||||
if(map.get("type").equals("PIPELINE")) {
|
||||
Map<String, Object> pipeline = (Map<String, Object>) map.get("pipeline");
|
||||
|
||||
List<Map<String, Object>> stages = (List<Map<String, Object>>) pipeline.get("stages");
|
||||
|
||||
if(stages == null) throw new LoadException("No pipeline stages defined!");
|
||||
|
||||
int init = (Integer) pipeline.getOrDefault("initial-size", 2);
|
||||
|
||||
StandardBiomeProvider.StandardBiomeProviderBuilder builder = new StandardBiomeProvider.StandardBiomeProviderBuilder(seed -> {
|
||||
BiomePipeline.BiomePipelineBuilder pipelineBuilder = new BiomePipeline.BiomePipelineBuilder(init);
|
||||
|
||||
for(Map<String, Object> stage : stages) {
|
||||
for(Map.Entry<String, Object> entry : stage.entrySet()) {
|
||||
pipelineBuilder.addStage(new StageBuilderLoader().load(SeededBuilder.class, entry, loader));
|
||||
}
|
||||
}
|
||||
|
||||
if(!pipeline.containsKey("source")) throw new LoadException("Biome Source not defined!");
|
||||
SeededBuilder<BiomeSource> source = new SourceBuilderLoader().load(BiomeSource.class, pipeline.get("source"), loader);
|
||||
|
||||
BiomePipeline biomePipeline = pipelineBuilder.build(source.apply(seed), seed);
|
||||
main.getDebugLogger().info("Biome Pipeline scale factor: " + biomePipeline.getSize());
|
||||
return biomePipeline;
|
||||
}, main);
|
||||
|
||||
builder.setResolution(resolution);
|
||||
if(map.containsKey("blend")) {
|
||||
Map<String, Object> blend = (Map<String, Object>) map.get("blend");
|
||||
if(blend.containsKey("amplitude")) builder.setNoiseAmp(Double.parseDouble(blend.get("amplitude").toString()));
|
||||
if(blend.containsKey("noise"))
|
||||
builder.setBlender(loader.loadClass(NoiseSeeded.class, blend.get("noise")));
|
||||
}
|
||||
return builder;
|
||||
} else if(map.get("type").equals("IMAGE")) {
|
||||
Map<String, Object> imageMap = (Map<String, Object>) map.get("image");
|
||||
try {
|
||||
main.getLogger().info("Using image " + imageMap.get("name") + " for biome distribution.");
|
||||
BufferedImage image = ImageIO.read(fileLoader.get(imageMap.get("name").toString()));
|
||||
return new ImageBiomeProvider.ImageBiomeProviderBuilder(image, resolution, biomeRegistry);
|
||||
} catch(IOException e) {
|
||||
throw new LoadException("Failed to load image", e);
|
||||
}
|
||||
} else if(map.get("type").equals("SINGLE")) {
|
||||
return seed -> {
|
||||
try {
|
||||
return new SingleBiomeProvider(loader.loadClass(TerraBiome.class, map.get("biome")));
|
||||
} catch(LoadException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
switch(loader.loadClass(BiomeProvider.Type.class, map.get("type"))) {
|
||||
case IMAGE:
|
||||
return loader.loadClass(ImageProviderTemplate.class, map);
|
||||
case PIPELINE:
|
||||
return loader.loadClass(BiomePipelineTemplate.class, map);
|
||||
case SINGLE:
|
||||
return loader.loadClass(SingleBiomeProviderTemplate.class, map);
|
||||
}
|
||||
|
||||
throw new LoadException("No such biome provider type: " + map.get("type"));
|
||||
|
||||
+3
-4
@@ -5,9 +5,8 @@ import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.api.math.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
||||
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.biome.pipeline.source.RandomSource;
|
||||
import com.dfsek.terra.config.loaders.Types;
|
||||
|
||||
@@ -15,9 +14,9 @@ import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class SourceBuilderLoader implements TypeLoader<SeededBuilder<BiomeSource>> {
|
||||
public class SourceBuilderLoader implements TypeLoader<SourceSeeded> {
|
||||
@Override
|
||||
public SeededBuilder<BiomeSource> load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
||||
public SourceSeeded load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
||||
Map<String, Object> source = (Map<String, Object>) c;
|
||||
|
||||
String type = source.get("type").toString();
|
||||
|
||||
+18
-12
@@ -3,10 +3,9 @@ package com.dfsek.terra.config.loaders.config.biome;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
||||
import com.dfsek.terra.biome.pipeline.stages.ExpanderStage;
|
||||
import com.dfsek.terra.biome.pipeline.stages.MutatorStage;
|
||||
import com.dfsek.terra.biome.pipeline.stages.Stage;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.expander.ExpanderStageTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.BorderListMutatorTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator.BorderMutatorTemplate;
|
||||
@@ -18,33 +17,40 @@ import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class StageBuilderLoader implements TypeLoader<SeededBuilder<Stage>> {
|
||||
public class StageBuilderLoader implements TypeLoader<StageSeeded> {
|
||||
@Override
|
||||
public SeededBuilder<Stage> load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
||||
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) c;
|
||||
public StageSeeded load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
||||
Map<String, Object> raw = (Map<String, Object>) c;
|
||||
|
||||
if(raw.size() != 1) throw new LoadException("Illegal stage map size: " + raw.size());
|
||||
|
||||
Map.Entry<String, Object> entry = null;
|
||||
|
||||
for(Map.Entry<String, Object> e : raw.entrySet()) {
|
||||
entry = e;
|
||||
}
|
||||
|
||||
Map<String, Object> mutator = (Map<String, Object>) entry.getValue();
|
||||
|
||||
if(entry.getKey().equals("expand")) {
|
||||
ExpanderStage.Type stageType = loader.loadClass(ExpanderStage.Type.class, mutator.get("type"));
|
||||
if(stageType.equals(ExpanderStage.Type.FRACTAL)) {
|
||||
return loader.loadClass(ExpanderStageTemplate.class, mutator).get();
|
||||
return loader.loadClass(ExpanderStageTemplate.class, mutator);
|
||||
} else throw new LoadException("No such expander \"" + stageType + "\"");
|
||||
} else if(entry.getKey().equals("mutate")) {
|
||||
switch(loader.loadClass(MutatorStage.Type.class, mutator.get("type"))) {
|
||||
case SMOOTH:
|
||||
return loader.loadClass(SmoothMutatorTemplate.class, mutator).get();
|
||||
return loader.loadClass(SmoothMutatorTemplate.class, mutator);
|
||||
case REPLACE:
|
||||
return loader.loadClass(ReplaceMutatorTemplate.class, mutator).get();
|
||||
return loader.loadClass(ReplaceMutatorTemplate.class, mutator);
|
||||
case REPLACE_LIST:
|
||||
return loader.loadClass(ReplaceListMutatorTemplate.class, mutator).get();
|
||||
return loader.loadClass(ReplaceListMutatorTemplate.class, mutator);
|
||||
case BORDER:
|
||||
return loader.loadClass(BorderMutatorTemplate.class, mutator).get();
|
||||
return loader.loadClass(BorderMutatorTemplate.class, mutator);
|
||||
case BORDER_LIST:
|
||||
return loader.loadClass(BorderListMutatorTemplate.class, mutator).get();
|
||||
return loader.loadClass(BorderListMutatorTemplate.class, mutator);
|
||||
default:
|
||||
throw new LoadException("No such mutator type \"" + mutator.get("type"));
|
||||
|
||||
}
|
||||
}
|
||||
throw new LoadException("No such mutator \"" + entry.getKey() + "\"");
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.core.TerraPlugin;
|
||||
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
||||
import com.dfsek.terra.biome.pipeline.BiomePipeline;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.StandardBiomeProvider;
|
||||
import com.dfsek.terra.registry.config.BiomeRegistry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"FieldMayBeFinal", "unused"})
|
||||
public class BiomePipelineTemplate extends BiomeProviderTemplate {
|
||||
private final TerraPlugin main;
|
||||
@Value("pipeline.initial-size")
|
||||
@Default
|
||||
private int initialSize = 2;
|
||||
|
||||
@Value("pipeline.stages")
|
||||
private List<StageSeeded> stages;
|
||||
|
||||
@Value("pipeline.source")
|
||||
private SourceSeeded source;
|
||||
|
||||
public BiomePipelineTemplate(BiomeRegistry registry, TerraPlugin main) {
|
||||
super(registry);
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
BiomePipeline.BiomePipelineBuilder biomePipelineBuilder = new BiomePipeline.BiomePipelineBuilder(initialSize);
|
||||
stages.forEach(biomePipelineBuilder::addStage);
|
||||
BiomePipeline pipeline = biomePipelineBuilder.build(source.apply(seed), seed);
|
||||
return new StandardBiomeProvider(pipeline, main, resolution, blend.apply(seed), blendAmp, (int) seed);
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.ConstantSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.registry.config.BiomeRegistry;
|
||||
|
||||
public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvider.BiomeProviderBuilder>, BiomeProvider.BiomeProviderBuilder {
|
||||
protected final BiomeRegistry registry;
|
||||
@Value("resolution")
|
||||
@Default
|
||||
protected int resolution = 1;
|
||||
@Value("blend.noise")
|
||||
@Default
|
||||
protected NoiseSeeded blend = new NoiseSeeded() {
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
return new ConstantSampler(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDimensions() {
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
@Value("blend.amplitude")
|
||||
@Default
|
||||
protected double blendAmp = 0d;
|
||||
@Value("type")
|
||||
BiomeProvider.Type type;
|
||||
|
||||
protected BiomeProviderTemplate(BiomeRegistry registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider.BiomeProviderBuilder get() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.ImageBiomeProvider;
|
||||
import com.dfsek.terra.registry.config.BiomeRegistry;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class ImageProviderTemplate extends BiomeProviderTemplate {
|
||||
@Value("image.name")
|
||||
private BufferedImage image;
|
||||
|
||||
@Value("image.align")
|
||||
private ImageBiomeProvider.Align align;
|
||||
|
||||
public ImageProviderTemplate(BiomeRegistry registry) {
|
||||
super(registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
return new ImageBiomeProvider(registry, image, resolution, align);
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.biome.TerraBiome;
|
||||
import com.dfsek.terra.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.biome.provider.SingleBiomeProvider;
|
||||
import com.dfsek.terra.registry.config.BiomeRegistry;
|
||||
|
||||
public class SingleBiomeProviderTemplate extends BiomeProviderTemplate {
|
||||
@Value("biome")
|
||||
private TerraBiome biome;
|
||||
|
||||
public SingleBiomeProviderTemplate(BiomeRegistry registry) {
|
||||
super(registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider build(long seed) {
|
||||
return new SingleBiomeProvider(biome);
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -4,14 +4,15 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
||||
import com.dfsek.terra.biome.pipeline.stages.Stage;
|
||||
|
||||
public abstract class StageTemplate implements ObjectTemplate<SeededBuilder<Stage>>, SeededBuilder<Stage> {
|
||||
public abstract class StageTemplate implements ObjectTemplate<SeededBuilder<Stage>>, StageSeeded {
|
||||
@Value("noise")
|
||||
protected NoiseSeeded noise;
|
||||
|
||||
@Override
|
||||
public SeededBuilder<Stage> get() {
|
||||
public StageSeeded get() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-31
@@ -1,50 +1,35 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler;
|
||||
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.api.math.noise.normalizer.Normalizer;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.DomainWarpTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.FastNoiseTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.ImageSamplerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.LinearNormalizerTemplate;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.NormalNormalizerTemplate;
|
||||
import com.dfsek.terra.registry.config.NoiseRegistry;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class NoiseSamplerBuilderLoader implements TypeLoader<NoiseSeeded> {
|
||||
private final NoiseRegistry noiseRegistry;
|
||||
|
||||
public NoiseSamplerBuilderLoader(NoiseRegistry noiseRegistry) {
|
||||
this.noiseRegistry = noiseRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoiseSeeded load(Type t, Object c, ConfigLoader loader) throws LoadException {
|
||||
Map<String, Object> map = (Map<String, Object>) c;
|
||||
|
||||
String samplerType = "NOISE";
|
||||
|
||||
if(map.containsKey("sampler-type")) {
|
||||
samplerType = map.get("sampler-type").toString();
|
||||
try {
|
||||
ObjectTemplate<NoiseSeeded> normalizerTemplate = noiseRegistry.get(((String) map.get("type")).toUpperCase(Locale.ROOT)).get();
|
||||
loader.load(normalizerTemplate, new Configuration(map));
|
||||
return normalizerTemplate.get();
|
||||
} catch(ConfigException e) {
|
||||
throw new LoadException("Unable to load noise function: ", e);
|
||||
}
|
||||
|
||||
switch(samplerType) {
|
||||
case "NOISE":
|
||||
return loader.loadClass(FastNoiseTemplate.class, map).get();
|
||||
case "NORMALIZER":
|
||||
Normalizer.NormalType normalType = loader.loadClass(Normalizer.NormalType.class, map.get("type"));
|
||||
switch(normalType) {
|
||||
case LINEAR:
|
||||
return loader.loadClass(LinearNormalizerTemplate.class, map).get();
|
||||
case NORMAL:
|
||||
return loader.loadClass(NormalNormalizerTemplate.class, map).get();
|
||||
}
|
||||
case "IMAGE": {
|
||||
return loader.loadClass(ImageSamplerTemplate.class, map).get();
|
||||
}
|
||||
case "DOMAIN_WARP":
|
||||
return loader.loadClass(DomainWarpTemplate.class, map).get();
|
||||
}
|
||||
|
||||
throw new LoadException("No such noise sampler type \"" + samplerType + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler;
|
||||
|
||||
public class NormalizerLoader {
|
||||
}
|
||||
-227
@@ -1,227 +0,0 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler.templates;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.FastNoiseLite;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public class FastNoiseTemplate extends SamplerTemplate<FastNoiseLite> implements NoiseSeeded {
|
||||
@Value("type")
|
||||
@Default
|
||||
private FastNoiseLite.NoiseType type = FastNoiseLite.NoiseType.OpenSimplex2;
|
||||
|
||||
@Value("fractal.octaves")
|
||||
@Default
|
||||
private int octaves = 1;
|
||||
|
||||
@Value("fractal.type")
|
||||
@Default
|
||||
private FastNoiseLite.FractalType fractalType = FastNoiseLite.FractalType.None;
|
||||
|
||||
@Value("frequency")
|
||||
@Default
|
||||
private double frequency = 0.02D;
|
||||
|
||||
@Value("fractal.gain")
|
||||
@Default
|
||||
private double fractalGain = 0.5D;
|
||||
|
||||
@Value("fractal.lacunarity")
|
||||
@Default
|
||||
private double fractalLacunarity = 2.0D;
|
||||
|
||||
@Value("fractal.ping-pong")
|
||||
@Default
|
||||
private double pingPong = 2.0D;
|
||||
|
||||
@Value("fractal.weighted-strength")
|
||||
@Default
|
||||
private double weightedStrength = 0.0D;
|
||||
|
||||
@Value("salt")
|
||||
@Default
|
||||
private int seedOffset = 0;
|
||||
|
||||
@Value("cellular.distance")
|
||||
@Default
|
||||
private FastNoiseLite.CellularDistanceFunction cellularDistanceFunction = FastNoiseLite.CellularDistanceFunction.EuclideanSq;
|
||||
|
||||
@Value("cellular.return")
|
||||
@Default
|
||||
private FastNoiseLite.CellularReturnType cellularReturnType = FastNoiseLite.CellularReturnType.Distance;
|
||||
|
||||
@Value("cellular.jitter")
|
||||
@Default
|
||||
private double cellularJitter = 1.0D;
|
||||
|
||||
@Value("rotation-type")
|
||||
@Default
|
||||
private FastNoiseLite.RotationType3D rotationType3D = FastNoiseLite.RotationType3D.None;
|
||||
|
||||
@Value("dimensions")
|
||||
@Default
|
||||
private int dimensions = 2;
|
||||
|
||||
@Value("cellular.lookup")
|
||||
@Default
|
||||
private NoiseSeeded lookup;
|
||||
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
FastNoiseLite noise = new FastNoiseLite((int) (seed + seedOffset));
|
||||
if(!fractalType.equals(FastNoiseLite.FractalType.None)) {
|
||||
noise.setFractalType(fractalType);
|
||||
noise.setFractalOctaves(octaves);
|
||||
noise.setFractalGain(fractalGain);
|
||||
noise.setFractalLacunarity(fractalLacunarity);
|
||||
if(fractalType.equals(FastNoiseLite.FractalType.PingPong)) noise.setFractalPingPongStrength(pingPong);
|
||||
noise.setFractalWeightedStrength(weightedStrength);
|
||||
}
|
||||
if(type.equals(FastNoiseLite.NoiseType.Cellular)) {
|
||||
noise.setCellularDistanceFunction(cellularDistanceFunction);
|
||||
noise.setCellularReturnType(cellularReturnType);
|
||||
noise.setCellularJitter(cellularJitter);
|
||||
if(lookup != null) noise.setCellularNoiseLookup(lookup.apply(seed));
|
||||
}
|
||||
|
||||
noise.setNoiseType(type);
|
||||
|
||||
noise.setRotationType3D(rotationType3D);
|
||||
|
||||
noise.setFrequency(frequency);
|
||||
return noise;
|
||||
}
|
||||
|
||||
public FastNoiseLite.NoiseType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setType(FastNoiseLite.NoiseType type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getSeedOffset() {
|
||||
return seedOffset;
|
||||
}
|
||||
|
||||
public void setSeedOffset(int seedOffset) {
|
||||
this.seedOffset = seedOffset;
|
||||
}
|
||||
|
||||
public FastNoiseLite.CellularDistanceFunction getCellularDistanceFunction() {
|
||||
return cellularDistanceFunction;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setCellularDistanceFunction(FastNoiseLite.CellularDistanceFunction cellularDistanceFunction) {
|
||||
this.cellularDistanceFunction = cellularDistanceFunction;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FastNoiseLite.CellularReturnType getCellularReturnType() {
|
||||
return cellularReturnType;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setCellularReturnType(FastNoiseLite.CellularReturnType cellularReturnType) {
|
||||
this.cellularReturnType = cellularReturnType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getCellularJitter() {
|
||||
return cellularJitter;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setCellularJitter(double cellularJitter) {
|
||||
this.cellularJitter = cellularJitter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getFractalGain() {
|
||||
return fractalGain;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setFractalGain(double fractalGain) {
|
||||
this.fractalGain = fractalGain;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getFractalLacunarity() {
|
||||
return fractalLacunarity;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setFractalLacunarity(double fractalLacunarity) {
|
||||
this.fractalLacunarity = fractalLacunarity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setFrequency(double frequency) {
|
||||
this.frequency = frequency;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getPingPong() {
|
||||
return pingPong;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setPingPong(double pingPong) {
|
||||
this.pingPong = pingPong;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getWeightedStrength() {
|
||||
return weightedStrength;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setWeightedStrength(double weightedStrength) {
|
||||
this.weightedStrength = weightedStrength;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getOctaves() {
|
||||
return octaves;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setOctaves(int octaves) {
|
||||
this.octaves = octaves;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FastNoiseLite.FractalType getFractalType() {
|
||||
return fractalType;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setFractalType(FastNoiseLite.FractalType fractalType) {
|
||||
this.fractalType = fractalType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FastNoiseLite.RotationType3D getRotationType3D() {
|
||||
return rotationType3D;
|
||||
}
|
||||
|
||||
public FastNoiseTemplate setRotationType3D(FastNoiseLite.RotationType3D rotationType3D) {
|
||||
this.rotationType3D = rotationType3D;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
public void setDimensions(int dimensions) {
|
||||
this.dimensions = dimensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoiseSeeded get() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler.templates;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
||||
import com.dfsek.tectonic.exception.ValidationException;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.KernelSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public class KernelTemplate extends SamplerTemplate<KernelSampler> implements ValidatedConfigTemplate {
|
||||
|
||||
@Value("kernel")
|
||||
private List<List<Double>> kernel;
|
||||
|
||||
@Value("factor")
|
||||
@Default
|
||||
private double factor = 1;
|
||||
|
||||
@Value("function")
|
||||
private NoiseSeeded function;
|
||||
|
||||
@Value("frequency")
|
||||
@Default
|
||||
private double frequency = 1;
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
double[][] k = new double[kernel.size()][kernel.get(0).size()];
|
||||
|
||||
for(int x = 0; x < kernel.size(); x++) {
|
||||
for(int y = 0; y < kernel.get(x).size(); y++) {
|
||||
k[x][y] = kernel.get(x).get(y) * factor;
|
||||
}
|
||||
}
|
||||
|
||||
KernelSampler sampler = new KernelSampler(k, function.apply(seed));
|
||||
sampler.setFrequency(frequency);
|
||||
return sampler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() throws ValidationException {
|
||||
|
||||
if(kernel.isEmpty()) throw new ValidationException("Kernel must not be empty.");
|
||||
|
||||
int len = kernel.get(0).size();
|
||||
|
||||
if(len == 0) throw new ValidationException("Kernel row must contain data.");
|
||||
|
||||
for(int i = 0; i < kernel.size(); i++) {
|
||||
if(kernel.get(i).size() != len)
|
||||
throw new ValidationException("Kernel row " + i + " size mismatch. Expected " + len + ", found " + kernel.get(i).size());
|
||||
}
|
||||
|
||||
return super.validate();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user