SDF, tags registry

This commit is contained in:
paulevsGitch 2020-09-29 00:07:47 +03:00
parent 9ccd0d987b
commit cf8955ea4b
14 changed files with 214 additions and 3 deletions

View file

@ -7,6 +7,7 @@ import ru.betterend.recipe.CraftingRecipes;
import ru.betterend.registry.BiomeRegistry;
import ru.betterend.registry.BlockEntityRegistry;
import ru.betterend.registry.BlockRegistry;
import ru.betterend.registry.BlockTagRegistry;
import ru.betterend.registry.FeatureRegistry;
import ru.betterend.registry.ItemRegistry;
import ru.betterend.util.Logger;
@ -28,5 +29,6 @@ public class BetterEnd implements ModInitializer {
BiomeRegistry.register();
BetterEndBiomeSource.register();
CraftingRecipes.register();
BlockTagRegistry.register();
}
}

View file

@ -5,6 +5,7 @@ import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.tag.Tag;
@Deprecated
@Mixin(targets = "net.minecraft.tag.RequiredTagList$TagWrapper")
public interface TagAccessor<T> {
@Accessor

View file

@ -0,0 +1,21 @@
package ru.betterend.registry;
import net.fabricmc.fabric.api.tag.TagRegistry;
import net.minecraft.block.Block;
import net.minecraft.tag.Tag;
import net.minecraft.tag.Tag.Identified;
import net.minecraft.util.Identifier;
import ru.betterend.BetterEnd;
import ru.betterend.util.TagHelper;
public class BlockTagRegistry {
public static final Tag.Identified<Block> END_GROUND = makeTag("end_ground");
private static Tag.Identified<Block> makeTag(String name) {
return (Identified<Block>) TagRegistry.block(new Identifier(BetterEnd.MOD_ID, name));
}
public static void register() {
TagHelper.addTag(END_GROUND, BlockRegistry.END_MOSS, BlockRegistry.END_MYCELIUM);
}
}

View file

@ -2,10 +2,12 @@ package ru.betterend.registry;
import ru.betterend.world.features.EndFeature;
import ru.betterend.world.features.EndLakeFeature;
import ru.betterend.world.features.MossyGlowshroomFeature;
import ru.betterend.world.features.StoneSpiralFeature;
public class FeatureRegistry {
public static final EndFeature STONE_SPIRAL = new EndFeature("stone_spiral", new StoneSpiralFeature(), 2);
public static final EndFeature MOSSY_GLOWSHROOM = new EndFeature("mossy_glowshroom", new MossyGlowshroomFeature(), 1);
public static final EndFeature END_LAKE = EndFeature.MakeRawGenFeature("end_lake", new EndLakeFeature(), 100);
public static void register() {}

View file

@ -42,6 +42,10 @@ public class BlocksHelper {
public static void setWithoutUpdate(WorldAccess world, BlockPos pos, BlockState state) {
world.setBlockState(pos, state, SET_SILENT);
}
public static void setWithoutUpdate(WorldAccess world, BlockPos pos, Block block) {
world.setBlockState(pos, block.getDefaultState(), SET_SILENT);
}
public static int upRay(WorldAccess world, BlockPos pos, int maxDist) {
int length = 0;

View file

@ -1,5 +1,83 @@
package ru.betterend.util.sdf;
import java.util.Set;
import java.util.function.Function;
import com.google.common.collect.Sets;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
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);
default void fillRecursive(ServerWorldAccess world, BlockPos start, Function<BlockState, Boolean> canReplace, int dx, int dy, int dz) {
Set<BlockPos> blocks = Sets.newHashSet();
Set<BlockPos> ends = Sets.newHashSet();
Set<BlockPos> add = Sets.newHashSet();
ends.add(new BlockPos(0, 0, 0));
boolean run = true;
while (run) {
for (BlockPos center: ends) {
for (Direction dir: Direction.values()) {
BlockPos pos = center.offset(dir);
BlockPos wpos = pos.add(start);
run &= Math.abs(pos.getX()) < dx;
run &= Math.abs(pos.getY()) < dy;
run &= Math.abs(pos.getZ()) < dz;
if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) {
if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) <= 0) {
BlocksHelper.setWithoutUpdate(world, wpos, Blocks.STONE);
add.add(pos);
}
}
}
}
blocks.addAll(ends);
ends.clear();
ends.addAll(add);
add.clear();
run &= !ends.isEmpty();
}
}
default void fillRecursive(ServerWorldAccess world, BlockPos start, Function<BlockState, Boolean> canReplace) {
Set<BlockPos> blocks = Sets.newHashSet();
Set<BlockPos> ends = Sets.newHashSet();
Set<BlockPos> add = Sets.newHashSet();
ends.add(new BlockPos(0, 0, 0));
boolean run = true;
while (run) {
for (BlockPos center: ends) {
for (Direction dir: Direction.values()) {
BlockPos pos = center.offset(dir);
BlockPos wpos = pos.add(start);
if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) {
if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) <= 0) {
BlocksHelper.setWithoutUpdate(world, wpos, Blocks.STONE);
add.add(pos);
}
}
}
}
blocks.addAll(ends);
ends.clear();
ends.addAll(add);
add.clear();
run &= !ends.isEmpty();
}
}
}

