KernelErosionOperation class
Пакет: com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential
Файл: com/hypixel/hytale/builtin/buildertools/scriptedbrushes/operations/sequential/KernelErosionOperation.java
extends: SequenceBrushOperation
Поля (44)
| Модификаторы | Тип | Имя |
|---|---|---|
final |
BuilderCodec<KernelErosionOperation> |
CODEC |
|
Full,
Heightmap, |
Flat |
|
|
break |
|
final SculptOperation.Kernel |
flat |
|
final SculptOperation.Kernel |
full |
|
final SculptOperation.Kernel |
heightmap |
|
BrushConfigEditStore |
var10 |
|
int |
var10 |
|
int |
var10 |
|
int |
var11 |
|
int |
var11 |
|
int |
var12 |
|
int |
var12 |
|
Sample.Result2D |
var13 |
|
int |
var13 |
|
int |
var13 |
|
Sample.Result3D |
var14 |
|
int |
var14 |
|
int |
var15 |
|
int |
var15 |
|
int |
var15 |
|
int |
var16 |
|
int |
var16 |
|
int |
var17 |
|
|
var17 |
|
|
var17 |
|
int |
var18 |
|
BlockType |
var18 |
|
DrawType |
var19 |
|
SculptOperation.Kernel |
var5 |
|
int |
var6 |
|
Material |
var6 |
|
int[][][] |
var6 |
|
double |
var7 |
|
double |
var7 |
|
Int2IntOpenHashMap |
var7 |
|
Material |
var8 |
|
int |
var8 |
|
Vector3i |
var9 |
|
int |
var9 |
|
Material |
var9 |
|
Material |
var9 |
|
int |
var9 |
|
int |
var9 |
Методы (33)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
|
|
SmoothKernel SmoothKernel(SculptOperation.Kernel nullxx, SculptOperation.Kernel nullxxx, SculptOperation.Kernel nullxxxx) |
|
|
SmoothMode SmoothMode() |
abstract |
|
Square Square(SculptOperation.SQUARE_KERNEL, SculptOperation.SQUARE_HEIGHTMAP, SculptOperation.SQUARE_FLAT) |
static |
int[][][] |
buildBufferint[][][] buildBuffer(BrushConfigEditStore var0, int var1, int var2, int var3, int var4, int var5) |
|
|
for for(int var11 = 1; var11 <= var10; var11++) |
|
|
for for(int var17 = 0; var17 > var16; var17--) |
|
|
for for(int var10 = 0; var10 < var4; var10++) |
|
|
for for(int var12 = 0; var12 < var4; var12++) |
|
|
for for(int var14 = 0; var14 < var5; var14++) |
|
|
if if(this.bufferWidth % 2 == 0) |
|
|
if if(this.bufferHeight % 2 == 0) |
|
|
if if(this.isHeightmap) |
|
|
if if(this.isHeightmap) |
|
|
if if(var9 >= var12
&& var10 >= var12
&& var11 >= var12
&& var9 < this.bufferWidth - var12
&& var10 < this.bufferHeight - var12
&& var11 < this.bufferWidth - var12) |
|
|
if if(this.buffer[var9][var10][var11] == -1) |
|
|
if if(this.isHeightmap) |
|
|
if if(var6 != this.originY) |
|
|
if if(var6 <= this.erosionThresholdLow) |
|
|
if if(var8 <= 0) |
|
|
if if(var6 <= this.erosionThresholdLow) |
|
|
if if(var7 <= 0) |
|
|
if if(var7 != 0) |
|
|
if if(var7 > 0.35) |
|
|
if if(var15 < 0 || var15 >= this.bufferHeight) |
|
|
if if(this.buffer[var12][var15][var13] <= 0) |
|
|
if if(var16 != 0) |
|
|
if if(var17 == Integer.MIN_VALUE) |
|
|
if if(var18 == null) |
private |
void |
smoothBlocksvoid smoothBlocks(BrushConfigEditStore var1, BrushConfig var2, int var3, int var4, int var5, int var6, int var7, int var8) |
private |
void |
smoothBlocksFastvoid smoothBlocksFast(BrushConfigEditStore var1, BrushConfig var2, int var3, int var4, int var5, int var6, int var7) |
private |
void |
smoothBlocksVerticalvoid smoothBlocksVertical(BrushConfigEditStore var1, BrushConfig var2, int var3, int var4, Sample.Result2D var5) |
abstract |
|
super super("Kernel Smooth", "Smooths terrain using weighted kernels with erosion thresholds", true) |
|
|
while while(true) |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential;
class="kw">import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfig;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfigCommandExecutor;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfigEditStore;
class="kw">import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.system.SequenceBrushOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.tooloperations.SculptOperation;
class="kw">import com.hypixel.hytale.builtin.buildertools.utils.Material;
class="kw">import com.hypixel.hytale.builtin.buildertools.utils.Sample;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.codec.codecs.EnumCodec;
class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.protocol.DrawType;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
class="kw">import javax.annotation.Nonnull;
class="kw">import org.joml.Vector3i;
class="kw">public class KernelErosionOperation class="kw">extends SequenceBrushOperation {
class="kw">public class="kw">static class="kw">final BuilderCodec<KernelErosionOperation> CODEC = BuilderCodec.builder(KernelErosionOperation.class, KernelErosionOperation::new)
.append(
new KeyedCodec<>("Kernel", new EnumCodec<>(KernelErosionOperation.SmoothKernel.class)), (var0, var1) -> var0.kernelArg = var1, var0 -> var0.kernelArg
)
.documentation("The smoothing kernel shape to use")
.add()
.<KernelErosionOperation.SmoothMode>append(
new KeyedCodec<>("Mode", new EnumCodec<>(KernelErosionOperation.SmoothMode.class)), (var0, var1) -> var0.modeArg = var1, var0 -> var0.modeArg
)
.documentation("Smoothing mode: Full (3D), Heightmap (2D heightmap), or Flat (XZ-plane only)")
.add()
.<Integer>append(new KeyedCodec<>("ErosionStrength", Codec.INTEGER), (var0, var1) -> var0.erosionStrength = var1, var0 -> var0.erosionStrength)
.documentation("Erosion strength from -10 to 10 (divided by 10 internally). Positive erodes, negative fills.")
.add()
.<Boolean>append(new KeyedCodec<>("SampleNearby", Codec.BOOLEAN), (var0, var1) -> var0.sampleNearby = var1, var0 -> var0.sampleNearby)
.documentation("When true, samples neighbor block types for fill material. When false, uses the brush pattern.")
.add()
.documentation("Smooths terrain using weighted kernels with erosion thresholds")
.build();
@Nonnull
class="kw">public KernelErosionOperation.SmoothKernel kernelArg = KernelErosionOperation.SmoothKernel.Normal;
@Nonnull
class="kw">public KernelErosionOperation.SmoothMode modeArg = KernelErosionOperation.SmoothMode.Full;
@Nonnull
class="kw">public Integer erosionStrength = 0;
@Nonnull
class="kw">public Boolean sampleNearby = false;
class="kw">private class="kw">static class="kw">final BlockTypeAssetMap<String, BlockType> ASSET_MAP = BlockType.getAssetMap();
class="kw">private class="kw">static class="kw">final int BUFFER_MARGIN = 2;
class="kw">private class="kw">static class="kw">final int MIN_EROSION_STRENGTH = -10;
class="kw">private class="kw">static class="kw">final int MAX_EROSION_STRENGTH = 10;
class="kw">private int[][][] buffer;
class="kw">private int[][] heightMapBuffer;
class="kw">private int originX;
class="kw">private int originY;
class="kw">private int originZ;
class="kw">private int bufferWidth;
class="kw">private int bufferHeight;
class="kw">private int halfBufferWidth;
class="kw">private int halfBufferHeight;
class="kw">private int[] kernelWeights;
class="kw">private int kernelTotal;
class="kw">private double erosionPreCalc;
class="kw">private double erosionThresholdLow;
class="kw">private double erosionThresholdHigh;
class="kw">private boolean isHeightmap;
class="kw">public KernelErosionOperation() {
super("Kernel Smooth", "Smooths terrain using weighted kernels with erosion thresholds", true);
}
@Override
class="kw">public void modifyBrushConfig(
@Nonnull Ref<EntityStore> var1, @Nonnull BrushConfig var2, @Nonnull BrushConfigCommandExecutor var3, @Nonnull ComponentAccessor<EntityStore> var4
) {
this.isHeightmap = this.modeArg == KernelErosionOperation.SmoothMode.Heightmap;
SculptOperation.Kernel var5 = class="kw">switch (this.modeArg) {
case Full -> this.kernelArg.full;
case Heightmap -> this.kernelArg.heightmap;
case Flat -> this.kernelArg.flat;
};
this.kernelWeights = var5.weights();
this.kernelTotal = var5.total();
int var6 = Math.max(-10, Math.min(10, this.erosionStrength));
double var7 = var6 / 10.0;
this.erosionPreCalc = -var5.range() * var7;
this.erosionThresholdLow = var5.stable() + this.erosionPreCalc;
this.erosionThresholdHigh = var5.stable() + 1.0 + this.erosionPreCalc;
Vector3i var9 = var2.getOrigin();
this.originX = var9.x;
this.originY = var9.y;
this.originZ = var9.z;
this.bufferWidth = var2.getShapeWidth() + 2;
this.bufferHeight = var2.getShapeHeight() + 2;
if (this.bufferWidth % 2 == 0) {
this.bufferWidth++;
}
if (this.bufferHeight % 2 == 0) {
this.bufferHeight++;
}
if (this.isHeightmap) {
this.bufferWidth += 4;
this.bufferHeight += 20;
}
this.halfBufferWidth = this.bufferWidth / 2;
this.halfBufferHeight = this.bufferHeight / 2;
BrushConfigEditStore var10 = var3.getEdit();
this.buffer = buildBuffer(var10, this.originX, this.originY, this.originZ, this.bufferWidth, this.bufferHeight);
if (this.isHeightmap) {
this.heightMapBuffer = SculptOperation.preCalcBuffer(this.originY, this.buffer);
}
}
@Override
class="kw">public boolean modifyBlocks(
Ref<EntityStore> var1,
BrushConfig var2,
BrushConfigCommandExecutor var3,
@Nonnull BrushConfigEditStore var4,
int var5,
int var6,
int var7,
ComponentAccessor<EntityStore> var8
) {
int var9 = var5 - this.originX + this.halfBufferWidth;
int var10 = var6 - this.originY + this.halfBufferHeight;
int var11 = var7 - this.originZ + this.halfBufferWidth;
int var12 = this.isHeightmap ? 2 : 1;
if (var9 >= var12
&& var10 >= var12
&& var11 >= var12
&& var9 < this.bufferWidth - var12
&& var10 < this.bufferHeight - var12
&& var11 < this.bufferWidth - var12) {
if (this.buffer[var9][var10][var11] == -1) {
var4.setMaterialWithFiller(var5, var6, var7, Material.EMPTY);
}
if (this.isHeightmap) {
if (var6 != this.originY) {
class="kw">return true;
}
Sample.Result2D var13 = Sample.calcDeltaHeights(
var9, var10, var11, this.heightMapBuffer, this.buffer, this.kernelWeights, this.kernelTotal, this.originY, this.sampleNearby
);
this.smoothBlocksVertical(var4, var2, var5, var7, var13);
} else if (this.sampleNearby) {
Sample.Result3D var14 = Sample.calculate3D(var9, var10, var11, this.buffer, this.kernelWeights);
this.smoothBlocks(var4, var2, var5, var6, var7, var14.airWeight(), var14.sampledBlock(), var14.originalBlock());
} else {
int var15 = Sample.calculateAirWeight3D(var9, var10, var11, this.buffer, this.kernelWeights);
this.smoothBlocksFast(var4, var2, var5, var6, var7, var15, this.buffer[var9][var10][var11]);
}
class="kw">return true;
} else {
class="kw">return true;
}
}
class="kw">private void smoothBlocks(BrushConfigEditStore var1, BrushConfig var2, int var3, int var4, int var5, int var6, int var7, int var8) {
Material var9 = var7 > 0 ? Material.block(var7) : var2.getNextMaterial();
if (var6 <= this.erosionThresholdLow) {
if (var8 <= 0) {
var1.setMaterialWithFiller(var3, var4, var5, var9);
}
} else if (var6 > this.erosionThresholdHigh && var8 != 0) {
var1.setMaterialWithFiller(var3, var4, var5, Material.EMPTY);
}
}
class="kw">private void smoothBlocksFast(BrushConfigEditStore var1, BrushConfig var2, int var3, int var4, int var5, int var6, int var7) {
if (var6 <= this.erosionThresholdLow) {
if (var7 <= 0) {
var1.setMaterialWithFiller(var3, var4, var5, var2.getNextMaterial());
} else {
Material var8 = var2.getNextMaterial();
if (var8.getBlockId() != var7) {
var1.setMaterialWithFiller(var3, var4, var5, var8);
}
}
} else if (var6 > this.erosionThresholdHigh) {
if (var7 != 0) {
var1.setMaterialWithFiller(var3, var4, var5, Material.EMPTY);
}
} else {
Material var9 = var2.getNextMaterial();
if (var9.getBlockId() != var7) {
var1.setMaterialWithFiller(var3, var4, var5, var9);
}
}
}
class="kw">private void smoothBlocksVertical(BrushConfigEditStore var1, BrushConfig var2, int var3, int var4, Sample.Result2D var5) {
if (var5.currentHeight() != -1) {
Material var6 = var5.sampledBlock() > 0 ? Material.block(var5.sampledBlock()) : var2.getNextMaterial();
double var7 = var5.deltaHeight() + this.erosionPreCalc;
int var9 = var5.currentHeight();
if (var7 > 0.35) {
int var10 = Math.max((int)var7, 1);
for (int var11 = 1; var11 <= var10; var11++) {
var1.setMaterialWithFiller(var3, var9 + var11, var4, var6);
}
} else if (var7 < -0.75) {
int var16 = Math.min((int)var7, -1);
for (int var17 = 0; var17 > var16; var17--) {
var1.setMaterialWithFiller(var3, var9 + var17, var4, Material.EMPTY);
}
int var18 = var9 + var16;
var1.setMaterialWithFiller(var3, var18, var4, var6);
int var12 = var3 - this.originX + this.halfBufferWidth;
int var13 = var4 - this.originZ + this.halfBufferWidth;
int var14 = var18 - 1;
while (true) {
int var15 = var14 - this.originY + this.halfBufferHeight;
if (var15 < 0 || var15 >= this.bufferHeight) {
break;
}
if (this.buffer[var12][var15][var13] <= 0) {
var1.setMaterialWithFiller(var3, var14, var4, var6);
}
var14--;
}
} else if (!this.sampleNearby && var6.getBlockId() != var5.originalBlock()) {
var1.setMaterialWithFiller(var3, var9, var4, var6);
}
}
}
class="kw">private class="kw">static int[][][] buildBuffer(BrushConfigEditStore var0, int var1, int var2, int var3, int var4, int var5) {
int[][][] var6 = new int[var4][var5][var4];
Int2IntOpenHashMap var7 = new Int2IntOpenHashMap();
var7.defaultReturnValue(Integer.MIN_VALUE);
int var8 = var4 / 2;
int var9 = var5 / 2;
for (int var10 = 0; var10 < var4; var10++) {
int var11 = var1 - var8 + var10;
for (int var12 = 0; var12 < var4; var12++) {
int var13 = var3 - var8 + var12;
for (int var14 = 0; var14 < var5; var14++) {
int var15 = var2 - var9 + var14;
int var16 = var0.getBlock(var11, var15, var13);
if (var16 != 0) {
int var17 = var7.get(var16);
if (var17 == Integer.MIN_VALUE) {
BlockType var18 = ASSET_MAP.getAsset(var16);
if (var18 == null) {
var17 = -1;
} else {
DrawType var19 = var18.getDrawType();
var17 = var19 != DrawType.Cube && var19 != DrawType.CubeWithModel ? -1 : var16;
}
var7.put(var16, var17);
}
var6[var10][var14][var12] = var17;
}
}
}
}
class="kw">return var6;
}
class="kw">public enum SmoothKernel {
Normal(SculptOperation.NORMAL_KERNEL, SculptOperation.NORMAL_HEIGHTMAP, SculptOperation.NORMAL_FLAT),
Uniform(SculptOperation.UNIFORM_KERNEL, SculptOperation.UNIFORM_HEIGHTMAP, SculptOperation.UNIFORM_FLAT),
Gaussian(SculptOperation.GAUSS_KERNEL, SculptOperation.GAUSS_HEIGHTMAP, SculptOperation.GAUSS_FLAT),
Neighbor(SculptOperation.NEIGHBOUR_KERNEL, SculptOperation.NEIGHBOUR_HEIGHTMAP, SculptOperation.NEIGHBOUR_FLAT),
Square(SculptOperation.SQUARE_KERNEL, SculptOperation.SQUARE_HEIGHTMAP, SculptOperation.SQUARE_FLAT);
class="kw">final SculptOperation.Kernel full;
class="kw">final SculptOperation.Kernel heightmap;
class="kw">final SculptOperation.Kernel flat;
SmoothKernel(SculptOperation.Kernel nullxx, SculptOperation.Kernel nullxxx, SculptOperation.Kernel nullxxxx) {
this.full = nullxx;
this.heightmap = nullxxx;
this.flat = nullxxxx;
}
}
class="kw">public enum SmoothMode {
Full,
Heightmap,
Flat;
SmoothMode() {
}
}
}