From 8dab7c11798c2fdcac55600898b7622757e99bf4 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Tue, 29 Sep 2020 15:42:48 +0300 Subject: [PATCH] SDF post process --- .../blocks/complex/WoodenMaterial.java | 14 +++-- .../java/ru/betterend/util/SplineHelper.java | 6 +- .../java/ru/betterend/util/sdf/PosInfo.java | 59 +++++++++++++++++++ .../util/sdf/{ISDF.java => SDF.java} | 41 ++++++++++--- .../util/sdf/operator/SDFBinary.java | 20 +++---- .../betterend/util/sdf/operator/SDFUnary.java | 14 ++--- .../util/sdf/primitive/SDFPrimitive.java | 10 ++-- .../features/MossyGlowshroomFeature.java | 27 +++++---- 8 files changed, 141 insertions(+), 50 deletions(-) create mode 100644 src/main/java/ru/betterend/util/sdf/PosInfo.java rename src/main/java/ru/betterend/util/sdf/{ISDF.java => SDF.java} (56%) diff --git a/src/main/java/ru/betterend/blocks/complex/WoodenMaterial.java b/src/main/java/ru/betterend/blocks/complex/WoodenMaterial.java index b3b14ec0..603f9076 100644 --- a/src/main/java/ru/betterend/blocks/complex/WoodenMaterial.java +++ b/src/main/java/ru/betterend/blocks/complex/WoodenMaterial.java @@ -3,6 +3,7 @@ package ru.betterend.blocks.complex; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; import net.minecraft.block.Block; +import net.minecraft.block.BlockState; import net.minecraft.block.Material; import net.minecraft.block.MaterialColor; import net.minecraft.item.Items; @@ -29,8 +30,7 @@ import ru.betterend.recipe.RecipeBuilder; import ru.betterend.registry.BlockRegistry; import ru.betterend.util.TagHelper; -public class WoodenMaterial -{ +public class WoodenMaterial { public final Block log; public final Block bark; @@ -55,8 +55,7 @@ public class WoodenMaterial public final Block chest; public final Block barrel; - public WoodenMaterial(String name, MaterialColor woodColor, MaterialColor planksColor) - { + public WoodenMaterial(String name, MaterialColor woodColor, MaterialColor planksColor) { FabricBlockSettings materialPlanks = FabricBlockSettings.of(Material.WOOD).sounds(BlockSoundGroup.WOOD).breakByTool(FabricToolTags.AXES).materialColor(planksColor); log_striped = BlockRegistry.registerBlock(name + "_striped_log", new BlockPillar(materialPlanks)); @@ -125,8 +124,11 @@ public class WoodenMaterial TagHelper.addTags(trapdoor, BlockTags.WOODEN_TRAPDOORS, BlockTags.TRAPDOORS); } - public boolean isTreeLog(Block block) - { + public boolean isTreeLog(Block block) { return block == log || block == bark; } + + public boolean isTreeLog(BlockState state) { + return isTreeLog(state.getBlock()); + } } \ No newline at end of file diff --git a/src/main/java/ru/betterend/util/SplineHelper.java b/src/main/java/ru/betterend/util/SplineHelper.java index 8fbedeb0..edc98d30 100644 --- a/src/main/java/ru/betterend/util/SplineHelper.java +++ b/src/main/java/ru/betterend/util/SplineHelper.java @@ -10,7 +10,7 @@ import net.minecraft.block.BlockState; import net.minecraft.client.util.math.Vector3f; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -import ru.betterend.util.sdf.ISDF; +import ru.betterend.util.sdf.SDF; import ru.betterend.util.sdf.operator.SDFUnion; import ru.betterend.util.sdf.primitive.SDFLine; @@ -41,10 +41,10 @@ public class SplineHelper { } } - public static ISDF buildSDF(List spline, float radius1, float radius2, Function placerFunction) { + public static SDF buildSDF(List spline, float radius1, float radius2, Function placerFunction) { int count = spline.size(); float max = count - 2; - ISDF result = null; + SDF result = null; Vector3f start = spline.get(0); for (int i = 1; i < count; i++) { Vector3f pos = spline.get(i); diff --git a/src/main/java/ru/betterend/util/sdf/PosInfo.java b/src/main/java/ru/betterend/util/sdf/PosInfo.java new file mode 100644 index 00000000..1466aa9a --- /dev/null +++ b/src/main/java/ru/betterend/util/sdf/PosInfo.java @@ -0,0 +1,59 @@ +package ru.betterend.util.sdf; + +import java.util.Map; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.util.math.BlockPos; + +public class PosInfo { + private static final BlockState AIR = Blocks.AIR.getDefaultState(); + private final Map blocks; + private final BlockPos pos; + private BlockState state; + + public static PosInfo create(Map blocks, BlockPos pos) { + return new PosInfo(blocks, pos); + } + + private PosInfo(Map blocks, BlockPos pos) { + this.blocks = blocks; + this.pos = pos; + blocks.put(pos, this); + } + + public BlockState getState() { + return state; + } + + public void setState(BlockState state) { + this.state = state; + } + + public BlockState getStateUp() { + PosInfo info = blocks.get(pos.up()); + if (info == null) { + return AIR; + } + return info.getState(); + } + + public BlockState getStateDown() { + PosInfo info = blocks.get(pos.down()); + if (info == null) { + return AIR; + } + return info.getState(); + } + + public int hashCode() { + return pos.hashCode(); + } + + public boolean equals(Object obj) { + if (!(obj instanceof PosInfo)) { + return false; + } + return pos.equals(((PosInfo) obj).pos); + } +} diff --git a/src/main/java/ru/betterend/util/sdf/ISDF.java b/src/main/java/ru/betterend/util/sdf/SDF.java similarity index 56% rename from src/main/java/ru/betterend/util/sdf/ISDF.java rename to src/main/java/ru/betterend/util/sdf/SDF.java index 8d4d9997..899c2782 100644 --- a/src/main/java/ru/betterend/util/sdf/ISDF.java +++ b/src/main/java/ru/betterend/util/sdf/SDF.java @@ -1,25 +1,39 @@ package ru.betterend.util.sdf; +import java.util.Map; import java.util.Set; import java.util.function.Function; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.ServerWorldAccess; +import ru.betterend.util.BlocksHelper; -public interface ISDF { - public float getDistance(float x, float y, float z); +public abstract class SDF { + private Function postProcess = (info) -> { + return info.getState(); + }; + + public abstract float getDistance(float x, float y, float z); - public void setBlock(ServerWorldAccess world, BlockPos pos); + public abstract BlockState getBlockState(BlockPos pos); - default void fillRecursive(ServerWorldAccess world, BlockPos start, Function canReplace, int dx, int dy, int dz) { + public SDF setPostProcess(Function postProcess) { + this.postProcess = postProcess; + return this; + } + + public void fillRecursive(ServerWorldAccess world, BlockPos start, Function canReplace, int dx, int dy, int dz) { + Map mapWorld = Maps.newHashMap(); Set blocks = Sets.newHashSet(); Set ends = Sets.newHashSet(); Set add = Sets.newHashSet(); ends.add(new BlockPos(0, 0, 0)); + boolean process = postProcess != null; boolean run = true; while (run) { @@ -34,7 +48,8 @@ public interface ISDF { if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) { if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) < 0) { - setBlock(world, wpos); + BlockState state = getBlockState(wpos); + PosInfo.create(mapWorld, wpos).setState(state); if (Math.abs(pos.getX()) < dx && Math.abs(pos.getY()) < dy && Math.abs(pos.getZ()) < dz) { add.add(pos); } @@ -50,9 +65,15 @@ public interface ISDF { run &= !ends.isEmpty(); } + + mapWorld.forEach((pos, info) -> { + BlockState state = postProcess.apply(info); + BlocksHelper.setWithoutUpdate(world, pos, state); + }); } - default void fillRecursive(ServerWorldAccess world, BlockPos start, Function canReplace) { + public void fillRecursive(ServerWorldAccess world, BlockPos start, Function canReplace) { + Map mapWorld = Maps.newHashMap(); Set blocks = Sets.newHashSet(); Set ends = Sets.newHashSet(); Set add = Sets.newHashSet(); @@ -67,7 +88,8 @@ public interface ISDF { if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) { if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) <= 0) { - setBlock(world, wpos); + BlockState state = getBlockState(wpos); + PosInfo.create(mapWorld, wpos).setState(state); add.add(pos); } } @@ -81,5 +103,10 @@ public interface ISDF { run &= !ends.isEmpty(); } + + mapWorld.forEach((pos, info) -> { + BlockState state = postProcess.apply(info); + BlocksHelper.setWithoutUpdate(world, pos, state); + }); } } diff --git a/src/main/java/ru/betterend/util/sdf/operator/SDFBinary.java b/src/main/java/ru/betterend/util/sdf/operator/SDFBinary.java index 90831a8a..4c8fd72f 100644 --- a/src/main/java/ru/betterend/util/sdf/operator/SDFBinary.java +++ b/src/main/java/ru/betterend/util/sdf/operator/SDFBinary.java @@ -1,20 +1,20 @@ package ru.betterend.util.sdf.operator; +import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.ServerWorldAccess; -import ru.betterend.util.sdf.ISDF; +import ru.betterend.util.sdf.SDF; -public abstract class SDFBinary implements ISDF { - protected ISDF sourceA; - protected ISDF sourceB; +public abstract class SDFBinary extends SDF { + protected SDF sourceA; + protected SDF sourceB; protected boolean firstValue; - public SDFBinary setSourceA(ISDF sourceA) { + public SDFBinary setSourceA(SDF sourceA) { this.sourceA = sourceA; return this; } - public SDFBinary setSourceB(ISDF sourceB) { + public SDFBinary setSourceB(SDF sourceB) { this.sourceB = sourceB; return this; } @@ -24,11 +24,11 @@ public abstract class SDFBinary implements ISDF { } @Override - public void setBlock(ServerWorldAccess world, BlockPos pos) { + public BlockState getBlockState(BlockPos pos) { if (firstValue) { - sourceA.setBlock(world, pos); + return sourceA.getBlockState(pos); } else { - sourceB.setBlock(world, pos); + return sourceB.getBlockState(pos); } } } diff --git a/src/main/java/ru/betterend/util/sdf/operator/SDFUnary.java b/src/main/java/ru/betterend/util/sdf/operator/SDFUnary.java index 16910da1..83ea8cc4 100644 --- a/src/main/java/ru/betterend/util/sdf/operator/SDFUnary.java +++ b/src/main/java/ru/betterend/util/sdf/operator/SDFUnary.java @@ -1,19 +1,19 @@ package ru.betterend.util.sdf.operator; +import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.ServerWorldAccess; -import ru.betterend.util.sdf.ISDF; +import ru.betterend.util.sdf.SDF; -public abstract class SDFUnary implements ISDF { - protected ISDF source; +public abstract class SDFUnary extends SDF { + protected SDF source; - public SDFUnary setSource(ISDF source) { + public SDFUnary setSource(SDF source) { this.source = source; return this; } @Override - public void setBlock(ServerWorldAccess world, BlockPos pos) { - source.setBlock(world, pos); + public BlockState getBlockState(BlockPos pos) { + return source.getBlockState(pos); } } diff --git a/src/main/java/ru/betterend/util/sdf/primitive/SDFPrimitive.java b/src/main/java/ru/betterend/util/sdf/primitive/SDFPrimitive.java index 44c8e39e..9038f3fd 100644 --- a/src/main/java/ru/betterend/util/sdf/primitive/SDFPrimitive.java +++ b/src/main/java/ru/betterend/util/sdf/primitive/SDFPrimitive.java @@ -4,11 +4,9 @@ import java.util.function.Function; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.ServerWorldAccess; -import ru.betterend.util.BlocksHelper; -import ru.betterend.util.sdf.ISDF; +import ru.betterend.util.sdf.SDF; -public abstract class SDFPrimitive implements ISDF { +public abstract class SDFPrimitive extends SDF { protected final Function placerFunction; public SDFPrimitive(Function placerFunction) { @@ -21,7 +19,7 @@ public abstract class SDFPrimitive implements ISDF { }; } - public void setBlock(ServerWorldAccess world, BlockPos pos) { - BlocksHelper.setWithoutUpdate(world, pos, placerFunction.apply(pos)); + public BlockState getBlockState(BlockPos pos) { + return placerFunction.apply(pos); } } diff --git a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java index dd256622..04ac9a22 100644 --- a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java +++ b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java @@ -11,22 +11,16 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.gen.chunk.ChunkGenerator; import net.minecraft.world.gen.feature.DefaultFeatureConfig; +import ru.betterend.registry.BlockRegistry; import ru.betterend.registry.BlockTagRegistry; import ru.betterend.util.MHelper; import ru.betterend.util.SplineHelper; -import ru.betterend.util.sdf.ISDF; -import ru.betterend.util.sdf.operator.SDFFlatWave; -import ru.betterend.util.sdf.operator.SDFScale3D; -import ru.betterend.util.sdf.operator.SDFSmoothUnion; -import ru.betterend.util.sdf.operator.SDFSubtraction; -import ru.betterend.util.sdf.operator.SDFTranslate; +import ru.betterend.util.sdf.SDF; import ru.betterend.util.sdf.primitive.SDFCapedCone; -import ru.betterend.util.sdf.primitive.SDFLine; -import ru.betterend.util.sdf.primitive.SDFSphere; public class MossyGlowshroomFeature extends DefaultFeature { private static final Function REPLACE; - private static final ISDF FUNCTION; + private static final SDF FUNCTION; @Override public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, DefaultFeatureConfig featureConfig) { @@ -43,8 +37,19 @@ public class MossyGlowshroomFeature extends DefaultFeature { int count = MHelper.floor(height / 4); List spline = SplineHelper.makeSpline(0, 0, 0, 0, height, 0, count); SplineHelper.offsetParts(spline, random, 1F, 0, 1F); - ISDF sdf = SplineHelper.buildSDF(spline, 2.1F, 1.5F, (pos) -> { - return Blocks.DIAMOND_BLOCK.getDefaultState(); + SDF sdf = SplineHelper.buildSDF(spline, 2.1F, 1.5F, (pos) -> { + return BlockRegistry.MOSSY_GLOWSHROOM.log.getDefaultState(); + }); + sdf.setPostProcess((info) -> { + if (!BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateUp())) { + return BlockRegistry.MOSSY_GLOWSHROOM.bark.getDefaultState(); + } + else if (!BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown())) { + return BlockRegistry.MOSSY_GLOWSHROOM.bark.getDefaultState(); + } + else { + return info.getState(); + } }); sdf.fillRecursive(world, blockPos, REPLACE);