SDF materials
This commit is contained in:
parent
2e632bf245
commit
257307d93d
14 changed files with 107 additions and 15 deletions
|
@ -6,15 +6,15 @@ import java.util.function.Function;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.world.ServerWorldAccess;
|
import net.minecraft.world.ServerWorldAccess;
|
||||||
import ru.betterend.util.BlocksHelper;
|
|
||||||
|
|
||||||
public interface ISDF {
|
public interface ISDF {
|
||||||
public float getDistance(float x, float y, float z);
|
public float getDistance(float x, float y, float z);
|
||||||
|
|
||||||
|
public void setBlock(ServerWorldAccess world, BlockPos pos);
|
||||||
|
|
||||||
default void fillRecursive(ServerWorldAccess world, BlockPos start, Function<BlockState, Boolean> canReplace, int dx, int dy, int dz) {
|
default void fillRecursive(ServerWorldAccess world, BlockPos start, Function<BlockState, Boolean> canReplace, int dx, int dy, int dz) {
|
||||||
Set<BlockPos> blocks = Sets.newHashSet();
|
Set<BlockPos> blocks = Sets.newHashSet();
|
||||||
Set<BlockPos> ends = Sets.newHashSet();
|
Set<BlockPos> ends = Sets.newHashSet();
|
||||||
|
@ -34,8 +34,10 @@ public interface ISDF {
|
||||||
|
|
||||||
if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) {
|
if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) {
|
||||||
if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) < 0) {
|
if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) < 0) {
|
||||||
BlocksHelper.setWithoutUpdate(world, wpos, Blocks.STONE);
|
setBlock(world, wpos);
|
||||||
add.add(pos);
|
if (Math.abs(pos.getX()) < dx && Math.abs(pos.getY()) < dy && Math.abs(pos.getZ()) < dz) {
|
||||||
|
add.add(pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +67,7 @@ public interface ISDF {
|
||||||
|
|
||||||
if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) {
|
if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) {
|
||||||
if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) <= 0) {
|
if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) <= 0) {
|
||||||
BlocksHelper.setWithoutUpdate(world, wpos, Blocks.STONE);
|
setBlock(world, wpos);
|
||||||
add.add(pos);
|
add.add(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package ru.betterend.util.sdf.operator;
|
package ru.betterend.util.sdf.operator;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.ServerWorldAccess;
|
||||||
import ru.betterend.util.sdf.ISDF;
|
import ru.betterend.util.sdf.ISDF;
|
||||||
|
|
||||||
public abstract class SDFBinary implements ISDF {
|
public abstract class SDFBinary implements ISDF {
|
||||||
protected ISDF sourceA;
|
protected ISDF sourceA;
|
||||||
protected ISDF sourceB;
|
protected ISDF sourceB;
|
||||||
|
protected boolean firstValue;
|
||||||
|
|
||||||
public SDFBinary setSourceA(ISDF sourceA) {
|
public SDFBinary setSourceA(ISDF sourceA) {
|
||||||
this.sourceA = sourceA;
|
this.sourceA = sourceA;
|
||||||
|
@ -15,4 +18,17 @@ public abstract class SDFBinary implements ISDF {
|
||||||
this.sourceB = sourceB;
|
this.sourceB = sourceB;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void selectValue(float a, float b) {
|
||||||
|
firstValue = a < b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlock(ServerWorldAccess world, BlockPos pos) {
|
||||||
|
if (firstValue) {
|
||||||
|
sourceA.setBlock(world, pos);
|
||||||
|
} else {
|
||||||
|
sourceB.setBlock(world, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ public class SDFIntersection extends SDFBinary {
|
||||||
public float getDistance(float x, float y, float z) {
|
public float getDistance(float x, float y, float z) {
|
||||||
float a = this.sourceA.getDistance(x, y, z);
|
float a = this.sourceA.getDistance(x, y, z);
|
||||||
float b = this.sourceB.getDistance(x, y, z);
|
float b = this.sourceB.getDistance(x, y, z);
|
||||||
|
this.selectValue(a, b);
|
||||||
return MHelper.max(a, b);
|
return MHelper.max(a, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ public class SDFSmoothIntersection extends SDFBinary {
|
||||||
public float getDistance(float x, float y, float z) {
|
public float getDistance(float x, float y, float z) {
|
||||||
float a = this.sourceA.getDistance(x, y, z);
|
float a = this.sourceA.getDistance(x, y, z);
|
||||||
float b = this.sourceB.getDistance(x, y, z);
|
float b = this.sourceB.getDistance(x, y, z);
|
||||||
|
this.selectValue(a, b);
|
||||||
float h = MathHelper.clamp(0.5F - 0.5F * (b - a) / radius, 0F, 1F);
|
float h = MathHelper.clamp(0.5F - 0.5F * (b - a) / radius, 0F, 1F);
|
||||||
return MathHelper.lerp(h, b, a) + radius * h * (1F - h);
|
return MathHelper.lerp(h, b, a) + radius * h * (1F - h);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ public class SDFSmoothSubtraction extends SDFBinary {
|
||||||
public float getDistance(float x, float y, float z) {
|
public float getDistance(float x, float y, float z) {
|
||||||
float a = this.sourceA.getDistance(x, y, z);
|
float a = this.sourceA.getDistance(x, y, z);
|
||||||
float b = this.sourceB.getDistance(x, y, z);
|
float b = this.sourceB.getDistance(x, y, z);
|
||||||
|
this.selectValue(a, b);
|
||||||
float h = MathHelper.clamp(0.5F - 0.5F * (b + a) / radius, 0F, 1F);
|
float h = MathHelper.clamp(0.5F - 0.5F * (b + a) / radius, 0F, 1F);
|
||||||
return MathHelper.lerp(h, b, -a) + radius * h * (1F - h);
|
return MathHelper.lerp(h, b, -a) + radius * h * (1F - h);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ public class SDFSmoothUnion extends SDFBinary {
|
||||||
public float getDistance(float x, float y, float z) {
|
public float getDistance(float x, float y, float z) {
|
||||||
float a = this.sourceA.getDistance(x, y, z);
|
float a = this.sourceA.getDistance(x, y, z);
|
||||||
float b = this.sourceB.getDistance(x, y, z);
|
float b = this.sourceB.getDistance(x, y, z);
|
||||||
|
this.selectValue(a, b);
|
||||||
float h = MathHelper.clamp(0.5F + 0.5F * (b - a) / radius, 0F, 1F);
|
float h = MathHelper.clamp(0.5F + 0.5F * (b - a) / radius, 0F, 1F);
|
||||||
return MathHelper.lerp(h, b, a) - radius * h * (1F - h);
|
return MathHelper.lerp(h, b, a) - radius * h * (1F - h);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ public class SDFSubtraction extends SDFBinary {
|
||||||
public float getDistance(float x, float y, float z) {
|
public float getDistance(float x, float y, float z) {
|
||||||
float a = this.sourceA.getDistance(x, y, z);
|
float a = this.sourceA.getDistance(x, y, z);
|
||||||
float b = this.sourceB.getDistance(x, y, z);
|
float b = this.sourceB.getDistance(x, y, z);
|
||||||
|
this.selectValue(a, b);
|
||||||
return MHelper.max(a, -b);
|
return MHelper.max(a, -b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ru.betterend.util.sdf.operator;
|
package ru.betterend.util.sdf.operator;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.ServerWorldAccess;
|
||||||
import ru.betterend.util.sdf.ISDF;
|
import ru.betterend.util.sdf.ISDF;
|
||||||
|
|
||||||
public abstract class SDFUnary implements ISDF {
|
public abstract class SDFUnary implements ISDF {
|
||||||
|
@ -9,4 +11,9 @@ public abstract class SDFUnary implements ISDF {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlock(ServerWorldAccess world, BlockPos pos) {
|
||||||
|
source.setBlock(world, pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ public class SDFUnion extends SDFBinary {
|
||||||
public float getDistance(float x, float y, float z) {
|
public float getDistance(float x, float y, float z) {
|
||||||
float a = this.sourceA.getDistance(x, y, z);
|
float a = this.sourceA.getDistance(x, y, z);
|
||||||
float b = this.sourceB.getDistance(x, y, z);
|
float b = this.sourceB.getDistance(x, y, z);
|
||||||
|
this.selectValue(a, b);
|
||||||
return MHelper.min(a, b);
|
return MHelper.min(a, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,24 @@
|
||||||
package ru.betterend.util.sdf.primitive;
|
package ru.betterend.util.sdf.primitive;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import ru.betterend.util.MHelper;
|
import ru.betterend.util.MHelper;
|
||||||
import ru.betterend.util.sdf.ISDF;
|
|
||||||
|
|
||||||
public class SDFCapsule implements ISDF {
|
public class SDFCapsule extends SDFPrimitive {
|
||||||
private float radius;
|
private float radius;
|
||||||
private float height;
|
private float height;
|
||||||
|
|
||||||
|
public SDFCapsule(Function<BlockPos, BlockState> placerFunction) {
|
||||||
|
super(placerFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SDFCapsule(BlockState state) {
|
||||||
|
super(state);
|
||||||
|
}
|
||||||
|
|
||||||
public SDFCapsule setRadius(float radius) {
|
public SDFCapsule setRadius(float radius) {
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package ru.betterend.util.sdf.primitive;
|
package ru.betterend.util.sdf.primitive;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import ru.betterend.util.MHelper;
|
import ru.betterend.util.MHelper;
|
||||||
import ru.betterend.util.sdf.ISDF;
|
|
||||||
|
|
||||||
public class SDFLine implements ISDF {
|
public class SDFLine extends SDFPrimitive {
|
||||||
private float radius;
|
private float radius;
|
||||||
private float x1;
|
private float x1;
|
||||||
private float y1;
|
private float y1;
|
||||||
|
@ -13,6 +16,14 @@ public class SDFLine implements ISDF {
|
||||||
private float y2;
|
private float y2;
|
||||||
private float z2;
|
private float z2;
|
||||||
|
|
||||||
|
public SDFLine(Function<BlockPos, BlockState> placerFunction) {
|
||||||
|
super(placerFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SDFLine(BlockState state) {
|
||||||
|
super(state);
|
||||||
|
}
|
||||||
|
|
||||||
public SDFLine setRadius(float radius) {
|
public SDFLine setRadius(float radius) {
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package ru.betterend.util.sdf.primitive;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
public abstract class SDFPrimitive implements ISDF {
|
||||||
|
protected final Function<BlockPos, BlockState> placerFunction;
|
||||||
|
|
||||||
|
public SDFPrimitive(Function<BlockPos, BlockState> placerFunction) {
|
||||||
|
this.placerFunction = placerFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SDFPrimitive(BlockState state) {
|
||||||
|
this.placerFunction = (pos) -> {
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlock(ServerWorldAccess world, BlockPos pos) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, pos, placerFunction.apply(pos));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,22 @@
|
||||||
package ru.betterend.util.sdf.primitive;
|
package ru.betterend.util.sdf.primitive;
|
||||||
|
|
||||||
import ru.betterend.util.MHelper;
|
import java.util.function.Function;
|
||||||
import ru.betterend.util.sdf.ISDF;
|
|
||||||
|
|
||||||
public class SDFSphere implements ISDF {
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import ru.betterend.util.MHelper;
|
||||||
|
|
||||||
|
public class SDFSphere extends SDFPrimitive {
|
||||||
private float radius;
|
private float radius;
|
||||||
|
|
||||||
|
public SDFSphere(Function<BlockPos, BlockState> placerFunction) {
|
||||||
|
super(placerFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SDFSphere(BlockState state) {
|
||||||
|
super(state);
|
||||||
|
}
|
||||||
|
|
||||||
public SDFSphere setRadius(float radius) {
|
public SDFSphere setRadius(float radius) {
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Random;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.StructureWorldAccess;
|
import net.minecraft.world.StructureWorldAccess;
|
||||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||||
|
@ -36,10 +37,10 @@ public class MossyGlowshroomFeature extends DefaultFeature {
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
SDFLine stem = new SDFLine().setRadius(2F).setEnd(0, 15, 0);
|
SDFLine stem = new SDFLine(Blocks.GOLD_BLOCK.getDefaultState()).setRadius(2F).setEnd(0, 15, 0);
|
||||||
|
|
||||||
SDFSphere outerSphere = new SDFSphere().setRadius(10);
|
SDFSphere outerSphere = new SDFSphere(Blocks.REDSTONE_BLOCK.getDefaultState()).setRadius(10);
|
||||||
SDFSphere innerSphere = new SDFSphere().setRadius(10);
|
SDFSphere innerSphere = new SDFSphere(Blocks.DIAMOND_BLOCK.getDefaultState()).setRadius(10);
|
||||||
|
|
||||||
SDFTranslate sphereOffset = new SDFTranslate().setTranslate(0, -10F, 0);
|
SDFTranslate sphereOffset = new SDFTranslate().setTranslate(0, -10F, 0);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue