create_ponder_wonder

Exports Create ponders to disk.
git clone git://git.oshgnacknak.de/create_ponder_wonder.git
Log | Files | Refs | README

commit a413ca96cae61141446b17cec529f394669ed5ec
parent 8a3b22cc159951360882b4db3b4a965f9b7efc22
Author: grimmauld <soeren@benjos.de>
Date:   Fri, 16 Apr 2021 17:54:06 +0200

More better gooder rendering

Diffstat:
Mbuild.gradle | 2+-
Msrc/main/java/de/oshgnacknak/create_ponder_wonder/PonderRenderScheduler.java | 208++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/main/java/de/oshgnacknak/create_ponder_wonder/PonderRenderer.java | 105++++++++++++++++++++++++++++++++-----------------------------------------------
3 files changed, 153 insertions(+), 162 deletions(-)

diff --git a/build.gradle b/build.gradle @@ -103,7 +103,7 @@ repositories { dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" implementation fg.deobf("curse.maven:create-328085:3278516") - // runtimeOnly fg.deobf("curse.maven:fpsred-280294:3103648") + runtimeOnly fg.deobf("curse.maven:fpsred-280294:3103648") compile fg.deobf("io.github.noeppi_noeppi.mods:LibX:1.16.3-1.0.15") annotationProcessor 'org.spongepowered:mixin:0.8:processor' } diff --git a/src/main/java/de/oshgnacknak/create_ponder_wonder/PonderRenderScheduler.java b/src/main/java/de/oshgnacknak/create_ponder_wonder/PonderRenderScheduler.java @@ -2,114 +2,126 @@ package de.oshgnacknak.create_ponder_wonder; import com.simibubi.create.foundation.ponder.PonderRegistry; import com.simibubi.create.foundation.ponder.PonderScene; +import io.netty.util.concurrent.GlobalEventExecutor; +import io.netty.util.concurrent.Promise; +import net.minecraft.client.Minecraft; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class PonderRenderScheduler { - private static final int GC_INTERVAL = 200; - - private ExecutorService executorService; - private boolean rendering; - - public void start(String basePath) { - if (rendering) { - CreatePonderWonder.chat("Error: cannot be done twice"); - throw new IllegalStateException("Cannot start rendering twice"); - } - - rendering = true; - executorService = Executors.newSingleThreadExecutor(); - - CreatePonderWonder.LOGGER.info("Started rendering ponders"); - CreatePonderWonder.chat("Started rendering ponders"); - - executorService.submit(() -> - renderAllPonders(basePath)); - } - - private void renderAllPonders(String basePath) { - PonderRegistry.all - .values() - .stream() - .map(PonderRegistry::compile) - .flatMap(List::stream) - .forEach(ponder -> saveFrames(ponder, basePath)); - - CreatePonderWonder.LOGGER.info("All ponders rendered: {}", basePath); - CreatePonderWonder.chat("All ponders rendered: " + basePath); - - finishRendering(); - } - - private void saveFrames(PonderScene ponder, String basePath) { - try { - Path path = getOutPath(ponder, basePath); - - for (PonderRenderer.RenderResult result : new PonderRenderer(ponder)) { - Path out = path.resolve(String.format("%06d.png", result.frame)); - result.image.write(out); - if (result.frame % GC_INTERVAL == 0) - System.gc(); - } - System.gc(); - - CreatePonderWonder.chat("Finished rendering Ponder: " + path); - CreatePonderWonder.LOGGER.info("Finished rendering Ponder: {}", path); - } catch (Exception e) { - CreatePonderWonder.chat("Error: " + e.getMessage()); - CreatePonderWonder.LOGGER.error("Could not save image", e); - e.printStackTrace(); - } - } - - private Path getOutPath(PonderScene ponder, String basePath) throws IOException { - Path path = Paths.get( - basePath, - CreatePonderWonder.MODID, - ponder.getString("out")); - Files.createDirectories(path); - return path; - } - - public void stop() { - if (!rendering) { - CreatePonderWonder.chat("Aleady stopped..."); - return; - } - - CreatePonderWonder.LOGGER.warn("Stopping rendering ponders abruptly"); - CreatePonderWonder.chat("Stopping rendering ponders abruptly"); - - try { - executorService.shutdown(); - while (!executorService.awaitTermination(3, TimeUnit.SECONDS)) { - executorService.shutdownNow(); - } - - finishRendering(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - private void finishRendering() { - executorService = null; - rendering = false; - System.gc(); - - CreatePonderWonder.LOGGER.info("Stopped rendering ponders"); - CreatePonderWonder.chat("Stopped rendering ponders"); - } - - public boolean isRendering() { - return rendering; - } + private static final int GC_INTERVAL = 200; + + private ExecutorService executorService; + private boolean rendering; + + public void start(String basePath) { + if (rendering) { + CreatePonderWonder.chat("Error: cannot be done twice"); + throw new IllegalStateException("Cannot start rendering twice"); + } + + rendering = true; + executorService = Executors.newSingleThreadExecutor(); + + CreatePonderWonder.LOGGER.info("Started rendering ponders"); + CreatePonderWonder.chat("Started rendering ponders"); + + renderAllPonders(basePath); + } + + private void renderAllPonders(String basePath) { + PonderRegistry.all + .values() + .stream() + .map(PonderRegistry::compile) + .flatMap(List::stream) + .forEach(ponder -> saveFrames(ponder, basePath)); + + CreatePonderWonder.LOGGER.info("All ponders rendered: {}", basePath); + CreatePonderWonder.chat("All ponders rendered: " + basePath); + + finishRendering(); + } + + private void saveFrames(PonderScene ponder, String basePath) { + Promise<?> promise = GlobalEventExecutor.INSTANCE.newPromise(); + Minecraft.getInstance().field_213275_aU.add(() -> { + try { + Path path = getOutPath(ponder, basePath); + + for (PonderRenderer.RenderResult result : new PonderRenderer(ponder)) { + Path out = path.resolve(String.format("%06d.png", result.frame)); + result.image.write(out); + if (result.frame % GC_INTERVAL == 0) + System.gc(); + } + System.gc(); + promise.setSuccess(null); + + CreatePonderWonder.chat("Finished rendering Ponder: " + path); + CreatePonderWonder.LOGGER.info("Finished rendering Ponder: {}", path); + } catch (Exception e) { + promise.setFailure(e); + } + }); + try { + promise.get(); + } catch (InterruptedException | ExecutionException e) { + CreatePonderWonder.chat("Error: " + e.getMessage()); + CreatePonderWonder.LOGGER.error("Could not save image", e); + e.printStackTrace(); + } + } + + private Path getOutPath(PonderScene ponder, String basePath) throws IOException { + Path path = Paths.get( + basePath, + CreatePonderWonder.MODID, + ponder.getString("out")); + Files.createDirectories(path); + return path; + } + + public void stop() { + if (!rendering) { + CreatePonderWonder.chat("Aleady stopped..."); + return; + } + + CreatePonderWonder.LOGGER.warn("Stopping rendering ponders abruptly"); + CreatePonderWonder.chat("Stopping rendering ponders abruptly"); + + try { + executorService.shutdown(); + while (!executorService.awaitTermination(3, TimeUnit.SECONDS)) { + executorService.shutdownNow(); + } + + finishRendering(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private void finishRendering() { + executorService = null; + rendering = false; + System.gc(); + + CreatePonderWonder.LOGGER.info("Stopped rendering ponders"); + CreatePonderWonder.chat("Stopped rendering ponders"); + } + + public boolean isRendering() { + return rendering; + } } \ No newline at end of file diff --git a/src/main/java/de/oshgnacknak/create_ponder_wonder/PonderRenderer.java b/src/main/java/de/oshgnacknak/create_ponder_wonder/PonderRenderer.java @@ -2,73 +2,52 @@ package de.oshgnacknak.create_ponder_wonder; import com.simibubi.create.foundation.ponder.PonderScene; import com.simibubi.create.foundation.ponder.PonderWonderUI; -import io.netty.util.concurrent.GlobalEventExecutor; -import io.netty.util.concurrent.Promise; -import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.NativeImage; import java.util.Iterator; -import java.util.concurrent.ExecutionException; public class PonderRenderer implements Iterable<PonderRenderer.RenderResult>, Iterator<PonderRenderer.RenderResult> { - public static class RenderResult { - public final NativeImage image; - public final int frame; - - public RenderResult(NativeImage image, int frame) { - this.image = image; - this.frame = frame; - } - } - - private static final int FPS = 60; - private static final int MAX_FRAMES = FPS*3; - - private final PonderWonderUI ponder; - private int frame; - - public PonderRenderer(PonderScene ponder) { - this.ponder = new PonderWonderUI(ponder); - this.frame = 0; - } - - @Override - public Iterator<RenderResult> iterator() { - return this; - } - - @Override - public boolean hasNext() { - return !ponder.isFinished() && frame < MAX_FRAMES; - } - - @Override - public RenderResult next() { - try { - Promise<NativeImage> promise = GlobalEventExecutor.INSTANCE.newPromise(); - - float pt = (frame % PonderRenderer.FPS) / (PonderRenderer.FPS / 3.0f); - Minecraft.getInstance().field_213275_aU.add(() -> { - try { - NativeImage img = RenderUtils.render(ms -> - ponder.ponderWonderRenderWindow(ms, pt)); - promise.setSuccess(img); - } catch (Exception e) { - promise.setFailure(e); - } - }); - - RenderResult res = new RenderResult(promise.get(), frame); - - if (frame % 3 == 2) { - ponder.tick(); - } - frame++; - - return res; - } catch (InterruptedException | ExecutionException e) { - throw new RuntimeException(e); - } - } + private static final int FPS = 60; + private static final int MAX_FRAMES = Integer.MAX_VALUE; // FPS*3; + private final PonderWonderUI ponder; + private int frame; + public PonderRenderer(PonderScene ponder) { + this.ponder = new PonderWonderUI(ponder); + this.frame = -1; + } + + @Override + public Iterator<RenderResult> iterator() { + return this; + } + + @Override + public boolean hasNext() { + return !ponder.isFinished() && frame < MAX_FRAMES; + } + + @Override + public RenderResult next() { + float pt = (frame % PonderRenderer.FPS) / (PonderRenderer.FPS / 3.0f); + NativeImage img = RenderUtils.render(ms -> + ponder.ponderWonderRenderWindow(ms, pt)); + + if (frame % 3 == 2) { + ponder.tick(); + } + frame++; + + return new RenderResult(img, frame); + } + + public static class RenderResult { + public final NativeImage image; + public final int frame; + + public RenderResult(NativeImage image, int frame) { + this.image = image; + this.frame = frame; + } + } }