Yatopia/patches/server/0025-lithium-MixinChunkGeneratorAbstract.patch
Ivan Pekov d065d41c0e
Drop this unsafe shit
Apparently caused issues we werent aware of.
Unfortunately there's no way to improve it without blocking the main thread.
2020-10-02 17:00:13 +03:00

190 lines
7.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: JellySquid <jellysquid+atwork@protonmail.com>
Date: Tue, 4 Aug 2020 21:06:02 +0200
Subject: [PATCH] lithium-MixinChunkGeneratorAbstract
Original code by JellySquid, licensed under GNU Lesser General Public License v3.0
you can find the original code on https://github.com/jellysquid3/lithium-fabric/tree/1.16.x/fabric (Yarn mappings)
Co-authored-by: tr7zw <tr7zw@live.de>
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/world/noise/SimplexNoiseCache.java b/src/main/java/me/jellysquid/mods/lithium/common/world/noise/SimplexNoiseCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..e6cd19e75a88f4dbf38d3cc63883068d95aa67d4
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/world/noise/SimplexNoiseCache.java
@@ -0,0 +1,135 @@
+package me.jellysquid.mods.lithium.common.world.noise;
+
+import it.unimi.dsi.fastutil.HashCommon;
+
+import net.minecraft.server.ChunkCoordIntPair;
+import net.minecraft.server.MathHelper;
+import net.minecraft.server.NoiseGenerator3Handler;
+
+import java.util.Arrays;
+
+/**
+ * A cache for the End's noise generator that caches computed values. Through the caching, we can eliminate a large
+ * amount of overhead in computing the noise values several hundred thousand times per chunk. This code uses the same
+ * array backed lossy cache as FastCachingLayerSampler.
+ */
+public class SimplexNoiseCache {
+ private static final int GRID_SIZE = 2;
+ private static final float MIN = -100.0F;
+ private static final float MAX = 80.0F;
+ private static final float ISLAND_RADIUS = 100.0F;
+ // The smallest encompassing power of two that can store all of the noise values in a chunk.
+ private static final int CACHE_SIZE = 8192;
+
+ private final int mask;
+ private final long[] keys;
+ private final float[] values;
+
+ private final NoiseGenerator3Handler sampler;
+
+ public SimplexNoiseCache(NoiseGenerator3Handler sampler) {
+ this.sampler = sampler;
+
+ this.mask = CACHE_SIZE - 1;
+
+ // Initialize default values
+ this.keys = new long[CACHE_SIZE];
+ Arrays.fill(this.keys, Long.MIN_VALUE);
+ this.values = new float[CACHE_SIZE];
+ }
+
+ /**
+ * Attempt to get the cached distance factor, saving computation time.
+ */
+ private float getDistanceFactor(int x, int z) {
+ // Hash key and get index
+ long key = ChunkCoordIntPair.pair(x, z);
+ int idx = (int) HashCommon.mix(key) & this.mask;
+
+ if (this.keys[idx] == key) {
+ // Cache hit, return cached value
+ return this.values[idx];
+ }
+
+ // Cache miss, compute and store value
+
+ // A marker for no value.
+ float value = -1.0F;
+
+ long lx = x;
+ long lz = z;
+ long distanceFromOriginSq = lx * lx + lz * lz;
+
+ // Ensure we are 64 grid cells away from the origin.
+ if (distanceFromOriginSq > 64 * 64) {
+ // Reduce the number of island-forming grid cells by sampling noise with a threshold
+ if (this.sampler.a(x, z) < -0.9) {
+ // Generate a pseudo-random value from 9 to 21
+ value = (Math.abs(x) * 3439.0F + Math.abs(z) * 147.0F) %13.0F + 9.0F;
+ }
+ }
+
+ // Store values in cache
+ this.keys[idx] = key;
+ this.values[idx] = value;
+
+ return value;
+ }
+
+ /**
+ * Mapped and cleaned up implementation of the End biome source's sampler. Tries to use cached values wherever
+ * possible.
+ */
+ public float getNoiseAt(int x, int z) {
+ // [VanillaCopy] TheEndBiomeSource#getNoiseAt
+
+ int gridX = x / GRID_SIZE;
+ int gridZ = z / GRID_SIZE;
+
+ // This is the "center point", offset to center around the current grid cell
+ int gridOriginX = x % GRID_SIZE;
+ int gridOriginZ = z % GRID_SIZE;
+
+ // Initialize density for the central island
+ float density = ISLAND_RADIUS - MathHelper.sqrt(x * x + z * z) * 8.0F;
+ if (density >= MAX) {
+ return MAX;
+ }
+
+ // Iterate through 25x25 grid cells
+ for (int offsetX = -12; offsetX <= 12; offsetX++) {
+ for (int offsetZ = -12; offsetZ <= 12; offsetZ++) {
+ int globalGridX = gridX + offsetX;
+ int globalGridZ = gridZ + offsetZ;
+
+ // Try to retrieve values from cache
+ float distanceFactor = getDistanceFactor(globalGridX, globalGridZ);
+ if (distanceFactor != -1.0F) {
+ // Compute the distance to the origin
+ float deltaX = gridOriginX - offsetX * GRID_SIZE;
+ float deltaZ = gridOriginZ - offsetZ * GRID_SIZE;
+
+ // Calculate the density at this grid cell
+ float scaledDistance = MathHelper.sqrt(deltaX * deltaX + deltaZ * deltaZ) * distanceFactor;
+ float densityHere = ISLAND_RADIUS - scaledDistance;
+
+ // Try to return early if we're over the max
+ if (densityHere > density) {
+ if (densityHere >= MAX) {
+ return MAX;
+ }
+
+ density = densityHere;
+ }
+ }
+ }
+ }
+
+ // Avoid a call to Math.max because the density cannot be bigger than the max.
+ if (density < MIN) {
+ return MIN;
+ }
+
+ return density;
+ }
+}
diff --git a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
index 321ebe8891defb46f3ad3dfea37c9bb6e2025ad7..119804e5c12aca3f4fbfeaf424f46152f43b3941 100644
--- a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
+++ b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
@@ -57,12 +57,13 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator {
private final NoiseGenerator t;
private final NoiseGeneratorOctaves u;
@Nullable
- private final NoiseGenerator3Handler v;
+ private final NoiseGenerator3Handler v; // Yatopia - yarn "SimplexNoiseSampler"
protected final IBlockData f;
protected final IBlockData g;
private final long w;
protected final Supplier<GeneratorSettingBase> h;
private final int x;
+ private ThreadLocal<me.jellysquid.mods.lithium.common.world.noise.SimplexNoiseCache> tlCache; // Yatopia
public ChunkGeneratorAbstract(WorldChunkManager worldchunkmanager, long i, Supplier<GeneratorSettingBase> supplier) {
this(worldchunkmanager, worldchunkmanager, i, supplier);
@@ -99,7 +100,7 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator {
} else {
this.v = null;
}
-
+ this.tlCache = ThreadLocal.withInitial(() -> new me.jellysquid.mods.lithium.common.world.noise.SimplexNoiseCache(v)); // Yatopia
}
@Override
@@ -164,7 +165,8 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator {
double d3;
if (this.v != null) {
- d0 = (double) (WorldChunkManagerTheEnd.a(this.v, i, j) - 8.0F);
+ //d0 = (double) (WorldChunkManagerTheEnd.a(this.v, i, j) - 8.0F); // Yatopia
+ d0 = tlCache.get().getNoiseAt(i, j) - 8.0F; // Yatopia
if (d0 > 0.0D) {
d1 = 0.25D;
} else {