From 8c05f1bf1d23010bf4624f822487d2da239518e0 Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Wed, 15 Apr 2026 16:35:49 -0400 Subject: [PATCH] polish --- .../actuator/IrisTerrainNormalActuator.java | 36 ++++++++----- .../components/MantleObjectComponent.java | 51 +++++++++++++++---- .../arcane/iris/engine/object/IrisBiome.java | 30 ++++++++++- .../iris/engine/object/IrisDimension.java | 30 ++++++++++- .../arcane/iris/engine/object/IrisRegion.java | 30 ++++++++++- 5 files changed, 153 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/art/arcane/iris/engine/actuator/IrisTerrainNormalActuator.java b/core/src/main/java/art/arcane/iris/engine/actuator/IrisTerrainNormalActuator.java index d204b4a8d..06284289c 100644 --- a/core/src/main/java/art/arcane/iris/engine/actuator/IrisTerrainNormalActuator.java +++ b/core/src/main/java/art/arcane/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -20,12 +20,14 @@ package art.arcane.iris.engine.actuator; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.framework.EngineAssignedActuator; +import art.arcane.iris.core.loader.IrisData; +import art.arcane.iris.engine.IrisComplex; import art.arcane.iris.engine.object.IrisBiome; +import art.arcane.iris.engine.object.IrisDimension; import art.arcane.iris.engine.object.IrisRegion; import art.arcane.volmlib.util.collection.KList; import art.arcane.iris.util.project.context.ChunkedDataCache; import art.arcane.iris.util.project.context.ChunkContext; -import art.arcane.iris.util.project.context.ChunkedDoubleDataCache; import art.arcane.volmlib.util.documentation.BlockCoordinates; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.math.RNG; @@ -171,11 +173,14 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator private void terrainSliverOptimized(int x, int z, int xf, Hunk h, ChunkContext context) { int chunkHeight = h.getHeight(); int chunkDepth = h.getDepth(); - int fluidHeight = getDimension().getFluidHeight(); - boolean bedrockEnabled = getDimension().isBedrock(); + IrisDimension dimension = getDimension(); + IrisData data = getData(); + IrisComplex complex = getComplex(); + RNG localRng = rng; + int fluidHeight = dimension.getFluidHeight(); + boolean bedrockEnabled = dimension.isBedrock(); ChunkedDataCache biomeCache = context.getBiome(); ChunkedDataCache regionCache = context.getRegion(); - ChunkedDoubleDataCache heightCache = context.getHeight(); ChunkedDataCache fluidCache = context.getFluid(); ChunkedDataCache rockCache = context.getRock(); int realX = xf + x; @@ -193,6 +198,8 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator int topY = Math.min(hf, chunkHeight - 1); BlockData fluid = fluidCache.get(xf, zf); BlockData rock = rockCache.get(xf, zf); + boolean hasSurfaceOres = biome.hasSurfaceOres() || region.hasSurfaceOres() || dimension.hasSurfaceOres(); + boolean hasUndergroundOres = biome.hasUndergroundOres() || region.hasUndergroundOres() || dimension.hasUndergroundOres(); KList blocks = null; KList fblocks = null; @@ -203,9 +210,12 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator continue; } - BlockData ore = biome.generateOres(realX, i, realZ, rng, getData(), true); - ore = ore == null ? region.generateOres(realX, i, realZ, rng, getData(), true) : ore; - ore = ore == null ? getDimension().generateOres(realX, i, realZ, rng, getData(), true) : ore; + BlockData ore = null; + if (hasSurfaceOres) { + ore = biome.generateSurfaceOres(realX, i, realZ, localRng, data); + ore = ore == null ? region.generateSurfaceOres(realX, i, realZ, localRng, data) : ore; + ore = ore == null ? dimension.generateSurfaceOres(realX, i, realZ, localRng, data) : ore; + } if (ore != null) { h.set(xf, i, zf, ore); continue; @@ -214,7 +224,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator if (i > he && i <= hf) { int fdepth = hf - i; if (fblocks == null) { - fblocks = biome.generateSeaLayers(realX, realZ, rng, hf - he, getData()); + fblocks = biome.generateSeaLayers(realX, realZ, localRng, hf - he, data); } if (fblocks.hasIndex(fdepth)) { @@ -228,7 +238,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator if (i <= he) { int depth = he - i; if (blocks == null) { - blocks = biome.generateLayers(getDimension(), realX, realZ, rng, he, he, getData(), getComplex()); + blocks = biome.generateLayers(dimension, realX, realZ, localRng, he, he, data, complex); } if (blocks.hasIndex(depth)) { @@ -236,9 +246,11 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator continue; } - ore = biome.generateOres(realX, i, realZ, rng, getData(), false); - ore = ore == null ? region.generateOres(realX, i, realZ, rng, getData(), false) : ore; - ore = ore == null ? getDimension().generateOres(realX, i, realZ, rng, getData(), false) : ore; + if (hasUndergroundOres) { + ore = biome.generateUndergroundOres(realX, i, realZ, localRng, data); + ore = ore == null ? region.generateUndergroundOres(realX, i, realZ, localRng, data) : ore; + ore = ore == null ? dimension.generateUndergroundOres(realX, i, realZ, localRng, data) : ore; + } if (ore != null) { h.set(xf, i, zf, ore); diff --git a/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleObjectComponent.java b/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleObjectComponent.java index 277ea364e..eee35fd25 100644 --- a/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleObjectComponent.java +++ b/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleObjectComponent.java @@ -32,6 +32,7 @@ import art.arcane.volmlib.util.collection.KMap; import art.arcane.volmlib.util.collection.KSet; import art.arcane.iris.util.project.context.ChunkContext; import art.arcane.iris.util.common.data.B; +import art.arcane.iris.util.project.stream.ProceduralStream; import art.arcane.volmlib.util.documentation.BlockCoordinates; import art.arcane.volmlib.util.documentation.ChunkCoordinates; import art.arcane.volmlib.util.format.Form; @@ -71,6 +72,7 @@ public class MantleObjectComponent extends IrisMantleComponent { IrisBiome surfaceBiome = complex.getTrueBiomeStream().get(xxx, zzz); int surfaceY = getEngineMantle().getEngine().getHeight(xxx, zzz, true); IrisBiome caveBiome = resolveCaveObjectBiome(xxx, zzz, surfaceY, surfaceBiome); + SurfaceHeightLookup surfaceHeightLookup = new SurfaceHeightLookup(context); if (traceRegen) { Iris.info("Regen object layer start: chunk=" + x + "," + z + " surfaceBiome=" + surfaceBiome.getLoadKey() @@ -81,7 +83,7 @@ public class MantleObjectComponent extends IrisMantleComponent { + " regionSurfacePlacers=" + region.getSurfaceObjects().size() + " regionCavePlacers=" + region.getCarvingObjects().size()); } - ObjectPlacementSummary summary = placeObjects(writer, rng, x, z, surfaceBiome, caveBiome, region, complex, traceRegen); + ObjectPlacementSummary summary = placeObjects(writer, rng, x, z, surfaceBiome, caveBiome, region, complex, traceRegen, surfaceHeightLookup); if (traceRegen) { Iris.info("Regen object layer done: chunk=" + x + "," + z + " biomeSurfacePlacersChecked=" + summary.biomeSurfacePlacersChecked() @@ -141,7 +143,7 @@ public class MantleObjectComponent extends IrisMantleComponent { } @ChunkCoordinates - private ObjectPlacementSummary placeObjects(MantleWriter writer, RNG rng, int x, int z, IrisBiome surfaceBiome, IrisBiome caveBiome, IrisRegion region, IrisComplex complex, boolean traceRegen) { + private ObjectPlacementSummary placeObjects(MantleWriter writer, RNG rng, int x, int z, IrisBiome surfaceBiome, IrisBiome caveBiome, IrisRegion region, IrisComplex complex, boolean traceRegen, SurfaceHeightLookup surfaceHeightLookup) { int biomeSurfaceChecked = 0; int biomeSurfaceTriggered = 0; int biomeCaveChecked = 0; @@ -174,7 +176,7 @@ public class MantleObjectComponent extends IrisMantleComponent { if (chance) { biomeSurfaceTriggered++; try { - ObjectPlacementResult result = placeObject(writer, rng, x << 4, z << 4, i, biomeSurfaceExclusionDepth, complex, traceRegen, x, z, "biome-surface"); + ObjectPlacementResult result = placeObject(writer, rng, x << 4, z << 4, i, biomeSurfaceExclusionDepth, complex, traceRegen, x, z, "biome-surface", surfaceHeightLookup); attempts += result.attempts(); placed += result.placed(); rejected += result.rejected(); @@ -239,7 +241,7 @@ public class MantleObjectComponent extends IrisMantleComponent { if (chance) { regionSurfaceTriggered++; try { - ObjectPlacementResult result = placeObject(writer, rng, x << 4, z << 4, i, regionSurfaceExclusionDepth, complex, traceRegen, x, z, "region-surface"); + ObjectPlacementResult result = placeObject(writer, rng, x << 4, z << 4, i, regionSurfaceExclusionDepth, complex, traceRegen, x, z, "region-surface", surfaceHeightLookup); attempts += result.attempts(); placed += result.placed(); rejected += result.rejected(); @@ -319,7 +321,8 @@ public class MantleObjectComponent extends IrisMantleComponent { boolean traceRegen, int chunkX, int chunkZ, - String scope + String scope, + SurfaceHeightLookup surfaceHeightLookup ) { int attempts = 0; int placed = 0; @@ -345,7 +348,7 @@ public class MantleObjectComponent extends IrisMantleComponent { int xx = rng.i(x, x + 15); int zz = rng.i(z, z + 15); int surfaceObjectExclusionRadius = resolveSurfaceObjectExclusionRadius(v); - if (surfaceObjectExclusionDepth > 0 && hasSurfaceCarveExposure(writer, xx, zz, surfaceObjectExclusionDepth, surfaceObjectExclusionRadius)) { + if (surfaceObjectExclusionDepth > 0 && hasSurfaceCarveExposure(writer, surfaceHeightLookup, xx, zz, surfaceObjectExclusionDepth, surfaceObjectExclusionRadius)) { rejected++; continue; } @@ -817,15 +820,16 @@ public class MantleObjectComponent extends IrisMantleComponent { return Math.max(1, caveProfile.getAnchorSearchAttempts()); } - private boolean hasSurfaceCarveExposure(MantleWriter writer, int x, int z, int depth, int radius) { + private boolean hasSurfaceCarveExposure(MantleWriter writer, SurfaceHeightLookup surfaceHeightLookup, int x, int z, int depth, int radius) { int horizontalRadius = Math.max(0, radius); + int maxY = getEngineMantle().getEngine().getHeight() - 1; for (int dx = -horizontalRadius; dx <= horizontalRadius; dx++) { for (int dz = -horizontalRadius; dz <= horizontalRadius; dz++) { int columnX = x + dx; int columnZ = z + dz; - int surfaceY = getEngineMantle().getEngine().getHeight(columnX, columnZ, true); + int surfaceY = surfaceHeightLookup.getRoundedHeight(columnX, columnZ); int fromY = Math.max(1, surfaceY - Math.max(0, depth)); - int toY = Math.min(getEngineMantle().getEngine().getHeight() - 1, surfaceY + 1); + int toY = Math.min(maxY, surfaceY + 1); for (int y = fromY; y <= toY; y++) { if (writer.isCarved(columnX, y, columnZ)) { return true; @@ -985,4 +989,33 @@ public class MantleObjectComponent extends IrisMantleComponent { return null; }); } + + private static final class SurfaceHeightLookup { + private final ChunkContext context; + private final ProceduralStream heightStream; + private final KMap columnHeights; + + private SurfaceHeightLookup(ChunkContext context) { + this.context = context; + this.heightStream = context.getComplex().getHeightStream(); + this.columnHeights = new KMap<>(); + } + + private int getRoundedHeight(int worldX, int worldZ) { + int chunkBlockX = worldX & ~15; + int chunkBlockZ = worldZ & ~15; + if (chunkBlockX == context.getX() && chunkBlockZ == context.getZ()) { + return context.getRoundedHeight(worldX & 15, worldZ & 15); + } + + long columnKey = Cache.key(worldX, worldZ); + Integer columnHeight = columnHeights.get(columnKey); + if (columnHeight == null) { + columnHeight = (int) Math.round(heightStream.getDouble(worldX, worldZ)); + columnHeights.put(columnKey, columnHeight); + } + + return columnHeight; + } + } } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisBiome.java b/core/src/main/java/art/arcane/iris/engine/object/IrisBiome.java index bf2463735..6aa93d6cc 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisBiome.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisBiome.java @@ -178,7 +178,27 @@ public class IrisBiome extends IrisRegistrant implements IRare { private KList ores = new KList<>(); public BlockData generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) { - KList localOres = getOres(surface); + KList localOres = surface ? getSurfaceOres() : getUndergroundOres(); + return generateOres(localOres, x, y, z, rng, data); + } + + public BlockData generateSurfaceOres(int x, int y, int z, RNG rng, IrisData data) { + return generateOres(getSurfaceOres(), x, y, z, rng, data); + } + + public BlockData generateUndergroundOres(int x, int y, int z, RNG rng, IrisData data) { + return generateOres(getUndergroundOres(), x, y, z, rng, data); + } + + public boolean hasSurfaceOres() { + return !getSurfaceOres().isEmpty(); + } + + public boolean hasUndergroundOres() { + return !getUndergroundOres().isEmpty(); + } + + private BlockData generateOres(KList localOres, int x, int y, int z, RNG rng, IrisData data) { if (localOres.isEmpty()) { return null; } @@ -200,6 +220,14 @@ public class IrisBiome extends IrisRegistrant implements IRare { undergroundOreCache.reset(); } + private KList getSurfaceOres() { + return getOres(true); + } + + private KList getUndergroundOres() { + return getOres(false); + } + private KList getOres(boolean surface) { AtomicCache> oreCache = surface ? surfaceOreCache : undergroundOreCache; return oreCache.aquire(() -> { diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java b/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java index 0d553ef5f..4bf55e5b9 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java @@ -293,7 +293,27 @@ public class IrisDimension extends IrisRegistrant { } public BlockData generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) { - KList localOres = getOres(surface); + KList localOres = surface ? getSurfaceOres() : getUndergroundOres(); + return generateOres(localOres, x, y, z, rng, data); + } + + public BlockData generateSurfaceOres(int x, int y, int z, RNG rng, IrisData data) { + return generateOres(getSurfaceOres(), x, y, z, rng, data); + } + + public BlockData generateUndergroundOres(int x, int y, int z, RNG rng, IrisData data) { + return generateOres(getUndergroundOres(), x, y, z, rng, data); + } + + public boolean hasSurfaceOres() { + return !getSurfaceOres().isEmpty(); + } + + public boolean hasUndergroundOres() { + return !getUndergroundOres().isEmpty(); + } + + private BlockData generateOres(KList localOres, int x, int y, int z, RNG rng, IrisData data) { if (localOres.isEmpty()) { return null; } @@ -315,6 +335,14 @@ public class IrisDimension extends IrisRegistrant { undergroundOreCache.reset(); } + private KList getSurfaceOres() { + return getOres(true); + } + + private KList getUndergroundOres() { + return getOres(false); + } + private KList getOres(boolean surface) { AtomicCache> oreCache = surface ? surfaceOreCache : undergroundOreCache; return oreCache.aquire(() -> { diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisRegion.java b/core/src/main/java/art/arcane/iris/engine/object/IrisRegion.java index b3ca1a91e..9a95e4a4d 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisRegion.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisRegion.java @@ -154,7 +154,27 @@ public class IrisRegion extends IrisRegistrant implements IRare { private KList ores = new KList<>(); public BlockData generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) { - KList localOres = getOres(surface); + KList localOres = surface ? getSurfaceOres() : getUndergroundOres(); + return generateOres(localOres, x, y, z, rng, data); + } + + public BlockData generateSurfaceOres(int x, int y, int z, RNG rng, IrisData data) { + return generateOres(getSurfaceOres(), x, y, z, rng, data); + } + + public BlockData generateUndergroundOres(int x, int y, int z, RNG rng, IrisData data) { + return generateOres(getUndergroundOres(), x, y, z, rng, data); + } + + public boolean hasSurfaceOres() { + return !getSurfaceOres().isEmpty(); + } + + public boolean hasUndergroundOres() { + return !getUndergroundOres().isEmpty(); + } + + private BlockData generateOres(KList localOres, int x, int y, int z, RNG rng, IrisData data) { if (localOres.isEmpty()) { return null; } @@ -176,6 +196,14 @@ public class IrisRegion extends IrisRegistrant implements IRare { undergroundOreCache.reset(); } + private KList getSurfaceOres() { + return getOres(true); + } + + private KList getUndergroundOres() { + return getOres(false); + } + private KList getOres(boolean surface) { AtomicCache> oreCache = surface ? surfaceOreCache : undergroundOreCache; return oreCache.aquire(() -> {