From 7e6b4a0b74cbdbdf7ea9a36fbfa396dcd59efb8c Mon Sep 17 00:00:00 2001 From: Astrash Date: Mon, 15 Aug 2022 10:34:29 +1000 Subject: [PATCH] Calculate slant with approx dot product rather than derivative --- .../config/palette/BiomePaletteTemplate.java | 6 ++-- .../generation/math/PaletteUtil.java | 36 +++++++++++-------- .../chunkgenerator/palette/SlantHolder.java | 26 +++++++------- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java index f1f0f804a..19b4a5abb 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java @@ -75,15 +75,15 @@ public class BiomePaletteTemplate implements ObjectTemplate { } TreeMap 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); } } diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/PaletteUtil.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/PaletteUtil.java index d649cf4f2..524f2b8d9 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/PaletteUtil.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/PaletteUtil.java @@ -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()); } } \ No newline at end of file diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SlantHolder.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SlantHolder.java index 6ceacee24..72e5f4a6a 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SlantHolder.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SlantHolder.java @@ -14,39 +14,39 @@ import java.util.TreeMap; public class SlantHolder { private final TreeMap layers; - private final double minSlope; + private final double maxSlant; - private SlantHolder(TreeMap layers, double minSlope) { + private SlantHolder(TreeMap layers, double maxSlant) { this.layers = layers; - this.minSlope = minSlope; + this.maxSlant = maxSlant; } - public static SlantHolder of(TreeMap layers, double minSlope) { + public static SlantHolder of(TreeMap layers, double maxSlant) { if(layers.size() == 1) { Entry 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; } }