Finished tree shape
This commit is contained in:
parent
418f048ed3
commit
34318e283b
19 changed files with 120 additions and 137 deletions
|
@ -61,7 +61,7 @@ public class BigEtherTreeFeature extends DefaultFeature {
|
||||||
|
|
||||||
sdf.setReplaceFunction((state) -> {
|
sdf.setReplaceFunction((state) -> {
|
||||||
return state.isIn(EndTags.END_GROUND) || state.getMaterial().equals(Material.PLANT) || state.getMaterial().isReplaceable();
|
return state.isIn(EndTags.END_GROUND) || state.getMaterial().equals(Material.PLANT) || state.getMaterial().isReplaceable();
|
||||||
}).setPostProcess((info) -> {
|
}).addPostProcess((info) -> {
|
||||||
if (info.getState().equals(log) && (!info.getStateUp().equals(log) || !info.getStateDown().equals(log))) {
|
if (info.getState().equals(log) && (!info.getStateUp().equals(log) || !info.getStateDown().equals(log))) {
|
||||||
return wood;
|
return wood;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,18 @@ import net.minecraft.block.Material;
|
||||||
import net.minecraft.client.util.math.Vector3f;
|
import net.minecraft.client.util.math.Vector3f;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.BlockPos.Mutable;
|
import net.minecraft.util.math.BlockPos.Mutable;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.world.StructureWorldAccess;
|
import net.minecraft.world.StructureWorldAccess;
|
||||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||||
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
||||||
import ru.betterend.integration.Integrations;
|
import ru.betterend.integration.Integrations;
|
||||||
import ru.betterend.registry.EndTags;
|
import ru.betterend.registry.EndTags;
|
||||||
|
import ru.betterend.util.BlocksHelper;
|
||||||
import ru.betterend.util.MHelper;
|
import ru.betterend.util.MHelper;
|
||||||
import ru.betterend.util.SplineHelper;
|
import ru.betterend.util.SplineHelper;
|
||||||
import ru.betterend.util.sdf.PosInfo;
|
import ru.betterend.util.sdf.PosInfo;
|
||||||
import ru.betterend.util.sdf.SDF;
|
import ru.betterend.util.sdf.SDF;
|
||||||
|
import ru.betterend.util.sdf.operator.SDFDisplacement;
|
||||||
import ru.betterend.util.sdf.operator.SDFFlatWave;
|
import ru.betterend.util.sdf.operator.SDFFlatWave;
|
||||||
import ru.betterend.util.sdf.operator.SDFSmoothUnion;
|
import ru.betterend.util.sdf.operator.SDFSmoothUnion;
|
||||||
import ru.betterend.util.sdf.primitive.SDFCappedCone;
|
import ru.betterend.util.sdf.primitive.SDFCappedCone;
|
||||||
|
@ -38,7 +41,7 @@ public class NightshadeRedwoodTreeFeature extends DefaultFeature {
|
||||||
BlockState log = Integrations.BYG.getDefaultState("nightshade_log");
|
BlockState log = Integrations.BYG.getDefaultState("nightshade_log");
|
||||||
BlockState wood = Integrations.BYG.getDefaultState("nightshade_wood");
|
BlockState wood = Integrations.BYG.getDefaultState("nightshade_wood");
|
||||||
BlockState leaves = Integrations.BYG.getDefaultState("nightshade_leaves");
|
BlockState leaves = Integrations.BYG.getDefaultState("nightshade_leaves");
|
||||||
//BlockState leaves_flower = Integrations.BYG.getDefaultState("flowering_nightshade_leaves");
|
BlockState leaves_flower = Integrations.BYG.getDefaultState("flowering_nightshade_leaves");
|
||||||
|
|
||||||
Function<BlockPos, BlockState> splinePlacer = (bpos) -> { return log; };
|
Function<BlockPos, BlockState> splinePlacer = (bpos) -> { return log; };
|
||||||
Function<BlockState, Boolean> replace = (state) -> {
|
Function<BlockState, Boolean> replace = (state) -> {
|
||||||
|
@ -66,7 +69,6 @@ public class NightshadeRedwoodTreeFeature extends DefaultFeature {
|
||||||
float start = trunk.size() / 3F;
|
float start = trunk.size() / 3F;
|
||||||
float delta = trunk.size() * 0.6F;
|
float delta = trunk.size() * 0.6F;
|
||||||
float max = height - 7;
|
float max = height - 7;
|
||||||
//SDF leavesSDF = null;
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
float scale = (float) (count - i) / count * 15;
|
float scale = (float) (count - i) / count * 15;
|
||||||
Vector3f offset = SplineHelper.getPos(trunk, (float) i / count * delta + start);
|
Vector3f offset = SplineHelper.getPos(trunk, (float) i / count * delta + start);
|
||||||
|
@ -79,41 +81,43 @@ public class NightshadeRedwoodTreeFeature extends DefaultFeature {
|
||||||
SplineHelper.offsetParts(branch, random, 0.3F, 0.3F, 0.3F);
|
SplineHelper.offsetParts(branch, random, 0.3F, 0.3F, 0.3F);
|
||||||
SplineHelper.offset(branch, offset);
|
SplineHelper.offset(branch, offset);
|
||||||
SplineHelper.fillSpline(branch, world, wood, pos, replace);
|
SplineHelper.fillSpline(branch, world, wood, pos, replace);
|
||||||
|
|
||||||
/*SDF leaf = null;
|
|
||||||
for (int j = 2; j < 5; j++) {
|
|
||||||
Vector3f point = branch.get(j);
|
|
||||||
float radius = (float) (j - 2) / 3F;
|
|
||||||
radius = (1F - radius) * 3F;
|
|
||||||
SDF sphere = new SDFSphere().setRadius(radius).setBlock(leaves);
|
|
||||||
sphere = new SDFTranslate().setTranslate(point.getX(), point.getY(), point.getZ()).setSource(sphere);
|
|
||||||
leaf = leaf == null ? sphere : new SDFUnion().setSourceA(leaf).setSourceB(leaf);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*SDF leaf = SplineHelper.buildSDF(branch, (del) -> {
|
|
||||||
float radius = 1 - del;
|
|
||||||
radius = radius * radius * 2 - 1;
|
|
||||||
radius *= radius;
|
|
||||||
radius = (1 - radius) * 2;
|
|
||||||
return radius;
|
|
||||||
}, (bpos) -> {
|
|
||||||
return leaves;
|
|
||||||
});*/
|
|
||||||
//leavesSDF = leavesSDF == null ? leaf : new SDFUnion().setSourceA(leavesSDF).setSourceB(leaf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDF sdf = SplineHelper.buildSDF(trunk, 2.3F, 0.8F, splinePlacer);
|
SDF sdf = SplineHelper.buildSDF(trunk, 2.3F, 0.8F, splinePlacer);
|
||||||
SDF roots = new SDFSphere().setRadius(2F).setBlock(log);
|
SDF roots = new SDFSphere().setRadius(2F).setBlock(log);
|
||||||
roots = new SDFFlatWave().setIntensity(2F).setRaysCount(MHelper.randRange(5, 7, random)).setAngle(random.nextFloat() * MHelper.PI2).setSource(roots);
|
roots = new SDFFlatWave().setIntensity(2F).setRaysCount(MHelper.randRange(5, 7, random)).setAngle(random.nextFloat() * MHelper.PI2).setSource(roots);
|
||||||
sdf = new SDFSmoothUnion().setRadius(2F).setSourceA(sdf).setSourceB(roots);
|
sdf = new SDFSmoothUnion().setRadius(2F).setSourceA(sdf).setSourceB(roots);
|
||||||
sdf.setReplaceFunction(replace).setPostProcess(post).fillRecursive(world, pos);
|
sdf.setReplaceFunction(replace).addPostProcess(post).fillRecursive(world, pos);
|
||||||
|
Vector3f last = SplineHelper.getPos(trunk, trunk.size() - 1.35F);
|
||||||
|
for (int y = 0; y < 8; y++) {
|
||||||
|
BlockPos p = pos.add(last.getX() + 0.5, last.getY() + y, last.getZ() + 0.5);
|
||||||
|
BlocksHelper.setWithoutUpdate(world, p, y == 4 ? wood : log);
|
||||||
|
}
|
||||||
|
|
||||||
/*if (leavesSDF != null) {
|
for (int y = 0; y < 16; y++) {
|
||||||
leavesSDF.fillArea(world, pos, new Box(pos).expand(20, 80, 20));
|
BlockPos p = pos.add(last.getX() + 0.5, last.getY() + y, last.getZ() + 0.5);
|
||||||
}*/
|
if (world.isAir(p)) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, p, leaves);
|
||||||
|
}
|
||||||
|
float radius = (1 - y / 16F) * 3F;
|
||||||
|
int rad = (int) (radius + 1);
|
||||||
|
radius *= radius;
|
||||||
|
for (int x = -rad; x <= rad; x++) {
|
||||||
|
int x2 = x * x;
|
||||||
|
for (int z = -rad; z <= rad; z++) {
|
||||||
|
int z2 = z * z;
|
||||||
|
if (x2 + z2 < radius - random.nextFloat() * rad) {
|
||||||
|
BlockPos lp = p.add(x, 0, z);
|
||||||
|
if (world.isAir(lp)) {
|
||||||
|
BlocksHelper.setWithoutUpdate(world, lp, leaves);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Mutable mut = new Mutable();
|
Mutable mut = new Mutable();
|
||||||
Function<PosInfo, BlockState> leavesPost = (info) -> {
|
Function<PosInfo, BlockState> leavesPost1 = (info) -> {
|
||||||
if (info.getState().equals(log) || info.getState().equals(wood)) {
|
if (info.getState().equals(log) || info.getState().equals(wood)) {
|
||||||
for (int x = -6; x < 7; x++) {
|
for (int x = -6; x < 7; x++) {
|
||||||
int ax = Math.abs(x);
|
int ax = Math.abs(x);
|
||||||
|
@ -138,23 +142,37 @@ public class NightshadeRedwoodTreeFeature extends DefaultFeature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (info.getState().getBlock() instanceof LeavesBlock) {
|
return info.getState();
|
||||||
|
};
|
||||||
|
Function<PosInfo, BlockState> leavesPost2 = (info) -> {
|
||||||
|
if (info.getState().getBlock() instanceof LeavesBlock) {
|
||||||
int distance = info.getState().get(LeavesBlock.DISTANCE);
|
int distance = info.getState().get(LeavesBlock.DISTANCE);
|
||||||
return distance > MHelper.randRange(3, 5, random) ? Blocks.AIR.getDefaultState() : info.getState();
|
if (distance > MHelper.randRange(2, 4, random)) {
|
||||||
|
return Blocks.AIR.getDefaultState();
|
||||||
|
}
|
||||||
|
for (Direction d: BlocksHelper.DIRECTIONS) {
|
||||||
|
int airCount = 0;
|
||||||
|
if (info.getState(d).isAir()) {
|
||||||
|
airCount ++;
|
||||||
|
}
|
||||||
|
if (airCount > 5) {
|
||||||
|
return Blocks.AIR.getDefaultState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (random.nextInt(8) == 0) {
|
||||||
|
return leaves_flower.with(LeavesBlock.DISTANCE, distance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return info.getState();
|
return info.getState();
|
||||||
};
|
};
|
||||||
|
|
||||||
SDF canopy = new SDFCappedCone().setRadius1(12F).setRadius2(3f).setHeight(height * 0.3F).setBlock(leaves);
|
SDF canopy = new SDFCappedCone().setRadius1(12F).setRadius2(1f).setHeight(height * 0.3F).setBlock(leaves);
|
||||||
canopy.setPostProcess(leavesPost ).fillRecursiveIgnore(world, pos.add(0, height * 0.75, 0), ignore);
|
canopy = new SDFDisplacement().setFunction((vec) -> { return MHelper.randRange(-3F, 3F, random); }).setSource(canopy);
|
||||||
|
canopy.addPostProcess(leavesPost1).addPostProcess(leavesPost2).fillRecursiveIgnore(world, pos.add(0, height * 0.75, 0), ignore);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//private void makeLeavesSphere(StructureWorldAccess world, BlockPos pos, BlockState leaves, Function<BlockState, Boolean> ignore) {
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
BRANCH = Lists.newArrayList(new Vector3f(0, 0, 0),
|
BRANCH = Lists.newArrayList(new Vector3f(0, 0, 0),
|
||||||
new Vector3f(0.25F, 0.1F, 0),
|
new Vector3f(0.25F, 0.1F, 0),
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class OldBulbisTreeFeature extends DefaultFeature {
|
||||||
sdf = (sdf == null) ? branch : new SDFUnion().setSourceA(sdf).setSourceB(branch);
|
sdf = (sdf == null) ? branch : new SDFUnion().setSourceA(sdf).setSourceB(branch);
|
||||||
}
|
}
|
||||||
|
|
||||||
sdf.setReplaceFunction(replacement).setPostProcess((info) -> {
|
sdf.setReplaceFunction(replacement).addPostProcess((info) -> {
|
||||||
if (info.getState().equals(stem) && (!info.getStateUp().equals(stem) || !info.getStateDown().equals(stem))) {
|
if (info.getState().equals(stem) && (!info.getStateUp().equals(stem) || !info.getStateDown().equals(stem))) {
|
||||||
return wood;
|
return wood;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
@ -20,9 +21,7 @@ import ru.betterend.util.BlocksHelper;
|
||||||
import ru.betterend.world.structures.StructureWorld;
|
import ru.betterend.world.structures.StructureWorld;
|
||||||
|
|
||||||
public abstract class SDF {
|
public abstract class SDF {
|
||||||
private Function<PosInfo, BlockState> postProcess = (info) -> {
|
private List<Function<PosInfo, BlockState>> postProcesses = Lists.newArrayList();
|
||||||
return info.getState();
|
|
||||||
};
|
|
||||||
private Function<BlockState, Boolean> canReplace = (state) -> {
|
private Function<BlockState, Boolean> canReplace = (state) -> {
|
||||||
return state.getMaterial().isReplaceable();
|
return state.getMaterial().isReplaceable();
|
||||||
};
|
};
|
||||||
|
@ -31,8 +30,8 @@ public abstract class SDF {
|
||||||
|
|
||||||
public abstract BlockState getBlockState(BlockPos pos);
|
public abstract BlockState getBlockState(BlockPos pos);
|
||||||
|
|
||||||
public SDF setPostProcess(Function<PosInfo, BlockState> postProcess) {
|
public SDF addPostProcess(Function<PosInfo, BlockState> postProcess) {
|
||||||
this.postProcess = postProcess;
|
this.postProcesses.add(postProcess);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,66 +40,6 @@ public abstract class SDF {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void fillRecursive(ServerWorldAccess world, BlockPos start, int dx, int dy, int dz) {
|
|
||||||
Map<BlockPos, PosInfo> mapWorld = Maps.newHashMap();
|
|
||||||
Map<BlockPos, PosInfo> addInfo = Maps.newHashMap();
|
|
||||||
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) {
|
|
||||||
BlockState state = getBlockState(wpos);
|
|
||||||
PosInfo.create(mapWorld, addInfo, wpos).setState(state);
|
|
||||||
if (Math.abs(pos.getX()) < dx && Math.abs(pos.getY()) < dy && Math.abs(pos.getZ()) < dz) {
|
|
||||||
add.add(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
blocks.addAll(ends);
|
|
||||||
ends.clear();
|
|
||||||
ends.addAll(add);
|
|
||||||
add.clear();
|
|
||||||
|
|
||||||
run &= !ends.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<PosInfo> infos = new ArrayList<PosInfo>(mapWorld.values());
|
|
||||||
if (infos.size() > 0) {
|
|
||||||
Collections.sort(infos);
|
|
||||||
infos.forEach((info) -> {
|
|
||||||
BlockState state = postProcess.apply(info);
|
|
||||||
BlocksHelper.setWithoutUpdate(world, info.getPos(), state);
|
|
||||||
});
|
|
||||||
|
|
||||||
infos.clear();
|
|
||||||
infos.addAll(addInfo.values());
|
|
||||||
Collections.sort(infos);
|
|
||||||
infos.forEach((info) -> {
|
|
||||||
if (canReplace.apply(world.getBlockState(info.getPos()))) {
|
|
||||||
BlockState state = postProcess.apply(info);
|
|
||||||
BlocksHelper.setWithoutUpdate(world, info.getPos(), state);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fillRecursive(ServerWorldAccess world, BlockPos start) {
|
public void fillRecursive(ServerWorldAccess world, BlockPos start) {
|
||||||
Map<BlockPos, PosInfo> mapWorld = Maps.newHashMap();
|
Map<BlockPos, PosInfo> mapWorld = Maps.newHashMap();
|
||||||
Map<BlockPos, PosInfo> addInfo = Maps.newHashMap();
|
Map<BlockPos, PosInfo> addInfo = Maps.newHashMap();
|
||||||
|
@ -139,8 +78,10 @@ public abstract class SDF {
|
||||||
List<PosInfo> infos = new ArrayList<PosInfo>(mapWorld.values());
|
List<PosInfo> infos = new ArrayList<PosInfo>(mapWorld.values());
|
||||||
if (infos.size() > 0) {
|
if (infos.size() > 0) {
|
||||||
Collections.sort(infos);
|
Collections.sort(infos);
|
||||||
infos.forEach((info) -> {
|
postProcesses.forEach((postProcess) -> {
|
||||||
info.setState(postProcess.apply(info));
|
infos.forEach((info) -> {
|
||||||
|
info.setState(postProcess.apply(info));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
infos.forEach((info) -> {
|
infos.forEach((info) -> {
|
||||||
BlocksHelper.setWithoutUpdate(world, info.getPos(), info.getState());
|
BlocksHelper.setWithoutUpdate(world, info.getPos(), info.getState());
|
||||||
|
@ -149,10 +90,14 @@ public abstract class SDF {
|
||||||
infos.clear();
|
infos.clear();
|
||||||
infos.addAll(addInfo.values());
|
infos.addAll(addInfo.values());
|
||||||
Collections.sort(infos);
|
Collections.sort(infos);
|
||||||
|
postProcesses.forEach((postProcess) -> {
|
||||||
|
infos.forEach((info) -> {
|
||||||
|
info.setState(postProcess.apply(info));
|
||||||
|
});
|
||||||
|
});
|
||||||
infos.forEach((info) -> {
|
infos.forEach((info) -> {
|
||||||
if (canReplace.apply(world.getBlockState(info.getPos()))) {
|
if (canReplace.apply(world.getBlockState(info.getPos()))) {
|
||||||
BlockState state = postProcess.apply(info);
|
BlocksHelper.setWithoutUpdate(world, info.getPos(), info.getState());
|
||||||
BlocksHelper.setWithoutUpdate(world, info.getPos(), state);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -182,8 +127,10 @@ public abstract class SDF {
|
||||||
List<PosInfo> infos = new ArrayList<PosInfo>(mapWorld.values());
|
List<PosInfo> infos = new ArrayList<PosInfo>(mapWorld.values());
|
||||||
if (infos.size() > 0) {
|
if (infos.size() > 0) {
|
||||||
Collections.sort(infos);
|
Collections.sort(infos);
|
||||||
infos.forEach((info) -> {
|
postProcesses.forEach((postProcess) -> {
|
||||||
info.setState(postProcess.apply(info));
|
infos.forEach((info) -> {
|
||||||
|
info.setState(postProcess.apply(info));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
infos.forEach((info) -> {
|
infos.forEach((info) -> {
|
||||||
BlocksHelper.setWithoutUpdate(world, info.getPos(), info.getState());
|
BlocksHelper.setWithoutUpdate(world, info.getPos(), info.getState());
|
||||||
|
@ -192,10 +139,14 @@ public abstract class SDF {
|
||||||
infos.clear();
|
infos.clear();
|
||||||
infos.addAll(addInfo.values());
|
infos.addAll(addInfo.values());
|
||||||
Collections.sort(infos);
|
Collections.sort(infos);
|
||||||
|
postProcesses.forEach((postProcess) -> {
|
||||||
|
infos.forEach((info) -> {
|
||||||
|
info.setState(postProcess.apply(info));
|
||||||
|
});
|
||||||
|
});
|
||||||
infos.forEach((info) -> {
|
infos.forEach((info) -> {
|
||||||
if (canReplace.apply(world.getBlockState(info.getPos()))) {
|
if (canReplace.apply(world.getBlockState(info.getPos()))) {
|
||||||
BlockState state = postProcess.apply(info);
|
BlocksHelper.setWithoutUpdate(world, info.getPos(), info.getState());
|
||||||
BlocksHelper.setWithoutUpdate(world, info.getPos(), state);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -239,8 +190,10 @@ public abstract class SDF {
|
||||||
List<PosInfo> infos = new ArrayList<PosInfo>(mapWorld.values());
|
List<PosInfo> infos = new ArrayList<PosInfo>(mapWorld.values());
|
||||||
if (infos.size() > 0) {
|
if (infos.size() > 0) {
|
||||||
Collections.sort(infos);
|
Collections.sort(infos);
|
||||||
infos.forEach((info) -> {
|
postProcesses.forEach((postProcess) -> {
|
||||||
info.setState(postProcess.apply(info));
|
infos.forEach((info) -> {
|
||||||
|
info.setState(postProcess.apply(info));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
infos.forEach((info) -> {
|
infos.forEach((info) -> {
|
||||||
BlocksHelper.setWithoutUpdate(world, info.getPos(), info.getState());
|
BlocksHelper.setWithoutUpdate(world, info.getPos(), info.getState());
|
||||||
|
@ -249,10 +202,14 @@ public abstract class SDF {
|
||||||
infos.clear();
|
infos.clear();
|
||||||
infos.addAll(addInfo.values());
|
infos.addAll(addInfo.values());
|
||||||
Collections.sort(infos);
|
Collections.sort(infos);
|
||||||
|
postProcesses.forEach((postProcess) -> {
|
||||||
|
infos.forEach((info) -> {
|
||||||
|
info.setState(postProcess.apply(info));
|
||||||
|
});
|
||||||
|
});
|
||||||
infos.forEach((info) -> {
|
infos.forEach((info) -> {
|
||||||
if (canReplace.apply(world.getBlockState(info.getPos()))) {
|
if (canReplace.apply(world.getBlockState(info.getPos()))) {
|
||||||
BlockState state = postProcess.apply(info);
|
BlocksHelper.setWithoutUpdate(world, info.getPos(), info.getState());
|
||||||
BlocksHelper.setWithoutUpdate(world, info.getPos(), state);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -295,17 +252,25 @@ public abstract class SDF {
|
||||||
|
|
||||||
List<PosInfo> infos = new ArrayList<PosInfo>(mapWorld.values());
|
List<PosInfo> infos = new ArrayList<PosInfo>(mapWorld.values());
|
||||||
Collections.sort(infos);
|
Collections.sort(infos);
|
||||||
|
postProcesses.forEach((postProcess) -> {
|
||||||
|
infos.forEach((info) -> {
|
||||||
|
info.setState(postProcess.apply(info));
|
||||||
|
});
|
||||||
|
});
|
||||||
infos.forEach((info) -> {
|
infos.forEach((info) -> {
|
||||||
BlockState state = postProcess.apply(info);
|
world.setBlock(info.getPos(), info.getState());
|
||||||
world.setBlock(info.getPos(), state);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
infos.clear();
|
infos.clear();
|
||||||
infos.addAll(addInfo.values());
|
infos.addAll(addInfo.values());
|
||||||
Collections.sort(infos);
|
Collections.sort(infos);
|
||||||
|
postProcesses.forEach((postProcess) -> {
|
||||||
|
infos.forEach((info) -> {
|
||||||
|
info.setState(postProcess.apply(info));
|
||||||
|
});
|
||||||
|
});
|
||||||
infos.forEach((info) -> {
|
infos.forEach((info) -> {
|
||||||
BlockState state = postProcess.apply(info);
|
world.setBlock(info.getPos(), info.getState());
|
||||||
world.setBlock(info.getPos(), state);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class BushFeature extends DefaultFeature {
|
||||||
sphere = new SDFDisplacement().setFunction((vec) -> { return MHelper.randRange(-2F, 2F, random); }).setSource(sphere);
|
sphere = new SDFDisplacement().setFunction((vec) -> { return MHelper.randRange(-2F, 2F, random); }).setSource(sphere);
|
||||||
sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere));
|
sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere));
|
||||||
sphere.setReplaceFunction(REPLACE);
|
sphere.setReplaceFunction(REPLACE);
|
||||||
sphere.setPostProcess((info) -> {
|
sphere.addPostProcess((info) -> {
|
||||||
if (info.getState().getBlock() instanceof LeavesBlock) {
|
if (info.getState().getBlock() instanceof LeavesBlock) {
|
||||||
int distance = info.getPos().getManhattanDistance(pos);
|
int distance = info.getPos().getManhattanDistance(pos);
|
||||||
if (distance < 7) {
|
if (distance < 7) {
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class TenaneaBushFeature extends DefaultFeature {
|
||||||
sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere));
|
sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere));
|
||||||
sphere.setReplaceFunction(REPLACE);
|
sphere.setReplaceFunction(REPLACE);
|
||||||
List<BlockPos> support = Lists.newArrayList();
|
List<BlockPos> support = Lists.newArrayList();
|
||||||
sphere.setPostProcess((info) -> {
|
sphere.addPostProcess((info) -> {
|
||||||
if (info.getState().getBlock() instanceof LeavesBlock) {
|
if (info.getState().getBlock() instanceof LeavesBlock) {
|
||||||
int distance = info.getPos().getManhattanDistance(pos);
|
int distance = info.getPos().getManhattanDistance(pos);
|
||||||
if (distance < 7) {
|
if (distance < 7) {
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class FloatingSpireFeature extends SpireFeature {
|
||||||
}).setSource(sdf);
|
}).setSource(sdf);
|
||||||
final BlockPos center = pos;
|
final BlockPos center = pos;
|
||||||
List<BlockPos> support = Lists.newArrayList();
|
List<BlockPos> support = Lists.newArrayList();
|
||||||
sdf.setReplaceFunction(REPLACE).setPostProcess((info) -> {
|
sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> {
|
||||||
if (info.getStateUp().isAir()) {
|
if (info.getStateUp().isAir()) {
|
||||||
if (random.nextInt(16) == 0) {
|
if (random.nextInt(16) == 0) {
|
||||||
support.add(info.getPos().up());
|
support.add(info.getPos().up());
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class IceStarFeature extends DefaultFeature {
|
||||||
final BlockState ancient = EndBlocks.ANCIENT_EMERALD_ICE.getDefaultState();
|
final BlockState ancient = EndBlocks.ANCIENT_EMERALD_ICE.getDefaultState();
|
||||||
final SDF sdfCopy = sdf;
|
final SDF sdfCopy = sdf;
|
||||||
|
|
||||||
sdf.setPostProcess((info) -> {
|
sdf.addPostProcess((info) -> {
|
||||||
BlockPos bpos = info.getPos();
|
BlockPos bpos = info.getPos();
|
||||||
float px = bpos.getX() - center.getX();
|
float px = bpos.getX() - center.getX();
|
||||||
float py = bpos.getY() - center.getY();
|
float py = bpos.getY() - center.getY();
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class SpireFeature extends DefaultFeature {
|
||||||
}).setSource(sdf);
|
}).setSource(sdf);
|
||||||
final BlockPos center = pos;
|
final BlockPos center = pos;
|
||||||
List<BlockPos> support = Lists.newArrayList();
|
List<BlockPos> support = Lists.newArrayList();
|
||||||
sdf.setReplaceFunction(REPLACE).setPostProcess((info) -> {
|
sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> {
|
||||||
if (info.getStateUp().isAir()) {
|
if (info.getStateUp().isAir()) {
|
||||||
if (random.nextInt(16) == 0) {
|
if (random.nextInt(16) == 0) {
|
||||||
support.add(info.getPos().up());
|
support.add(info.getPos().up());
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class DragonTreeFeature extends DefaultFeature {
|
||||||
});
|
});
|
||||||
|
|
||||||
function.setReplaceFunction(REPLACE);
|
function.setReplaceFunction(REPLACE);
|
||||||
function.setPostProcess(POST);
|
function.addPostProcess(POST);
|
||||||
function.fillRecursiveIgnore(world, pos, IGNORE);
|
function.fillRecursiveIgnore(world, pos, IGNORE);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -124,7 +124,7 @@ public class DragonTreeFeature extends DefaultFeature {
|
||||||
sphere = new SDFDisplacement().setFunction((vec) -> { return (float) noise.eval(vec.getX() * 0.2, vec.getY() * 0.2, vec.getZ() * 0.2) * 1.5F; }).setSource(sphere);
|
sphere = new SDFDisplacement().setFunction((vec) -> { return (float) noise.eval(vec.getX() * 0.2, vec.getY() * 0.2, vec.getZ() * 0.2) * 1.5F; }).setSource(sphere);
|
||||||
sphere = new SDFDisplacement().setFunction((vec) -> { return random.nextFloat() * 3F - 1.5F; }).setSource(sphere);
|
sphere = new SDFDisplacement().setFunction((vec) -> { return random.nextFloat() * 3F - 1.5F; }).setSource(sphere);
|
||||||
Mutable mut = new Mutable();
|
Mutable mut = new Mutable();
|
||||||
sphere.setPostProcess((info) -> {
|
sphere.addPostProcess((info) -> {
|
||||||
if (random.nextInt(5) == 0) {
|
if (random.nextInt(5) == 0) {
|
||||||
for (Direction dir: Direction.values()) {
|
for (Direction dir: Direction.values()) {
|
||||||
BlockState state = info.getState(dir, 2);
|
BlockState state = info.getState(dir, 2);
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class HelixTreeFeature extends DefaultFeature {
|
||||||
dx = 30 * scale;
|
dx = 30 * scale;
|
||||||
float dy1 = -20 * scale;
|
float dy1 = -20 * scale;
|
||||||
float dy2 = 100 * scale;
|
float dy2 = 100 * scale;
|
||||||
sdf.setPostProcess(POST).fillArea(world, pos, new Box(pos.add(-dx, dy1, -dx), pos.add(dx, dy2, dx)));
|
sdf.addPostProcess(POST).fillArea(world, pos, new Box(pos.add(-dx, dy1, -dx), pos.add(dx, dy2, dx)));
|
||||||
SplineHelper.scale(spline, scale);
|
SplineHelper.scale(spline, scale);
|
||||||
SplineHelper.fillSplineForce(spline, world, EndBlocks.HELIX_TREE.bark.getDefaultState(), pos, (state) -> {
|
SplineHelper.fillSplineForce(spline, world, EndBlocks.HELIX_TREE.bark.getDefaultState(), pos, (state) -> {
|
||||||
return state.getMaterial().isReplaceable();
|
return state.getMaterial().isReplaceable();
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class JellyshroomFeature extends DefaultFeature {
|
||||||
final Vector3f last = spline.get(spline.size() - 1);
|
final Vector3f last = spline.get(spline.size() - 1);
|
||||||
cap = new SDFTranslate().setTranslate(last.getX(), last.getY(), last.getZ()).setSource(cap);
|
cap = new SDFTranslate().setTranslate(last.getX(), last.getY(), last.getZ()).setSource(cap);
|
||||||
sdf = new SDFSmoothUnion().setRadius(3F).setSourceA(sdf).setSourceB(cap);
|
sdf = new SDFSmoothUnion().setRadius(3F).setSourceA(sdf).setSourceB(cap);
|
||||||
sdf.setReplaceFunction(REPLACE).setPostProcess((info) -> {
|
sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> {
|
||||||
if (EndBlocks.JELLYSHROOM.isTreeLog(info.getState())) {
|
if (EndBlocks.JELLYSHROOM.isTreeLog(info.getState())) {
|
||||||
if (EndBlocks.JELLYSHROOM.isTreeLog(info.getStateUp()) && EndBlocks.JELLYSHROOM.isTreeLog(info.getStateDown())) {
|
if (EndBlocks.JELLYSHROOM.isTreeLog(info.getStateUp()) && EndBlocks.JELLYSHROOM.isTreeLog(info.getStateDown())) {
|
||||||
return EndBlocks.JELLYSHROOM.log.getDefaultState();
|
return EndBlocks.JELLYSHROOM.log.getDefaultState();
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class LacugroveFeature extends DefaultFeature {
|
||||||
});
|
});
|
||||||
|
|
||||||
function.setReplaceFunction(REPLACE);
|
function.setReplaceFunction(REPLACE);
|
||||||
function.setPostProcess(POST);
|
function.addPostProcess(POST);
|
||||||
function.fillRecursive(world, pos);
|
function.fillRecursive(world, pos);
|
||||||
|
|
||||||
spline = spline.subList(4, 6);
|
spline = spline.subList(4, 6);
|
||||||
|
@ -110,7 +110,7 @@ public class LacugroveFeature extends DefaultFeature {
|
||||||
sphere = new SDFDisplacement().setFunction((vec) -> { return random.nextFloat() * 3F - 1.5F; }).setSource(sphere);
|
sphere = new SDFDisplacement().setFunction((vec) -> { return random.nextFloat() * 3F - 1.5F; }).setSource(sphere);
|
||||||
sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(new SDFTranslate().setTranslate(0, -radius - 2, 0).setSource(sphere));
|
sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(new SDFTranslate().setTranslate(0, -radius - 2, 0).setSource(sphere));
|
||||||
Mutable mut = new Mutable();
|
Mutable mut = new Mutable();
|
||||||
sphere.setPostProcess((info) -> {
|
sphere.addPostProcess((info) -> {
|
||||||
if (random.nextInt(5) == 0) {
|
if (random.nextInt(5) == 0) {
|
||||||
for (Direction dir: Direction.values()) {
|
for (Direction dir: Direction.values()) {
|
||||||
BlockState state = info.getState(dir, 2);
|
BlockState state = info.getState(dir, 2);
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class MossyGlowshroomFeature extends DefaultFeature {
|
||||||
new SDFScale().setScale(scale)
|
new SDFScale().setScale(scale)
|
||||||
.setSource(FUNCTION)
|
.setSource(FUNCTION)
|
||||||
.setReplaceFunction(REPLACE)
|
.setReplaceFunction(REPLACE)
|
||||||
.setPostProcess((info) -> {
|
.addPostProcess((info) -> {
|
||||||
if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) {
|
if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) {
|
||||||
if (random.nextBoolean() && info.getStateUp().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) {
|
if (random.nextBoolean() && info.getStateUp().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) {
|
||||||
info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.getDefaultState().with(MossyGlowshroomCapBlock.TRANSITION, true));
|
info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.getDefaultState().with(MossyGlowshroomCapBlock.TRANSITION, true));
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class PythadendronTreeFeature extends DefaultFeature {
|
||||||
return EndBlocks.PYTHADENDRON.bark.getDefaultState();
|
return EndBlocks.PYTHADENDRON.bark.getDefaultState();
|
||||||
});
|
});
|
||||||
function.setReplaceFunction(REPLACE);
|
function.setReplaceFunction(REPLACE);
|
||||||
function.setPostProcess(POST);
|
function.addPostProcess(POST);
|
||||||
function.fillRecursive(world, pos);
|
function.fillRecursive(world, pos);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -115,7 +115,7 @@ public class PythadendronTreeFeature extends DefaultFeature {
|
||||||
sphere = new SDFDisplacement().setFunction((vec) -> { return random.nextFloat() * 3F - 1.5F; }).setSource(sphere);
|
sphere = new SDFDisplacement().setFunction((vec) -> { return random.nextFloat() * 3F - 1.5F; }).setSource(sphere);
|
||||||
sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere));
|
sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere));
|
||||||
Mutable mut = new Mutable();
|
Mutable mut = new Mutable();
|
||||||
sphere.setPostProcess((info) -> {
|
sphere.addPostProcess((info) -> {
|
||||||
if (random.nextInt(5) == 0) {
|
if (random.nextInt(5) == 0) {
|
||||||
for (Direction dir: Direction.values()) {
|
for (Direction dir: Direction.values()) {
|
||||||
BlockState state = info.getState(dir, 2);
|
BlockState state = info.getState(dir, 2);
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class TenaneaFeature extends DefaultFeature {
|
||||||
BlockState outer = EndBlocks.TENANEA_OUTER_LEAVES.getDefaultState();
|
BlockState outer = EndBlocks.TENANEA_OUTER_LEAVES.getDefaultState();
|
||||||
|
|
||||||
List<BlockPos> support = Lists.newArrayList();
|
List<BlockPos> support = Lists.newArrayList();
|
||||||
sphere.setPostProcess((info) -> {
|
sphere.addPostProcess((info) -> {
|
||||||
if (random.nextInt(6) == 0 && info.getStateDown().isAir()) {
|
if (random.nextInt(6) == 0 && info.getStateDown().isAir()) {
|
||||||
BlockPos d = info.getPos().down();
|
BlockPos d = info.getPos().down();
|
||||||
support.add(d);
|
support.add(d);
|
||||||
|
|
|
@ -100,7 +100,7 @@ public class UmbrellaTreeFeature extends DefaultFeature {
|
||||||
sdf = new SDFScale().setScale(scale).setSource(sdf);
|
sdf = new SDFScale().setScale(scale).setSource(sdf);
|
||||||
}
|
}
|
||||||
|
|
||||||
sdf.setReplaceFunction(REPLACE).setPostProcess((info) -> {
|
sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> {
|
||||||
if (EndBlocks.UMBRELLA_TREE.isTreeLog(info.getStateUp()) && EndBlocks.UMBRELLA_TREE.isTreeLog(info.getStateDown())) {
|
if (EndBlocks.UMBRELLA_TREE.isTreeLog(info.getStateUp()) && EndBlocks.UMBRELLA_TREE.isTreeLog(info.getStateDown())) {
|
||||||
return EndBlocks.UMBRELLA_TREE.log.getDefaultState();
|
return EndBlocks.UMBRELLA_TREE.log.getDefaultState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class StructureGiantIceStar extends SDFStructureFeature {
|
||||||
final BlockState ancient = EndBlocks.ANCIENT_EMERALD_ICE.getDefaultState();
|
final BlockState ancient = EndBlocks.ANCIENT_EMERALD_ICE.getDefaultState();
|
||||||
final SDF sdfCopy = sdf;
|
final SDF sdfCopy = sdf;
|
||||||
|
|
||||||
return sdf.setPostProcess((info) -> {
|
return sdf.addPostProcess((info) -> {
|
||||||
BlockPos bpos = info.getPos();
|
BlockPos bpos = info.getPos();
|
||||||
float px = bpos.getX() - center.getX();
|
float px = bpos.getX() - center.getX();
|
||||||
float py = bpos.getY() - center.getY();
|
float py = bpos.getY() - center.getY();
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class StructureGiantMossyGlowshroom extends SDFStructureFeature {
|
||||||
return new SDFRound().setRadius(1.5F).setSource(new SDFScale()
|
return new SDFRound().setRadius(1.5F).setSource(new SDFScale()
|
||||||
.setScale(scale)
|
.setScale(scale)
|
||||||
.setSource(function))
|
.setSource(function))
|
||||||
.setPostProcess((info) -> {
|
.addPostProcess((info) -> {
|
||||||
if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) {
|
if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) {
|
||||||
if (random.nextBoolean() && info.getStateUp().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) {
|
if (random.nextBoolean() && info.getStateUp().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) {
|
||||||
info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.getDefaultState().with(MossyGlowshroomCapBlock.TRANSITION, true));
|
info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.getDefaultState().with(MossyGlowshroomCapBlock.TRANSITION, true));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue