mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-20 19:22:48 +00:00
355 lines
7.7 KiB
Java
355 lines
7.7 KiB
Java
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.IrisTerrainProvider;
|
|
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)
|
|
{
|
|
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(IrisTerrainProvider 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;
|
|
}
|
|
}
|