mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-26 10:39:07 +00:00
@@ -21,7 +21,6 @@ package com.volmit.iris;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.ServerConfigurator;
|
||||
import com.volmit.iris.core.link.*;
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ServerConfigurator {
|
||||
}
|
||||
|
||||
private static void increaseKeepAliveSpigot() throws IOException, InvalidConfigurationException {
|
||||
File spigotConfig = new File("spigot.yml");
|
||||
File spigotConfig = new File("config/spigot.yml");
|
||||
FileConfiguration f = new YamlConfiguration();
|
||||
f.load(spigotConfig);
|
||||
long tt = f.getLong("settings.timeout-time");
|
||||
@@ -69,15 +69,15 @@ public class ServerConfigurator {
|
||||
}
|
||||
|
||||
private static void increasePaperWatchdog() throws IOException, InvalidConfigurationException {
|
||||
File spigotConfig = new File("paper.yml");
|
||||
File spigotConfig = new File("config/paper-global.yml");
|
||||
FileConfiguration f = new YamlConfiguration();
|
||||
f.load(spigotConfig);
|
||||
long tt = f.getLong("settings.watchdog.early-warning-delay");
|
||||
long tt = f.getLong("watchdog.early-warning-delay");
|
||||
|
||||
if(tt < TimeUnit.MINUTES.toMillis(3)) {
|
||||
Iris.warn("Updating paper.yml watchdog early-warning-delay: " + tt + " -> " + TimeUnit.MINUTES.toMillis(3) + " (3 minutes)");
|
||||
Iris.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value.");
|
||||
f.set("settings.watchdog.early-warning-delay", TimeUnit.MINUTES.toMillis(3));
|
||||
f.set("watchdog.early-warning-delay", TimeUnit.MINUTES.toMillis(3));
|
||||
f.save(spigotConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ public class CommandIris implements DecreeExecutor {
|
||||
public void download(
|
||||
@Param(name = "pack", description = "The pack to download", defaultValue = "overworld", aliases = "project")
|
||||
String pack,
|
||||
@Param(name = "branch", description = "The branch to download from", defaultValue = "master")
|
||||
@Param(name = "branch", description = "The branch to download from", defaultValue = "main")
|
||||
String branch,
|
||||
@Param(name = "trim", description = "Whether or not to download a trimmed version (do not enable when editing)", defaultValue = "false")
|
||||
boolean trim,
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
package com.volmit.iris.core.commands;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.link.WorldEditLink;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
|
||||
@@ -20,7 +20,7 @@ package com.volmit.iris.core.nms;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.nms.v18_2.NMSBinding18_2;
|
||||
import com.volmit.iris.core.nms.v19_1.NMSBinding19_1;
|
||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -28,7 +28,7 @@ import org.bukkit.Bukkit;
|
||||
public class INMS {
|
||||
//@builder
|
||||
private static final KMap<String, Class<? extends INMSBinding>> bindings = new KMap<String, Class<? extends INMSBinding>>()
|
||||
.qput("v1_18_R2", NMSBinding18_2.class);
|
||||
.qput("v1_19_R1", NMSBinding19_1.class);
|
||||
//@done
|
||||
private static final INMSBinding binding = bind();
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public enum NMSVersion {
|
||||
R1_19_1,
|
||||
R1_18_2,
|
||||
R1_18,
|
||||
R1_17,
|
||||
@@ -102,6 +103,9 @@ public enum NMSVersion {
|
||||
if(tryVersion("1_18_R2")) {
|
||||
return R1_18_2;
|
||||
}
|
||||
if(tryVersion("1_19_R1")) {
|
||||
return R1_19_1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.nms.v18_2;
|
||||
package com.volmit.iris.core.nms.v19_1;
|
||||
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
@@ -39,10 +39,15 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import net.minecraft.core.*;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.BitStorage;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.chunk.Palette;
|
||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -50,9 +55,10 @@ import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
||||
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.block.data.CraftBlockData;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -68,7 +74,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class NMSBinding18_2 implements INMSBinding {
|
||||
public class NMSBinding19_1 implements INMSBinding {
|
||||
|
||||
private final KMap<Biome, Object> baseBiomeCache = new KMap<>();
|
||||
private final BlockData AIR = Material.AIR.createBlockData();
|
||||
@@ -231,13 +237,13 @@ public class NMSBinding18_2 implements INMSBinding {
|
||||
return v;
|
||||
}
|
||||
//noinspection unchecked
|
||||
v = org.bukkit.craftbukkit.v1_18_R2.block.CraftBlock.biomeToBiomeBase((Registry<net.minecraft.world.level.biome.Biome>) registry, biome);
|
||||
v = org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock.biomeToBiomeBase((Registry<net.minecraft.world.level.biome.Biome>) registry, biome);
|
||||
if(v == null) {
|
||||
// Ok so there is this new biome name called "CUSTOM" in Paper's new releases.
|
||||
// But, this does NOT exist within CraftBukkit which makes it return an error.
|
||||
// So, we will just return the ID that the plains biome returns instead.
|
||||
//noinspection unchecked
|
||||
return org.bukkit.craftbukkit.v1_18_R2.block.CraftBlock.biomeToBiomeBase((Registry<net.minecraft.world.level.biome.Biome>) registry, Biome.PLAINS);
|
||||
return org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock.biomeToBiomeBase((Registry<net.minecraft.world.level.biome.Biome>) registry, Biome.PLAINS);
|
||||
}
|
||||
baseBiomeCache.put(biome, v);
|
||||
return v;
|
||||
@@ -336,13 +342,46 @@ public class NMSBinding18_2 implements INMSBinding {
|
||||
public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) {
|
||||
try {
|
||||
ChunkAccess s = (ChunkAccess) getFieldForBiomeStorage(chunk).get(chunk);
|
||||
s.setBiome(x, y, z, (Holder<net.minecraft.world.level.biome.Biome>) somethingVeryDirty); // probably not safe? it said it wanted a holder, so i made it a holder...
|
||||
Holder<net.minecraft.world.level.biome.Biome> biome = (Holder<net.minecraft.world.level.biome.Biome>) somethingVeryDirty;
|
||||
s.setBiome(x, y, z, biome);
|
||||
/*int l = QuartPos.fromBlock(s.getMinBuildHeight());
|
||||
int i1 = l + QuartPos.fromBlock(s.getHeight()) - 1;
|
||||
PalettedContainer<Holder<net.minecraft.world.level.biome.Biome>> palette = getPalette(s, s.getSectionIndex(QuartPos.toBlock(Mth.clamp(y, l, i1))));
|
||||
int index = getPaletteIndex(x, y, z, s, palette);
|
||||
int data = getPaletteDataId(palette, biome);
|
||||
setPaletteData(palette, index, data);*/
|
||||
} catch(IllegalAccessException e) {
|
||||
Iris.reportError(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private PalettedContainer<Holder<net.minecraft.world.level.biome.Biome>> getPalette(ChunkAccess ca, int index) {
|
||||
LevelChunkSection[] sections = fieldForClass(LevelChunkSection[].class, ChunkAccess.class, ca);
|
||||
return fieldForClass(PalettedContainer.class, LevelChunkSection.class, sections[index]);
|
||||
}
|
||||
|
||||
private int getPaletteIndex(int x, int y, int z, ChunkAccess s, PalettedContainer<?> palette) {
|
||||
int l = QuartPos.fromBlock(s.getMinBuildHeight());
|
||||
int i1 = l + QuartPos.fromBlock(s.getHeight()) - 1;
|
||||
int j1 = Mth.clamp(y, l, i1);
|
||||
return fieldForClass(PalettedContainer.Strategy.class, PalettedContainer.class, palette).getIndex(x & 3, j1 & 3, z & 3);
|
||||
}
|
||||
|
||||
private <T extends Holder<?>> int getPaletteDataId(PalettedContainer<T> palette, T data) throws ClassNotFoundException {
|
||||
Class<?> dataType = getClassType(PalettedContainer.class, 1);
|
||||
Object paletteData = fieldFor(dataType, palette);
|
||||
Palette<T> fuckinFinally = fieldForClass(Palette.class,dataType, paletteData);
|
||||
return fuckinFinally.idFor(data);
|
||||
}
|
||||
|
||||
private void setPaletteData(PalettedContainer<?> palette, int index, int data) throws ClassNotFoundException {
|
||||
Class<?> dataType = getClassType(PalettedContainer.class, 1);
|
||||
Object paletteData = fieldFor(dataType, palette);
|
||||
BitStorage storage = fieldForClass(BitStorage.class, dataType, paletteData);
|
||||
storage.set(index, data);
|
||||
}
|
||||
|
||||
private Field getFieldForBiomeStorage(Object storage) {
|
||||
Field f = biomeStorageCache;
|
||||
|
||||
@@ -404,7 +443,7 @@ public class NMSBinding18_2 implements INMSBinding {
|
||||
if(i.getReturnType().equals(returns)) {
|
||||
i.setAccessible(true);
|
||||
try {
|
||||
Iris.info("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()");
|
||||
Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()");
|
||||
return i.invoke(in);
|
||||
} catch(Throwable e) {
|
||||
e.printStackTrace();
|
||||
@@ -421,16 +460,21 @@ public class NMSBinding18_2 implements INMSBinding {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T fieldForClass(Class<T> returnType, Class<?> sourceType, Object in) {
|
||||
for(Field i : sourceType.getFields())
|
||||
for(Field i : sourceType.getDeclaredFields()) {
|
||||
if(i.getType().equals(returnType)) {
|
||||
i.setAccessible(true);
|
||||
try {
|
||||
Iris.info("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName());
|
||||
return (T)i.get(in);
|
||||
Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName());
|
||||
return (T) i.get(in);
|
||||
} catch(IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Class<?> getClassType(Class<?> type, int ordinal) {
|
||||
return type.getDeclaredClasses()[ordinal];
|
||||
}
|
||||
}
|
||||
@@ -112,8 +112,8 @@ public class IrisComplex implements DataProvider {
|
||||
.getAllBiomes(this).forEach((b) -> b
|
||||
.getGenerators()
|
||||
.forEach((c) -> registerGenerator(c.getCachedGenerator(this)))));
|
||||
overlayStream = ProceduralStream.ofDouble((x, z) -> 0D);
|
||||
engine.getDimension().getOverlayNoise().forEach((i) -> overlayStream.add((x, z) -> i.get(rng, getData(), x, z)));
|
||||
overlayStream = ProceduralStream.ofDouble((x, z) -> 0.0D);
|
||||
engine.getDimension().getOverlayNoise().forEach(i -> overlayStream = overlayStream.add((x, z) -> i.get(rng, getData(), x, z)));
|
||||
rockStream = engine.getDimension().getRockPalette().getLayerGenerator(rng.nextParallelRNG(45), data).stream()
|
||||
.select(engine.getDimension().getRockPalette().getBlockData(data));
|
||||
fluidStream = engine.getDimension().getFluidPalette().getLayerGenerator(rng.nextParallelRNG(78), data).stream()
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
@@ -67,7 +68,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
|
||||
@Override
|
||||
public void onActuate(int x, int z, Hunk<Biome> h, boolean multicore) {
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
BurstExecutor burst = burst().burst(multicore);
|
||||
BurstExecutor burst = burst().burst(PaperLib.isPaper() && multicore);
|
||||
|
||||
for(int xf = 0; xf < h.getWidth(); xf++) {
|
||||
int finalXf = xf;
|
||||
|
||||
@@ -101,7 +101,6 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
|
||||
KList<BlockData> blocks = null;
|
||||
KList<BlockData> fblocks = null;
|
||||
int depth, fdepth;
|
||||
|
||||
for(int i = hf; i >= 0; i--) {
|
||||
if(i >= h.getHeight()) {
|
||||
continue;
|
||||
|
||||
@@ -228,8 +228,6 @@ public class IrisDimension extends IrisRegistrant {
|
||||
private IrisMaterialPalette rockPalette = new IrisMaterialPalette().qclear().qadd("stone");
|
||||
@Desc("The palette of blocks for 'water'")
|
||||
private IrisMaterialPalette fluidPalette = new IrisMaterialPalette().qclear().qadd("water");
|
||||
// @Desc("Cartographer map trade overrides")
|
||||
// private IrisVillagerOverride patchCartographers = new IrisVillagerOverride().setDisableTrade(false);
|
||||
@Desc("Remove cartographers so they do not crash the server (Iris worlds only)")
|
||||
private boolean removeCartographersDueToCrash = true;
|
||||
@Desc("Notify players of cancelled cartographer villager in this radius in blocks (set to -1 to disable, -2 for everyone)")
|
||||
@@ -418,7 +416,7 @@ public class IrisDimension extends IrisRegistrant {
|
||||
{
|
||||
"pack": {
|
||||
"description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.",
|
||||
"pack_format": 9
|
||||
"pack_format": 10
|
||||
}
|
||||
}
|
||||
""");
|
||||
@@ -481,6 +479,8 @@ public class IrisDimension extends IrisRegistrant {
|
||||
"bed_works": true,
|
||||
"respawn_anchor_works": false,
|
||||
"has_raids": true,
|
||||
"monster_spawn_block_light_limit": 7,
|
||||
"monster_spawn_light_level": 1,
|
||||
"infiniburn": "#minecraft:infiniburn_overworld",
|
||||
"effects": "minecraft:overworld"
|
||||
}""";
|
||||
|
||||
@@ -35,6 +35,8 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Snippet("style")
|
||||
@Accessors(chain = true)
|
||||
@NoArgsConstructor
|
||||
@@ -70,6 +72,10 @@ public class IrisGeneratorStyle {
|
||||
@MaxNumber(64)
|
||||
@Desc("The exponent")
|
||||
private double exponent = 1;
|
||||
@MinNumber(0)
|
||||
@MaxNumber(8192)
|
||||
@Desc("If the cache size is set above 0, this generator will be cached")
|
||||
private int cacheSize = 0;
|
||||
|
||||
public IrisGeneratorStyle(NoiseStyle s) {
|
||||
this.style = s;
|
||||
@@ -81,6 +87,18 @@ public class IrisGeneratorStyle {
|
||||
}
|
||||
|
||||
public CNG createNoCache(RNG rng, IrisData data) {
|
||||
return createNoCache(rng, data, false);
|
||||
}
|
||||
|
||||
|
||||
private int hash()
|
||||
{
|
||||
return Objects.hash(expression, imageMap, multiplier, axialFracturing, fracture != null ? fracture.hash() : 0, exponent, cacheSize, zoom, cellularZoom, cellularFrequency, style);
|
||||
}
|
||||
|
||||
public CNG createNoCache(RNG rng, IrisData data, boolean actuallyCached) {
|
||||
String cacheKey = hash() + "";
|
||||
|
||||
if(getExpression() != null) {
|
||||
IrisExpression e = data.getExpressionLoader().load(getExpression());
|
||||
|
||||
@@ -134,7 +152,7 @@ public class IrisGeneratorStyle {
|
||||
}
|
||||
|
||||
public CNG create(RNG rng, IrisData data) {
|
||||
return cng.aquire(() -> createNoCache(rng, data));
|
||||
return cng.aquire(() -> createNoCache(rng, data, true));
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
|
||||
@@ -46,7 +46,7 @@ import net.minecraft.nbt.TagParser;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
|
||||
@@ -506,7 +506,9 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
|
||||
boolean warped = !config.getWarp().isFlat();
|
||||
boolean stilting = (config.getMode().equals(ObjectPlaceMode.STILT) || config.getMode().equals(ObjectPlaceMode.FAST_STILT));
|
||||
boolean stilting = (config.getMode().equals(ObjectPlaceMode.STILT) || config.getMode().equals(ObjectPlaceMode.FAST_STILT) ||
|
||||
config.getMode() == ObjectPlaceMode.MIN_STILT || config.getMode() == ObjectPlaceMode.FAST_MIN_STILT ||
|
||||
config.getMode() == ObjectPlaceMode.CENTER_STILT);
|
||||
KMap<Position2, Integer> heightmap = config.getSnow() > 0 ? new KMap<>() : null;
|
||||
int spinx = rng.imax() / 1000;
|
||||
int spiny = rng.imax() / 1000;
|
||||
@@ -520,7 +522,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
boolean bail = false;
|
||||
|
||||
if(yv < 0) {
|
||||
if(config.getMode().equals(ObjectPlaceMode.CENTER_HEIGHT)) {
|
||||
if(config.getMode().equals(ObjectPlaceMode.CENTER_HEIGHT) || config.getMode() == ObjectPlaceMode.CENTER_STILT) {
|
||||
y = (c != null ? c.getSurface() : placer.getHighest(x, z, getLoader(), config.isUnderwater())) + rty;
|
||||
if(placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) {
|
||||
bail = true;
|
||||
@@ -548,6 +550,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
} else if(config.getMode().equals(ObjectPlaceMode.FAST_MAX_HEIGHT) || config.getMode().equals(ObjectPlaceMode.FAST_STILT)) {
|
||||
BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
|
||||
BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
|
||||
|
||||
int xRadius = (rotatedDimensions.getBlockX() / 2);
|
||||
int xLength = xRadius + offset.getBlockX();
|
||||
int minX = Math.min(x - xLength, x + xLength);
|
||||
@@ -556,6 +559,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
int zLength = zRadius + offset.getBlockZ();
|
||||
int minZ = Math.min(z - zLength, z + zLength);
|
||||
int maxZ = Math.max(z - zLength, z + zLength);
|
||||
|
||||
for(int i = minX; i <= maxX; i += Math.abs(xRadius) + 1) {
|
||||
for(int ii = minZ; ii <= maxZ; ii += Math.abs(zRadius) + 1) {
|
||||
int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty;
|
||||
@@ -567,15 +571,21 @@ public class IrisObject extends IrisRegistrant {
|
||||
y = h;
|
||||
}
|
||||
}
|
||||
} else if(config.getMode().equals(ObjectPlaceMode.MIN_HEIGHT)) {
|
||||
} else if(config.getMode().equals(ObjectPlaceMode.MIN_HEIGHT) || config.getMode() == ObjectPlaceMode.MIN_STILT) {
|
||||
y = rdata.getEngine().getHeight() + 1;
|
||||
BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
|
||||
BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
|
||||
|
||||
for(int i = x - (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i <= x + (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i++) {
|
||||
for(int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j++) {
|
||||
int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty;
|
||||
if(placer.isCarved(i, h, j) || placer.isCarved(i, h - 1, j) || placer.isCarved(i, h - 2, j) || placer.isCarved(i, h - 3, j)) {
|
||||
int xLength = (rotatedDimensions.getBlockX() / 2) + offset.getBlockX();
|
||||
int minX = Math.min(x - xLength, x + xLength);
|
||||
int maxX = Math.max(x - xLength, x + xLength);
|
||||
int zLength = (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ();
|
||||
int minZ = Math.min(z - zLength, z + zLength);
|
||||
int maxZ = Math.max(z - zLength, z + zLength);
|
||||
for(int i = minX; i <= maxX; i++) {
|
||||
for(int ii = minZ; ii <= maxZ; ii++) {
|
||||
int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty;
|
||||
if(placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) {
|
||||
bail = true;
|
||||
break;
|
||||
}
|
||||
@@ -584,15 +594,24 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(config.getMode().equals(ObjectPlaceMode.FAST_MIN_HEIGHT)) {
|
||||
} else if(config.getMode().equals(ObjectPlaceMode.FAST_MIN_HEIGHT) || config.getMode() == ObjectPlaceMode.FAST_MIN_STILT) {
|
||||
y = rdata.getEngine().getHeight() + 1;
|
||||
BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
|
||||
BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
|
||||
|
||||
for(int i = x - (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i <= x + (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i += (rotatedDimensions.getBlockX() / 2) + 1) {
|
||||
for(int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j += (rotatedDimensions.getBlockZ() / 2) + 1) {
|
||||
int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty;
|
||||
if(placer.isCarved(i, h, j) || placer.isCarved(i, h - 1, j) || placer.isCarved(i, h - 2, j) || placer.isCarved(i, h - 3, j)) {
|
||||
int xRadius = (rotatedDimensions.getBlockX() / 2);
|
||||
int xLength = xRadius + offset.getBlockX();
|
||||
int minX = Math.min(x - xLength, x + xLength);
|
||||
int maxX = Math.max(x - xLength, x + xLength);
|
||||
int zRadius = (rotatedDimensions.getBlockZ() / 2);
|
||||
int zLength = zRadius + offset.getBlockZ();
|
||||
int minZ = Math.min(z - zLength, z + zLength);
|
||||
int maxZ = Math.max(z - zLength, z + zLength);
|
||||
|
||||
for(int i = minX; i <= maxX; i += Math.abs(xRadius) + 1) {
|
||||
for(int ii = minZ; ii <= maxZ; ii += Math.abs(zRadius) + 1) {
|
||||
int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty;
|
||||
if(placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) {
|
||||
bail = true;
|
||||
break;
|
||||
}
|
||||
@@ -806,21 +825,26 @@ public class IrisObject extends IrisRegistrant {
|
||||
|
||||
if(stilting) {
|
||||
readLock.lock();
|
||||
IrisStiltSettings settings = config.getStiltSettings();
|
||||
for(BlockVector g : getBlocks().keySet()) {
|
||||
BlockData d;
|
||||
|
||||
try {
|
||||
d = getBlocks().get(g);
|
||||
} catch(Throwable e) {
|
||||
Iris.reportError(e);
|
||||
Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (stilt cme)");
|
||||
d = AIR;
|
||||
}
|
||||
if(settings == null || settings.getPalette() == null) {
|
||||
try {
|
||||
d = getBlocks().get(g);
|
||||
} catch(Throwable e) {
|
||||
Iris.reportError(e);
|
||||
Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (stilt cme)");
|
||||
d = AIR;
|
||||
}
|
||||
|
||||
if(d == null) {
|
||||
Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (stilt null)");
|
||||
d = AIR;
|
||||
}
|
||||
} else
|
||||
d = config.getStiltSettings().getPalette().get(rng, x, y, z, rdata);
|
||||
|
||||
if(d == null) {
|
||||
Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (stilt null)");
|
||||
d = AIR;
|
||||
}
|
||||
|
||||
BlockVector i = g.clone();
|
||||
i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone();
|
||||
@@ -856,15 +880,21 @@ public class IrisObject extends IrisRegistrant {
|
||||
zz += config.warp(rng, i.getZ() + z, i.getY() + y, i.getX() + x, getLoader());
|
||||
}
|
||||
|
||||
int yg = placer.getHighest(xx, zz, getLoader(), true);
|
||||
int highest = placer.getHighest(xx, zz, getLoader(), true);
|
||||
|
||||
if(config.isWaterloggable() && yg <= placer.getFluidHeight() && d instanceof Waterlogged)
|
||||
if(config.isWaterloggable() && highest <= placer.getFluidHeight() && d instanceof Waterlogged)
|
||||
((Waterlogged) d).setWaterlogged(true);
|
||||
|
||||
if(yv >= 0 && config.isBottom())
|
||||
y += Math.floorDiv(h, 2);
|
||||
|
||||
for(int j = lowest + y; j > yg - config.getOverStilt() - 1; j--)
|
||||
int lowerBound = highest - 1;
|
||||
if(settings != null) {
|
||||
lowerBound -= config.getStiltSettings().getOverStilt() - rng.i(0, config.getStiltSettings().getYRand());
|
||||
if(settings.getYMax() != 0)
|
||||
lowerBound -= Math.min(config.getStiltSettings().getYMax() - (lowest + y - highest), 0);
|
||||
}
|
||||
for(int j = lowest + y; j > lowerBound; j--)
|
||||
placer.set(xx, j, zz, d);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,10 +75,8 @@ public class IrisObjectPlacement {
|
||||
private int density = 1;
|
||||
@Desc("If the chance check passes, and you specify this, it picks a number in the range based on noise, and 'density' is ignored.")
|
||||
private IrisStyledRange densityStyle = null;
|
||||
@MaxNumber(64)
|
||||
@MinNumber(0)
|
||||
@Desc("If the place mode is set to stilt, you can over-stilt it even further into the ground. Especially useful when using fast stilt due to inaccuracies.")
|
||||
private int overStilt = 0;
|
||||
@Desc("When stilting is enabled, this object will define various properties related to it.")
|
||||
private IrisStiltSettings stiltSettings;
|
||||
@MaxNumber(64)
|
||||
@MinNumber(0)
|
||||
@Desc("When bore is enabled, expand max-y of the cuboid it removes")
|
||||
@@ -146,7 +144,7 @@ public class IrisObjectPlacement {
|
||||
p.setUnderwater(underwater);
|
||||
p.setBoreExtendMaxY(boreExtendMaxY);
|
||||
p.setBoreExtendMinY(boreExtendMinY);
|
||||
p.setOverStilt(overStilt);
|
||||
p.setStiltSettings(stiltSettings);
|
||||
p.setDensity(density);
|
||||
p.setChance(chance);
|
||||
p.setSnow(snow);
|
||||
|
||||
@@ -44,7 +44,7 @@ public class IrisObjectTranslate {
|
||||
@Required
|
||||
@MinNumber(-128) // TODO: WARNING HEIGHT
|
||||
@MaxNumber(128) // TODO: WARNING HEIGHT
|
||||
@Desc("The x shift in blocks")
|
||||
@Desc("The y shift in blocks")
|
||||
private int y = 0;
|
||||
|
||||
@MinNumber(-128) // TODO: WARNING HEIGHT
|
||||
@@ -54,7 +54,7 @@ public class IrisObjectTranslate {
|
||||
|
||||
@MinNumber(-128) // TODO: WARNING HEIGHT
|
||||
@MaxNumber(128) // TODO: WARNING HEIGHT
|
||||
@Desc("The x shift in blocks")
|
||||
@Desc("The z shift in blocks")
|
||||
private int z = 0;
|
||||
|
||||
public boolean canTranslate() {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.volmit.iris.engine.object;
|
||||
|
||||
import com.volmit.iris.engine.object.annotations.Desc;
|
||||
import com.volmit.iris.engine.object.annotations.MaxNumber;
|
||||
import com.volmit.iris.engine.object.annotations.MinNumber;
|
||||
import com.volmit.iris.engine.object.annotations.Snippet;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Snippet("stilt-settings")
|
||||
@Accessors(chain = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Desc("Defines stilting behaviour.")
|
||||
@Data
|
||||
public class IrisStiltSettings {
|
||||
@MinNumber(0)
|
||||
@MaxNumber(64)
|
||||
@Desc("Defines the maximum amount of blocks the object stilts verticially before overstilting and randomRange.")
|
||||
private int yMax;
|
||||
@MinNumber(0)
|
||||
@MaxNumber(64)
|
||||
@Desc("Defines the upper boundary for additional blocks after overstilting and/or maxStiltRange.")
|
||||
private int yRand;
|
||||
@MaxNumber(64)
|
||||
@MinNumber(0)
|
||||
@Desc("If the place mode is set to stilt, you can over-stilt it even further into the ground. Especially useful when using fast stilt due to inaccuracies.")
|
||||
private int overStilt;
|
||||
@Desc("If defined, stilting will be done using this block palette rather than the last layer of the object.")
|
||||
private IrisMaterialPalette palette;
|
||||
|
||||
}
|
||||
@@ -50,6 +50,18 @@ public enum ObjectPlaceMode {
|
||||
|
||||
FAST_STILT,
|
||||
|
||||
@Desc("Stilting is MIN_HEIGHT but it repeats the bottom most block of your object until it hits the surface. This is expensive because it has to first sample every height value for each x,z position of your object. Avoid using this unless its structures for performance reasons.")
|
||||
|
||||
MIN_STILT,
|
||||
|
||||
@Desc("Just like MIN_STILT but very inaccurate. Useful for stilting a lot of objects without too much care on accuracy (you can use the over-stilt value to force stilts under ground further)")
|
||||
|
||||
FAST_MIN_STILT,
|
||||
|
||||
@Desc("Stilting is CENTER_HEIGHT but it repeats the bottom most block of your object until it hits the surface. This is expensive because it has to first sample every height value for each x,z position of your object. Avoid using this unless its structures for performance reasons.")
|
||||
|
||||
CENTER_STILT,
|
||||
|
||||
@Desc("Samples the height of the terrain at every x,z position of your object and pushes it down to the surface. It's pretty much like a melt function over the terrain.")
|
||||
|
||||
PAINT
|
||||
|
||||
@@ -31,11 +31,15 @@ import com.volmit.iris.engine.object.StudioMode;
|
||||
import com.volmit.iris.engine.platform.studio.StudioGenerator;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.data.IrisBiomeStorage;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.hunk.view.BiomeGridHunkHolder;
|
||||
import com.volmit.iris.util.hunk.view.ChunkDataHunkHolder;
|
||||
import com.volmit.iris.util.io.ReactiveFolder;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.Looper;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Setter;
|
||||
@@ -278,9 +282,11 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
if(studioGenerator != null) {
|
||||
studioGenerator.generateChunk(getEngine(), tc, x, z);
|
||||
} else {
|
||||
Hunk<BlockData> blocks = Hunk.view(tc);
|
||||
Hunk<Biome> biomes = Hunk.view(tc, tc.getMinHeight(), tc.getMaxHeight());
|
||||
ChunkDataHunkHolder blocks = new ChunkDataHunkHolder(tc);
|
||||
BiomeGridHunkHolder biomes = new BiomeGridHunkHolder(tc, tc.getMinHeight(), tc.getMaxHeight());
|
||||
getEngine().generate(x << 4, z << 4, blocks, biomes, true);
|
||||
blocks.apply();
|
||||
biomes.apply();
|
||||
}
|
||||
|
||||
ChunkData c = tc.getRaw();
|
||||
|
||||
82
src/main/java/com/volmit/iris/util/cache/ArrayCache.java
vendored
Normal file
82
src/main/java/com/volmit/iris/util/cache/ArrayCache.java
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
import com.volmit.iris.engine.data.cache.Cache;
|
||||
import com.volmit.iris.util.hunk.bits.Writable;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface ArrayCache<T> extends Writable<T> {
|
||||
T get(int i);
|
||||
|
||||
void set(int i, T t);
|
||||
|
||||
void iset(int i, int v);
|
||||
|
||||
int getWidth();
|
||||
|
||||
int getHeight();
|
||||
|
||||
void writeCache(DataOutputStream dos) throws IOException;
|
||||
|
||||
static int zigZag(int coord, int size)
|
||||
{
|
||||
if(coord < 0)
|
||||
{
|
||||
coord = Math.abs(coord);
|
||||
}
|
||||
|
||||
if(coord % (size * 2) >= size)
|
||||
{
|
||||
return (size) - (coord % size) - 1;
|
||||
}
|
||||
|
||||
else {
|
||||
return coord % size;
|
||||
}
|
||||
}
|
||||
|
||||
default void set(int x, int y, T v)
|
||||
{
|
||||
set((zigZag(y, getHeight()) * getWidth()) + zigZag(x, getWidth()), v);
|
||||
}
|
||||
|
||||
default T get(int x, int y)
|
||||
{
|
||||
try
|
||||
{
|
||||
return get((zigZag(y, getHeight()) * getWidth()) + zigZag(x, getWidth()));
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
default void iset(int x, int y, int v)
|
||||
{
|
||||
iset((zigZag(y, getHeight()) * getWidth()) + zigZag(x, getWidth()), v);
|
||||
}
|
||||
}
|
||||
44
src/main/java/com/volmit/iris/util/cache/ByteBitCache.java
vendored
Normal file
44
src/main/java/com/volmit/iris/util/cache/ByteBitCache.java
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ByteBitCache extends DataBitCache<Integer> {
|
||||
public ByteBitCache(int width, int height) {
|
||||
super(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer readNodeData(DataInputStream din) throws IOException {
|
||||
return (int) din.readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNodeData(DataOutputStream dos, Integer integer) throws IOException {
|
||||
dos.writeByte(integer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iset(int i, int v) {
|
||||
set(i, v);
|
||||
}
|
||||
}
|
||||
76
src/main/java/com/volmit/iris/util/cache/ByteCache.java
vendored
Normal file
76
src/main/java/com/volmit/iris/util/cache/ByteCache.java
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ByteCache implements ArrayCache<Integer> {
|
||||
@Getter
|
||||
private final int width;
|
||||
@Getter
|
||||
private final int height;
|
||||
private final byte[] cache;
|
||||
|
||||
public ByteCache(int width, int height)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
cache = new byte[width * height];
|
||||
}
|
||||
|
||||
public void set(int i, Integer v)
|
||||
{
|
||||
cache[i] = v.byteValue();
|
||||
}
|
||||
|
||||
public Integer get(int i)
|
||||
{
|
||||
return (int)cache[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCache(DataOutputStream dos) throws IOException {
|
||||
dos.writeInt(width);
|
||||
dos.writeInt(height);
|
||||
|
||||
for(int i = 0; i < width * height; i++)
|
||||
{
|
||||
dos.writeByte(get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer readNodeData(DataInputStream din) throws IOException {
|
||||
return (int) din.readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNodeData(DataOutputStream dos, Integer integer) throws IOException {
|
||||
dos.writeByte(integer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iset(int i, int v) {
|
||||
set(i, v);
|
||||
}
|
||||
}
|
||||
58
src/main/java/com/volmit/iris/util/cache/DataBitCache.java
vendored
Normal file
58
src/main/java/com/volmit/iris/util/cache/DataBitCache.java
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
import com.volmit.iris.util.hunk.bits.DataContainer;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class DataBitCache<T> implements ArrayCache<T> {
|
||||
@Getter
|
||||
private final int width;
|
||||
@Getter
|
||||
private final int height;
|
||||
private final DataContainer<T> cache;
|
||||
|
||||
public DataBitCache(int width, int height)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
cache = new DataContainer<>(this, width * height);
|
||||
}
|
||||
|
||||
public void set(int i, T v)
|
||||
{
|
||||
cache.set(i, v);
|
||||
}
|
||||
|
||||
public T get(int i)
|
||||
{
|
||||
return cache.get(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCache(DataOutputStream dos) throws IOException {
|
||||
dos.writeInt(width);
|
||||
dos.writeInt(height);
|
||||
cache.writeDos(dos);
|
||||
}
|
||||
}
|
||||
44
src/main/java/com/volmit/iris/util/cache/FloatBitCache.java
vendored
Normal file
44
src/main/java/com/volmit/iris/util/cache/FloatBitCache.java
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FloatBitCache extends DataBitCache<Float> {
|
||||
public FloatBitCache(int width, int height) {
|
||||
super(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float readNodeData(DataInputStream din) throws IOException {
|
||||
return din.readFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNodeData(DataOutputStream dos, Float integer) throws IOException {
|
||||
dos.writeFloat(integer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iset(int i, int v) {
|
||||
set(i, (float)v);
|
||||
}
|
||||
}
|
||||
93
src/main/java/com/volmit/iris/util/cache/FloatCache.java
vendored
Normal file
93
src/main/java/com/volmit/iris/util/cache/FloatCache.java
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FloatCache implements ArrayCache<Float> {
|
||||
@Getter
|
||||
private final int width;
|
||||
@Getter
|
||||
private final int height;
|
||||
private final float[] cache;
|
||||
|
||||
|
||||
public FloatCache(File file) throws IOException {
|
||||
this(new DataInputStream(new FileInputStream(file)));
|
||||
}
|
||||
|
||||
public FloatCache(DataInputStream din) throws IOException {
|
||||
this(din.readInt(), din.readInt());
|
||||
for(int i = 0; i < width * height; i++)
|
||||
{
|
||||
cache[i] = din.readFloat();
|
||||
}
|
||||
din.close();
|
||||
}
|
||||
|
||||
public FloatCache(int width, int height)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
cache = new float[width * height];
|
||||
}
|
||||
|
||||
public void set(int i, Float v)
|
||||
{
|
||||
cache[i] = v;
|
||||
}
|
||||
|
||||
public Float get(int i)
|
||||
{
|
||||
return cache[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCache(DataOutputStream dos) throws IOException {
|
||||
dos.writeInt(width);
|
||||
dos.writeInt(height);
|
||||
|
||||
for(int i = 0; i < width * height; i++)
|
||||
{
|
||||
dos.writeFloat(get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float readNodeData(DataInputStream din) throws IOException {
|
||||
return din.readFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNodeData(DataOutputStream dos, Float integer) throws IOException {
|
||||
dos.writeFloat(integer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iset(int i, int v) {
|
||||
set(i, (float) v);
|
||||
}
|
||||
}
|
||||
44
src/main/java/com/volmit/iris/util/cache/IntBitCache.java
vendored
Normal file
44
src/main/java/com/volmit/iris/util/cache/IntBitCache.java
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class IntBitCache extends DataBitCache<Integer> {
|
||||
public IntBitCache(int width, int height) {
|
||||
super(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer readNodeData(DataInputStream din) throws IOException {
|
||||
return din.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNodeData(DataOutputStream dos, Integer integer) throws IOException {
|
||||
dos.writeInt(integer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iset(int i, int v) {
|
||||
set(i, v);
|
||||
}
|
||||
}
|
||||
78
src/main/java/com/volmit/iris/util/cache/IntCache.java
vendored
Normal file
78
src/main/java/com/volmit/iris/util/cache/IntCache.java
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
import com.volmit.iris.util.hunk.bits.DataContainer;
|
||||
import com.volmit.iris.util.hunk.bits.Writable;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class IntCache implements ArrayCache<Integer> {
|
||||
@Getter
|
||||
private final int width;
|
||||
@Getter
|
||||
private final int height;
|
||||
private final int[] cache;
|
||||
|
||||
public IntCache(int width, int height)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
cache = new int[width * height];
|
||||
}
|
||||
|
||||
public void set(int i, Integer v)
|
||||
{
|
||||
cache[i] = v;
|
||||
}
|
||||
|
||||
public Integer get(int i)
|
||||
{
|
||||
return cache[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCache(DataOutputStream dos) throws IOException {
|
||||
dos.writeInt(width);
|
||||
dos.writeInt(height);
|
||||
|
||||
for(int i = 0; i < width * height; i++)
|
||||
{
|
||||
dos.writeInt(get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer readNodeData(DataInputStream din) throws IOException {
|
||||
return din.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNodeData(DataOutputStream dos, Integer integer) throws IOException {
|
||||
dos.writeInt(integer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iset(int i, int v) {
|
||||
set(i, v);
|
||||
}
|
||||
}
|
||||
44
src/main/java/com/volmit/iris/util/cache/ShortBitCache.java
vendored
Normal file
44
src/main/java/com/volmit/iris/util/cache/ShortBitCache.java
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ShortBitCache extends DataBitCache<Short> {
|
||||
public ShortBitCache(int width, int height) {
|
||||
super(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short readNodeData(DataInputStream din) throws IOException {
|
||||
return din.readShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNodeData(DataOutputStream dos, Short integer) throws IOException {
|
||||
dos.writeShort(integer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iset(int i, int v) {
|
||||
set(i, (short) v);
|
||||
}
|
||||
}
|
||||
76
src/main/java/com/volmit/iris/util/cache/ShortCache.java
vendored
Normal file
76
src/main/java/com/volmit/iris/util/cache/ShortCache.java
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ShortCache implements ArrayCache<Short> {
|
||||
@Getter
|
||||
private final int width;
|
||||
@Getter
|
||||
private final int height;
|
||||
private final short[] cache;
|
||||
|
||||
public ShortCache(int width, int height)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
cache = new short[width * height];
|
||||
}
|
||||
|
||||
public void set(int i, Short v)
|
||||
{
|
||||
cache[i] = v;
|
||||
}
|
||||
|
||||
public Short get(int i)
|
||||
{
|
||||
return cache[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCache(DataOutputStream dos) throws IOException {
|
||||
dos.writeInt(width);
|
||||
dos.writeInt(height);
|
||||
|
||||
for(int i = 0; i < width * height; i++)
|
||||
{
|
||||
dos.writeShort(get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short readNodeData(DataInputStream din) throws IOException {
|
||||
return din.readShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNodeData(DataOutputStream dos, Short integer) throws IOException {
|
||||
dos.writeShort(integer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iset(int i, int v) {
|
||||
set(i, (short) v);
|
||||
}
|
||||
}
|
||||
40
src/main/java/com/volmit/iris/util/cache/UByteBitCache.java
vendored
Normal file
40
src/main/java/com/volmit/iris/util/cache/UByteBitCache.java
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
public class UByteBitCache extends ByteBitCache {
|
||||
public UByteBitCache(int width, int height) {
|
||||
super(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int i, Integer v) {
|
||||
super.set(i, v + Byte.MIN_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer get(int i) {
|
||||
return super.get(i) - Byte.MIN_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iset(int i, int v) {
|
||||
set(i, v);
|
||||
}
|
||||
}
|
||||
40
src/main/java/com/volmit/iris/util/cache/UByteCache.java
vendored
Normal file
40
src/main/java/com/volmit/iris/util/cache/UByteCache.java
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.cache;
|
||||
|
||||
public class UByteCache extends ByteCache {
|
||||
public UByteCache(int width, int height) {
|
||||
super(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int i, Integer v) {
|
||||
super.set(i, v + Byte.MIN_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer get(int i) {
|
||||
return super.get(i) - Byte.MIN_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iset(int i, int v) {
|
||||
set(i, v);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.hunk.view;
|
||||
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.data.chunk.LinkedTerrainChunk;
|
||||
import com.volmit.iris.util.hunk.storage.AtomicHunk;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
|
||||
|
||||
@SuppressWarnings("ClassCanBeRecord")
|
||||
public class BiomeGridHunkHolder extends AtomicHunk<Biome> {
|
||||
@Getter
|
||||
private final BiomeGrid chunk;
|
||||
private final int minHeight;
|
||||
private final int maxHeight;
|
||||
|
||||
public BiomeGridHunkHolder(BiomeGrid chunk, int minHeight, int maxHeight) {
|
||||
super(16, maxHeight - minHeight, 16);
|
||||
this.chunk = chunk;
|
||||
this.minHeight = minHeight;
|
||||
this.maxHeight = maxHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDepth() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return maxHeight - minHeight;
|
||||
}
|
||||
|
||||
public void apply() {
|
||||
for(int i = 0; i < getHeight(); i++) {
|
||||
for(int j = 0; j < getWidth(); j++) {
|
||||
for(int k = 0; k < getDepth(); k++) {
|
||||
Biome b = super.getRaw(j, i, k);
|
||||
|
||||
if(b != null)
|
||||
{
|
||||
chunk.setBiome(j, i + minHeight, k, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getRaw(int x, int y, int z) {
|
||||
Biome b = super.getRaw(x, y, z);
|
||||
|
||||
return b != null ? b : Biome.PLAINS;
|
||||
}
|
||||
|
||||
public void forceBiomeBaseInto(int x, int y, int z, Object somethingVeryDirty) {
|
||||
if(chunk instanceof LinkedTerrainChunk) {
|
||||
INMS.get().forceBiomeInto(x, y + minHeight, z, somethingVeryDirty, ((LinkedTerrainChunk) chunk).getRawBiome());
|
||||
return;
|
||||
}
|
||||
INMS.get().forceBiomeInto(x, y + minHeight, z, somethingVeryDirty, chunk);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
package com.volmit.iris.util.hunk.view;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.data.chunk.LinkedTerrainChunk;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
@@ -31,6 +32,7 @@ public class BiomeGridHunkView implements Hunk<Biome> {
|
||||
private final BiomeGrid chunk;
|
||||
private final int minHeight;
|
||||
private final int maxHeight;
|
||||
private int highest = -1000;
|
||||
|
||||
public BiomeGridHunkView(BiomeGrid chunk, int minHeight, int maxHeight) {
|
||||
this.chunk = chunk;
|
||||
@@ -56,6 +58,12 @@ public class BiomeGridHunkView implements Hunk<Biome> {
|
||||
@Override
|
||||
public void setRaw(int x, int y, int z, Biome t) {
|
||||
chunk.setBiome(x, y + minHeight, z, t);
|
||||
|
||||
if(y > highest)
|
||||
{
|
||||
highest = y;
|
||||
Iris.info("Highest = " + highest);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.hunk.view;
|
||||
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.hunk.storage.AtomicHunk;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
|
||||
@SuppressWarnings("ClassCanBeRecord")
|
||||
public class ChunkDataHunkHolder extends AtomicHunk<BlockData> {
|
||||
private static final BlockData AIR = Material.AIR.createBlockData();
|
||||
private final ChunkData chunk;
|
||||
|
||||
public ChunkDataHunkHolder(ChunkData chunk) {
|
||||
super(16, chunk.getMaxHeight() - chunk.getMinHeight(), 16);
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDepth() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return chunk.getMaxHeight() - chunk.getMinHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData getRaw(int x, int y, int z) {
|
||||
BlockData b = super.getRaw(x, y, z);
|
||||
|
||||
return b != null ? b : AIR;
|
||||
}
|
||||
|
||||
public void apply() {
|
||||
for(int i = 0; i < getHeight(); i++) {
|
||||
for(int j = 0; j < getWidth(); j++) {
|
||||
for(int k = 0; k < getDepth(); k++) {
|
||||
BlockData b = super.getRaw(j, i, k);
|
||||
|
||||
if(b != null)
|
||||
{
|
||||
chunk.setBlock(j, i + chunk.getMinHeight(), k, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@ import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||
import com.volmit.iris.engine.object.IRare;
|
||||
import com.volmit.iris.engine.object.NoiseStyle;
|
||||
import com.volmit.iris.util.cache.FloatBitCache;
|
||||
import com.volmit.iris.util.cache.FloatCache;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.function.NoiseInjector;
|
||||
@@ -33,6 +35,11 @@ import com.volmit.iris.util.stream.arithmetic.FittedStream;
|
||||
import com.volmit.iris.util.stream.sources.CNGStream;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@@ -56,6 +63,7 @@ public class CNG {
|
||||
private boolean trueFracturing = false;
|
||||
private KList<CNG> children;
|
||||
private CNG fracture;
|
||||
private FloatCache cache;
|
||||
private NoiseGenerator generator;
|
||||
private NoiseInjector injector;
|
||||
private RNG rng;
|
||||
@@ -134,14 +142,55 @@ public class CNG {
|
||||
}, 1D, 1);
|
||||
}
|
||||
|
||||
public CNG cached(int size)
|
||||
public CNG cached(int size, String key, File cacheFolder)
|
||||
{
|
||||
if(size <= 0)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
generator = new CachedNoise(generator, size);
|
||||
cache = null;
|
||||
|
||||
File f = new File(new File(cacheFolder, ".cache"), key + ".cnm");
|
||||
FloatCache fbc;
|
||||
boolean cached = false;
|
||||
if(f.exists())
|
||||
{
|
||||
try {
|
||||
fbc = new FloatCache(f);
|
||||
cached = true;
|
||||
} catch(IOException e) {
|
||||
fbc = new FloatCache(size, size);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
fbc = new FloatCache(size, size);
|
||||
}
|
||||
|
||||
if(!cached)
|
||||
{
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
for(int j = 0; j < size; j++)
|
||||
{
|
||||
fbc.set(i, j, (float) noise(i, j));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
f.getParentFile().mkdirs();
|
||||
FileOutputStream fos = new FileOutputStream(f);
|
||||
DataOutputStream dos = new DataOutputStream(fos);
|
||||
fbc.writeCache(dos);
|
||||
dos.close();
|
||||
Iris.info("Saved Noise Cache " + f.getName());
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
cache = fbc;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -436,6 +485,11 @@ public class CNG {
|
||||
}
|
||||
|
||||
public double noise(double... dim) {
|
||||
if(cache != null && dim.length == 2)
|
||||
{
|
||||
return cache.get((int)dim[0], (int)dim[1]);
|
||||
}
|
||||
|
||||
double n = getNoise(dim);
|
||||
n = power != 1D ? (n < 0 ? -Math.pow(Math.abs(n), power) : Math.pow(n, power)) : n;
|
||||
double m = 1;
|
||||
|
||||
@@ -51,6 +51,7 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Represents a volume sender. A command sender with extra crap in it
|
||||
@@ -230,7 +231,7 @@ public class VolmitSender implements CommandSender {
|
||||
Iris.audiences.player(player()).showTitle(Title.title(
|
||||
createComponent(title),
|
||||
createComponent(subtitle),
|
||||
Title.Times.of(Duration.ofMillis(i), Duration.ofMillis(s), Duration.ofMillis(o))));
|
||||
Title.Times.times(Duration.ofMillis(i), Duration.ofMillis(s), Duration.ofMillis(o))));
|
||||
}
|
||||
|
||||
public void sendProgress(double percent, String thing) {
|
||||
@@ -260,43 +261,43 @@ public class VolmitSender implements CommandSender {
|
||||
Iris.audiences.player(player()).showTitle(Title.title(
|
||||
createNoPrefixComponent(" "),
|
||||
createNoPrefixComponent(subtitle),
|
||||
Title.Times.of(Duration.ofMillis(i), Duration.ofMillis(s), Duration.ofMillis(o))));
|
||||
Title.Times.times(Duration.ofMillis(i), Duration.ofMillis(s), Duration.ofMillis(o))));
|
||||
}
|
||||
|
||||
private Component createNoPrefixComponent(String message) {
|
||||
if(!IrisSettings.get().getGeneral().canUseCustomColors(this)) {
|
||||
String t = C.translateAlternateColorCodes('&', MiniMessage.get().stripTokens(message));
|
||||
return MiniMessage.get().parse(t);
|
||||
String t = C.translateAlternateColorCodes('&', MiniMessage.miniMessage().stripTags(message));
|
||||
return MiniMessage.miniMessage().deserialize(t);
|
||||
}
|
||||
|
||||
String t = C.translateAlternateColorCodes('&', message);
|
||||
String a = C.aura(t, IrisSettings.get().getGeneral().getSpinh(), IrisSettings.get().getGeneral().getSpins(), IrisSettings.get().getGeneral().getSpinb(), 0.36);
|
||||
return MiniMessage.get().parse(a);
|
||||
return MiniMessage.miniMessage().deserialize(a);
|
||||
}
|
||||
|
||||
private Component createNoPrefixComponentNoProcessing(String message) {
|
||||
return MiniMessage.get().parse(message);
|
||||
return MiniMessage.builder().postProcessor(c -> c).build().deserialize(message);
|
||||
}
|
||||
|
||||
private Component createComponent(String message) {
|
||||
if(!IrisSettings.get().getGeneral().canUseCustomColors(this)) {
|
||||
String t = C.translateAlternateColorCodes('&', MiniMessage.get().stripTokens(getTag() + message));
|
||||
return MiniMessage.get().parse(t);
|
||||
String t = C.translateAlternateColorCodes('&', MiniMessage.miniMessage().stripTags(getTag() + message));
|
||||
return MiniMessage.miniMessage().deserialize(t);
|
||||
}
|
||||
|
||||
String t = C.translateAlternateColorCodes('&', getTag() + message);
|
||||
String a = C.aura(t, IrisSettings.get().getGeneral().getSpinh(), IrisSettings.get().getGeneral().getSpins(), IrisSettings.get().getGeneral().getSpinb());
|
||||
return MiniMessage.get().parse(a);
|
||||
return MiniMessage.miniMessage().deserialize(a);
|
||||
}
|
||||
|
||||
private Component createComponentRaw(String message) {
|
||||
if(!IrisSettings.get().getGeneral().canUseCustomColors(this)) {
|
||||
String t = C.translateAlternateColorCodes('&', MiniMessage.get().stripTokens(getTag() + message));
|
||||
return MiniMessage.get().parse(t);
|
||||
String t = C.translateAlternateColorCodes('&', MiniMessage.miniMessage().stripTags(getTag() + message));
|
||||
return MiniMessage.miniMessage().deserialize(t);
|
||||
}
|
||||
|
||||
String t = C.translateAlternateColorCodes('&', getTag() + message);
|
||||
return MiniMessage.get().parse(t);
|
||||
return MiniMessage.miniMessage().deserialize(t);
|
||||
}
|
||||
|
||||
public <T> void showWaiting(String passive, CompletableFuture<T> f) {
|
||||
|
||||
14
src/main/java/com/volmit/iris/util/uniques/U.java
Normal file
14
src/main/java/com/volmit/iris/util/uniques/U.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package com.volmit.iris.util.uniques;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class U {
|
||||
public static void main(String[] a)
|
||||
{
|
||||
UniqueRenderer r = new UniqueRenderer("helloworld", 2560 , 1440);
|
||||
|
||||
r.writeCollectionFrames(new File("collection"), 1, 1024);
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.volmit.iris.util.uniques;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
public class UBufferedImage implements UImage {
|
||||
private final BufferedImage buf;
|
||||
|
||||
public UBufferedImage(BufferedImage buf)
|
||||
{
|
||||
this.buf = buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return buf.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return buf.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UImage copy() {
|
||||
ColorModel cm = buf.getColorModel();
|
||||
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
|
||||
WritableRaster raster = buf.copyData(null);
|
||||
return new UBufferedImage(new BufferedImage(cm, raster, isAlphaPremultiplied, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color get(int x, int y) {
|
||||
return new Color(buf.getRGB(x, y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int x, int y, Color color) {
|
||||
try
|
||||
{
|
||||
buf.setRGB(x, y, color.getRGB());
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
77
src/main/java/com/volmit/iris/util/uniques/UFeature.java
Normal file
77
src/main/java/com/volmit/iris/util/uniques/UFeature.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package com.volmit.iris.util.uniques;
|
||||
|
||||
import com.volmit.iris.engine.object.NoiseStyle;
|
||||
import com.volmit.iris.util.function.Function2;
|
||||
import com.volmit.iris.util.function.NoiseInjector;
|
||||
import com.volmit.iris.util.interpolation.InterpolationMethod;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import com.volmit.iris.util.stream.ProceduralStream;
|
||||
import com.volmit.iris.util.stream.interpolation.Interpolated;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface UFeature {
|
||||
List<NoiseInjector> injectors = List.of(
|
||||
CNG.ADD,
|
||||
CNG.DST_MOD,
|
||||
CNG.DST_POW,
|
||||
CNG.DST_SUBTRACT,
|
||||
CNG.MAX,
|
||||
CNG.MIN,
|
||||
CNG.SRC_MOD,
|
||||
CNG.SRC_POW,
|
||||
CNG.SRC_SUBTRACT,
|
||||
CNG.MULTIPLY
|
||||
);
|
||||
|
||||
void render(UImage image, RNG rng, double time, Consumer<Double> progressor, UFeatureMeta meta);
|
||||
|
||||
default Color color(CNG hue, CNG saturation, CNG brightness, double x, double y, double t)
|
||||
{
|
||||
return Color.getHSBColor((float)hue.fitDouble(0, 1, x + t, y + t),
|
||||
(float)saturation.fitDouble(0, 1, x + t, y + t),
|
||||
(float)brightness.fitDouble(0, 1, x + t, y + t));
|
||||
}
|
||||
|
||||
default InterpolationMethod interpolator(RNG rng)
|
||||
{
|
||||
return rng.pick(
|
||||
UniqueRenderer.renderer.getInterpolators()
|
||||
);
|
||||
}
|
||||
|
||||
default CNG generator(String key, RNG rng, double scaleMod, long salt, UFeatureMeta meta)
|
||||
{
|
||||
return generator(key, rng, scaleMod, rng.i(1, 3), rng.i(1, 5), salt, meta);
|
||||
}
|
||||
|
||||
default CNG generator(String key, RNG rng, double scaleMod, int fractures, int composites, long salt, UFeatureMeta meta)
|
||||
{
|
||||
RNG rngg = rng.nextParallelRNG(salt);
|
||||
CNG cng = rng.pick(UniqueRenderer.renderer.getStyles()).create(rngg).oct(rng.i(1, 5));
|
||||
RNG rngf = rngg.nextParallelRNG(-salt);
|
||||
cng.scale(rngf.d(0.33 * scaleMod, 1.66 * scaleMod));
|
||||
|
||||
if(fractures > 0)
|
||||
{
|
||||
cng.fractureWith(generator(null, rngf.nextParallelRNG(salt + fractures), scaleMod / rng.d(4, 17), fractures-1, composites, salt + fractures + 55, null), scaleMod * rngf.nextDouble(16, 256));
|
||||
}
|
||||
|
||||
for(int i = 0; i < composites; i++)
|
||||
{
|
||||
CNG sub = generator(null, rngf.nextParallelRNG(salt + fractures), scaleMod * rngf.d(0.4, 3.3), fractures / 3, 0, salt + fractures + composites + 78, null);
|
||||
sub.setInjector(rng.pick(injectors));
|
||||
cng.child(sub);
|
||||
}
|
||||
|
||||
if(key != null && meta != null)
|
||||
{
|
||||
meta.registerGenerator(key, cng);
|
||||
}
|
||||
return cng;
|
||||
}
|
||||
}
|
||||
102
src/main/java/com/volmit/iris/util/uniques/UFeatureMeta.java
Normal file
102
src/main/java/com/volmit/iris/util/uniques/UFeatureMeta.java
Normal file
@@ -0,0 +1,102 @@
|
||||
package com.volmit.iris.util.uniques;
|
||||
|
||||
import com.volmit.iris.engine.object.NoiseStyle;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.function.NoiseInjector;
|
||||
import com.volmit.iris.util.interpolation.InterpolationMethod;
|
||||
import com.volmit.iris.util.interpolation.IrisInterpolation;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class UFeatureMeta {
|
||||
private KMap<String, UFeatureMetaInterpolator> interpolators;
|
||||
private KMap<String, UFeatureMetaGenerator> generators;
|
||||
private String feature;
|
||||
|
||||
public void registerInterpolator(String key, InterpolationMethod method, double radius)
|
||||
{
|
||||
if(interpolators == null)
|
||||
{
|
||||
interpolators = new KMap<>();
|
||||
}
|
||||
interpolators.put(key, new UFeatureMetaInterpolator(method, radius));
|
||||
}
|
||||
|
||||
public void registerGenerator(String key, CNG cng)
|
||||
{
|
||||
if(generators == null)
|
||||
{
|
||||
generators = new KMap<>();
|
||||
}
|
||||
generators.put(key, buildGenerator(cng));
|
||||
}
|
||||
|
||||
public UFeatureMetaGenerator buildGenerator(CNG cng)
|
||||
{
|
||||
UFeatureMetaGenerator g = new UFeatureMetaGenerator();
|
||||
g.setScale(cng.getScale());
|
||||
g.setOctaves(cng.getOct());
|
||||
|
||||
if(cng.getFracture() != null)
|
||||
{
|
||||
g.setFracture(buildGenerator(cng.getFracture()));
|
||||
g.setFractureMultiplier(cng.getFscale());
|
||||
}
|
||||
|
||||
if(cng.getChildren() != null && cng.getChildren().isNotEmpty())
|
||||
{
|
||||
g.setChildren(new KList<>());
|
||||
|
||||
for(CNG i : cng.getChildren())
|
||||
{
|
||||
g.getChildren().add(buildGenerator(i));
|
||||
}
|
||||
}
|
||||
|
||||
if(cng.getInjector() == CNG.ADD){g.setParentInject("add");}
|
||||
else if(cng.getInjector() == CNG.SRC_SUBTRACT){g.setParentInject("src_subtract");}
|
||||
else if(cng.getInjector() == CNG.DST_SUBTRACT){g.setParentInject("dst_subtract");}
|
||||
else if(cng.getInjector() == CNG.MULTIPLY ){g.setParentInject("multiply");}
|
||||
else if(cng.getInjector() == CNG.MAX){g.setParentInject("max");}
|
||||
else if(cng.getInjector() == CNG.MIN){g.setParentInject("min");}
|
||||
else if(cng.getInjector() == CNG.SRC_MOD ){g.setParentInject("src_mod");}
|
||||
else if(cng.getInjector() == CNG.SRC_POW ){g.setParentInject("src_pow");}
|
||||
else if(cng.getInjector() == CNG.DST_MOD ){g.setParentInject("dst_mod");}
|
||||
else if(cng.getInjector() == CNG.DST_POW){g.setParentInject("dst_pow");}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return (interpolators == null || interpolators.isEmpty()) && (generators == null || generators.isEmpty());
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
static class UFeatureMetaInterpolator
|
||||
{
|
||||
private InterpolationMethod interpolator;
|
||||
private double radius;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
static class UFeatureMetaGenerator
|
||||
{
|
||||
private NoiseStyle style;
|
||||
private int octaves = 1;
|
||||
private double scale = 1;
|
||||
private String parentInject;
|
||||
private UFeatureMetaGenerator fracture;
|
||||
private Double fractureMultiplier;
|
||||
private List<UFeatureMetaGenerator> children;
|
||||
}
|
||||
}
|
||||
20
src/main/java/com/volmit/iris/util/uniques/UImage.java
Normal file
20
src/main/java/com/volmit/iris/util/uniques/UImage.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package com.volmit.iris.util.uniques;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public interface UImage {
|
||||
int getWidth();
|
||||
|
||||
int getHeight();
|
||||
|
||||
default boolean isInBounds(int x, int y)
|
||||
{
|
||||
return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
|
||||
}
|
||||
|
||||
UImage copy();
|
||||
|
||||
Color get(int x, int y);
|
||||
|
||||
void set(int x, int y, Color color);
|
||||
}
|
||||
56
src/main/java/com/volmit/iris/util/uniques/UMeta.java
Normal file
56
src/main/java/com/volmit/iris/util/uniques/UMeta.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package com.volmit.iris.util.uniques;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.volmit.iris.engine.object.NoiseStyle;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.interpolation.InterpolationMethod;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class UMeta {
|
||||
private transient BufferedImage image;
|
||||
private KMap<String, UFeatureMeta> features;
|
||||
private long id;
|
||||
private double time;
|
||||
private int width;
|
||||
private int height;
|
||||
|
||||
public void registerFeature(String key, UFeatureMeta feature)
|
||||
{
|
||||
if(features == null)
|
||||
{
|
||||
features = new KMap<>();
|
||||
}
|
||||
|
||||
features.put(key, feature);
|
||||
}
|
||||
|
||||
public void export(File destination) throws IOException {
|
||||
|
||||
for(String i : features.k())
|
||||
{
|
||||
if(features.get(i).isEmpty())
|
||||
{
|
||||
features.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
width = image.getWidth();
|
||||
height = image.getHeight();
|
||||
ImageIO.write(image, "PNG", destination);
|
||||
IO.writeAll(new File(destination.getParentFile(), destination.getName() + ".json"), new GsonBuilder().setPrettyPrinting().create().toJson(this));
|
||||
}
|
||||
}
|
||||
338
src/main/java/com/volmit/iris/util/uniques/UniqueRenderer.java
Normal file
338
src/main/java/com/volmit/iris/util/uniques/UniqueRenderer.java
Normal file
@@ -0,0 +1,338 @@
|
||||
package com.volmit.iris.util.uniques;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.engine.object.NoiseStyle;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.function.NoiseProvider;
|
||||
import com.volmit.iris.util.interpolation.InterpolationMethod;
|
||||
import com.volmit.iris.util.interpolation.IrisInterpolation;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import com.volmit.iris.util.stream.ProceduralStream;
|
||||
import com.volmit.iris.util.uniques.features.*;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class UniqueRenderer {
|
||||
static UniqueRenderer renderer;
|
||||
|
||||
static final List<UFeature> backgrounds = List.of(new UFWarpedBackground());
|
||||
static final List<UFeature> interpolators = List.of(new UFInterpolator(), new UFNOOP());
|
||||
static final List<UFeature> features = List.of(new UFWarpedLines(), new UFWarpedDisc(), new UFWarpedDots(), new UFWarpedCircle());
|
||||
private final String seed;
|
||||
private final ProceduralStream<RNG> spatialSeed;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final KMap<String, String> writing = new KMap<>();
|
||||
private KList<NoiseStyle> sortedStyles = new KList<NoiseStyle>();
|
||||
private KList<InterpolationMethod> sortedInterpolators = new KList<InterpolationMethod>();
|
||||
int cores = Runtime.getRuntime().availableProcessors();
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
|
||||
|
||||
public UniqueRenderer(String seed, int width, int height)
|
||||
{
|
||||
renderer = this;
|
||||
computeNoiseStyles(3000, 2);
|
||||
computeInterpolationMethods(3000, 2);
|
||||
this.seed = seed;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
spatialSeed = NoiseStyle.FRACTAL_WATER.stream(new RNG(seed)).convert((d) -> new RNG(Math.round(seed.hashCode() + (d * 934321234D))));
|
||||
new Thread(() -> {
|
||||
while(true)
|
||||
{
|
||||
J.sleep(5000);
|
||||
|
||||
if(!writing.isEmpty())
|
||||
{
|
||||
System.out.println(Form.repeat("\n", 60));
|
||||
System.out.println(Form.memSize(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(), 2) + " of " + Form.memSize(Runtime.getRuntime().totalMemory(), 2));
|
||||
KMap<String, String> c = writing.copy();
|
||||
|
||||
for(String i : writing.k().sort())
|
||||
{
|
||||
String prog = "";
|
||||
String f = writing.get(i);
|
||||
|
||||
if(f.contains("%"))
|
||||
{
|
||||
String v = f.split("\\Q%\\E")[0];
|
||||
try
|
||||
{
|
||||
prog = drawProgress(Double.valueOf(Integer.parseInt(v.substring(v.length() - 2))) / 100D, 30);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
try
|
||||
{
|
||||
prog = drawProgress(Double.valueOf(Integer.parseInt(v.substring(v.length() - 1))) / 100D, 30);
|
||||
}
|
||||
|
||||
catch(Throwable ee)
|
||||
{
|
||||
try
|
||||
{
|
||||
prog = drawProgress(Double.valueOf(Integer.parseInt(v.substring(v.length() - 3))) / 100D, 30);
|
||||
}
|
||||
|
||||
catch(Throwable eee)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(prog + " " + i + " => " + f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public UMeta renderFrameBuffer(long id, double t)
|
||||
{
|
||||
UMeta meta = new UMeta();
|
||||
meta.setId(id);
|
||||
meta.setTime(t);
|
||||
RNG rng = spatialSeed.get(id, id + ((id * id) % (id / 3D)));
|
||||
RNG rngbg = spatialSeed.get(id, -id + ((id * id) % (id / 4D)));
|
||||
BufferedImage buf = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
BufferedImage bufFG = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
UImage image = new UBufferedImage(buf);
|
||||
UImage imageFG = new UBufferedImage(bufFG);
|
||||
ChronoLatch cl = new ChronoLatch(250);
|
||||
UFeature background = rng.pick(backgrounds);
|
||||
UFeature interpolator = rng.pick(interpolators);
|
||||
UFeature foreground = rng.pick(features);
|
||||
UFeature foregroundInterpolator = rng.pick(interpolators);
|
||||
UFeatureMeta backgroundMeta = new UFeatureMeta();
|
||||
UFeatureMeta foregroundMeta = new UFeatureMeta();
|
||||
UFeatureMeta backgroundInterpolatorMeta = new UFeatureMeta();
|
||||
UFeatureMeta foregroundInterpolatorMeta = new UFeatureMeta();
|
||||
background.render(image, rngbg, t, (p) -> {
|
||||
if(cl.flip())
|
||||
{
|
||||
writing.put("#" + id + ":" + t, Form.pc(p / 4D) + " [" + background.getClass().getSimpleName() + " " + Form.pc(p) + "]");
|
||||
}
|
||||
}, backgroundMeta);
|
||||
backgroundMeta.setFeature(background.getClass().getSimpleName());
|
||||
meta.registerFeature("background", backgroundMeta);
|
||||
interpolator.render(image, rng, t, (p) -> {
|
||||
if(cl.flip())
|
||||
{
|
||||
writing.put("#" + id + ":" + t, Form.pc(0.25 + (p / 4d)) + " [" + interpolator.getClass().getSimpleName() + " " + Form.pc(p) + "]");
|
||||
}
|
||||
}, backgroundInterpolatorMeta);
|
||||
backgroundInterpolatorMeta.setFeature(interpolator.getClass().getSimpleName());
|
||||
meta.registerFeature("backgroundInterpolator", backgroundInterpolatorMeta);
|
||||
foreground.render(imageFG, rng, t, (p) -> {
|
||||
if(cl.flip())
|
||||
{
|
||||
writing.put("#" + id + ":" + t, Form.pc(0.5 + (p / 4d)) + " [" + foreground.getClass().getSimpleName() + " " + Form.pc(p) + "]");
|
||||
}
|
||||
}, foregroundMeta);
|
||||
foregroundMeta.setFeature(foreground.getClass().getSimpleName());
|
||||
meta.registerFeature("foreground", foregroundMeta);
|
||||
overlay(imageFG, bufFG, image);
|
||||
foregroundInterpolator.render(image, rng, t, (p) -> {
|
||||
if(cl.flip())
|
||||
{
|
||||
writing.put("#" + id + ":" + t, Form.pc(0.75 + (p / 4d)) + " [" + interpolator.getClass().getSimpleName() + " " + Form.pc(p) + "]");
|
||||
}
|
||||
}, foregroundInterpolatorMeta);
|
||||
foregroundInterpolatorMeta.setFeature(foregroundInterpolator.getClass().getSimpleName());
|
||||
meta.registerFeature("foregroundInterpolator", foregroundInterpolatorMeta);
|
||||
overlay(imageFG, bufFG, image);
|
||||
meta.setImage(buf);
|
||||
writing.remove("#" + id + ":" + t);
|
||||
return meta;
|
||||
}
|
||||
|
||||
private void overlay(UImage layer, BufferedImage layerBuf, UImage onto)
|
||||
{
|
||||
for(int i = 0; i < onto.getWidth(); i++)
|
||||
{
|
||||
for(int j = 0; j < onto.getHeight(); j++)
|
||||
{
|
||||
if(layerBuf.getRGB(i, j) != 0)
|
||||
{
|
||||
onto.set(i, j, layer.get(i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String drawProgress(double progress, int len)
|
||||
{
|
||||
int max = len;
|
||||
int in = (int) Math.round(progress * max);
|
||||
max -= in;
|
||||
|
||||
return "[" + Form.repeat("=", in) + Form.repeat(" ", max)+ "]";
|
||||
}
|
||||
|
||||
private void computeNoiseStyles(double time, double scope) {
|
||||
List<NoiseStyle> allowedStyles = new KList<>(NoiseStyle.values());
|
||||
allowedStyles.remove(NoiseStyle.FLAT);
|
||||
KMap<NoiseStyle, Integer> speeds = new KMap<>();
|
||||
double allocateMS = time;
|
||||
double maxTestDuration = allocateMS / allowedStyles.size();
|
||||
System.out.println("Running Noise Style Benchmark for " + Form.duration(allocateMS, 0) + ".");
|
||||
System.out.println("Benchmarking " + allowedStyles.size() + " + Noise Styles for " + Form.duration(maxTestDuration, 1) + " each.");
|
||||
System.out.println();
|
||||
|
||||
for(NoiseStyle i : allowedStyles)
|
||||
{
|
||||
int score = 0;
|
||||
CNG cng = i.create(new RNG("renderspeedtest"));
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
double g = 0;
|
||||
while(p.getMilliseconds() < maxTestDuration)
|
||||
{
|
||||
cng.noise(g, -g * 2);
|
||||
g+= 0.1;
|
||||
g *= 1.25;
|
||||
score++;
|
||||
}
|
||||
|
||||
speeds.put(i, score);
|
||||
}
|
||||
|
||||
for(NoiseStyle i : speeds.sortKNumber())
|
||||
{
|
||||
System.out.println(Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " ")) + " => " + Form.f(speeds.get(i)));
|
||||
}
|
||||
System.out.println();
|
||||
int takeUpTo = (int) Math.max(1, scope * speeds.size());
|
||||
System.out.println("Choosing the fastest " + Form.pc(scope) + " styles (" + takeUpTo + ")");
|
||||
|
||||
for(NoiseStyle i : speeds.sortKNumber().reverse())
|
||||
{
|
||||
if(takeUpTo-- <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
sortedStyles.add(i);
|
||||
System.out.println("- " + Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " ")));
|
||||
}
|
||||
}
|
||||
|
||||
private void computeInterpolationMethods(double time, double scope) {
|
||||
List<InterpolationMethod> allowedStyles = new KList<>(InterpolationMethod.values());
|
||||
allowedStyles.remove(InterpolationMethod.NONE);
|
||||
KMap<InterpolationMethod, Integer> speeds = new KMap<>();
|
||||
double allocateMS = time;
|
||||
double maxTestDuration = allocateMS / allowedStyles.size();
|
||||
System.out.println("Running Interpolation Method Benchmark for " + Form.duration(allocateMS, 0) + ".");
|
||||
System.out.println("Benchmarking " + allowedStyles.size() + " + Interpolation Methods for " + Form.duration(maxTestDuration, 1) + " each.");
|
||||
System.out.println();
|
||||
|
||||
RNG r = new RNG("renderspeedtestinterpolation");
|
||||
CNG cng = NoiseStyle.SIMPLEX.create(r);
|
||||
NoiseProvider np = (x, z) -> cng.noise(x, z);
|
||||
|
||||
for(InterpolationMethod i : allowedStyles)
|
||||
{
|
||||
int score = 0;
|
||||
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
double g = 0;
|
||||
while(p.getMilliseconds() < maxTestDuration)
|
||||
{
|
||||
IrisInterpolation.getNoise(i, (int) g, (int) (-g * 2.225), r.d(4, 64), np);
|
||||
cng.noise(g, -g * 2);
|
||||
g+= 1.1;
|
||||
g *= 1.25;
|
||||
score++;
|
||||
}
|
||||
|
||||
speeds.put(i, score);
|
||||
}
|
||||
|
||||
for(InterpolationMethod i : speeds.sortKNumber())
|
||||
{
|
||||
System.out.println(Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " ")) + " => " + Form.f(speeds.get(i)));
|
||||
}
|
||||
System.out.println();
|
||||
int takeUpTo = (int) Math.max(1, scope * speeds.size());
|
||||
System.out.println("Choosing the fastest " + Form.pc(scope) + " interpolators (" + takeUpTo + ")");
|
||||
|
||||
for(InterpolationMethod i : speeds.sortKNumber().reverse())
|
||||
{
|
||||
if(takeUpTo-- <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
sortedInterpolators.add(i);
|
||||
System.out.println("- " + Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " ")));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeCollectionFrames(File folder, int fromId, int toId)
|
||||
{
|
||||
folder.mkdirs();
|
||||
BurstExecutor burst = new BurstExecutor(executor, Math.min(toId - fromId, 1000));
|
||||
burst.setMulticore(true);
|
||||
AtomicInteger ai = new AtomicInteger(0);
|
||||
int max = toId - fromId;
|
||||
|
||||
for(int i = fromId; i <= toId; i++)
|
||||
{
|
||||
int ii = i;
|
||||
burst.queue(() -> {
|
||||
|
||||
writing.put("!#[" + fromId + "-" + toId + "] Collection", ai.get() + " of " + max + " (" + Form.pc(ai.get() / (double)max, 0) + ")");
|
||||
writeFrame(new File(folder, ii + ".png"), ii, 0);
|
||||
ai.incrementAndGet();
|
||||
writing.put("!#[" + fromId + "-" + toId + "] Collection", ai.get() + " of " + max + " (" + Form.pc(ai.get() /(double) max, 0) + ")");
|
||||
});
|
||||
}
|
||||
|
||||
burst.complete();
|
||||
writing.remove("!#[" + fromId + "-" + toId + "] Collection");
|
||||
}
|
||||
|
||||
public void writeFrame(File destination, long id, double t) {
|
||||
try
|
||||
{
|
||||
renderFrameBuffer(id, t).export(destination);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void report(String s)
|
||||
{
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
public KList<NoiseStyle> getStyles() {
|
||||
return sortedStyles;
|
||||
}
|
||||
|
||||
public List<InterpolationMethod> getInterpolators() {
|
||||
return sortedInterpolators;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.volmit.iris.util.uniques.features;
|
||||
|
||||
import com.volmit.iris.util.function.NoiseProvider;
|
||||
import com.volmit.iris.util.interpolation.InterpolationMethod;
|
||||
import com.volmit.iris.util.interpolation.IrisInterpolation;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import com.volmit.iris.util.uniques.UFeature;
|
||||
import com.volmit.iris.util.uniques.UFeatureMeta;
|
||||
import com.volmit.iris.util.uniques.UImage;
|
||||
import com.volmit.iris.util.uniques.UniqueRenderer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class UFInterpolator implements UFeature {
|
||||
@Override
|
||||
public void render(UImage image, RNG rng, double t, Consumer<Double> progressor, UFeatureMeta meta) {
|
||||
UImage ref = image.copy();
|
||||
CNG rmod = generator("interpolator_radius", rng, 1, 33004, meta);
|
||||
|
||||
NoiseProvider nHue = (x, y) -> {
|
||||
int ix = Math.abs(((int)x)%ref.getWidth());
|
||||
int iy = Math.abs(((int)y)%ref.getHeight());
|
||||
Color color = ref.get(ix, iy);
|
||||
float[] hsv = new float[3];
|
||||
Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getGreen(), hsv);
|
||||
return hsv[0];
|
||||
};
|
||||
NoiseProvider nSat = (x, y) -> {
|
||||
int ix = Math.abs(((int)x)%ref.getWidth());
|
||||
int iy = Math.abs(((int)y)%ref.getHeight());
|
||||
Color color = ref.get(ix, iy);
|
||||
float[] hsv = new float[3];
|
||||
Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getGreen(), hsv);
|
||||
return hsv[1];
|
||||
};
|
||||
NoiseProvider nBri = (x, y) -> {
|
||||
int ix = Math.abs(((int)x)%ref.getWidth());
|
||||
int iy = Math.abs(((int)y)%ref.getHeight());
|
||||
Color color = ref.get(ix, iy);
|
||||
float[] hsv = new float[3];
|
||||
Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getGreen(), hsv);
|
||||
return hsv[2];
|
||||
};
|
||||
InterpolationMethod method = interpolator(rng);
|
||||
int sizeMin = Math.min(image.getWidth(), image.getHeight());
|
||||
double radius = Math.max(4, rmod.fit(sizeMin / 256, sizeMin / 4, t * rng.d(0.03, 1.25), t * rng.d(0.01, 2.225)));
|
||||
for(int i = 0; i < image.getWidth(); i++)
|
||||
{
|
||||
for(int j = 0; j < image.getHeight(); j++)
|
||||
{
|
||||
image.set(i, j, Color.getHSBColor(
|
||||
(float)Math.max(Math.min(1D, IrisInterpolation.getNoise(method, i, j, radius, nHue)), 0D),
|
||||
(float)Math.max(Math.min(1D, IrisInterpolation.getNoise(method, i, j, radius, nSat)), 0D),
|
||||
(float)Math.max(Math.min(1D, IrisInterpolation.getNoise(method, i, j, radius, nBri)), 0D)
|
||||
));
|
||||
}
|
||||
|
||||
progressor.accept(i / (double)image.getWidth());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.volmit.iris.util.uniques.features;
|
||||
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import com.volmit.iris.util.uniques.UFeature;
|
||||
import com.volmit.iris.util.uniques.UFeatureMeta;
|
||||
import com.volmit.iris.util.uniques.UImage;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class UFNOOP implements UFeature {
|
||||
@Override
|
||||
public void render(UImage image, RNG rng, double t, Consumer<Double> progressor, UFeatureMeta meta) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.volmit.iris.util.uniques.features;
|
||||
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import com.volmit.iris.util.uniques.UFeature;
|
||||
import com.volmit.iris.util.uniques.UFeatureMeta;
|
||||
import com.volmit.iris.util.uniques.UImage;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class UFWarpedBackground implements UFeature {
|
||||
@Override
|
||||
public void render(UImage image, RNG rng, double t, Consumer<Double> progressor, UFeatureMeta meta) {
|
||||
CNG hue = generator("color_hue", rng, rng.d(0.001, rng.d(2, 5)), rng.i(0, 3) ,rng.i(0, 3), 31007, meta);
|
||||
CNG sat = generator("color_sat", rng, rng.d(0.001, rng.d(2, 5)), rng.i(0, 2) ,rng.i(0, 2), 33004, meta);
|
||||
CNG bri = generator("color_bri", rng, rng.d(0.001, rng.d(2, 5)), rng.i(0, 1) ,rng.i(0, 1), 32005, meta).patch(0.145);
|
||||
double tcf = rng.d(0.15, 0.55);
|
||||
|
||||
for(int i = 0; i < image.getWidth(); i++)
|
||||
{
|
||||
for(int j = 0; j < image.getHeight(); j++)
|
||||
{
|
||||
image.set(i, j, color(hue, sat, bri, i, j, tcf * t));
|
||||
}
|
||||
|
||||
progressor.accept(i / (double)image.getWidth());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.volmit.iris.util.uniques.features;
|
||||
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import com.volmit.iris.util.uniques.UFeature;
|
||||
import com.volmit.iris.util.uniques.UFeatureMeta;
|
||||
import com.volmit.iris.util.uniques.UImage;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class UFWarpedCircle implements UFeature {
|
||||
@Override
|
||||
public void render(UImage image, RNG rng, double t, Consumer<Double> progressor, UFeatureMeta meta) {
|
||||
double r = Math.min(image.getWidth(), image.getHeight()) / 2.5D;
|
||||
double i, angle, x1, y1;
|
||||
CNG xShift = generator("x_warp", rng, 0.6, 1001, meta);
|
||||
CNG yShift = generator("y_warp", rng, 0.6, 1002, meta);
|
||||
CNG hue = generator("color_hue", rng, rng.d(0.25, 2.5), 1003, meta);
|
||||
CNG sat = generator("color_sat",rng, rng.d(0.25, 2.5), 1004, meta);
|
||||
CNG bri = generator("color_bri",rng, rng.d(0.25, 2.5), 1005, meta);
|
||||
double tcf = rng.d(0.75, 11.25);
|
||||
double rcf = rng.d(7.75, 16.25);
|
||||
int x = image.getWidth()/2;
|
||||
int y = image.getHeight()/2;
|
||||
|
||||
for(int d = 0; d < 256; d++)
|
||||
{
|
||||
r -= Math.min(image.getWidth(), image.getHeight()) / 300D;
|
||||
|
||||
if(r <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < 360; i += 0.1)
|
||||
{
|
||||
angle = i;
|
||||
x1 = r * Math.cos(angle * Math.PI / 180);
|
||||
y1 = r * Math.sin(angle * Math.PI / 180);
|
||||
image.set((int)Math.round(x + x1 + xShift.fit(-r/2, r/2, x1 + (t+ (d * 8)), -y1 + (t+ (d * 8)))),
|
||||
(int)Math.round(y + y1 + yShift.fit(-r/2, r/2, y1 + (t+ (d * 8)), -x1 + (t+ (d * 8)))),
|
||||
color(hue, sat, bri, x1, y1, (t * tcf) + (d * rcf)));
|
||||
}
|
||||
|
||||
progressor.accept(d / 256D);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.volmit.iris.util.uniques.features;
|
||||
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import com.volmit.iris.util.uniques.UFeature;
|
||||
import com.volmit.iris.util.uniques.UFeatureMeta;
|
||||
import com.volmit.iris.util.uniques.UImage;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class UFWarpedDisc implements UFeature {
|
||||
@Override
|
||||
public void render(UImage image, RNG rng, double t, Consumer<Double> progressor, UFeatureMeta meta) {
|
||||
double r = Math.min(image.getWidth(), image.getHeight()) / 3D;
|
||||
CNG xShift = generator("x_warp", rng, 0.6, 1001, meta);
|
||||
CNG yShift = generator("y_warp",rng, 0.6, 1002, meta);
|
||||
CNG hue = generator("color_hue",rng, rng.d(0.25, 2.5), 1003, meta);
|
||||
CNG sat = generator("color_sat",rng, rng.d(0.25, 2.5), 1004, meta);
|
||||
CNG bri = generator("color_bri",rng, rng.d(0.25, 2.5), 1005, meta);
|
||||
double tcf = rng.d(0.75, 11.25);
|
||||
int x = image.getWidth()/2;
|
||||
int y = image.getHeight()/2;
|
||||
|
||||
for(int i = (int)( x - r); i < x+r; i++)
|
||||
{
|
||||
for(int j =(int)( y - r); j < y+r; j++)
|
||||
{
|
||||
if(image.isInBounds(i, j) && Math.pow(x - i, 2) + Math.pow(y - j, 2) <= r*r)
|
||||
{
|
||||
image.set(Math.round(i + xShift.fit(-r/2, r/2, i+t, -j+t)),
|
||||
Math.round(j + yShift.fit(-r/2, r/2, j+t, -i+t)),
|
||||
color(hue, sat, bri, i, j, tcf * t));
|
||||
}
|
||||
}
|
||||
|
||||
progressor.accept(i / (x + r));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.volmit.iris.util.uniques.features;
|
||||
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import com.volmit.iris.util.uniques.UFeature;
|
||||
import com.volmit.iris.util.uniques.UFeatureMeta;
|
||||
import com.volmit.iris.util.uniques.UImage;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class UFWarpedDots implements UFeature {
|
||||
@Override
|
||||
public void render(UImage image, RNG rng, double t, Consumer<Double> progressor, UFeatureMeta meta) {
|
||||
CNG genX = generator("x_pos", rng, 4, 2000, meta);
|
||||
CNG genY = generator("y_pos", rng, 4, 2001, meta);
|
||||
|
||||
double tcf = rng.d(0.75, 11.25);
|
||||
|
||||
for(int i = 1; i <= 8; i++)
|
||||
{
|
||||
CNG xShift = generator("x_warp_" + i, rng, 2, 2006+i, meta);
|
||||
CNG yShift = generator("y_warp_" + i,rng, 2, 2007+i, meta);
|
||||
CNG hue = generator("color_hue_" + i,rng, rng.d(0.55, 3.5), 2003+i, meta);
|
||||
CNG sat = generator("color_sat_" + i,rng, rng.d(0.55, 3.5), 2004+i, meta);
|
||||
CNG bri = generator("color_bri_" + i,rng, rng.d(0.55, 3.5), 2005+i, meta);
|
||||
int x = genX.fit(0, image.getWidth(), i * 128, i * 5855);
|
||||
int y = genY.fit(0, image.getHeight(), i * 128, i * 5855);
|
||||
Color color = color(hue, sat, bri, x, y, t);
|
||||
double r = Math.max(genX.fit(image.getWidth() / 10, image.getWidth() / 6, x, y), genY.fit(image.getHeight() / 10, image.getHeight() / 6, x, y));
|
||||
|
||||
for(int j = (int)(x - r); j < x + r; j++)
|
||||
{
|
||||
for(int k = (int)(y - r); k < y + r; k++)
|
||||
{
|
||||
if(image.isInBounds(j, k) && Math.pow(x - j, 2) + Math.pow(y - k, 2) <= r*r)
|
||||
{
|
||||
image.set(Math.round(j + xShift.fit(-r/2, r/2, j+t, -k+t)),
|
||||
Math.round(k + yShift.fit(-r/2, r/2, k+t, -j+t)),
|
||||
color(hue, sat, bri, j, k, tcf * t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
progressor.accept(i / 32D);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.volmit.iris.util.uniques.features;
|
||||
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import com.volmit.iris.util.uniques.UFeature;
|
||||
import com.volmit.iris.util.uniques.UFeatureMeta;
|
||||
import com.volmit.iris.util.uniques.UImage;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class UFWarpedLines implements UFeature {
|
||||
@Override
|
||||
public void render(UImage image, RNG rng, double t, Consumer<Double> progressor, UFeatureMeta meta) {
|
||||
for(int g = 1; g < 5; g++)
|
||||
{
|
||||
CNG xShift = generator("x_warp_"+g, rng, 0.6, 1001 * g, meta);
|
||||
CNG yShift = generator("y_warp_"+g, rng, 0.6, 1002 * g, meta);
|
||||
CNG cX = generator("x_clip_"+g, rng, rng.d(0.035, 0.6), 77001 * g, meta);
|
||||
CNG cY = generator("y_clip"+g, rng, rng.d(0.035, 0.6), 77002, meta);
|
||||
CNG hue = generator("color_hue_"+g, rng, rng.d(0.25, 2.5), 1003 * g, meta);
|
||||
CNG sat = generator("color_sat_"+g, rng, rng.d(0.25, 2.5), 1004 * g, meta);
|
||||
CNG bri = generator("color_bri_"+g, rng, rng.d(0.25, 2.5), 1005 * g, meta);
|
||||
double tcf = rng.d(0.75, 11.25 + (g * 4));
|
||||
double rcf = rng.d(7.75, 16.25 + (g * 5));
|
||||
double xcf = rng.d(0.15, 0.55 + (g * 0.645));
|
||||
double w = rng.d(64, 186 + (g * 8));
|
||||
double ww = image.getWidth() / rng.d(3, 9);
|
||||
double hh = image.getHeight() / rng.d(3, 9);
|
||||
boolean wh = rng.nextBoolean();
|
||||
double sa = rng.d(0.35, 0.66);
|
||||
double sb = rng.d(0.35, 0.66);
|
||||
|
||||
for(int i = 0; i < image.getWidth(); i+= (wh ? image.getWidth() / w : 1))
|
||||
{
|
||||
for(int j = 0; j < image.getHeight(); j+= (!wh ? image.getHeight() / w : 1))
|
||||
{
|
||||
if(cX.fitDouble(0, 1, i, -j, t * xcf) > sa && cY.fitDouble(0, 1, -j, i, t * xcf) > sb)
|
||||
{
|
||||
image.set(Math.round(i + xShift.fit(-ww, ww, i, j, (t * rcf))),
|
||||
Math.round(j + yShift.fit(-hh, hh, -j, i, (t * rcf))),
|
||||
color(hue, sat, bri, i, j, (t * tcf)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user