diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java b/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java index 8b3518c..9cc0512 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java @@ -43,6 +43,14 @@ public class GeneratorMain { Entity entity = new Entity(modelId); TextureConfig textureConfig = new TextureConfig(); + File textureConfigFile = new File(folder, "texture_config.json"); + if (textureConfigFile.exists()) { + try { + textureConfig = GSON.fromJson(Files.readString(textureConfigFile.toPath()), TextureConfig.class); + } catch (IOException e) { + e.printStackTrace(); + } + } boolean canAdd = false; for (File e : folder.listFiles()) { if (e.isDirectory()) { @@ -52,13 +60,16 @@ public class GeneratorMain { String textureName = e.getName().replace(".png", ""); Set bindingBones = new HashSet<>(); bindingBones.add("*"); - if (!textureConfig.getBingingBones().containsKey(textureName)) { + if (textureConfig.getBingingBones().containsKey(textureName)) { bindingBones = textureConfig.getBingingBones().get(textureName); } - textureMap.computeIfAbsent(modelId, s -> new HashMap<>()).put(textureName, new Texture(modelId, currentPath, bindingBones, e.toPath())); - if (!textureConfig.getBingingBones().isEmpty()) { + Map map = textureMap.computeIfAbsent(modelId, s -> new HashMap<>()); + map.put(textureName, new Texture(modelId, currentPath, bindingBones, e.toPath())); + entity.setTextureMap(map); + if (textureConfig.getBingingBones().isEmpty()) { textureConfig.getBingingBones().put(textureName, Set.of("*")); } + } if (e.getName().endsWith(".json")) { try { @@ -101,6 +112,13 @@ public class GeneratorMain { } catch (IOException ex) { ex.printStackTrace(); } + try { + Files.writeString(textureConfigFile.toPath(), GSON.toJson(textureConfig)); + } catch (IOException ex) { + ex.printStackTrace(); + } + + entity.setTextureConfig(textureConfig); entity.setPath(currentPath); entityMap.put(modelId, entity); } @@ -200,17 +218,20 @@ public class GeneratorMain { } } - for (Map.Entry> entry : textureMap.entrySet()) { - Path path = texturesFolder.toPath().resolve(entry.getValue().getPath() + entry.getKey() + ".png"); - path.toFile().getParentFile().mkdirs(); + for (Map.Entry> textures : textureMap.entrySet()) { - if (path.toFile().exists()) { - continue; - } - try { - Files.copy(entry.getValue().getOriginalPath(), path, StandardCopyOption.REPLACE_EXISTING); - } catch (IOException e) { - e.printStackTrace(); + for (Map.Entry entry : textures.getValue().entrySet()) { + Path path = texturesFolder.toPath().resolve(entry.getValue().getPath() + textures.getKey() + "/" + entry.getKey() + ".png"); + path.toFile().getParentFile().mkdirs(); + + if (path.toFile().exists()) { + continue; + } + try { + Files.copy(entry.getValue().getOriginalPath(), path, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + e.printStackTrace(); + } } } diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Bone.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Bone.java new file mode 100644 index 0000000..c31535d --- /dev/null +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Bone.java @@ -0,0 +1,23 @@ +package re.imc.geysermodelenginepackgenerator.generator; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +public class Bone { + String name; + String parent; + Set children = new HashSet<>(); + Set allChildren = new HashSet<>(); +} diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java index 0ed2c85..50f9e0e 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java @@ -10,10 +10,7 @@ import lombok.Setter; import me.zimzaza4.geyserutils.geyser.GeyserUtils; import re.imc.geysermodelenginepackgenerator.GeneratorMain; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; +import java.util.*; @Getter @Setter @@ -33,6 +30,7 @@ public class Entity { "textures": { }, "geometry": { + "default": "%geometry%" }, "animations": { "look_at_target": "%look_at_target%" @@ -43,7 +41,6 @@ public class Entity { ] }, "render_controllers": [ - "%render_controller%" ] } } @@ -58,7 +55,7 @@ public class Entity { Geometry geometry; RenderController renderController; String path; - Map textureMap; + Map textureMap = new HashMap<>(); TextureConfig textureConfig; @@ -76,17 +73,17 @@ public class Entity { .replace("%geometry%", "geometry.modelengine_" + modelId) .replace("%texture%", "textures/entity/" + path + modelId) .replace("%look_at_target%", Boolean.parseBoolean(config.getProperty("head-rotation", "true".toLowerCase())) ? "animation." + modelId + ".look_at_target" : "animation.none") - .replace("%material%", config.getProperty("material", "entity_alphatest_change_color")) - .replace("%render_controller%", config.getProperty("render_controller", "controller.render.default"))).getAsJsonObject(); + .replace("%material%", config.getProperty("material", "entity_alphatest_change_color"))).getAsJsonObject(); 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(); + JsonArray jsonRenderControllers = description.get("render_controllers").getAsJsonArray(); + for (String name : textureMap.keySet()) { jsonTextures.addProperty(name,"textures/entity/" + path + modelId + "/" + name); - jsonGeometry.addProperty(name, "geometry.modelengine_" + modelId); + jsonRenderControllers.add("controller.render." + modelId + "_" + name); } JsonArray animate = description.get("scripts").getAsJsonObject().get("animate").getAsJsonArray(); diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java index b00bcf3..c8c6bd5 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java @@ -5,6 +5,8 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.geysermc.geyser.api.extension.ExtensionLogger; +import re.imc.geysermodelenginepackgenerator.ExtensionMain; import java.util.*; @@ -17,7 +19,7 @@ public class Geometry { String modelId; JsonObject json; - Set bones = new HashSet<>(); + Map bones = new HashMap<>(); String path; public void load(String json) { @@ -41,6 +43,7 @@ public class Geometry { if (element.isJsonObject()) { String name = element.getAsJsonObject().get("name").getAsString().toLowerCase(Locale.ROOT); + String parent = element.getAsJsonObject().has("parent") ? element.getAsJsonObject().get("parent").getAsString() : null; element.getAsJsonObject().remove("name"); element.getAsJsonObject().addProperty("name", name); @@ -51,10 +54,27 @@ public class Geometry { name.startsWith("b_") || name.startsWith("ob_")) { iterator.remove(); - } else bones.add(name); + } else bones.put(name, new Bone(name, parent, new HashSet<>(), new HashSet<>())); + } + + for (Bone bone : bones.values()) { + if (bone.parent != null) { + Bone parent = bones.get(bone.parent); + if (parent != null) { + parent.children.add(bone); + addAllChildren(parent, bone); + } + } } } setId("geometry.modelengine_" + modelId); } + public void addAllChildren(Bone p, Bone c) { + p.allChildren.add(c); + Bone parent = bones.get(p.parent); + if (parent != null) { + addAllChildren(parent, c); + } + } } diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/RenderController.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/RenderController.java index 275c0ec..235e145 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/RenderController.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/RenderController.java @@ -2,18 +2,22 @@ package re.imc.geysermodelenginepackgenerator.generator; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import com.google.gson.internal.bind.TypeAdapters; import re.imc.geysermodelenginepackgenerator.GeneratorMain; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.IOException; import java.util.*; public class RenderController { - public static final Set NEED_REMOVE_WHEN_SORT = Set.of("pbody_", "plarm_", "prarm_", "plleg_", "prleg_", "phead_", "p_"); + public static final Set NEED_REMOVE_WHEN_SORT = Set.of("pbody_", "plarm_", "prarm_", "plleg_", "prleg_", "phead_", "p_", "uv_"); String modelId; - Set bones; + Map bones; Entity entity; - public RenderController(String modelId, Set bones, Entity entity) { + public RenderController(String modelId, Map bones, Entity entity) { this.modelId = modelId; this.bones = bones; this.entity = entity; @@ -27,53 +31,97 @@ public class RenderController { JsonObject renderControllers = new JsonObject(); root.add("render_controllers", renderControllers); - JsonObject controller = new JsonObject(); - renderControllers.add("controller.render." + modelId, controller); + Set processedBones = new HashSet<>(); + for (String key : entity.textureMap.keySet()) { - controller.addProperty("geometry", "Geometry.default"); + Texture texture = entity.textureMap.get(key); + Set uvBonesId = entity.getTextureConfig().bingingBones.get(key); + TextureConfig.AnimTextureOptions anim = entity.getTextureConfig().getAnimTextures().get(key); - JsonArray materials = new JsonArray(); - JsonObject materialItem = new JsonObject(); - materialItem.addProperty("*", "Material.default"); - materials.add(materialItem); - controller.add("materials", materials); + JsonObject controller = new JsonObject(); - JsonArray textures = new JsonArray(); - textures.add("Texture.default"); - controller.add("textures", textures); - Entity entity = GeneratorMain.entityMap - .get(modelId); - // boolean enable = Boolean.parseBoolean(entity.getConfig().getProperty("enable-part-visibility", "true")); + renderControllers.add("controller.render." + modelId + "_" + key, controller); - // if (enable) { - JsonArray partVisibility = new JsonArray(); - JsonObject visibilityDefault = new JsonObject(); - visibilityDefault.addProperty("*", true); - partVisibility.add(visibilityDefault); - int i = 0; - List sorted = new ArrayList<>(bones); - Map originalId = new HashMap<>(); - ListIterator iterator = sorted.listIterator(); - while (iterator.hasNext()) { - String s = iterator.next(); - String o = s; - for (String r : NEED_REMOVE_WHEN_SORT) { - s = s.replace(r, ""); + controller.addProperty("geometry", "Geometry.default"); + + JsonArray materials = new JsonArray(); + JsonObject materialItem = new JsonObject(); + if (anim != null) { + materialItem.addProperty("*", "Material.anim"); + JsonObject uvAnim = new JsonObject(); + controller.add("uv_anim", uvAnim); + JsonArray offset = new JsonArray(); + offset.add(0.0); + offset.add("math.mod(math.floor(q.life_time * " + anim.fps + ")," + anim.frames + ") / " + anim.frames); + uvAnim.add("offset", offset); + JsonArray scale = new JsonArray(); + scale.add(1.0); + scale.add("1 / " + anim.frames); + uvAnim.add("scale", scale); + } else { + materialItem.addProperty("*", "Material.default"); } - iterator.set(s); - originalId.put(s, o); + materials.add(materialItem); + controller.add("materials", materials); + + JsonArray textures = new JsonArray(); + textures.add("Texture." + key); + controller.add("textures", textures); + + // if (enable) { + JsonArray partVisibility = new JsonArray(); + JsonObject visibilityDefault = new JsonObject(); + visibilityDefault.addProperty("*", false); + partVisibility.add(visibilityDefault); + int i = 0; + List sorted = new ArrayList<>(bones.keySet()); + Map originalId = new HashMap<>(); + ListIterator iterator = sorted.listIterator(); + while (iterator.hasNext()) { + String s = iterator.next(); + String o = s; + for (String r : NEED_REMOVE_WHEN_SORT) { + s = s.replace(r, ""); + } + iterator.set(s); + originalId.put(s, o); + } + Collections.sort(sorted); + + Set uvAllBones = new HashSet<>(); + for (String uvBone : uvBonesId) { + if (uvBone.equals("*")) { + uvAllBones.addAll(bones.keySet()); + } + if (!bones.containsKey(uvBone)) { + continue; + } + for (Bone child : bones.get(uvBone).allChildren) { + uvAllBones.add(child.getName()); + } + uvAllBones.add(uvBone); + } + + + for (String boneName : sorted) { + boneName = originalId.get(boneName); + JsonObject visibilityItem = new JsonObject(); + int n = (int) Math.pow(2, (i % 24)); + Bone bone = bones.get(boneName); + + if (!processedBones.contains(bone) && (uvAllBones.contains(boneName) || uvBonesId.contains("*"))) { + visibilityItem.addProperty(boneName, "math.mod(math.floor(query.property('modelengine:bone" + i / 24 + "') / " + n + "), 2) == 1"); + partVisibility.add(visibilityItem); + if (!uvBonesId.contains("*")) { + processedBones.add(bone); + } + } + i++; + } + controller.add("part_visibility", partVisibility); + //} } - Collections.sort(sorted); - for (String bone : sorted) { - bone = originalId.get(bone); - JsonObject visibilityItem = new JsonObject(); - int n = (int) Math.pow(2, (i % 24)); - visibilityItem.addProperty(bone, "math.mod(math.floor(query.property('modelengine:bone" + i / 24 + "') / " + n + "), 2) == 1"); - partVisibility.add(visibilityItem); - i++; - } - controller.add("part_visibility", partVisibility); - //} + return root.toString(); } diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Texture.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Texture.java index 2715e5e..7784b6d 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Texture.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Texture.java @@ -16,4 +16,5 @@ public class Texture { String path; Set bindingBones; Path originalPath; + }