SmoothMode enum

Пакет: com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential

Файл: com/hypixel/hytale/builtin/buildertools/scriptedbrushes/operations/sequential/KernelErosionOperation.java

Поля (1)

МодификаторыТипИмя
Full, Heightmap, Flat

Исходный код

Показать/скрыть
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() {
      }
   }
}