public void Save(string filePath, ObjectDatabase objectDatabase, TextureDatabase textureDatabase, BoneDatabase boneDatabase) { // Assume it's being exported for F2nd PS3 if (BinaryFormatUtilities.IsClassic(Format) && filePath.EndsWith(".osd", StringComparison.OrdinalIgnoreCase)) { Format = BinaryFormat.F2nd; Endianness = Endianness.BigEndian; } // Or reverse else if (BinaryFormatUtilities.IsModern(Format) && filePath.EndsWith(".bin", StringComparison.OrdinalIgnoreCase)) { Format = BinaryFormat.DT; Endianness = Endianness.LittleEndian; } string fileName = Path.GetFileName(filePath); bool exported = false; if (objectDatabase != null && TextureSet != null) { var objectEntry = objectDatabase.GetObjectByFileName(fileName); if (objectEntry != null) { string textureOutputPath = Path.Combine(Path.GetDirectoryName(filePath), objectEntry.TextureFileName); TextureSet.Save(textureOutputPath); exported = true; } } if (!exported && TextureSet != null) { string textureOutputPath = string.Empty; // Try to assume a texture output name if (filePath.EndsWith("_obj.bin", StringComparison.OrdinalIgnoreCase)) { textureOutputPath = $"{filePath.Substring( 0, filePath.Length - 8 )}_tex.bin"; } else if (filePath.EndsWith(".osd", StringComparison.OrdinalIgnoreCase)) { textureOutputPath = Path.ChangeExtension(filePath, "txd"); } if (!string.IsNullOrEmpty(textureOutputPath)) { TextureSet.Save(textureOutputPath); } } using (var destination = File.Create(filePath)) Save(destination, objectDatabase, textureDatabase, boneDatabase); }
public static Motion CombineBone(string path, string filePath, string outputFilePath) { string baseFilePath = Path.ChangeExtension(filePath, null); BoneDatabase bonedb = new BoneDatabase(); bonedb.Load(path + "bone_data.bon"); var rootMotion = new Motion(); var skeletonEntry = bonedb.Skeletons[0]; rootMotion.Load(filePath, skeletonEntry); var rootController = rootMotion.GetController(); for (int i = 1; ; i++) { string divFilePath = $"{baseFilePath}_div_{i}.mot"; if (!File.Exists(divFilePath)) { break; } var divMotion = new Motion(); { divMotion.Load(divFilePath, skeletonEntry); } var divController = divMotion.GetController(); rootController.Merge(divController); } return(rootMotion); }
public void Save(Stream destination, ObjectDatabase objectDatabase, TextureDatabase textureDatabase, BoneDatabase boneDatabase, bool leaveOpen = false) { if (objectDatabase != null) { foreach (var mesh in Meshes) { mesh.Id = objectDatabase.GetMesh(mesh.Name)?.Id ?? mesh.Id; } } if (boneDatabase != null) { string fileName = destination is FileStream fileStream ? Path.GetFileName(fileStream.Name) : string.Empty; var skeletonEntry = boneDatabase.Skeletons.FirstOrDefault(x => fileName.StartsWith(x.Name, StringComparison.OrdinalIgnoreCase)) ?? boneDatabase.Skeletons.FirstOrDefault(x => x.Name.Equals("CMN", StringComparison.OrdinalIgnoreCase)) ?? boneDatabase.Skeletons[0]; if (skeletonEntry != null) { foreach (var skin in Meshes.Where(x => x.Skin != null).Select(x => x.Skin)) { foreach (var bone in skin.Bones) { int index = skin.ExData?.BoneNames?.FindIndex(x => x.Equals(bone.Name, StringComparison.OrdinalIgnoreCase)) ?? -1; if (index == -1) { index = skeletonEntry.BoneNames1.FindIndex(x => x.Equals(bone.Name, StringComparison.OrdinalIgnoreCase)); } else { index = 0x8000 | index; } if (index == -1) { continue; } foreach (var childBone in skin.Bones.Where(x => x.ParentId == bone.Id)) { childBone.ParentId = index; } bone.Id = index; } } } } if (textureDatabase != null && TextureSet != null) { int id = textureDatabase.Textures.Max(x => x.Id) + 1; var idDictionary = new Dictionary <int, int>(TextureSet.Textures.Count); foreach (var texture in TextureSet.Textures) { var textureEntry = !string.IsNullOrEmpty(texture.Name) ? textureDatabase.GetTexture(texture.Name) : textureDatabase.GetTexture(texture.Id); if (textureEntry == null) { textureDatabase.Textures.Add( textureEntry = new TextureEntry { Name = texture.Name, Id = id++ }); if (string.IsNullOrEmpty(textureEntry.Name)) { textureEntry.Name = $"Unnamed {textureEntry.Id}"; } } idDictionary[texture.Id] = textureEntry.Id; texture.Name = textureEntry.Name; texture.Id = textureEntry.Id; } foreach (var materialTexture in Meshes.SelectMany(x => x.Materials) .SelectMany(x => x.MaterialTextures)) { if (idDictionary.TryGetValue(materialTexture.TextureId, out id)) { materialTexture.TextureId = id; } } TextureIds.Clear(); TextureIds.AddRange(TextureSet.Textures.Select(x => x.Id)); } Save(destination, leaveOpen); }
private void doRobConvert() { string ac_path = ""; string ft_path = ""; string fs_path = ""; string ct_path = ""; bool ask_user = false; bool skip_robs = false; if (File.Exists("config.txt")) { StreamReader sr = new StreamReader("config.txt"); while (sr.Peek() > -1) { var line = sr.ReadLine(); var lines = line.Split('='); if (lines[0] == "AC") { ac_path = lines[1]; } if (lines[0] == "FT") { ft_path = lines[1]; } if (lines[0] == "FS") { fs_path = lines[1]; } if (lines[0] == "CT") { ct_path = lines[1]; } if (lines[0] == "I_HAVE_CHANGED_THIS") { if (lines[1] == "TRUE") { ask_user = true; } } if (lines[0] == "SKIP_ROBS") { if (lines[1] == "TRUE") { skip_robs = true; } } } sr.Close(); } if ((ask_user) && (!skip_robs)) { Logs.WriteLine("Rob Retarget Start"); string[] filespl = System.IO.Directory.GetFiles(ft_path + @"\rob\", "*.farc", SearchOption.AllDirectories); string[] filesfs = { }; string[] filesct = { }; if (fs_path != "") { filesfs = System.IO.Directory.GetFiles(fs_path + @"\rob\", "*.farc", SearchOption.AllDirectories); } if (ct_path != "") { filesct = System.IO.Directory.GetFiles(ct_path + @"\rob\", "*.farc", SearchOption.AllDirectories); } string[] files = filespl.Concat(filesfs).ToArray().Concat(filesct).ToArray(); var BoneDatabaseFT = new BoneDatabase(); var BoneDatabaseAC = new BoneDatabase(); var MotionDatabaseFT = new MotionDatabase(); var MotionDatabaseAC = new MotionDatabase(); BoneDatabaseFT.Load(ft_path + "\\bone_data.bin"); BoneDatabaseAC.Load(ac_path + "\\bone_data.bin"); using (var farcArchive = BinaryFile.Load <FarcArchive>(ac_path + "\\rob\\mot_db.farc")) using (var entryStream = farcArchive.Open(farcArchive.Entries.First(), EntryStreamMode.MemoryStream)) MotionDatabaseAC.Load(entryStream); using (var farcArchive = BinaryFile.Load <FarcArchive>(ft_path + "\\rob\\mot_db.farc")) using (var entryStream = farcArchive.Open(farcArchive.Entries.First(), EntryStreamMode.MemoryStream)) MotionDatabaseFT.Load(entryStream); var SkeletonEntryAC = BoneDatabaseAC.Skeletons[0]; var SkeletonEntryFT = BoneDatabaseFT.Skeletons[0]; foreach (var filePath in files) { var motionset = new MotionSet(); if (!File.Exists(ac_path + "\\rob\\" + Path.GetFileName(filePath))) { if (!filePath.Contains("db")) { Logs.WriteLine("Processing " + Path.GetFileNameWithoutExtension(filePath)); string farcpath = filePath; using (var farcArchive = BinaryFile.Load <FarcArchive>(farcpath)) using (var entryStream = farcArchive.Open(farcArchive.Entries.First(), EntryStreamMode.MemoryStream)) motionset.Load(entryStream, SkeletonEntryFT, MotionDatabaseFT); { motionset.Save("temp", SkeletonEntryAC, MotionDatabaseAC); //motionset.Dispose(); FarcArchive newfarc = new FarcArchive(); newfarc.Add(Path.GetFileNameWithoutExtension(filePath) + ".bin", "temp"); newfarc.Save(ac_path + "\\rob\\" + Path.GetFileName(filePath)); } } } } } }
public void Save(Stream destination, ObjectDatabase objectDatabase, TextureDatabase textureDatabase, BoneDatabase boneDatabase, bool leaveOpen = false) { if (objectDatabase != null) { foreach (var mesh in Meshes) { mesh.ID = objectDatabase.GetMesh(mesh.Name)?.ID ?? mesh.ID; } } if (boneDatabase != null) { string fileName = (destination is FileStream fileStream) ? Path.GetFileName(fileStream.Name) : string.Empty; // Assume we are exporting in game's style var skeleton = boneDatabase.Skeletons.FirstOrDefault(x => fileName.StartsWith(x.Name, StringComparison.OrdinalIgnoreCase)); // If we couldn't find it, default to CMN skeleton if (skeleton == null) { skeleton = boneDatabase.Skeletons.FirstOrDefault(x => x.Name.Equals("CMN", StringComparison.OrdinalIgnoreCase)); } // Still?? Then default to the first skeleton (this is unlikely to happen though) if (skeleton == null) { skeleton = boneDatabase.Skeletons[0]; } // Pretty much impossible to miss if (skeleton != null) { foreach (var skin in Meshes.Where(x => x.Skin != null).Select(x => x.Skin)) { foreach (var bone in skin.Bones) { int index = skin.ExData?.BoneNames?.FindIndex(x => x.Equals(bone.Name, StringComparison.OrdinalIgnoreCase)) ?? -1; if (index == -1) { index = skeleton.BoneNames1.FindIndex(x => x.Equals(bone.Name, StringComparison.OrdinalIgnoreCase)); } else { index = 0x8000 | index; } if (index != -1) { // Before we do this, fix the child bones foreach (var childBone in skin.Bones.Where(x => x.ParentID.Equals(bone.ID))) { childBone.ParentID = index; } // Now replace the ID bone.ID = index; } else { Debug.WriteLine($"Model.Save: Bone wasn't found in bone database or ex-data: {bone.Name}"); } } } } } if (textureDatabase != null && TextureSet != null) { var newIDs = new List <int>(TextureSet.Textures.Count); int currentID = textureDatabase.Textures.Max(x => x.ID) + 1; foreach (var texture in TextureSet.Textures) { var textureEntry = !string.IsNullOrEmpty(texture.Name) ? textureDatabase.GetTexture(texture.Name) : textureDatabase.GetTexture(texture.ID); if (textureEntry == null) { textureDatabase.Textures.Add(textureEntry = new TextureEntry { ID = currentID++, Name = texture.Name ?? $"Texture{currentID}", }); } newIDs.Add(textureEntry.ID); } if (!newIDs.SequenceEqual(TextureIDs)) { TextureUtilities.ReAssignTextureIDs(this, newIDs); } } Save(destination, leaveOpen); }
public static void Convert(string path, string acpath, string mot_db, divamodgen divamods) { if (Directory.Exists(path + "temp")) { Directory.Delete(path + "temp", true); } if (Directory.Exists(path + "temp2")) { Directory.Delete(path + "temp2", true); } if (Directory.Exists(acpath + "\\rom\\rob_temp")) { Directory.Delete(acpath + "\\rom\\rob_temp", true); } Directory.CreateDirectory(path + "temp"); Directory.CreateDirectory(path + "temp2"); Directory.CreateDirectory(acpath + "\\rom\\rob_temp"); MotionDatabase acmot = new MotionDatabase(); BoneDatabase acbone = new BoneDatabase(); acbone.Load(acpath + "\\rom\\bone_data.bin"); var skeletonEntry = acbone.Skeletons[0]; using (var farcArchive = BinaryFile.Load <FarcArchive>(mot_db)) using (var entryStream = farcArchive.Open(farcArchive.Entries.First(), EntryStreamMode.MemoryStream)) acmot.Load(entryStream); foreach (string file in Directory.EnumerateFiles(path, "mot_pv*.farc", SearchOption.TopDirectoryOnly)) { Tools.Extract(file, path + "temp\\"); //Console.WriteLine("Extracted " + Path.GetFileName(file)); } var maxid = acmot.MotionSets.Max(c => c.Id); var maxid2 = -1; foreach (var i in acmot.MotionSets) { if (i.Id > maxid2) { maxid2 = i.Id; } } foreach (string file in Directory.EnumerateFiles(path + "temp", "*p1_00.mot", SearchOption.AllDirectories)) { Directory.CreateDirectory(path + "temp2\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)); var moti = CombineBone(path, file, path + "temp2\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "_p1.mot"); MotionSet motion = new MotionSet(); if (File.Exists(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + ".bin")) { motion.Load(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + ".bin"); } motion.Motions.Add(moti); if (!Directory.Exists(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3))) { Directory.CreateDirectory(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)); } motion.Save(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + ".bin", skeletonEntry, acmot); maxid++; maxid2++; var check = acmot.MotionSets.Where(c => c.Name == "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)).FirstOrDefault(); if (check == null) { var motset = new MotionSetEntry(); motset.Name = "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3); motset.Id = maxid + 1; acmot.MotionSets.Add(motset); check = acmot.MotionSets.Where(c => c.Name == "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)).First(); } var motentry = new MotionEntry(); motentry.Id = maxid2 + 1; motentry.Name = "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "_P1"; check.Motions.Add(motentry); int pvid = int.Parse(Path.GetFileNameWithoutExtension(file).Substring(2, 3)); var check2 = divamods.Divamods.Where(c => c.pvid == pvid).FirstOrDefault(); if (check2 == null) { divamods.Divamods.Add(new pdaconversion.divamods(pvid)); Logs.WriteLine("Motion: Created new PV at id " + (pvid)); check2 = divamods.Divamods.Where(c => c.pvid == pvid).First(); } Console.WriteLine("Converted " + Path.GetFileName(file)); GC.Collect(); GC.WaitForPendingFinalizers(); } foreach (string file in Directory.EnumerateFiles(path + "temp", "*p2_00.mot", SearchOption.AllDirectories)) { Directory.CreateDirectory(path + "temp2\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)); var moti = CombineBone(path, file, path + "temp2\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "_p2.mot"); MotionSet motion = new MotionSet(); if (File.Exists(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + ".bin")) { motion.Load(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + ".bin"); } motion.Motions.Add(moti); if (!Directory.Exists(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3))) { Directory.CreateDirectory(acpath + "\\rom\\rob_temp\\" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)); } motion.Save(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + ".bin", skeletonEntry, acmot); Console.WriteLine("Converted " + Path.GetFileName(file)); maxid++; maxid2++; var check = acmot.MotionSets.Where(c => c.Name == "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)).FirstOrDefault(); if (check == null) { var motset = new MotionSetEntry(); motset.Name = "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3); motset.Id = maxid; acmot.MotionSets.Add(motset); check = acmot.MotionSets.Where(c => c.Name == "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)).First(); } var motentry = new MotionEntry(); motentry.Id = maxid2; motentry.Name = "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "_P2"; check.Motions.Add(motentry); int pvid = int.Parse(Path.GetFileNameWithoutExtension(file).Substring(2, 3)); var check2 = divamods.Divamods.Where(c => c.pvid == pvid).FirstOrDefault(); if (check2 == null) { divamods.Divamods.Add(new pdaconversion.divamods(pvid)); Logs.WriteLine("Motion: Created new PV at id " + (pvid)); check2 = divamods.Divamods.Where(c => c.pvid == pvid).First(); //check2.duet = true; } check2.duet = true; GC.Collect(); GC.WaitForPendingFinalizers(); } foreach (string file in Directory.EnumerateFiles(path + "temp", "*p3_00.mot", SearchOption.AllDirectories)) { Directory.CreateDirectory(path + "temp2\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)); var moti = CombineBone(path, file, path + "temp2\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "_p3.mot"); MotionSet motion = new MotionSet(); if (File.Exists(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + ".bin")) { motion.Load(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + ".bin"); } motion.Motions.Add(moti); if (!Directory.Exists(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3))) { Directory.CreateDirectory(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)); } motion.Save(acpath + "\\rom\\rob_temp\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "\\mot_PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + ".bin", skeletonEntry, acmot); Console.WriteLine("Converted " + Path.GetFileName(file)); maxid++; maxid2++; var check = acmot.MotionSets.Where(c => c.Name == "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)).FirstOrDefault(); if (check == null) { var motset = new MotionSetEntry(); motset.Name = "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3); motset.Id = maxid; acmot.MotionSets.Add(motset); check = acmot.MotionSets.Where(c => c.Name == "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3)).First(); } var motentry = new MotionEntry(); motentry.Id = maxid2; motentry.Name = "PV" + Path.GetFileNameWithoutExtension(file).Substring(2, 3) + "_P3"; check.Motions.Add(motentry); GC.Collect(); GC.WaitForPendingFinalizers(); } Directory.CreateDirectory(acpath + "\\rom\\rob_temp\\mot_db"); acmot.Save(acpath + "\\rom\\rob_temp\\mot_db\\mot_db.bin"); Console.WriteLine("Packing farcs..."); Tools.MassPackFolders(acpath + "\\rom\\rob_temp", acpath + "\\rom\\rob\\"); GC.Collect(); GC.WaitForPendingFinalizers(); }