mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-07-04 19:54:19 +00:00
GameModelImporter - Fully implemented game-model export to block bench
This commit is contained in:
17
PCK-Studio/External/Format/BlockBenchModel.cs
vendored
17
PCK-Studio/External/Format/BlockBenchModel.cs
vendored
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user