optimize ores and sampling

This commit is contained in:
dfsek 2021-03-15 21:10:52 -07:00
parent 5ad349e350
commit 6f4251796e
7 changed files with 39 additions and 12 deletions

View File

@ -15,6 +15,11 @@ public interface ChunkInterpolator {
*/
double getNoise(double x, double y, double z);
default double getNoise(int x, int y, int z) { // Floating-point modulus operations are expensive. This allows implementations to optionally handle integers separately.
return getNoise((double) x, y, z);
}
default double computeNoise(Map<Generator, MutableInteger> gens, double x, double y, double z) {
double n = 0;
double div = 0;

View File

@ -81,4 +81,8 @@ public class ChunkInterpolator2D implements ChunkInterpolator {
public double getNoise(double x, double y, double z) {
return interpGrid[reRange(((int) x) / 4, 3)][reRange(((int) z) / 4, 3)].bilerp((x % 4) / 4, (z % 4) / 4);
}
public double getNoise(int x, int y, int z) {
return interpGrid[x / 4][z / 4].bilerp((double) (x % 4) / 4, (double) (z % 4) / 4);
}
}

View File

@ -100,4 +100,8 @@ public class ChunkInterpolator3D implements ChunkInterpolator {
public double getNoise(double x, double y, double z) {
return interpGrid[reRange(((int) x) / 4, 3)][FastMath.max(FastMath.min(((int) y), max), min) / 4][reRange(((int) z) / 4, 3)].trilerp((x % 4) / 4, (y % 4) / 4, (z % 4) / 4);
}
public double getNoise(int x, int y, int z) {
return interpGrid[x / 4][y / 4][z / 4].trilerp((double) (x % 4) / 4, (double) (y % 4) / 4, (double) (z % 4) / 4);
}
}

View File

@ -3,4 +3,8 @@ package com.dfsek.terra.world.generation.math.samplers;
@FunctionalInterface
public interface Sampler {
double sample(double x, double y, double z);
default double sample(int x, int y, int z) { // Floating-point modulus operations are expensive. This allows implementations to optionally handle integers separately.
return sample((double) x, y, z);
}
}

View File

@ -19,4 +19,9 @@ public class Sampler2D implements Sampler {
public double sample(double x, double y, double z) {
return interpolator.getNoise(x, 0, z) + elevationInterpolator.getElevation(FastMath.roundToInt(x), FastMath.roundToInt(z));
}
@Override
public double sample(int x, int y, int z) {
return interpolator.getNoise(x, 0, z) + elevationInterpolator.getElevation(FastMath.roundToInt(x), FastMath.roundToInt(z));
}
}

View File

@ -19,4 +19,9 @@ public class Sampler3D implements Sampler {
public double sample(double x, double y, double z) {
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(FastMath.roundToInt(x), FastMath.roundToInt(z));
}
@Override
public double sample(int x, int y, int z) {
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(FastMath.roundToInt(x), FastMath.roundToInt(z));
}
}

View File

@ -5,7 +5,6 @@ import com.dfsek.terra.api.math.Range;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.handle.WorldHandle;
import com.dfsek.terra.api.platform.world.Chunk;
import com.dfsek.terra.api.util.collections.MaterialSet;
import net.jafama.FastMath;
@ -23,7 +22,6 @@ public class VanillaOre extends Ore {
@Override
public void generate(Vector3 location, Chunk chunk, Random random) {
WorldHandle handle = main.getWorldHandle();
double size = sizeRange.get(random);
int centerX = location.getBlockX();
@ -31,29 +29,31 @@ public class VanillaOre extends Ore {
int centerY = location.getBlockY();
float f = random.nextFloat() * (float) Math.PI;
double f = random.nextFloat() * Math.PI;
double d1 = centerX + 8 + FastMath.sin(f) * size / 8.0F;
double d2 = centerX + 8 - FastMath.sin(f) * size / 8.0F;
double d3 = centerZ + 8 + FastMath.cos(f) * size / 8.0F;
double d4 = centerZ + 8 - FastMath.cos(f) * size / 8.0F;
double fS = FastMath.sin(f) * size / 8.0F;
double fC = FastMath.cos(f) * size / 8.0F;
double d1 = centerX + 8 + fS;
double d2 = centerX + 8 - fS;
double d3 = centerZ + 8 + fC;
double d4 = centerZ + 8 - fC;
double d5 = centerY + random.nextInt(3) - 2D;
double d6 = centerY + random.nextInt(3) - 2D;
for(int i = 0; i < size; i++) {
float iFactor = (float) i / (float) size;
double iFactor = i / size;
double d10 = random.nextDouble() * size / 16.0D;
double d11 = (FastMath.sin(Math.PI * iFactor) + 1.0) * d10 + 1.0;
double d12 = (FastMath.sin(Math.PI * iFactor) + 1.0) * d10 + 1.0;
int xStart = FastMath.roundToInt(FastMath.floor(d1 + (d2 - d1) * iFactor - d11 / 2.0D));
int yStart = FastMath.roundToInt(FastMath.floor(d5 + (d6 - d5) * iFactor - d12 / 2.0D));
int yStart = FastMath.roundToInt(FastMath.floor(d5 + (d6 - d5) * iFactor - d11 / 2.0D));
int zStart = FastMath.roundToInt(FastMath.floor(d3 + (d4 - d3) * iFactor - d11 / 2.0D));
int xEnd = FastMath.roundToInt(FastMath.floor(d1 + (d2 - d1) * iFactor + d11 / 2.0D));
int yEnd = FastMath.roundToInt(FastMath.floor(d5 + (d6 - d5) * iFactor + d12 / 2.0D));
int yEnd = FastMath.roundToInt(FastMath.floor(d5 + (d6 - d5) * iFactor + d11 / 2.0D));
int zEnd = FastMath.roundToInt(FastMath.floor(d3 + (d4 - d3) * iFactor + d11 / 2.0D));
for(int x = xStart; x <= xEnd; x++) {
@ -61,7 +61,7 @@ public class VanillaOre extends Ore {
if(d13 * d13 < 1.0D) {
for(int y = yStart; y <= yEnd; y++) {
double d14 = (y + 0.5D - (d5 + (d6 - d5) * iFactor)) / (d12 / 2.0D);
double d14 = (y + 0.5D - (d5 + (d6 - d5) * iFactor)) / (d11 / 2.0D);
if(d13 * d13 + d14 * d14 < 1.0D) {
for(int z = zStart; z <= zEnd; z++) {
double d15 = (z + 0.5D - (d3 + (d4 - d3) * iFactor)) / (d11 / 2.0D);