mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Faster Schematic Placement
This commit is contained in:
parent
4094034aaf
commit
ad7a4503e0
@ -38,6 +38,7 @@ import ninja.bytecode.shuriken.collections.GMap;
|
|||||||
import ninja.bytecode.shuriken.collections.GSet;
|
import ninja.bytecode.shuriken.collections.GSet;
|
||||||
import ninja.bytecode.shuriken.execution.J;
|
import ninja.bytecode.shuriken.execution.J;
|
||||||
import ninja.bytecode.shuriken.execution.TaskExecutor;
|
import ninja.bytecode.shuriken.execution.TaskExecutor;
|
||||||
|
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup;
|
||||||
import ninja.bytecode.shuriken.format.F;
|
import ninja.bytecode.shuriken.format.F;
|
||||||
import ninja.bytecode.shuriken.io.IO;
|
import ninja.bytecode.shuriken.io.IO;
|
||||||
import ninja.bytecode.shuriken.json.JSONException;
|
import ninja.bytecode.shuriken.json.JSONException;
|
||||||
@ -49,7 +50,6 @@ public class Iris extends JavaPlugin implements Listener
|
|||||||
public static GSet<Chunk> refresh = new GSet<>();
|
public static GSet<Chunk> refresh = new GSet<>();
|
||||||
public static Profiler profiler;
|
public static Profiler profiler;
|
||||||
public static TaskExecutor genPool;
|
public static TaskExecutor genPool;
|
||||||
public static TaskExecutor buildPool;
|
|
||||||
public static IrisGenerator gen;
|
public static IrisGenerator gen;
|
||||||
public static Settings settings;
|
public static Settings settings;
|
||||||
public static Iris instance;
|
public static Iris instance;
|
||||||
@ -60,7 +60,6 @@ public class Iris extends JavaPlugin implements Listener
|
|||||||
|
|
||||||
public void onEnable()
|
public void onEnable()
|
||||||
{
|
{
|
||||||
PrecisionStopwatch stopwatch = PrecisionStopwatch.start();
|
|
||||||
Direction.calculatePermutations();
|
Direction.calculatePermutations();
|
||||||
dimensions = new GMap<>();
|
dimensions = new GMap<>();
|
||||||
biomes = new GMap<>();
|
biomes = new GMap<>();
|
||||||
@ -69,19 +68,19 @@ public class Iris extends JavaPlugin implements Listener
|
|||||||
values = new GMap<>();
|
values = new GMap<>();
|
||||||
instance = this;
|
instance = this;
|
||||||
settings = new Settings();
|
settings = new Settings();
|
||||||
buildPool = new TaskExecutor(getTC(), settings.performance.threadPriority, "Iris Compiler");
|
|
||||||
J.attempt(() -> createTempCache());
|
J.attempt(() -> createTempCache());
|
||||||
loadContent();
|
loadContent();
|
||||||
processContent();
|
|
||||||
gen = new IrisGenerator();
|
gen = new IrisGenerator();
|
||||||
genPool = new TaskExecutor(getTC(), settings.performance.threadPriority, "Iris Generator");
|
genPool = new TaskExecutor(getTC(), settings.performance.threadPriority, "Iris Generator");
|
||||||
getServer().getPluginManager().registerEvents((Listener) this, this);
|
getServer().getPluginManager().registerEvents((Listener) this, this);
|
||||||
getCommand("iris").setExecutor(new CommandIris());
|
getCommand("iris").setExecutor(new CommandIris());
|
||||||
getCommand("ish").setExecutor(new CommandIsh());
|
getCommand("ish").setExecutor(new CommandIsh());
|
||||||
new WandManager();
|
new WandManager();
|
||||||
|
loadComplete();
|
||||||
|
}
|
||||||
|
|
||||||
// Debug world regens
|
private void loadComplete()
|
||||||
|
{
|
||||||
if(settings.performance.loadonstart)
|
if(settings.performance.loadonstart)
|
||||||
{
|
{
|
||||||
GSet<String> ws = new GSet<>();
|
GSet<String> ws = new GSet<>();
|
||||||
@ -101,24 +100,6 @@ public class Iris extends JavaPlugin implements Listener
|
|||||||
Bukkit.unloadWorld(i, false);
|
Bukkit.unloadWorld(i, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double ms = stopwatch.getMilliseconds();
|
|
||||||
|
|
||||||
J.a(() ->
|
|
||||||
{
|
|
||||||
J.sleep(5000);
|
|
||||||
L.i("Iris Startup Took " + F.duration(ms, 2));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processContent()
|
|
||||||
{
|
|
||||||
L.v("Processing Content");
|
|
||||||
|
|
||||||
for(SchematicGroup i : schematics.v())
|
|
||||||
{
|
|
||||||
i.processVariants();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File internalResource(String resource)
|
private static File internalResource(String resource)
|
||||||
@ -158,6 +139,7 @@ public class Iris extends JavaPlugin implements Listener
|
|||||||
|
|
||||||
private void loadContent()
|
private void loadContent()
|
||||||
{
|
{
|
||||||
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
L.i("Loading Content");
|
L.i("Loading Content");
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -177,11 +159,23 @@ public class Iris extends JavaPlugin implements Listener
|
|||||||
{
|
{
|
||||||
m += i.size();
|
m += i.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
L.v("Processing Content");
|
||||||
|
|
||||||
|
TaskExecutor exf = new TaskExecutor(settings.performance.compilerThreads, settings.performance.compilerPriority, "Iris Compiler");
|
||||||
|
TaskGroup gg = exf.startWork();
|
||||||
|
for(SchematicGroup i : schematics.v())
|
||||||
|
{
|
||||||
|
gg.queue(i::processVariants);
|
||||||
|
}
|
||||||
|
gg.execute();
|
||||||
|
exf.close();
|
||||||
|
|
||||||
L.i("Dimensions: " + dimensions.size());
|
L.i("Dimensions: " + dimensions.size());
|
||||||
L.i("Biomes: " + biomes.size());
|
L.i("Biomes: " + biomes.size());
|
||||||
L.i("Object Groups: " + schematics.size());
|
L.i("Object Groups: " + schematics.size());
|
||||||
L.i("Objects: " + F.f(m));
|
L.i("Objects: " + F.f(m));
|
||||||
|
L.i("Compilation Time: " + F.duration(p.getMilliseconds(), 2));
|
||||||
L.flush();
|
L.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +189,8 @@ public class Iris extends JavaPlugin implements Listener
|
|||||||
return Runtime.getRuntime().availableProcessors();
|
return Runtime.getRuntime().availableProcessors();
|
||||||
case SINGLE_THREADED:
|
case SINGLE_THREADED:
|
||||||
return 1;
|
return 1;
|
||||||
|
case DOUBLE_CPU:
|
||||||
|
return Runtime.getRuntime().availableProcessors() * 2;
|
||||||
case UNLIMITED:
|
case UNLIMITED:
|
||||||
return -1;
|
return -1;
|
||||||
case EXPLICIT:
|
case EXPLICIT:
|
||||||
|
@ -9,11 +9,14 @@ public class Settings
|
|||||||
|
|
||||||
public static class PerformanceSettings
|
public static class PerformanceSettings
|
||||||
{
|
{
|
||||||
public PerformanceMode performanceMode = PerformanceMode.MATCH_CPU;
|
public PerformanceMode performanceMode = PerformanceMode.DOUBLE_CPU;
|
||||||
public int threadCount = 1;
|
public int threadCount = 1;
|
||||||
public int threadPriority = Thread.MIN_PRIORITY;
|
public int threadPriority = Thread.MIN_PRIORITY;
|
||||||
public boolean loadonstart = false;
|
public boolean loadonstart = true;
|
||||||
public boolean fastPlacement = false;
|
public boolean fastPlacement = false;
|
||||||
|
public int compilerThreads = 4;
|
||||||
|
public int compilerPriority = Thread.MAX_PRIORITY;
|
||||||
|
public int decorationAccuracy = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GeneratorSettings
|
public static class GeneratorSettings
|
||||||
|
@ -20,8 +20,7 @@ import ninja.bytecode.iris.generator.layer.GenLayerOreGold;
|
|||||||
import ninja.bytecode.iris.generator.layer.GenLayerOreIron;
|
import ninja.bytecode.iris.generator.layer.GenLayerOreIron;
|
||||||
import ninja.bytecode.iris.generator.layer.GenLayerOreLapis;
|
import ninja.bytecode.iris.generator.layer.GenLayerOreLapis;
|
||||||
import ninja.bytecode.iris.generator.layer.GenLayerRidge;
|
import ninja.bytecode.iris.generator.layer.GenLayerRidge;
|
||||||
import ninja.bytecode.iris.generator.populator.BiomeBiasSchematicPopulator;
|
import ninja.bytecode.iris.generator.populator.ObjectPopulator;
|
||||||
import ninja.bytecode.iris.schematic.Schematic;
|
|
||||||
import ninja.bytecode.iris.schematic.SchematicGroup;
|
import ninja.bytecode.iris.schematic.SchematicGroup;
|
||||||
import ninja.bytecode.iris.spec.IrisBiome;
|
import ninja.bytecode.iris.spec.IrisBiome;
|
||||||
import ninja.bytecode.iris.spec.IrisDimension;
|
import ninja.bytecode.iris.spec.IrisDimension;
|
||||||
@ -255,28 +254,13 @@ public class IrisGenerator extends ParallelChunkGenerator
|
|||||||
|
|
||||||
if(Iris.settings.gen.doSchematics)
|
if(Iris.settings.gen.doSchematics)
|
||||||
{
|
{
|
||||||
int b = 0;
|
p.add(new ObjectPopulator(this));
|
||||||
int sch = 0;
|
|
||||||
for(IrisBiome i : IrisBiome.getAllBiomes().copy().add(dim.getBiomes()))
|
|
||||||
{
|
|
||||||
b++;
|
|
||||||
L.i("Processing Populators for Biome " + i.getName());
|
|
||||||
|
|
||||||
for(String j : i.getSchematicGroups().keySet())
|
|
||||||
{
|
|
||||||
SchematicGroup gs = loadSchematics(j);
|
|
||||||
sch += gs.size();
|
|
||||||
p.add(new BiomeBiasSchematicPopulator(i.getSchematicGroups().get(j), i, gs.getSchematics().toArray(new Schematic[gs.size()])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
L.i("Initialized " + b + " Biomes with " + p.size() + " Populators using " + sch + " Schematics");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SchematicGroup loadSchematics(String folder)
|
public SchematicGroup loadSchematics(String folder)
|
||||||
{
|
{
|
||||||
return Iris.schematics.get(folder);
|
return Iris.schematics.get(folder);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,121 @@
|
|||||||
|
package ninja.bytecode.iris.generator.populator;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.generator.BlockPopulator;
|
||||||
|
|
||||||
|
import ninja.bytecode.iris.Iris;
|
||||||
|
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||||
|
import ninja.bytecode.iris.schematic.SchematicGroup;
|
||||||
|
import ninja.bytecode.iris.spec.IrisBiome;
|
||||||
|
import ninja.bytecode.shuriken.collections.GMap;
|
||||||
|
import ninja.bytecode.shuriken.collections.GSet;
|
||||||
|
import ninja.bytecode.shuriken.math.M;
|
||||||
|
|
||||||
|
public class ObjectPopulator extends BlockPopulator
|
||||||
|
{
|
||||||
|
private GMap<Biome, IrisBiome> biomeMap;
|
||||||
|
private GMap<Biome, GMap<SchematicGroup, Double>> populationCache;
|
||||||
|
|
||||||
|
public ObjectPopulator(IrisGenerator generator)
|
||||||
|
{
|
||||||
|
biomeMap = new GMap<>();
|
||||||
|
populationCache = new GMap<>();
|
||||||
|
|
||||||
|
for(IrisBiome i : generator.getLoadedBiomes())
|
||||||
|
{
|
||||||
|
biomeMap.put(i.getRealBiome(), i);
|
||||||
|
|
||||||
|
GMap<SchematicGroup, Double> gk = new GMap<>();
|
||||||
|
|
||||||
|
for(String j : i.getSchematicGroups().k())
|
||||||
|
{
|
||||||
|
gk.put(Iris.schematics.get(j), i.getSchematicGroups().get(j));
|
||||||
|
}
|
||||||
|
|
||||||
|
populationCache.put(i.getRealBiome(), gk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void populate(World world, Random random, Chunk source)
|
||||||
|
{
|
||||||
|
GSet<Biome> hits = new GSet<>();
|
||||||
|
|
||||||
|
for(int i = 0; i < Iris.settings.performance.decorationAccuracy; i++)
|
||||||
|
{
|
||||||
|
int x = (source.getX() << 4) + random.nextInt(16);
|
||||||
|
int z = (source.getZ() << 4) + random.nextInt(16);
|
||||||
|
Biome biome = world.getBiome(x, z);
|
||||||
|
|
||||||
|
if(hits.contains(biome))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IrisBiome ibiome = biomeMap.get(biome);
|
||||||
|
|
||||||
|
if(ibiome == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GMap<SchematicGroup, Double> objects = populationCache.get(biome);
|
||||||
|
|
||||||
|
if(objects == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
hits.add(biome);
|
||||||
|
populate(world, random, source, biome, objects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populate(World world, Random random, Chunk source, Biome biome, GMap<SchematicGroup, Double> objects)
|
||||||
|
{
|
||||||
|
for(SchematicGroup i : objects.k())
|
||||||
|
{
|
||||||
|
for(int j = 0; j < getTries(objects.get(i)); j++)
|
||||||
|
{
|
||||||
|
int x = (source.getX() << 4) + random.nextInt(16);
|
||||||
|
int z = (source.getZ() << 4) + random.nextInt(16);
|
||||||
|
Block b = world.getHighestBlockAt(x, z);
|
||||||
|
|
||||||
|
if(!b.getRelative(BlockFace.DOWN).getType().isSolid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.getSchematics().get(random.nextInt(i.getSchematics().size())).place(world, x, b.getY() - 1, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTries(double chance)
|
||||||
|
{
|
||||||
|
if(chance <= 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Math.floor(chance) == chance)
|
||||||
|
{
|
||||||
|
return (int) chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
int floor = (int) Math.floor(chance);
|
||||||
|
|
||||||
|
if(chance - floor > 0 && M.r(chance - floor))
|
||||||
|
{
|
||||||
|
floor++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return floor;
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
import ninja.bytecode.iris.Iris;
|
import ninja.bytecode.iris.Iris;
|
||||||
import ninja.bytecode.iris.util.Direction;
|
import ninja.bytecode.iris.util.Direction;
|
||||||
import ninja.bytecode.shuriken.collections.GList;
|
import ninja.bytecode.shuriken.collections.GList;
|
||||||
|
import ninja.bytecode.shuriken.execution.TaskExecutor;
|
||||||
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup;
|
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup;
|
||||||
import ninja.bytecode.shuriken.io.IO;
|
import ninja.bytecode.shuriken.io.IO;
|
||||||
import ninja.bytecode.shuriken.logging.L;
|
import ninja.bytecode.shuriken.logging.L;
|
||||||
@ -122,9 +123,10 @@ public class SchematicGroup
|
|||||||
GList<Schematic> inject = new GList<>();
|
GList<Schematic> inject = new GList<>();
|
||||||
L.v("Processing " + name + " Objects");
|
L.v("Processing " + name + " Objects");
|
||||||
L.v("# Creating Rotations for " + getSchematics().size() + " Objects");
|
L.v("# Creating Rotations for " + getSchematics().size() + " Objects");
|
||||||
|
String x = Thread.currentThread().getName();
|
||||||
ReentrantLock rr = new ReentrantLock();
|
ReentrantLock rr = new ReentrantLock();
|
||||||
TaskGroup gg = Iris.buildPool.startWork();
|
TaskExecutor ex = new TaskExecutor(Iris.settings.performance.compilerThreads, Iris.settings.performance.compilerPriority, x + "/Subroutine ");
|
||||||
|
TaskGroup gg = ex.startWork();
|
||||||
for(Schematic i : getSchematics())
|
for(Schematic i : getSchematics())
|
||||||
{
|
{
|
||||||
for(Direction j : new Direction[] {Direction.S, Direction.E, Direction.W})
|
for(Direction j : new Direction[] {Direction.S, Direction.E, Direction.W})
|
||||||
@ -142,7 +144,7 @@ public class SchematicGroup
|
|||||||
}
|
}
|
||||||
|
|
||||||
gg.execute();
|
gg.execute();
|
||||||
gg = Iris.buildPool.startWork();
|
gg = ex.startWork();
|
||||||
getSchematics().add(inject);
|
getSchematics().add(inject);
|
||||||
L.v("# Generated " + inject.size() + " Rotated Objects to " + getName());
|
L.v("# Generated " + inject.size() + " Rotated Objects to " + getName());
|
||||||
|
|
||||||
@ -159,5 +161,46 @@ public class SchematicGroup
|
|||||||
}
|
}
|
||||||
|
|
||||||
gg.execute();
|
gg.execute();
|
||||||
|
ex.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((flags == null) ? 0 : flags.hashCode());
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
result = prime * result + priority;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
if(this == obj)
|
||||||
|
return true;
|
||||||
|
if(obj == null)
|
||||||
|
return false;
|
||||||
|
if(getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
SchematicGroup other = (SchematicGroup) obj;
|
||||||
|
if(flags == null)
|
||||||
|
{
|
||||||
|
if(other.flags != null)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(!flags.equals(other.flags))
|
||||||
|
return false;
|
||||||
|
if(name == null)
|
||||||
|
{
|
||||||
|
if(other.name != null)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
if(priority != other.priority)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import org.bukkit.World.Environment;
|
|||||||
import ninja.bytecode.iris.Iris;
|
import ninja.bytecode.iris.Iris;
|
||||||
import ninja.bytecode.shuriken.collections.GList;
|
import ninja.bytecode.shuriken.collections.GList;
|
||||||
import ninja.bytecode.shuriken.execution.J;
|
import ninja.bytecode.shuriken.execution.J;
|
||||||
|
import ninja.bytecode.shuriken.execution.TaskExecutor;
|
||||||
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup;
|
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup;
|
||||||
import ninja.bytecode.shuriken.json.JSONArray;
|
import ninja.bytecode.shuriken.json.JSONArray;
|
||||||
import ninja.bytecode.shuriken.json.JSONException;
|
import ninja.bytecode.shuriken.json.JSONException;
|
||||||
@ -74,7 +75,8 @@ public class IrisDimension
|
|||||||
private GList<IrisBiome> biomesFromArray(JSONArray a) throws JSONException, IOException
|
private GList<IrisBiome> biomesFromArray(JSONArray a) throws JSONException, IOException
|
||||||
{
|
{
|
||||||
GList<IrisBiome> b = new GList<>();
|
GList<IrisBiome> b = new GList<>();
|
||||||
TaskGroup g = Iris.buildPool.startWork();
|
TaskExecutor ex= new TaskExecutor(Iris.settings.performance.compilerThreads, Iris.settings.performance.compilerPriority, "Iris Dim Compiler");
|
||||||
|
TaskGroup g = ex.startWork();
|
||||||
ReentrantLock lock = new ReentrantLock();
|
ReentrantLock lock = new ReentrantLock();
|
||||||
|
|
||||||
for(int i = 0; i < a.length(); i++)
|
for(int i = 0; i < a.length(); i++)
|
||||||
@ -90,6 +92,7 @@ public class IrisDimension
|
|||||||
}
|
}
|
||||||
|
|
||||||
g.execute();
|
g.execute();
|
||||||
|
ex.close();
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ public enum PerformanceMode
|
|||||||
SINGLE_THREADED,
|
SINGLE_THREADED,
|
||||||
UNLIMITED,
|
UNLIMITED,
|
||||||
MATCH_CPU,
|
MATCH_CPU,
|
||||||
|
DOUBLE_CPU,
|
||||||
HALF_CPU,
|
HALF_CPU,
|
||||||
EXPLICIT,
|
EXPLICIT,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user