Reduce performance impact of rendering, fixed scaling bug

This commit is contained in:
SydMontague 2021-07-08 16:46:28 +02:00
parent eb9671c8e6
commit 5c0a854ba3
3 changed files with 31 additions and 11 deletions

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>net.craftcitizen</groupId> <groupId>net.craftcitizen</groupId>
<artifactId>imagemaps</artifactId> <artifactId>imagemaps</artifactId>
<version>1.0.7-SNAPSHOT</version> <version>1.0.7</version>
<name>ImageMaps</name> <name>ImageMaps</name>
<description>Render Images onto maps!</description> <description>Render Images onto maps!</description>

View File

@ -6,10 +6,15 @@ import java.awt.image.BufferedImage;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas; import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapPalette;
import org.bukkit.map.MapRenderer; import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView; import org.bukkit.map.MapView;
import de.craftlancer.core.LambdaRunnable;
public class ImageMapRenderer extends MapRenderer { public class ImageMapRenderer extends MapRenderer {
private ImageMaps plugin;
private BufferedImage image = null; private BufferedImage image = null;
private boolean first = true; private boolean first = true;
@ -17,7 +22,8 @@ public class ImageMapRenderer extends MapRenderer {
private final int y; private final int y;
private final double scale; private final double scale;
public ImageMapRenderer(BufferedImage image, int x, int y, double scale) { public ImageMapRenderer(ImageMaps plugin, BufferedImage image, int x, int y, double scale) {
this.plugin = plugin;
this.x = x; this.x = x;
this.y = y; this.y = y;
this.scale = scale; this.scale = scale;
@ -28,11 +34,11 @@ public class ImageMapRenderer extends MapRenderer {
if (x * ImageMaps.MAP_WIDTH > Math.round(input.getWidth() * scale) || y * ImageMaps.MAP_HEIGHT > Math.round(input.getHeight() * scale)) if (x * ImageMaps.MAP_WIDTH > Math.round(input.getWidth() * scale) || y * ImageMaps.MAP_HEIGHT > Math.round(input.getHeight() * scale))
return; return;
int x1 = (int) Math.round(x * ImageMaps.MAP_WIDTH / scale); int x1 = (int) Math.floor(x * ImageMaps.MAP_WIDTH / scale);
int y1 = (int) Math.round(y * ImageMaps.MAP_HEIGHT / scale); int y1 = (int) Math.floor(y * ImageMaps.MAP_HEIGHT / scale);
int x2 = (int) Math.round(Math.min(input.getWidth(), ((x + 1) * ImageMaps.MAP_WIDTH / scale))); int x2 = (int) Math.ceil(Math.min(input.getWidth(), ((x + 1) * ImageMaps.MAP_WIDTH / scale)));
int y2 = (int) Math.round(Math.min(input.getHeight(), ((y + 1) * ImageMaps.MAP_HEIGHT / scale))); int y2 = (int) Math.ceil(Math.min(input.getHeight(), ((y + 1) * ImageMaps.MAP_HEIGHT / scale)));
if (x2 - x1 <= 0 || y2 - y1 <= 0) if (x2 - x1 <= 0 || y2 - y1 <= 0)
return; return;
@ -53,8 +59,22 @@ public class ImageMapRenderer extends MapRenderer {
@Override @Override
public void render(MapView view, MapCanvas canvas, Player player) { public void render(MapView view, MapCanvas canvas, Player player) {
if (image != null && first) { if (image != null && first) {
canvas.drawImage(0, 0, image); new LambdaRunnable(() -> {
@SuppressWarnings("deprecation")
byte[] imageData = MapPalette.imageToBytes(image);
new LambdaRunnable(() -> {
for (int x2 = 0; x2 < image.getWidth(null); ++x2) {
for (int y2 = 0; y2 < image.getHeight(null); ++y2) {
canvas.setPixel(x2, y2, imageData[y2 * image.getWidth(null) + x2]);
}
}
}).runTaskLater(plugin, System.nanoTime() % 20);
// spread out pseudo randomly in a very naive way
}).runTaskAsynchronously(plugin);
first = false; first = false;
} }
} }
} }

View File

@ -205,7 +205,7 @@ public class ImageMaps extends JavaPlugin implements Listener {
if(isSetTrackingSupported()) if(isSetTrackingSupported())
map.setTrackingPosition(false); map.setTrackingPosition(false);
map.getRenderers().forEach(map::removeRenderer); map.getRenderers().forEach(map::removeRenderer);
map.addRenderer(new ImageMapRenderer(image, imageMap.getX(), imageMap.getY(), imageMap.getScale())); map.addRenderer(new ImageMapRenderer(this, image, imageMap.getX(), imageMap.getY(), imageMap.getScale()));
maps.put(imageMap, id); maps.put(imageMap, id);
}); });
} }
@ -346,7 +346,7 @@ public class ImageMaps extends JavaPlugin implements Listener {
return PlacementResult.INSUFFICIENT_WALL; return PlacementResult.INSUFFICIENT_WALL;
if (frameBlock.getType().isSolid()) if (frameBlock.getType().isSolid())
return PlacementResult.INSUFFICIENT_SPACE; return PlacementResult.INSUFFICIENT_SPACE;
if (!b.getWorld().getNearbyEntities(frameBlock.getLocation().add(0.5, 0.5, 0.5), 0.5, 0.5, 0.5, a -> (a instanceof Hanging)).isEmpty()) if (!b.getWorld().getNearbyEntities(frameBlock.getLocation().add(0.5, 0.5, 0.5), 0.5, 0.5, 0.5, Hanging.class::isInstance).isEmpty())
return PlacementResult.OVERLAPPING_ENTITY; return PlacementResult.OVERLAPPING_ENTITY;
} }
@ -418,7 +418,7 @@ public class ImageMaps extends JavaPlugin implements Listener {
} }
maps.entrySet().stream().filter(a -> a.getKey().getFilename().equalsIgnoreCase(filename)).map(a -> Bukkit.getMap(a.getValue())) maps.entrySet().stream().filter(a -> a.getKey().getFilename().equalsIgnoreCase(filename)).map(a -> Bukkit.getMap(a.getValue()))
.flatMap(a -> a.getRenderers().stream()).filter(a -> a instanceof ImageMapRenderer).forEach(a -> ((ImageMapRenderer) a).recalculateInput(image)); .flatMap(a -> a.getRenderers().stream()).filter(ImageMapRenderer.class::isInstance).forEach(a -> ((ImageMapRenderer) a).recalculateInput(image));
return true; return true;
} }
@ -436,7 +436,7 @@ public class ImageMaps extends JavaPlugin implements Listener {
MapView map = getServer().createMap(getServer().getWorlds().get(0)); MapView map = getServer().createMap(getServer().getWorlds().get(0));
map.getRenderers().forEach(map::removeRenderer); map.getRenderers().forEach(map::removeRenderer);
map.addRenderer(new ImageMapRenderer(image, x, y, getScale(image, data.getSize()))); map.addRenderer(new ImageMapRenderer(this, image, x, y, getScale(image, data.getSize())));
if(isSetTrackingSupported()) if(isSetTrackingSupported())
map.setTrackingPosition(false); map.setTrackingPosition(false);