parse 26.x texture objects in block models (redstone, glass, panes)
Since 26.x a model texture can be an object {"sprite": ..., "force_translucent": ...}
instead of a string. The block-model DTO only accepted strings, so those
models failed to load and rendered as the grey fallback cube: redstone
wire and every glass block and pane (110 models). Accept both forms in
ModelResolver (shared with ItemGeometry).
Edge-case test plugin: redstone/glass scene.
This commit is contained in:
1 parent
9e59435e13
commit
73e521131b
4 files changed
+37
-9
No files matched your search
@@ -29,6 +29,16 @@ public final class ModelResolver {
|
|||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A texture value: a plain reference, or the {@code sprite} of a 26.x texture object; null otherwise. */
|
||||||
|
public static String textureRef(com.google.gson.JsonElement v) {
|
||||||
|
if (v == null) return null;
|
||||||
|
if (v.isJsonPrimitive()) return v.getAsString();
|
||||||
|
if (v.isJsonObject() && v.getAsJsonObject().has("sprite")) {
|
||||||
|
return v.getAsJsonObject().get("sprite").getAsString();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private FlatModel resolve(ResourceLocation modelId, int depth) {
|
private FlatModel resolve(ResourceLocation modelId, int depth) {
|
||||||
ModelFileDto dto =
|
ModelFileDto dto =
|
||||||
reader.readJson(AssetPaths.model(modelId), ModelFileDto.class).orElse(null);
|
reader.readJson(AssetPaths.model(modelId), ModelFileDto.class).orElse(null);
|
||||||
@@ -47,7 +57,10 @@ public final class ModelResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dto.textures != null) {
|
if (dto.textures != null) {
|
||||||
textures.putAll(dto.textures);
|
dto.textures.forEach((key, value) -> {
|
||||||
|
String ref = textureRef(value);
|
||||||
|
if (ref != null) textures.put(key, ref);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FlatModel(textures, elements);
|
return new FlatModel(textures, elements);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package eu.mhsl.minecraft.pixelpics.assets.dto;
|
package eu.mhsl.minecraft.pixelpics.assets.dto;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -9,7 +10,8 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class ModelFileDto {
|
public class ModelFileDto {
|
||||||
public String parent;
|
public String parent;
|
||||||
public Map<String, String> textures;
|
// Values are texture refs ("block/stone", "#side") or, since 26.x, objects {"sprite": …, "force_translucent": …}.
|
||||||
|
public Map<String, JsonElement> textures;
|
||||||
public List<ElementDto> elements;
|
public List<ElementDto> elements;
|
||||||
|
|
||||||
public static class ElementDto {
|
public static class ElementDto {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.google.gson.JsonObject;
|
|||||||
import eu.mhsl.minecraft.pixelpics.assets.AssetPaths;
|
import eu.mhsl.minecraft.pixelpics.assets.AssetPaths;
|
||||||
import eu.mhsl.minecraft.pixelpics.assets.AssetReader;
|
import eu.mhsl.minecraft.pixelpics.assets.AssetReader;
|
||||||
import eu.mhsl.minecraft.pixelpics.assets.BlockModelRegistry;
|
import eu.mhsl.minecraft.pixelpics.assets.BlockModelRegistry;
|
||||||
|
import eu.mhsl.minecraft.pixelpics.assets.ModelResolver;
|
||||||
import eu.mhsl.minecraft.pixelpics.assets.ResourceLocation;
|
import eu.mhsl.minecraft.pixelpics.assets.ResourceLocation;
|
||||||
import eu.mhsl.minecraft.pixelpics.assets.TextureCache;
|
import eu.mhsl.minecraft.pixelpics.assets.TextureCache;
|
||||||
import eu.mhsl.minecraft.pixelpics.assets.model.Direction;
|
import eu.mhsl.minecraft.pixelpics.assets.model.Direction;
|
||||||
@@ -183,13 +184,7 @@ public final class ItemGeometry {
|
|||||||
if (mo.has("textures")) {
|
if (mo.has("textures")) {
|
||||||
for (Map.Entry<String, JsonElement> e :
|
for (Map.Entry<String, JsonElement> e :
|
||||||
mo.getAsJsonObject("textures").entrySet()) {
|
mo.getAsJsonObject("textures").entrySet()) {
|
||||||
JsonElement v = e.getValue();
|
String val = ModelResolver.textureRef(e.getValue());
|
||||||
// 26.x textures may be objects ({"sprite": …, "force_translucent": …}).
|
|
||||||
String val = v.isJsonPrimitive()
|
|
||||||
? v.getAsString()
|
|
||||||
: (v.isJsonObject() && v.getAsJsonObject().has("sprite")
|
|
||||||
? v.getAsJsonObject().get("sprite").getAsString()
|
|
||||||
: null);
|
|
||||||
if (val != null) tex.putIfAbsent(e.getKey(), val);
|
if (val != null) tex.putIfAbsent(e.getKey(), val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public class PPTest extends JavaPlugin {
|
|||||||
scenes.put("shelftop", new Scene("shelftop", this::shelf, 0.52, 6, 0.5, 0.5, 0, 0.5));
|
scenes.put("shelftop", new Scene("shelftop", this::shelf, 0.52, 6, 0.5, 0.5, 0, 0.5));
|
||||||
scenes.put("rotated", new Scene("rotated", this::rotated, 3, 4.5, -4, 3, 0.5, 2));
|
scenes.put("rotated", new Scene("rotated", this::rotated, 3, 4.5, -4, 3, 0.5, 2));
|
||||||
scenes.put("rotated2", new Scene("rotated2", this::rotated, -0.5, 3.5, 9.5, -0.5, 0.5, 5));
|
scenes.put("rotated2", new Scene("rotated2", this::rotated, -0.5, 3.5, 9.5, -0.5, 0.5, 5));
|
||||||
|
scenes.put("redstone", new Scene("redstone", this::redstone, 3, 3, -3, 3, 0, 2));
|
||||||
scenes.put("vehicles", new Scene("vehicles", this::vehicles, 5, 3, -7, 5, 0.6, 1.5));
|
scenes.put("vehicles", new Scene("vehicles", this::vehicles, 5, 3, -7, 5, 0.6, 1.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,6 +425,23 @@ public class PPTest extends JavaPlugin {
|
|||||||
o.clone().add(9, 0, 4).getBlock().setBlockData(Bukkit.createBlockData("minecraft:oak_log[axis=z]"), false);
|
o.clone().add(9, 0, 4).getBlock().setBlockData(Bukkit.createBlockData("minecraft:oak_log[axis=z]"), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Redstone wire (dot, line, corner, climbing a wall, powered/unpowered) next to glass and panes. */
|
||||||
|
private void redstone(Location o) {
|
||||||
|
java.util.function.BiConsumer<int[], String> put = (p, data) -> o.clone().add(p[0], p[1], p[2]).getBlock()
|
||||||
|
.setBlockData(Bukkit.createBlockData("minecraft:" + data), false);
|
||||||
|
put.accept(new int[] {0, 0, 0}, "redstone_wire[power=0]");
|
||||||
|
for (int x = 1; x <= 4; x++) put.accept(new int[] {x, 0, 0}, "redstone_wire[east=side,west=side,power=" + (x * 3) + "]");
|
||||||
|
put.accept(new int[] {5, 0, 0}, "redstone_wire[west=side,north=side,power=15]");
|
||||||
|
put.accept(new int[] {5, 0, -1}, "redstone_wire[south=side,north=up,power=15]");
|
||||||
|
put.accept(new int[] {5, 0, -2}, "stone");
|
||||||
|
put.accept(new int[] {5, 1, -2}, "redstone_wire[south=side,power=15]");
|
||||||
|
put.accept(new int[] {0, 0, 3}, "glass");
|
||||||
|
put.accept(new int[] {1, 0, 3}, "red_stained_glass");
|
||||||
|
put.accept(new int[] {2, 0, 3}, "glass_pane[east=true,west=false]");
|
||||||
|
put.accept(new int[] {3, 0, 3}, "blue_stained_glass_pane[east=true,west=true]");
|
||||||
|
put.accept(new int[] {4, 0, 3}, "blue_stained_glass_pane[west=true,north=true]");
|
||||||
|
}
|
||||||
|
|
||||||
private void vehicles(Location o) {
|
private void vehicles(Location o) {
|
||||||
spawn(o, 0, 0, 0, 0, EntityType.CHEST_MINECART);
|
spawn(o, 0, 0, 0, 0, EntityType.CHEST_MINECART);
|
||||||
spawn(o, 1.8, 0, 0, 90, EntityType.FURNACE_MINECART);
|
spawn(o, 1.8, 0, 0, 90, EntityType.FURNACE_MINECART);
|
||||||
|
|||||||
Reference in new issue
Block a user