9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-26 10:39:07 +00:00

Merge remote-tracking branch 'origin/Development' into Development

This commit is contained in:
Vatuu
2022-07-01 21:00:17 +02:00
33 changed files with 1925 additions and 6 deletions

View File

@@ -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")

View File

@@ -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();

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View File

@@ -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);
}
}

View File

@@ -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

View 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.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);
}
}
}
}
}
}

View File

@@ -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;
@@ -133,14 +141,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;
}
@@ -435,6 +484,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;

View 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);
}
}

View File

@@ -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)
{
}
}
}

View 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;
}
}

View 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;
}
}

View 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);
}

View 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));
}
}

View 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;
}
}

View File

@@ -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());
}
}
}

View File

@@ -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) {
}
}

View File

@@ -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());
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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));
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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)));
}
}
}
}
}
}