using System.Collections.Generic;
using System.Linq;
using AssetBank.Editor.SchemaConverter.Data.Input;
using AssetBank.Editor.SchemaConverter.Data.Output;
using AssetBank.Editor.SchemaConverter.Processors;
using Newtonsoft.Json;
namespace AssetBank.Editor.SchemaConverter
{
///
/// Public-facing static class to orchestrate the JSON schema conversion.
///
public static class JsonSchemaConverter
{
///
/// Converts a raw JSON string from the original format to the new, hierarchical SceneGraph format.
///
/// The raw JSON string to convert.
/// Internal flag to prevent infinite loops when processing prefabs inside prefabs.
/// A new JSON string representing the structured SceneGraph.
public static string Convert(string originalJson, bool isRecursiveCall = false)
{
var sceneGraph = ConvertToSceneGraph(originalJson, isRecursiveCall);
return JsonConvert.SerializeObject(sceneGraph, Formatting.None);
}
///
/// Converts the JSON to a SceneGraph object. This is the core logic.
///
public static SceneGraph ConvertToSceneGraph(string originalJson, bool isRecursiveCall = false)
{
var allNodes = JsonConvert.DeserializeObject>(originalJson);
if (allNodes == null) return new SceneGraph();
var warnings = new List();
var sceneGraph = new SceneGraph();
// 1. Process Prefabs first to get a definitive list of all GUIDs.
var prefabInstanceNodes = allNodes.Where(n => n.type_id == "1001").ToList();
var (prefabGuids, prefabWarnings) = PrefabProcessor.Process(prefabInstanceNodes);
if (!isRecursiveCall)
{
sceneGraph.prefabs = prefabGuids;
}
warnings.AddRange(prefabWarnings);
// 2. Process Hierarchy, passing the prefab GUID list for context.
var prefabInstanceMap = prefabInstanceNodes.ToDictionary(n => n.anchor_id);
var hierarchyProcessor = new HierarchyProcessor();
var (rootNodes, hierarchyWarnings, consumedIds) = hierarchyProcessor.Process(allNodes, prefabInstanceMap, prefabGuids);
sceneGraph.hierarchy = rootNodes;
warnings.AddRange(hierarchyWarnings);
// Also mark all prefab instances themselves as "consumed"
foreach (var key in prefabInstanceMap.Keys)
{
consumedIds.Add(key);
}
// 3. Process Scene Data with the remaining, unconsumed nodes
// sceneGraph.scene_data = SceneDataProcessor.Process(allNodes, consumedIds);
// 4. Assemble Metadata
sceneGraph.metadata = new Metadata
{
warnings = warnings.Count > 0 ? warnings : null
};
return sceneGraph;
}
}
}