// Export models from stage (Assimp) private void ExportLevelObj(string fileName, bool selectedOnly) { int stepCount = 0; int numSteps = 0; if (LevelData.TextureBitmaps != null && LevelData.TextureBitmaps.Count > 0) { stepCount = LevelData.TextureBitmaps[LevelData.leveltexs].Length; numSteps = stepCount; } List <COL> cols = LevelData.geo.COL; List <GeoAnimData> anims = LevelData.geo.Anim; if (selectedOnly) { cols = selectedItems.Items.OfType <LevelItem>().Select(a => a.CollisionData).ToList(); anims = selectedItems.Items.OfType <LevelAnim>().Select(a => a.GeoAnimationData).ToList(); } stepCount += cols.Count; stepCount += anims.Count; Assimp.AssimpContext context = new Assimp.AssimpContext(); Assimp.Scene scene = new Assimp.Scene(); scene.Materials.Add(new Assimp.Material()); Assimp.Node n = new Assimp.Node(); n.Name = "RootNode"; scene.RootNode = n; string rootPath = Path.GetDirectoryName(fileName); List <string> texturePaths = new List <string>(); ProgressDialog progress = new ProgressDialog("Exporting stage: " + levelName, stepCount, true, false); progress.Show(this); progress.SetTaskAndStep("Exporting..."); List <string> texlist = new List <string>(); for (int i = 0; i < numSteps; i++) { BMPInfo bmp = LevelData.TextureBitmaps[LevelData.leveltexs][i]; texlist.Add(bmp.Name); texturePaths.Add(Path.Combine(rootPath, bmp.Name + ".png")); if (!File.Exists(Path.Combine(rootPath, bmp.Name + ".png"))) { bmp.Image.Save(Path.Combine(rootPath, bmp.Name + ".png")); } progress.Step = $"Texture {i + 1}/{numSteps}"; progress.StepProgress(); Application.DoEvents(); } // Save texture list SplitTools.NJS_TEXLIST textureNamesArray = new SplitTools.NJS_TEXLIST(texlist.ToArray()); textureNamesArray.Save(Path.Combine(rootPath, Path.GetFileNameWithoutExtension(fileName) + ".satex")); for (int i = 0; i < cols.Count; i++) { SAEditorCommon.Import.AssimpStuff.AssimpExport(cols[i].Model, scene, Matrix.Identity, texturePaths.Count > 0 ? texturePaths.ToArray() : null, scene.RootNode); progress.Step = $"Mesh {i + 1}/{cols.Count}"; progress.StepProgress(); Application.DoEvents(); } for (int i = 0; i < anims.Count; i++) { SAEditorCommon.Import.AssimpStuff.AssimpExport(anims[i].Model, scene, Matrix.Identity, texturePaths.Count > 0 ? texturePaths.ToArray() : null, scene.RootNode); progress.Step = $"Animation {i + 1}/{anims.Count}"; progress.StepProgress(); Application.DoEvents(); } string ftype = "collada"; switch (Path.GetExtension(fileName).ToLowerInvariant()) { case ".fbx": ftype = "fbx"; break; case ".obj": ftype = "obj"; break; } context.ExportFile(scene, fileName, ftype, Assimp.PostProcessSteps.ValidateDataStructure | Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.FlipUVs); progress.SetTaskAndStep("Export complete!"); }
public static Texture[] GetTextures(string name, SplitTools.NJS_TEXLIST texnames = null, Device dev = null) { Texture[] result = null; if (LevelData.Textures == null || EditorOptions.DisableTextures) { return(result); } if (LevelData.Textures.ContainsKey(name)) { result = LevelData.Textures[name]; } else if (LevelData.Textures.ContainsKey(name.ToUpperInvariant())) { result = LevelData.Textures[name.ToUpperInvariant()]; } else if (LevelData.Textures.ContainsKey(name.ToLowerInvariant())) { result = LevelData.Textures[name.ToLowerInvariant()]; } if (texnames == null) { return(result); } // Partial texlist else { if (LevelData.TextureBitmaps == null || dev == null) { return(result); } Direct3D.TextureSystem.BMPInfo[] texturebmps = null; if (LevelData.TextureBitmaps.ContainsKey(name)) { texturebmps = LevelData.TextureBitmaps[name]; } else if (LevelData.TextureBitmaps.ContainsKey(name.ToUpperInvariant())) { texturebmps = LevelData.TextureBitmaps[name.ToUpperInvariant()]; } else if (LevelData.TextureBitmaps.ContainsKey(name.ToLowerInvariant())) { texturebmps = LevelData.TextureBitmaps[name.ToLowerInvariant()]; } List <Texture> texlist = new List <Texture>(); if (texturebmps == null) { return(result); } for (int i = 0; i < texnames.TextureNames.Length; i++) { for (int b = 0; b < texturebmps.Length; b++) { if (texturebmps[b].Name.ToLowerInvariant() == texnames.TextureNames[i].ToLowerInvariant()) { texlist.Add(texturebmps[b].Image.ToTexture(dev)); break; } } } return(texlist.ToArray()); } }
/// <summary> /// Exports a single level, model or animation file as text. /// </summary> /// <param name="source">Source pathname.</param> /// <param name="type">Type of text conversion.</param> /// <param name="destination">Destination pathname. Leave blank to export in the same folder with a swapped extension.</param> /// <param name="basicDX">Use the SADX2004 format for Basic models.</param> public static void ConvertFileToText(string source, TextType type, string destination = "", bool basicDX = true, bool overwrite = true) { string outext = ".c"; string extension = Path.GetExtension(source); switch (extension.ToLowerInvariant()) { case ".sa2lvl": case ".sa1lvl": if (type == TextType.CStructs || type == TextType.NJA) { if (destination == "") { destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext); } if (!overwrite && File.Exists(destination)) { while (File.Exists(destination)) { destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext); } } LandTable land = LandTable.LoadFromFile(source); List <string> labels = new List <string>() { land.Name }; LandTableFormat fmt = land.Format; using (StreamWriter sw = File.CreateText(destination)) { if (type == TextType.CStructs) { sw.Write("/* Sonic Adventure "); switch (land.Format) { case LandTableFormat.SA1: case LandTableFormat.SADX: if (basicDX) { sw.Write("DX"); fmt = LandTableFormat.SADX; } else { sw.Write("1"); fmt = LandTableFormat.SA1; } break; case LandTableFormat.SA2: sw.Write("2"); fmt = LandTableFormat.SA2; break; case LandTableFormat.SA2B: sw.Write("2 Battle"); fmt = LandTableFormat.SA2B; break; } sw.WriteLine(" LandTable"); sw.WriteLine(" * "); sw.WriteLine(" * Generated by DataToolbox"); sw.WriteLine(" * "); if (!string.IsNullOrEmpty(land.Description)) { sw.Write(" * Description: "); sw.WriteLine(land.Description); sw.WriteLine(" * "); } if (!string.IsNullOrEmpty(land.Author)) { sw.Write(" * Author: "); sw.WriteLine(land.Author); sw.WriteLine(" * "); } sw.WriteLine(" */"); sw.WriteLine(); } land.ToStructVariables(sw, fmt, labels, null, type == TextType.NJA); sw.Flush(); sw.Close(); } } break; case ".sa1mdl": case ".sa2mdl": ModelFile modelFile = new ModelFile(source); NJS_OBJECT model = modelFile.Model; List <NJS_MOTION> animations = new List <NJS_MOTION>(modelFile.Animations); if (type == TextType.CStructs) { outext = ".c"; if (destination == "") { destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext); } if (!overwrite && File.Exists(destination)) { while (File.Exists(destination)) { destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext); } } using (StreamWriter sw = File.CreateText(destination)) { sw.Write("/* NINJA "); switch (modelFile.Format) { case ModelFormat.Basic: case ModelFormat.BasicDX: if (basicDX) { sw.Write("Basic (with Sonic Adventure DX additions)"); } else { sw.Write("Basic"); } break; case ModelFormat.Chunk: sw.Write("Chunk"); break; case ModelFormat.GC: sw.Write("GC"); break; } sw.WriteLine(" model"); sw.WriteLine(" * "); sw.WriteLine(" * Generated by DataToolbox"); sw.WriteLine(" * "); if (modelFile != null) { if (!string.IsNullOrEmpty(modelFile.Description)) { sw.Write(" * Description: "); sw.WriteLine(modelFile.Description); sw.WriteLine(" * "); } if (!string.IsNullOrEmpty(modelFile.Author)) { sw.Write(" * Author: "); sw.WriteLine(modelFile.Author); sw.WriteLine(" * "); } } sw.WriteLine(" */"); sw.WriteLine(); List <string> labels_m = new List <string>() { model.Name }; model.ToStructVariables(sw, basicDX, labels_m, null); foreach (NJS_MOTION anim in animations) { anim.ToStructVariables(sw); } sw.Flush(); sw.Close(); } } else if (type == TextType.NJA) { outext = ".nja"; bool isDup = destination.ToLowerInvariant().Contains(".dup"); if (destination == "") { destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext); } if (!overwrite && File.Exists(destination)) { while (File.Exists(destination)) { destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext); } } using (StreamWriter sw2 = File.CreateText(destination)) { List <string> labels_nj = new List <string>() { model.Name }; model.ToNJA(sw2, labels_nj, null, isDup); sw2.Flush(); sw2.Close(); } } break; case ".saanim": NJS_MOTION animation = NJS_MOTION.Load(source); if (type == TextType.CStructs) { outext = ".c"; if (destination == "") { destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext); } if (!overwrite && File.Exists(destination)) { while (File.Exists(destination)) { destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext); } } using (StreamWriter sw = File.CreateText(destination)) { sw.WriteLine("/* NINJA Motion"); sw.WriteLine(" * "); sw.WriteLine(" * Generated by DataToolbox"); sw.WriteLine(" * "); sw.WriteLine(" */"); sw.WriteLine(); animation.ToStructVariables(sw); sw.Flush(); sw.Close(); } } else if (type == TextType.JSON) { outext = ".json"; if (destination == "") { destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext); } if (!overwrite && File.Exists(destination)) { while (File.Exists(destination)) { destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext); } } JsonSerializer js = new JsonSerializer() { Culture = System.Globalization.CultureInfo.InvariantCulture }; using (TextWriter tw = File.CreateText(destination)) using (JsonTextWriter jtw = new JsonTextWriter(tw) { Formatting = Formatting.Indented }) js.Serialize(jtw, animation); } else if (type == TextType.NJA) { outext = animation.IsShapeMotion() ? ".nas" : ".nam"; bool isDum = destination.ToLowerInvariant().Contains(".dum"); if (destination == "") { destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext); } if (!overwrite && File.Exists(destination)) { while (File.Exists(destination)) { destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext); } } using (StreamWriter sw2 = File.CreateText(destination)) { animation.ToNJA(sw2, null, isDum); sw2.Flush(); sw2.Close(); } } break; case ".satex": SplitTools.NJS_TEXLIST texlist = SplitTools.NJS_TEXLIST.Load(source); if (type == TextType.CStructs) { outext = ".c"; if (destination == "") { destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext); } if (!overwrite && File.Exists(destination)) { while (File.Exists(destination)) { destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext); } } using (StreamWriter sw = File.CreateText(destination)) { sw.WriteLine("/* NINJA Texlist"); sw.WriteLine(" * "); sw.WriteLine(" * Generated by DataToolbox"); sw.WriteLine(" * "); sw.WriteLine(" */"); sw.WriteLine(); texlist.ToStruct(sw); sw.Flush(); sw.Close(); } } else if (type == TextType.NJA) { outext = ".tls"; if (destination == "") { destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext); } if (!overwrite && File.Exists(destination)) { while (File.Exists(destination)) { destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext); } } using (StreamWriter sw2 = File.CreateText(destination)) { texlist.ToNJA(sw2); sw2.Flush(); sw2.Close(); } } break; } }