From 64f4a3c6b046ef8b4f90f9eb680d918f401152b2 Mon Sep 17 00:00:00 2001 From: zimzaza4 <3625282098@qq.com> Date: Sun, 27 Oct 2024 10:44:11 +0800 Subject: [PATCH] per texture uv --- .../GeneratorMain.java | 34 ++++++++++++++- .../generator/Entity.java | 25 ++++++++--- .../generator/Geometry.java | 12 +++++- .../generator/ModelConfig.java | 8 ++++ .../generator/RenderController.java | 41 ++++++++++++++----- .../generator/Texture.java | 1 + 6 files changed, 103 insertions(+), 18 deletions(-) diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java b/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java index 224a5b0..9f11a7c 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java @@ -5,9 +5,9 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonParser; import re.imc.geysermodelenginepackgenerator.generator.*; +import javax.imageio.ImageIO; import java.io.File; import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -210,12 +210,42 @@ public class GeneratorMain { entry.getValue().modify(); Path path = modelsFolder.toPath().resolve(entry.getValue().getPath() + entry.getKey() + ".geo.json"); path.toFile().getParentFile().mkdirs(); + String id = entry.getValue().getGeometryId(); + + Entity entity = entityMap.get(entry.getKey()); + if (entity != null) { + ModelConfig modelConfig = entity.getModelConfig(); + if (!modelConfig.getPerTextureUvSize().isEmpty()) { + for (Map.Entry textureEntry : entity.getTextureMap().entrySet()) { + String name = textureEntry.getKey(); + + Integer[] size = modelConfig.getPerTextureUvSize().getOrDefault(name, new Integer[]{16, 16}); + String suffix = size[0] + "_" + size[1]; + + path = modelsFolder.toPath().resolve(entry.getValue().getPath() + entry.getKey() + "_" + suffix + ".geo.json"); + + entry.getValue().setId(id + "_" + suffix); + + if (path.toFile().exists()) { + continue; + } + + try { + Files.writeString(path, GSON.toJson(entry.getValue().getJson()), StandardCharsets.UTF_8); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + } if (path.toFile().exists()) { continue; } + try { - Files.writeString(path, entry.getValue().getJson().toString(), StandardCharsets.UTF_8); + Files.writeString(path, GSON.toJson(entry.getValue().getJson()), StandardCharsets.UTF_8); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java index 76ca3af..050b45a 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java @@ -29,7 +29,7 @@ public class Entity { "textures": { }, "geometry": { - "default": "%geometry%" + }, "animations": { "look_at_target": "%look_at_target%" @@ -68,7 +68,7 @@ public class Entity { public void modify() { json = new JsonParser().parse(TEMPLATE.replace("%entity_id%", modelId) - .replace("%geometry%", "geometry.modelengine_" + modelId) + .replace("%geometry%", "geometry.meg_" + modelId) .replace("%texture%", "textures/entity/" + path + modelId) .replace("%look_at_target%", modelConfig.isEnableHeadRotation() ? "animation." + modelId + ".look_at_target" : "animation.none") .replace("%material%", modelConfig.getMaterial())).getAsJsonObject(); @@ -76,6 +76,7 @@ public class Entity { JsonObject description = json.get("minecraft:client_entity").getAsJsonObject().get("description").getAsJsonObject(); JsonObject jsonAnimations = description.get("animations").getAsJsonObject(); JsonObject jsonTextures = description.get("textures").getAsJsonObject(); + JsonObject jsonGeometry = description.get("geometry").getAsJsonObject(); JsonObject jsonMaterials = description.get("materials").getAsJsonObject(); JsonArray jsonRenderControllers = description.get("render_controllers").getAsJsonArray(); @@ -83,10 +84,22 @@ public class Entity { Map materials = getModelConfig().getTextureMaterials(); materials.forEach(jsonMaterials::addProperty); + if (modelConfig.getPerTextureUvSize().isEmpty()) { + jsonGeometry.addProperty("default", "geometry.meg_" + modelId); + jsonTextures.addProperty("default", "textures/entity/" + path + modelId + "/" + textureMap.keySet().stream().findFirst().orElse("def")); + } for (String name : textureMap.keySet()) { - jsonTextures.addProperty(name,"textures/entity/" + path + modelId + "/" + name); + if (modelConfig.getPerTextureUvSize().containsKey(name)) { + Integer[] size = modelConfig.getPerTextureUvSize().getOrDefault(name, new Integer[]{16, 16}); + String suffix = size[0] + "_" + size[1]; + + jsonGeometry.addProperty("t_" + suffix, "geometry.meg_" + modelId + "_" + suffix); + jsonTextures.addProperty(name, "textures/entity/" + path + modelId + "/" + name); + + } jsonRenderControllers.add("controller.render." + modelId + "_" + name); + } JsonArray animate = description.get("scripts").getAsJsonObject().get("animate").getAsJsonArray(); @@ -108,8 +121,10 @@ public class Entity { if (geometry == null) { return; } - for (int i = 0; i < Math.ceil(geometry.getBones().size() / 24f); i++) { - GeyserUtils.addProperty(id, "modelengine:bone" + i, Integer.class); + if (!modelConfig.isDisablePartVisibility()) { + for (int i = 0; i < Math.ceil(geometry.getBones().size() / 24f); i++) { + GeyserUtils.addProperty(id, "modelengine:bone" + i, Integer.class); + } } if (animation != null) { diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java index c8c6bd5..049ce53 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java @@ -18,6 +18,7 @@ public class Geometry { String modelId; + String geometryId; JsonObject json; Map bones = new HashMap<>(); @@ -26,9 +27,18 @@ public class Geometry { this.json = new JsonParser().parse(json).getAsJsonObject(); } public void setId(String id) { + geometryId = id; getInternal().get("description").getAsJsonObject().addProperty("identifier", id); } + public void setTextureWidth(int w) { + getInternal().get("description").getAsJsonObject().addProperty("texture_width", w); + } + + public void setTextureHeight(int h) { + getInternal().get("description").getAsJsonObject().addProperty("texture_height", h); + } + public JsonObject getInternal() { return json.get("minecraft:geometry").getAsJsonArray().get(0) .getAsJsonObject(); @@ -67,7 +77,7 @@ public class Geometry { } } } - setId("geometry.modelengine_" + modelId); + setId("geometry.meg_" + modelId); } public void addAllChildren(Bone p, Bone c) { diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/ModelConfig.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/ModelConfig.java index d2f0419..fd4dace 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/ModelConfig.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/ModelConfig.java @@ -28,11 +28,19 @@ public class ModelConfig { Map animTextures = new HashMap<>(); @SerializedName("texture_materials") Map textureMaterials = new HashMap<>(); + @SerializedName("per_texture_uv_size") + Map perTextureUvSize; + @SerializedName("disable_part_visibility") + boolean disablePartVisibility; public Map getTextureMaterials() { return textureMaterials != null ? textureMaterials : Map.of(); } + public Map getPerTextureUvSize() { + return perTextureUvSize != null ? perTextureUvSize : Map.of(); + } + @NoArgsConstructor @AllArgsConstructor @Getter diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/RenderController.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/RenderController.java index c36e639..0a1565f 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/RenderController.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/RenderController.java @@ -27,9 +27,10 @@ public class RenderController { root.add("render_controllers", renderControllers); Set processedBones = new HashSet<>(); + boolean singleTexture = entity.textureMap.size() == 1; for (String key : entity.textureMap.keySet()) { - Texture texture = entity.textureMap.get(key); + // Texture texture = entity.textureMap.get(key); Set uvBonesId = entity.getModelConfig().bingingBones.get(key); ModelConfig.AnimTextureOptions anim = entity.getModelConfig().getAnimTextures().get(key); @@ -37,10 +38,17 @@ public class RenderController { renderControllers.add("controller.render." + modelId + "_" + key, controller); - controller.addProperty("geometry", "Geometry.default"); - + if (!entity.getModelConfig().getPerTextureUvSize().isEmpty()) { + Integer[] size = entity.getModelConfig().getPerTextureUvSize().getOrDefault(key, new Integer[]{16, 16}); + String suffix = "t_" + size[0] + "_" + size[1]; + controller.addProperty("geometry", "Geometry." + suffix); + } else { + controller.addProperty("geometry", "Geometry.default"); + } JsonArray materials = new JsonArray(); String material = entity.getModelConfig().getTextureMaterials().get(key); + + JsonObject materialItem = new JsonObject(); if (material != null) { materialItem.addProperty("*", "Material." + material); @@ -63,7 +71,11 @@ public class RenderController { controller.add("materials", materials); JsonArray textures = new JsonArray(); - textures.add("Texture." + key); + if (singleTexture) { + textures.add("Texture.default"); + } else { + textures.add("Texture." + key); + } controller.add("textures", textures); // if (enable) { @@ -94,9 +106,6 @@ public class RenderController { if (!bones.containsKey(uvBone)) { continue; } - for (Bone child : bones.get(uvBone).allChildren) { - uvAllBones.add(child.getName()); - } uvAllBones.add(uvBone); } @@ -105,15 +114,27 @@ public class RenderController { boneName = originalId.get(boneName); JsonObject visibilityItem = new JsonObject(); Bone bone = bones.get(boneName); + boolean uvParent = false; + for (Bone child : bone.children) { + if (child.getName().startsWith("uv_")) { + if (uvAllBones.contains(child.getName())) { + uvParent = true; + } + } + } - if (!processedBones.contains(bone) && (uvAllBones.contains(boneName) || uvBonesId.contains("*"))) { + if (!processedBones.contains(bone) && (uvParent || uvAllBones.contains(boneName) || uvBonesId.contains("*"))) { int index = i; if (boneName.startsWith("uv_")) { index = sorted.indexOf(bone.parent); } - int n = (int) Math.pow(2, (index % 24)); - visibilityItem.addProperty(boneName, "math.mod(math.floor(query.property('modelengine:bone" + i / 24 + "') / " + n + "), 2) == 1"); + int n = (int) Math.pow(2, (index % 24)); + if (entity.modelConfig.isDisablePartVisibility()) { + visibilityItem.addProperty(boneName, true); + } else { + visibilityItem.addProperty(boneName, "math.mod(math.floor(query.property('modelengine:bone" + index / 24 + "') / " + n + "), 2) == 1"); + } partVisibility.add(visibilityItem); if (!uvBonesId.contains("*")) { processedBones.add(bone); diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Texture.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Texture.java index 7784b6d..8b8ed75 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Texture.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Texture.java @@ -4,6 +4,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; +import java.awt.image.BufferedImage; import java.nio.file.Path; import java.util.Set;