Mapping overload

This commit is contained in:
Daniel Mills 2021-07-15 07:58:20 -04:00
parent df273aca7e
commit 753b69726a
5 changed files with 341 additions and 70 deletions

View File

@ -18,22 +18,36 @@
package com.volmit.iris.manager.gui;
import com.volmit.iris.map.RenderType;
import com.volmit.iris.scaffold.engine.Engine;
import com.volmit.iris.util.IrisInterpolation;
import org.bukkit.Material;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.function.BiFunction;
@SuppressWarnings("ClassCanBeRecord")
public class IrisRenderer {
private final Renderer renderer;
private final Engine renderer;
public IrisRenderer(Renderer renderer) {
public IrisRenderer(Engine renderer) {
this.renderer = renderer;
}
public BufferedImage render(double sx, double sz, double size, int resolution) {
public BufferedImage render(double sx, double sz, double size, int resolution, RenderType currentType) {
BufferedImage image = new BufferedImage(resolution, resolution, BufferedImage.TYPE_INT_RGB);
BiFunction<Double, Double, Integer> colorFunction = (d, dx) -> Color.black.getRGB();
switch (currentType) {
case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getTrueBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
case BIOME_LAND -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getLandBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
case BIOME_SEA -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getSeaBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
case REGION -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getRegionStream().get(x, z).getColor(renderer.getFramework().getComplex(), currentType).getRGB();
case CAVE_LAND -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getCaveBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(renderer.getFramework().getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB();
}
double x, z;
int i, j;
for (i = 0; i < resolution; i++) {
@ -41,7 +55,7 @@ public class IrisRenderer {
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());
image.setRGB(i, j, colorFunction.apply(x, z));
}
}

View File

@ -19,7 +19,13 @@
package com.volmit.iris.manager.gui;
import com.volmit.iris.Iris;
import com.volmit.iris.generator.IrisEngine;
import com.volmit.iris.map.RenderType;
import com.volmit.iris.object.IrisBiome;
import com.volmit.iris.object.IrisRegion;
import com.volmit.iris.scaffold.engine.Engine;
import com.volmit.iris.scaffold.engine.IrisAccess;
import com.volmit.iris.scaffold.parallel.MultiBurst;
import com.volmit.iris.util.*;
import org.bukkit.World;
import org.bukkit.entity.Player;
@ -27,33 +33,45 @@ import org.bukkit.entity.Player;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.BiFunction;
public class IrisVision extends JPanel implements MouseWheelListener {
public class IrisVision extends JPanel implements MouseWheelListener, KeyListener, MouseMotionListener {
private static final long serialVersionUID = 2094606939770332040L;
private IrisRenderer renderer;
private RenderType currentType = RenderType.BIOME;
private boolean help = true;
private boolean helpIgnored = false;
private boolean shift = false;
private boolean debug = false;
private boolean follow = false;
private boolean alt = false;
private int posX = 0;
private IrisRenderer renderer;
private World world;
private double velocity = 0;
private int lowq = 12;
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 lx = 0;
private double lz = 0;
private double ox = 0;
private double oz = 0;
private double hx = 0;
private double hz = 0;
private double oxp = 0;
private double ozp = 0;
private Engine engine;
double tfps = 240D;
int ltc = 3;
private final RollingSequence rs = new RollingSequence(512);
private final O<Integer> m = new O<>();
private int tid = 0;
@ -61,7 +79,7 @@ public class IrisVision extends JPanel implements MouseWheelListener {
private final KMap<BlockPosition, BufferedImage> fastpositions = new KMap<>();
private final KSet<BlockPosition> working = new KSet<>();
private final KSet<BlockPosition> workingfast = new KSet<>();
private final ExecutorService e = Executors.newFixedThreadPool(24, r -> {
private final ExecutorService e = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), r -> {
tid++;
Thread t = new Thread(r);
t.setName("Iris HD Renderer " + tid);
@ -75,7 +93,7 @@ public class IrisVision extends JPanel implements MouseWheelListener {
return t;
});
private final ExecutorService eh = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), r -> {
private final ExecutorService eh = Executors.newFixedThreadPool(ltc, r -> {
tid++;
Thread t = new Thread(r);
t.setName("Iris Renderer " + tid);
@ -89,30 +107,130 @@ public class IrisVision extends JPanel implements MouseWheelListener {
return t;
});
public IrisVision() {
public IrisVision(JFrame frame) {
m.set(8);
renderer = new IrisRenderer(null);
rs.put(1);
addMouseWheelListener(this);
addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseMoved(MouseEvent e) {
Point cp = e.getPoint();
lx = (cp.getX());
lz = (cp.getY());
}
addMouseMotionListener(this);
frame.addKeyListener(this);
J.a(() -> {
J.sleep(10000);
@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();
if (!helpIgnored && help) {
help = false;
}
});
}
@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 int getColor(double wx, double wz) {
BiFunction<Double, Double, Integer> colorFunction = (d, dx) -> Color.black.getRGB();
switch (currentType) {
case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> engine.getFramework().getComplex().getTrueBiomeStream().get(x, z).getColor(engine, currentType).getRGB();
case BIOME_LAND -> colorFunction = (x, z) -> engine.getFramework().getComplex().getLandBiomeStream().get(x, z).getColor(engine, currentType).getRGB();
case BIOME_SEA -> colorFunction = (x, z) -> engine.getFramework().getComplex().getSeaBiomeStream().get(x, z).getColor(engine, currentType).getRGB();
case REGION -> colorFunction = (x, z) -> engine.getFramework().getComplex().getRegionStream().get(x, z).getColor(engine.getFramework().getComplex(), currentType).getRGB();
case CAVE_LAND -> colorFunction = (x, z) -> engine.getFramework().getComplex().getCaveBiomeStream().get(x, z).getColor(engine, currentType).getRGB();
case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(engine.getFramework().getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB();
}
return colorFunction.apply(wx, wz);
}
@Override
public void keyTyped(KeyEvent e) {
int currentMode = currentType.ordinal();
if (e.getKeyCode() == KeyEvent.VK_M) {
currentType = RenderType.values()[(currentMode+1) % RenderType.values().length];
dump();
}
if (e.getKeyCode() == KeyEvent.VK_R) {
dump();
return;
}
if (e.getKeyCode() == KeyEvent.VK_EQUALS) {
return;
}
if (e.getKeyCode() == KeyEvent.VK_MINUS) {
return;
}
for(RenderType i : RenderType.values())
{
if (e.getKeyChar() == String.valueOf(i.ordinal()+1).charAt(0)) {
if(i.ordinal() != currentMode)
{
currentType = i;
dump();
return;
}
}
}
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
shift = true;
} else if (e.getKeyCode() == KeyEvent.VK_SEMICOLON) {
debug = true;
} else if (e.getKeyCode() == KeyEvent.VK_SLASH) {
help = true;
helpIgnored = true;
}else if (e.getKeyCode() == KeyEvent.VK_ALT) {
alt = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SEMICOLON) {
debug = false;
} else if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
shift = false;
} else if (e.getKeyCode() == KeyEvent.VK_SLASH) {
help = false;
helpIgnored = true;
}else if (e.getKeyCode() == KeyEvent.VK_ALT) {
alt = false;
}
if (e.getKeyCode() == KeyEvent.VK_F) {
Iris.info("FOLLOW TOGGLE");
follow = !follow;
}
}
private void dump()
{
positions.clear();
fastpositions.clear();
}
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);
@ -125,14 +243,14 @@ public class IrisVision extends JPanel implements MouseWheelListener {
if (!working.contains(key) && working.size() < 9) {
m.set(m.get() - 1);
if (m.get() >= 0) {
if (m.get() >= 0 && velocity < 50) {
working.add(key);
double mk = mscale;
double mkd = scale;
e.submit(() ->
{
PrecisionStopwatch ps = PrecisionStopwatch.start();
BufferedImage b = renderer.render(x * mscale, z * mscale, div * mscale, div);
BufferedImage b = renderer.render(x * mscale, z * mscale, div * mscale, div, currentType);
rs.put(ps.getMilliseconds());
working.remove(key);
@ -146,71 +264,88 @@ public class IrisVision extends JPanel implements MouseWheelListener {
return fastpositions.get(key);
}
if (workingfast.contains(key)) {
if (workingfast.contains(key) || workingfast.size() > Runtime.getRuntime().availableProcessors()) {
return null;
}
m.set(m.get() - 1);
workingfast.add(key);
double mk = mscale;
double mkd = scale;
eh.submit(() ->
{
PrecisionStopwatch ps = PrecisionStopwatch.start();
BufferedImage b = renderer.render(x * mscale, z * mscale, div * mscale, div / lowq, currentType);
rs.put(ps.getMilliseconds());
workingfast.remove(key);
if (m.get() >= 0) {
workingfast.add(key);
double mk = mscale;
double mkd = scale;
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) {
fastpositions.put(key, b);
}
});
}
if (mk == mscale && mkd == scale) {
fastpositions.put(key, b);
}
});
return null;
}
private double getWorldX(double screenX) {
return (screenX + oxp) * mscale;
return (mscale * screenX) + ((oxp / scale) * mscale);
}
private double getWorldZ(double screenZ) {
return (screenZ + ozp) * mscale;
return (mscale * screenZ) + ((ozp / scale) * mscale);
}
private double getScreenX(double x) {
return (oxp + x) / mscale;
return (x / mscale) - ((oxp / scale));
}
private double getScreenZ(double z) {
return (ozp + z) / mscale;
return (z / mscale) - ((ozp / scale));
}
@Override
public void paint(Graphics gx) {
if (ox < oxp) {
oxp -= Math.abs(ox - oxp) * 0.36;
velocity = Math.abs(ox - oxp) * 0.06;
oxp -= velocity;
}
if (ox > oxp) {
oxp += Math.abs(oxp - ox) * 0.36;
velocity = Math.abs(oxp - ox) * 0.06;
oxp += velocity;
}
if (oz < ozp) {
ozp -= Math.abs(oz - ozp) * 0.36;
velocity = Math.abs(oz - ozp) * 0.06;
ozp -= velocity;
}
if (oz > ozp) {
ozp += Math.abs(ozp - oz) * 0.36;
velocity = Math.abs(ozp - oz) * 0.06;
ozp += velocity;
}
if (lx < hx) {
hx -= Math.abs(lx - hx) * 0.06;
}
if (lx > hx) {
hx += Math.abs(hx - lx) * 0.06;
}
if (lz < hz) {
hz -= Math.abs(lz - hz) * 0.06;
}
if (lz > hz) {
hz += Math.abs(hz - lz) * 0.06;
}
lowq = Math.max(Math.min((int)M.lerp(8, 28, velocity / 1000D), 28), 8);
PrecisionStopwatch p = PrecisionStopwatch.start();
Graphics2D g = (Graphics2D) gx;
w = getWidth();
h = getHeight();
double vscale = scale;
scale = w / 16D;
scale = w / 12D;
if (scale != vscale) {
positions.clear();
@ -248,10 +383,7 @@ public class IrisVision extends JPanel implements MouseWheelListener {
}
}
for (Player i : world.getPlayers()) {
g.setColor(Color.getHSBColor(RNG.r.f(), 1f, 1f));
g.drawRect((int) getScreenX(i.getLocation().getX()), (int) getScreenZ(i.getLocation().getZ()), 4, 4);
}
renderOverlays(g);
if (!isVisible()) {
return;
@ -272,10 +404,135 @@ public class IrisVision extends JPanel implements MouseWheelListener {
});
}
private static void createAndShowGUI(Renderer r, int s, World world) {
private void renderOverlays(Graphics2D g) {
if(help)
{
renderOverlayHelp(g);
}
else if(debug)
{
renderOverlayDebug(g);
}
renderHoverOverlay(g, shift);
Player b = null;
for(Player i : world.getPlayers())
{
b = i;
renderPosition(g, i.getLocation().getX(), i.getLocation().getZ());
}
if(follow && b != null)
{
animateTo(b.getLocation().getX(), b.getLocation().getZ());
drawCardTL(g, new KList<>("Following " + b.getName()));
}
}
private void animateTo(double wx, double wz) {
double sx = getScreenX(wx);
double sz = getScreenZ(wz);
double cx = getWorldX(getWidth()/2);
double cz = getWorldZ(getHeight()/2);
ox += (wx - cx) * 0.77;
oz += (wz - cz) * 0.77;
}
private void renderPosition(Graphics2D g, double x, double z)
{
g.setColor(Color.orange);
g.fillRoundRect((int)getScreenX(x) - 15, (int)getScreenZ(z) - 15, 30, 30, 15, 15);
g.setColor(Color.blue.brighter().brighter());
g.fillRoundRect((int)getScreenX(x) - 10, (int)getScreenZ(z) - 10, 20, 20, 10, 10);
}
private void renderHoverOverlay(Graphics2D g, boolean detailed) {
IrisBiome biome = engine.getFramework().getComplex().getTrueBiomeStream().get(getWorldX(hx), getWorldZ(hz));
IrisRegion region = engine.getFramework().getComplex().getRegionStream().get(getWorldX(hx), getWorldZ(hz));
KList<String> l = new KList<>();
l.add(biome.getName());
if(detailed)
{
l.add("Block " + (int)getWorldX(hx) + ", " + (int)getWorldZ(hz));
l.add("Chunk " + ((int)getWorldX(hx)>>4) + ", " + ((int)getWorldZ(hz)>>4));
l.add("Region " + (((int)getWorldX(hx)>>4)>>5) + ", " + (((int)getWorldZ(hz)>>4)>>5));
l.add("Key: " + biome.getLoadKey());
l.add("File: " + biome.getLoadFile());
l.add("Region: " + region.getName() + "(" + region.getLoadKey() + ")");
}
drawCardAt((float)hx, (float)hz, g, l);
}
private void renderOverlayDebug(Graphics2D g) {
KList<String> l = new KList<>();
l.add("Velocity: " + velocity);
drawCardTL(g, l);
}
private void renderOverlayHelp(Graphics2D g) {
KList<String> l = new KList<>();
l.add("/ to show this help screen");
l.add("R to repaint the screen");
l.add("F to follow first player");
l.add("+/- to Change Zoom");
l.add("M to cycle render modes");
int ff = 0;
for (RenderType i : RenderType.values()) {
ff++;
l.add(ff + " to view " + Form.capitalizeWords(i.name().toLowerCase().replaceAll("\\Q_\\E", " ")));
}
l.add("Shift for additional biome details (at cursor)");
l.add("Shift + Click to teleport to location");
l.add("Alt + Click to open biome in VSCode");
drawCardTL(g, l);
}
private void drawCardTL(Graphics2D g, KList<String> text)
{
drawCardAt(0, 0, g, text);
}
private void drawCardAt(float x, float y, Graphics2D g, KList<String> text)
{
int h = 0;
int w = 0;
for(String i : text)
{
h += g.getFontMetrics().getHeight();
w = Math.max(w, g.getFontMetrics().stringWidth(i));
}
w += 28;
h += 28;
g.setColor(Color.darkGray);
g.fillRect((int)x + 7 + 2, (int)y + 7 + 2, w + 7, h + 7); // Shadow
g.setColor(Color.gray);
g.fillRect((int)x + 7 + 1, (int)y + 7 + 1, w + 7, h + 7); // Shadow
g.setColor(Color.white);
g.fillRect((int)x + 7, (int)y + 7, w + 7, h + 7);
g.setColor(Color.black);
int m = 0;
for(String i : text)
{
g.drawString(i, x + 14, y + 14 + (++m * g.getFontMetrics().getHeight()));
}
}
private static void createAndShowGUI(Engine r, int s, World world) {
JFrame frame = new JFrame("Vision");
IrisVision nv = new IrisVision();
IrisVision nv = new IrisVision(frame);
nv.world = world;
nv.engine = r;
nv.renderer = new IrisRenderer(r);
frame.add(nv);
frame.setSize(1440, 820);
@ -293,7 +550,7 @@ public class IrisVision extends JPanel implements MouseWheelListener {
public static void launch(IrisAccess g, int i) {
J.a(() ->
createAndShowGUI((x, z) -> g.getEngineAccess(i).draw(x, z), i, g.getCompound().getWorld()));
createAndShowGUI(g.getCompound().getEngine(i), i, g.getCompound().getWorld()));
}
public void mouseWheelMoved(MouseWheelEvent e) {

View File

@ -54,11 +54,12 @@ public class MapVision extends JPanel {
private boolean help = true;
private boolean helpIgnored = false;
private boolean dirty = true; //Whether to repaint textures
private double scale = 1;
private boolean shift = false;
private boolean alt = false;
private boolean dirty = true; //Whether to repaint textures
private double scale = 1;
private final KMap<Integer, Tile> tiles = new KMap<>();
private final Set<Tile> visibleTiles = new ConcurrentSet<>(); //Tiles that are visible on screen

View File

@ -90,7 +90,7 @@ public class HunkRegionSlice<T> {
}
public synchronized void save() {
BurstExecutor e = MultiBurst.burstAux.burst();
BurstExecutor e = MultiBurst.burst.burst();
for (ChunkPosition i : save.copy()) {
if (i == null) {
continue;

View File

@ -26,7 +26,6 @@ import java.util.concurrent.Executors;
public class MultiBurst {
public static final MultiBurst burst = new MultiBurst("Iris Burster", 10, Runtime.getRuntime().availableProcessors());
public static final MultiBurst burstAux = new MultiBurst("Iris Aux Burster", 8, Runtime.getRuntime().availableProcessors()/2);
private final ExecutorService service;
private ExecutorService syncService;
private int tid;