use of com.demod.dcba.CommandReporting.Level in project Factorio-FBSR by demodude4u.
the class FBSR method applyRendering.
private static BufferedImage applyRendering(CommandReporting reporting, int tileSize, List<Renderer> renderers, ArrayListMultimap<Direction, PanelRenderer> borderPanels, JSONObject options) throws JSONException {
Rectangle2D.Double worldBounds = computeBounds(renderers);
worldBounds.setFrameFromDiagonal(Math.floor(worldBounds.getMinX() + 0.4) - 1, Math.floor(worldBounds.getMinY() + 0.4) - 1, Math.ceil(worldBounds.getMaxX() - 0.4) + 1, Math.ceil(worldBounds.getMaxY() - 0.4) + 1);
Rectangle2D.Double centerBounds = new Rectangle2D.Double(worldBounds.x, worldBounds.y, worldBounds.width, worldBounds.height);
for (Entry<Direction, PanelRenderer> entry : borderPanels.entries()) {
Direction dir = entry.getKey();
PanelRenderer panel = entry.getValue();
switch(dir) {
case NORTH:
case SOUTH:
centerBounds.width = Math.max(centerBounds.width, panel.minWidth);
break;
case EAST:
case WEST:
centerBounds.height = Math.max(centerBounds.height, panel.minHeight);
break;
default:
System.err.println("INVALID BORDER DIRECTION: " + dir);
break;
}
}
float worldRenderScale = 1;
while (((long) (centerBounds.getWidth() * worldRenderScale * tileSize) * (long) (centerBounds.getHeight() * worldRenderScale * tileSize)) > MAX_WORLD_RENDER_PIXELS) {
worldRenderScale /= 2;
}
double borderTop = 0, borderRight = 0, borderBottom = 0, borderLeft = 0;
double borderRightBudget = 0;
for (Entry<Direction, PanelRenderer> entry : borderPanels.entries()) {
Direction dir = entry.getKey();
PanelRenderer panel = entry.getValue();
switch(dir) {
case NORTH:
borderTop += panel.minHeight;
break;
case EAST:
if (borderRightBudget + panel.minHeight > centerBounds.height) {
borderRightBudget = 0;
}
if (borderRightBudget == 0) {
borderRight += panel.minWidth;
}
borderRightBudget += panel.minHeight;
break;
case SOUTH:
borderBottom += panel.minHeight;
break;
case WEST:
borderLeft += panel.minWidth;
break;
default:
System.err.println("INVALID BORDER DIRECTION: " + dir);
break;
}
}
if (options.has("max-width")) {
int width = (int) ((centerBounds.width + borderLeft / worldRenderScale + borderRight / worldRenderScale) * worldRenderScale * tileSize);
int maxWidth = options.getInt("max-width");
if (maxWidth < 10) {
maxWidth = 10;
}
if (width > maxWidth) {
worldRenderScale = (float) ((maxWidth - tileSize * (borderLeft + borderRight)) / (centerBounds.width * tileSize));
}
}
if (options.has("max-height")) {
int height = (int) ((centerBounds.height + borderTop / worldRenderScale + borderBottom / worldRenderScale) * worldRenderScale * tileSize);
int maxHeight = options.getInt("max-height");
if (maxHeight < 10) {
maxHeight = 10;
}
if (height > maxHeight) {
worldRenderScale = (float) ((maxHeight - tileSize * (borderTop + borderBottom)) / (centerBounds.height * tileSize));
}
}
Rectangle2D.Double totalBounds = new Rectangle2D.Double(centerBounds.x - borderLeft / worldRenderScale, centerBounds.y - borderTop / worldRenderScale, centerBounds.width + borderLeft / worldRenderScale + borderRight / worldRenderScale, centerBounds.height + borderTop / worldRenderScale + borderBottom / worldRenderScale);
// System.out.println("IMAGE SCALE: " + worldRenderScale);
// System.out.println("IMAGE DIM: " + (int) (totalBounds.getWidth() *
// worldRenderScale * tileSize) + ","
// + (int) (totalBounds.getHeight() * worldRenderScale * tileSize));
int imageWidth = (int) (totalBounds.getWidth() * worldRenderScale * tileSize);
int imageHeight = (int) (totalBounds.getHeight() * worldRenderScale * tileSize);
System.out.println("\t" + imageWidth + "x" + imageHeight + " (" + worldRenderScale + ")");
BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
BufferedImage shadowImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D shadowG = shadowImage.createGraphics();
AffineTransform noXform = g.getTransform();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.scale(image.getWidth() / totalBounds.getWidth(), image.getHeight() / totalBounds.getHeight());
g.translate(-totalBounds.getX(), -totalBounds.getY());
AffineTransform worldXform = g.getTransform();
shadowG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
shadowG.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
shadowG.setTransform(worldXform);
// Background
g.setColor(GROUND_COLOR);
g.fill(totalBounds);
// Grid Lines
g.setStroke(GRID_STROKE);
g.setColor(GRID_COLOR);
for (double x = Math.round(worldBounds.getMinX()); x <= worldBounds.getMaxX(); x++) {
g.draw(new Line2D.Double(x, worldBounds.getMinY(), x, worldBounds.getMaxY()));
}
for (double y = Math.round(worldBounds.getMinY()); y <= worldBounds.getMaxY(); y++) {
g.draw(new Line2D.Double(worldBounds.getMinX(), y, worldBounds.getMaxX(), y));
}
renderers.stream().filter(r -> r instanceof EntityRenderer).map(r -> (EntityRenderer) r).forEach(r -> {
try {
r.renderShadows(shadowG);
} catch (Exception e) {
reporting.addException(e);
}
});
shadowG.dispose();
RenderUtils.halveAlpha(shadowImage);
renderers.add(new Renderer(Layer.SHADOW_BUFFER, worldBounds) {
@Override
public void render(Graphics2D g) throws Exception {
AffineTransform tempXform = g.getTransform();
g.setTransform(noXform);
g.drawImage(shadowImage, 0, 0, null);
g.setTransform(tempXform);
}
});
boolean debugBounds = options.optBoolean("debug-bounds");
renderers.stream().sorted((r1, r2) -> {
int ret;
ret = r1.getLayer().compareTo(r2.getLayer());
if (ret != 0) {
return ret;
}
Rectangle2D.Double b1 = r1.getBounds();
Rectangle2D.Double b2 = r2.getBounds();
ret = Double.compare(b1.getMinY(), b2.getMinY());
if (ret != 0) {
return ret;
}
ret = Double.compare(b1.getMinX(), b2.getMinX());
if (ret != 0) {
return ret;
}
ret = r1.getLayer().compareTo(r2.getLayer());
return ret;
}).forEach(r -> {
try {
r.render(g);
if (debugBounds) {
g.setStroke(new BasicStroke(1f / 32f));
g.setColor(Color.magenta);
g.draw(r.bounds);
}
} catch (Exception e) {
reporting.addException(e);
}
});
g.setTransform(worldXform);
// Grid Numbers
g.setColor(GRID_COLOR);
g.setFont(new Font("Monospaced", Font.BOLD, 1).deriveFont(0.6f));
for (double x = Math.round(worldBounds.getMinX()) + 1, i = 1; x <= worldBounds.getMaxX() - 2; x++, i++) {
g.drawString(String.format("%02d", (int) Math.round(i) % 100), (float) x + 0.2f, (float) (worldBounds.getMaxY() - 1 + 0.65f));
g.drawString(String.format("%02d", (int) Math.round(i) % 100), (float) x + 0.2f, (float) (worldBounds.getMinY() + 0.65f));
}
for (double y = Math.round(worldBounds.getMinY()) + 1, i = 1; y <= worldBounds.getMaxY() - 2; y++, i++) {
g.drawString(String.format("%02d", (int) Math.round(i) % 100), (float) (worldBounds.getMaxX() - 1 + 0.2f), (float) y + 0.65f);
g.drawString(String.format("%02d", (int) Math.round(i) % 100), (float) (worldBounds.getMinX() + 0.2f), (float) y + 0.65f);
}
{
Rectangle2D.Double bounds = new Rectangle2D.Double(centerBounds.getMinX(), centerBounds.getMinY(), 0, 0);
for (PanelRenderer panel : borderPanels.get(Direction.NORTH)) {
g.setTransform(worldXform);
bounds.y -= panel.minHeight / worldRenderScale;
bounds.width = centerBounds.width;
bounds.height = panel.minHeight;
g.translate(bounds.x, bounds.y);
g.scale(1 / worldRenderScale, 1 / worldRenderScale);
try {
panel.render(g, bounds.width, bounds.height);
} catch (Exception e) {
reporting.addException(e);
}
}
}
{
Rectangle2D.Double bounds = new Rectangle2D.Double(centerBounds.getMaxX(), centerBounds.getMinY(), 0, 0);
for (PanelRenderer panel : borderPanels.get(Direction.EAST)) {
g.setTransform(worldXform);
if (bounds.y + panel.minHeight > centerBounds.getMaxY()) {
bounds.y = centerBounds.getMinY();
bounds.x += panel.minWidth;
}
bounds.width = panel.minWidth;
bounds.height = panel.minHeight;
g.translate(bounds.x, bounds.y);
g.scale(1 / worldRenderScale, 1 / worldRenderScale);
try {
panel.render(g, bounds.width, bounds.height);
} catch (Exception e) {
reporting.addException(e);
}
bounds.y += panel.minHeight / worldRenderScale;
}
}
{
Rectangle2D.Double bounds = new Rectangle2D.Double(centerBounds.getMinX(), centerBounds.getMaxY(), 0, 0);
for (PanelRenderer panel : borderPanels.get(Direction.SOUTH)) {
g.setTransform(worldXform);
bounds.width = centerBounds.width;
bounds.height = panel.minHeight;
g.translate(bounds.x, bounds.y);
g.scale(1 / worldRenderScale, 1 / worldRenderScale);
try {
panel.render(g, bounds.width, bounds.height);
} catch (Exception e) {
reporting.addException(e);
}
bounds.y += panel.minHeight / worldRenderScale;
}
}
{
Rectangle2D.Double bounds = new Rectangle2D.Double(centerBounds.getMinX(), centerBounds.getMinY(), 0, 0);
for (PanelRenderer panel : borderPanels.get(Direction.WEST)) {
g.setTransform(worldXform);
bounds.x -= panel.minWidth / worldRenderScale;
bounds.width = panel.minWidth;
bounds.height = centerBounds.height;
g.translate(bounds.x, bounds.y);
g.scale(1 / worldRenderScale, 1 / worldRenderScale);
try {
panel.render(g, bounds.width, bounds.height);
} catch (Exception e) {
reporting.addException(e);
}
}
}
Level level = reporting.getLevel();
if (level != Level.INFO) {
g.setTransform(worldXform);
g.setStroke(GRID_STROKE);
g.setColor(level.getColor().darker());
g.draw(centerBounds);
}
g.dispose();
return image;
}
Aggregations