simplify tools: shared harness setup (pipeline, block proxy, render job, framing, record copy, label cells, contact sheets) for the standalone renderers and the benchmark, block-entity scenes as name/yaw records, one dump pipeline for mob and avatar renderers with a shared submit helper, transform record and jem/entry/subset helpers, posed block entities from direct layer constants, pptest scenes registered once with settle-tick and resolution tables and put() for all blocks, jdk detection and full error log in the dump script, pptest jar rebuilt instead of updated, gradle task printing the tool classpath, comments trimmed
This commit is contained in:
1 parent
b242adb6d2
commit
02e052787c
11 files changed
+1449
-1686
No files matched your search
+24
-79
@@ -1,105 +1,50 @@
|
||||
import eu.mhsl.minecraft.pixelpics.assets.*;
|
||||
import eu.mhsl.minecraft.pixelpics.render.entity.*;
|
||||
import eu.mhsl.minecraft.pixelpics.render.render.*;
|
||||
import eu.mhsl.minecraft.pixelpics.render.sky.SkyContext;
|
||||
import eu.mhsl.minecraft.pixelpics.render.snapshot.WorldSnapshot;
|
||||
import eu.mhsl.minecraft.pixelpics.render.tint.BiomeTintProvider;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Standalone (no server) render of {@link ObjectState}s — block/item/text displays, dropped items,
|
||||
* falling blocks — in one scene, to check the ObjectBaker geometry, UV orientation and transforms.
|
||||
* Output: ~/Dokumente/PixelPics-Entity-Renders/objects.png
|
||||
* Standalone (no server) render of {@link ObjectState}s (block/item/text displays, dropped items) in one scene,
|
||||
* to check the ObjectBaker geometry, UV orientation and transforms. Output: {@code -Dout} (default
|
||||
* ~/Dokumente/PixelPics-Entity-Renders/objects.png). Build: see {@link Harness}.
|
||||
*/
|
||||
public class ObjectTestRender {
|
||||
|
||||
static final String ROOT = "/home/elias/Dokumente/mcTestServer/plugins/PixelPics";
|
||||
|
||||
/** Server-free BlockData stand-in: material + blockstate string are all the model registry needs. */
|
||||
static BlockData block(Material m, String state) {
|
||||
String s = "minecraft:" + m.getKey().getKey() + (state == null ? "" : "[" + state + "]");
|
||||
return (BlockData) Proxy.newProxyInstance(ObjectTestRender.class.getClassLoader(),
|
||||
new Class<?>[]{BlockData.class}, (p, meth, a) -> switch (meth.getName()) {
|
||||
case "getMaterial" -> m;
|
||||
case "getAsString" -> s;
|
||||
case "equals" -> p == a[0];
|
||||
case "hashCode" -> System.identityHashCode(p);
|
||||
case "toString" -> s;
|
||||
default -> {
|
||||
Class<?> rt = meth.getReturnType();
|
||||
yield rt == boolean.class ? false : (rt.isPrimitive() ? 0 : null);
|
||||
}
|
||||
});
|
||||
static ObjectState item(Affine a, String id, Material block, String state) {
|
||||
return ObjectState.item(a, new ItemSpec(id, block == null ? null : Harness.block(block, state), null, false), "none", false);
|
||||
}
|
||||
|
||||
static ObjectState obj(ObjectState.Kind k, Affine a, BlockData b, String item, List<String> lines, int bg) {
|
||||
return switch (k) {
|
||||
case BLOCK -> ObjectState.block(a, b, null);
|
||||
case ITEM -> ObjectState.item(a, new ItemSpec(item, b, null, false), "none", false);
|
||||
case TEXT -> ObjectState.text(a, lines, 200, 0xFFFFFFFF, bg, true);
|
||||
case LEASH -> ObjectState.leash(new double[6]);
|
||||
};
|
||||
static ObjectState text(Affine a, int background, String... lines) {
|
||||
return ObjectState.text(a, List.of(lines), 200, 0xFFFFFFFF, background, true);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Logger log = Logger.getLogger("test");
|
||||
ResourcePack pack = ResourcePackLoader.load(new File(ROOT, "resourcepack"), log).orElseThrow();
|
||||
AssetReader reader = new AssetReader(pack);
|
||||
TextureCache textures = new TextureCache(pack);
|
||||
BlockModelRegistry registry = new BlockModelRegistry(reader, textures);
|
||||
BiomeTintProvider tint = new BiomeTintProvider(textures);
|
||||
var geo = new eu.mhsl.minecraft.pixelpics.render.entity.cem.CemModelLoader();
|
||||
var font = eu.mhsl.minecraft.pixelpics.assets.font.FontLoader.load(pack, textures, log);
|
||||
SkinCache skins = new SkinCache();
|
||||
var baker = new eu.mhsl.minecraft.pixelpics.render.entity.cem.CemBaker(geo, textures, skins);
|
||||
var beBaker = new eu.mhsl.minecraft.pixelpics.render.entity.cem.BlockEntityBaker(geo, textures, skins, font);
|
||||
geo.load(new java.io.FileInputStream("src/main/resources/cem/cem_template_models.json"), log);
|
||||
geo.load(new java.io.FileInputStream("src/main/resources/cem/vanilla_entity_models.json"), log);
|
||||
DefaultScreenRenderer renderer = new DefaultScreenRenderer(registry, tint, textures, baker, beBaker, log);
|
||||
|
||||
Harness h = new Harness("test");
|
||||
List<ObjectState> objs = new ArrayList<>();
|
||||
// Block displays: plain grass block (tinted), rotated + scaled stairs.
|
||||
objs.add(obj(ObjectState.Kind.BLOCK, Affine.translation(0, 0, 0), block(Material.GRASS_BLOCK, "snowy=false"), null, List.of(), 0));
|
||||
objs.add(obj(ObjectState.Kind.BLOCK,
|
||||
Affine.translation(2, 0, 0).mul(Affine.rotY(Math.toRadians(30))).mul(Affine.scale(0.75)),
|
||||
block(Material.OAK_STAIRS, "facing=north,half=bottom,shape=straight,waterlogged=false"), null, List.of(), 0));
|
||||
// Item displays: a flat item and a block item (centred).
|
||||
objs.add(obj(ObjectState.Kind.ITEM, Affine.translation(0.5, 2.0, 0.5), null, "diamond_sword", List.of(), 0));
|
||||
objs.add(obj(ObjectState.Kind.ITEM, Affine.translation(2.5, 2.0, 0.5).mul(Affine.scale(0.6)),
|
||||
block(Material.OAK_LOG, "axis=y"), "oak_log", List.of(), 0));
|
||||
// Text display (facing the camera side), opaque background.
|
||||
objs.add(obj(ObjectState.Kind.TEXT,
|
||||
Affine.translation(1.5, 3.0, 0).mul(Affine.rotY(Math.PI)).mul(Affine.scale(0.025)), null, null,
|
||||
List.of("Hallo PixelPics!", "Zeile zwei äöü"), 0xFF203040));
|
||||
// Text seen from the BACK (front faces +Z, camera is on -Z) on the vanilla default 25% black
|
||||
// background (blended), and a shield item.
|
||||
objs.add(obj(ObjectState.Kind.TEXT, Affine.translation(-0.5, 3.0, 0).mul(Affine.scale(0.025)), null, null,
|
||||
List.of("Rueckseite"), 0x40000000));
|
||||
objs.add(obj(ObjectState.Kind.ITEM, Affine.translation(4, 1.0, 0.5), null, "shield", List.of(), 0));
|
||||
objs.add(ObjectState.block(Affine.translation(0, 0, 0), Harness.block(Material.GRASS_BLOCK, "snowy=false"), null));
|
||||
objs.add(ObjectState.block(Affine.translation(2, 0, 0).mul(Affine.rotY(Math.toRadians(30))).mul(Affine.scale(0.75)),
|
||||
Harness.block(Material.OAK_STAIRS, "facing=north,half=bottom,shape=straight,waterlogged=false"), null));
|
||||
// Item displays: a flat item and a block item.
|
||||
objs.add(item(Affine.translation(0.5, 2.0, 0.5), "diamond_sword", null, null));
|
||||
objs.add(item(Affine.translation(2.5, 2.0, 0.5).mul(Affine.scale(0.6)), "oak_log", Material.OAK_LOG, "axis=y"));
|
||||
// Text facing the camera on an opaque background, and seen from the BACK (front faces +Z, camera is on -Z)
|
||||
// on the vanilla default 25% black background (blended); a shield item.
|
||||
objs.add(text(Affine.translation(1.5, 3.0, 0).mul(Affine.rotY(Math.PI)).mul(Affine.scale(0.025)), 0xFF203040,
|
||||
"Hallo PixelPics!", "Zeile zwei äöü"));
|
||||
objs.add(text(Affine.translation(-0.5, 3.0, 0).mul(Affine.scale(0.025)), 0x40000000, "Rueckseite"));
|
||||
objs.add(item(Affine.translation(4, 1.0, 0.5), "shield", null, null));
|
||||
// Dropped item (flat) on the ground.
|
||||
objs.add(obj(ObjectState.Kind.ITEM, Affine.translation(-1, 0.3, 0.5).mul(Affine.scale(0.5)), null, "apple", List.of(), 0));
|
||||
objs.add(item(Affine.translation(-1, 0.3, 0.5).mul(Affine.scale(0.5)), "apple", null, null));
|
||||
|
||||
BlockData air = block(Material.AIR, null);
|
||||
WorldSnapshot empty = new WorldSnapshot(Map.of(), 0, 1, air);
|
||||
SkyContext sky = new SkyContext(6000, 0, 6000);
|
||||
int W = 480, H = 360;
|
||||
Vector cam = new Vector(1.5, 3.2, -6.5);
|
||||
Location loc = new Location(null, cam.getX(), cam.getY(), cam.getZ());
|
||||
loc.setDirection(new Vector(1.2, 1.3, 0.5).subtract(cam));
|
||||
List<Vector> rayMap = EntityTestRender.buildRayMap(loc, W * 3, H * 3);
|
||||
RenderJob job = new RenderJob(empty, rayMap, cam, W, H, sky, List.of(), List.of(), List.of(), objs);
|
||||
BufferedImage img = renderer.execute(job);
|
||||
int w = 480, ht = 360;
|
||||
BufferedImage img = h.renderer.execute(Harness.job(Harness.emptyWorld(0, 1), new Vector(1.5, 3.2, -6.5),
|
||||
new Vector(1.2, 1.3, 0.5), w, ht, List.of(), List.of(), List.of(), objs));
|
||||
File out = new File(System.getProperty("out", "/home/elias/Dokumente/PixelPics-Entity-Renders/objects.png"));
|
||||
ImageIO.write(img, "png", out);
|
||||
System.out.println("WROTE " + out);
|
||||
|
||||
Reference in new issue
Block a user