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() {
      }
   }
}