private Tuple <ModelDefinition, ImcVariant> GetMonsterModelDefinition() { const string ImcPathFormat = "chara/monster/m{0:D4}/obj/body/b{1:D4}/b{1:D4}.imc"; const string ModelPathFormat = "chara/monster/m{0:D4}/obj/body/b{1:D4}/model/m{0:D4}b{1:D4}.mdl"; string imcPath = string.Format(ImcPathFormat, ModelKey, BaseKey); string mdlPath = string.Format(ModelPathFormat, ModelKey, BaseKey); IO.PackCollection packs = this.Sheet.Collection.PackCollection; if (!packs.TryGetFile(imcPath, out IO.File imcFileBase) || !packs.TryGetFile(mdlPath, out IO.File mdlFileBase) || !(mdlFileBase is ModelFile)) { throw new InvalidOperationException($"Unable to find files for {this}."); } try { ModelDefinition model = ((ModelFile)mdlFileBase).GetModelDefinition(); ImcFile imcFile = new ImcFile(imcFileBase); ImcVariant variant = imcFile.GetVariant(Variant); return(Tuple.Create(model, variant)); } catch (Exception ex) { throw new InvalidOperationException($"Unable to load model for {this}.", ex); } }
private bool TryGetModel(out Skeleton skeleton, out ModelDefinition model, out ImcVariant variant, out int m, out int b) { model = null; skeleton = null; variant = ImcVariant.Default; m = 0; b = 0; var asVariant = SelectedEntry as Models.ModelCharaVariant; if (asVariant == null) { return(false); } int v = asVariant.Value; b = asVariant.Parent.Value; m = asVariant.Parent.Parent.Value; var imcPath = string.Format(ImcPathFormat, m, b); var mdlPath = string.Format(ModelPathFormat, m, b); var sklPath = string.Format(SkeletonPathFormat, m, 1);// b); SaintCoinach.IO.File imcFileBase; SaintCoinach.IO.File mdlFileBase; if (!Parent.Realm.Packs.TryGetFile(imcPath, out imcFileBase) || !Parent.Realm.Packs.TryGetFile(mdlPath, out mdlFileBase) || !(mdlFileBase is ModelFile)) { System.Windows.MessageBox.Show(string.Format("Unable to find files for {0}.", asVariant), "File not found", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); return(false); } SaintCoinach.IO.File sklFileBase; if (!Parent.Realm.Packs.TryGetFile(sklPath, out sklFileBase)) { System.Windows.MessageBox.Show(string.Format("Unable to find skeleton for {0}.", asVariant), "File not found", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); return(false); } skeleton = new Skeleton(new SklbFile(sklFileBase)); try { var imcFile = new ImcFile(imcFileBase); model = ((ModelFile)mdlFileBase).GetModelDefinition(); variant = imcFile.GetVariant(v); return(true); } catch (Exception e) { System.Windows.MessageBox.Show(string.Format("Unable to load model for {0}:{1}{2}", asVariant, Environment.NewLine, e), "Failure to load", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); return(false); } }
private Mesh InitEquipMesh(Tribe t, Sex s, Quad q, EquipSlotKey slotKey) { var path = PathFormatter.Instance.GetEquipmentModelPath(t, s, q, slotKey); ModelFile mf = (ModelFile)Parent.Realm.Packs.GetFile(path); Model model = mf.GetModelDefinition().GetModel(ModelQuality.High); ImcVariant variant = PathFormatter.Instance.GetVariant(q, slotKey); Mesh ret = LoadMeshWithVariant(model, variant); return(ret); }
public static ModelExport AsObj(Model model, ImcVariant variant) { ModelExport export = new ModelExport(); export.Model = model; export.Variant = variant; export.Meshes = new List <MeshExport>(); foreach (Mesh mesh in model.Meshes) { byte[] bytes = Obj.GetBytes(mesh); Material material = mesh.Material.Get(variant); export.Meshes.Add(new MeshExport(bytes, material)); } return(export); }
public static string[] GetHiddenMeshParts(this ImcVariant variant) { ushort mask = variant.PartVisibilityMask; const char start = 'a'; List <string> hiddenParts = new List <string>(); for (byte i = 0; i < 10; i++) { if (((mask >> i) & 1) == 0) { hiddenParts.Add("_" + (char)(start + i)); } } return(hiddenParts.ToArray()); }
// This will have to be greatly expanded on, with support for // all gear's EquipmentParameters.......... kill me public static Mesh LoadMeshWithVariant(Model m, ImcVariant variant) { var ranges = new List<Range>(); var hiddenAttrs = variant.GetHiddenMeshParts(); Mesh[] meshes = m.Meshes; foreach (var mesh in meshes) { foreach (var part in mesh.Parts) { if (part.Attributes.Length == 0) ranges.Add(new Range(part.IndexOffset, part.IndexCount)); if (part.ShouldDisplay(hiddenAttrs)) ranges.Add(new Range(part.IndexOffset, part.IndexCount)); } } List<Vertex> realVertices = new List<Vertex>(); List<ushort> tmpIndices = new List<ushort>(); List<ushort> realIndices = new List<ushort>(); ushort vOffset = 0; for (int i = 0; i < meshes.Length; i++) { if (i != 0) vOffset += (ushort)meshes[i - 1].Vertices.Length; while (tmpIndices.Count != meshes[i].Header.IndexBufferOffset) tmpIndices.Add(0); foreach (Vertex t in meshes[i].Vertices) realVertices.Add(t); foreach (ushort t in meshes[i].Indices) tmpIndices.Add((ushort)(t + vOffset)); } foreach (Range r in ranges) for (int j = r.Start; j < r.End; j++) realIndices.Add(tmpIndices[j]); return new Mesh(m, 0, realVertices.ToArray(), realIndices.ToArray()); }
public static bool IsHiddenForVariant(this ModelAttribute attr, ImcVariant variant) { return(IsHiddenForVariant(attr, GetHiddenMeshParts(variant))); }
// This is monster-specific because the loading of actual materials assumes b0000 for some reason? public static void ExportMonsterMaterials(ARealmReversed realm, string folder, MaterialDefinition[] thisDefinitionMaterials, ImcVariant variant) { string format = "chara/monster/m{0}/obj/body/b{1}/material/v{2:D4}{3}"; foreach (var material in thisDefinitionMaterials) { string path = material.Name; string m = path.Substring(path.IndexOf("_m") + 2, 4); string b = path.Substring(path.IndexOf("_m") + 7, 4); Material mat = new Material(material, realm.Packs.GetFile(String.Format(format, m, b, variant.Variant, path)), variant); foreach (var tex in mat.TexturesFiles) { string texFile = tex.Path.Substring(tex.Path.LastIndexOf('/')).Replace(".tex", ".png"); string output = folder + '\\' + texFile; tex.GetImage().Save(output); } } }
private IComponent CreateModel(Engine engine, Skeleton skeleton, ModelDefinition model, ImcVariant variant, int m, int b) { const string PapPathFormat = "chara/monster/m{0:D4}/animation/a0001/bt_common/resident/monster.pap"; var component = new AnimatedModel(engine, skeleton, variant, model, ModelQuality.High) { }; var papPath = string.Format(PapPathFormat, m, b); SaintCoinach.IO.File papFileBase; if (Parent.Realm.Packs.TryGetFile(papPath, out papFileBase)) { var anim = new AnimationContainer(skeleton, new PapFile(papFileBase)); var hasAnim = false; for (var i = 0; i < DefaultAnimationNames.Length && !hasAnim; ++i) { var n = DefaultAnimationNames[i]; if (anim.AnimationNames.Contains(n)) { component.AnimationPlayer.Animation = anim.Get(n); hasAnim = true; } } if (!hasAnim) { component.AnimationPlayer.Animation = anim.Get(0); } } return(component); }