using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; using OMI.Formats.Model; using PckStudio.Core.Extensions; using PckStudio.Core.Json; using PckStudio.Core.Properties; using PckStudio.Interfaces; namespace PckStudio.Core.Model { public class AbstractModelContainer { static Dictionary _metaData = JsonConvert.DeserializeObject>(Resources.modelMetaData); private IDictionary _models = new Dictionary(); public AbstractModel GetModelByName(string name) => _models[name]; public bool AddModel(AbstractModel model) { if (model == null || _models.ContainsKey(model.Name)) return false; _models.Add(model.Name, model); return true; } public bool RemoveModel(AbstractModel model) => model is not null && _models.Remove(model.Name); public static AbstractModelContainer FromModelContainer(OMI.Formats.Model.ModelContainer models, ITryGet texture) { var abstractModelContainer = new AbstractModelContainer(); if (models is null) return abstractModelContainer; foreach (OMI.Formats.Model.Model model in models.GetModels().Where(m => _metaData.ContainsKey(m.Name) && m.Name.EqualsAny(_metaData[m.Name].RootParts.Select(mdp => mdp.Name).ToArray()))) { if (!_metaData.TryGetValue(model.Name, out JsonModelMetaData modelMetaData)) { Trace.TraceWarning($"No model meta data found for: '{model.Name}'."); continue; } IDictionary parts = model.GetParts().ToDictionary(part => part.Name); IReadOnlyDictionary textures = modelMetaData.TextureLocations.Where(s => texture.TryGet(s, out _)).ToDictionary(Path.GetFileNameWithoutExtension, s => { texture.TryGet(s, out Image img); return img; }); AbstractModel abstractModel = new AbstractModel(model.Name, model.TextureSize, textures.FirstOrDefault(), textures); abstractModel.AddParts(GetRootAbstractModelPart(modelMetaData.RootParts, parts, null)); abstractModelContainer.AddModel(abstractModel); } return abstractModelContainer; } private static IEnumerable GetRootAbstractModelPart(ModelMetaDataPart[] dataParts, IDictionary parts, AbstractModelPart parent) { foreach (ModelMetaDataPart rootPart in dataParts) { if (!parts.TryGetValue(rootPart.Name, out ModelPart part)) continue; var abstractModelPart = new AbstractModelPart(part.Name, parent, part.Translation, part.Rotation + part.AdditionalRotation, part.GetBoxes().Select(mb => new Box(mb.Position, mb.Size, mb.Uv, mb.Inflate, mb.Mirror))); abstractModelPart.AddParts(GetRootAbstractModelPart(rootPart.Children, parts, abstractModelPart)); yield return abstractModelPart; } } } }