mirror of
https://github.com/BX-Team/DivineMC.git
synced 2025-12-19 14:59:25 +00:00
remove dfc
This commit is contained in:
@@ -5,7 +5,7 @@ Subject: [PATCH] Configurable MC-67
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index 356a1bfc610214912f58c4126cdd5694ffecfcb8..55bde2487078d0c7dcb3a367d070838770fc0f4e 100644
|
index 33f24b21e2170700f3d38e072c106e1a65bafc62..b7661fc012eea6c0199a471208a1e230f206d64b 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -4020,6 +4020,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -4020,6 +4020,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
@@ -5,7 +5,7 @@ Subject: [PATCH] Regionized Chunk Ticking
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||||
index 2678bf59d557f085c7265e2f3eb038647723d35e..f13ddc9a11ad0bc6396e31d7629f8ab9425cd4d7 100644
|
index b30d6968fba2ab4d9cde0ac9d4f1cfc629c65359..2aeb819cfea737284a8061debcf829417c19aa3c 100644
|
||||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||||
@@ -56,6 +56,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
@@ -56,6 +56,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||||
@@ -7,7 +7,7 @@ Original author - Taiyou06
|
|||||||
Original patch - https://github.com/Winds-Studio/Leaf/pull/235
|
Original patch - https://github.com/Winds-Studio/Leaf/pull/235
|
||||||
|
|
||||||
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
||||||
index 5b46036868b6c9d082e35591e58735e16adaae62..a7f5c08726cce94c6a6c2a69028ad016a1bef30a 100644
|
index 5b46036868b6c9d082e35591e58735e16adaae62..0cd7cfb4ef5303f8f756640ed0f7e49b51bf9627 100644
|
||||||
--- a/net/minecraft/network/Connection.java
|
--- a/net/minecraft/network/Connection.java
|
||||||
+++ b/net/minecraft/network/Connection.java
|
+++ b/net/minecraft/network/Connection.java
|
||||||
@@ -85,7 +85,11 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
@@ -85,7 +85,11 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||||
@@ -5,7 +5,7 @@ Subject: [PATCH] lithium: block_entity_ticking.sleeping
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index 7aef92967cb8a662e644225a4122a544f3cff937..87837ab5ac16786db0b0ddd420b9f7cb797e5bbb 100644
|
index 9ccc6dd7d0e64a9cd54ab6f7bc276d380ea26717..c1a2d6716021909b511b1cb62f79aa68663faf41 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -2439,7 +2439,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -2439,7 +2439,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
@@ -10,7 +10,7 @@ As part of: ModernFix (https://github.com/embeddedt/ModernFix)
|
|||||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java
|
diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||||
index 58fe9e7aebeadc36f5f8f6f1073100c21e521e9d..352caf649a8b2fefef3825bdf71b0ddd5f77b528 100644
|
index 230cb433c38f9b6ffb1adeaa8b6040490f13e826..a436ec61bafc90d3ba6da0d5534f3b56b498b29b 100644
|
||||||
--- a/net/minecraft/world/level/chunk/PalettedContainer.java
|
--- a/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||||
+++ b/net/minecraft/world/level/chunk/PalettedContainer.java
|
+++ b/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||||
@@ -275,6 +275,28 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
@@ -275,6 +275,28 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||||
@@ -181,7 +181,6 @@ public class DivineConfig {
|
|||||||
public static boolean enableSecureSeed = false;
|
public static boolean enableSecureSeed = false;
|
||||||
public static boolean smoothBedrockLayer = false;
|
public static boolean smoothBedrockLayer = false;
|
||||||
public static boolean slopesVisualFix = false;
|
public static boolean slopesVisualFix = false;
|
||||||
public static boolean enableDensityFunctionCompiler = false;
|
|
||||||
public static boolean enableStructureLayoutOptimizer = true;
|
public static boolean enableStructureLayoutOptimizer = true;
|
||||||
public static boolean deduplicateShuffledTemplatePoolElementList = false;
|
public static boolean deduplicateShuffledTemplatePoolElementList = false;
|
||||||
private static void chunkGeneration() {
|
private static void chunkGeneration() {
|
||||||
@@ -230,19 +229,6 @@ public class DivineConfig {
|
|||||||
slopesVisualFix = getBoolean("settings.chunk-generation.slopes-visual-fix", slopesVisualFix,
|
slopesVisualFix = getBoolean("settings.chunk-generation.slopes-visual-fix", slopesVisualFix,
|
||||||
"Fixes MC-258859, fixing slopes visual bug in biomes like Snowy Slopes, Frozen Peaks, Jagged Peaks, and including Terralith.");
|
"Fixes MC-258859, fixing slopes visual bug in biomes like Snowy Slopes, Frozen Peaks, Jagged Peaks, and including Terralith.");
|
||||||
|
|
||||||
enableDensityFunctionCompiler = getBoolean("settings.chunk-generation.experimental.enable-density-function-compiler", enableDensityFunctionCompiler,
|
|
||||||
"Whether to use density function compiler to accelerate world generation",
|
|
||||||
"",
|
|
||||||
"Density function: https://minecraft.wiki/w/Density_function",
|
|
||||||
"",
|
|
||||||
"This functionality compiles density functions from world generation",
|
|
||||||
"datapacks (including vanilla generation) to JVM bytecode to increase",
|
|
||||||
"performance by allowing JVM JIT to better optimize the code.",
|
|
||||||
"All functions provided by vanilla are implemented.",
|
|
||||||
"",
|
|
||||||
"Please test if this optimization actually benefits your server, as",
|
|
||||||
"it can sometimes slow down chunk performance than speed it up.");
|
|
||||||
|
|
||||||
enableStructureLayoutOptimizer = getBoolean("settings.chunk-generation.experimental.enable-structure-layout-optimizer", enableStructureLayoutOptimizer,
|
enableStructureLayoutOptimizer = getBoolean("settings.chunk-generation.experimental.enable-structure-layout-optimizer", enableStructureLayoutOptimizer,
|
||||||
"Enables a port of the mod StructureLayoutOptimizer, which optimizes general Jigsaw structure generation");
|
"Enables a port of the mod StructureLayoutOptimizer, which optimizes general Jigsaw structure generation");
|
||||||
deduplicateShuffledTemplatePoolElementList = getBoolean("settings.chunk-generation.experimental.deduplicate-shuffled-template-pool-element-list", deduplicateShuffledTemplatePoolElementList,
|
deduplicateShuffledTemplatePoolElementList = getBoolean("settings.chunk-generation.experimental.deduplicate-shuffled-template-pool-element-list", deduplicateShuffledTemplatePoolElementList,
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common;
|
|
||||||
|
|
||||||
import net.minecraft.world.level.levelgen.NoiseRouterData;
|
|
||||||
|
|
||||||
public interface IDensityFunctionsCaveScaler {
|
|
||||||
static double invokeScaleCaves(double value) {
|
|
||||||
return NoiseRouterData.QuantizedSpaghettiRarity.getSphaghettiRarity2D(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double invokeScaleTunnels(double value) {
|
|
||||||
return NoiseRouterData.QuantizedSpaghettiRarity.getSpaghettiRarity3D(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public interface AstNode {
|
|
||||||
double evalSingle(int var1, int var2, int var3, EvalType var4);
|
|
||||||
|
|
||||||
void evalMulti(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5);
|
|
||||||
|
|
||||||
AstNode[] getChildren();
|
|
||||||
|
|
||||||
AstNode transform(AstTransformer var1);
|
|
||||||
|
|
||||||
void doBytecodeGenSingle(BytecodeGen.Context var1, InstructionAdapter var2, BytecodeGen.Context.LocalVarConsumer var3);
|
|
||||||
|
|
||||||
void doBytecodeGenMulti(BytecodeGen.Context var1, InstructionAdapter var2, BytecodeGen.Context.LocalVarConsumer var3);
|
|
||||||
|
|
||||||
boolean relaxedEquals(AstNode var1);
|
|
||||||
|
|
||||||
int relaxedHashCode();
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast;
|
|
||||||
|
|
||||||
public interface AstTransformer {
|
|
||||||
AstNode transform(AstNode var1);
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.vif.EachApplierVanillaInterface;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import net.minecraft.world.level.levelgen.NoiseChunk;
|
|
||||||
|
|
||||||
public enum EvalType {
|
|
||||||
NORMAL,
|
|
||||||
INTERPOLATION;
|
|
||||||
|
|
||||||
private EvalType() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EvalType from(DensityFunction.FunctionContext pos) {
|
|
||||||
return pos instanceof NoiseChunk ? INTERPOLATION : NORMAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EvalType from(DensityFunction.ContextProvider applier) {
|
|
||||||
if (applier instanceof EachApplierVanillaInterface vif) {
|
|
||||||
return vif.getType();
|
|
||||||
} else {
|
|
||||||
return applier instanceof NoiseChunk ? INTERPOLATION : NORMAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.binary.AddNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.binary.MaxNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.binary.MaxShortNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.binary.MinNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.binary.MinShortNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.binary.MulNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.misc.CacheLikeNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.misc.ConstantNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.misc.DelegateNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.misc.RangeChoiceNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.misc.YClampedGradientNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.noise.DFTNoiseNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.noise.DFTShiftANode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.noise.DFTShiftBNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.noise.DFTShiftNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.noise.DFTWeirdScaledSamplerNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.noise.ShiftedNoiseNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.spline.SplineAstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.unary.AbsNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.unary.CubeNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.unary.NegMulNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.unary.SquareNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.unary.SqueezeNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ducks.IEqualityOverriding;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ducks.IFastCacheLike;
|
|
||||||
import org.bxteam.divinemc.dfc.common.vif.AstVanillaInterface;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunctions;
|
|
||||||
import net.minecraft.world.level.levelgen.NoiseChunk;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class McToAst {
|
|
||||||
public McToAst() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AstNode toAst(DensityFunction df) {
|
|
||||||
Objects.requireNonNull(df);
|
|
||||||
return switch (df) {
|
|
||||||
case AstVanillaInterface f -> f.getAstNode();
|
|
||||||
|
|
||||||
case NoiseChunk.BlendAlpha f -> new ConstantNode(1.0);
|
|
||||||
case NoiseChunk.BlendOffset f -> new ConstantNode(0.0);
|
|
||||||
case DensityFunctions.BlendAlpha f -> new ConstantNode(1.0);
|
|
||||||
case DensityFunctions.BlendOffset f -> new ConstantNode(0.0);
|
|
||||||
case DensityFunctions.TwoArgumentSimpleFunction f -> switch (f.type()) {
|
|
||||||
case ADD -> new AddNode(toAst(f.argument1()), toAst(f.argument2()));
|
|
||||||
case MUL -> new MulNode(toAst(f.argument1()), toAst(f.argument2()));
|
|
||||||
case MIN -> {
|
|
||||||
double rightMin = f.argument2().minValue();
|
|
||||||
if (f.argument1().minValue() < rightMin) {
|
|
||||||
yield new MinShortNode(toAst(f.argument1()), toAst(f.argument2()), rightMin);
|
|
||||||
} else {
|
|
||||||
yield new MinNode(toAst(f.argument1()), toAst(f.argument2()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case MAX -> {
|
|
||||||
double rightMax = f.argument2().maxValue();
|
|
||||||
if (f.argument1().maxValue() > rightMax) {
|
|
||||||
yield new MaxShortNode(toAst(f.argument1()), toAst(f.argument2()), rightMax);
|
|
||||||
} else {
|
|
||||||
yield new MaxNode(toAst(f.argument1()), toAst(f.argument2()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
case DensityFunctions.BlendDensity f -> toAst(f.input());
|
|
||||||
case DensityFunctions.Clamp f -> new MaxNode(new ConstantNode(f.minValue()), new MinNode(new ConstantNode(f.maxValue()), toAst(f.input())));
|
|
||||||
case DensityFunctions.Constant f -> new ConstantNode(f.value());
|
|
||||||
case DensityFunctions.HolderHolder f -> toAst(f.function().value());
|
|
||||||
case DensityFunctions.Mapped f -> switch (f.type()) {
|
|
||||||
case ABS -> new AbsNode(toAst(f.input()));
|
|
||||||
case SQUARE -> new SquareNode(toAst(f.input()));
|
|
||||||
case CUBE -> new CubeNode(toAst(f.input()));
|
|
||||||
case HALF_NEGATIVE -> new NegMulNode(toAst(f.input()), 0.5);
|
|
||||||
case QUARTER_NEGATIVE -> new NegMulNode(toAst(f.input()), 0.25);
|
|
||||||
case SQUEEZE -> new SqueezeNode(toAst(f.input()));
|
|
||||||
};
|
|
||||||
case DensityFunctions.RangeChoice f -> new RangeChoiceNode(toAst(f.input()), f.minInclusive(), f.maxExclusive(), toAst(f.whenInRange()), toAst(f.whenOutOfRange()));
|
|
||||||
case DensityFunctions.Marker f -> {
|
|
||||||
DensityFunctions.Marker wrapping = new DensityFunctions.Marker(f.type(), new AstVanillaInterface(toAst(f.wrapped()), null));
|
|
||||||
((IEqualityOverriding) (Object) wrapping).c2me$overrideEquality(wrapping);
|
|
||||||
yield new DelegateNode(wrapping);
|
|
||||||
}
|
|
||||||
case IFastCacheLike f -> new CacheLikeNode(f, toAst(f.c2me$getDelegate()));
|
|
||||||
case DensityFunctions.ShiftedNoise f -> new ShiftedNoiseNode(toAst(f.shiftX()), toAst(f.shiftY()), toAst(f.shiftZ()), f.xzScale(), f.yScale(), f.noise());
|
|
||||||
case DensityFunctions.Noise f -> new DFTNoiseNode(f.noise(), f.xzScale(), f.yScale());
|
|
||||||
case DensityFunctions.Shift f -> new DFTShiftNode(f.offsetNoise());
|
|
||||||
case DensityFunctions.ShiftA f -> new DFTShiftANode(f.offsetNoise());
|
|
||||||
case DensityFunctions.ShiftB f -> new DFTShiftBNode(f.offsetNoise());
|
|
||||||
case DensityFunctions.YClampedGradient f -> new YClampedGradientNode(f.fromY(), f.toY(), f.fromValue(), f.toValue());
|
|
||||||
case DensityFunctions.WeirdScaledSampler f -> new DFTWeirdScaledSamplerNode(toAst(f.input()), f.noise(), f.rarityValueMapper());
|
|
||||||
case DensityFunctions.Spline f -> new SplineAstNode(f.spline());
|
|
||||||
|
|
||||||
default -> {
|
|
||||||
// delegateStatistics.computeIfAbsent(df.getClass(), unused -> new LongAdder()).increment();;
|
|
||||||
yield new DelegateNode(df);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @NotNull DensityFunction wrapVanilla(DensityFunction densityFunction) {
|
|
||||||
return new AstVanillaInterface(toAst(densityFunction), densityFunction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.binary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
|
|
||||||
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
|
|
||||||
import java.util.Objects;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public abstract class AbstractBinaryNode implements AstNode {
|
|
||||||
protected final AstNode left;
|
|
||||||
protected final AstNode right;
|
|
||||||
|
|
||||||
public AbstractBinaryNode(AstNode left, AstNode right) {
|
|
||||||
this.left = (AstNode)Objects.requireNonNull(left);
|
|
||||||
this.right = (AstNode)Objects.requireNonNull(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[]{this.left, this.right};
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
AbstractBinaryNode that = (AbstractBinaryNode)o;
|
|
||||||
return Objects.equals(this.left, that.left) && Objects.equals(this.right, that.right);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + this.left.hashCode();
|
|
||||||
result = 31 * result + this.right.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
AbstractBinaryNode that = (AbstractBinaryNode)o;
|
|
||||||
return this.left.relaxedEquals(that.left) && this.right.relaxedEquals(that.right);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + this.left.relaxedHashCode();
|
|
||||||
result = 31 * result + this.right.relaxedHashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract AstNode newInstance(AstNode var1, AstNode var2);
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
AstNode left = this.left.transform(transformer);
|
|
||||||
AstNode right = this.right.transform(transformer);
|
|
||||||
return left == this.left && right == this.right ? transformer.transform(this) : transformer.transform(this.newInstance(left, right));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String leftMethod = context.newSingleMethod(this.left);
|
|
||||||
String rightMethod = context.newSingleMethod(this.right);
|
|
||||||
context.callDelegateSingle(m, leftMethod);
|
|
||||||
context.callDelegateSingle(m, rightMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String leftMethod = context.newMultiMethod(this.left);
|
|
||||||
String rightMethod = context.newMultiMethod(this.right);
|
|
||||||
int res1 = localVarConsumer.createLocalVariable("res1", Type.getDescriptor(double[].class));
|
|
||||||
m.load(6, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.arraylength();
|
|
||||||
m.iconst(0);
|
|
||||||
m.invokevirtual(Type.getInternalName(ArrayCache.class), "getDoubleArray", Type.getMethodDescriptor(Type.getType(double[].class), new Type[]{Type.INT_TYPE, Type.BOOLEAN_TYPE}), false);
|
|
||||||
m.store(res1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
context.callDelegateMulti(m, leftMethod);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(res1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(6, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(context.className, rightMethod, Context.MULTI_DESC, false);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
this.bytecodeGenMultiBody(m, idx, res1);
|
|
||||||
});
|
|
||||||
m.load(6, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(res1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(ArrayCache.class), "recycle", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class)}), false);
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void bytecodeGenMultiBody(InstructionAdapter var1, int var2, int var3);
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.binary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class AddNode extends AbstractBinaryNode {
|
|
||||||
public AddNode(AstNode left, AstNode right) {
|
|
||||||
super(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AstNode newInstance(AstNode left, AstNode right) {
|
|
||||||
return new AddNode(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return this.left.evalSingle(x, y, z, type) + this.right.evalSingle(x, y, z, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
double[] res1 = new double[res.length];
|
|
||||||
this.left.evalMulti(res, x, y, z, type);
|
|
||||||
this.right.evalMulti(res1, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res1.length; ++i) {
|
|
||||||
res[i] += res1[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenSingle(context, m, localVarConsumer);
|
|
||||||
m.add(Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.load(res1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.add(Type.DOUBLE_TYPE);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.binary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class MaxNode extends AbstractBinaryNode {
|
|
||||||
public MaxNode(AstNode left, AstNode right) {
|
|
||||||
super(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AstNode newInstance(AstNode left, AstNode right) {
|
|
||||||
return new MaxNode(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return Math.max(this.left.evalSingle(x, y, z, type), this.right.evalSingle(x, y, z, type));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
double[] res1 = new double[res.length];
|
|
||||||
this.left.evalMulti(res, x, y, z, type);
|
|
||||||
this.right.evalMulti(res1, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res1.length; ++i) {
|
|
||||||
res[i] = Math.max(res[i], res1[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenSingle(context, m, localVarConsumer);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.load(res1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.binary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class MaxShortNode extends AbstractBinaryNode {
|
|
||||||
private final double rightMax;
|
|
||||||
|
|
||||||
public MaxShortNode(AstNode left, AstNode right, double rightMax) {
|
|
||||||
super(left, right);
|
|
||||||
this.rightMax = rightMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AstNode newInstance(AstNode left, AstNode right) {
|
|
||||||
return new MaxShortNode(left, right, this.rightMax);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
double evaled = this.left.evalSingle(x, y, z, type);
|
|
||||||
return evaled >= this.rightMax ? evaled : Math.max(evaled, this.right.evalSingle(x, y, z, type));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this.left.evalMulti(res, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = res[i] >= this.rightMax ? res[i] : Math.max(res[i], this.right.evalSingle(x[i], y[i], z[i], type));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String leftMethod = context.newSingleMethod(this.left);
|
|
||||||
String rightMethod = context.newSingleMethod(this.right);
|
|
||||||
Label minLabel = new Label();
|
|
||||||
context.callDelegateSingle(m, leftMethod);
|
|
||||||
m.dup2();
|
|
||||||
m.dconst(this.rightMax);
|
|
||||||
m.cmpl(Type.DOUBLE_TYPE);
|
|
||||||
m.iflt(minLabel);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
m.visitLabel(minLabel);
|
|
||||||
context.callDelegateSingle(m, rightMethod);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String leftMethod = context.newMultiMethod(this.left);
|
|
||||||
String rightMethodSingle = context.newSingleMethod(this.right);
|
|
||||||
context.callDelegateMulti(m, leftMethod);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
Label minLabel = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.dconst(this.rightMax);
|
|
||||||
m.cmpl(Type.DOUBLE_TYPE);
|
|
||||||
m.iflt(minLabel);
|
|
||||||
m.goTo(end);
|
|
||||||
m.visitLabel(minLabel);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(context.className, rightMethodSingle, Context.SINGLE_DESC, false);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
m.visitLabel(end);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.binary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class MinNode extends AbstractBinaryNode {
|
|
||||||
public MinNode(AstNode left, AstNode right) {
|
|
||||||
super(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AstNode newInstance(AstNode left, AstNode right) {
|
|
||||||
return new MinNode(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return Math.min(this.left.evalSingle(x, y, z, type), this.right.evalSingle(x, y, z, type));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
double[] res1 = new double[res.length];
|
|
||||||
this.left.evalMulti(res, x, y, z, type);
|
|
||||||
this.right.evalMulti(res1, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res1.length; ++i) {
|
|
||||||
res[i] = Math.min(res[i], res1[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenSingle(context, m, localVarConsumer);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.load(res1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.binary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class MinShortNode extends AbstractBinaryNode {
|
|
||||||
private final double rightMin;
|
|
||||||
|
|
||||||
public MinShortNode(AstNode left, AstNode right, double rightMin) {
|
|
||||||
super(left, right);
|
|
||||||
this.rightMin = rightMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AstNode newInstance(AstNode left, AstNode right) {
|
|
||||||
return new MinShortNode(left, right, this.rightMin);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
double evaled = this.left.evalSingle(x, y, z, type);
|
|
||||||
return evaled <= this.rightMin ? evaled : Math.min(evaled, this.right.evalSingle(x, y, z, type));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this.left.evalMulti(res, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = res[i] <= this.rightMin ? res[i] : Math.min(res[i], this.right.evalSingle(x[i], y[i], z[i], type));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String leftMethod = context.newSingleMethod(this.left);
|
|
||||||
String rightMethod = context.newSingleMethod(this.right);
|
|
||||||
Label minLabel = new Label();
|
|
||||||
context.callDelegateSingle(m, leftMethod);
|
|
||||||
m.dup2();
|
|
||||||
m.dconst(this.rightMin);
|
|
||||||
m.cmpg(Type.DOUBLE_TYPE);
|
|
||||||
m.ifgt(minLabel);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
m.visitLabel(minLabel);
|
|
||||||
context.callDelegateSingle(m, rightMethod);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String leftMethod = context.newMultiMethod(this.left);
|
|
||||||
String rightMethodSingle = context.newSingleMethod(this.right);
|
|
||||||
context.callDelegateMulti(m, leftMethod);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
Label minLabel = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.dconst(this.rightMin);
|
|
||||||
m.cmpg(Type.DOUBLE_TYPE);
|
|
||||||
m.ifgt(minLabel);
|
|
||||||
m.goTo(end);
|
|
||||||
m.visitLabel(minLabel);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(context.className, rightMethodSingle, Context.SINGLE_DESC, false);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
m.visitLabel(end);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.binary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class MulNode extends AbstractBinaryNode {
|
|
||||||
public MulNode(AstNode left, AstNode right) {
|
|
||||||
super(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AstNode newInstance(AstNode left, AstNode right) {
|
|
||||||
return new MulNode(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
double evaled = this.left.evalSingle(x, y, z, type);
|
|
||||||
return evaled == 0.0 ? 0.0 : evaled * this.right.evalSingle(x, y, z, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this.left.evalMulti(res, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = res[i] == 0.0 ? 0.0 : res[i] * this.right.evalSingle(x[i], y[i], z[i], type);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String leftMethod = context.newSingleMethod(this.left);
|
|
||||||
String rightMethod = context.newSingleMethod(this.right);
|
|
||||||
Label notZero = new Label();
|
|
||||||
context.callDelegateSingle(m, leftMethod);
|
|
||||||
m.dup2();
|
|
||||||
m.dconst(0.0);
|
|
||||||
m.cmpl(Type.DOUBLE_TYPE);
|
|
||||||
m.ifne(notZero);
|
|
||||||
m.dconst(0.0);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
m.visitLabel(notZero);
|
|
||||||
context.callDelegateSingle(m, rightMethod);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String leftMethod = context.newMultiMethod(this.left);
|
|
||||||
String rightMethodSingle = context.newSingleMethod(this.right);
|
|
||||||
context.callDelegateMulti(m, leftMethod);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
Label minLabel = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.dconst(0.0);
|
|
||||||
m.cmpl(Type.DOUBLE_TYPE);
|
|
||||||
m.ifne(minLabel);
|
|
||||||
m.pop2();
|
|
||||||
m.dconst(0.0);
|
|
||||||
m.goTo(end);
|
|
||||||
m.visitLabel(minLabel);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(context.className, rightMethodSingle, Context.SINGLE_DESC, false);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.visitLabel(end);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.dfvisitor;
|
|
||||||
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunctions;
|
|
||||||
import net.minecraft.world.level.levelgen.NoiseChunk;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class StripBlending implements DensityFunction.Visitor {
|
|
||||||
public static final StripBlending INSTANCE = new StripBlending();
|
|
||||||
|
|
||||||
private StripBlending() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull DensityFunction apply(@NotNull DensityFunction densityFunction) {
|
|
||||||
return switch (densityFunction) {
|
|
||||||
case NoiseChunk.BlendAlpha _ -> DensityFunctions.constant(1.0);
|
|
||||||
case NoiseChunk.BlendOffset _ -> DensityFunctions.constant(0.0);
|
|
||||||
case DensityFunctions.BlendAlpha _ -> DensityFunctions.constant(1.0);
|
|
||||||
case DensityFunctions.BlendOffset _ -> DensityFunctions.constant(0.0);
|
|
||||||
default -> densityFunction;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,256 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.misc;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ducks.IFastCacheLike;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.IMultiMethod;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.ISingleMethod;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.SubCompiledDensityFunction;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunctions;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.objectweb.asm.Handle;
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class CacheLikeNode implements AstNode {
|
|
||||||
private final IFastCacheLike cacheLike;
|
|
||||||
private final AstNode delegate;
|
|
||||||
|
|
||||||
public CacheLikeNode(IFastCacheLike cacheLike, AstNode delegate) {
|
|
||||||
this.cacheLike = cacheLike;
|
|
||||||
this.delegate = (AstNode)Objects.requireNonNull(delegate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
if (this.cacheLike == null) {
|
|
||||||
return this.delegate.evalSingle(x, y, z, type);
|
|
||||||
} else {
|
|
||||||
double cached = this.cacheLike.c2me$getCached(x, y, z, type);
|
|
||||||
if (Double.doubleToRawLongBits(cached) != 9222769054270909007L) {
|
|
||||||
return cached;
|
|
||||||
} else {
|
|
||||||
double eval = this.delegate.evalSingle(x, y, z, type);
|
|
||||||
this.cacheLike.c2me$cache(x, y, z, type, eval);
|
|
||||||
return eval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
if (this.cacheLike == null) {
|
|
||||||
this.delegate.evalMulti(res, x, y, z, type);
|
|
||||||
} else {
|
|
||||||
boolean cached = this.cacheLike.c2me$getCached(res, x, y, z, type);
|
|
||||||
if (!cached) {
|
|
||||||
this.delegate.evalMulti(res, x, y, z, type);
|
|
||||||
this.cacheLike.c2me$cache(res, x, y, z, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[]{this.delegate};
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
AstNode delegate = this.delegate.transform(transformer);
|
|
||||||
return this.delegate == delegate ? transformer.transform(this) : transformer.transform(new CacheLikeNode(this.cacheLike, delegate));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(@NotNull Context context, @NotNull InstructionAdapter m, Context.@NotNull LocalVarConsumer localVarConsumer) {
|
|
||||||
String delegateMethod = context.newSingleMethod(this.delegate);
|
|
||||||
String cacheLikeField = context.newField(IFastCacheLike.class, this.cacheLike);
|
|
||||||
this.genPostprocessingMethod(context, cacheLikeField);
|
|
||||||
int eval = localVarConsumer.createLocalVariable("eval", Type.DOUBLE_TYPE.getDescriptor());
|
|
||||||
Label cacheExists = new Label();
|
|
||||||
Label cacheMiss = new Label();
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
|
|
||||||
m.ifnonnull(cacheExists);
|
|
||||||
context.callDelegateSingle(m, delegateMethod);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
m.visitLabel(cacheExists);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
|
|
||||||
m.load(1, Type.INT_TYPE);
|
|
||||||
m.load(2, Type.INT_TYPE);
|
|
||||||
m.load(3, Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokeinterface(Type.getInternalName(IFastCacheLike.class), "c2me$getCached", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.getType(EvalType.class)}));
|
|
||||||
m.dup2();
|
|
||||||
m.invokestatic(Type.getInternalName(Double.class), "doubleToRawLongBits", Type.getMethodDescriptor(Type.LONG_TYPE, new Type[]{Type.DOUBLE_TYPE}), false);
|
|
||||||
m.lconst(9222769054270909007L);
|
|
||||||
m.lcmp();
|
|
||||||
m.ifeq(cacheMiss);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
m.visitLabel(cacheMiss);
|
|
||||||
m.pop2();
|
|
||||||
context.callDelegateSingle(m, delegateMethod);
|
|
||||||
m.store(eval, Type.DOUBLE_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
|
|
||||||
m.load(1, Type.INT_TYPE);
|
|
||||||
m.load(2, Type.INT_TYPE);
|
|
||||||
m.load(3, Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(eval, Type.DOUBLE_TYPE);
|
|
||||||
m.invokeinterface(Type.getInternalName(IFastCacheLike.class), "c2me$cache", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.getType(EvalType.class), Type.DOUBLE_TYPE}));
|
|
||||||
m.load(eval, Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(@NotNull Context context, @NotNull InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String delegateMethod = context.newMultiMethod(this.delegate);
|
|
||||||
String cacheLikeField = context.newField(IFastCacheLike.class, this.cacheLike);
|
|
||||||
this.genPostprocessingMethod(context, cacheLikeField);
|
|
||||||
Label cacheExists = new Label();
|
|
||||||
Label cacheMiss = new Label();
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
|
|
||||||
m.ifnonnull(cacheExists);
|
|
||||||
context.callDelegateMulti(m, delegateMethod);
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
m.visitLabel(cacheExists);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokeinterface(Type.getInternalName(IFastCacheLike.class), "c2me$getCached", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[]{Type.getType(double[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(EvalType.class)}));
|
|
||||||
m.ifeq(cacheMiss);
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
m.visitLabel(cacheMiss);
|
|
||||||
context.callDelegateMulti(m, delegateMethod);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokeinterface(Type.getInternalName(IFastCacheLike.class), "c2me$cache", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(EvalType.class)}));
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void genPostprocessingMethod(@NotNull Context context, String cacheLikeField) {
|
|
||||||
String methodName = String.format("postProcessing_%s", cacheLikeField);
|
|
||||||
String delegateSingle = context.newSingleMethod(this.delegate);
|
|
||||||
String delegateMulti = context.newMultiMethod(this.delegate);
|
|
||||||
context.genPostprocessingMethod(methodName, (m) -> {
|
|
||||||
Label cacheExists = new Label();
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
|
|
||||||
m.dup();
|
|
||||||
m.ifnonnull(cacheExists);
|
|
||||||
m.pop();
|
|
||||||
m.pop();
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
m.visitLabel(cacheExists);
|
|
||||||
m.anew(Type.getType(SubCompiledDensityFunction.class));
|
|
||||||
m.dup();
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokedynamic("evalSingle", Type.getMethodDescriptor(Type.getType(ISingleMethod.class), new Type[]{Type.getType(context.classDesc)}), new Handle(6, "java/lang/invoke/LambdaMetafactory", "metafactory", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;", false), new Object[]{Type.getMethodType(Context.SINGLE_DESC), new Handle(5, context.className, delegateSingle, Context.SINGLE_DESC, false), Type.getMethodType(Context.SINGLE_DESC)});
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokedynamic("evalMulti", Type.getMethodDescriptor(Type.getType(IMultiMethod.class), new Type[]{Type.getType(context.classDesc)}), new Handle(6, "java/lang/invoke/LambdaMetafactory", "metafactory", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;", false), new Object[]{Type.getMethodType(Context.MULTI_DESC), new Handle(5, context.className, delegateMulti, Context.MULTI_DESC, false), Type.getMethodType(Context.MULTI_DESC)});
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
|
|
||||||
m.checkcast(Type.getType(DensityFunction.class));
|
|
||||||
m.invokespecial(Type.getInternalName(SubCompiledDensityFunction.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(ISingleMethod.class), Type.getType(IMultiMethod.class), Type.getType(DensityFunction.class)}), false);
|
|
||||||
m.checkcast(Type.getType(DensityFunction.class));
|
|
||||||
m.invokeinterface(Type.getInternalName(IFastCacheLike.class), "c2me$withDelegate", Type.getMethodDescriptor(Type.getType(DensityFunction.class), new Type[]{Type.getType(DensityFunction.class)}));
|
|
||||||
m.putfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public IFastCacheLike getCacheLike() {
|
|
||||||
return this.cacheLike;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode getDelegate() {
|
|
||||||
return this.delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
CacheLikeNode that = (CacheLikeNode)o;
|
|
||||||
return equals(this.cacheLike, that.cacheLike) && Objects.equals(this.delegate, that.delegate);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean equals(IFastCacheLike a, IFastCacheLike b) {
|
|
||||||
if (a instanceof DensityFunctions.Marker wrappingA) {
|
|
||||||
if (b instanceof DensityFunctions.Marker wrappingB) {
|
|
||||||
return wrappingA.type() == wrappingB.type();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.equals(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + hashCode(this.cacheLike);
|
|
||||||
result = 31 * result + this.delegate.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int hashCode(IFastCacheLike o) {
|
|
||||||
if (o instanceof DensityFunctions.Marker wrapping) {
|
|
||||||
return wrapping.type().hashCode();
|
|
||||||
} else {
|
|
||||||
return o.hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
CacheLikeNode that = (CacheLikeNode)o;
|
|
||||||
return relaxedEquals(this.cacheLike, that.cacheLike) && this.delegate.relaxedEquals(that.delegate);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean relaxedEquals(IFastCacheLike a, IFastCacheLike b) {
|
|
||||||
if (a instanceof DensityFunctions.Marker wrappingA) {
|
|
||||||
if (b instanceof DensityFunctions.Marker wrappingB) {
|
|
||||||
return wrappingA.type() == wrappingB.type();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.getClass() == b.getClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + relaxedHashCode(this.cacheLike);
|
|
||||||
result = 31 * result + this.delegate.relaxedHashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int relaxedHashCode(IFastCacheLike o) {
|
|
||||||
if (o instanceof DensityFunctions.Marker wrapping) {
|
|
||||||
return wrapping.type().hashCode();
|
|
||||||
} else {
|
|
||||||
return o.getClass().hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.misc;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class ConstantNode implements AstNode {
|
|
||||||
private final double value;
|
|
||||||
|
|
||||||
public ConstantNode(double value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
Arrays.fill(res, this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
return transformer.transform(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
m.dconst(this.value);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.dconst(this.value);
|
|
||||||
m.invokestatic(Type.getInternalName(Arrays.class), "fill", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class), Type.DOUBLE_TYPE}), false);
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
ConstantNode that = (ConstantNode)o;
|
|
||||||
return Double.compare(this.value, that.value) == 0;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
return Double.hashCode(this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
return this.equals(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
return this.hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.misc;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
|
|
||||||
import org.bxteam.divinemc.dfc.common.vif.EachApplierVanillaInterface;
|
|
||||||
import org.bxteam.divinemc.dfc.common.vif.NoisePosVanillaInterface;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class DelegateNode implements AstNode {
|
|
||||||
private final DensityFunction densityFunction;
|
|
||||||
|
|
||||||
public DelegateNode(DensityFunction densityFunction) {
|
|
||||||
this.densityFunction = Objects.requireNonNull(densityFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return this.densityFunction.compute(new NoisePosVanillaInterface(x, y, z, type));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
if (res.length == 1) {
|
|
||||||
res[0] = this.evalSingle(x[0], y[0], z[0], type);
|
|
||||||
} else {
|
|
||||||
this.densityFunction.fillArray(res, new EachApplierVanillaInterface(x, y, z, type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
return transformer.transform(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String newField = context.newField(DensityFunction.class, this.densityFunction);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, newField, Type.getDescriptor(DensityFunction.class));
|
|
||||||
m.anew(Type.getType(NoisePosVanillaInterface.class));
|
|
||||||
m.dup();
|
|
||||||
m.load(1, Type.INT_TYPE);
|
|
||||||
m.load(2, Type.INT_TYPE);
|
|
||||||
m.load(3, Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokespecial(Type.getInternalName(NoisePosVanillaInterface.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.getType(EvalType.class)), false);
|
|
||||||
m.invokeinterface(Type.getInternalName(DensityFunction.class), "compute", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.getType(DensityFunction.FunctionContext.class)));
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String newField = context.newField(DensityFunction.class, this.densityFunction);
|
|
||||||
Label moreThanTwoLabel = new Label();
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.arraylength();
|
|
||||||
m.iconst(1);
|
|
||||||
m.ificmpgt(moreThanTwoLabel);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.iconst(0);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, newField, Type.getDescriptor(DensityFunction.class));
|
|
||||||
m.anew(Type.getType(NoisePosVanillaInterface.class));
|
|
||||||
m.dup();
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.iconst(0);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.iconst(0);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.iconst(0);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokespecial(Type.getInternalName(NoisePosVanillaInterface.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.getType(EvalType.class)), false);
|
|
||||||
m.invokeinterface(Type.getInternalName(DensityFunction.class), "compute", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.getType(DensityFunction.FunctionContext.class)));
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
m.visitLabel(moreThanTwoLabel);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, newField, Type.getDescriptor(DensityFunction.class));
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.anew(Type.getType(EachApplierVanillaInterface.class));
|
|
||||||
m.dup();
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(6, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokespecial(Type.getInternalName(EachApplierVanillaInterface.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(int[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(EvalType.class), Type.getType(ArrayCache.class)), false);
|
|
||||||
m.invokeinterface(Type.getInternalName(DensityFunction.class), "fillArray", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(double[].class), Type.getType(DensityFunction.ContextProvider.class)));
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DensityFunction getDelegate() {
|
|
||||||
return this.densityFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
DelegateNode that = (DelegateNode)o;
|
|
||||||
return Objects.equals(this.densityFunction, that.densityFunction);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + Objects.hashCode(this.getClass());
|
|
||||||
result = 31 * result + Objects.hashCode(this.densityFunction);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
DelegateNode that = (DelegateNode)o;
|
|
||||||
return this.densityFunction.getClass() == that.densityFunction.getClass();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + Objects.hashCode(this.getClass());
|
|
||||||
result = 31 * result + Objects.hashCode(this.densityFunction.getClass());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.misc;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
|
|
||||||
import java.util.Objects;
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class RangeChoiceNode implements AstNode {
|
|
||||||
private final AstNode input;
|
|
||||||
private final double minInclusive;
|
|
||||||
private final double maxExclusive;
|
|
||||||
private final AstNode whenInRange;
|
|
||||||
private final AstNode whenOutOfRange;
|
|
||||||
|
|
||||||
public RangeChoiceNode(AstNode input, double minInclusive, double maxExclusive, AstNode whenInRange, AstNode whenOutOfRange) {
|
|
||||||
this.input = (AstNode)Objects.requireNonNull(input);
|
|
||||||
this.minInclusive = minInclusive;
|
|
||||||
this.maxExclusive = maxExclusive;
|
|
||||||
this.whenInRange = (AstNode)Objects.requireNonNull(whenInRange);
|
|
||||||
this.whenOutOfRange = (AstNode)Objects.requireNonNull(whenOutOfRange);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
double v = this.input.evalSingle(x, y, z, type);
|
|
||||||
return v >= this.minInclusive && v < this.maxExclusive ? this.whenInRange.evalSingle(x, y, z, type) : this.whenOutOfRange.evalSingle(x, y, z, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this.input.evalMulti(res, x, y, z, type);
|
|
||||||
int numInRange = 0;
|
|
||||||
|
|
||||||
int numOutOfRange;
|
|
||||||
for(numOutOfRange = 0; numOutOfRange < x.length; ++numOutOfRange) {
|
|
||||||
double v = res[numOutOfRange];
|
|
||||||
if (v >= this.minInclusive && v < this.maxExclusive) {
|
|
||||||
++numInRange;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
numOutOfRange = res.length - numInRange;
|
|
||||||
if (numInRange == 0) {
|
|
||||||
this.evalChildMulti(this.whenOutOfRange, res, x, y, z, type);
|
|
||||||
} else if (numInRange == res.length) {
|
|
||||||
this.evalChildMulti(this.whenInRange, res, x, y, z, type);
|
|
||||||
} else {
|
|
||||||
int idx1 = 0;
|
|
||||||
int[] i1 = new int[numInRange];
|
|
||||||
double[] res1 = new double[numInRange];
|
|
||||||
int[] x1 = new int[numInRange];
|
|
||||||
int[] y1 = new int[numInRange];
|
|
||||||
int[] z1 = new int[numInRange];
|
|
||||||
int idx2 = 0;
|
|
||||||
int[] i2 = new int[numOutOfRange];
|
|
||||||
double[] res2 = new double[numOutOfRange];
|
|
||||||
int[] x2 = new int[numOutOfRange];
|
|
||||||
int[] y2 = new int[numOutOfRange];
|
|
||||||
int[] z2 = new int[numOutOfRange];
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < res.length; ++i) {
|
|
||||||
double v = res[i];
|
|
||||||
int index;
|
|
||||||
if (v >= this.minInclusive && v < this.maxExclusive) {
|
|
||||||
index = idx1++;
|
|
||||||
i1[index] = i;
|
|
||||||
x1[index] = x[i];
|
|
||||||
y1[index] = y[i];
|
|
||||||
z1[index] = z[i];
|
|
||||||
} else {
|
|
||||||
index = idx2++;
|
|
||||||
i2[index] = i;
|
|
||||||
x2[index] = x[i];
|
|
||||||
y2[index] = y[i];
|
|
||||||
z2[index] = z[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.evalChildMulti(this.whenInRange, res1, x1, y1, z1, type);
|
|
||||||
this.evalChildMulti(this.whenOutOfRange, res2, x2, y2, z2, type);
|
|
||||||
|
|
||||||
for(i = 0; i < numInRange; ++i) {
|
|
||||||
res[i1[i]] = res1[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < numOutOfRange; ++i) {
|
|
||||||
res[i2[i]] = res2[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void evalMultiStatic(double[] res, int[] x, int[] y, int[] z, EvalType type, double minInclusive, double maxExclusive, BytecodeGen.EvalSingleInterface whenInRangeSingle, BytecodeGen.EvalSingleInterface whenOutOfRangeSingle, BytecodeGen.EvalMultiInterface inputMulti, BytecodeGen.EvalMultiInterface whenInRangeMulti, BytecodeGen.EvalMultiInterface whenOutOfRangeMulti) {
|
|
||||||
inputMulti.evalMulti(res, x, y, z, type);
|
|
||||||
int numInRange = 0;
|
|
||||||
|
|
||||||
int numOutOfRange;
|
|
||||||
for(numOutOfRange = 0; numOutOfRange < x.length; ++numOutOfRange) {
|
|
||||||
double v = res[numOutOfRange];
|
|
||||||
if (v >= minInclusive && v < maxExclusive) {
|
|
||||||
++numInRange;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
numOutOfRange = res.length - numInRange;
|
|
||||||
if (numInRange == 0) {
|
|
||||||
evalChildMulti(whenOutOfRangeSingle, whenOutOfRangeMulti, res, x, y, z, type);
|
|
||||||
} else if (numInRange == res.length) {
|
|
||||||
evalChildMulti(whenInRangeSingle, whenInRangeMulti, res, x, y, z, type);
|
|
||||||
} else {
|
|
||||||
int idx1 = 0;
|
|
||||||
int[] i1 = new int[numInRange];
|
|
||||||
double[] res1 = new double[numInRange];
|
|
||||||
int[] x1 = new int[numInRange];
|
|
||||||
int[] y1 = new int[numInRange];
|
|
||||||
int[] z1 = new int[numInRange];
|
|
||||||
int idx2 = 0;
|
|
||||||
int[] i2 = new int[numOutOfRange];
|
|
||||||
double[] res2 = new double[numOutOfRange];
|
|
||||||
int[] x2 = new int[numOutOfRange];
|
|
||||||
int[] y2 = new int[numOutOfRange];
|
|
||||||
int[] z2 = new int[numOutOfRange];
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < res.length; ++i) {
|
|
||||||
double v = res[i];
|
|
||||||
int index;
|
|
||||||
if (v >= minInclusive && v < maxExclusive) {
|
|
||||||
index = idx1++;
|
|
||||||
i1[index] = i;
|
|
||||||
x1[index] = x[i];
|
|
||||||
y1[index] = y[i];
|
|
||||||
z1[index] = z[i];
|
|
||||||
} else {
|
|
||||||
index = idx2++;
|
|
||||||
i2[index] = i;
|
|
||||||
x2[index] = x[i];
|
|
||||||
y2[index] = y[i];
|
|
||||||
z2[index] = z[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
evalChildMulti(whenInRangeSingle, whenInRangeMulti, res1, x1, y1, z1, type);
|
|
||||||
evalChildMulti(whenOutOfRangeSingle, whenOutOfRangeMulti, res2, x2, y2, z2, type);
|
|
||||||
|
|
||||||
for(i = 0; i < numInRange; ++i) {
|
|
||||||
res[i1[i]] = res1[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < numOutOfRange; ++i) {
|
|
||||||
res[i2[i]] = res2[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void evalChildMulti(BytecodeGen.EvalSingleInterface single, BytecodeGen.EvalMultiInterface multi, double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
if (res.length == 1) {
|
|
||||||
res[0] = single.evalSingle(x[0], y[0], z[0], type);
|
|
||||||
} else {
|
|
||||||
multi.evalMulti(res, x, y, z, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void evalChildMulti(AstNode child, double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
if (res.length == 1) {
|
|
||||||
res[0] = child.evalSingle(x[0], y[0], z[0], type);
|
|
||||||
} else {
|
|
||||||
child.evalMulti(res, x, y, z, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[]{this.input, this.whenInRange, this.whenOutOfRange};
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
AstNode input = this.input.transform(transformer);
|
|
||||||
AstNode whenInRange = this.whenInRange.transform(transformer);
|
|
||||||
AstNode whenOutOfRange = this.whenOutOfRange.transform(transformer);
|
|
||||||
return this.input == input && this.whenInRange == whenInRange && this.whenOutOfRange == whenOutOfRange ? transformer.transform(this) : transformer.transform(new RangeChoiceNode(input, this.minInclusive, this.maxExclusive, whenInRange, whenOutOfRange));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String inputMethod = context.newSingleMethod(this.input);
|
|
||||||
String whenInRangeMethod = context.newSingleMethod(this.whenInRange);
|
|
||||||
String whenOutOfRangeMethod = context.newSingleMethod(this.whenOutOfRange);
|
|
||||||
int inputValue = localVarConsumer.createLocalVariable("inputValue", Type.DOUBLE_TYPE.getDescriptor());
|
|
||||||
context.callDelegateSingle(m, inputMethod);
|
|
||||||
m.store(inputValue, Type.DOUBLE_TYPE);
|
|
||||||
Label whenOutOfRangeLabel = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.load(inputValue, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.minInclusive);
|
|
||||||
m.cmpl(Type.DOUBLE_TYPE);
|
|
||||||
m.iflt(whenOutOfRangeLabel);
|
|
||||||
m.load(inputValue, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.maxExclusive);
|
|
||||||
m.cmpg(Type.DOUBLE_TYPE);
|
|
||||||
m.ifge(whenOutOfRangeLabel);
|
|
||||||
if (whenInRangeMethod.equals(inputMethod)) {
|
|
||||||
m.load(inputValue, Type.DOUBLE_TYPE);
|
|
||||||
} else {
|
|
||||||
context.callDelegateSingle(m, whenInRangeMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
m.goTo(end);
|
|
||||||
m.visitLabel(whenOutOfRangeLabel);
|
|
||||||
if (whenOutOfRangeMethod.equals(inputMethod)) {
|
|
||||||
m.load(inputValue, Type.DOUBLE_TYPE);
|
|
||||||
} else {
|
|
||||||
context.callDelegateSingle(m, whenOutOfRangeMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
m.visitLabel(end);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String inputSingle = context.newSingleMethod(this.input);
|
|
||||||
String whenInRangeSingle = context.newSingleMethod(this.whenInRange);
|
|
||||||
String whenOutOfRangeSingle = context.newSingleMethod(this.whenOutOfRange);
|
|
||||||
String inputMulti = context.newMultiMethod(this.input);
|
|
||||||
context.callDelegateMulti(m, inputMulti);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
Label whenOutOfRangeLabel = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.minInclusive);
|
|
||||||
m.cmpl(Type.DOUBLE_TYPE);
|
|
||||||
m.iflt(whenOutOfRangeLabel);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.maxExclusive);
|
|
||||||
m.cmpg(Type.DOUBLE_TYPE);
|
|
||||||
m.ifge(whenOutOfRangeLabel);
|
|
||||||
if (whenInRangeSingle.equals(inputSingle)) {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
} else {
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(context.className, whenInRangeSingle, Context.SINGLE_DESC, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
m.goTo(end);
|
|
||||||
m.visitLabel(whenOutOfRangeLabel);
|
|
||||||
if (whenOutOfRangeSingle.equals(inputSingle)) {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
} else {
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(context.className, whenOutOfRangeSingle, Context.SINGLE_DESC, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
m.visitLabel(end);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
RangeChoiceNode that = (RangeChoiceNode)o;
|
|
||||||
return Double.compare(this.minInclusive, that.minInclusive) == 0 && Double.compare(this.maxExclusive, that.maxExclusive) == 0 && Objects.equals(this.input, that.input) && Objects.equals(this.whenInRange, that.whenInRange) && Objects.equals(this.whenOutOfRange, that.whenOutOfRange);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + this.input.hashCode();
|
|
||||||
result = 31 * result + Double.hashCode(this.minInclusive);
|
|
||||||
result = 31 * result + Double.hashCode(this.maxExclusive);
|
|
||||||
result = 31 * result + this.whenInRange.hashCode();
|
|
||||||
result = 31 * result + this.whenOutOfRange.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
RangeChoiceNode that = (RangeChoiceNode)o;
|
|
||||||
return Double.compare(this.minInclusive, that.minInclusive) == 0 && Double.compare(this.maxExclusive, that.maxExclusive) == 0 && this.input.relaxedEquals(that.input) && this.whenInRange.relaxedEquals(that.whenInRange) && this.whenOutOfRange.relaxedEquals(that.whenOutOfRange);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + this.input.relaxedHashCode();
|
|
||||||
result = 31 * result + Double.hashCode(this.minInclusive);
|
|
||||||
result = 31 * result + Double.hashCode(this.maxExclusive);
|
|
||||||
result = 31 * result + this.whenInRange.relaxedHashCode();
|
|
||||||
result = 31 * result + this.whenOutOfRange.relaxedHashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.misc;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import java.util.Objects;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class RootNode implements AstNode {
|
|
||||||
private final AstNode next;
|
|
||||||
|
|
||||||
public RootNode(AstNode next) {
|
|
||||||
this.next = (AstNode)Objects.requireNonNull(next);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return this.next.evalSingle(x, y, z, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this.next.evalMulti(res, x, y, z, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[]{this.next};
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
AstNode next = this.next.transform(transformer);
|
|
||||||
return next == this.next ? transformer.transform(this) : transformer.transform(new RootNode(next));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String nextMethod = context.newSingleMethod(this.next);
|
|
||||||
context.callDelegateSingle(m, nextMethod);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String nextMethod = context.newMultiMethod(this.next);
|
|
||||||
context.callDelegateMulti(m, nextMethod);
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
RootNode that = (RootNode)o;
|
|
||||||
return Objects.equals(this.next, that.next);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + this.next.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
RootNode that = (RootNode)o;
|
|
||||||
return this.next.relaxedEquals(that.next);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + this.next.relaxedHashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.misc;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import net.minecraft.util.Mth;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class YClampedGradientNode implements AstNode {
|
|
||||||
private final double fromY;
|
|
||||||
private final double toY;
|
|
||||||
private final double fromValue;
|
|
||||||
private final double toValue;
|
|
||||||
|
|
||||||
public YClampedGradientNode(double fromY, double toY, double fromValue, double toValue) {
|
|
||||||
this.fromY = fromY;
|
|
||||||
this.toY = toY;
|
|
||||||
this.fromValue = fromValue;
|
|
||||||
this.toValue = toValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return Mth.clampedMap((double)y, this.fromY, this.toY, this.fromValue, this.toValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = Mth.clampedMap((double)y[i], this.fromY, this.toY, this.fromValue, this.toValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
return transformer.transform(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
m.load(2, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.fromY);
|
|
||||||
m.dconst(this.toY);
|
|
||||||
m.dconst(this.fromValue);
|
|
||||||
m.dconst(this.toValue);
|
|
||||||
m.invokestatic(Type.getInternalName(Mth.class), "clampedMap", "(DDDDD)D", false);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.fromY);
|
|
||||||
m.dconst(this.toY);
|
|
||||||
m.dconst(this.fromValue);
|
|
||||||
m.dconst(this.toValue);
|
|
||||||
m.invokestatic(Type.getInternalName(Mth.class), "clampedMap", "(DDDDD)D", false);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
YClampedGradientNode that = (YClampedGradientNode)o;
|
|
||||||
return Double.compare(this.fromY, that.fromY) == 0 && Double.compare(this.toY, that.toY) == 0 && Double.compare(this.fromValue, that.fromValue) == 0 && Double.compare(this.toValue, that.toValue) == 0;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + Double.hashCode(this.fromY);
|
|
||||||
result = 31 * result + Double.hashCode(this.toY);
|
|
||||||
result = 31 * result + Double.hashCode(this.fromValue);
|
|
||||||
result = 31 * result + Double.hashCode(this.toValue);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
return this.equals(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
return this.hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.noise;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class DFTNoiseNode implements AstNode {
|
|
||||||
private final DensityFunction.NoiseHolder noise;
|
|
||||||
private final double xzScale;
|
|
||||||
private final double yScale;
|
|
||||||
|
|
||||||
public DFTNoiseNode(DensityFunction.NoiseHolder noise, double xzScale, double yScale) {
|
|
||||||
this.noise = (DensityFunction.NoiseHolder)Objects.requireNonNull(noise);
|
|
||||||
this.xzScale = xzScale;
|
|
||||||
this.yScale = yScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return this.noise.getValue((double)x * this.xzScale, (double)y * this.yScale, (double)z * this.xzScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = this.noise.getValue((double)x[i] * this.xzScale, (double)y[i] * this.yScale, (double)z[i] * this.xzScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
return transformer.transform(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(1, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.xzScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(2, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.yScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(3, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.xzScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.xzScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.yScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.xzScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
DFTNoiseNode that = (DFTNoiseNode)o;
|
|
||||||
return Double.compare(this.xzScale, that.xzScale) == 0 && Double.compare(this.yScale, that.yScale) == 0 && Objects.equals(this.noise, that.noise);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + this.noise.hashCode();
|
|
||||||
result = 31 * result + Double.hashCode(this.xzScale);
|
|
||||||
result = 31 * result + Double.hashCode(this.yScale);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
DFTNoiseNode that = (DFTNoiseNode)o;
|
|
||||||
return Double.compare(this.xzScale, that.xzScale) == 0 && Double.compare(this.yScale, that.yScale) == 0;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + Double.hashCode(this.xzScale);
|
|
||||||
result = 31 * result + Double.hashCode(this.yScale);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.noise;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class DFTShiftANode implements AstNode {
|
|
||||||
private final DensityFunction.NoiseHolder offsetNoise;
|
|
||||||
|
|
||||||
public DFTShiftANode(DensityFunction.NoiseHolder offsetNoise) {
|
|
||||||
this.offsetNoise = (DensityFunction.NoiseHolder)Objects.requireNonNull(offsetNoise);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return this.offsetNoise.getValue((double)x * 0.25, 0.0, (double)z * 0.25) * 4.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = this.offsetNoise.getValue((double)x[i] * 0.25, 0.0, (double)z[i] * 0.25) * 4.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
return transformer.transform(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(1, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.0);
|
|
||||||
m.load(3, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.dconst(4.0);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.0);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.dconst(4.0);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
DFTShiftANode that = (DFTShiftANode)o;
|
|
||||||
return Objects.equals(this.offsetNoise, that.offsetNoise);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
Object o = this.getClass();
|
|
||||||
result = 31 * result + o.hashCode();
|
|
||||||
result = 31 * result + this.offsetNoise.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return o != null && this.getClass() == o.getClass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
return this.getClass().hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.noise;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class DFTShiftBNode implements AstNode {
|
|
||||||
private final DensityFunction.NoiseHolder offsetNoise;
|
|
||||||
|
|
||||||
public DFTShiftBNode(DensityFunction.NoiseHolder offsetNoise) {
|
|
||||||
this.offsetNoise = (DensityFunction.NoiseHolder)Objects.requireNonNull(offsetNoise);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return this.offsetNoise.getValue((double)z * 0.25, (double)x * 0.25, 0.0) * 4.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = this.offsetNoise.getValue((double)z[i] * 0.25, (double)x[i] * 0.25, 0.0) * 4.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
return transformer.transform(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(3, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(1, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.0);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.dconst(4.0);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.0);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.dconst(4.0);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
DFTShiftBNode that = (DFTShiftBNode)o;
|
|
||||||
return Objects.equals(this.offsetNoise, that.offsetNoise);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
Object o = this.getClass();
|
|
||||||
result = 31 * result + o.hashCode();
|
|
||||||
result = 31 * result + this.offsetNoise.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return o != null && this.getClass() == o.getClass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
return this.getClass().hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.noise;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class DFTShiftNode implements AstNode {
|
|
||||||
private final DensityFunction.NoiseHolder offsetNoise;
|
|
||||||
|
|
||||||
public DFTShiftNode(DensityFunction.NoiseHolder offsetNoise) {
|
|
||||||
this.offsetNoise = (DensityFunction.NoiseHolder)Objects.requireNonNull(offsetNoise);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return this.offsetNoise.getValue((double)x * 0.25, (double)y * 0.25, (double)z * 0.25) * 4.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = this.offsetNoise.getValue((double)x[i] * 0.25, (double)y[i] * 0.25, (double)z[i] * 0.25) * 4.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
return transformer.transform(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(1, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(2, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(3, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.dconst(4.0);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.25);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.dconst(4.0);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
DFTShiftNode that = (DFTShiftNode)o;
|
|
||||||
return Objects.equals(this.offsetNoise, that.offsetNoise);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
Object o = this.getClass();
|
|
||||||
result = 31 * result + o.hashCode();
|
|
||||||
result = 31 * result + this.offsetNoise.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return o != null && this.getClass() == o.getClass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
return this.getClass().hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.noise;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.IDensityFunctionsCaveScaler;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunctions;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class DFTWeirdScaledSamplerNode implements AstNode {
|
|
||||||
private final AstNode input;
|
|
||||||
private final DensityFunction.NoiseHolder noise;
|
|
||||||
private final DensityFunctions.WeirdScaledSampler.RarityValueMapper mapper;
|
|
||||||
|
|
||||||
public DFTWeirdScaledSamplerNode(AstNode input, DensityFunction.NoiseHolder noise, DensityFunctions.WeirdScaledSampler.RarityValueMapper mapper) {
|
|
||||||
this.input = Objects.requireNonNull(input);
|
|
||||||
this.noise = Objects.requireNonNull(noise);
|
|
||||||
this.mapper = Objects.requireNonNull(mapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
double v = this.input.evalSingle(x, y, z, type);
|
|
||||||
double d = (this.mapper.mapper).get(v);
|
|
||||||
return d * Math.abs(this.noise.getValue((double)x / d, (double)y / d, (double)z / d));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this.input.evalMulti(res, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
double d = (this.mapper.mapper).get(res[i]);
|
|
||||||
res[i] = d * Math.abs(this.noise.getValue((double)x[i] / d, (double)y[i] / d, (double)z[i] / d));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[]{this.input};
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
AstNode input = this.input.transform(transformer);
|
|
||||||
return input == this.input ? transformer.transform(this) : transformer.transform(new DFTWeirdScaledSamplerNode(input, this.noise, this.mapper));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.@NotNull Context context, InstructionAdapter m, BytecodeGen.Context.@NotNull LocalVarConsumer localVarConsumer) {
|
|
||||||
String inputMethod = context.newSingleMethod(this.input);
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
|
|
||||||
int scale = localVarConsumer.createLocalVariable("scale", Type.DOUBLE_TYPE.getDescriptor());
|
|
||||||
context.callDelegateSingle(m, inputMethod);
|
|
||||||
switch (this.mapper) {
|
|
||||||
case TYPE1 -> m.invokestatic(Type.getInternalName(IDensityFunctionsCaveScaler.class), "invokeScaleTunnels", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE), true);
|
|
||||||
case TYPE2 -> m.invokestatic(Type.getInternalName(IDensityFunctionsCaveScaler.class), "invokeScaleCaves", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE), true);
|
|
||||||
default -> throw new UnsupportedOperationException(String.format("Unknown mapper %s", this.mapper));
|
|
||||||
}
|
|
||||||
|
|
||||||
m.store(scale, Type.DOUBLE_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(1, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.load(scale, Type.DOUBLE_TYPE);
|
|
||||||
m.div(Type.DOUBLE_TYPE);
|
|
||||||
m.load(2, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.load(scale, Type.DOUBLE_TYPE);
|
|
||||||
m.div(Type.DOUBLE_TYPE);
|
|
||||||
m.load(3, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.load(scale, Type.DOUBLE_TYPE);
|
|
||||||
m.div(Type.DOUBLE_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "abs", "(D)D", false);
|
|
||||||
m.load(scale, Type.DOUBLE_TYPE);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String inputMethod = context.newMultiMethod(this.input);
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
|
|
||||||
context.callDelegateMulti(m, inputMethod);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
int scale = localVarConsumer.createLocalVariable("scale", Type.DOUBLE_TYPE.getDescriptor());
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
switch (this.mapper) {
|
|
||||||
case TYPE1 -> m.invokestatic(Type.getInternalName(IDensityFunctionsCaveScaler.class), "invokeScaleTunnels", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE), true);
|
|
||||||
case TYPE2 -> m.invokestatic(Type.getInternalName(IDensityFunctionsCaveScaler.class), "invokeScaleCaves", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE), true);
|
|
||||||
default -> throw new UnsupportedOperationException(String.format("Unknown mapper %s", this.mapper));
|
|
||||||
}
|
|
||||||
|
|
||||||
m.store(scale, Type.DOUBLE_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.load(scale, Type.DOUBLE_TYPE);
|
|
||||||
m.div(Type.DOUBLE_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.load(scale, Type.DOUBLE_TYPE);
|
|
||||||
m.div(Type.DOUBLE_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.load(scale, Type.DOUBLE_TYPE);
|
|
||||||
m.div(Type.DOUBLE_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "abs", "(D)D", false);
|
|
||||||
m.load(scale, Type.DOUBLE_TYPE);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
DFTWeirdScaledSamplerNode that = (DFTWeirdScaledSamplerNode)o;
|
|
||||||
return Objects.equals(this.input, that.input) && Objects.equals(this.noise, that.noise) && this.mapper == that.mapper;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + this.input.hashCode();
|
|
||||||
result = 31 * result + this.noise.hashCode();
|
|
||||||
result = 31 * result + this.mapper.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
DFTWeirdScaledSamplerNode that = (DFTWeirdScaledSamplerNode)o;
|
|
||||||
return this.input.relaxedEquals(that.input) && this.mapper == that.mapper;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + this.input.relaxedHashCode();
|
|
||||||
result = 31 * result + this.mapper.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,215 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.noise;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
|
|
||||||
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class ShiftedNoiseNode implements AstNode {
|
|
||||||
private final AstNode shiftX;
|
|
||||||
private final AstNode shiftY;
|
|
||||||
private final AstNode shiftZ;
|
|
||||||
private final double xzScale;
|
|
||||||
private final double yScale;
|
|
||||||
private final DensityFunction.NoiseHolder noise;
|
|
||||||
|
|
||||||
public ShiftedNoiseNode(AstNode shiftX, AstNode shiftY, AstNode shiftZ, double xzScale, double yScale, DensityFunction.NoiseHolder noise) {
|
|
||||||
this.shiftX = (AstNode)Objects.requireNonNull(shiftX);
|
|
||||||
this.shiftY = (AstNode)Objects.requireNonNull(shiftY);
|
|
||||||
this.shiftZ = (AstNode)Objects.requireNonNull(shiftZ);
|
|
||||||
this.xzScale = xzScale;
|
|
||||||
this.yScale = yScale;
|
|
||||||
this.noise = (DensityFunction.NoiseHolder)Objects.requireNonNull(noise);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
double d = (double)x * this.xzScale + this.shiftX.evalSingle(x, y, z, type);
|
|
||||||
double e = (double)y * this.yScale + this.shiftY.evalSingle(x, y, z, type);
|
|
||||||
double f = (double)z * this.xzScale + this.shiftZ.evalSingle(x, y, z, type);
|
|
||||||
return this.noise.getValue(d, e, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
double[] res1 = new double[res.length];
|
|
||||||
double[] res2 = new double[res.length];
|
|
||||||
this.shiftX.evalMulti(res, x, y, z, type);
|
|
||||||
this.shiftY.evalMulti(res1, x, y, z, type);
|
|
||||||
this.shiftZ.evalMulti(res2, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = this.noise.getValue((double)x[i] * this.xzScale + res[i], (double)y[i] * this.yScale + res1[i], (double)z[i] * this.xzScale + res2[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[]{this.shiftX, this.shiftY, this.shiftZ};
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
AstNode shiftX = this.shiftX.transform(transformer);
|
|
||||||
AstNode shiftY = this.shiftY.transform(transformer);
|
|
||||||
AstNode shiftZ = this.shiftZ.transform(transformer);
|
|
||||||
return shiftX == this.shiftX && shiftY == this.shiftY && shiftZ == this.shiftZ ? transformer.transform(this) : transformer.transform(new ShiftedNoiseNode(shiftX, shiftY, shiftZ, this.xzScale, this.yScale, this.noise));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
|
|
||||||
String shiftXMethod = context.newSingleMethod(this.shiftX);
|
|
||||||
String shiftYMethod = context.newSingleMethod(this.shiftY);
|
|
||||||
String shiftZMethod = context.newSingleMethod(this.shiftZ);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(1, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.xzScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
context.callDelegateSingle(m, shiftXMethod);
|
|
||||||
m.add(Type.DOUBLE_TYPE);
|
|
||||||
m.load(2, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.yScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
context.callDelegateSingle(m, shiftYMethod);
|
|
||||||
m.add(Type.DOUBLE_TYPE);
|
|
||||||
m.load(3, Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.xzScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
context.callDelegateSingle(m, shiftZMethod);
|
|
||||||
m.add(Type.DOUBLE_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
|
|
||||||
String shiftXMethod = context.newMultiMethod(this.shiftX);
|
|
||||||
String shiftYMethod = context.newMultiMethod(this.shiftY);
|
|
||||||
String shiftZMethod = context.newMultiMethod(this.shiftZ);
|
|
||||||
int res1 = localVarConsumer.createLocalVariable("res1", Type.getDescriptor(double[].class));
|
|
||||||
int res2 = localVarConsumer.createLocalVariable("res2", Type.getDescriptor(double[].class));
|
|
||||||
m.load(6, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.arraylength();
|
|
||||||
m.iconst(0);
|
|
||||||
m.invokevirtual(Type.getInternalName(ArrayCache.class), "getDoubleArray", Type.getMethodDescriptor(Type.getType(double[].class), new Type[]{Type.INT_TYPE, Type.BOOLEAN_TYPE}), false);
|
|
||||||
m.store(res1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(6, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.arraylength();
|
|
||||||
m.iconst(0);
|
|
||||||
m.invokevirtual(Type.getInternalName(ArrayCache.class), "getDoubleArray", Type.getMethodDescriptor(Type.getType(double[].class), new Type[]{Type.INT_TYPE, Type.BOOLEAN_TYPE}), false);
|
|
||||||
m.store(res2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
context.callDelegateMulti(m, shiftXMethod);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(res1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(6, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(context.className, shiftYMethod, Context.MULTI_DESC, false);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(res2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(6, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(context.className, shiftZMethod, Context.MULTI_DESC, false);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.xzScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.add(Type.DOUBLE_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.yScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(res1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.add(Type.DOUBLE_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.xzScale);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.load(res2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.add(Type.DOUBLE_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.load(6, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(res1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(ArrayCache.class), "recycle", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class)}), false);
|
|
||||||
m.load(6, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(res2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(Type.getInternalName(ArrayCache.class), "recycle", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class)}), false);
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
ShiftedNoiseNode that = (ShiftedNoiseNode)o;
|
|
||||||
return Double.compare(this.xzScale, that.xzScale) == 0 && Double.compare(this.yScale, that.yScale) == 0 && Objects.equals(this.shiftX, that.shiftX) && Objects.equals(this.shiftY, that.shiftY) && Objects.equals(this.shiftZ, that.shiftZ) && Objects.equals(this.noise, that.noise);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.shiftX.hashCode();
|
|
||||||
result = 31 * result + this.shiftY.hashCode();
|
|
||||||
result = 31 * result + this.shiftZ.hashCode();
|
|
||||||
result = 31 * result + Double.hashCode(this.xzScale);
|
|
||||||
result = 31 * result + Double.hashCode(this.yScale);
|
|
||||||
result = 31 * result + this.noise.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
ShiftedNoiseNode that = (ShiftedNoiseNode)o;
|
|
||||||
return Double.compare(this.xzScale, that.xzScale) == 0 && Double.compare(this.yScale, that.yScale) == 0 && this.shiftX.relaxedEquals(that.shiftX) && this.shiftY.relaxedEquals(that.shiftY) && this.shiftZ.relaxedEquals(that.shiftZ);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.shiftX.relaxedHashCode();
|
|
||||||
result = 31 * result + this.shiftY.relaxedHashCode();
|
|
||||||
result = 31 * result + this.shiftZ.relaxedHashCode();
|
|
||||||
result = 31 * result + Double.hashCode(this.xzScale);
|
|
||||||
result = 31 * result + Double.hashCode(this.yScale);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,453 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.spline;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.McToAst;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import org.bxteam.divinemc.dfc.common.vif.NoisePosVanillaInterface;
|
|
||||||
import it.unimi.dsi.fastutil.Pair;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntObjectPair;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import net.minecraft.util.CubicSpline;
|
|
||||||
import net.minecraft.util.Mth;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunctions;
|
|
||||||
import org.bxteam.divinemc.util.Assertions;
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.AnalyzerAdapter;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class SplineAstNode implements AstNode {
|
|
||||||
public static final String SPLINE_METHOD_DESC;
|
|
||||||
private final CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline;
|
|
||||||
|
|
||||||
public SplineAstNode(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline) {
|
|
||||||
this.spline = spline;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return (double)this.spline.apply(new DensityFunctions.Spline.Point(new NoisePosVanillaInterface(x, y, z, type)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = this.evalSingle(x[i], y[i], z[i], type);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
return transformer.transform(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
ValuesMethodDef splineMethod = doBytecodeGenSpline(context, this.spline);
|
|
||||||
callSplineSingle(context, m, splineMethod);
|
|
||||||
m.cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ValuesMethodDef doBytecodeGenSpline(BytecodeGen.Context context, CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline) {
|
|
||||||
String name = context.getCachedSplineMethod(spline);
|
|
||||||
if (name != null) {
|
|
||||||
return new ValuesMethodDef(false, name, 0.0F);
|
|
||||||
} else if (spline instanceof CubicSpline.Constant) {
|
|
||||||
CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline1 = (CubicSpline.Constant)spline;
|
|
||||||
return new ValuesMethodDef(true, (String)null, spline1.value());
|
|
||||||
} else {
|
|
||||||
name = context.nextMethodName("Spline");
|
|
||||||
InstructionAdapter m = new InstructionAdapter(new AnalyzerAdapter(context.className, 18, name, SPLINE_METHOD_DESC, context.classWriter.visitMethod(18, name, SPLINE_METHOD_DESC, (String)null, (String[])null)));
|
|
||||||
List<IntObjectPair<Pair<String, String>>> extraLocals = new ArrayList();
|
|
||||||
Label start = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.visitLabel(start);
|
|
||||||
BytecodeGen.Context.LocalVarConsumer localVarConsumer = (localName, localDesc) -> {
|
|
||||||
int ordinal = extraLocals.size() + 5;
|
|
||||||
extraLocals.add(IntObjectPair.of(ordinal, Pair.of(localName, localDesc)));
|
|
||||||
return ordinal;
|
|
||||||
};
|
|
||||||
if (spline instanceof CubicSpline.Multipoint) {
|
|
||||||
CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> impl = (CubicSpline.Multipoint)spline;
|
|
||||||
ValuesMethodDef[] valuesMethods = (ValuesMethodDef[])impl.values().stream().map((spline1x) -> {
|
|
||||||
return doBytecodeGenSpline(context, spline1x);
|
|
||||||
}).toArray((x$0) -> {
|
|
||||||
return new ValuesMethodDef[x$0];
|
|
||||||
});
|
|
||||||
String locations = context.newField(float[].class, impl.locations());
|
|
||||||
String derivatives = context.newField(float[].class, impl.derivatives());
|
|
||||||
int point = localVarConsumer.createLocalVariable("point", Type.FLOAT_TYPE.getDescriptor());
|
|
||||||
int rangeForLocation = localVarConsumer.createLocalVariable("rangeForLocation", Type.INT_TYPE.getDescriptor());
|
|
||||||
int lastConst = impl.locations().length - 1;
|
|
||||||
String locationFunction = context.newSingleMethod(McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)impl.coordinate()).function().value()));
|
|
||||||
context.callDelegateSingle(m, locationFunction);
|
|
||||||
m.cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE);
|
|
||||||
m.store(point, Type.FLOAT_TYPE);
|
|
||||||
if (valuesMethods.length == 1) {
|
|
||||||
m.load(point, Type.FLOAT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
|
|
||||||
callSplineSingle(context, m, valuesMethods[0]);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, derivatives, Type.getDescriptor(float[].class));
|
|
||||||
m.iconst(0);
|
|
||||||
m.invokestatic(Type.getInternalName(SplineSupport.class), "sampleOutsideRange", Type.getMethodDescriptor(Type.FLOAT_TYPE, new Type[]{Type.FLOAT_TYPE, Type.getType(float[].class), Type.FLOAT_TYPE, Type.getType(float[].class), Type.INT_TYPE}), false);
|
|
||||||
m.areturn(Type.FLOAT_TYPE);
|
|
||||||
} else {
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
|
|
||||||
m.load(point, Type.FLOAT_TYPE);
|
|
||||||
m.invokestatic(Type.getInternalName(SplineSupport.class), "findRangeForLocation", Type.getMethodDescriptor(Type.INT_TYPE, new Type[]{Type.getType(float[].class), Type.FLOAT_TYPE}), false);
|
|
||||||
m.store(rangeForLocation, Type.INT_TYPE);
|
|
||||||
Label label1 = new Label();
|
|
||||||
Label label2 = new Label();
|
|
||||||
m.load(rangeForLocation, Type.INT_TYPE);
|
|
||||||
m.ifge(label1);
|
|
||||||
m.load(point, Type.FLOAT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
|
|
||||||
callSplineSingle(context, m, valuesMethods[0]);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, derivatives, Type.getDescriptor(float[].class));
|
|
||||||
m.iconst(0);
|
|
||||||
m.invokestatic(Type.getInternalName(SplineSupport.class), "sampleOutsideRange", Type.getMethodDescriptor(Type.FLOAT_TYPE, new Type[]{Type.FLOAT_TYPE, Type.getType(float[].class), Type.FLOAT_TYPE, Type.getType(float[].class), Type.INT_TYPE}), false);
|
|
||||||
m.areturn(Type.FLOAT_TYPE);
|
|
||||||
m.visitLabel(label1);
|
|
||||||
m.load(rangeForLocation, Type.INT_TYPE);
|
|
||||||
m.iconst(lastConst);
|
|
||||||
m.ificmpne(label2);
|
|
||||||
m.load(point, Type.FLOAT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
|
|
||||||
callSplineSingle(context, m, valuesMethods[lastConst]);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, derivatives, Type.getDescriptor(float[].class));
|
|
||||||
m.iconst(lastConst);
|
|
||||||
m.invokestatic(Type.getInternalName(SplineSupport.class), "sampleOutsideRange", Type.getMethodDescriptor(Type.FLOAT_TYPE, new Type[]{Type.FLOAT_TYPE, Type.getType(float[].class), Type.FLOAT_TYPE, Type.getType(float[].class), Type.INT_TYPE}), false);
|
|
||||||
m.areturn(Type.FLOAT_TYPE);
|
|
||||||
m.visitLabel(label2);
|
|
||||||
int loc0 = localVarConsumer.createLocalVariable("loc0", Type.FLOAT_TYPE.getDescriptor());
|
|
||||||
int loc1 = localVarConsumer.createLocalVariable("loc1", Type.FLOAT_TYPE.getDescriptor());
|
|
||||||
int locDist = localVarConsumer.createLocalVariable("locDist", Type.FLOAT_TYPE.getDescriptor());
|
|
||||||
int k = localVarConsumer.createLocalVariable("k", Type.FLOAT_TYPE.getDescriptor());
|
|
||||||
int n = localVarConsumer.createLocalVariable("n", Type.FLOAT_TYPE.getDescriptor());
|
|
||||||
int o = localVarConsumer.createLocalVariable("o", Type.FLOAT_TYPE.getDescriptor());
|
|
||||||
int onDist = localVarConsumer.createLocalVariable("onDist", Type.FLOAT_TYPE.getDescriptor());
|
|
||||||
int p = localVarConsumer.createLocalVariable("p", Type.FLOAT_TYPE.getDescriptor());
|
|
||||||
int q = localVarConsumer.createLocalVariable("q", Type.FLOAT_TYPE.getDescriptor());
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
|
|
||||||
m.load(rangeForLocation, Type.INT_TYPE);
|
|
||||||
m.aload(Type.FLOAT_TYPE);
|
|
||||||
m.store(loc0, Type.FLOAT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
|
|
||||||
m.load(rangeForLocation, Type.INT_TYPE);
|
|
||||||
m.iconst(1);
|
|
||||||
m.add(Type.INT_TYPE);
|
|
||||||
m.aload(Type.FLOAT_TYPE);
|
|
||||||
m.store(loc1, Type.FLOAT_TYPE);
|
|
||||||
m.load(loc1, Type.FLOAT_TYPE);
|
|
||||||
m.load(loc0, Type.FLOAT_TYPE);
|
|
||||||
m.sub(Type.FLOAT_TYPE);
|
|
||||||
m.store(locDist, Type.FLOAT_TYPE);
|
|
||||||
m.load(point, Type.FLOAT_TYPE);
|
|
||||||
m.load(loc0, Type.FLOAT_TYPE);
|
|
||||||
m.sub(Type.FLOAT_TYPE);
|
|
||||||
m.load(locDist, Type.FLOAT_TYPE);
|
|
||||||
m.div(Type.FLOAT_TYPE);
|
|
||||||
m.store(k, Type.FLOAT_TYPE);
|
|
||||||
Label[] jumpLabels = new Label[valuesMethods.length - 1];
|
|
||||||
boolean[] jumpGenerated = new boolean[valuesMethods.length - 1];
|
|
||||||
|
|
||||||
for(int i = 0; i < valuesMethods.length - 1; ++i) {
|
|
||||||
jumpLabels[i] = new Label();
|
|
||||||
}
|
|
||||||
|
|
||||||
Label defaultLabel = new Label();
|
|
||||||
Label label3 = new Label();
|
|
||||||
m.load(rangeForLocation, Type.INT_TYPE);
|
|
||||||
m.tableswitch(0, valuesMethods.length - 2, defaultLabel, jumpLabels);
|
|
||||||
|
|
||||||
for(int i = 0; i < valuesMethods.length - 1; ++i) {
|
|
||||||
if (!jumpGenerated[i]) {
|
|
||||||
m.visitLabel(jumpLabels[i]);
|
|
||||||
jumpGenerated[i] = true;
|
|
||||||
|
|
||||||
for(int j = i + 1; j < valuesMethods.length - 1; ++j) {
|
|
||||||
if (valuesMethods[i].equals(valuesMethods[j]) && valuesMethods[i + 1].equals(valuesMethods[j + 1])) {
|
|
||||||
m.visitLabel(jumpLabels[j]);
|
|
||||||
jumpGenerated[j] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
callSplineSingle(context, m, valuesMethods[i]);
|
|
||||||
if (valuesMethods[i].equals(valuesMethods[i + 1])) {
|
|
||||||
m.dup();
|
|
||||||
m.store(n, Type.FLOAT_TYPE);
|
|
||||||
m.store(o, Type.FLOAT_TYPE);
|
|
||||||
} else {
|
|
||||||
m.store(n, Type.FLOAT_TYPE);
|
|
||||||
callSplineSingle(context, m, valuesMethods[i + 1]);
|
|
||||||
m.store(o, Type.FLOAT_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
m.goTo(label3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m.visitLabel(defaultLabel);
|
|
||||||
m.iconst(0);
|
|
||||||
m.aconst("boom");
|
|
||||||
m.invokestatic(Type.getInternalName(Assertions.class), "assertTrue", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.BOOLEAN_TYPE, Type.getType(String.class)}), false);
|
|
||||||
m.fconst(Float.NaN);
|
|
||||||
m.areturn(Type.FLOAT_TYPE);
|
|
||||||
m.visitLabel(label3);
|
|
||||||
m.load(o, Type.FLOAT_TYPE);
|
|
||||||
m.load(n, Type.FLOAT_TYPE);
|
|
||||||
m.sub(Type.FLOAT_TYPE);
|
|
||||||
m.store(onDist, Type.FLOAT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, derivatives, Type.getDescriptor(float[].class));
|
|
||||||
m.load(rangeForLocation, Type.INT_TYPE);
|
|
||||||
m.aload(Type.FLOAT_TYPE);
|
|
||||||
m.load(locDist, Type.FLOAT_TYPE);
|
|
||||||
m.mul(Type.FLOAT_TYPE);
|
|
||||||
m.load(onDist, Type.FLOAT_TYPE);
|
|
||||||
m.sub(Type.FLOAT_TYPE);
|
|
||||||
m.store(p, Type.FLOAT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, derivatives, Type.getDescriptor(float[].class));
|
|
||||||
m.load(rangeForLocation, Type.INT_TYPE);
|
|
||||||
m.iconst(1);
|
|
||||||
m.add(Type.INT_TYPE);
|
|
||||||
m.aload(Type.FLOAT_TYPE);
|
|
||||||
m.neg(Type.FLOAT_TYPE);
|
|
||||||
m.load(locDist, Type.FLOAT_TYPE);
|
|
||||||
m.mul(Type.FLOAT_TYPE);
|
|
||||||
m.load(onDist, Type.FLOAT_TYPE);
|
|
||||||
m.add(Type.FLOAT_TYPE);
|
|
||||||
m.store(q, Type.FLOAT_TYPE);
|
|
||||||
m.load(k, Type.FLOAT_TYPE);
|
|
||||||
m.load(n, Type.FLOAT_TYPE);
|
|
||||||
m.load(o, Type.FLOAT_TYPE);
|
|
||||||
m.invokestatic(Type.getInternalName(Mth.class), "lerp", "(FFF)F", false);
|
|
||||||
m.load(k, Type.FLOAT_TYPE);
|
|
||||||
m.fconst(1.0F);
|
|
||||||
m.load(k, Type.FLOAT_TYPE);
|
|
||||||
m.sub(Type.FLOAT_TYPE);
|
|
||||||
m.mul(Type.FLOAT_TYPE);
|
|
||||||
m.load(k, Type.FLOAT_TYPE);
|
|
||||||
m.load(p, Type.FLOAT_TYPE);
|
|
||||||
m.load(q, Type.FLOAT_TYPE);
|
|
||||||
m.invokestatic(Type.getInternalName(Mth.class), "lerp", "(FFF)F", false);
|
|
||||||
m.mul(Type.FLOAT_TYPE);
|
|
||||||
m.add(Type.FLOAT_TYPE);
|
|
||||||
m.areturn(Type.FLOAT_TYPE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!(spline instanceof CubicSpline.Constant)) {
|
|
||||||
throw new UnsupportedOperationException(String.format("Unsupported spline implementation: %s", spline.getClass().getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> floatFunction = (CubicSpline.Constant)spline;
|
|
||||||
m.fconst(floatFunction.value());
|
|
||||||
m.areturn(Type.FLOAT_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
m.visitLabel(end);
|
|
||||||
m.visitLocalVariable("this", context.classDesc, (String)null, start, end, 0);
|
|
||||||
m.visitLocalVariable("x", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 1);
|
|
||||||
m.visitLocalVariable("y", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 2);
|
|
||||||
m.visitLocalVariable("z", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 3);
|
|
||||||
m.visitLocalVariable("evalType", Type.getType(EvalType.class).getDescriptor(), (String)null, start, end, 4);
|
|
||||||
Iterator var35 = extraLocals.iterator();
|
|
||||||
|
|
||||||
while(var35.hasNext()) {
|
|
||||||
IntObjectPair<Pair<String, String>> local = (IntObjectPair)var35.next();
|
|
||||||
m.visitLocalVariable((String)((Pair)local.right()).left(), (String)((Pair)local.right()).right(), (String)null, start, end, local.leftInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
m.visitMaxs(0, 0);
|
|
||||||
context.cacheSplineMethod(spline, name);
|
|
||||||
return new ValuesMethodDef(false, name, 0.0F);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void callSplineSingle(BytecodeGen.Context context, InstructionAdapter m, ValuesMethodDef target) {
|
|
||||||
if (target.isConst()) {
|
|
||||||
m.fconst(target.constValue());
|
|
||||||
} else {
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(1, Type.INT_TYPE);
|
|
||||||
m.load(2, Type.INT_TYPE);
|
|
||||||
m.load(3, Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(context.className, target.generatedMethod(), SPLINE_METHOD_DESC, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
context.delegateToSingle(m, localVarConsumer, this);
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean deepEquals(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a, CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b) {
|
|
||||||
if (a instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
|
|
||||||
if (b instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b1) {
|
|
||||||
return a1.value() == b1.value();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
|
|
||||||
if (b instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b1) {
|
|
||||||
boolean equals1 = Arrays.equals(a1.derivatives(), b1.derivatives()) && Arrays.equals(a1.locations(), b1.locations()) && a1.values().size() == b1.values().size() && McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)a1.coordinate()).function().value()).equals(McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)b1.coordinate()).function().value()));
|
|
||||||
if (!equals1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int size = a1.values().size();
|
|
||||||
|
|
||||||
for(int i = 0; i < size; ++i) {
|
|
||||||
if (!deepEquals((CubicSpline)a1.values().get(i), (CubicSpline)b1.values().get(i))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean deepRelaxedEquals(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a, CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b) {
|
|
||||||
if (a instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
|
|
||||||
if (b instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b1) {
|
|
||||||
return a1.value() == b1.value();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
|
|
||||||
if (b instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b1) {
|
|
||||||
boolean equals1 = a1.values().size() == b1.values().size() && McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)a1.coordinate()).function().value()).relaxedEquals(McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)b1.coordinate()).function().value()));
|
|
||||||
if (!equals1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int size = a1.values().size();
|
|
||||||
|
|
||||||
for(int i = 0; i < size; ++i) {
|
|
||||||
if (!deepRelaxedEquals((CubicSpline)a1.values().get(i), (CubicSpline)b1.values().get(i))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int deepHashcode(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a) {
|
|
||||||
if (a instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
|
|
||||||
return Float.hashCode(a1.value());
|
|
||||||
} else if (!(a instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1)) {
|
|
||||||
return a.hashCode();
|
|
||||||
} else {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + Arrays.hashCode(a1.derivatives());
|
|
||||||
result = 31 * result + Arrays.hashCode(a1.locations());
|
|
||||||
|
|
||||||
CubicSpline spline;
|
|
||||||
for(Iterator var4 = a1.values().iterator(); var4.hasNext(); result = 31 * result + deepHashcode(spline)) {
|
|
||||||
spline = (CubicSpline)var4.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
result = 31 * result + McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)a1.coordinate()).function().value()).hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int deepRelaxedHashcode(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a) {
|
|
||||||
if (a instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
|
|
||||||
return Float.hashCode(a1.value());
|
|
||||||
} else if (!(a instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1)) {
|
|
||||||
return a.hashCode();
|
|
||||||
} else {
|
|
||||||
int result = 1;
|
|
||||||
|
|
||||||
CubicSpline spline;
|
|
||||||
for(Iterator var4 = a1.values().iterator(); var4.hasNext(); result = 31 * result + deepRelaxedHashcode(spline)) {
|
|
||||||
spline = (CubicSpline)var4.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
result = 31 * result + McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)a1.coordinate()).function().value()).relaxedHashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
SplineAstNode that = (SplineAstNode)o;
|
|
||||||
return deepEquals(this.spline, that.spline);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
return deepHashcode(this.spline);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
SplineAstNode that = (SplineAstNode)o;
|
|
||||||
return deepRelaxedEquals(this.spline, that.spline);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
return deepRelaxedHashcode(this.spline);
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
SPLINE_METHOD_DESC = Type.getMethodDescriptor(Type.getType(Float.TYPE), new Type[]{Type.getType(Integer.TYPE), Type.getType(Integer.TYPE), Type.getType(Integer.TYPE), Type.getType(EvalType.class)});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static record ValuesMethodDef(boolean isConst, String generatedMethod, float constValue) {
|
|
||||||
private ValuesMethodDef(boolean isConst, String generatedMethod, float constValue) {
|
|
||||||
this.isConst = isConst;
|
|
||||||
this.generatedMethod = generatedMethod;
|
|
||||||
this.constValue = constValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isConst() {
|
|
||||||
return this.isConst;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String generatedMethod() {
|
|
||||||
return this.generatedMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float constValue() {
|
|
||||||
return this.constValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.spline;
|
|
||||||
|
|
||||||
public class SplineSupport {
|
|
||||||
public SplineSupport() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int findRangeForLocation(float[] locations, float x) {
|
|
||||||
int min = 0;
|
|
||||||
int i = locations.length;
|
|
||||||
|
|
||||||
while(i > 0) {
|
|
||||||
int j = i / 2;
|
|
||||||
int k = min + j;
|
|
||||||
if (x < locations[k]) {
|
|
||||||
i = j;
|
|
||||||
} else {
|
|
||||||
min = k + 1;
|
|
||||||
i -= j + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return min - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float sampleOutsideRange(float point, float[] locations, float value, float[] derivatives, int i) {
|
|
||||||
float f = derivatives[i];
|
|
||||||
return f == 0.0F ? value : value + f * (point - locations[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.unary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class AbsNode extends AbstractUnaryNode {
|
|
||||||
public AbsNode(AstNode operand) {
|
|
||||||
super(operand);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AstNode newInstance(AstNode operand) {
|
|
||||||
return new AbsNode(operand);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
return Math.abs(this.operand.evalSingle(x, y, z, type));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this.operand.evalMulti(res, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = Math.abs(res[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenSingle(context, m, localVarConsumer);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "abs", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE}), false);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenMulti(context, m, localVarConsumer);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "abs", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE}), false);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.unary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import java.util.Objects;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public abstract class AbstractUnaryNode implements AstNode {
|
|
||||||
protected final AstNode operand;
|
|
||||||
|
|
||||||
public AbstractUnaryNode(AstNode operand) {
|
|
||||||
this.operand = (AstNode)Objects.requireNonNull(operand);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode[] getChildren() {
|
|
||||||
return new AstNode[]{this.operand};
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
AbstractUnaryNode that = (AbstractUnaryNode)o;
|
|
||||||
return Objects.equals(this.operand, that.operand);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + this.operand.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean relaxedEquals(AstNode o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
} else if (o != null && this.getClass() == o.getClass()) {
|
|
||||||
AbstractUnaryNode that = (AbstractUnaryNode)o;
|
|
||||||
return this.operand.relaxedEquals(that.operand);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int relaxedHashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + this.getClass().hashCode();
|
|
||||||
result = 31 * result + this.operand.relaxedHashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract AstNode newInstance(AstNode var1);
|
|
||||||
|
|
||||||
public AstNode transform(AstTransformer transformer) {
|
|
||||||
AstNode operand = this.operand.transform(transformer);
|
|
||||||
return this.operand == operand ? transformer.transform(this) : transformer.transform(this.newInstance(operand));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String operandMethod = context.newSingleMethod(this.operand);
|
|
||||||
context.callDelegateSingle(m, operandMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
String operandMethod = context.newMultiMethod(this.operand);
|
|
||||||
context.callDelegateMulti(m, operandMethod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.unary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class CubeNode extends AbstractUnaryNode {
|
|
||||||
public CubeNode(AstNode operand) {
|
|
||||||
super(operand);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AstNode newInstance(AstNode operand) {
|
|
||||||
return new CubeNode(operand);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
double v = this.operand.evalSingle(x, y, z, type);
|
|
||||||
return v * v * v;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this.operand.evalMulti(res, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] = res[i] * res[i] * res[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenSingle(context, m, localVarConsumer);
|
|
||||||
m.dup2();
|
|
||||||
m.dup2();
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenMulti(context, m, localVarConsumer);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.dup2();
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.unary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class NegMulNode extends AbstractUnaryNode {
|
|
||||||
private final double negMul;
|
|
||||||
|
|
||||||
public NegMulNode(AstNode operand, double negMul) {
|
|
||||||
super(operand);
|
|
||||||
this.negMul = negMul;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AstNode newInstance(AstNode operand) {
|
|
||||||
return new NegMulNode(operand, this.negMul);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
double v = this.operand.evalSingle(x, y, z, type);
|
|
||||||
return v > 0.0 ? v : v * this.negMul;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this.operand.evalMulti(res, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
double v = res[i];
|
|
||||||
res[i] = v > 0.0 ? v : v * this.negMul;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenSingle(context, m, localVarConsumer);
|
|
||||||
int v = localVarConsumer.createLocalVariable("v", Type.DOUBLE_TYPE.getDescriptor());
|
|
||||||
m.store(v, Type.DOUBLE_TYPE);
|
|
||||||
Label negMulLabel = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.load(v, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.0);
|
|
||||||
m.cmpl(Type.DOUBLE_TYPE);
|
|
||||||
m.ifle(negMulLabel);
|
|
||||||
m.load(v, Type.DOUBLE_TYPE);
|
|
||||||
m.goTo(end);
|
|
||||||
m.visitLabel(negMulLabel);
|
|
||||||
m.load(v, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.negMul);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.visitLabel(end);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenMulti(context, m, localVarConsumer);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
int v = localVarConsumer.createLocalVariable("v", Type.DOUBLE_TYPE.getDescriptor());
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.store(v, Type.DOUBLE_TYPE);
|
|
||||||
Label negMulLabel = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.load(v, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(0.0);
|
|
||||||
m.cmpl(Type.DOUBLE_TYPE);
|
|
||||||
m.ifle(negMulLabel);
|
|
||||||
m.load(v, Type.DOUBLE_TYPE);
|
|
||||||
m.goTo(end);
|
|
||||||
m.visitLabel(negMulLabel);
|
|
||||||
m.load(v, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(this.negMul);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.visitLabel(end);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.unary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class SquareNode extends AbstractUnaryNode {
|
|
||||||
public SquareNode(AstNode operand) {
|
|
||||||
super(operand);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AstNode newInstance(AstNode operand) {
|
|
||||||
return new SquareNode(operand);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
double v = this.operand.evalSingle(x, y, z, type);
|
|
||||||
return v * v;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this.operand.evalMulti(res, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
res[i] *= res[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenSingle(context, m, localVarConsumer);
|
|
||||||
m.dup2();
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenMulti(context, m, localVarConsumer);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ast.unary;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
|
|
||||||
import net.minecraft.util.Mth;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class SqueezeNode extends AbstractUnaryNode {
|
|
||||||
public SqueezeNode(AstNode operand) {
|
|
||||||
super(operand);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AstNode newInstance(AstNode operand) {
|
|
||||||
return new SqueezeNode(operand);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double evalSingle(int x, int y, int z, EvalType type) {
|
|
||||||
double v = Mth.clamp(this.operand.evalSingle(x, y, z, type), -1.0, 1.0);
|
|
||||||
return v / 2.0 - v * v * v / 24.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this.operand.evalMulti(res, x, y, z, type);
|
|
||||||
|
|
||||||
for(int i = 0; i < res.length; ++i) {
|
|
||||||
double v = Mth.clamp(res[i], -1.0, 1.0);
|
|
||||||
res[i] = v / 2.0 - v * v * v / 24.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenSingle(context, m, localVarConsumer);
|
|
||||||
m.dconst(1.0);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
m.dconst(-1.0);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
int v = localVarConsumer.createLocalVariable("v", Type.DOUBLE_TYPE.getDescriptor());
|
|
||||||
m.store(v, Type.DOUBLE_TYPE);
|
|
||||||
m.load(v, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(2.0);
|
|
||||||
m.div(Type.DOUBLE_TYPE);
|
|
||||||
m.load(v, Type.DOUBLE_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.dup2();
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(24.0);
|
|
||||||
m.div(Type.DOUBLE_TYPE);
|
|
||||||
m.sub(Type.DOUBLE_TYPE);
|
|
||||||
m.areturn(Type.DOUBLE_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
|
|
||||||
super.doBytecodeGenMulti(context, m, localVarConsumer);
|
|
||||||
context.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
int v = localVarConsumer.createLocalVariable("v", Type.DOUBLE_TYPE.getDescriptor());
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.aload(Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(1.0);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
m.dconst(-1.0);
|
|
||||||
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
|
|
||||||
m.store(v, Type.DOUBLE_TYPE);
|
|
||||||
m.load(v, Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(2.0);
|
|
||||||
m.div(Type.DOUBLE_TYPE);
|
|
||||||
m.load(v, Type.DOUBLE_TYPE);
|
|
||||||
m.dup2();
|
|
||||||
m.dup2();
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.mul(Type.DOUBLE_TYPE);
|
|
||||||
m.dconst(24.0);
|
|
||||||
m.div(Type.DOUBLE_TYPE);
|
|
||||||
m.sub(Type.DOUBLE_TYPE);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ducks;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
|
|
||||||
|
|
||||||
public interface IArrayCacheCapable {
|
|
||||||
ArrayCache c2me$getArrayCache();
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ducks;
|
|
||||||
|
|
||||||
public interface IBlendingAwareVisitor {
|
|
||||||
boolean c2me$isBlendingEnabled();
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ducks;
|
|
||||||
|
|
||||||
public interface ICoordinatesFilling {
|
|
||||||
void c2me$fillCoordinates(int[] var1, int[] var2, int[] var3);
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ducks;
|
|
||||||
|
|
||||||
public interface IEqualityOverriding {
|
|
||||||
void c2me$overrideEquality(Object var1);
|
|
||||||
|
|
||||||
Object c2me$getOverriddenEquality();
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.ducks;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
|
|
||||||
public interface IFastCacheLike extends DensityFunction {
|
|
||||||
long CACHE_MISS_NAN_BITS = 9222769054270909007L;
|
|
||||||
|
|
||||||
double c2me$getCached(int var1, int var2, int var3, EvalType var4);
|
|
||||||
|
|
||||||
boolean c2me$getCached(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5);
|
|
||||||
|
|
||||||
void c2me$cache(int var1, int var2, int var3, EvalType var4, double var5);
|
|
||||||
|
|
||||||
void c2me$cache(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5);
|
|
||||||
|
|
||||||
DensityFunction c2me$getDelegate();
|
|
||||||
|
|
||||||
DensityFunction c2me$withDelegate(DensityFunction var1);
|
|
||||||
}
|
|
||||||
@@ -1,499 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.gen;
|
|
||||||
|
|
||||||
import com.google.common.io.Files;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.McToAst;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.dfvisitor.StripBlending;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.misc.ConstantNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.misc.RootNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
|
|
||||||
import org.bxteam.divinemc.dfc.common.vif.AstVanillaInterface;
|
|
||||||
import it.unimi.dsi.fastutil.Hash;
|
|
||||||
import it.unimi.dsi.fastutil.Pair;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntObjectPair;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ReferenceMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ReferenceMaps;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenCustomHashMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ListIterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.IntConsumer;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import net.minecraft.util.CubicSpline;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunctions;
|
|
||||||
import org.objectweb.asm.ClassWriter;
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.AnalyzerAdapter;
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
|
||||||
|
|
||||||
public class BytecodeGen {
|
|
||||||
private static final File exportDir = new File("./cache/c2me-dfc");
|
|
||||||
private static final AtomicLong ordinal = new AtomicLong();
|
|
||||||
public static final Hash.Strategy<AstNode> RELAXED_STRATEGY;
|
|
||||||
private static final Object2ReferenceMap<AstNode, Class<?>> compilationCache;
|
|
||||||
|
|
||||||
public BytecodeGen() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DensityFunction compile(DensityFunction densityFunction, Reference2ReferenceMap<DensityFunction, DensityFunction> tempCache) {
|
|
||||||
DensityFunction cached = (DensityFunction)tempCache.get(densityFunction);
|
|
||||||
if (cached != null) {
|
|
||||||
return cached;
|
|
||||||
} else if (densityFunction instanceof AstVanillaInterface) {
|
|
||||||
AstVanillaInterface vif = (AstVanillaInterface)densityFunction;
|
|
||||||
AstNode ast = vif.getAstNode();
|
|
||||||
return new CompiledDensityFunction(compile0(ast), vif.getBlendingFallback());
|
|
||||||
} else {
|
|
||||||
AstNode ast = McToAst.toAst(densityFunction.mapAll(StripBlending.INSTANCE));
|
|
||||||
if (ast instanceof ConstantNode) {
|
|
||||||
ConstantNode constantNode = (ConstantNode)ast;
|
|
||||||
return DensityFunctions.constant(constantNode.getValue());
|
|
||||||
} else {
|
|
||||||
CompiledDensityFunction compiled = new CompiledDensityFunction(compile0(ast), densityFunction);
|
|
||||||
tempCache.put(densityFunction, compiled);
|
|
||||||
return compiled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized CompiledEntry compile0(AstNode node) {
|
|
||||||
Class<?> cached = (Class)compilationCache.get(node);
|
|
||||||
ClassWriter writer = new ClassWriter(3);
|
|
||||||
String name = cached != null ? String.format("DfcCompiled_discarded") : String.format("DfcCompiled_%d", ordinal.getAndIncrement());
|
|
||||||
writer.visit(65, 17, name, (String)null, Type.getInternalName(Object.class), new String[]{Type.getInternalName(CompiledEntry.class)});
|
|
||||||
RootNode rootNode = new RootNode(node);
|
|
||||||
Context genContext = new Context(writer, name);
|
|
||||||
genContext.newSingleMethod0((adapter, localVarConsumer) -> {
|
|
||||||
rootNode.doBytecodeGenSingle(genContext, adapter, localVarConsumer);
|
|
||||||
}, "evalSingle", true);
|
|
||||||
genContext.newMultiMethod0((adapter, localVarConsumer) -> {
|
|
||||||
rootNode.doBytecodeGenMulti(genContext, adapter, localVarConsumer);
|
|
||||||
}, "evalMulti", true);
|
|
||||||
List<Object> args = (List)genContext.args.entrySet().stream().sorted(Comparator.comparingInt((o) -> {
|
|
||||||
return ((Context.FieldRecord)o.getValue()).ordinal();
|
|
||||||
})).map(Map.Entry::getKey).collect(Collectors.toCollection(ArrayList::new));
|
|
||||||
if (cached != null) {
|
|
||||||
try {
|
|
||||||
return (CompiledEntry)cached.getConstructor(List.class).newInstance(args);
|
|
||||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | InstantiationException var11) {
|
|
||||||
ReflectiveOperationException e = var11;
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
genConstructor(genContext);
|
|
||||||
genGetArgs(genContext);
|
|
||||||
genNewInstance(genContext);
|
|
||||||
|
|
||||||
Object var8;
|
|
||||||
for(ListIterator<Object> iterator = args.listIterator(); iterator.hasNext(); var8 = iterator.next()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] bytes = writer.toByteArray();
|
|
||||||
dumpClass(genContext.className, bytes);
|
|
||||||
Class<?> defined = defineClass(genContext.className, bytes);
|
|
||||||
compilationCache.put(node, defined);
|
|
||||||
|
|
||||||
try {
|
|
||||||
return (CompiledEntry)defined.getConstructor(List.class).newInstance(args);
|
|
||||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | InstantiationException var12) {
|
|
||||||
ReflectiveOperationException e = var12;
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void genConstructor(Context context) {
|
|
||||||
InstructionAdapter m = new InstructionAdapter(new AnalyzerAdapter(context.className, 1, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(List.class)}), context.classWriter.visitMethod(1, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(List.class)}), (String)null, (String[])null)));
|
|
||||||
Label start = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.visitLabel(start);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokespecial(Type.getInternalName(Object.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[0]), false);
|
|
||||||
Iterator var4 = context.args.entrySet().stream().sorted(Comparator.comparingInt((o) -> {
|
|
||||||
return ((Context.FieldRecord)o.getValue()).ordinal();
|
|
||||||
})).toList().iterator();
|
|
||||||
|
|
||||||
while(var4.hasNext()) {
|
|
||||||
Map.Entry<Object, Context.FieldRecord> entry = (Map.Entry)var4.next();
|
|
||||||
String name = ((Context.FieldRecord)entry.getValue()).name();
|
|
||||||
Class<?> type = ((Context.FieldRecord)entry.getValue()).type();
|
|
||||||
int ordinal = ((Context.FieldRecord)entry.getValue()).ordinal();
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.iconst(ordinal);
|
|
||||||
m.invokeinterface(Type.getInternalName(List.class), "get", Type.getMethodDescriptor(InstructionAdapter.OBJECT_TYPE, new Type[]{Type.INT_TYPE}));
|
|
||||||
m.checkcast(Type.getType(type));
|
|
||||||
m.putfield(context.className, name, Type.getDescriptor(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
var4 = context.postProcessMethods.stream().sorted().toList().iterator();
|
|
||||||
|
|
||||||
while(var4.hasNext()) {
|
|
||||||
String postProcessingMethod = (String)var4.next();
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(context.className, postProcessingMethod, "()V", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
m.areturn(Type.VOID_TYPE);
|
|
||||||
m.visitLabel(end);
|
|
||||||
m.visitLocalVariable("this", context.classDesc, (String)null, start, end, 0);
|
|
||||||
m.visitLocalVariable("list", Type.getDescriptor(List.class), (String)null, start, end, 1);
|
|
||||||
m.visitMaxs(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void genGetArgs(Context context) {
|
|
||||||
InstructionAdapter m = new InstructionAdapter(new AnalyzerAdapter(context.className, 17, "getArgs", Type.getMethodDescriptor(Type.getType(List.class), new Type[0]), context.classWriter.visitMethod(17, "getArgs", Type.getMethodDescriptor(Type.getType(List.class), new Type[0]), (String)null, (String[])null)));
|
|
||||||
Label start = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.visitLabel(start);
|
|
||||||
m.anew(Type.getType(ArrayList.class));
|
|
||||||
m.dup();
|
|
||||||
m.iconst(context.args.size());
|
|
||||||
m.invokespecial(Type.getInternalName(ArrayList.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.INT_TYPE}), false);
|
|
||||||
m.store(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
Iterator var4 = context.args.entrySet().stream().sorted(Comparator.comparingInt((o) -> {
|
|
||||||
return ((Context.FieldRecord)o.getValue()).ordinal();
|
|
||||||
})).toList().iterator();
|
|
||||||
|
|
||||||
while(var4.hasNext()) {
|
|
||||||
Map.Entry<Object, Context.FieldRecord> entry = (Map.Entry)var4.next();
|
|
||||||
String name = ((Context.FieldRecord)entry.getValue()).name();
|
|
||||||
Class<?> type = ((Context.FieldRecord)entry.getValue()).type();
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.getfield(context.className, name, Type.getDescriptor(type));
|
|
||||||
m.invokeinterface(Type.getInternalName(List.class), "add", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[]{InstructionAdapter.OBJECT_TYPE}));
|
|
||||||
m.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.areturn(InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.visitLabel(end);
|
|
||||||
m.visitLocalVariable("this", context.classDesc, (String)null, start, end, 0);
|
|
||||||
m.visitLocalVariable("list", Type.getDescriptor(List.class), (String)null, start, end, 1);
|
|
||||||
m.visitMaxs(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void genNewInstance(Context context) {
|
|
||||||
InstructionAdapter m = new InstructionAdapter(new AnalyzerAdapter(context.className, 17, "newInstance", Type.getMethodDescriptor(Type.getType(CompiledEntry.class), new Type[]{Type.getType(List.class)}), context.classWriter.visitMethod(17, "newInstance", Type.getMethodDescriptor(Type.getType(CompiledEntry.class), new Type[]{Type.getType(List.class)}), (String)null, (String[])null)));
|
|
||||||
Label start = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.visitLabel(start);
|
|
||||||
m.anew(Type.getType(context.classDesc));
|
|
||||||
m.dup();
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokespecial(context.className, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(List.class)}), false);
|
|
||||||
m.areturn(InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.visitLabel(end);
|
|
||||||
m.visitLocalVariable("this", context.classDesc, (String)null, start, end, 0);
|
|
||||||
m.visitLocalVariable("list", Type.getDescriptor(List.class), (String)null, start, end, 1);
|
|
||||||
m.visitMaxs(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void dumpClass(String className, byte[] bytes) {
|
|
||||||
File outputFile = new File(exportDir, className + ".class");
|
|
||||||
outputFile.getParentFile().mkdirs();
|
|
||||||
|
|
||||||
try {
|
|
||||||
Files.write(bytes, outputFile);
|
|
||||||
} catch (IOException var4) {
|
|
||||||
IOException e = var4;
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Class<?> defineClass(final String className, final byte[] bytes) {
|
|
||||||
ClassLoader classLoader = new ClassLoader(BytecodeGen.class.getClassLoader()) {
|
|
||||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
|
||||||
return name.equals(className) ? super.defineClass(name, bytes, 0, bytes.length) : super.loadClass(name);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
return classLoader.loadClass(className);
|
|
||||||
} catch (ClassNotFoundException var4) {
|
|
||||||
ClassNotFoundException e = var4;
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
org.bxteam.divinemc.util.Files.deleteRecursively(exportDir);
|
|
||||||
} catch (IOException var1) {
|
|
||||||
IOException e = var1;
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
RELAXED_STRATEGY = new Hash.Strategy<AstNode>() {
|
|
||||||
public int hashCode(AstNode o) {
|
|
||||||
return o.relaxedHashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(AstNode a, AstNode b) {
|
|
||||||
return a.relaxedEquals(b);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
compilationCache = Object2ReferenceMaps.synchronize(new Object2ReferenceOpenCustomHashMap<>(RELAXED_STRATEGY));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Context {
|
|
||||||
public static final String SINGLE_DESC;
|
|
||||||
public static final String MULTI_DESC;
|
|
||||||
public final ClassWriter classWriter;
|
|
||||||
public final String className;
|
|
||||||
public final String classDesc;
|
|
||||||
private int methodIdx = 0;
|
|
||||||
private final Object2ReferenceOpenHashMap<AstNode, String> singleMethods = new Object2ReferenceOpenHashMap<>();
|
|
||||||
private final Object2ReferenceOpenHashMap<AstNode, String> multiMethods = new Object2ReferenceOpenHashMap<>();
|
|
||||||
private final Object2ReferenceOpenHashMap<CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate>, String> splineMethods = new Object2ReferenceOpenHashMap<>();
|
|
||||||
private final ObjectOpenHashSet<String> postProcessMethods = new ObjectOpenHashSet<>();
|
|
||||||
private final Reference2ObjectOpenHashMap<Object, FieldRecord> args = new Reference2ObjectOpenHashMap<>();
|
|
||||||
|
|
||||||
public Context(ClassWriter classWriter, String className) {
|
|
||||||
this.classWriter = (ClassWriter)Objects.requireNonNull(classWriter);
|
|
||||||
this.className = (String)Objects.requireNonNull(className);
|
|
||||||
this.classDesc = String.format("L%s;", this.className);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String nextMethodName() {
|
|
||||||
return String.format("method_%d", this.methodIdx++);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String nextMethodName(String suffix) {
|
|
||||||
return String.format("method_%d_%s", this.methodIdx++, suffix);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String newSingleMethod(AstNode node) {
|
|
||||||
return this.singleMethods.computeIfAbsent(node, (AstNode node1) -> this.newSingleMethod((adapter, localVarConsumer) -> node1.doBytecodeGenSingle(this, adapter, localVarConsumer), nextMethodName(node.getClass().getSimpleName())));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String newSingleMethod(BiConsumer<InstructionAdapter, LocalVarConsumer> generator) {
|
|
||||||
return this.newSingleMethod(generator, this.nextMethodName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String newSingleMethod(BiConsumer<InstructionAdapter, LocalVarConsumer> generator, String name) {
|
|
||||||
this.newSingleMethod0(generator, name, false);
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void newSingleMethod0(BiConsumer<InstructionAdapter, LocalVarConsumer> generator, String name, boolean isPublic) {
|
|
||||||
InstructionAdapter adapter = new InstructionAdapter(new AnalyzerAdapter(this.className, (isPublic ? 1 : 2) | 16, name, SINGLE_DESC, this.classWriter.visitMethod((isPublic ? 1 : 2) | 16, name, SINGLE_DESC, (String)null, (String[])null)));
|
|
||||||
List<IntObjectPair<Pair<String, String>>> extraLocals = new ArrayList<>();
|
|
||||||
Label start = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
adapter.visitLabel(start);
|
|
||||||
generator.accept(adapter, (localName, localDesc) -> {
|
|
||||||
int ordinal = extraLocals.size() + 5;
|
|
||||||
extraLocals.add(IntObjectPair.of(ordinal, Pair.of(localName, localDesc)));
|
|
||||||
return ordinal;
|
|
||||||
});
|
|
||||||
adapter.visitLabel(end);
|
|
||||||
adapter.visitLocalVariable("this", this.classDesc, (String)null, start, end, 0);
|
|
||||||
adapter.visitLocalVariable("x", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 1);
|
|
||||||
adapter.visitLocalVariable("y", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 2);
|
|
||||||
adapter.visitLocalVariable("z", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 3);
|
|
||||||
adapter.visitLocalVariable("evalType", Type.getType(EvalType.class).getDescriptor(), (String)null, start, end, 4);
|
|
||||||
Iterator var8 = extraLocals.iterator();
|
|
||||||
|
|
||||||
while(var8.hasNext()) {
|
|
||||||
IntObjectPair<Pair<String, String>> local = (IntObjectPair)var8.next();
|
|
||||||
adapter.visitLocalVariable((String)((Pair)local.right()).left(), (String)((Pair)local.right()).right(), (String)null, start, end, local.leftInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter.visitMaxs(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String newMultiMethod(AstNode node) {
|
|
||||||
return this.multiMethods.computeIfAbsent(node, (AstNode node1) -> this.newMultiMethod((adapter, localVarConsumer) -> node1.doBytecodeGenMulti(this, adapter, localVarConsumer), nextMethodName(node.getClass().getSimpleName())));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String newMultiMethod(BiConsumer<InstructionAdapter, LocalVarConsumer> generator) {
|
|
||||||
return this.newMultiMethod(generator, this.nextMethodName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String newMultiMethod(BiConsumer<InstructionAdapter, LocalVarConsumer> generator, String name) {
|
|
||||||
this.newMultiMethod0(generator, name, false);
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void newMultiMethod0(BiConsumer<InstructionAdapter, LocalVarConsumer> generator, String name, boolean isPublic) {
|
|
||||||
InstructionAdapter adapter = new InstructionAdapter(new AnalyzerAdapter(this.className, (isPublic ? 1 : 2) | 16, name, MULTI_DESC, this.classWriter.visitMethod((isPublic ? 1 : 2) | 16, name, MULTI_DESC, (String)null, (String[])null)));
|
|
||||||
List<IntObjectPair<Pair<String, String>>> extraLocals = new ArrayList();
|
|
||||||
Label start = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
adapter.visitLabel(start);
|
|
||||||
generator.accept(adapter, (localName, localDesc) -> {
|
|
||||||
int ordinal = extraLocals.size() + 7;
|
|
||||||
extraLocals.add(IntObjectPair.of(ordinal, Pair.of(localName, localDesc)));
|
|
||||||
return ordinal;
|
|
||||||
});
|
|
||||||
adapter.visitLabel(end);
|
|
||||||
adapter.visitLocalVariable("this", this.classDesc, (String)null, start, end, 0);
|
|
||||||
adapter.visitLocalVariable("res", Type.getType(double[].class).getDescriptor(), (String)null, start, end, 1);
|
|
||||||
adapter.visitLocalVariable("x", Type.getType(double[].class).getDescriptor(), (String)null, start, end, 2);
|
|
||||||
adapter.visitLocalVariable("y", Type.getType(double[].class).getDescriptor(), (String)null, start, end, 3);
|
|
||||||
adapter.visitLocalVariable("z", Type.getType(double[].class).getDescriptor(), (String)null, start, end, 4);
|
|
||||||
adapter.visitLocalVariable("evalType", Type.getType(EvalType.class).getDescriptor(), (String)null, start, end, 5);
|
|
||||||
adapter.visitLocalVariable("arrayCache", Type.getType(ArrayCache.class).getDescriptor(), (String)null, start, end, 6);
|
|
||||||
Iterator var8 = extraLocals.iterator();
|
|
||||||
|
|
||||||
while(var8.hasNext()) {
|
|
||||||
IntObjectPair<Pair<String, String>> local = (IntObjectPair)var8.next();
|
|
||||||
adapter.visitLocalVariable((String)((Pair)local.right()).left(), (String)((Pair)local.right()).right(), (String)null, start, end, local.leftInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter.visitMaxs(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCachedSplineMethod(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline) {
|
|
||||||
return (String)this.splineMethods.get(spline);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cacheSplineMethod(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline, String method) {
|
|
||||||
this.splineMethods.put(spline, method);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void callDelegateSingle(InstructionAdapter m, String target) {
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(1, Type.INT_TYPE);
|
|
||||||
m.load(2, Type.INT_TYPE);
|
|
||||||
m.load(3, Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(this.className, target, SINGLE_DESC, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void callDelegateMulti(InstructionAdapter m, String target) {
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(6, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(this.className, target, MULTI_DESC, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> String newField(Class<T> type, T data) {
|
|
||||||
FieldRecord existing = (FieldRecord)this.args.get(data);
|
|
||||||
if (existing != null) {
|
|
||||||
return existing.name();
|
|
||||||
} else {
|
|
||||||
int size = this.args.size();
|
|
||||||
String name = String.format("field_%d", size);
|
|
||||||
this.classWriter.visitField(2, name, Type.getDescriptor(type), (String)null, (Object)null);
|
|
||||||
this.args.put(data, new FieldRecord(name, size, type));
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doCountedLoop(InstructionAdapter m, LocalVarConsumer localVarConsumer, IntConsumer bodyGenerator) {
|
|
||||||
int loopIdx = localVarConsumer.createLocalVariable("loopIdx", Type.INT_TYPE.getDescriptor());
|
|
||||||
m.iconst(0);
|
|
||||||
m.store(loopIdx, Type.INT_TYPE);
|
|
||||||
Label start = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
m.visitLabel(start);
|
|
||||||
m.load(loopIdx, Type.INT_TYPE);
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.arraylength();
|
|
||||||
m.ificmpge(end);
|
|
||||||
bodyGenerator.accept(loopIdx);
|
|
||||||
m.iinc(loopIdx, 1);
|
|
||||||
m.goTo(start);
|
|
||||||
m.visitLabel(end);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delegateToSingle(InstructionAdapter m, LocalVarConsumer localVarConsumer, AstNode current) {
|
|
||||||
String singleMethod = this.newSingleMethod(current);
|
|
||||||
this.doCountedLoop(m, localVarConsumer, (idx) -> {
|
|
||||||
m.load(1, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.load(0, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(2, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(3, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(4, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.load(idx, Type.INT_TYPE);
|
|
||||||
m.aload(Type.INT_TYPE);
|
|
||||||
m.load(5, InstructionAdapter.OBJECT_TYPE);
|
|
||||||
m.invokevirtual(this.className, singleMethod, SINGLE_DESC, false);
|
|
||||||
m.astore(Type.DOUBLE_TYPE);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void genPostprocessingMethod(String name, Consumer<InstructionAdapter> generator) {
|
|
||||||
if (!this.postProcessMethods.contains(name)) {
|
|
||||||
InstructionAdapter adapter = new InstructionAdapter(new AnalyzerAdapter(this.className, 18, name, "()V", this.classWriter.visitMethod(18, name, "()V", (String)null, (String[])null)));
|
|
||||||
Label start = new Label();
|
|
||||||
Label end = new Label();
|
|
||||||
adapter.visitLabel(start);
|
|
||||||
generator.accept(adapter);
|
|
||||||
adapter.visitLabel(end);
|
|
||||||
adapter.visitMaxs(0, 0);
|
|
||||||
adapter.visitLocalVariable("this", this.classDesc, (String)null, start, end, 0);
|
|
||||||
this.postProcessMethods.add(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
SINGLE_DESC = Type.getMethodDescriptor(Type.getType(Double.TYPE), new Type[]{Type.getType(Integer.TYPE), Type.getType(Integer.TYPE), Type.getType(Integer.TYPE), Type.getType(EvalType.class)});
|
|
||||||
MULTI_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(EvalType.class), Type.getType(ArrayCache.class)});
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface LocalVarConsumer {
|
|
||||||
int createLocalVariable(String var1, String var2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static record FieldRecord(String name, int ordinal, Class<?> type) {
|
|
||||||
private FieldRecord(String name, int ordinal, Class<?> type) {
|
|
||||||
this.name = name;
|
|
||||||
this.ordinal = ordinal;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String name() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int ordinal() {
|
|
||||||
return this.ordinal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<?> type() {
|
|
||||||
return this.type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface EvalMultiInterface {
|
|
||||||
void evalMulti(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5);
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface EvalSingleInterface {
|
|
||||||
double evalSingle(int var1, int var2, int var3, EvalType var4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.gen;
|
|
||||||
|
|
||||||
import com.google.common.base.Suppliers;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ducks.IBlendingAwareVisitor;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ducks.IFastCacheLike;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ListIterator;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
|
|
||||||
public class CompiledDensityFunction extends SubCompiledDensityFunction {
|
|
||||||
private final CompiledEntry compiledEntry;
|
|
||||||
|
|
||||||
public CompiledDensityFunction(CompiledEntry compiledEntry, DensityFunction blendingFallback) {
|
|
||||||
super(compiledEntry, compiledEntry, blendingFallback);
|
|
||||||
this.compiledEntry = (CompiledEntry)Objects.requireNonNull(compiledEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
private CompiledDensityFunction(CompiledEntry compiledEntry, Supplier<DensityFunction> blendingFallback) {
|
|
||||||
super(compiledEntry, compiledEntry, blendingFallback);
|
|
||||||
this.compiledEntry = (CompiledEntry)Objects.requireNonNull(compiledEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DensityFunction mapAll(Visitor visitor) {
|
|
||||||
if (visitor instanceof IBlendingAwareVisitor blendingAwareVisitor) {
|
|
||||||
if (blendingAwareVisitor.c2me$isBlendingEnabled()) {
|
|
||||||
DensityFunction fallback1 = this.getFallback();
|
|
||||||
if (fallback1 == null) {
|
|
||||||
throw new IllegalStateException("blendingFallback is no more");
|
|
||||||
}
|
|
||||||
|
|
||||||
return fallback1.mapAll(visitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean modified = false;
|
|
||||||
List<Object> args = this.compiledEntry.getArgs();
|
|
||||||
ListIterator<Object> iterator = args.listIterator();
|
|
||||||
|
|
||||||
Object next;
|
|
||||||
while(iterator.hasNext()) {
|
|
||||||
next = iterator.next();
|
|
||||||
if (next instanceof DensityFunction df) {
|
|
||||||
if (!(df instanceof IFastCacheLike)) {
|
|
||||||
DensityFunction applied = df.mapAll(visitor);
|
|
||||||
if (df != applied) {
|
|
||||||
iterator.set(applied);
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (next instanceof NoiseHolder noise) {
|
|
||||||
NoiseHolder applied = visitor.visitNoise(noise);
|
|
||||||
if (noise != applied) {
|
|
||||||
iterator.set(applied);
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator = args.listIterator();
|
|
||||||
|
|
||||||
while(iterator.hasNext()) {
|
|
||||||
next = iterator.next();
|
|
||||||
if (next instanceof IFastCacheLike cacheLike) {
|
|
||||||
DensityFunction applied = visitor.apply(cacheLike);
|
|
||||||
if (applied == cacheLike.c2me$getDelegate()) {
|
|
||||||
iterator.set((Object)null);
|
|
||||||
modified = true;
|
|
||||||
} else {
|
|
||||||
if (!(applied instanceof IFastCacheLike)) {
|
|
||||||
throw new UnsupportedOperationException("Unsupported transformation on Wrapping node");
|
|
||||||
}
|
|
||||||
|
|
||||||
IFastCacheLike newCacheLike = (IFastCacheLike)applied;
|
|
||||||
iterator.set(newCacheLike);
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Supplier<DensityFunction> fallback = this.blendingFallback != null ? Suppliers.memoize(() -> {
|
|
||||||
DensityFunction densityFunction = (DensityFunction)this.blendingFallback.get();
|
|
||||||
return densityFunction != null ? densityFunction.mapAll(visitor) : null;
|
|
||||||
}) : null;
|
|
||||||
if (fallback != this.blendingFallback) {
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modified) {
|
|
||||||
return new CompiledDensityFunction(this.compiledEntry.newInstance(args), fallback);
|
|
||||||
} else {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.gen;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface CompiledEntry extends ISingleMethod, IMultiMethod {
|
|
||||||
double evalSingle(int var1, int var2, int var3, EvalType var4);
|
|
||||||
|
|
||||||
void evalMulti(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5, ArrayCache var6);
|
|
||||||
|
|
||||||
CompiledEntry newInstance(List<?> var1);
|
|
||||||
|
|
||||||
List<Object> getArgs();
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.gen;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ducks.IBlendingAwareVisitor;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class DelegatingBlendingAwareVisitor implements IBlendingAwareVisitor, DensityFunction.Visitor {
|
|
||||||
private final DensityFunction.Visitor delegate;
|
|
||||||
private final boolean blendingEnabled;
|
|
||||||
|
|
||||||
public DelegatingBlendingAwareVisitor(DensityFunction.Visitor delegate, boolean blendingEnabled) {
|
|
||||||
this.delegate = Objects.requireNonNull(delegate);
|
|
||||||
this.blendingEnabled = blendingEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull DensityFunction apply(@NotNull DensityFunction densityFunction) {
|
|
||||||
return this.delegate.apply(densityFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DensityFunction.@NotNull NoiseHolder visitNoise(DensityFunction.@NotNull NoiseHolder noiseDensityFunction) {
|
|
||||||
return this.delegate.visitNoise(noiseDensityFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean c2me$isBlendingEnabled() {
|
|
||||||
return this.blendingEnabled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.gen;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface IMultiMethod {
|
|
||||||
void evalMulti(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5, ArrayCache var6);
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.gen;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ISingleMethod {
|
|
||||||
double evalSingle(int var1, int var2, int var3, EvalType var4);
|
|
||||||
}
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.gen;
|
|
||||||
|
|
||||||
import com.google.common.base.Suppliers;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ducks.IArrayCacheCapable;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ducks.IBlendingAwareVisitor;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ducks.ICoordinatesFilling;
|
|
||||||
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
|
|
||||||
import org.bxteam.divinemc.dfc.common.vif.EachApplierVanillaInterface;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import net.minecraft.util.KeyDispatchDataCodec;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import net.minecraft.world.level.levelgen.NoiseChunk;
|
|
||||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class SubCompiledDensityFunction implements DensityFunction {
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(SubCompiledDensityFunction.class);
|
|
||||||
private final ISingleMethod singleMethod;
|
|
||||||
private final IMultiMethod multiMethod;
|
|
||||||
protected final Supplier<DensityFunction> blendingFallback;
|
|
||||||
|
|
||||||
public SubCompiledDensityFunction(ISingleMethod singleMethod, IMultiMethod multiMethod, DensityFunction blendingFallback) {
|
|
||||||
this(singleMethod, multiMethod, unwrap(blendingFallback));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected SubCompiledDensityFunction(ISingleMethod singleMethod, IMultiMethod multiMethod, Supplier<DensityFunction> blendingFallback) {
|
|
||||||
this.singleMethod = (ISingleMethod)Objects.requireNonNull(singleMethod);
|
|
||||||
this.multiMethod = (IMultiMethod)Objects.requireNonNull(multiMethod);
|
|
||||||
this.blendingFallback = blendingFallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Supplier<DensityFunction> unwrap(DensityFunction densityFunction) {
|
|
||||||
if (densityFunction instanceof SubCompiledDensityFunction scdf) {
|
|
||||||
return scdf.blendingFallback;
|
|
||||||
} else {
|
|
||||||
return densityFunction != null ? Suppliers.ofInstance(densityFunction) : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double compute(FunctionContext pos) {
|
|
||||||
if (pos.getBlender() != Blender.empty()) {
|
|
||||||
DensityFunction fallback = this.getFallback();
|
|
||||||
if (fallback == null) {
|
|
||||||
throw new IllegalStateException("blendingFallback is no more");
|
|
||||||
} else {
|
|
||||||
return fallback.compute(pos);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return this.singleMethod.evalSingle(pos.blockX(), pos.blockY(), pos.blockZ(), EvalType.from(pos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fillArray(double[] densities, ContextProvider applier) {
|
|
||||||
if (applier instanceof NoiseChunk sampler) {
|
|
||||||
if (sampler.getBlender() != Blender.empty()) {
|
|
||||||
DensityFunction fallback = this.getFallback();
|
|
||||||
if (fallback == null) {
|
|
||||||
throw new IllegalStateException("blendingFallback is no more");
|
|
||||||
}
|
|
||||||
|
|
||||||
fallback.fillArray(densities, applier);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (applier instanceof EachApplierVanillaInterface vanillaInterface) {
|
|
||||||
this.multiMethod.evalMulti(densities, vanillaInterface.getX(), vanillaInterface.getY(), vanillaInterface.getZ(), EvalType.from(applier), vanillaInterface.c2me$getArrayCache());
|
|
||||||
} else {
|
|
||||||
ArrayCache var10000;
|
|
||||||
if (applier instanceof IArrayCacheCapable cacheCapable) {
|
|
||||||
var10000 = cacheCapable.c2me$getArrayCache();
|
|
||||||
} else {
|
|
||||||
var10000 = new ArrayCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayCache cache = var10000;
|
|
||||||
int[] x = cache.getIntArray(densities.length, false);
|
|
||||||
int[] y = cache.getIntArray(densities.length, false);
|
|
||||||
int[] z = cache.getIntArray(densities.length, false);
|
|
||||||
if (applier instanceof ICoordinatesFilling coordinatesFilling) {
|
|
||||||
coordinatesFilling.c2me$fillCoordinates(x, y, z);
|
|
||||||
} else {
|
|
||||||
for(int i = 0; i < densities.length; ++i) {
|
|
||||||
FunctionContext pos = applier.forIndex(i);
|
|
||||||
x[i] = pos.blockX();
|
|
||||||
y[i] = pos.blockY();
|
|
||||||
z[i] = pos.blockZ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.multiMethod.evalMulti(densities, x, y, z, EvalType.from(applier), cache);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public DensityFunction mapAll(Visitor visitor) {
|
|
||||||
if (this.getClass() != SubCompiledDensityFunction.class) {
|
|
||||||
throw new AbstractMethodError();
|
|
||||||
} else {
|
|
||||||
if (visitor instanceof IBlendingAwareVisitor) {
|
|
||||||
IBlendingAwareVisitor blendingAwareVisitor = (IBlendingAwareVisitor)visitor;
|
|
||||||
if (blendingAwareVisitor.c2me$isBlendingEnabled()) {
|
|
||||||
DensityFunction fallback1 = this.getFallback();
|
|
||||||
if (fallback1 == null) {
|
|
||||||
throw new IllegalStateException("blendingFallback is no more");
|
|
||||||
}
|
|
||||||
|
|
||||||
return fallback1.mapAll(visitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean modified = false;
|
|
||||||
Supplier<DensityFunction> fallback = this.blendingFallback != null ? Suppliers.memoize(() -> {
|
|
||||||
DensityFunction densityFunction = (DensityFunction)this.blendingFallback.get();
|
|
||||||
return densityFunction != null ? densityFunction.mapAll(visitor) : null;
|
|
||||||
}) : null;
|
|
||||||
if (fallback != this.blendingFallback) {
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return modified ? new SubCompiledDensityFunction(this.singleMethod, this.multiMethod, fallback) : this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double minValue() {
|
|
||||||
return Double.MIN_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double maxValue() {
|
|
||||||
return Double.MAX_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyDispatchDataCodec<? extends DensityFunction> codec() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected DensityFunction getFallback() {
|
|
||||||
return this.blendingFallback != null ? (DensityFunction)this.blendingFallback.get() : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.util;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ReferenceArrayMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class ArrayCache {
|
|
||||||
private final Int2ReferenceArrayMap<ReferenceArrayList<double[]>> doubleArrayCache = new Int2ReferenceArrayMap<>();
|
|
||||||
private final Int2ReferenceArrayMap<ReferenceArrayList<int[]>> intArrayCache = new Int2ReferenceArrayMap<>();
|
|
||||||
|
|
||||||
public ArrayCache() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public double[] getDoubleArray(int size, boolean zero) {
|
|
||||||
ReferenceArrayList<double[]> list = this.doubleArrayCache.computeIfAbsent(size, (k) -> {
|
|
||||||
return new ReferenceArrayList<>();
|
|
||||||
});
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
return new double[size];
|
|
||||||
} else {
|
|
||||||
double[] popped = list.pop();
|
|
||||||
if (zero) {
|
|
||||||
Arrays.fill(popped, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return popped;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getIntArray(int size, boolean zero) {
|
|
||||||
ReferenceArrayList<int[]> list = this.intArrayCache.computeIfAbsent(size, (k) -> {
|
|
||||||
return new ReferenceArrayList<>();
|
|
||||||
});
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
return new int[size];
|
|
||||||
} else {
|
|
||||||
int[] popped = list.pop();
|
|
||||||
if (zero) {
|
|
||||||
Arrays.fill(popped, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return popped;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void recycle(double[] array) {
|
|
||||||
this.doubleArrayCache.computeIfAbsent(array.length, (k) -> {
|
|
||||||
return new ReferenceArrayList<>();
|
|
||||||
}).add(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void recycle(int[] array) {
|
|
||||||
this.intArrayCache.computeIfAbsent(array.length, (k) -> {
|
|
||||||
return new ReferenceArrayList<>();
|
|
||||||
}).add(array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.vif;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.AstNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.misc.CacheLikeNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.misc.DelegateNode;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ducks.IFastCacheLike;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.util.KeyDispatchDataCodec;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
import net.minecraft.world.level.levelgen.NoiseChunk;
|
|
||||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
|
||||||
|
|
||||||
public class AstVanillaInterface implements DensityFunction {
|
|
||||||
private final AstNode astNode;
|
|
||||||
private final DensityFunction blendingFallback;
|
|
||||||
|
|
||||||
public AstVanillaInterface(AstNode astNode, DensityFunction blendingFallback) {
|
|
||||||
this.astNode = (AstNode)Objects.requireNonNull(astNode);
|
|
||||||
this.blendingFallback = blendingFallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double compute(FunctionContext pos) {
|
|
||||||
if (pos.getBlender() != Blender.empty()) {
|
|
||||||
if (this.blendingFallback == null) {
|
|
||||||
throw new IllegalStateException("blendingFallback is no more");
|
|
||||||
} else {
|
|
||||||
return this.blendingFallback.compute(pos);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return this.astNode.evalSingle(pos.blockX(), pos.blockY(), pos.blockZ(), EvalType.from(pos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fillArray(double[] densities, ContextProvider applier) {
|
|
||||||
if (applier instanceof NoiseChunk sampler) {
|
|
||||||
if (sampler.getBlender() != Blender.empty()) {
|
|
||||||
if (this.blendingFallback == null) {
|
|
||||||
throw new IllegalStateException("blendingFallback is no more");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.blendingFallback.fillArray(densities, applier);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (applier instanceof EachApplierVanillaInterface vanillaInterface) {
|
|
||||||
this.astNode.evalMulti(densities, vanillaInterface.getX(), vanillaInterface.getY(), vanillaInterface.getZ(), EvalType.from(applier));
|
|
||||||
} else {
|
|
||||||
int[] x = new int[densities.length];
|
|
||||||
int[] y = new int[densities.length];
|
|
||||||
int[] z = new int[densities.length];
|
|
||||||
|
|
||||||
for(int i = 0; i < densities.length; ++i) {
|
|
||||||
FunctionContext pos = applier.forIndex(i);
|
|
||||||
x[i] = pos.blockX();
|
|
||||||
y[i] = pos.blockY();
|
|
||||||
z[i] = pos.blockZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.astNode.evalMulti(densities, x, y, z, EvalType.from(applier));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public DensityFunction mapAll(Visitor visitor) {
|
|
||||||
AstNode transformed = this.astNode.transform((astNode) -> {
|
|
||||||
if (astNode instanceof DelegateNode delegateNode) {
|
|
||||||
return new DelegateNode(delegateNode.getDelegate().mapAll(visitor));
|
|
||||||
} else if (astNode instanceof CacheLikeNode cacheLikeNode) {
|
|
||||||
return new CacheLikeNode((IFastCacheLike)cacheLikeNode.getCacheLike().mapAll(visitor), cacheLikeNode.getDelegate());
|
|
||||||
} else {
|
|
||||||
return astNode;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
DensityFunction blendingFallback1 = this.blendingFallback != null ? this.blendingFallback.mapAll(visitor) : null;
|
|
||||||
return transformed == this.astNode && blendingFallback1 == this.blendingFallback ? this : new AstVanillaInterface(transformed, blendingFallback1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double minValue() {
|
|
||||||
return this.blendingFallback.minValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public double maxValue() {
|
|
||||||
return this.blendingFallback.maxValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyDispatchDataCodec<? extends DensityFunction> codec() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstNode getAstNode() {
|
|
||||||
return this.astNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DensityFunction getBlendingFallback() {
|
|
||||||
return this.blendingFallback;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.vif;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import org.bxteam.divinemc.dfc.common.ducks.IArrayCacheCapable;
|
|
||||||
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
|
|
||||||
public class EachApplierVanillaInterface implements DensityFunction.ContextProvider, IArrayCacheCapable {
|
|
||||||
private final int[] x;
|
|
||||||
private final int[] y;
|
|
||||||
private final int[] z;
|
|
||||||
private final EvalType type;
|
|
||||||
private final ArrayCache cache;
|
|
||||||
|
|
||||||
public EachApplierVanillaInterface(int[] x, int[] y, int[] z, EvalType type) {
|
|
||||||
this(x, y, z, type, new ArrayCache());
|
|
||||||
}
|
|
||||||
|
|
||||||
public EachApplierVanillaInterface(int[] x, int[] y, int[] z, EvalType type, ArrayCache cache) {
|
|
||||||
this.x = (int[])Objects.requireNonNull(x);
|
|
||||||
this.y = (int[])Objects.requireNonNull(y);
|
|
||||||
this.z = (int[])Objects.requireNonNull(z);
|
|
||||||
this.type = (EvalType)Objects.requireNonNull(type);
|
|
||||||
this.cache = (ArrayCache)Objects.requireNonNull(cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DensityFunction.FunctionContext forIndex(int index) {
|
|
||||||
return new NoisePosVanillaInterface(this.x[index], this.y[index], this.z[index], this.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fillAllDirectly(double[] densities, DensityFunction densityFunction) {
|
|
||||||
for(int i = 0; i < this.x.length; ++i) {
|
|
||||||
densities[i] = densityFunction.compute(this.forIndex(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getX() {
|
|
||||||
return this.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getY() {
|
|
||||||
return this.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getZ() {
|
|
||||||
return this.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EvalType getType() {
|
|
||||||
return this.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayCache c2me$getArrayCache() {
|
|
||||||
return this.cache;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package org.bxteam.divinemc.dfc.common.vif;
|
|
||||||
|
|
||||||
import org.bxteam.divinemc.dfc.common.ast.EvalType;
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
|
||||||
|
|
||||||
public class NoisePosVanillaInterface implements DensityFunction.FunctionContext {
|
|
||||||
private final int x;
|
|
||||||
private final int y;
|
|
||||||
private final int z;
|
|
||||||
private final EvalType type;
|
|
||||||
|
|
||||||
public NoisePosVanillaInterface(int x, int y, int z, EvalType type) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
this.type = (EvalType)Objects.requireNonNull(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int blockX() {
|
|
||||||
return this.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int blockY() {
|
|
||||||
return this.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int blockZ() {
|
|
||||||
return this.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EvalType getType() {
|
|
||||||
return this.type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,297 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
|
||||||
Date: Wed, 22 May 2024 23:15:23 +0300
|
|
||||||
Subject: [PATCH] C2ME: opts math
|
|
||||||
|
|
||||||
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/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java b/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
|
|
||||||
index 9a97e5cd23d839183ac4d243d28df92af3119fe7..04f3adc26999aebe039436bdd6ef85ab0197c5b4 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;
|
|
||||||
|
|
||||||
+ // DivineMC 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,
|
|
||||||
+ };
|
|
||||||
+ // DivineMC end
|
|
||||||
+
|
|
||||||
public ImprovedNoise(RandomSource random) {
|
|
||||||
this.xo = random.nextDouble() * 256.0;
|
|
||||||
this.yo = random.nextDouble() * 256.0;
|
|
||||||
@@ -41,9 +62,20 @@ public final class ImprovedNoise {
|
|
||||||
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;
|
|
||||||
+ // DivineMC start - C2ME: opts math
|
|
||||||
+ double g;
|
|
||||||
+ double h;
|
|
||||||
+ double l;
|
|
||||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
|
||||||
+ g = d - (double)i;
|
|
||||||
+ h = e - (double)j;
|
|
||||||
+ l = f - (double)k;
|
|
||||||
+ } else {
|
|
||||||
+ g = d - i;
|
|
||||||
+ h = e - j;
|
|
||||||
+ l = f - k;
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end
|
|
||||||
double o;
|
|
||||||
if (yScale != 0.0) {
|
|
||||||
double m;
|
|
||||||
@@ -53,12 +85,24 @@ public final class ImprovedNoise {
|
|
||||||
m = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
- o = (double)Mth.floor(m / yScale + 1.0E-7F) * yScale;
|
|
||||||
+ // DivineMC start - C2ME: opts math
|
|
||||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
|
||||||
+ o = (double)Mth.floor(m / yScale + 1.0E-7F) * yScale;
|
|
||||||
+ } else {
|
|
||||||
+ o = Math.floor(m / yScale + (double)1.0E-7F) * yScale;
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end
|
|
||||||
} else {
|
|
||||||
o = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return this.sampleAndLerp(i, j, k, g, h - o, l, h);
|
|
||||||
+ // DivineMC start - C2ME: opts math
|
|
||||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
|
||||||
+ return this.sampleAndLerp(i, j, k, g, h - o, l, h);
|
|
||||||
+ } else {
|
|
||||||
+ return this.sampleAndLerp((int) i, (int) j, (int) k, g, h - o, l, h);
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end
|
|
||||||
}
|
|
||||||
|
|
||||||
public double noiseWithDerivative(double x, double y, double z, double[] ds) {
|
|
||||||
@@ -68,10 +112,19 @@ public final class ImprovedNoise {
|
|
||||||
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;
|
|
||||||
- return this.sampleWithDerivative(i, j, k, g, h, l, ds);
|
|
||||||
+ // DivineMC start - C2ME: opts math
|
|
||||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
|
||||||
+ double g = d - (double)i;
|
|
||||||
+ double h = e - (double)j;
|
|
||||||
+ double l = f - (double)k;
|
|
||||||
+ return this.sampleWithDerivative(i, j, k, g, h, l, ds);
|
|
||||||
+ } else {
|
|
||||||
+ double g = d - i;
|
|
||||||
+ double h = e - j;
|
|
||||||
+ double l = f - k;
|
|
||||||
+ return this.sampleWithDerivative((int) i, (int) j, (int) k, g, h, l, ds);
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double gradDot(int hash, double x, double y, double z) {
|
|
||||||
@@ -83,24 +136,90 @@ public final class ImprovedNoise {
|
|
||||||
}
|
|
||||||
|
|
||||||
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.0, localY, localZ);
|
|
||||||
- double f = gradDot(this.p(l + sectionZ), localX, localY - 1.0, localZ);
|
|
||||||
- double g = gradDot(this.p(n + sectionZ), localX - 1.0, localY - 1.0, localZ);
|
|
||||||
- double h = gradDot(this.p(k + sectionZ + 1), localX, localY, localZ - 1.0);
|
|
||||||
- double o = gradDot(this.p(m + sectionZ + 1), localX - 1.0, localY, localZ - 1.0);
|
|
||||||
- double p = gradDot(this.p(l + sectionZ + 1), localX, localY - 1.0, localZ - 1.0);
|
|
||||||
- double q = gradDot(this.p(n + sectionZ + 1), localX - 1.0, localY - 1.0, localZ - 1.0);
|
|
||||||
- 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);
|
|
||||||
+ // DivineMC start - C2ME: opts math
|
|
||||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
|
||||||
+ 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.0, localY, localZ);
|
|
||||||
+ double f = gradDot(this.p(l + sectionZ), localX, localY - 1.0, localZ);
|
|
||||||
+ double g = gradDot(this.p(n + sectionZ), localX - 1.0, localY - 1.0, localZ);
|
|
||||||
+ double h = gradDot(this.p(k + sectionZ + 1), localX, localY, localZ - 1.0);
|
|
||||||
+ double o = gradDot(this.p(m + sectionZ + 1), localX - 1.0, localY, localZ - 1.0);
|
|
||||||
+ double p = gradDot(this.p(l + sectionZ + 1), localX, localY - 1.0, localZ - 1.0);
|
|
||||||
+ double q = gradDot(this.p(n + sectionZ + 1), localX - 1.0, localY - 1.0, localZ - 1.0);
|
|
||||||
+ 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);
|
|
||||||
+ } else {
|
|
||||||
+ 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 = fadeLocalY * 6.0 - 15.0;
|
|
||||||
+ final double var97 = localZ * 6.0 - 15.0;
|
|
||||||
+ final double var98 = localX * var95 + 10.0;
|
|
||||||
+ final double var99 = fadeLocalY * var96 + 10.0;
|
|
||||||
+ final double var100 = localZ * var97 + 10.0;
|
|
||||||
+ final double var101 = localX * localX * localX * var98;
|
|
||||||
+ final double var102 = fadeLocalY * fadeLocalY * fadeLocalY * 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));
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end
|
|
||||||
}
|
|
||||||
|
|
||||||
private double sampleWithDerivative(int sectionX, int sectionY, int sectionZ, double localX, double localY, double localZ, double[] ds) {
|
|
||||||
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 35820670837376bcad8891241724d5b946fbd31f..74a666a45289f0902b426ba57986cd93b41cb42c 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;
|
|
||||||
+ // DivineMC start - C2ME: opts math
|
|
||||||
+ private final int octaveSamplersCount;
|
|
||||||
+ private final double [] amplitudesArray;
|
|
||||||
+ // DivineMC end
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static PerlinNoise createLegacyForBlendedNoise(RandomSource random, IntStream octaves) {
|
|
||||||
@@ -127,6 +131,10 @@ public class PerlinNoise {
|
|
||||||
this.lowestFreqInputFactor = Math.pow(2.0, (double)(-j));
|
|
||||||
this.lowestFreqValueFactor = Math.pow(2.0, (double)(i - 1)) / (Math.pow(2.0, (double)i) - 1.0);
|
|
||||||
this.maxValue = this.edgeValue(2.0);
|
|
||||||
+ // DivineMC start - C2ME: opts math
|
|
||||||
+ this.octaveSamplersCount = this.noiseLevels.length;
|
|
||||||
+ this.amplitudesArray = this.amplitudes.toDoubleArray();
|
|
||||||
+ // DivineMC end
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double maxValue() {
|
|
||||||
@@ -138,7 +146,30 @@ public class PerlinNoise {
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getValue(double x, double y, double z) {
|
|
||||||
- return this.getValue(x, y, z, 0.0, 0.0, false);
|
|
||||||
+ // DivineMC start - C2ME: opts math
|
|
||||||
+ if (!space.bxteam.divinemc.configuration.DivineConfig.optimizeNoiseGeneration) {
|
|
||||||
+ return this.getValue(x, y, z, 0.0, 0.0, false);
|
|
||||||
+ } else {
|
|
||||||
+ 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;
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
|
||||||
index c88157b27b344b2ed1153a44daee751f5b53b45d..aaf3afd0fe1f13ed7375d272e2690e9db0410417 100644
|
|
||||||
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
|
||||||
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
|
|
||||||
@@ -162,8 +162,10 @@ public class DivineConfig {
|
|
||||||
|
|
||||||
public static boolean biomeManagerOptimization = true;
|
|
||||||
public static boolean optimizedDragonRespawn = true;
|
|
||||||
+ public static boolean optimizeNoiseGeneration = true;
|
|
||||||
private static void optimizations() {
|
|
||||||
biomeManagerOptimization = getBoolean("settings.optimizations.biome-manager-optimization", biomeManagerOptimization);
|
|
||||||
optimizedDragonRespawn = getBoolean("settings.optimizations.optimized-dragon-respawn", optimizedDragonRespawn);
|
|
||||||
+ optimizeNoiseGeneration = getBoolean("settings.optimizations.optimize-noise-generation", optimizeNoiseGeneration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user