View file

@ -0,0 +1,19 @@
package ru.betterend.util.sdf.operator;
public class SDFScale3D extends SDFUnary {
private float x;
private float y;
private float z;
public SDFScale3D setScale(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
return this;
}
@Override
public float getDistance(float x, float y, float z) {
return source.getDistance(x / this.x, y / this.y, z / this.z);
}
}

View file

@ -7,6 +7,6 @@ public class SDFSubtraction extends SDFBinary {
public float getDistance(float x, float y, float z) {
float a = this.sourceA.getDistance(x, y, z);
float b = this.sourceB.getDistance(x, y, z);
return MHelper.max(-a, b);
return MHelper.max(a, -b);
}
}

View file

@ -0,0 +1,19 @@
package ru.betterend.util.sdf.operator;
public class SDFTranslate extends SDFUnary {
float x;
float y;
float z;
public SDFTranslate setTranslate(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
return this;
}
@Override
public float getDistance(float x, float y, float z) {
return source.getDistance(x - this.x, y - this.y, z - this.z);
}
}

View file

@ -20,6 +20,6 @@ public class SDFCapsule implements ISDF {
@Override
public float getDistance(float x, float y, float z) {
return MHelper.length(x, MathHelper.clamp(y, 0F, height), z) - radius;
return MHelper.length(x, MathHelper.clamp(y, -height, 0), z) - radius;
}
}

View file

@ -12,6 +12,6 @@ public class BiomeFoggyMushroomland extends EndBiome {
.setWaterFogColor(119, 227, 250)
.setSurface(BlockRegistry.END_MOSS, BlockRegistry.END_MYCELIUM)
.addFeature(FeatureRegistry.END_LAKE)
.addFeature(FeatureRegistry.STONE_SPIRAL));
.addFeature(FeatureRegistry.MOSSY_GLOWSHROOM));
}
}

View file

@ -0,0 +1,58 @@
package ru.betterend.world.features;
import java.util.Random;
import java.util.function.Function;
import net.minecraft.block.BlockState;
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.BlockTagRegistry;
import ru.betterend.util.sdf.ISDF;
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.primitive.SDFCapsule;
import ru.betterend.util.sdf.primitive.SDFSphere;
public class MossyGlowshroomFeature extends DefaultFeature {
private static final Function<BlockState, Boolean> REPLACE;
private static final ISDF FUNCTION;
@Override
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, DefaultFeatureConfig featureConfig) {
blockPos = getTopPos(world, blockPos);
if (blockPos.getY() < 5) {
return false;
}
if (!world.getBlockState(blockPos.down()).isIn(BlockTagRegistry.END_GROUND)) {
return false;
}
FUNCTION.fillRecursive(world, getTopPos(world, blockPos), REPLACE, 10, 20, 10);
return true;
}
static {
SDFCapsule capsule = new SDFCapsule().setRadius(1.7F).setHeight(5);
SDFSphere outerSphere = new SDFSphere().setRadius(10);
SDFSphere innerSphere = new SDFSphere().setRadius(30);
ISDF scaled1 = new SDFScale3D().setScale(1, 0.3F, 1).setSource(outerSphere);
ISDF scaled2 = new SDFScale3D().setScale(1, 0.3F, 1).setSource(innerSphere);
SDFTranslate sphereOffset = new SDFTranslate().setTranslate(0, -10F, 0);
ISDF head = new SDFSubtraction().setSourceA(scaled1).setSourceB(sphereOffset.setSource(scaled2));
SDFTranslate headOffset = new SDFTranslate().setTranslate(0, 10, 0);
//FUNCTION = new SDFSmoothUnion().setRadius(3).setSourceA(capsule).setSourceB(headOffset.setSource(head));
FUNCTION = headOffset.setSource(head);
REPLACE = (state) -> {
return state.getMaterial().isReplaceable();
};
}
}

View file

@ -22,6 +22,7 @@ public class BiomeMap
public BiomeMap(long seed, int size, BiomePicker picker)
{
MAPS.clear();
RANDOM.setSeed(seed);
noiseX = new OpenSimplexNoise(RANDOM.nextLong());
noiseZ = new OpenSimplexNoise(RANDOM.nextLong());

View file

@ -0,0 +1,6 @@
{
"replace": "false",
"values": [
"minecraft:end_stone"
]
}