This commit is contained in:
Daniel Mills
2020-08-29 14:30:12 -04:00
parent ed9ddc0825
commit 20b715f7cb
41 changed files with 17273 additions and 14829 deletions

View File

@@ -0,0 +1,34 @@
package com.volmit.iris.gui;
import java.awt.image.BufferedImage;
import com.volmit.iris.util.IrisInterpolation;
public class IrisRenderer
{
private Renderer renderer;
public IrisRenderer(Renderer renderer)
{
this.renderer = renderer;
}
public BufferedImage render(double sx, double sz, double size, int resolution)
{
BufferedImage image = new BufferedImage(resolution, resolution, BufferedImage.TYPE_INT_RGB);
double x, z;
int i, j;
for(i = 0; i < resolution; i++)
{
x = IrisInterpolation.lerp(sx, sx + size, (double) i / (double) (resolution));
for(j = 0; j < resolution; j++)
{
z = IrisInterpolation.lerp(sz, sz + size, (double) j / (double) (resolution));
image.setRGB(i, j, renderer.draw(x, z).getRGB());
}
}
return image;
}
}

View File

@@ -0,0 +1,355 @@
package com.volmit.iris.gui;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.volmit.iris.Iris;
import com.volmit.iris.gen.IrisChunkGenerator;
import com.volmit.iris.util.BlockPosition;
import com.volmit.iris.util.J;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.KSet;
import com.volmit.iris.util.O;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.RollingSequence;
public class IrisVision extends JPanel implements MouseWheelListener
{
private static final long serialVersionUID = 2094606939770332040L;
private IrisRenderer renderer;
private int posX = 0;
private int posZ = 0;
private double scale = 128;
private double mscale = 1D;
private int w = 0;
private int h = 0;
private double lx = Double.MAX_VALUE;
private double lz = Double.MAX_VALUE;
private double ox = 0;
private double oz = 0;
private double oxp = 0;
private double ozp = 0;
private short lid = -1;
double tfps = 240D;
private RollingSequence rs = new RollingSequence(512);
private O<Integer> m = new O<>();
private int tid = 0;
private KMap<BlockPosition, BufferedImage> positions = new KMap<>();
private KMap<BlockPosition, BufferedImage> fastpositions = new KMap<>();
private KSet<BlockPosition> working = new KSet<>();
private KSet<BlockPosition> workingfast = new KSet<>();
private final ExecutorService e = Executors.newFixedThreadPool(8, new ThreadFactory()
{
@Override
public Thread newThread(Runnable r)
{
tid++;
Thread t = new Thread(r);
t.setName("Iris HD Renderer " + tid);
t.setPriority(Thread.MIN_PRIORITY);
t.setUncaughtExceptionHandler((et, e) ->
{
Iris.info("Exception encountered in " + et.getName());
e.printStackTrace();
});
return t;
}
});
private final ExecutorService eh = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory()
{
@Override
public Thread newThread(Runnable r)
{
tid++;
Thread t = new Thread(r);
t.setName("Iris Renderer " + tid);
t.setPriority(Thread.NORM_PRIORITY);
t.setUncaughtExceptionHandler((et, e) ->
{
Iris.info("Exception encountered in " + et.getName());
e.printStackTrace();
});
return t;
}
});
public IrisVision()
{
m.set(8);
renderer = new IrisRenderer(null);
rs.put(1);
addMouseWheelListener((MouseWheelListener) this);
addMouseMotionListener(new MouseMotionListener()
{
@Override
public void mouseMoved(MouseEvent e)
{
Point cp = e.getPoint();
lx = (cp.getX());
lz = (cp.getY());
}
@Override
public void mouseDragged(MouseEvent e)
{
Point cp = e.getPoint();
ox += (lx - cp.getX()) * scale;
oz += (lz - cp.getY()) * scale;
lx = cp.getX();
lz = cp.getY();
}
});
}
public BufferedImage getTile(KSet<BlockPosition> fg, int div, int x, int z, O<Integer> m)
{
Iris.proj.getCurrentProject().getCache().targetChunk(x, z);
BlockPosition key = new BlockPosition((int) mscale, Math.floorDiv(x, div), Math.floorDiv(z, div));
fg.add(key);
if(positions.containsKey(key))
{
return positions.get(key);
}
if(fastpositions.containsKey(key))
{
if(!working.contains(key) && working.size() < 9)
{
m.set(m.get() - 1);
if(m.get() >= 0)
{
working.add(key);
double mk = mscale;
double mkd = scale;
short l = lid;
e.submit(() ->
{
PrecisionStopwatch ps = PrecisionStopwatch.start();
BufferedImage b = renderer.render(x * mscale, z * mscale, div * mscale, div);
rs.put(ps.getMilliseconds());
working.remove(key);
if(mk == mscale && mkd == scale && lid == l)
{
positions.put(key, b);
}
});
}
}
return fastpositions.get(key);
}
if(workingfast.contains(key))
{
return null;
}
m.set(m.get() - 1);
if(m.get() >= 0)
{
workingfast.add(key);
double mk = mscale;
double mkd = scale;
short l = lid;
eh.submit(() ->
{
PrecisionStopwatch ps = PrecisionStopwatch.start();
BufferedImage b = renderer.render(x * mscale, z * mscale, div * mscale, div / 12);
rs.put(ps.getMilliseconds());
workingfast.remove(key);
if(mk == mscale && mkd == scale && lid == l)
{
fastpositions.put(key, b);
}
});
}
return null;
}
@Override
public void paint(Graphics gx)
{
if(ox < oxp)
{
oxp -= Math.abs(ox - oxp) * 0.36;
}
if(ox > oxp)
{
oxp += Math.abs(oxp - ox) * 0.36;
}
if(oz < ozp)
{
ozp -= Math.abs(oz - ozp) * 0.36;
}
if(oz > ozp)
{
ozp += Math.abs(ozp - oz) * 0.36;
}
if(lid != Iris.proj.getCurrentProject().getCacheID())
{
working.clear();
workingfast.clear();
positions.clear();
fastpositions.clear();
lid = Iris.proj.getCurrentProject().getCacheID();
Iris.info("Hotloading Vision");
}
PrecisionStopwatch p = PrecisionStopwatch.start();
Graphics2D g = (Graphics2D) gx;
w = getWidth();
h = getHeight();
double vscale = scale;
scale = w / 32D;
if(scale != vscale)
{
positions.clear();
}
KSet<BlockPosition> gg = new KSet<>();
int iscale = (int) scale;
g.setColor(Color.white);
g.clearRect(0, 0, w, h);
posX = (int) oxp;
posZ = (int) ozp;
m.set(3);
for(int r = 0; r < Math.max(w, h); r += iscale)
{
for(int i = -iscale; i < w + iscale; i += iscale)
{
for(int j = -iscale; j < h + iscale; j += iscale)
{
int a = i - (w / 2);
int b = j - (h / 2);
if(a * a + b * b <= r * r)
{
BufferedImage t = getTile(gg, iscale, Math.floorDiv((posX / iscale) + i, iscale) * iscale, Math.floorDiv((posZ / iscale) + j, iscale) * iscale, m);
if(t != null)
{
g.drawImage(t, i - ((posX / iscale) % (iscale)), j - ((posZ / iscale) % (iscale)), (int) (iscale), (int) (iscale), new ImageObserver()
{
@Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
{
return true;
}
});
}
}
}
}
}
p.end();
for(BlockPosition i : positions.k())
{
if(!gg.contains(i))
{
positions.remove(i);
}
}
if(!isVisible())
{
return;
}
if(!getParent().isVisible())
{
return;
}
if(!getParent().getParent().isVisible())
{
return;
}
J.a(() ->
{
J.sleep((long) 1);
repaint();
});
}
private static void createAndShowGUI(Renderer r, short s)
{
JFrame frame = new JFrame("Vision");
IrisVision nv = new IrisVision();
nv.renderer = new IrisRenderer(r);
frame.add(nv);
frame.setSize(1440, 820);
nv.lid = s;
frame.setVisible(true);
File file = Iris.getCached("Iris Icon", "https://raw.githubusercontent.com/VolmitSoftware/Iris/master/icon.png");
if(file != null)
{
try
{
frame.setIconImage(ImageIO.read(file));
}
catch(IOException e)
{
}
}
}
public static void launch(IrisChunkGenerator g)
{
J.a(() ->
{
createAndShowGUI(g.createRenderer(), g.getCacheID());
});
}
public void mouseWheelMoved(MouseWheelEvent e)
{
int notches = e.getWheelRotation();
if(e.isControlDown())
{
return;
}
Iris.info("BPP: " + (mscale) + " BW: " + (w * mscale));
positions.clear();
fastpositions.clear();
mscale = mscale + ((0.044 * mscale) * notches);
mscale = mscale < 0.00001 ? 0.00001 : mscale;
}
}

