Calculate slant with approx dot product rather than derivative

This commit is contained in:
Astrash
2022-08-15 10:34:29 +10:00
parent 3dd3c047b4
commit 7e6b4a0b74
3 changed files with 38 additions and 30 deletions

View File

@@ -75,15 +75,15 @@ public class BiomePaletteTemplate implements ObjectTemplate<PaletteInfo> {
}
TreeMap<Double, PaletteHolder> slantLayers = new TreeMap<>();
double minThreshold = Double.MAX_VALUE;
double maxThreshold = Double.MIN_VALUE;
for(SlantLayer layer : slant) {
double threshold = layer.getThreshold();
if(threshold < minThreshold) minThreshold = threshold;
if(threshold > maxThreshold) maxThreshold = threshold;
slantLayers.put(threshold, layer.getPalette());
}
return new PaletteInfo(builder.build(), SlantHolder.of(slantLayers, minThreshold), oceanPalette, seaLevel, slantDepth,
return new PaletteInfo(builder.build(), SlantHolder.of(slantLayers, maxThreshold), oceanPalette, seaLevel, slantDepth,
updatePalette);
}
}

View File

@@ -10,6 +10,7 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math;
import com.dfsek.terra.addons.chunkgenerator.config.palette.PaletteInfo;
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder;
import com.dfsek.terra.api.util.vector.Vector3;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
@@ -22,25 +23,32 @@ public final class PaletteUtil {
public static Palette getPalette(int x, int y, int z, Sampler3D sampler, PaletteInfo paletteInfo, int depth) {
SlantHolder slant = paletteInfo.slantHolder();
if(!slant.isEmpty() && depth <= paletteInfo.maxSlantDepth()) {
double slope = derivative(sampler, x, y, z);
if(slope > slant.getMinSlope()) {
return slant.getPalette(slope).getPalette(y);
double dot = surfaceNormalDotProduct(sampler, x, y, z);
if(dot <= slant.getMaxSlant()) {
return slant.getPalette(dot).getPalette(y);
}
}
return paletteInfo.paletteHolder().getPalette(y);
}
public static double derivative(Sampler3D sampler, double x, double y, double z) {
double baseSample = sampler.sample(x, y, z);
double xVal1 = (sampler.sample(x + DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
double xVal2 = (sampler.sample(x - DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
double zVal1 = (sampler.sample(x, y, z + DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
double zVal2 = (sampler.sample(x, y, z - DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
double yVal1 = (sampler.sample(x, y + DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
double yVal2 = (sampler.sample(x, y - DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
return Math.sqrt(((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1)));
private static final Vector3[] samplePoints = {
Vector3.of(0, 0, -DERIVATIVE_DIST),
Vector3.of(0, 0, DERIVATIVE_DIST),
Vector3.of(0, -DERIVATIVE_DIST, 0),
Vector3.of(0, DERIVATIVE_DIST, 0),
Vector3.of(-DERIVATIVE_DIST, 0, 0),
Vector3.of(DERIVATIVE_DIST, 0, 0),
};
private static final Vector3 direction = Vector3.of(0, 1, 0);
public static double surfaceNormalDotProduct(Sampler3D sampler, double x, double y, double z) {
Vector3.Mutable surfaceNormalApproximation = Vector3.Mutable.of(0, 0, 0);
for(Vector3 point : samplePoints) {
double scalar = -sampler.sample(x+point.getX(), y+point.getY(), z+point.getZ());
surfaceNormalApproximation.add(point.mutable().multiply(scalar));
}
return direction.dot(surfaceNormalApproximation.normalize());
}
}

View File

@@ -14,39 +14,39 @@ import java.util.TreeMap;
public class SlantHolder {
private final TreeMap<Double, PaletteHolder> layers;
private final double minSlope;
private final double maxSlant;
private SlantHolder(TreeMap<Double, PaletteHolder> layers, double minSlope) {
private SlantHolder(TreeMap<Double, PaletteHolder> layers, double maxSlant) {
this.layers = layers;
this.minSlope = minSlope;
this.maxSlant = maxSlant;
}
public static SlantHolder of(TreeMap<Double, PaletteHolder> layers, double minSlope) {
public static SlantHolder of(TreeMap<Double, PaletteHolder> layers, double maxSlant) {
if(layers.size() == 1) {
Entry<Double, PaletteHolder> firstEntry = layers.firstEntry();
return new Single(firstEntry.getValue(), minSlope);
return new Single(firstEntry.getValue(), maxSlant);
}
return new SlantHolder(layers, minSlope);
return new SlantHolder(layers, maxSlant);
}
public boolean isEmpty() {
return layers.isEmpty();
}
public PaletteHolder getPalette(double slope) {
return layers.floorEntry(slope).getValue();
public PaletteHolder getPalette(double slant) {
return layers.ceilingEntry(slant).getValue();
}
public double getMinSlope() {
return minSlope;
public double getMaxSlant() {
return maxSlant;
}
private static final class Single extends SlantHolder {
private final PaletteHolder layers;
public Single(PaletteHolder layers, double minSlope) {
super(of(minSlope, layers), minSlope);
public Single(PaletteHolder layers, double maxSlant) {
super(of(maxSlant, layers), maxSlant);
this.layers = layers;
}
@@ -57,7 +57,7 @@ public class SlantHolder {
}
@Override
public PaletteHolder getPalette(double slope) {
public PaletteHolder getPalette(double slant) {
return layers;
}
}