From 4dec940311145ec95668cff4e92eae215c63c42b Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Wed, 21 Oct 2026 23:21:45 -0400 Subject: [PATCH] Compiled cave density programs - Carver base, detail, warp and module fields evaluate through compiled noise programs - Near-parity tests inject replacement densities as compiled programs --- .../mantle/CaveFieldModuleState.java | 10 ++-- .../generation/mantle/IrisCaveCarver3D.java | 57 ++++++++++--------- .../IrisCaveCarver3DNearParityTest.java | 37 ++++++------ 3 files changed, 53 insertions(+), 51 deletions(-) diff --git a/core/src/main/java/art/arcane/iris/generation/mantle/CaveFieldModuleState.java b/core/src/main/java/art/arcane/iris/generation/mantle/CaveFieldModuleState.java index 66e60be24..c963f2af2 100644 --- a/core/src/main/java/art/arcane/iris/generation/mantle/CaveFieldModuleState.java +++ b/core/src/main/java/art/arcane/iris/generation/mantle/CaveFieldModuleState.java @@ -20,10 +20,10 @@ package art.arcane.iris.generation.mantle; import art.arcane.iris.generation.cave.IrisCaveFieldModule; import art.arcane.iris.pack.value.IrisRange; -import art.arcane.volmlib.util.noise.CNG; +import art.arcane.volmlib.util.noise.program.NoiseProgram; final class CaveFieldModuleState { - final CNG density; + final NoiseProgram density; final int minY; final int maxY; final double weight; @@ -32,7 +32,7 @@ final class CaveFieldModuleState { final double minContribution; final double maxContribution; - CaveFieldModuleState(IrisCaveFieldModule module, CNG density) { + CaveFieldModuleState(IrisCaveFieldModule module, NoiseProgram density) { IrisRange range = module.getVerticalRange(); this.density = density; this.minY = (int) Math.floor(range.getMin()); @@ -47,12 +47,12 @@ final class CaveFieldModuleState { } double sample(double x, int y, double z) { - double sampled = density.noiseFastSigned3D(x, y, z); + double sampled = density.sampleSigned3D(x, y, z); return invert ? (threshold - sampled) * weight : (sampled - threshold) * weight; } double sample(double x, double y, double z) { - double sampled = density.noiseFastSigned3D(x, y, z); + double sampled = density.sampleSigned3D(x, y, z); return invert ? (threshold - sampled) * weight : (sampled - threshold) * weight; } } diff --git a/core/src/main/java/art/arcane/iris/generation/mantle/IrisCaveCarver3D.java b/core/src/main/java/art/arcane/iris/generation/mantle/IrisCaveCarver3D.java index 9c5551908..2566a19bf 100644 --- a/core/src/main/java/art/arcane/iris/generation/mantle/IrisCaveCarver3D.java +++ b/core/src/main/java/art/arcane/iris/generation/mantle/IrisCaveCarver3D.java @@ -26,6 +26,7 @@ import art.arcane.iris.pack.value.IrisRange; import art.arcane.iris.generation.noise.IrisGeneratorStyle; import art.arcane.iris.generation.noise.IrisStyledRange; import art.arcane.volmlib.util.noise.CNG; +import art.arcane.volmlib.util.noise.program.NoiseProgram; import art.arcane.volmlib.util.mantle.runtime.MantleChunk; import art.arcane.volmlib.util.math.M; import art.arcane.volmlib.util.math.PowerOfTwoCoordinates; @@ -73,9 +74,9 @@ public class IrisCaveCarver3D { private final Engine engine; private final IrisData data; private final IrisCaveProfile profile; - private final CNG baseDensity; - private final CNG detailDensity; - private final CNG warpDensity; + private final NoiseProgram baseDensity; + private final NoiseProgram detailDensity; + private final NoiseProgram warpDensity; private final CNG surfaceBreakDensity; private final RNG thresholdRng; private final CaveFieldModuleState[] modules; @@ -123,9 +124,9 @@ public class IrisCaveCarver3D { List moduleStates = new ArrayList<>(); RNG baseRng = new RNG(engine.getSeedManager().getCarve()); - this.baseDensity = profile.getBaseDensityStyle().create(baseRng.nextParallelRNG(934_447), data); - this.detailDensity = profile.getDetailDensityStyle().create(baseRng.nextParallelRNG(612_991), data); - this.warpDensity = profile.getWarpStyle().create(baseRng.nextParallelRNG(770_713), data); + this.baseDensity = NoiseProgram.compileSigned3D(profile.getBaseDensityStyle().create(baseRng.nextParallelRNG(934_447), data)); + this.detailDensity = NoiseProgram.compileSigned3D(profile.getDetailDensityStyle().create(baseRng.nextParallelRNG(612_991), data)); + this.warpDensity = NoiseProgram.compileSigned3D(profile.getWarpStyle().create(baseRng.nextParallelRNG(770_713), data)); this.surfaceBreakDensity = profile.getSurfaceBreakStyle().create(baseRng.nextParallelRNG(341_219), data); this.thresholdRng = baseRng.nextParallelRNG(489_112); this.baseWeight = profile.getBaseWeight(); @@ -143,7 +144,7 @@ public class IrisCaveCarver3D { int index = 0; for (IrisCaveFieldModule module : profile.getModules()) { CNG moduleDensity = module.getStyle().create(baseRng.nextParallelRNG(1_000_003L + (index * 65_537L)), data); - CaveFieldModuleState state = new CaveFieldModuleState(module, moduleDensity); + CaveFieldModuleState state = new CaveFieldModuleState(module, NoiseProgram.compileSigned3D(moduleDensity)); moduleStates.add(state); weight += Math.abs(state.weight); index++; @@ -2644,7 +2645,7 @@ public class IrisCaveCarver3D { } private boolean classifyDensityPointNoWarpNoModules(int x, int y, int z, double thresholdLimit) { - double density = baseDensity.noiseFastSigned3D(x, y, z) * baseWeight; + double density = baseDensity.sampleSigned3D(x, y, z) * baseWeight; if ((density + detailMinContribution) > thresholdLimit) { return false; } @@ -2652,7 +2653,7 @@ public class IrisCaveCarver3D { return true; } - density += detailDensity.noiseFastSigned3D(x, y, z) * detailWeight; + density += detailDensity.sampleSigned3D(x, y, z) * detailWeight; return density <= thresholdLimit; } @@ -2670,7 +2671,7 @@ public class IrisCaveCarver3D { return classifyDensityPointNoWarpNoModules(x, y, z, thresholdLimit); } - double density = baseDensity.noiseFastSigned3D(x, y, z) * baseWeight; + double density = baseDensity.sampleSigned3D(x, y, z) * baseWeight; if ((density + detailMinContribution + remainingMin[0]) > thresholdLimit) { return false; } @@ -2678,7 +2679,7 @@ public class IrisCaveCarver3D { return true; } - density += detailDensity.noiseFastSigned3D(x, y, z) * detailWeight; + density += detailDensity.sampleSigned3D(x, y, z) * detailWeight; if ((density + remainingMin[0]) > thresholdLimit) { return false; } @@ -2720,7 +2721,7 @@ public class IrisCaveCarver3D { double warpedX = x + (warpA * warpStrength); double warpedY = y + (warpB * warpStrength); double warpedZ = z + ((warpA - warpB) * 0.5D * warpStrength); - double density = baseDensity.noiseFastSigned3D(warpedX, warpedY, warpedZ) * baseWeight; + double density = baseDensity.sampleSigned3D(warpedX, warpedY, warpedZ) * baseWeight; if ((density + detailMinContribution) > thresholdLimit) { return false; } @@ -2728,7 +2729,7 @@ public class IrisCaveCarver3D { return true; } - density += detailDensity.noiseFastSigned3D(warpedX, warpedY, warpedZ) * detailWeight; + density += detailDensity.sampleSigned3D(warpedX, warpedY, warpedZ) * detailWeight; return density <= thresholdLimit; } @@ -2756,7 +2757,7 @@ public class IrisCaveCarver3D { double warpedX = x + (warpA * warpStrength); double warpedY = y + (warpB * warpStrength); double warpedZ = z + ((warpA - warpB) * 0.5D * warpStrength); - double density = baseDensity.noiseFastSigned3D(warpedX, warpedY, warpedZ) * baseWeight; + double density = baseDensity.sampleSigned3D(warpedX, warpedY, warpedZ) * baseWeight; if ((density + detailMinContribution + remainingMin[0]) > thresholdLimit) { return false; } @@ -2764,7 +2765,7 @@ public class IrisCaveCarver3D { return true; } - density += detailDensity.noiseFastSigned3D(warpedX, warpedY, warpedZ) * detailWeight; + density += detailDensity.sampleSigned3D(warpedX, warpedY, warpedZ) * detailWeight; if ((density + remainingMin[0]) > thresholdLimit) { return false; } @@ -3020,8 +3021,8 @@ public class IrisCaveCarver3D { } private double sampleDensityNoWarpNoModules(int x, int y, int z) { - double density = baseDensity.noiseFastSigned3D(x, y, z) * baseWeight; - density += detailDensity.noiseFastSigned3D(x, y, z) * detailWeight; + double density = baseDensity.sampleSigned3D(x, y, z) * baseWeight; + density += detailDensity.sampleSigned3D(x, y, z) * detailWeight; return density * inverseNormalization; } @@ -3032,11 +3033,11 @@ public class IrisCaveCarver3D { } CaveFieldModuleState[] localModules = scratch.activeModules; - double density = baseDensity.noiseFastSigned3D(x, y, z) * baseWeight; - density += detailDensity.noiseFastSigned3D(x, y, z) * detailWeight; + double density = baseDensity.sampleSigned3D(x, y, z) * baseWeight; + density += detailDensity.sampleSigned3D(x, y, z) * detailWeight; for (int moduleIndex = 0; moduleIndex < activeModuleCount; moduleIndex++) { CaveFieldModuleState module = localModules[moduleIndex]; - double moduleDensity = module.density.noiseFastSigned3D(x, y, z) - module.threshold; + double moduleDensity = module.density.sampleSigned3D(x, y, z) - module.threshold; if (module.invert) { moduleDensity = -moduleDensity; } @@ -3057,8 +3058,8 @@ public class IrisCaveCarver3D { double warpedX = x + (warpA * warpStrength); double warpedY = y + (warpB * warpStrength); double warpedZ = z + ((warpA - warpB) * 0.5D * warpStrength); - double density = baseDensity.noiseFastSigned3D(warpedX, warpedY, warpedZ) * baseWeight; - density += detailDensity.noiseFastSigned3D(warpedX, warpedY, warpedZ) * detailWeight; + double density = baseDensity.sampleSigned3D(warpedX, warpedY, warpedZ) * baseWeight; + density += detailDensity.sampleSigned3D(warpedX, warpedY, warpedZ) * detailWeight; return density * inverseNormalization; } @@ -3082,11 +3083,11 @@ public class IrisCaveCarver3D { double warpedX = x + (warpA * warpStrength); double warpedY = y + (warpB * warpStrength); double warpedZ = z + ((warpA - warpB) * 0.5D * warpStrength); - double density = baseDensity.noiseFastSigned3D(warpedX, warpedY, warpedZ) * baseWeight; - density += detailDensity.noiseFastSigned3D(warpedX, warpedY, warpedZ) * detailWeight; + double density = baseDensity.sampleSigned3D(warpedX, warpedY, warpedZ) * baseWeight; + density += detailDensity.sampleSigned3D(warpedX, warpedY, warpedZ) * detailWeight; for (int moduleIndex = 0; moduleIndex < activeModuleCount; moduleIndex++) { CaveFieldModuleState module = localModules[moduleIndex]; - double moduleDensity = module.density.noiseFastSigned3D(warpedX, warpedY, warpedZ) - module.threshold; + double moduleDensity = module.density.sampleSigned3D(warpedX, warpedY, warpedZ) - module.threshold; if (module.invert) { moduleDensity = -moduleDensity; } @@ -3110,8 +3111,8 @@ public class IrisCaveCarver3D { scratch.warpCacheX[slot] = sx; scratch.warpCacheY[slot] = sy; scratch.warpCacheZ[slot] = sz; - scratch.warpCacheA[slot] = warpDensity.noiseFastSigned3D(sx, sy, sz); - scratch.warpCacheB[slot] = warpDensity.noiseFastSigned3D(sx + 31.37D, sy - 17.21D, sz + 23.91D); + scratch.warpCacheA[slot] = warpDensity.sampleSigned3D(sx, sy, sz); + scratch.warpCacheB[slot] = warpDensity.sampleSigned3D(sx + 31.37D, sy - 17.21D, sz + 23.91D); return slot; } @@ -3227,7 +3228,7 @@ public class IrisCaveCarver3D { private boolean isAquiferCandidate(CaveCarveScratch scratch, int x, int y, int z, double localThreshold) { double depthFactor = Math.max(0D, Math.min(1.5D, (fluidHeight - y) / 48D)); double cutoff = 0.35D + (depthFactor * 0.2D); - if (detailDensity.noiseFastSigned3D(x, y * 0.5D, z) <= cutoff) { + if (detailDensity.sampleSigned3D(x, y * 0.5D, z) <= cutoff) { return false; } return !fluidRequiresFloor || hasAquiferCupSupport(scratch, x, y, z, localThreshold); diff --git a/core/src/test/java/art/arcane/iris/generation/mantle/IrisCaveCarver3DNearParityTest.java b/core/src/test/java/art/arcane/iris/generation/mantle/IrisCaveCarver3DNearParityTest.java index ced1764da..28edd359d 100644 --- a/core/src/test/java/art/arcane/iris/generation/mantle/IrisCaveCarver3DNearParityTest.java +++ b/core/src/test/java/art/arcane/iris/generation/mantle/IrisCaveCarver3DNearParityTest.java @@ -13,6 +13,7 @@ import art.arcane.iris.generation.noise.IrisStyledRange; import art.arcane.iris.world.IrisWorld; import art.arcane.iris.generation.noise.NoiseStyle; import art.arcane.volmlib.util.noise.CNG; +import art.arcane.volmlib.util.noise.program.NoiseProgram; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.mantle.runtime.Mantle; import art.arcane.volmlib.util.mantle.runtime.MantleChunk; @@ -148,7 +149,7 @@ public class IrisCaveCarver3DNearParityTest { sampledY.add((int) y); return x * 0.0001D + y * 0.01D + z * 0.0002D; }).when(density).noiseFastSigned3D(anyDouble(), anyDouble(), anyDouble()); - baseDensityField.set(carver, density); + baseDensityField.set(carver, NoiseProgram.compileSigned3D(density)); Method prepare = IrisCaveCarver3D.class.getDeclaredMethod("prepareVerticalDensityPlane", CaveCarveScratch.class, int.class, int.class, int.class); prepare.setAccessible(true); @@ -168,7 +169,7 @@ public class IrisCaveCarver3DNearParityTest { doReturn(1).when(dimension).getCaveDensitySamplingStep(); IrisCaveCarver3D scalar = new IrisCaveCarver3D(engine, createProfile(false, false).setDetailWeight(0D).setAllowFluid(false)); - baseDensityField.set(scalar, density); + baseDensityField.set(scalar, NoiseProgram.compileSigned3D(density)); CaveCarveScratch scalarScratch = new CaveCarveScratch(); for (int index = 0; index < 256; index++) { scalarScratch.planeColumnIndices[index] = index; @@ -292,10 +293,10 @@ public class IrisCaveCarver3DNearParityTest { IrisCaveCarver3D carver = new IrisCaveCarver3D(engine, profile); CNG base = mock(CNG.class, withSettings().stubOnly()); doReturn(1D).when(base).noiseFastSigned3D(anyDouble(), anyDouble(), anyDouble()); - baseDensityField.set(carver, base); + baseDensityField.set(carver, NoiseProgram.compileSigned3D(base)); CNG module = mock(CNG.class, withSettings().stubOnly()); doReturn(-1D).when(module).noiseFastSigned3D(anyDouble(), anyDouble(), anyDouble()); - moduleDensityField.set(((CaveFieldModuleState[]) modulesField.get(carver))[0], module); + moduleDensityField.set(((CaveFieldModuleState[]) modulesField.get(carver))[0], NoiseProgram.compileSigned3D(module)); WriterCapture capture = createWriterCapture(128); carver.carve(capture.writer, -1, 2, fullWeights(), 0D, 0D, null, filledHeights(110)); assertEquals(512, capture.carvedCells.size()); @@ -364,7 +365,7 @@ public class IrisCaveCarver3DNearParityTest { } return -1D; }).when(density).noiseFastSigned3D(anyDouble(), anyDouble(), anyDouble()); - baseDensityField.set(carver, density); + baseDensityField.set(carver, NoiseProgram.compileSigned3D(density)); assertThrows(IllegalStateException.class, () -> carver.carve(capture.writer, 0, 0, fullWeights(), 0D, 0D, null, filledHeights(110))); } else { @@ -439,7 +440,7 @@ public class IrisCaveCarver3DNearParityTest { }).when(detail).noiseFastSigned3D(anyDouble(), anyDouble(), anyDouble()); Field detailField = IrisCaveCarver3D.class.getDeclaredField("detailDensity"); detailField.setAccessible(true); - detailField.set(carver, detail); + detailField.set(carver, NoiseProgram.compileSigned3D(detail)); WriterCapture capture = createWriterCapture(128); try (ForkJoinPool pool = new ForkJoinPool(4)) { assertEquals(0, pool.submit(() -> carver.carve(capture.writer, 0, 0, fullWeights(), @@ -772,7 +773,7 @@ public class IrisCaveCarver3DNearParityTest { rejectedDensity.put("11:10:10", -1D); rejectedDensity.put("9:10:10", -1D); CoordinateDensityCNG rejectedNoise = new CoordinateDensityCNG(rejectedDensity); - baseDensityField.set(carver, rejectedNoise); + baseDensityField.set(carver, NoiseProgram.compileSigned3D(rejectedNoise)); boolean rejected = (boolean) aquiferCupSupportMethod.invoke( carver, new CaveCarveScratch(), 10, 10, 10, 0D); @@ -781,7 +782,7 @@ public class IrisCaveCarver3DNearParityTest { assertEquals(List.of("10:9:10", "10:8:10", "11:10:10", "9:10:10"), rejectedNoise.sampledCoordinates); CoordinateDensityCNG acceptedNoise = new CoordinateDensityCNG(Map.of()); - baseDensityField.set(carver, acceptedNoise); + baseDensityField.set(carver, NoiseProgram.compileSigned3D(acceptedNoise)); boolean accepted = (boolean) aquiferCupSupportMethod.invoke( carver, new CaveCarveScratch(), 10, 10, 10, 0D); @@ -1100,7 +1101,7 @@ public class IrisCaveCarver3DNearParityTest { AtomicLong isolatedSamples = new AtomicLong(); IrisCaveCarver3D shared = new IrisCaveCarver3D(engine, createProfile(warp, modules).setAdaptiveSampling(true), new CaveDensityGrid(4096)); - baseDensityField.set(shared, new CountingCNG((CNG) baseDensityField.get(shared), sharedSamples)); + baseDensityField.set(shared, NoiseProgram.compileSigned3D(new CountingCNG((NoiseProgram) baseDensityField.get(shared), sharedSamples))); for (int chunkX = -1; chunkX <= 1; chunkX++) { for (int chunkZ = -1; chunkZ <= 1; chunkZ++) { WriterCapture sharedCapture = createWriterCapture(96); @@ -1108,7 +1109,7 @@ public class IrisCaveCarver3DNearParityTest { null, filledHeights(90)); IrisCaveCarver3D isolated = new IrisCaveCarver3D(engine, createProfile(warp, modules).setAdaptiveSampling(true)); - baseDensityField.set(isolated, new CountingCNG((CNG) baseDensityField.get(isolated), isolatedSamples)); + baseDensityField.set(isolated, NoiseProgram.compileSigned3D(new CountingCNG((NoiseProgram) baseDensityField.get(isolated), isolatedSamples))); WriterCapture isolatedCapture = createWriterCapture(96); int isolatedCarved = isolated.carve(isolatedCapture.writer, chunkX, chunkZ, fullWeights(), 0D, 0D, null, filledHeights(90)); @@ -1241,7 +1242,7 @@ public class IrisCaveCarver3DNearParityTest { new IrisCaveCarver3D(engine, profile).carve(expected.writer, -1, 2, fullWeights(), 0D, 0D, null, filledHeights(110)); IrisCaveCarver3D carver = new IrisCaveCarver3D(engine, profile); - CNG original = (CNG) baseDensityField.get(carver); + NoiseProgram original = (NoiseProgram) baseDensityField.get(carver); CNG density = mock(CNG.class, withSettings().stubOnly()); AtomicBoolean entered = new AtomicBoolean(); WriterCapture nested = createWriterCapture(128); @@ -1252,9 +1253,9 @@ public class IrisCaveCarver3DNearParityTest { double x = invocation.getArgument(0); double y = invocation.getArgument(1); double z = invocation.getArgument(2); - return original.noiseFastSigned3D(x, y, z); + return original.sampleSigned3D(x, y, z); }).when(density).noiseFastSigned3D(anyDouble(), anyDouble(), anyDouble()); - baseDensityField.set(carver, density); + baseDensityField.set(carver, NoiseProgram.compileSigned3D(density)); WriterCapture actual = createWriterCapture(128); carver.carve(actual.writer, -1, 2, fullWeights(), 0D, 0D, null, filledHeights(110)); assertTrue(entered.get()); @@ -1292,10 +1293,10 @@ public class IrisCaveCarver3DNearParityTest { } private void countSkippableSamples(IrisCaveCarver3D carver, AtomicLong samples) throws Exception { - detailDensityField.set(carver, new CountingCNG((CNG) detailDensityField.get(carver), samples)); + detailDensityField.set(carver, NoiseProgram.compileSigned3D(new CountingCNG((NoiseProgram) detailDensityField.get(carver), samples))); CaveFieldModuleState[] modules = (CaveFieldModuleState[]) modulesField.get(carver); for (CaveFieldModuleState module : modules) { - moduleDensityField.set(module, new CountingCNG((CNG) moduleDensityField.get(module), samples)); + moduleDensityField.set(module, NoiseProgram.compileSigned3D(new CountingCNG((NoiseProgram) moduleDensityField.get(module), samples))); } } @@ -1893,10 +1894,10 @@ public class IrisCaveCarver3DNearParityTest { } private static final class CountingCNG extends CNG { - private final CNG delegate; + private final NoiseProgram delegate; private final AtomicLong samples; - private CountingCNG(CNG delegate, AtomicLong samples) { + private CountingCNG(NoiseProgram delegate, AtomicLong samples) { super(new RNG(41_117L)); this.delegate = delegate; this.samples = samples; @@ -1905,7 +1906,7 @@ public class IrisCaveCarver3DNearParityTest { @Override public double noiseFastSigned3D(double x, double y, double z) { samples.incrementAndGet(); - return delegate.noiseFastSigned3D(x, y, z); + return delegate.sampleSigned3D(x, y, z); } }