View File

@@ -1,322 +0,0 @@
package com.volmit.iris.gui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JViewport;
import com.volmit.iris.Iris;
import com.volmit.iris.gen.IrisChunkGenerator;
import com.volmit.iris.noise.CNG;
import com.volmit.iris.object.NoiseStyle;
import com.volmit.iris.util.Function2;
import com.volmit.iris.util.GroupedExecutor;
import com.volmit.iris.util.J;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.M;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.RollingSequence;
public class NoiseView extends JPanel implements MouseWheelListener {
private static final long serialVersionUID = 2094606939770332040L;
static JComboBox<String> combo;
RollingSequence r = new RollingSequence(90);
boolean colorMode = true;
double scale = 1;
static boolean hd = false;
static double ascale = 10;
CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong()));
GroupedExecutor gx = new GroupedExecutor(Runtime.getRuntime().availableProcessors(), Thread.MAX_PRIORITY,
"Iris Renderer");
ReentrantLock l = new ReentrantLock();
int[][] co;
int w = 0;
int h = 0;
static Function2<Double, Double, Color> renderer;
static double oxp = 0;
static double ozp = 0;
double ox = 0;
double oz = 0;
double mx = 0;
double mz = 0;
static double mxx = 0;
static double mzz = 0;
static boolean down = false;
double lx = Double.MAX_VALUE;
double lz = Double.MAX_VALUE;
double tz = 1D;
double t = 1D;
public NoiseView() {
addMouseWheelListener((MouseWheelListener) this);
addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseMoved(MouseEvent e) {
Point cp = e.getPoint();
lx = (cp.getX());
lz = (cp.getY());
mx = lx;
mz = lz;
}
@Override
public void mouseDragged(MouseEvent e) {
Point cp = e.getPoint();
ox += (lx - cp.getX()) * scale;
oz += (lz - cp.getY()) * scale;
lx = cp.getX();
lz = cp.getY();
}
});
}
public void mouseWheelMoved(MouseWheelEvent e) {
int notches = e.getWheelRotation();
if (e.isControlDown()) {
t = t + ((0.001 * t) * notches);
return;
}
scale = scale + ((0.044 * scale) * notches);
scale = scale < 0.00001 ? 0.00001 : scale;
}
@Override
public void paint(Graphics g) {
if (scale < ascale) {
ascale -= Math.abs(scale - ascale) * 0.16;
}
if (scale > ascale) {
ascale += Math.abs(ascale - scale) * 0.16;
}
if (t < tz) {
tz -= Math.abs(t - tz) * 0.29;
}
if (t > tz) {
tz += Math.abs(tz - t) * 0.29;
}
if (ox < oxp) {
oxp -= Math.abs(ox - oxp) * 0.16;
}
if (ox > oxp) {
oxp += Math.abs(oxp - ox) * 0.16;
}
if (oz < ozp) {
ozp -= Math.abs(oz - ozp) * 0.16;
}
if (oz > ozp) {
ozp += Math.abs(ozp - oz) * 0.16;
}
if (mx < mxx) {
mxx -= Math.abs(mx - mxx) * 0.16;
}
if (mx > mxx) {
mxx += Math.abs(mxx - mx) * 0.16;
}
if (mz < mzz) {
mzz -= Math.abs(mz - mzz) * 0.16;
}
if (mz > mzz) {
mzz += Math.abs(mzz - mz) * 0.16;
}
PrecisionStopwatch p = PrecisionStopwatch.start();
int accuracy = hd ? 1 : M.clip((r.getAverage() / 6D), 1D, 128D).intValue();
accuracy = down ? accuracy * 4 : accuracy;
int v = 1000;
Iris.proj.getCurrentProject().getCache().targetChunk(0, 0);
if (g instanceof Graphics2D) {
Graphics2D gg = (Graphics2D) g;
if (getParent().getWidth() != w || getParent().getHeight() != h) {
w = getParent().getWidth();
h = getParent().getHeight();
co = null;
}
if (co == null) {
co = new int[getParent().getWidth()][getParent().getHeight()];
}
for (int x = 0; x < getParent().getWidth(); x += accuracy) {
int xx = x;
for (int z = 0; z < getParent().getHeight(); z += accuracy) {
int zz = z;
gx.queue("a", () -> {
if (renderer != null) {
co[xx][zz] = renderer.apply((xx * ascale) + oxp, (zz * ascale) + ozp).getRGB();
}
else {
double n = cng.noise((xx * ascale) + oxp, tz, (zz * ascale) + ozp);
if (n > 1 || n < 0) {
System.out.println("EXCEEDED " + n);
return;
}
Color color = colorMode
? Color.getHSBColor((float) (n), 1f - (float) (n * n * n * n * n * n),
1f - (float) n)
: Color.getHSBColor(0f, 0f, (float) n);
int rgb = color.getRGB();
co[xx][zz] = rgb;
}
});
}
gx.waitFor("a");
if (hd && p.getMilliseconds() > v) {
break;
}
}
for (int x = 0; x < getParent().getWidth(); x += accuracy) {
for (int z = 0; z < getParent().getHeight(); z += accuracy) {
gg.setColor(new Color(co[x][z]));
gg.fillRect(x, z, accuracy, accuracy);
}
}
if (renderer != null) {
String text = Iris.proj.getCurrentProject().textFor((mxx * ascale) + oxp, (mzz * ascale) + ozp);
gg.setColor(Color.black);
gg.setFont(new Font("TimesRoman", Font.PLAIN, 24));
gg.drawString(text, (float) mxx, (float) mzz);
}
}
p.end();
t += 1D;
r.put(p.getMilliseconds());
if (!isVisible()) {
return;
}
if (!getParent().isVisible()) {
return;
}
if (!getParent().getParent().isVisible()) {
return;
}
EventQueue.invokeLater(() -> {
J.sleep((long) Math.max(0, 32 - r.getAverage()));
repaint();
});
}
private static void createAndShowGUI(IrisChunkGenerator g) {
JFrame frame = new JFrame("Vision");
NoiseView nv = new NoiseView();
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
KList<String> li = new KList<NoiseStyle>(NoiseStyle.values()).toStringList().qadd("PROJECT");
combo = new JComboBox<String>(li.toArray(new String[li.size()]));
combo.setSelectedItem(g != null ? "PROJECT" : "STATIC");
if (g != null) {
renderer = Iris.proj.getCurrentProject().createRenderer();
}
combo.setFocusable(false);
combo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
@SuppressWarnings("unchecked")
String b = (String) (((JComboBox<String>) e.getSource()).getSelectedItem());
if (b.equals("PROJECT")) {
renderer = Iris.proj.getCurrentProject().createRenderer();
return;
}
renderer = null;
NoiseStyle s = NoiseStyle.valueOf(b);
nv.cng = s.create(RNG.r.nextParallelRNG(RNG.r.imax()));
}
});
combo.setSize(500, 30);
JLayeredPane pane = new JLayeredPane();
nv.setSize(new Dimension(1440, 820));
pane.add(nv, 1, 0);
pane.add(combo, 2, 0);
frame.add(pane);
frame.setSize(1440, 820);
frame.setVisible(true);
}
public static void launch(IrisChunkGenerator g) {
EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowGUI(g);
}
});
}
static class HandScrollListener extends MouseAdapter {
private static final Point pp = new Point();
@Override
public void mouseDragged(MouseEvent e) {
JViewport vport = (JViewport) e.getSource();
JComponent label = (JComponent) vport.getView();
Point cp = e.getPoint();
Point vp = vport.getViewPosition();
vp.translate(pp.x - cp.x, pp.y - cp.y);
label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
pp.setLocation(cp);
}
@Override
public void mousePressed(MouseEvent e) {
pp.setLocation(e.getPoint());
}
}
}

View File

@@ -0,0 +1,9 @@
package com.volmit.iris.gui;
import java.awt.Color;
@FunctionalInterface
public interface Renderer
{
public Color draw(double x, double z);
}