From e9e8390bbcf89334da8826dd0dd3c8a2d42df7e3 Mon Sep 17 00:00:00 2001 From: Perfare Date: Wed, 17 Jul 2019 12:51:00 +0800 Subject: [PATCH] Supported merge GameObject to export --- AssetStudio/Math/Vector3.cs | 2 + AssetStudioGUI/AssetStudioGUIForm.Designer.cs | 52 ++++++++----- AssetStudioGUI/AssetStudioGUIForm.cs | 42 ++++++++-- AssetStudioGUI/Exporter.cs | 19 +++-- AssetStudioGUI/Studio.cs | 27 ++++++- AssetStudioUtility/ModelConverter.cs | 76 +++++++++++++------ 6 files changed, 164 insertions(+), 54 deletions(-) diff --git a/AssetStudio/Math/Vector3.cs b/AssetStudio/Math/Vector3.cs index 31402e4..2426552 100644 --- a/AssetStudio/Math/Vector3.cs +++ b/AssetStudio/Math/Vector3.cs @@ -89,6 +89,8 @@ namespace AssetStudio public static Vector3 Zero => new Vector3(); + public static Vector3 One => new Vector3(1.0f, 1.0f, 1.0f); + public static Vector3 operator +(Vector3 a, Vector3 b) { return new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z); diff --git a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs index 4d2ccaa..f8f0881 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs @@ -49,6 +49,9 @@ this.exportAllObjectssplitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.exportSelectedObjectsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportSelectedObjectsWithAnimationClipToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.exportSelectedObjectsmergeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportAllAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportSelectedAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -106,7 +109,6 @@ this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.exportSelectedAssetsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportAnimatorwithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.exportobjectswithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.jumpToSceneHierarchyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.menuStrip1.SuspendLayout(); @@ -279,7 +281,10 @@ this.modelToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.exportAllObjectssplitToolStripMenuItem1, this.exportSelectedObjectsToolStripMenuItem, - this.exportSelectedObjectsWithAnimationClipToolStripMenuItem}); + this.exportSelectedObjectsWithAnimationClipToolStripMenuItem, + this.toolStripSeparator1, + this.exportSelectedObjectsmergeToolStripMenuItem, + this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem}); this.modelToolStripMenuItem.Name = "modelToolStripMenuItem"; this.modelToolStripMenuItem.Size = new System.Drawing.Size(58, 21); this.modelToolStripMenuItem.Text = "Model"; @@ -287,24 +292,43 @@ // exportAllObjectssplitToolStripMenuItem1 // this.exportAllObjectssplitToolStripMenuItem1.Name = "exportAllObjectssplitToolStripMenuItem1"; - this.exportAllObjectssplitToolStripMenuItem1.Size = new System.Drawing.Size(323, 22); + this.exportAllObjectssplitToolStripMenuItem1.Size = new System.Drawing.Size(373, 22); this.exportAllObjectssplitToolStripMenuItem1.Text = "Export all objects (split)"; this.exportAllObjectssplitToolStripMenuItem1.Click += new System.EventHandler(this.exportAllObjectssplitToolStripMenuItem1_Click); // // exportSelectedObjectsToolStripMenuItem // this.exportSelectedObjectsToolStripMenuItem.Name = "exportSelectedObjectsToolStripMenuItem"; - this.exportSelectedObjectsToolStripMenuItem.Size = new System.Drawing.Size(323, 22); - this.exportSelectedObjectsToolStripMenuItem.Text = "Export selected objects"; + this.exportSelectedObjectsToolStripMenuItem.Size = new System.Drawing.Size(373, 22); + this.exportSelectedObjectsToolStripMenuItem.Text = "Export selected objects (split)"; this.exportSelectedObjectsToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedObjectsToolStripMenuItem_Click); // // exportSelectedObjectsWithAnimationClipToolStripMenuItem // this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Name = "exportSelectedObjectsWithAnimationClipToolStripMenuItem"; - this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Size = new System.Drawing.Size(323, 22); - this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Text = "Export selected objects with AnimationClip"; + this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Size = new System.Drawing.Size(373, 22); + this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Text = "Export selected objects (split) with AnimationClip"; this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Click += new System.EventHandler(this.exportObjectswithAnimationClipMenuItem_Click); // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(370, 6); + // + // exportSelectedObjectsmergeToolStripMenuItem + // + this.exportSelectedObjectsmergeToolStripMenuItem.Name = "exportSelectedObjectsmergeToolStripMenuItem"; + this.exportSelectedObjectsmergeToolStripMenuItem.Size = new System.Drawing.Size(373, 22); + this.exportSelectedObjectsmergeToolStripMenuItem.Text = "Export selected objects (merge)"; + this.exportSelectedObjectsmergeToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedObjectsmergeToolStripMenuItem_Click); + // + // exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem + // + this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Name = "exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem"; + this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Size = new System.Drawing.Size(373, 22); + this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Text = "Export selected objects (merge) with AnimationClip"; + this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem_Click); + // // exportToolStripMenuItem // this.exportToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -825,6 +849,7 @@ this.columnHeader2}); this.classesListView.Dock = System.Windows.Forms.DockStyle.Fill; this.classesListView.FullRowSelect = true; + this.classesListView.HideSelection = false; this.classesListView.Location = new System.Drawing.Point(0, 0); this.classesListView.MultiSelect = false; this.classesListView.Name = "classesListView"; @@ -868,7 +893,6 @@ this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.exportSelectedAssetsToolStripMenuItem, this.exportAnimatorwithselectedAnimationClipMenuItem, - this.exportobjectswithselectedAnimationClipMenuItem, this.jumpToSceneHierarchyToolStripMenuItem, this.showOriginalFileToolStripMenuItem}); this.contextMenuStrip1.Name = "contextMenuStrip1"; @@ -889,14 +913,6 @@ this.exportAnimatorwithselectedAnimationClipMenuItem.Visible = false; this.exportAnimatorwithselectedAnimationClipMenuItem.Click += new System.EventHandler(this.exportAnimatorwithAnimationClipMenuItem_Click); // - // exportobjectswithselectedAnimationClipMenuItem - // - this.exportobjectswithselectedAnimationClipMenuItem.Name = "exportobjectswithselectedAnimationClipMenuItem"; - this.exportobjectswithselectedAnimationClipMenuItem.Size = new System.Drawing.Size(334, 22); - this.exportobjectswithselectedAnimationClipMenuItem.Text = "Export objects with selected AnimationClip"; - this.exportobjectswithselectedAnimationClipMenuItem.Visible = false; - this.exportobjectswithselectedAnimationClipMenuItem.Click += new System.EventHandler(this.exportObjectswithAnimationClipMenuItem_Click); - // // jumpToSceneHierarchyToolStripMenuItem // this.jumpToSceneHierarchyToolStripMenuItem.Name = "jumpToSceneHierarchyToolStripMenuItem"; @@ -1029,7 +1045,6 @@ private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; private System.Windows.Forms.ToolStripMenuItem showOriginalFileToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem exportAnimatorwithselectedAnimationClipMenuItem; - private System.Windows.Forms.ToolStripMenuItem exportobjectswithselectedAnimationClipMenuItem; private System.Windows.Forms.ToolStripMenuItem exportSelectedAssetsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem filterTypeToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem allToolStripMenuItem; @@ -1039,6 +1054,9 @@ private System.Windows.Forms.ToolStripMenuItem exportAnimatorWithSelectedAnimationClipToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem exportAllObjectssplitToolStripMenuItem1; private System.Windows.Forms.ToolStripMenuItem jumpToSceneHierarchyToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exportSelectedObjectsmergeToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; } } diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index 6dc677d..eb83042 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -1723,7 +1723,6 @@ namespace AssetStudioGUI jumpToSceneHierarchyToolStripMenuItem.Visible = false; showOriginalFileToolStripMenuItem.Visible = false; exportAnimatorwithselectedAnimationClipMenuItem.Visible = false; - exportobjectswithselectedAnimationClipMenuItem.Visible = false; if (assetListView.SelectedIndices.Count == 1) { @@ -1737,10 +1736,6 @@ namespace AssetStudioGUI { exportAnimatorwithselectedAnimationClipMenuItem.Visible = true; } - else if (selectedAssets.All(x => x.Type == ClassIDType.AnimationClip)) - { - exportobjectswithselectedAnimationClipMenuItem.Visible = true; - } } contextMenuStrip1.Show(assetListView, e.X, e.Y); @@ -1828,6 +1823,43 @@ namespace AssetStudioGUI } } + private void exportSelectedObjectsmergeToolStripMenuItem_Click(object sender, EventArgs e) + { + if (sceneTreeView.Nodes.Count > 0) + { + var gameObjects = new List(); + GetSelectedParentNode(sceneTreeView.Nodes, gameObjects); + var saveFileDialog = new SaveFileDialog(); + saveFileDialog.FileName = gameObjects[0].m_Name + " (merge).fbx"; + saveFileDialog.AddExtension = false; + saveFileDialog.Filter = "Fbx file (*.fbx)|*.fbx"; + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + var exportPath = saveFileDialog.FileName; + ExportObjectsMergeWithAnimationClip(exportPath, openAfterExport.Checked, gameObjects); + } + } + } + + private void exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem_Click(object sender, EventArgs e) + { + if (sceneTreeView.Nodes.Count > 0) + { + var gameObjects = new List(); + GetSelectedParentNode(sceneTreeView.Nodes, gameObjects); + var saveFileDialog = new SaveFileDialog(); + saveFileDialog.FileName = gameObjects[0].m_Name + " (merge).fbx"; + saveFileDialog.AddExtension = false; + saveFileDialog.Filter = "Fbx file (*.fbx)|*.fbx"; + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + var exportPath = saveFileDialog.FileName; + var animationList = GetSelectedAssets().Where(x => x.Type == ClassIDType.AnimationClip).ToList(); + ExportObjectsMergeWithAnimationClip(exportPath, openAfterExport.Checked, gameObjects, animationList.Count == 0 ? null : animationList); + } + } + } + private void jumpToSceneHierarchyToolStripMenuItem_Click(object sender, EventArgs e) { var selectasset = (AssetItem)assetListView.Items[assetListView.SelectedIndices[0]]; diff --git a/AssetStudioGUI/Exporter.cs b/AssetStudioGUI/Exporter.cs index 28a246f..c73fe0e 100644 --- a/AssetStudioGUI/Exporter.cs +++ b/AssetStudioGUI/Exporter.cs @@ -82,7 +82,7 @@ namespace AssetStudioGUI var exportFullName = exportPath + item.Text + ".shader"; if (ExportFileExists(exportFullName)) return false; - var m_Shader = (Shader) item.Asset; + var m_Shader = (Shader)item.Asset; if (m_Shader.compressedBlob != null) //5.5 and up { var strs = ShaderConverter.ConvertMultiple(m_Shader); @@ -299,17 +299,25 @@ namespace AssetStudioGUI var m_Animator = (Animator)item.Asset; var convert = animationList != null ? new ModelConverter(m_Animator, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(m_Animator); exportPath = $"{exportPath}{item.Text}\\{item.Text}.fbx"; - return ExportFbx(convert, exportPath); + ExportFbx(convert, exportPath); + return true; } - public static bool ExportGameObject(GameObject gameObject, string exportPath, List animationList = null) + public static void ExportGameObject(GameObject gameObject, string exportPath, List animationList = null) { var convert = animationList != null ? new ModelConverter(gameObject, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(gameObject); exportPath = exportPath + Studio.FixFileName(gameObject.m_Name) + ".fbx"; - return ExportFbx(convert, exportPath); + ExportFbx(convert, exportPath); } - private static bool ExportFbx(IImported convert, string exportPath) + public static void ExportGameObjectMerge(List gameObject, string exportPath, List animationList = null) + { + var rootName = Path.GetFileNameWithoutExtension(exportPath); + var convert = animationList != null ? new ModelConverter(rootName, gameObject, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(rootName, gameObject); + ExportFbx(convert, exportPath); + } + + private static void ExportFbx(IImported convert, string exportPath) { var eulerFilter = (bool)Properties.Settings.Default["eulerFilter"]; var filterPrecision = (float)(decimal)Properties.Settings.Default["filterPrecision"]; @@ -321,7 +329,6 @@ namespace AssetStudioGUI var fbxVersion = (int)Properties.Settings.Default["fbxVersion"]; var fbxFormat = (int)Properties.Settings.Default["fbxFormat"]; ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision, allFrames, allBones, skins, boneSize, scaleFactor, fbxVersion, fbxFormat == 1); - return true; } } } diff --git a/AssetStudioGUI/Studio.cs b/AssetStudioGUI/Studio.cs index 738edca..1f3d8f1 100644 --- a/AssetStudioGUI/Studio.cs +++ b/AssetStudioGUI/Studio.cs @@ -615,7 +615,32 @@ namespace AssetStudioGUI }); } - private static void GetSelectedParentNode(TreeNodeCollection nodes, List gameObjects) + public static void ExportObjectsMergeWithAnimationClip(string exportPath, bool openAfterExport, List gameObjects, List animationList = null) + { + ThreadPool.QueueUserWorkItem(state => + { + var name = Path.GetFileName(exportPath); + Progress.Reset(); + Logger.Info($"Exporting {name}"); + try + { + ExportGameObjectMerge(gameObjects, exportPath, animationList); + Progress.Report(1, 1); + Logger.Info($"Finished exporting {name}"); + } + catch (Exception ex) + { + MessageBox.Show($"Export Model:{name} error\r\n{ex.Message}\r\n{ex.StackTrace}"); + Logger.Info("Error in export"); + } + if (openAfterExport) + { + Process.Start(Path.GetDirectoryName(exportPath)); + } + }); + } + + public static void GetSelectedParentNode(TreeNodeCollection nodes, List gameObjects) { foreach (GameObjectTreeNode i in nodes) { diff --git a/AssetStudioUtility/ModelConverter.cs b/AssetStudioUtility/ModelConverter.cs index 1807cec..c586118 100644 --- a/AssetStudioUtility/ModelConverter.cs +++ b/AssetStudioUtility/ModelConverter.cs @@ -22,46 +22,72 @@ namespace AssetStudio private Dictionary textureNameDictionary = new Dictionary(); private Dictionary transformDictionary = new Dictionary(); - public ModelConverter(GameObject m_GameObject) + public ModelConverter(GameObject m_GameObject, AnimationClip[] animationList = null) { if (m_GameObject.m_Animator != null) { InitWithAnimator(m_GameObject.m_Animator); - CollectAnimationClip(m_GameObject.m_Animator); + if (animationList == null) + { + CollectAnimationClip(m_GameObject.m_Animator); + } } else + { InitWithGameObject(m_GameObject); + } + if (animationList != null) + { + foreach (var animationClip in animationList) + { + animationClipHashSet.Add(animationClip); + } + } ConvertAnimations(); } - public ModelConverter(GameObject m_GameObject, AnimationClip[] animationList) + public ModelConverter(string rootName, List m_GameObjects, AnimationClip[] animationList = null) { - if (m_GameObject.m_Animator != null) + RootFrame = CreateFrame(rootName, Vector3.Zero, new Quaternion(0, 0, 0, 0), Vector3.One); + foreach (var m_GameObject in m_GameObjects) { - InitWithAnimator(m_GameObject.m_Animator); + if (m_GameObject.m_Animator != null && animationList == null) + { + CollectAnimationClip(m_GameObject.m_Animator); + } + + var m_Transform = m_GameObject.m_Transform; + ConvertTransforms(m_Transform, RootFrame); + CreateBonePathHash(m_Transform); + } + foreach (var m_GameObject in m_GameObjects) + { + var m_Transform = m_GameObject.m_Transform; + ConvertMeshRenderer(m_Transform); + } + if (animationList != null) + { + foreach (var animationClip in animationList) + { + animationClipHashSet.Add(animationClip); + } + } + ConvertAnimations(); + } + + public ModelConverter(Animator m_Animator, AnimationClip[] animationList = null) + { + InitWithAnimator(m_Animator); + if (animationList == null) + { + CollectAnimationClip(m_Animator); } else - InitWithGameObject(m_GameObject); - foreach (var animationClip in animationList) { - animationClipHashSet.Add(animationClip); - } - ConvertAnimations(); - } - - public ModelConverter(Animator m_Animator) - { - InitWithAnimator(m_Animator); - CollectAnimationClip(m_Animator); - ConvertAnimations(); - } - - public ModelConverter(Animator m_Animator, AnimationClip[] animationList) - { - InitWithAnimator(m_Animator); - foreach (var animationClip in animationList) - { - animationClipHashSet.Add(animationClip); + foreach (var animationClip in animationList) + { + animationClipHashSet.Add(animationClip); + } } ConvertAnimations(); }