rendering fixes: rebaked cubes keep unshaded/additive (end portal/gateway in displays), piston heads no longer skulls (shared block-entity material source), armor/horse armor/carpets/saddles from the equippable component (custom assets, trader llama carpet), inverse-transpose normals for non-uniformly scaled displays, later layer wins on equal depth like vanilla, block tints exactly like vanilla blockcolors (redstone table, stems by age, untinted unknown blocks), pose visibility not forced, pptest scenes tint_blocks/equip_assets/display_fixes

This commit is contained in:
MineTec committed 2026-11-05 13:18:04 +01:00
1 parent 4be03afa3f
commit 291d51891f
14 files changed
+322 -141

No files matched your search

+92 -5
View File
@@ -275,6 +275,97 @@ public class PPTest extends JavaPlugin {
scene("liq_under_warm_top", o -> liqUnder(o, Biome.WARM_OCEAN), -3, 4, -10, 6, -6, 2);
scene("liq_lava", this::liqLava, 4, 4.5, -6, 9, 0, 1);
scene("liq_lava_in", this::liqLava, 3.5, -0.5, 1.5, 9, -0.5, 1.5);
// Block tints like vanilla BlockColors: untinted tintindex blocks (cherry/pale oak leaves, bamboo,
// stonecutter, lava/powder-snow cauldron), leaf litter (dry foliage), petals/wildflowers (stems only), melon
// stems age 0-7 + attached, redstone wire power 0-15 (RedStoneWireBlock.COLORS).
scene("tint_blocks", this::tintBlocks, 7.5, 6, -4.5, 7.5, 0, 2.5);
scene("tint_blocks_close", this::tintBlocks, 4, 2.6, -1.6, 4, 0, 1);
// Equipment from the EQUIPPABLE asset: custom-asset armor/horse armor, elytra on the head (an item, not
// armor), carpets on llamas and on a trader llama, saddles on horse/donkey/pig.
scene("equip_assets", this::equipAssets, 5, 2.8, -5.5, 5, 0.9, 1.5);
// Block displays: end portal/gateway (unshaded), piston head (no skull), a non-uniformly scaled + rotated
// log (normals), grass block (side overlay); shulkers without and with colour.
scene("display_fixes", this::displayFixes, 4.5, 3.2, -5, 4.5, 0.8, 1.5);
}
private void tintBlocks(Location o) {
String[] row0 = {"grass_block", "oak_leaves[persistent=true]", "cherry_leaves[persistent=true]",
"pale_oak_leaves[persistent=true]", "bamboo[age=0,leaves=small,stage=0]", "stonecutter[facing=north]",
"lava_cauldron", "powder_snow_cauldron[level=3]", "water_cauldron[level=3]",
"leaf_litter[facing=north,segment_amount=4]", "pink_petals[facing=north,flower_amount=4]",
"wildflowers[facing=north,flower_amount=4]", "fern", "sugar_cane", "vine[north=false,south=true]"};
for (int i = 0; i < row0.length; i++) put(o, i, 0, 0, row0[i]);
for (int a = 0; a < 8; a++) put(o, a, 0, 2, "melon_stem[age=" + a + "]");
put(o, 8, 0, 2, "attached_melon_stem[facing=south]");
put(o, 9, 0, 2, "pumpkin_stem[age=7]");
put(o, 10, 0, 2, "attached_pumpkin_stem[facing=north]");
for (int p = 0; p < 16; p++)
put(o, p, 0, 4, "redstone_wire[power=" + p + ",north=side,south=side,east=none,west=none]");
}
private static ItemStack withAsset(Material m, EquipmentSlot slot, String asset) {
ItemStack s = it(m);
s.setData(io.papermc.paper.datacomponent.DataComponentTypes.EQUIPPABLE,
io.papermc.paper.datacomponent.item.Equippable.equippable(slot)
.assetId(net.kyori.adventure.key.Key.key("minecraft", asset))
.build());
return s;
}
private void equipAssets(Location o) {
Zombie z = rfSpawn(o, 0, 0, 0, 180, Zombie.class);
z.getEquipment().setChestplate(withAsset(Material.DIAMOND_CHESTPLATE, EquipmentSlot.CHEST, "gold"));
z.getEquipment().setLeggings(withAsset(Material.LEATHER_LEGGINGS, EquipmentSlot.LEGS, "netherite"));
Zombie z2 = rfSpawn(o, 1.3, 0, 0, 180, Zombie.class);
z2.getEquipment().setHelmet(it(Material.ELYTRA));
z2.getEquipment().setChestplate(it(Material.IRON_CHESTPLATE));
Horse h = rfSpawn(o, 3, 0, 0, 180, Horse.class);
h.setColor(Horse.Color.WHITE);
h.setStyle(Horse.Style.NONE);
h.getInventory().setArmor(withAsset(Material.IRON_HORSE_ARMOR, EquipmentSlot.BODY, "diamond"));
h.getInventory().setSaddle(it(Material.SADDLE));
Horse h2 = rfSpawn(o, 5, 0, 0, 180, Horse.class);
h2.setColor(Horse.Color.BROWN);
h2.setStyle(Horse.Style.NONE);
h2.getInventory().setArmor(it(Material.GOLDEN_HORSE_ARMOR));
h2.getInventory().setSaddle(it(Material.SADDLE));
Donkey d = rfSpawn(o, 7, 0, 0, 180, Donkey.class);
d.getInventory().setSaddle(it(Material.SADDLE));
Pig pig = rfSpawn(o, 8.6, 0, 0, 180, Pig.class);
pig.getEquipment().setItem(EquipmentSlot.SADDLE, it(Material.SADDLE));
Llama l = rfSpawn(o, 0.5, 0, 2.5, 180, Llama.class);
l.setColor(Llama.Color.CREAMY);
l.getInventory().setDecor(it(Material.WHITE_CARPET));
Llama l2 = rfSpawn(o, 2.5, 0, 2.5, 180, Llama.class);
l2.setColor(Llama.Color.GRAY);
l2.getInventory().setDecor(it(Material.LIME_CARPET));
TraderLlama t = rfSpawn(o, 4.5, 0, 2.5, 180, TraderLlama.class);
t.setColor(Llama.Color.CREAMY);
t.getInventory().setDecor(it(Material.RED_CARPET));
TraderLlama t2 = rfSpawn(o, 6.5, 0, 2.5, 180, TraderLlama.class);
t2.setColor(Llama.Color.BROWN);
faceNorth(o);
}
private void displayFixes(Location o) {
String[] blocks = {"end_portal", "end_gateway", "piston_head[facing=up,short=false,type=normal]",
"piston_head[facing=north,short=false,type=sticky]", "grass_block[snowy=false]"};
for (int i = 0; i < blocks.length; i++) {
BlockDisplay b = spawn(o, i * 1.6, 0, 0, 0, BlockDisplay.class);
b.setBlock(Bukkit.createBlockData("minecraft:" + blocks[i]));
}
// Non-uniform scale + rotation: the normals need the inverse-transpose (face shading).
Quaternionf rot = new Quaternionf().rotateY((float) Math.toRadians(35)).rotateX((float) Math.toRadians(25));
BlockDisplay n1 = spawn(o, 0.5, 0.2, 2.5, 0, BlockDisplay.class);
n1.setBlock(Bukkit.createBlockData("minecraft:crafting_table"));
n1.setTransformation(new Transformation(new Vector3f(), rot, new Vector3f(2f, 0.6f, 0.4f), new Quaternionf()));
BlockDisplay n2 = spawn(o, 4, 0.2, 2.5, 0, BlockDisplay.class);
n2.setBlock(Bukkit.createBlockData("minecraft:crafting_table"));
n2.setTransformation(new Transformation(new Vector3f(), rot, new Vector3f(0.8f), new Quaternionf()));
Shulker s1 = rfSpawn(o, 6.5, 0, 2.5, 180, Shulker.class);
s1.setColor(null);
Shulker s2 = rfSpawn(o, 8, 0, 2.5, 180, Shulker.class);
s2.setColor(DyeColor.PURPLE);
}
private static ItemStack shield(DyeColor base, Object... patterns) {
@@ -1491,11 +1582,7 @@ public class PPTest extends JavaPlugin {
}
private Entity rfSpawn(Location o, double x, double y, double z, float yaw, EntityType type) {
Location l = o.clone().add(x, y, z);
l.setYaw(yaw);
Entity e = w.spawnEntity(l, type, false);
if (e instanceof Mob m) m.setAI(false);
return e;
return rfSpawn(o, x, y, z, yaw, type.getEntityClass());
}
private void faceNorth(Location o) {