This commit is contained in:
Daniel Mills 2020-01-21 15:43:00 -05:00
parent 1e633278dd
commit 0e12c6906f
7 changed files with 220 additions and 31 deletions

View File

@ -17,7 +17,6 @@ import ninja.bytecode.iris.util.Direction;
import ninja.bytecode.iris.util.IrisController; import ninja.bytecode.iris.util.IrisController;
import ninja.bytecode.iris.util.IrisControllerSet; import ninja.bytecode.iris.util.IrisControllerSet;
import ninja.bytecode.shuriken.logging.L; import ninja.bytecode.shuriken.logging.L;
import ninja.bytecode.shuriken.math.CNG;
public class Iris extends JavaPlugin implements Listener public class Iris extends JavaPlugin implements Listener
{ {

View File

@ -1,6 +1,7 @@
package ninja.bytecode.iris; package ninja.bytecode.iris;
import ninja.bytecode.iris.util.InterpolationMode; import ninja.bytecode.iris.util.InterpolationMode;
import ninja.bytecode.iris.util.ObjectMode;
import ninja.bytecode.iris.util.PerformanceMode; import ninja.bytecode.iris.util.PerformanceMode;
public class Settings public class Settings
@ -10,14 +11,15 @@ public class Settings
public static class PerformanceSettings public static class PerformanceSettings
{ {
public PerformanceMode performanceMode = PerformanceMode.DOUBLE_CPU; public PerformanceMode performanceMode = PerformanceMode.HALF_CPU;
public ObjectMode objectMode = ObjectMode.FAST_LIGHTING;
public boolean fastMode = false; public boolean fastMode = false;
public int threadPriority = Thread.MAX_PRIORITY; public int threadPriority = Thread.MAX_PRIORITY;
public int threadCount = 4; public int threadCount = 4;
public boolean debugMode = true; public boolean debugMode = true;
public int decorationAccuracy = 2; public int decorationAccuracy = 2;
public boolean noObjectFail = false; public boolean noObjectFail = false;
public boolean verbose = false; public boolean verbose = true;
public int placeHistoryLimit = 8192; public int placeHistoryLimit = 8192;
} }
@ -42,7 +44,6 @@ public class Settings
public double caveScale = 1.2; public double caveScale = 1.2;
public double biomeScale = 0.65; public double biomeScale = 0.65;
public boolean flatBedrock = true; public boolean flatBedrock = true;
public boolean genObjects = true;
public boolean genCarving = true; public boolean genCarving = true;
public boolean genCaverns = true; public boolean genCaverns = true;
public boolean genCaves = true; public boolean genCaves = true;

View File

@ -1,13 +1,13 @@
package ninja.bytecode.iris.generator; package ninja.bytecode.iris.generator;
import java.util.List;
import java.util.Random; import java.util.Random;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.generator.ChunkGenerator.BiomeGrid; import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator.ChunkData;
import org.bukkit.util.NumberConversions; import org.bukkit.util.NumberConversions;
import mortar.util.text.C; import mortar.util.text.C;
@ -28,12 +28,12 @@ import ninja.bytecode.iris.generator.parallax.ParallaxWorldGenerator;
import ninja.bytecode.iris.pack.BiomeType; import ninja.bytecode.iris.pack.BiomeType;
import ninja.bytecode.iris.pack.CompiledDimension; import ninja.bytecode.iris.pack.CompiledDimension;
import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.pack.IrisDimension;
import ninja.bytecode.iris.pack.IrisRegion; import ninja.bytecode.iris.pack.IrisRegion;
import ninja.bytecode.iris.util.ChunkPlan; import ninja.bytecode.iris.util.ChunkPlan;
import ninja.bytecode.iris.util.InterpolationMode; import ninja.bytecode.iris.util.InterpolationMode;
import ninja.bytecode.iris.util.IrisInterpolation; import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.MB; import ninja.bytecode.iris.util.MB;
import ninja.bytecode.iris.util.ObjectMode;
import ninja.bytecode.iris.util.SChunkVector; import ninja.bytecode.iris.util.SChunkVector;
import ninja.bytecode.shuriken.bench.PrecisionStopwatch; import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GList;
@ -137,7 +137,11 @@ public class IrisGenerator extends ParallaxWorldGenerator
glCliffs = new GenLayerCliffs(this, world, random, rTerrain.nextParallelRNG(9)); glCliffs = new GenLayerCliffs(this, world, random, rTerrain.nextParallelRNG(9));
scatterCache = new double[16][][]; scatterCache = new double[16][][];
scatter = new CNG(rTerrain.nextParallelRNG(52), 1, 1).scale(10); scatter = new CNG(rTerrain.nextParallelRNG(52), 1, 1).scale(10);
god = new GenObjectDecorator(this);
if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX))
{
god = new GenObjectDecorator(this);
}
//@done //@done
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
@ -303,13 +307,26 @@ public class IrisGenerator extends ParallaxWorldGenerator
return glBiome.getRegion(biome.getRegion()); return glBiome.getRegion(biome.getRegion());
} }
@Override
public List<BlockPopulator> getDefaultPopulators(World world)
{
GList<BlockPopulator> p = new GList<>();
if(Iris.settings.performance.objectMode.equals(ObjectMode.FAST_LIGHTING) || Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING))
{
p.add(god = new GenObjectDecorator(this));
}
return p;
}
@Override @Override
public void onGenParallax(int x, int z, Random random) public void onGenParallax(int x, int z, Random random)
{ {
try try
{ {
PrecisionStopwatch s = getMetrics().start(); PrecisionStopwatch s = getMetrics().start();
god.decorateParallax(x, z, random); god.populateParallax(x, z, random);
String xx = "x" + getParallaxSize().getX() * getParallaxSize().getZ(); String xx = "x" + getParallaxSize().getX() * getParallaxSize().getZ();
getMetrics().stop("object:" + xx + ":.:ms:/parallax", s); getMetrics().stop("object:" + xx + ":.:ms:/parallax", s);
} }

View File

@ -3,7 +3,11 @@ package ninja.bytecode.iris.generator.genobject;
import java.util.Collections; import java.util.Collections;
import java.util.Random; import java.util.Random;
import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.generator.BlockPopulator;
import mortar.logic.format.F; import mortar.logic.format.F;
import mortar.util.text.C; import mortar.util.text.C;
@ -12,9 +16,12 @@ import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.parallax.ParallaxCache; import ninja.bytecode.iris.generator.parallax.ParallaxCache;
import ninja.bytecode.iris.generator.placer.AtomicParallaxPlacer; import ninja.bytecode.iris.generator.placer.AtomicParallaxPlacer;
import ninja.bytecode.iris.generator.placer.BukkitPlacer;
import ninja.bytecode.iris.generator.placer.NMSPlacer;
import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.util.IPlacer; import ninja.bytecode.iris.util.IPlacer;
import ninja.bytecode.iris.util.MB; import ninja.bytecode.iris.util.MB;
import ninja.bytecode.iris.util.ObjectMode;
import ninja.bytecode.iris.util.SMCAVector; import ninja.bytecode.iris.util.SMCAVector;
import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.collections.GMap;
@ -24,7 +31,7 @@ import ninja.bytecode.shuriken.logging.L;
import ninja.bytecode.shuriken.math.M; import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG; import ninja.bytecode.shuriken.math.RNG;
public class GenObjectDecorator public class GenObjectDecorator extends BlockPopulator
{ {
private GList<PlacedObject> placeHistory; private GList<PlacedObject> placeHistory;
private GMap<IrisBiome, GList<GenObjectGroup>> orderCache; private GMap<IrisBiome, GList<GenObjectGroup>> orderCache;
@ -92,7 +99,151 @@ public class GenObjectDecorator
L.i("Population Cache is " + populationCache.size()); L.i("Population Cache is " + populationCache.size());
} }
public void decorateParallax(int cx, int cz, Random random) @Override
public void populate(World world, Random random, Chunk source)
{
try
{
if(g.isDisposed())
{
placeHistory.clear();
return;
}
GSet<IrisBiome> hits = new GSet<>();
int cx = source.getX();
int cz = source.getZ();
for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++)
{
int x = (cx << 4) + random.nextInt(16);
int z = (cz << 4) + random.nextInt(16);
IrisBiome biome = g.getBiome((int) g.getOffsetX(x), (int) g.getOffsetZ(z));
if(hits.contains(biome))
{
continue;
}
GMap<GenObjectGroup, Double> objects = populationCache.get(biome);
if(objects == null)
{
continue;
}
hits.add(biome);
populate(world, cx, cz, random, biome);
}
}
catch(Throwable e)
{
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
private void populate(World world, int cx, int cz, Random random, IrisBiome biome)
{
for(GenObjectGroup i : orderCache.get(biome))
{
if(biome.getSchematicGroups().get(i.getName()) == null)
{
L.w(C.YELLOW + "Cannot find chance for " + C.RED + i.getName() + C.YELLOW + " in Biome " + C.RED + biome.getName());
continue;
}
for(int j = 0; j < getTries(biome.getSchematicGroups().get(i.getName())); j++)
{
if(M.r(Iris.settings.gen.objectDensity))
{
GenObject go = i.getSchematics().get(random.nextInt(i.getSchematics().size()));
int x = (cx << 4) + random.nextInt(16);
int z = (cz << 4) + random.nextInt(16);
if(i.getWorldChance() >= 0D)
{
int rngx = (int) Math.floor(x / (double) (i.getWorldRadius() == 0 ? 32 : i.getWorldRadius()));
int rngz = (int) Math.floor(z / (double) (i.getWorldRadius() == 0 ? 32 : i.getWorldRadius()));
if(new RNG(new SMCAVector(rngx, rngz).hashCode()).nextDouble() < i.getWorldChance())
{
if(Iris.settings.performance.verbose)
{
L.w(C.WHITE + "Object " + C.YELLOW + i.getName() + "/*" + C.WHITE + " failed to place due to a world chance.");
}
break;
}
}
int by = world.getHighestBlockYAt(x, z);
Block b = world.getBlockAt(x, by - 1, z);
MB mb = MB.of(b.getType(), b.getData());
if(!Iris.settings.performance.noObjectFail)
{
if(!mb.material.isSolid() || !biome.isSurface(mb.material))
{
if(Iris.settings.performance.verbose)
{
L.w(C.WHITE + "Object " + C.YELLOW + i.getName() + "/*" + C.WHITE + " failed to place in " + C.YELLOW + mb.material.toString().toLowerCase() + C.WHITE + " at " + C.YELLOW + F.f(x) + " " + F.f(by) + " " + F.f(z));
}
return;
}
}
if(Iris.settings.performance.objectMode.equals(ObjectMode.FAST_LIGHTING))
{
placer = new NMSPlacer(world);
}
else if(Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING_PHYSICS))
{
placer = new BukkitPlacer(world, true);
}
else if(Iris.settings.performance.objectMode.equals(ObjectMode.LIGHTING))
{
placer = new BukkitPlacer(world, false);
}
Location start = go.place(x, by, z, placer);
if(start != null)
{
g.hitObject();
if(Iris.settings.performance.verbose)
{
L.v(C.GRAY + "Placed " + C.DARK_GREEN + i.getName() + C.WHITE + "/" + C.DARK_GREEN + go.getName() + C.GRAY + " at " + C.DARK_GREEN + F.f(start.getBlockX()) + " " + F.f(start.getBlockY()) + " " + F.f(start.getBlockZ()));
}
if(Iris.settings.performance.debugMode)
{
placeHistory.add(new PlacedObject(start.getBlockX(), start.getBlockY(), start.getBlockZ(), i.getName() + ":" + go.getName()));
if(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
{
while(placeHistory.size() > Iris.settings.performance.placeHistoryLimit)
{
placeHistory.remove(0);
}
}
}
}
}
}
}
if(placer != null && cl.flip())
{
placer.flush();
}
}
public void populateParallax(int cx, int cz, Random random)
{ {
try try
{ {
@ -124,7 +275,7 @@ public class GenObjectDecorator
} }
hits.add(biome); hits.add(biome);
populate(cx, cz, random, biome, cache); populateParallax(cx, cz, random, biome, cache);
} }
} }
@ -134,7 +285,7 @@ public class GenObjectDecorator
} }
} }
private void populate(int cx, int cz, Random random, IrisBiome biome, ParallaxCache cache) private void populateParallax(int cx, int cz, Random random, IrisBiome biome, ParallaxCache cache)
{ {
for(GenObjectGroup i : orderCache.get(biome)) for(GenObjectGroup i : orderCache.get(biome))
{ {

View File

@ -15,17 +15,16 @@ import org.bukkit.event.world.WorldUnloadEvent;
import mortar.api.nms.NMP; import mortar.api.nms.NMP;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.controller.TimingsController;
import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.atomics.AtomicChunkData; import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
import ninja.bytecode.iris.util.ChunkPlan; import ninja.bytecode.iris.util.ChunkPlan;
import ninja.bytecode.iris.util.IrisWorldData; import ninja.bytecode.iris.util.IrisWorldData;
import ninja.bytecode.iris.util.ObjectMode;
import ninja.bytecode.iris.util.SChunkVector; import ninja.bytecode.iris.util.SChunkVector;
import ninja.bytecode.shuriken.bench.PrecisionStopwatch; import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
import ninja.bytecode.shuriken.collections.GSet; import ninja.bytecode.shuriken.collections.GSet;
import ninja.bytecode.shuriken.execution.ChronoLatch; import ninja.bytecode.shuriken.execution.ChronoLatch;
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup; import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup;
import ninja.bytecode.shuriken.format.F;
import ninja.bytecode.shuriken.math.RNG; import ninja.bytecode.shuriken.math.RNG;
public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator implements Listener public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator implements Listener
@ -72,7 +71,7 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl
return; return;
} }
if(!Iris.settings.performance.fastMode && e.getWorld().equals(world)) if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX) && !Iris.settings.performance.fastMode && e.getWorld().equals(world))
{ {
NMP.host.relight(e.getChunk()); NMP.host.relight(e.getChunk());
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> fix.add(e.getChunk()), 20); Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> fix.add(e.getChunk()), 20);
@ -141,10 +140,8 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl
public final ChunkPlan initChunk(World world, int x, int z, Random random) public final ChunkPlan initChunk(World world, int x, int z, Random random)
{ {
PrecisionStopwatch ps = PrecisionStopwatch.start(); PrecisionStopwatch ps = PrecisionStopwatch.start();
int gg = 0;
int gx = 0;
TaskGroup g = startWork(); TaskGroup g = startWork();
if(Iris.settings.gen.genObjects) if(Iris.settings.performance.objectMode.equals(ObjectMode.PARALLAX))
{ {
for(int ii = Iris.settings.performance.fastMode ? -1 : -(getParallaxSize().getX() / 2) - 1; ii < (Iris.settings.performance.fastMode ? 1 : ((getParallaxSize().getX() / 2) + 1)); ii++) for(int ii = Iris.settings.performance.fastMode ? -1 : -(getParallaxSize().getX() / 2) - 1; ii < (Iris.settings.performance.fastMode ? 1 : ((getParallaxSize().getX() / 2) + 1)); ii++)
{ {
@ -152,7 +149,6 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl
for(int jj = Iris.settings.performance.fastMode ? -1 : -(getParallaxSize().getZ() / 2) - 1; jj < (Iris.settings.performance.fastMode ? 1 : ((getParallaxSize().getZ() / 2) + 1)); jj++) for(int jj = Iris.settings.performance.fastMode ? -1 : -(getParallaxSize().getZ() / 2) - 1; jj < (Iris.settings.performance.fastMode ? 1 : ((getParallaxSize().getZ() / 2) + 1)); jj++)
{ {
gx++;
int j = jj; int j = jj;
int cx = x + i; int cx = x + i;
int cz = z + j; int cz = z + j;
@ -164,23 +160,14 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl
onGenParallax(cx, cz, getRMaster(cx, cz, -59328)); onGenParallax(cx, cz, getRMaster(cx, cz, -59328));
getWorldData().getChunk(cx, cz); getWorldData().getChunk(cx, cz);
}); });
gg++;
} }
} }
} }
} }
double a = ps.getMilliseconds();
double b = g.execute().timeElapsed;
((IrisGenerator) this).getMetrics().put("parallax:ms:/chunk", ps.getMillis()); ((IrisGenerator) this).getMetrics().put("parallax:ms:/chunk", ps.getMillis());
if(Iris.settings.performance.verbose)
{
System.out.println("MS: " + F.duration(Iris.getController(TimingsController.class).getResult("terrain"), 2) + " \tQMS: " + F.duration(a, 2) + " " + " \tEMS: " + F.duration(b, 2) + "\tSCG: " + gg + " / " + gx + " (" + F.pc(((double) gg / (double) gx)) + ") " + " \tTC: " + F.f(getWorldData().getLoadedChunks().size()) + " \tTR: " + getWorldData().getLoadedRegions().size());
}
return onInitChunk(world, x, z, random); return onInitChunk(world, x, z, random);
} }

