mirror of
https://github.com/YatopiaMC/Yatopia.git
synced 2024-11-29 22:23:50 +01:00
d065d41c0e
Apparently caused issues we werent aware of. Unfortunately there's no way to improve it without blocking the main thread.
190 lines
7.4 KiB
Diff
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 {
|