add some options for customizing caves

This commit is contained in:
Julian Krings
2025-06-23 17:16:45 +02:00
parent e5cb4d82a3
commit a802edc375
4 changed files with 131 additions and 12 deletions

View File

@@ -35,6 +35,7 @@ import com.volmit.iris.util.mantle.Mantle;
import com.volmit.iris.util.mantle.MantleChunk;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.matter.Matter;
import com.volmit.iris.util.noise.CNG;
import lombok.Data;
import org.bukkit.block.data.BlockData;
import org.bukkit.util.Vector;
@@ -71,6 +72,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
private static Set<IrisPosition> getBallooned(Set<IrisPosition> vset, double radius) {
Set<IrisPosition> returnset = new HashSet<>();
int ceilrad = (int) Math.ceil(radius);
double r2 = Math.pow(radius, 2);
for (IrisPosition v : vset) {
int tipx = v.getX();
@@ -80,7 +82,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) {
for (int loopy = tipy - ceilrad; loopy <= tipy + ceilrad; loopy++) {
for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) {
if (hypot(loopx - tipx, loopy - tipy, loopz - tipz) <= radius) {
if (hypot(loopx - tipx, loopy - tipy, loopz - tipz) <= r2) {
returnset.add(new IrisPosition(loopx, loopy, loopz));
}
}
@@ -113,7 +115,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
for (double d : pars) {
sum += Math.pow(d, 2);
}
return Math.sqrt(sum);
return sum;
}
private static double lengthSq(double x, double y, double z) {
@@ -453,6 +455,62 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
* @param <T> the type of data to apply to the mantle
*/
public <T> void setLineConsumer(List<IrisPosition> vectors, double radius, boolean filled, Function3<Integer, Integer, Integer, T> data) {
Set<IrisPosition> vset = cleanup(vectors);
vset = getBallooned(vset, radius);
if (!filled) {
vset = getHollowed(vset);
}
setConsumer(vset, data);
}
/**
* Set lines for points
*
* @param vectors the points
* @param radius the radius
* @param filled hollow or filled?
* @param data the data to set
* @param <T> the type of data to apply to the mantle
*/
public <T> void setNoiseMasked(List<IrisPosition> vectors, double radius, double threshold, CNG shape, Set<IrisPosition> masks, boolean filled, Function3<Integer, Integer, Integer, T> data) {
Set<IrisPosition> vset = cleanup(vectors);
vset = masks == null ? getBallooned(vset, radius) : getMasked(vset, masks, radius);
vset.removeIf(p -> shape.noise(p.getX(), p.getY(), p.getZ()) < threshold);
if (!filled) {
vset = getHollowed(vset);
}
setConsumer(vset, data);
}
private static Set<IrisPosition> getMasked(Set<IrisPosition> vectors, Set<IrisPosition> masks, double radius) {
Set<IrisPosition> vset = new KSet<>();
int ceil = (int) Math.ceil(radius);
double r2 = Math.pow(radius, 2);
for (IrisPosition v : vectors) {
int tipX = v.getX();
int tipY = v.getY();
int tipZ = v.getZ();
for (int x = -ceil; x <= ceil; x++) {
for (int y = -ceil; y <= ceil; y++) {
for (int z = -ceil; z <= ceil; z++) {
if (hypot(x, y, z) > r2 || !masks.contains(new IrisPosition(x, y, z)))
continue;
vset.add(new IrisPosition(tipX + x, tipY + y, tipZ + z));
}
}
}
}
return vset;
}
private static Set<IrisPosition> cleanup(List<IrisPosition> vectors) {
Set<IrisPosition> vset = new KSet<>();
for (int i = 0; vectors.size() != 0 && i < vectors.size() - 1; i++) {
@@ -504,13 +562,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
}
}
vset = getBallooned(vset, radius);
if (!filled) {
vset = getHollowed(vset);
}
setConsumer(vset, data);
return vset;
}
/**

View File

@@ -25,9 +25,11 @@ import com.volmit.iris.engine.mantle.MantleWriter;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.RegistryListResource;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.matter.MatterCavern;
import com.volmit.iris.util.noise.CNG;
import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -55,6 +57,9 @@ public class IrisCave extends IrisRegistrant {
@Desc("Limit the worm from ever getting higher or lower than this range")
private IrisRange verticalRange = new IrisRange(3, 255);
@Desc("Shape of the caves")
private IrisCaveShape shape = new IrisCaveShape();
@Override
public String getFolderName() {
return "caves";
@@ -96,8 +101,10 @@ public class IrisCave extends IrisRegistrant {
MatterCavern c = new MatterCavern(true, customBiome, (byte) 0);
MatterCavern w = new MatterCavern(true, customBiome, (byte) 1);
writer.setLineConsumer(points,
girth, true,
CNG cng = shape.getNoise(rng, engine);
KSet<IrisPosition> mask = shape.getMasked(rng, engine);
writer.setNoiseMasked(points,
girth, cng.noise(x, y, z), cng, mask, true,
(xf, yf, zf) -> yf <= h ? w : c);
}

View File

@@ -0,0 +1,52 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.RegistryListResource;
import com.volmit.iris.engine.object.annotations.Snippet;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Snippet("cave-shape")
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Cave Shape")
@Data
public class IrisCaveShape {
private transient final KMap<IrisPosition, KSet<IrisPosition>> cache = new KMap<>();
@Desc("Noise used for the shape of the cave")
private IrisGeneratorStyle noise = new IrisGeneratorStyle();
@RegistryListResource(IrisObject.class)
@Desc("Object used as mask for the shape of the cave")
private String object = null;
@Desc("Rotation to apply to objects before using them as mask")
private IrisObjectRotation objectRotation = new IrisObjectRotation();
public CNG getNoise(RNG rng, Engine engine) {
return noise.create(rng, engine.getData());
}
public KSet<IrisPosition> getMasked(RNG rng, Engine engine) {
if (object == null) return null;
return cache.computeIfAbsent(new IrisPosition(
rng.i(0, 360),
rng.i(0, 360),
rng.i(0, 360)),
pos -> {
var rotated = new KSet<IrisPosition>();
engine.getData().getObjectLoader().load(object).getBlocks().forEach((vector, data) -> {
if (data.getMaterial().isAir()) return;
rotated.add(new IrisPosition(objectRotation.rotate(vector, pos.getX(), pos.getY(), pos.getZ())));
});
return rotated;
});
}
}

View File

@@ -27,6 +27,7 @@ import com.volmit.iris.util.matter.IrisMatter;
import com.volmit.iris.util.matter.Matter;
import com.volmit.iris.util.matter.MatterSlice;
import lombok.Getter;
import lombok.SneakyThrows;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
@@ -111,9 +112,11 @@ public class MantleChunk {
}
}
public void close() throws InterruptedException {
@SneakyThrows
public void close() {
closed.set(true);
ref.acquire(Integer.MAX_VALUE);
ref.release(Integer.MAX_VALUE);
}
public boolean inUse() {
@@ -123,6 +126,10 @@ public class MantleChunk {
public MantleChunk use() {
if (closed.get()) throw new IllegalStateException("Chunk is closed!");
ref.acquireUninterruptibly();
if (closed.get()) {
ref.release();
throw new IllegalStateException("Chunk is closed!");
}
return this;
}
@@ -213,6 +220,7 @@ public class MantleChunk {
* @throws IOException shit happens
*/
public void write(DataOutputStream dos) throws IOException {
close();
dos.writeByte(x);
dos.writeByte(z);
dos.writeByte(sections.length());