block-entity contents from the decompiled renderers: enchanting table book (closed, open towards a nearby photographer), campfire and shelf items, vault display item, copper golem statues (poses, weathering), spawner and trial spawner mobs, beacon beam with glass colours, end portal and gateway star field, block-entity parts in block displays (lectern book, bell), outer item-model transformations for special models, contents test scenes

This commit is contained in:
MineTec committed 2026-11-04 20:15:40 +01:00
1 parent 318a309580
commit 9e48e35680
13 files changed
+925 -28

No files matched your search

+66
View File
@@ -199,6 +199,35 @@ public class BlockEntityTestRender {
scenes.put("wall_piglin_E", List.of(head(Kind.WALL_HEAD, "piglin", 270)));
frontCam.put("wall_piglin_E", 270f);
// --- block-entity contents (no block models in this harness: tables/campfires/shelves/cages absent) ---
scenes.put("enchant_book_closed", List.of(be(Kind.ENCHANTING_TABLE, 0)));
scenes.put("enchant_book_open", List.of(st(Kind.ENCHANTING_TABLE, 0, 0, 90, null, true, null, 0, null, List.of(), List.of())));
frontCam.put("enchant_book_open", 0f);
scenes.put("campfire_items", List.of(contents(Kind.CAMPFIRE, 0, items("beef", "cod", "porkchop", null), null, null, null, null)));
scenes.put("campfire_items_E", List.of(contents(Kind.CAMPFIRE, 270, items("beef", "cod", "porkchop", "salmon"), null, null, null, null)));
scenes.put("shelf_items_S", List.of(contents(Kind.SHELF, 0, items("diamond", "book", "golden_apple"), null, null, null, null)));
frontCam.put("shelf_items_S", 0f);
scenes.put("shelf_items_E", List.of(contents(Kind.SHELF, 270, items("stick", null, "emerald"), null, null, null, null)));
frontCam.put("shelf_items_E", 270f);
scenes.put("vault_item", List.of(contents(Kind.VAULT, 0, items("trial_key"), null, null, null, null)));
frontCam.put("vault_item", 0f);
String[] poses = {"standing", "running", "sitting", "star"};
String[] stages = {null, "exposed", "weathered", "oxidized"};
for (int i = 0; i < 4; i++) {
scenes.put("statue_" + poses[i], List.of(contents(Kind.COPPER_GOLEM_STATUE, i * 90, List.of(), null, null, poses[i], stages[i])));
frontCam.put("statue_" + poses[i], i * 90f);
}
for (String mob : new String[] {"zombie", "pig", "spider", "blaze"}) {
scenes.put("spawner_" + mob, List.of(contents(Kind.SPAWNER, 0, List.of(), spawnerMob(mob), null, null, null)));
frontCam.put("spawner_" + mob, 0f);
}
scenes.put("beacon_beam", List.of(contents(Kind.BEACON, 0, List.of(), null,
new Beam(List.of(new BeamSection(0xFFF9FFFE, 1), new BeamSection(0xFFB02E26, 2), new BeamSection(0xFF3C44AA, 1)), 1f), null, null)));
List<BlockEntityState> portal = new ArrayList<>();
for (int x = 0; x < 3; x++) for (int z = 0; z < 3; z++) portal.add(st(Kind.END_PORTAL, x, z, 0, null, false, null, 0, null, List.of(), List.of()));
scenes.put("end_portal", portal);
scenes.put("end_gateway", List.of(st(Kind.END_GATEWAY, 0, 0, 0, "down+up+north+south+west+east", false, null, 0, null, List.of(), List.of())));
// Decoration scenes (paintings + item frames), rendered via the same scene path.
LinkedHashMap<String, List<DecorationState>> decoScenes = new LinkedHashMap<>();
// kebab is 1x1; place a thin quad facing south spanning the block at z=0..0.0625.
@@ -252,6 +281,42 @@ public class BlockEntityTestRender {
List.of(), List.of(), null, null);
}
/** A contents-bearing block-entity at the origin (items / spawner mob / beacon beam / statue pose). */
static BlockEntityState contents(Kind kind, float yaw, List<eu.mhsl.minecraft.pixelpics.render.entity.ItemSpec> items,
EntityState mob, Beam beam, String pose, String color) {
return new BlockEntityState(kind, 0, 0, 0, yaw, null, false, null, 0, color, null, null,
List.of(), List.of(), null, null, items, mob, beam, pose);
}
static List<eu.mhsl.minecraft.pixelpics.render.entity.ItemSpec> items(String... ids) {
List<eu.mhsl.minecraft.pixelpics.render.entity.ItemSpec> out = new ArrayList<>();
for (String id : ids) out.add(id == null ? null : new eu.mhsl.minecraft.pixelpics.render.entity.ItemSpec(id, null, null, false));
return out;
}
/** EntityTestRender's default state of a mob with its real bounding box (spawner scale depends on it). */
static EntityState spawnerMob(String type) throws Exception {
EntityState e = EntityTestRender.state(type, 0);
double[] dims = switch (type) {
case "zombie" -> new double[] {0.6, 1.95};
case "pig" -> new double[] {0.9, 0.9};
case "spider" -> new double[] {1.4, 0.9};
default -> new double[] {0.6, 1.8};
};
var comps = EntityState.class.getRecordComponents();
Object[] vals = new Object[comps.length];
Class<?>[] types = new Class<?>[comps.length];
for (int i = 0; i < comps.length; i++) {
types[i] = comps[i].getType();
vals[i] = switch (comps[i].getName()) {
case "width" -> dims[0];
case "height" -> dims[1];
default -> comps[i].getAccessor().invoke(e);
};
}
return EntityState.class.getDeclaredConstructor(types).newInstance(vals);
}
static BlockEntityState head(Kind kind, String type, float yaw) {
return st(kind, 0, 0, yaw, null, false, null, 0, type, List.of(), List.of());
}
@@ -266,6 +331,7 @@ public class BlockEntityTestRender {
for (int a = 0; a < 3; a++) { min[a] = Math.min(min[a], re.aabbMin[a]); max[a] = Math.max(max[a], re.aabbMax[a]); }
}
if (min[0] > max[0]) { min = new double[]{0, 0, 0}; max = new double[]{1, 1, 1}; }
if (states.get(0).kind() == Kind.BEACON) max[1] = min[1] + 4; // frame the beam's foot, not 2048 blocks
double cx = (min[0] + max[0]) / 2, cy = (min[1] + max[1]) / 2, cz = (min[2] + max[2]) / 2;
double ext = 0.5;
for (int a = 0; a < 3; a++) ext = Math.max(ext, max[a] - min[a]);