526 lines
22 KiB
Diff
526 lines
22 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: ishland <ishlandmc@yeah.net>
|
|
Date: Tue, 21 Sep 2021 10:37:34 +0200
|
|
Subject: [PATCH] C2ME optimizations
|
|
|
|
c2me: opts math
|
|
|
|
Copyright (c) 2021-2022 ishland
|
|
|
|
Original code by RelativityMC, licensed under MIT
|
|
You can find the original code on https://github.com/RelativityMC/C2ME-fabric (Yarn mappings)
|
|
|
|
c2me: reduce_allocs
|
|
|
|
Copyright (c) 2021-2022 ishland
|
|
|
|
Original code by RelativityMC, licensed under MIT
|
|
You can find the original code on https://github.com/RelativityMC/C2ME-fabric (Yarn mappings)
|
|
|
|
diff --git a/src/main/java/com/ishland/c2me/opts/allocs/common/ObjectCachingUtils.java b/src/main/java/com/ishland/c2me/opts/allocs/common/ObjectCachingUtils.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..b1229bae2e74d22065c723c6d3eaf9a97d572b04
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/ishland/c2me/opts/allocs/common/ObjectCachingUtils.java
|
|
@@ -0,0 +1,23 @@
|
|
+package com.ishland.c2me.opts.allocs.common;
|
|
+
|
|
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|
+
|
|
+import java.util.BitSet;
|
|
+import java.util.function.IntFunction;
|
|
+
|
|
+public class ObjectCachingUtils {
|
|
+
|
|
+ private static final IntFunction<BitSet> bitSetConstructor = BitSet::new;
|
|
+
|
|
+ public static ThreadLocal<Int2ObjectOpenHashMap<BitSet>> BITSETS = ThreadLocal.withInitial(Int2ObjectOpenHashMap::new);
|
|
+
|
|
+ private ObjectCachingUtils() {
|
|
+ }
|
|
+
|
|
+ public static BitSet getCachedOrNewBitSet(int bits) {
|
|
+ final BitSet bitSet = BITSETS.get().computeIfAbsent(bits, bitSetConstructor);
|
|
+ bitSet.clear();
|
|
+ return bitSet;
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/com/ishland/c2me/opts/allocs/common/PooledFeatureContext.java b/src/main/java/com/ishland/c2me/opts/allocs/common/PooledFeatureContext.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..4c84006c90bda4849b27879d5218f98e6d98f1dc
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/ishland/c2me/opts/allocs/common/PooledFeatureContext.java
|
|
@@ -0,0 +1,68 @@
|
|
+package com.ishland.c2me.opts.allocs.common;
|
|
+
|
|
+import java.util.Optional;
|
|
+import net.minecraft.core.BlockPos;
|
|
+import net.minecraft.util.RandomSource;
|
|
+import net.minecraft.world.level.WorldGenLevel;
|
|
+import net.minecraft.world.level.chunk.ChunkGenerator;
|
|
+import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
|
+import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
|
+import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
|
+
|
|
+public class PooledFeatureContext<FC extends FeatureConfiguration> extends FeaturePlaceContext<FC> {
|
|
+
|
|
+ public static final ThreadLocal<SimpleObjectPool<PooledFeatureContext<?>>> POOL = ThreadLocal.withInitial(() -> new SimpleObjectPool<>(unused -> new PooledFeatureContext<>(), unused -> {}, 2048));
|
|
+
|
|
+ private Optional<ConfiguredFeature<?, ?>> feature;
|
|
+ private WorldGenLevel world;
|
|
+ private ChunkGenerator generator;
|
|
+ private RandomSource random;
|
|
+ private BlockPos origin;
|
|
+ private FC config;
|
|
+
|
|
+ public PooledFeatureContext() {
|
|
+ super(null, null, null, null, null, null);
|
|
+ }
|
|
+
|
|
+ public void reInit(Optional<ConfiguredFeature<?, ?>> feature, WorldGenLevel world, ChunkGenerator generator, RandomSource random, BlockPos origin, FC config) {
|
|
+ this.feature = feature;
|
|
+ this.world = world;
|
|
+ this.generator = generator;
|
|
+ this.random = random;
|
|
+ this.origin = origin;
|
|
+ this.config = config;
|
|
+ }
|
|
+
|
|
+ public void reInit() {
|
|
+ this.feature = null;
|
|
+ this.world = null;
|
|
+ this.generator = null;
|
|
+ this.random = null;
|
|
+ this.origin = null;
|
|
+ this.config = null;
|
|
+ }
|
|
+
|
|
+ public WorldGenLevel level() {
|
|
+ return this.world;
|
|
+ }
|
|
+
|
|
+ public ChunkGenerator chunkGenerator() {
|
|
+ return this.generator;
|
|
+ }
|
|
+
|
|
+ public RandomSource random() {
|
|
+ return this.random;
|
|
+ }
|
|
+
|
|
+ public BlockPos origin() {
|
|
+ return this.origin;
|
|
+ }
|
|
+
|
|
+ public FC config() {
|
|
+ return this.config;
|
|
+ }
|
|
+
|
|
+ public Optional<ConfiguredFeature<?, ?>> topFeature() {
|
|
+ return this.feature;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/com/ishland/c2me/opts/allocs/common/SimpleObjectPool.java b/src/main/java/com/ishland/c2me/opts/allocs/common/SimpleObjectPool.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..b989019847f73ba3af57f7428699c9c869d6332f
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/ishland/c2me/opts/allocs/common/SimpleObjectPool.java
|
|
@@ -0,0 +1,57 @@
|
|
+package com.ishland.c2me.opts.allocs.common;
|
|
+
|
|
+import com.google.common.base.Preconditions;
|
|
+
|
|
+import java.util.Objects;
|
|
+import java.util.function.Consumer;
|
|
+import java.util.function.Function;
|
|
+
|
|
+public class SimpleObjectPool<T> {
|
|
+
|
|
+ private final Function<SimpleObjectPool<T>, T> constructor;
|
|
+ private final Consumer<T> initializer;
|
|
+ private final int size;
|
|
+
|
|
+ private final Object[] cachedObjects;
|
|
+ private int allocatedCount = 0;
|
|
+
|
|
+ public SimpleObjectPool(Function<SimpleObjectPool<T>, T> constructor, Consumer<T> initializer, int size) {
|
|
+ this.constructor = Objects.requireNonNull(constructor);
|
|
+ this.initializer = Objects.requireNonNull(initializer);
|
|
+ Preconditions.checkArgument(size > 0);
|
|
+ this.cachedObjects = new Object[size];
|
|
+ this.size = size;
|
|
+
|
|
+ for (int i = 0; i < size; i++) {
|
|
+ final T object = constructor.apply(this);
|
|
+ this.cachedObjects[i] = object;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public T alloc() {
|
|
+ final T object;
|
|
+ synchronized (this) {
|
|
+ if (this.allocatedCount >= this.size) { // oversized, falling back to normal alloc
|
|
+ object = this.constructor.apply(this);
|
|
+ return object;
|
|
+ }
|
|
+
|
|
+ // get an object from the array
|
|
+ final int ordinal = this.allocatedCount++;
|
|
+ object = (T) this.cachedObjects[ordinal];
|
|
+ this.cachedObjects[ordinal] = null;
|
|
+ }
|
|
+
|
|
+ this.initializer.accept(object); // initialize the object
|
|
+
|
|
+ return object;
|
|
+ }
|
|
+
|
|
+ public void release(T object) {
|
|
+ synchronized (this) {
|
|
+ if (this.allocatedCount == 0) return; // pool is full
|
|
+ this.cachedObjects[--this.allocatedCount] = object; // store the object into the pool
|
|
+ }
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/resources/ResourceLocation.java b/src/main/java/net/minecraft/resources/ResourceLocation.java
|
|
index 7017dd42f832d928f1008a05f01701667d951644..4e767dd8f9594e8a8f5d71e2bfd8c976c0032f98 100644
|
|
--- a/src/main/java/net/minecraft/resources/ResourceLocation.java
|
|
+++ b/src/main/java/net/minecraft/resources/ResourceLocation.java
|
|
@@ -27,6 +27,7 @@ public class ResourceLocation implements Comparable<ResourceLocation> {
|
|
public static final String REALMS_NAMESPACE = "realms";
|
|
protected final String namespace;
|
|
protected final String path;
|
|
+ private String cachedString = null; // Mirai - c2me: opts allocs
|
|
|
|
protected ResourceLocation(String[] id) {
|
|
this.namespace = StringUtils.isEmpty(id[0]) ? "minecraft" : id[0];
|
|
@@ -99,7 +100,16 @@ public class ResourceLocation implements Comparable<ResourceLocation> {
|
|
|
|
@Override
|
|
public String toString() {
|
|
- return this.namespace + ":" + this.path;
|
|
+ // Mirai start - c2me: opts allocs
|
|
+ /**
|
|
+ * @author ishland
|
|
+ * @reason cache toString
|
|
+ */
|
|
+ if (this.cachedString != null) return this.cachedString;
|
|
+ final String s = this.namespace + ":" + this.path;
|
|
+ this.cachedString = s;
|
|
+ return s;
|
|
+ // Mirai end
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/ConfiguredFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/ConfiguredFeature.java
|
|
index 2f67705132df06ae6231dd1b89a4f61a90616ef5..1013df19df55316200169f6c3deec8876ea4686a 100644
|
|
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/ConfiguredFeature.java
|
|
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/ConfiguredFeature.java
|
|
@@ -12,6 +12,10 @@ import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.level.WorldGenLevel;
|
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
|
+// Mirai start - c2me: opts allocs
|
|
+import com.ishland.c2me.opts.allocs.common.PooledFeatureContext;
|
|
+import com.ishland.c2me.opts.allocs.common.SimpleObjectPool;
|
|
+// Mirai end
|
|
|
|
public record ConfiguredFeature<FC extends FeatureConfiguration, F extends Feature<FC>>(F feature, FC config) {
|
|
public static final Codec<ConfiguredFeature<?, ?>> DIRECT_CODEC = Registry.FEATURE.byNameCodec().dispatch((configuredFeature) -> {
|
|
@@ -21,7 +25,22 @@ public record ConfiguredFeature<FC extends FeatureConfiguration, F extends Featu
|
|
public static final Codec<HolderSet<ConfiguredFeature<?, ?>>> LIST_CODEC = RegistryCodecs.homogeneousList(Registry.CONFIGURED_FEATURE_REGISTRY, DIRECT_CODEC);
|
|
|
|
public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, RandomSource random, BlockPos origin) {
|
|
- return this.feature.place(this.config, world, chunkGenerator, random, origin);
|
|
+ // Mirai start - c2me: opts allocs
|
|
+ /**
|
|
+ * @author ishland
|
|
+ * @reason pool FeatureContext
|
|
+ */
|
|
+ if (!world.ensureCanWrite(origin)) return false;
|
|
+ final SimpleObjectPool<PooledFeatureContext<?>> pool = PooledFeatureContext.POOL.get();
|
|
+ final PooledFeatureContext<FC> context = (PooledFeatureContext<FC>) pool.alloc();
|
|
+ try {
|
|
+ context.reInit(java.util.Optional.empty(), world, chunkGenerator, random, origin, this.config);
|
|
+ return this.feature.place(context);
|
|
+ } finally {
|
|
+ context.reInit();
|
|
+ pool.release(context);
|
|
+ }
|
|
+ // Mirai end
|
|
}
|
|
|
|
public Stream<ConfiguredFeature<?, ?>> getFeatures() {
|
|
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java
|
|
index b2f36a998437e2a63a3cbc6c3aa95b1402bff2f1..d69a57f67eeb99f3db4f80d13b9f0276ce4603af 100644
|
|
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java
|
|
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java
|
|
@@ -54,7 +54,7 @@ public class OreFeature extends Feature<OreConfiguration> {
|
|
|
|
protected boolean doPlace(WorldGenLevel world, RandomSource randomSource, OreConfiguration config, double startX, double endX, double startZ, double endZ, double startY, double endY, int x, int y, int z, int horizontalSize, int verticalSize) {
|
|
int i = 0;
|
|
- BitSet bitSet = new BitSet(horizontalSize * verticalSize * horizontalSize);
|
|
+ BitSet bitSet = com.ishland.c2me.opts.allocs.common.ObjectCachingUtils.getCachedOrNewBitSet(horizontalSize * verticalSize * horizontalSize); // Mirai - c2me: opts allocs
|
|
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
|
int j = config.size;
|
|
double[] ds = new double[j * 4];
|
|
diff --git a/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java b/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
|
|
index fb84d703b4461343d50510d7c9be32fc1f09ed22..3da6b30febc98e5392e42d39c5bd69a82116dc2d 100644
|
|
--- a/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
|
|
+++ b/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
|
|
@@ -11,6 +11,27 @@ public final class ImprovedNoise {
|
|
public final double yo;
|
|
public final double zo;
|
|
|
|
+ // Mirai start - c2me: opts math
|
|
+ private static final double[] FLAT_SIMPLEX_GRAD = new double[]{
|
|
+ 1, 1, 0, 0,
|
|
+ -1, 1, 0, 0,
|
|
+ 1, -1, 0, 0,
|
|
+ -1, -1, 0, 0,
|
|
+ 1, 0, 1, 0,
|
|
+ -1, 0, 1, 0,
|
|
+ 1, 0, -1, 0,
|
|
+ -1, 0, -1, 0,
|
|
+ 0, 1, 1, 0,
|
|
+ 0, -1, 1, 0,
|
|
+ 0, 1, -1, 0,
|
|
+ 0, -1, -1, 0,
|
|
+ 1, 1, 0, 0,
|
|
+ 0, -1, 1, 0,
|
|
+ -1, 1, 0, 0,
|
|
+ 0, -1, -1, 0,
|
|
+ };
|
|
+ // Mirai end
|
|
+
|
|
public ImprovedNoise(RandomSource random) {
|
|
this.xo = random.nextDouble() * 256.0D;
|
|
this.yo = random.nextDouble() * 256.0D;
|
|
@@ -34,34 +55,38 @@ public final class ImprovedNoise {
|
|
return this.noise(x, y, z, 0.0D, 0.0D);
|
|
}
|
|
|
|
+ // Mirai start - c2me: opts math
|
|
+ /**
|
|
+ * @author ishland
|
|
+ * @reason optimize: remove frequent type conversions
|
|
+ */
|
|
/** @deprecated */
|
|
@Deprecated
|
|
public double noise(double x, double y, double z, double yScale, double yMax) {
|
|
double d = x + this.xo;
|
|
double e = y + this.yo;
|
|
double f = z + this.zo;
|
|
- int i = Mth.floor(d);
|
|
- int j = Mth.floor(e);
|
|
- int k = Mth.floor(f);
|
|
- double g = d - (double)i;
|
|
- double h = e - (double)j;
|
|
- double l = f - (double)k;
|
|
- double o;
|
|
- if (yScale != 0.0D) {
|
|
+ double i = Mth.floor(d);
|
|
+ double j = Mth.floor(e);
|
|
+ double k = Mth.floor(f);
|
|
+ double g = d - i;
|
|
+ double h = e - j;
|
|
+ double l = f - k;
|
|
+ double o = 0.0D;
|
|
+ if (yScale != 0.0) {
|
|
double m;
|
|
- if (yMax >= 0.0D && yMax < h) {
|
|
+ if (yMax >= 0.0 && yMax < h) {
|
|
m = yMax;
|
|
} else {
|
|
m = h;
|
|
}
|
|
|
|
- o = (double)Mth.floor(m / yScale + (double)1.0E-7F) * yScale;
|
|
- } else {
|
|
- o = 0.0D;
|
|
+ o = Mth.floor(m / yScale + 1.0E-7F) * yScale;
|
|
}
|
|
|
|
- return this.sampleAndLerp(i, j, k, g, h - o, l, h);
|
|
+ return this.sampleAndLerp((int) i, (int) j, (int) k, g, h - o, l, h);
|
|
}
|
|
+ // Mirai end
|
|
|
|
public double noiseWithDerivative(double x, double y, double z, double[] ds) {
|
|
double d = x + this.xo;
|
|
@@ -84,26 +109,76 @@ public final class ImprovedNoise {
|
|
return this.p[input & 255] & 255;
|
|
}
|
|
|
|
- private double sampleAndLerp(int sectionX, int sectionY, int sectionZ, double localX, double localY, double localZ, double fadeLocalY) {
|
|
- int i = this.p(sectionX);
|
|
- int j = this.p(sectionX + 1);
|
|
- int k = this.p(i + sectionY);
|
|
- int l = this.p(i + sectionY + 1);
|
|
- int m = this.p(j + sectionY);
|
|
- int n = this.p(j + sectionY + 1);
|
|
- double d = gradDot(this.p(k + sectionZ), localX, localY, localZ);
|
|
- double e = gradDot(this.p(m + sectionZ), localX - 1.0D, localY, localZ);
|
|
- double f = gradDot(this.p(l + sectionZ), localX, localY - 1.0D, localZ);
|
|
- double g = gradDot(this.p(n + sectionZ), localX - 1.0D, localY - 1.0D, localZ);
|
|
- double h = gradDot(this.p(k + sectionZ + 1), localX, localY, localZ - 1.0D);
|
|
- double o = gradDot(this.p(m + sectionZ + 1), localX - 1.0D, localY, localZ - 1.0D);
|
|
- double p = gradDot(this.p(l + sectionZ + 1), localX, localY - 1.0D, localZ - 1.0D);
|
|
- double q = gradDot(this.p(n + sectionZ + 1), localX - 1.0D, localY - 1.0D, localZ - 1.0D);
|
|
- double r = Mth.smoothstep(localX);
|
|
- double s = Mth.smoothstep(fadeLocalY);
|
|
- double t = Mth.smoothstep(localZ);
|
|
- return Mth.lerp3(r, s, t, d, e, f, g, h, o, p, q);
|
|
+ // Mirai start - c2me: opts math
|
|
+ /**
|
|
+ * @author ishland
|
|
+ * @reason inline math & small optimization: remove frequent type conversions and redundant ops
|
|
+ */
|
|
+ private double sampleAndLerp(int sectionX, int sectionY, int sectionZ, double localX, double localY, double localZ, double fadeLocalX) {
|
|
+ // TODO [VanillaCopy] but optimized
|
|
+ final int var0 = sectionX & 0xFF;
|
|
+ final int var1 = (sectionX + 1) & 0xFF;
|
|
+ final int var2 = this.p[var0] & 0xFF;
|
|
+ final int var3 = this.p[var1] & 0xFF;
|
|
+ final int var4 = (var2 + sectionY) & 0xFF;
|
|
+ final int var5 = (var3 + sectionY) & 0xFF;
|
|
+ final int var6 = (var2 + sectionY + 1) & 0xFF;
|
|
+ final int var7 = (var3 + sectionY + 1) & 0xFF;
|
|
+ final int var8 = this.p[var4] & 0xFF;
|
|
+ final int var9 = this.p[var5] & 0xFF;
|
|
+ final int var10 = this.p[var6] & 0xFF;
|
|
+ final int var11 = this.p[var7] & 0xFF;
|
|
+
|
|
+ final int var12 = (var8 + sectionZ) & 0xFF;
|
|
+ final int var13 = (var9 + sectionZ) & 0xFF;
|
|
+ final int var14 = (var10 + sectionZ) & 0xFF;
|
|
+ final int var15 = (var11 + sectionZ) & 0xFF;
|
|
+ final int var16 = (var8 + sectionZ + 1) & 0xFF;
|
|
+ final int var17 = (var9 + sectionZ + 1) & 0xFF;
|
|
+ final int var18 = (var10 + sectionZ + 1) & 0xFF;
|
|
+ final int var19 = (var11 + sectionZ + 1) & 0xFF;
|
|
+ final int var20 = (this.p[var12] & 15) << 2;
|
|
+ final int var21 = (this.p[var13] & 15) << 2;
|
|
+ final int var22 = (this.p[var14] & 15) << 2;
|
|
+ final int var23 = (this.p[var15] & 15) << 2;
|
|
+ final int var24 = (this.p[var16] & 15) << 2;
|
|
+ final int var25 = (this.p[var17] & 15) << 2;
|
|
+ final int var26 = (this.p[var18] & 15) << 2;
|
|
+ final int var27 = (this.p[var19] & 15) << 2;
|
|
+ final double var60 = localX - 1.0;
|
|
+ final double var61 = localY - 1.0;
|
|
+ final double var62 = localZ - 1.0;
|
|
+ final double var87 = FLAT_SIMPLEX_GRAD[(var20) | 0] * localX + FLAT_SIMPLEX_GRAD[(var20) | 1] * localY + FLAT_SIMPLEX_GRAD[(var20) | 2] * localZ;
|
|
+ final double var88 = FLAT_SIMPLEX_GRAD[(var21) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var21) | 1] * localY + FLAT_SIMPLEX_GRAD[(var21) | 2] * localZ;
|
|
+ final double var89 = FLAT_SIMPLEX_GRAD[(var22) | 0] * localX + FLAT_SIMPLEX_GRAD[(var22) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var22) | 2] * localZ;
|
|
+ final double var90 = FLAT_SIMPLEX_GRAD[(var23) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var23) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var23) | 2] * localZ;
|
|
+ final double var91 = FLAT_SIMPLEX_GRAD[(var24) | 0] * localX + FLAT_SIMPLEX_GRAD[(var24) | 1] * localY + FLAT_SIMPLEX_GRAD[(var24) | 2] * var62;
|
|
+ final double var92 = FLAT_SIMPLEX_GRAD[(var25) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var25) | 1] * localY + FLAT_SIMPLEX_GRAD[(var25) | 2] * var62;
|
|
+ final double var93 = FLAT_SIMPLEX_GRAD[(var26) | 0] * localX + FLAT_SIMPLEX_GRAD[(var26) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var26) | 2] * var62;
|
|
+ final double var94 = FLAT_SIMPLEX_GRAD[(var27) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var27) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var27) | 2] * var62;
|
|
+
|
|
+ final double var95 = localX * 6.0 - 15.0;
|
|
+ final double var96 = fadeLocalX * 6.0 - 15.0;
|
|
+ final double var97 = localZ * 6.0 - 15.0;
|
|
+ final double var98 = localX * var95 + 10.0;
|
|
+ final double var99 = fadeLocalX * var96 + 10.0;
|
|
+ final double var100 = localZ * var97 + 10.0;
|
|
+ final double var101 = localX * localX * localX * var98;
|
|
+ final double var102 = fadeLocalX * fadeLocalX * fadeLocalX * var99;
|
|
+ final double var103 = localZ * localZ * localZ * var100;
|
|
+
|
|
+ final double var113 = var87 + var101 * (var88 - var87);
|
|
+ final double var114 = var93 + var101 * (var94 - var93);
|
|
+ final double var115 = var91 + var101 * (var92 - var91);
|
|
+ final double var116 = var89 + var101 * (var90 - var89);
|
|
+ final double var117 = var114 - var115;
|
|
+ final double var118 = var102 * (var116 - var113);
|
|
+ final double var119 = var102 * var117;
|
|
+ final double var120 = var113 + var118;
|
|
+ final double var121 = var115 + var119;
|
|
+ return var120 + (var103 * (var121 - var120));
|
|
}
|
|
+ // Mirai end
|
|
|
|
private double sampleWithDerivative(int sectionX, int sectionY, int sectionZ, double localX, double localY, double localZ, double[] ds) {
|
|
int i = this.p(sectionX);
|
|
diff --git a/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java b/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
|
|
index 03c752e4abfe9e1f27c79024af48b31f7e90e555..125ae55681212e902e6e1ed3f82990180d1a56c4 100644
|
|
--- a/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
|
|
+++ b/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
|
|
@@ -26,6 +26,10 @@ public class PerlinNoise {
|
|
private final double lowestFreqValueFactor;
|
|
private final double lowestFreqInputFactor;
|
|
private final double maxValue;
|
|
+ // Mirai start - c2me: opts math
|
|
+ private int octaveSamplersCount = 0;
|
|
+ private double[] amplitudesArray = null;
|
|
+ // Mirai end
|
|
|
|
/** @deprecated */
|
|
@Deprecated
|
|
@@ -131,6 +135,10 @@ public class PerlinNoise {
|
|
this.lowestFreqInputFactor = Math.pow(2.0D, (double)(-j));
|
|
this.lowestFreqValueFactor = Math.pow(2.0D, (double)(i - 1)) / (Math.pow(2.0D, (double)i) - 1.0D);
|
|
this.maxValue = this.edgeValue(2.0D);
|
|
+ // Mirai start - c2me: opts math
|
|
+ this.octaveSamplersCount = this.noiseLevels.length;
|
|
+ this.amplitudesArray = this.amplitudes.toDoubleArray();
|
|
+ // Mirai end
|
|
}
|
|
|
|
protected double maxValue() {
|
|
@@ -141,9 +149,33 @@ public class PerlinNoise {
|
|
random.consumeCount(262);
|
|
}
|
|
|
|
+ // Mirai start - c2me: opts math
|
|
+ /**
|
|
+ * @author ishland
|
|
+ * @reason optimize for common cases
|
|
+ */
|
|
public double getValue(double x, double y, double z) {
|
|
- return this.getValue(x, y, z, 0.0D, 0.0D, false);
|
|
+ double d = 0.0;
|
|
+ double e = this.lowestFreqInputFactor;
|
|
+ double f = this.lowestFreqValueFactor;
|
|
+
|
|
+ for(int i = 0; i < this.octaveSamplersCount; ++i) {
|
|
+ ImprovedNoise perlinNoiseSampler = this.noiseLevels[i];
|
|
+ if (perlinNoiseSampler != null) {
|
|
+ @SuppressWarnings("deprecation")
|
|
+ double g = perlinNoiseSampler.noise(
|
|
+ wrap(x * e), wrap(y * e), wrap(z * e), 0.0, 0.0
|
|
+ );
|
|
+ d += this.amplitudesArray[i] * g * f;
|
|
+ }
|
|
+
|
|
+ e *= 2.0;
|
|
+ f /= 2.0;
|
|
+ }
|
|
+
|
|
+ return d;
|
|
}
|
|
+ // Mirai end
|
|
|
|
/** @deprecated */
|
|
@Deprecated
|
|
@@ -191,9 +223,15 @@ public class PerlinNoise {
|
|
return this.noiseLevels[this.noiseLevels.length - 1 - octave];
|
|
}
|
|
|
|
+ // Mirai start - c2me: opts math
|
|
+ /**
|
|
+ * @author ishland
|
|
+ * @reason remove frequent type conversion
|
|
+ */
|
|
public static double wrap(double value) {
|
|
- return value - (double)Mth.lfloor(value / 3.3554432E7D + 0.5D) * 3.3554432E7D;
|
|
+ return value - Mth.lfloor(value / 3.3554432E7 + 0.5) * 3.3554432E7;
|
|
}
|
|
+ // Mirai end
|
|
|
|
protected int firstOctave() {
|
|
return this.firstOctave;
|