GameModelImporter - Fully implemented game-model export to block bench

This commit is contained in:
miku-666
2024-08-11 22:18:53 +02:00
parent 97cf7e3507
commit 06860bfb7a
4 changed files with 187 additions and 68 deletions

View File

@@ -264,23 +264,6 @@ namespace PckStudio.External.Format
rotation[2] = value.Z;
}
}
[JsonProperty("pivot")]
private float[] pivot;
[JsonIgnore]
public Vector3 Pivot
{
get => new Vector3(pivot?[0] ?? 0, pivot?[1] ?? 0, pivot?[2] ?? 0);
set
{
if (pivot is null || pivot.Length < 3)
pivot = new float[3];
pivot[0] = value.X;
pivot[1] = value.Y;
pivot[2] = value.Z;
}
}
[JsonProperty("uuid")]
internal Guid Uuid;

View File

@@ -12,6 +12,7 @@ using System.IO;
using PckStudio.Internal.Json;
using System.Collections.ObjectModel;
using PckStudio.Properties;
using System.Diagnostics;
namespace PckStudio.Internal
{
@@ -36,17 +37,8 @@ namespace PckStudio.Internal
Vector3 transformAxis = new Vector3(1, 1, 0);
Outline GetOrCreateOutline(string partName)
{
if (!outliners.ContainsKey(partName))
outliners.Add(partName, new Outline(partName));
return outliners[partName];
}
foreach (ModelPart part in modelInfo.Model.Parts.Values)
{
//Outline outline = GetOrCreateOutline(part.Name);
var outline = new Outline(part.Name);
Vector3 partTranslation = part.Translation;
@@ -65,14 +57,59 @@ namespace PckStudio.Internal
}
outliners.Add(part.Name, outline);
}
if (!ModelTextureLocations.TryGetValue(modelInfo.Model.Name, out JsonModelMetaData modelMetaData))
{
Trace.TraceError($"[{nameof(GameModelImporter)}:{nameof(ExportBlockBenchModel)}] Failed to get model meta data for '{modelInfo.Model.Name}'.");
return;
}
TraverseChildren(modelMetaData.RootParts, ref outliners);
blockBenchModel.Elements = elements.ToArray();
blockBenchModel.Outliner = JArray.FromObject(outliners.Values);
blockBenchModel.Outliner = JArray.FromObject(outliners.Values.Where(value => modelMetaData.RootParts.Count == 0 || modelMetaData.RootParts.ContainsKey(value.Name)));
string content = JsonConvert.SerializeObject(blockBenchModel);
string content = JsonConvert.SerializeObject(blockBenchModel, Formatting.Indented);
File.WriteAllText(fileName, content);
}
private static void TraverseChildren(IReadOnlyDictionary<string, JArray> keyValues, ref Dictionary<string, Outline> outliners)
{
foreach (KeyValuePair<string, JArray> item in keyValues)
{
if (!outliners.ContainsKey(item.Key))
{
Debug.WriteLine($"{item.Key} not in {nameof(outliners)}.");
continue;
}
Outline partentOutline = outliners[item.Key];
foreach (JToken child in item.Value)
{
if (child.Type == JTokenType.String && outliners.TryGetValue(child.ToString(), out Outline childOutline))
{
childOutline.Rotation += -partentOutline.Rotation;
partentOutline.Children.Add(JToken.FromObject(childOutline));
}
if (child.Type == JTokenType.Object)
{
IReadOnlyDictionary<string, JArray> childKeyValues = child.ToObject<ReadOnlyDictionary<string, JArray>>();
TraverseChildren(childKeyValues, ref outliners);
foreach (var key in childKeyValues.Keys)
{
if (!outliners.ContainsKey(key))
{
Debug.WriteLine($"{key} not in {nameof(outliners)}.");
continue;
}
childOutline = outliners[key];
childOutline.Rotation += -partentOutline.Rotation;
partentOutline.Children.Add(JToken.FromObject(childOutline));
}
}
}
}
}
private static Element CreateElement(ModelBox box, Vector3 origin, string name)
{
Vector3 pos = box.Position;

View File

@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PckStudio.Internal.Json
{
@@ -13,7 +15,7 @@ namespace PckStudio.Internal.Json
[JsonProperty("textureLocations", Required = Required.Always)]
public string[] TextureLocations { get; set; }
//[JsonProperty("parents", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Populate)]
//public Dictionary<string, string> ParentBones { get; set; }
[JsonProperty("root", NullValueHandling = NullValueHandling.Ignore)]
public ReadOnlyDictionary<string, JArray> RootParts { get; set; } = new ReadOnlyDictionary<string, JArray>(new Dictionary<string, JArray>());
}
}

View File

