Reproduzierbarer Export aus den Blender-Quellen der Godot-Referenz nach FBX, geprüft auf beiden Seiten; sechs repräsentative Assets vollständig in Unity verifiziert (normale Einheit g01, Einheit mit Skelett Funkenlanze, Turm Grenzwacht, Ancient, Schlundkrone, Vegetation/Kartenrequisiten), dazu Bastion, Kernwacht und Bossgrotte für die Szene. - tools/blender: Manifest mit Exportregeln je Asset, Exportskript mit Prüfungen (Einheiten, Maßstab, Achsen, Vorderseite, Mesh-Namen, Dreiecke, Materialslots, Normalen, Tangenten, Vertexfarben, Maße, Root Bone, Bone-Namen, Clips, Blend Shapes) gegen die Manifeste der Godot-GLBs, FBX-Rundreise, byteidentische Ausgabe (feste Uhrzeit, PYTHONHASHSEED). - Regeln wie beim GLB-Export: HIGH-RES-Modifikatoren weglassen, logische Namen, Skin-Teile zusammenfügen; 180°-Drehung, damit die Vorderseite nach Unitys Achsen-Bake auf +Z liegt (Unity = (-x, y, z) der Godot-Koordinaten). - Unity: Importregeln (Postprocessor), Verifier gegen das Blender-Protokoll, Vorschaubilder; URP-Asset, Linear-Farbraum, URP-Settings nach Assets/Luneraria/Settings/Rendering. - Ergebnis: 176/176 Blender-Prüfungen, 128/128 Unity-Prüfungen, Dreiecke gleich den Godot-GLBs, Maße auf 0,05 mm. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
45 lines
1.7 KiB
C#
45 lines
1.7 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
namespace Luneraria.EditorTools
|
|
{
|
|
/// <summary>
|
|
/// The facts and checks that tools/blender/lune_fbx_export.py writes next to every FBX
|
|
/// (<id>.export.json). The importer reads the clip data from it; the verifier compares
|
|
/// the imported model with the Blender side.
|
|
/// </summary>
|
|
public sealed class ExportReport
|
|
{
|
|
public readonly string Path;
|
|
public readonly JObject Data;
|
|
|
|
ExportReport(string path, JObject data)
|
|
{
|
|
Path = path;
|
|
Data = data;
|
|
}
|
|
|
|
public string Id { get { return (string)Data["id"]; } }
|
|
public string Kind { get { return (string)Data["kind"]; } }
|
|
public bool Skinned { get { return Kind == "skinned"; } }
|
|
public bool BlenderOk { get { return (bool)Data["ok"]; } }
|
|
public JObject Meshes { get { return (JObject)Data["meshes"]; } }
|
|
public JArray Clips { get { return (JArray)Data["clips"] ?? new JArray(); } }
|
|
|
|
/// <summary>Report of an FBX asset path, or null if the model was not exported by the pipeline.</summary>
|
|
public static ExportReport ForModel(string modelPath)
|
|
{
|
|
string path = System.IO.Path.ChangeExtension(modelPath, ".export.json");
|
|
if (!File.Exists(path))
|
|
return null;
|
|
return new ExportReport(path, JObject.Parse(File.ReadAllText(path)));
|
|
}
|
|
|
|
public static IEnumerable<string> AllModels(string root)
|
|
{
|
|
foreach (string path in Directory.GetFiles(root, "*.export.json", SearchOption.AllDirectories))
|
|
yield return path.Replace('\\', '/').Replace(".export.json", ".fbx");
|
|
}
|
|
}
|
|
}
|