View File

@ -10,6 +10,7 @@ import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.controller.PackController; import ninja.bytecode.iris.controller.PackController;
import ninja.bytecode.iris.generator.layer.BiomeNoiseGenerator; import ninja.bytecode.iris.generator.layer.BiomeNoiseGenerator;
import ninja.bytecode.iris.util.MB; import ninja.bytecode.iris.util.MB;
import ninja.bytecode.iris.util.ObjectMode;
import ninja.bytecode.iris.util.PolygonGenerator; import ninja.bytecode.iris.util.PolygonGenerator;
import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.collections.GMap;
@ -265,7 +266,7 @@ public class IrisBiome
J.attempt(() -> scatterSurfaceSub = o.getString("subSurfaceType").equalsIgnoreCase("scatter")); J.attempt(() -> scatterSurfaceSub = o.getString("subSurfaceType").equalsIgnoreCase("scatter"));
J.attempt(() -> J.attempt(() ->
{ {
if(Iris.settings.gen.genObjects) if(!Iris.settings.performance.objectMode.equals(ObjectMode.NONE))
{ {
schematicGroups = strFromJSON(o.getJSONArray("objects")); schematicGroups = strFromJSON(o.getJSONArray("objects"));
} }
@ -277,7 +278,7 @@ public class IrisBiome
if(chain) if(chain)
{ {
if(Iris.settings.gen.genObjects) if(!Iris.settings.performance.objectMode.equals(ObjectMode.NONE))
{ {
for(String i : schematicGroups.k()) for(String i : schematicGroups.k())
{ {

View File

@ -0,0 +1,33 @@
package ninja.bytecode.iris.util;
public enum ObjectMode
{
/**
* Technically the fasted mode. I.e. Do nothing
*/
NONE,
/**
* The fastest placer. Places without updating lighting or physics
*
* Lighting is applied later with packets
*/
FAST_LIGHTING,
/**
* Somewhat slow but produces near-perfect results. Updates lighting.
*/
LIGHTING,
/**
* Somewhat slow but produces near-perfect results. Updates lighting & physics
*/
LIGHTING_PHYSICS,
/**
* Somewhat slow but never cascades and is instantly placed with terrain
*
* Lighting is applied later with packets
*/
PARALLAX;
}