mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-27 06:20:02 +00:00
Refined featurette edge behavior
- Keep coral tips attached to the fan silhouette - Preserve large leaf weights and disable zero threshold ores - Reuse formation palette sources across each object
This commit is contained in:
commit
fda24db789
9 files changed
+290
-20
No files matched your search
@@ -58,7 +58,7 @@ public class IrisOreGenerator {
|
||||
}
|
||||
|
||||
public PlatformBlockState generate(int x, int y, int z, RNG rng, IrisData data) {
|
||||
if (!range.contains(y)) {
|
||||
if (threshold <= 0 || !range.contains(y)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,16 +88,18 @@ public final class CoralGenerator {
|
||||
|
||||
private static void buildFan(CoralCanvas canvas, IrisCoral coral, int height, long seed) {
|
||||
int half = Math.max(1, coral.getFanWidth());
|
||||
for (int y = 0; y < height; y++) {
|
||||
int tippedWidth = -1;
|
||||
for (int y = height - 1; y >= 0; y--) {
|
||||
double t = y / (double) Math.max(1, height - 1);
|
||||
double profile = Math.sin(Math.PI * t);
|
||||
int w = (int) Math.round(half * profile);
|
||||
for (int dx = -w; dx <= w; dx++) {
|
||||
canvas.set(dx, y, 0, CoralCanvas.Role.STRUCTURE);
|
||||
if (Math.abs(dx) > tippedWidth) {
|
||||
placeTip(canvas, coral, dx, y, 0, seed + dx);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int dx = -half; dx <= half; dx++) {
|
||||
placeTip(canvas, coral, dx, height - 1, 0, seed + dx);
|
||||
tippedWidth = Math.max(tippedWidth, w);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+23
-10
@@ -25,35 +25,48 @@ import art.arcane.iris.engine.object.IrisProceduralBlocks;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.util.common.math.Vector3i;
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public final class FormationBlockResolver {
|
||||
private FormationBlockResolver() {
|
||||
private final IrisFormation formation;
|
||||
private final IrisData data;
|
||||
private final RNG paletteRng;
|
||||
private final Int2ObjectOpenHashMap<RNG> strataRngs = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
public FormationBlockResolver(IrisFormation formation, IrisData data) {
|
||||
this.formation = formation;
|
||||
this.data = data;
|
||||
paletteRng = new RNG(formation.getSeed());
|
||||
}
|
||||
|
||||
public static PlatformBlockState resolve(IrisFormation f, IrisData data, FormationCanvas.Role role, Vector3i raw) {
|
||||
public PlatformBlockState resolve(FormationCanvas.Role role, Vector3i raw) {
|
||||
int x = raw.getBlockX();
|
||||
int y = raw.getBlockY();
|
||||
int z = raw.getBlockZ();
|
||||
RNG paletteRng = new RNG(f.getSeed());
|
||||
|
||||
if (role == FormationCanvas.Role.CAP && capDefined(f)) {
|
||||
PlatformBlockState cap = IrisProceduralBlocks.resolve(f.getCapBlock(), f.getCapPalette(), data, x, y, z, paletteRng);
|
||||
if (role == FormationCanvas.Role.CAP && capDefined(formation)) {
|
||||
PlatformBlockState cap = IrisProceduralBlocks.resolve(formation.getCapBlock(), formation.getCapPalette(), data, x, y, z, paletteRng);
|
||||
if (cap != null) {
|
||||
return cap;
|
||||
}
|
||||
}
|
||||
|
||||
if (strataDefined(f)) {
|
||||
IrisMaterialPalette strata = f.getStrataPalette();
|
||||
int thickness = Math.max(1, f.getStrataThickness());
|
||||
if (strataDefined(formation)) {
|
||||
IrisMaterialPalette strata = formation.getStrataPalette();
|
||||
int thickness = Math.max(1, formation.getStrataThickness());
|
||||
int band = Math.floorDiv(y, thickness);
|
||||
PlatformBlockState strataState = strata.get(new RNG(f.getSeed() + (band * 31L)), x, band, z, data);
|
||||
RNG strataRng = strataRngs.get(band);
|
||||
if (strataRng == null) {
|
||||
strataRng = new RNG(formation.getSeed() + band * 31L);
|
||||
strataRngs.put(band, strataRng);
|
||||
}
|
||||
PlatformBlockState strataState = strata.get(strataRng, x, band, z, data);
|
||||
if (strataState != null) {
|
||||
return strataState;
|
||||
}
|
||||
}
|
||||
|
||||
return IrisProceduralBlocks.resolve(f.getBlock(), f.getBlockPalette(), data, x, y, z, paletteRng);
|
||||
return IrisProceduralBlocks.resolve(formation.getBlock(), formation.getBlockPalette(), data, x, y, z, paletteRng);
|
||||
}
|
||||
|
||||
private static boolean capDefined(IrisFormation f) {
|
||||
|
||||
@@ -62,8 +62,9 @@ public final class FormationGenerator {
|
||||
}
|
||||
|
||||
Map<Vector3i, PlatformBlockState> resolved = new HashMap<>();
|
||||
FormationBlockResolver resolver = new FormationBlockResolver(f, data);
|
||||
for (Map.Entry<Vector3i, FormationCanvas.Role> entry : canvas.getCells().entrySet()) {
|
||||
PlatformBlockState bd = FormationBlockResolver.resolve(f, data, entry.getValue(), entry.getKey());
|
||||
PlatformBlockState bd = resolver.resolve(entry.getValue(), entry.getKey());
|
||||
if (bd == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import art.arcane.iris.engine.object.IrisMaterialPalette;
|
||||
import art.arcane.iris.engine.object.IrisProceduralBlocks;
|
||||
import art.arcane.iris.engine.object.IrisProceduralTree;
|
||||
import art.arcane.iris.engine.object.IrisTreeDecorator;
|
||||
import art.arcane.iris.engine.object.IrisTreeSecondaryLeaf;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.util.common.data.B;
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
@@ -106,16 +107,16 @@ public final class TreeBlockResolver {
|
||||
}
|
||||
|
||||
private static String pickWeighted(IrisProceduralTree tree, RNG rng) {
|
||||
int total = 0;
|
||||
for (art.arcane.iris.engine.object.IrisTreeSecondaryLeaf s : tree.getWeightedSecondaryLeaves()) {
|
||||
long total = 0;
|
||||
for (IrisTreeSecondaryLeaf s : tree.getWeightedSecondaryLeaves()) {
|
||||
total += Math.max(0, s.getWeight());
|
||||
}
|
||||
if (total <= 0) {
|
||||
return null;
|
||||
}
|
||||
double r = rng.nextDouble() * total;
|
||||
double cumulative = 0;
|
||||
for (art.arcane.iris.engine.object.IrisTreeSecondaryLeaf s : tree.getWeightedSecondaryLeaves()) {
|
||||
long cumulative = 0;
|
||||
for (IrisTreeSecondaryLeaf s : tree.getWeightedSecondaryLeaves()) {
|
||||
cumulative += Math.max(0, s.getWeight());
|
||||
if (r < cumulative) {
|
||||
return s.getBlock();
|
||||
|
||||
Reference in new issue
Block a user