From 53e85f510b038cc62d8d69339f2c62956d0e5d30 Mon Sep 17 00:00:00 2001 From: KillzXGaming Date: Sat, 8 Feb 2020 10:28:18 -0500 Subject: [PATCH] Add option to export models for G1M --- .../FileFormats/HyruleWarriors/G1M/G1M.cs | 71 ++++++++++++++----- .../Editors/Object Editor/ObjectEditorTree.cs | 49 +++++++++++-- .../Interfaces/ModelData/IExportableModel.cs | 16 +++++ Switch_Toolbox_Library/Toolbox_Library.csproj | 1 + 4 files changed, 115 insertions(+), 22 deletions(-) create mode 100644 Switch_Toolbox_Library/Interfaces/ModelData/IExportableModel.cs diff --git a/File_Format_Library/FileFormats/HyruleWarriors/G1M/G1M.cs b/File_Format_Library/FileFormats/HyruleWarriors/G1M/G1M.cs index f6803f8a..2fee8896 100644 --- a/File_Format_Library/FileFormats/HyruleWarriors/G1M/G1M.cs +++ b/File_Format_Library/FileFormats/HyruleWarriors/G1M/G1M.cs @@ -13,7 +13,7 @@ using OpenTK; namespace HyruleWarriors.G1M { - public class G1M : TreeNodeFile, IFileFormat + public class G1M : TreeNodeFile, IFileFormat, IExportableModel { public FileType FileType { get; set; } = FileType.Model; @@ -85,6 +85,45 @@ namespace HyruleWarriors.G1M } } + public List Meshes + { + get { + List meshes = new List(); + foreach (var mesh in Model.GenericMeshes) + meshes.Add(mesh); + return meshes; + } + } + + public List Materials + { + get { + List materials = new List(); + foreach (var mat in Model.Materials) + materials.Add(mat); + return materials; + } + } + + public STSkeleton Skeleton => G1MSkeleton.GenericSkeleton; + + public List TextureList + { + get + { + //Export all textures that use the same archive + List textures = new List(); + foreach (var container in FirstPlugin.PluginRuntime.G1TextureContainers) + { + if (this.IFileInfo.ArchiveParent == container.IFileInfo.ArchiveParent) { + foreach (var texture in container.TextureList) + textures.Add(texture); + } + } + return textures; + } + } + public G1M_Renderer Renderer; public DrawableContainer DrawableContainer = new DrawableContainer(); @@ -103,7 +142,7 @@ namespace HyruleWarriors.G1M { } - public G1MS Skeleton { get; set; } + public G1MS G1MSkeleton { get; set; } public G1MG Model { get; set; } public NUNO NUNO { get; set; } public NUNV NUNV { get; set; } @@ -157,13 +196,13 @@ namespace HyruleWarriors.G1M } else if (chunk.Magic == "SM1G" || chunk.Magic == "G1MS") { - Skeleton = new G1MS(reader); - Renderer.Skeleton = Skeleton.GenericSkeleton; - DrawableContainer.Drawables.Add(Skeleton.GenericSkeleton); + G1MSkeleton = new G1MS(reader); + Renderer.Skeleton = G1MSkeleton.GenericSkeleton; + DrawableContainer.Drawables.Add(G1MSkeleton.GenericSkeleton); TreeNode skeleton = new TreeNode("Skeleton"); Nodes.Add(skeleton); - foreach (var bn in Skeleton.GenericSkeleton.bones) + foreach (var bn in G1MSkeleton.GenericSkeleton.bones) if (bn.Parent == null) { skeleton.Nodes.Add(bn); @@ -194,7 +233,7 @@ namespace HyruleWarriors.G1M for (int v = 0; v < mesh.vertices.Count; v++) { var boneId = mesh.vertices[v].boneIds[0]; - var transform = Skeleton.GenericSkeleton.bones[boneId].Transform; + var transform = G1MSkeleton.GenericSkeleton.bones[boneId].Transform; mesh.vertices[v].pos = Vector3.TransformPosition( mesh.vertices[v].pos, transform); mesh.vertices[v].nrm = Vector3.TransformNormal( @@ -244,7 +283,7 @@ namespace HyruleWarriors.G1M /// public void ComputeClothDrivers() { - var boneList = Skeleton.GenericSkeleton.bones; + var boneList = G1MSkeleton.GenericSkeleton.bones; var nunProps = new List(); uint nunoOffset = 0; @@ -280,7 +319,7 @@ namespace HyruleWarriors.G1M var point = prop.Points[p]; var link = prop.Influences[p]; - STBone b = new STBone(Skeleton.GenericSkeleton); + STBone b = new STBone(G1MSkeleton.GenericSkeleton); b.Text = $"CP_{boneList.Count}"; b.FromTransform(OpenTK.Matrix4.Identity); b.Position = point.Xyz; @@ -291,19 +330,19 @@ namespace HyruleWarriors.G1M { b.parentIndex += boneStart; b.Position = OpenTK.Vector3.TransformPosition( - point.Xyz, Skeleton.GenericSkeleton.GetBoneTransform((int)parentBone) * - Skeleton.GenericSkeleton.GetBoneTransform(b.parentIndex).Inverted()); + point.Xyz, G1MSkeleton.GenericSkeleton.GetBoneTransform((int)parentBone) * + G1MSkeleton.GenericSkeleton.GetBoneTransform(b.parentIndex).Inverted()); } boneList.Add(b); - Skeleton.GenericSkeleton.reset(); - Skeleton.GenericSkeleton.update(); + G1MSkeleton.GenericSkeleton.reset(); + G1MSkeleton.GenericSkeleton.update(); mesh.vertices.Add(new Vertex() { pos = Vector3.TransformPosition(Vector3.Zero, - Skeleton.GenericSkeleton.GetBoneTransform(boneList.Count - 1)), + G1MSkeleton.GenericSkeleton.GetBoneTransform(boneList.Count - 1)), boneWeights = new List() { 1 }, boneIds = new List() { boneList.Count - 1 }, }); @@ -351,9 +390,9 @@ namespace HyruleWarriors.G1M { var vert = mesh.vertices[i]; vert.pos = Vector3.TransformPosition(vert.pos, - Skeleton.GenericSkeleton.GetBoneTransform((int)Model.JointInfos[poly.IndexIntoJointMap].JointIndices[0])); + G1MSkeleton.GenericSkeleton.GetBoneTransform((int)Model.JointInfos[poly.IndexIntoJointMap].JointIndices[0])); vert.nrm = Vector3.TransformNormal(vert.nrm, - Skeleton.GenericSkeleton.GetBoneTransform((int)Model.JointInfos[poly.IndexIntoJointMap].JointIndices[0])); + G1MSkeleton.GenericSkeleton.GetBoneTransform((int)Model.JointInfos[poly.IndexIntoJointMap].JointIndices[0])); mesh.vertices[i] = vert; } diff --git a/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs b/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs index 99b15bd4..2b5c82fa 100644 --- a/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs +++ b/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs @@ -379,6 +379,10 @@ namespace Toolbox.Library.Forms Console.WriteLine($"archiveMenus {archiveMenus.Count}"); } + if (e.Node is IExportableModel) { + menuItems.Add(new ToolStripMenuItem("Export Model", null, ExportModelAction, Keys.Control | Keys.E)); + } + bool IsRoot = e.Node.Parent == null; bool HasChildren = e.Node.Nodes.Count > 0; @@ -422,7 +426,12 @@ namespace Toolbox.Library.Forms if (!HasExpand && HasChildren) menuItems.Add(new ToolStripMenuItem("Expand All", null, ExpandAllAction, Keys.Control | Keys.P)); - if (archiveMenus.Count > 0) + + } + + if (archiveMenus.Count > 0) + { + if (menuItems.Count > 0) { STToolStipMenuItem archiveItem = new STToolStipMenuItem("Archive"); treeNodeContextMenu.Items.Add(archiveItem); @@ -430,11 +439,11 @@ namespace Toolbox.Library.Forms foreach (var item in archiveMenus) archiveItem.DropDownItems.Add(item); } - } - else - { - if (archiveMenus.Count > 0) - treeNodeContextMenu.Items.AddRange(archiveMenus.ToArray()); + else + { + if (archiveMenus.Count > 0) + treeNodeContextMenu.Items.AddRange(archiveMenus.ToArray()); + } } var fileFormat = TryGetActiveFile(e.Node); @@ -479,6 +488,34 @@ namespace Toolbox.Library.Forms return null; } + private void ExportModelAction(object sender, EventArgs args) + { + var node = treeViewCustom1.SelectedNode as IExportableModel; + if (node != null) + { + SaveFileDialog sfd = new SaveFileDialog(); + sfd.Filter = "Supported Formats|*.dae;"; + if (sfd.ShowDialog() == DialogResult.OK) + { + ExportModelSettings exportDlg = new ExportModelSettings(); + if (exportDlg.ShowDialog() == DialogResult.OK) + ExportModel(node, sfd.FileName, exportDlg.Settings); + } + } + } + + public void ExportModel(IExportableModel exportableModel, string fileName, DAE.ExportSettings settings) + { + var model = new STGenericModel(); + model.Materials = exportableModel.Materials; + model.Objects = exportableModel.Meshes; + var textures = new List(); + foreach (var tex in exportableModel.TextureList) + textures.Add(tex); + + DAE.Export(fileName, settings, model, textures, exportableModel.Skeleton); + } + private void SelectFileInExplorer(object sender, EventArgs args) { var node = treeViewCustom1.SelectedNode; diff --git a/Switch_Toolbox_Library/Interfaces/ModelData/IExportableModel.cs b/Switch_Toolbox_Library/Interfaces/ModelData/IExportableModel.cs new file mode 100644 index 00000000..b861eb1f --- /dev/null +++ b/Switch_Toolbox_Library/Interfaces/ModelData/IExportableModel.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Toolbox.Library +{ + public interface IExportableModel + { + List Meshes { get; } + List Materials { get; } + STSkeleton Skeleton { get; } + List TextureList { get; } + } +} diff --git a/Switch_Toolbox_Library/Toolbox_Library.csproj b/Switch_Toolbox_Library/Toolbox_Library.csproj index a0165939..e5db5fe9 100644 --- a/Switch_Toolbox_Library/Toolbox_Library.csproj +++ b/Switch_Toolbox_Library/Toolbox_Library.csproj @@ -402,6 +402,7 @@ +