@@ -1,13 +1,23 @@
// TODO: Add parent detection
{
"bat": {
"textureLocations": [
"res/mob/bat"
],
"parents": {
"rightEar": "head",
"leftEar": "head"
"root": {
"head": [
"rightEar",
"leftEar"
],
"body": [
{
"rightWing": [
"rightWingTip"
],
"leftWing": [
"leftWingTip"
]
}
]
}
},
"bed": {
@@ -19,7 +29,6 @@
"textureLocations": [
"res/mob/fire"
]
},
"boat": {
"textureLocations": [
@@ -34,11 +43,7 @@
"chicken": {
"textureLocations": [
"res/mob/chicken"
],
"parents": {
"comb": "head",
"beak": "head"
}
]
},
"cow": {
"textureLocations": [
@@ -58,28 +63,75 @@
"dolphin": {
"textureLocations": [
"res/mob/dolphin"
]
],
"root": {
"body": [
{ "head": [ "nose" ] },
"left_fin",
"right_fin",
"back_fin",
{ "tail": [ "tail_fin" ] }
]
}
// - body
// - head
// - nose
// - left_fin
// - right_fin
// - back_fin
// - tail
// - tail_fin
},
"dragon": {
"textureLocations": [
"res/mob/enderdragon/ender"
]
],
"root": {
"head": [ "jaw" ],
"body": [],
"wing": [ "wingtip" ],
"wing1": [ "wingtip1" ],
"rearleg": [ { "rearlegtip": [ "rearfoot" ] } ],
"rearleg1": [ { "rearlegtip1": [ "rearfoot1" ] } ],
"frontleg": [ { "frontlegtip": [ "frontfoot" ] } ],
"frontleg1": [ { "frontlegtip1": [ "frontfoot1" ] } ]
}
// TODO: Finish!
// - head
// - jaw
// - body
// - wing
// - wingtip
// - wing1
// - wingtip1
// - rearleg
// - rearlegtip
// - rearfoot
// - rearleg1
// - rearlegtip1
// - rearfoot1
// - frontleg
// - frontlegtip
// - frontfoot
// - frontleg1
// - frontlegtip1
// - frontfoot1
},
"dragon_head": {
"textureLocations": [
"res/mob/enderdragon/ender"
]
],
"root": {
"head": [ "jaw" ]
}
// - head
// - jaw
},
"enderman": {
"textureLocations": [
"res/mob/enderman"
]
},
"evoker": {
"textureLocations": [
"res/mob/illager/evoker"
]
},
"ghast": {
"textureLocations": [
"res/mob/ghast",
@@ -90,7 +142,15 @@
"textureLocations": [
"res/mob/guardian",
"res/mob/guardian_elder"
]
],
"root": {
"head": [
"eye",
{
"tailpart0": [ { "tailpart1": [ "tailpart2" ] } ]
}
]
}
},
"irongolem": {
"textureLocations": [
@@ -116,6 +176,7 @@
"res/item/cart"
]
},
// the ocelot model is weird.. -miku
"ocelot": {
"textureLocations": [
"res/mob/ozelot"
@@ -128,12 +189,29 @@
"res/mob/parrot/parrot_grey",
"res/mob/parrot/parrot_red_blue",
"res/mob/parrot/parrot_yellow_blue"
]
],
"root": {
"head": [ "head2", "beak1", "beak2", "feather" ],
"body": [],
"tail": [],
"wing0": [],
"wing1": [],
"leg0": [],
"leg1": []
}
},
"phantom": {
"textureLocations": [
"res/mob/phantom"
]
],
"root": {
"body": [
"head",
{ "wing0": [ "wingtip0" ] },
{ "wing1": [ "wingtip1" ] },
{ "tail": [ "tailtip" ] }
]
}
},
"pig": {
"textureLocations": [
@@ -165,12 +243,13 @@
},
"sheep": {
"textureLocations": [
"res/mob/sheep"
// locations not tested
"res/mob/sheep_fur"
]
},
"sheep.sheared": {
"textureLocations": [
""
"res/mob/sheep"
]
},
"shulker": {
@@ -234,12 +313,6 @@
"res/mob/sea_turtle"
]
},
"vex": {
"textureLocations": [
"res/mob/illager/vex",
"res/mob/illager/vex_charging"
]
},
"villager": {
"textureLocations": [
"res/mob/villager/villager",
@@ -255,6 +328,17 @@
"res/mob/witch"
]
},
"vex": {
"textureLocations": [
"res/mob/illager/vex",
"res/mob/illager/vex_charging"
]
},
"evoker": {
"textureLocations": [
"res/mob/illager/evoker"
]
},
"vindicator": {
"textureLocations": [
"res/mob/illager/vindicator"
@@ -307,7 +391,20 @@
"res/mob/horse/horse_white",
"res/mob/horse/horse_zombie",
"res/mob/horse/mule"
]
],
"root": {
"Neck": [ { "Head": [ "UMouth", "Ear1", "Ear2", "MuleEarL", "MuleEarR", "SaddleMouthL", "SaddleMouthR", "HeadSaddle" ] } ],
"Body": [ "TailA", "Saddle" ],
"Mane": [],
"Leg1A": [],
"Leg2A": [],
"Leg3A": [],
"Leg4A": [],
"Bag1": [],
"Bag2": [],
"SaddleMouthLine": [],
"SaddleMouthLineR": []
}
},
"cat": {
"textureLocations": [
@@ -316,11 +413,6 @@
"res/mob/cat_siamese"
]
},
"cod": {
"textureLocations": [
"res/mob/fish/cod"
]
},
"zombie.drowned": {
"textureLocations": [
"res/mob/zombie/drowned"
@@ -336,7 +428,12 @@
null
]
},
"pufferfish.large": {
"cod": {
"textureLocations": [
"res/mob/fish/cod"
]
},
"pufferfish.small": {
"textureLocations": [
"res/mob/fish/pufferfish"
]
@@ -346,7 +443,7 @@
"res/mob/fish/pufferfish"
]
},
"pufferfish.small": {
"pufferfish.large": {
"textureLocations": [
"res/mob/fish/pufferfish"
]