diff --git a/AssetStudio/AssetStudioForm.Designer.cs b/AssetStudio/AssetStudioForm.Designer.cs index 5a2470a..f7dede4 100644 --- a/AssetStudio/AssetStudioForm.Designer.cs +++ b/AssetStudio/AssetStudioForm.Designer.cs @@ -113,6 +113,7 @@ 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(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); @@ -163,33 +164,33 @@ // loadFileToolStripMenuItem // this.loadFileToolStripMenuItem.Name = "loadFileToolStripMenuItem"; - this.loadFileToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.loadFileToolStripMenuItem.Size = new System.Drawing.Size(154, 22); this.loadFileToolStripMenuItem.Text = "Load file"; this.loadFileToolStripMenuItem.Click += new System.EventHandler(this.loadFile_Click); // // loadFolderToolStripMenuItem // this.loadFolderToolStripMenuItem.Name = "loadFolderToolStripMenuItem"; - this.loadFolderToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.loadFolderToolStripMenuItem.Size = new System.Drawing.Size(154, 22); this.loadFolderToolStripMenuItem.Text = "Load folder"; this.loadFolderToolStripMenuItem.Click += new System.EventHandler(this.loadFolder_Click); // // toolStripMenuItem1 // this.toolStripMenuItem1.Name = "toolStripMenuItem1"; - this.toolStripMenuItem1.Size = new System.Drawing.Size(177, 6); + this.toolStripMenuItem1.Size = new System.Drawing.Size(151, 6); // // extractFileToolStripMenuItem // this.extractFileToolStripMenuItem.Name = "extractFileToolStripMenuItem"; - this.extractFileToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.extractFileToolStripMenuItem.Size = new System.Drawing.Size(154, 22); this.extractFileToolStripMenuItem.Text = "Extract file"; this.extractFileToolStripMenuItem.Click += new System.EventHandler(this.extractFileToolStripMenuItem_Click); // // extractFolderToolStripMenuItem // this.extractFolderToolStripMenuItem.Name = "extractFolderToolStripMenuItem"; - this.extractFolderToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.extractFolderToolStripMenuItem.Size = new System.Drawing.Size(154, 22); this.extractFolderToolStripMenuItem.Text = "Extract folder"; this.extractFolderToolStripMenuItem.Click += new System.EventHandler(this.extractFolderToolStripMenuItem_Click); // @@ -902,9 +903,10 @@ this.exportSelectedAssetsToolStripMenuItem, this.exportAnimatorwithselectedAnimationClipMenuItem, this.exportobjectswithselectedAnimationClipMenuItem, + this.jumpToSceneHierarchyToolStripMenuItem, this.showOriginalFileToolStripMenuItem}); this.contextMenuStrip1.Name = "contextMenuStrip1"; - this.contextMenuStrip1.Size = new System.Drawing.Size(335, 92); + this.contextMenuStrip1.Size = new System.Drawing.Size(335, 136); // // exportSelectedAssetsToolStripMenuItem // @@ -929,6 +931,14 @@ this.exportobjectswithselectedAnimationClipMenuItem.Visible = false; this.exportobjectswithselectedAnimationClipMenuItem.Click += new System.EventHandler(this.exportObjectswithAnimationClipMenuItem_Click); // + // jumpToSceneHierarchyToolStripMenuItem + // + this.jumpToSceneHierarchyToolStripMenuItem.Name = "jumpToSceneHierarchyToolStripMenuItem"; + this.jumpToSceneHierarchyToolStripMenuItem.Size = new System.Drawing.Size(334, 22); + this.jumpToSceneHierarchyToolStripMenuItem.Text = "Jump to scene hierarchy"; + this.jumpToSceneHierarchyToolStripMenuItem.Visible = false; + this.jumpToSceneHierarchyToolStripMenuItem.Click += new System.EventHandler(this.jumpToSceneHierarchyToolStripMenuItem_Click); + // // showOriginalFileToolStripMenuItem // this.showOriginalFileToolStripMenuItem.Name = "showOriginalFileToolStripMenuItem"; @@ -1068,6 +1078,7 @@ private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; private System.Windows.Forms.ToolStripMenuItem exportAnimatorWithSelectedAnimationClipToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem exportAllObjectssplitToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem jumpToSceneHierarchyToolStripMenuItem; } } diff --git a/AssetStudio/AssetStudioForm.cs b/AssetStudio/AssetStudioForm.cs index ebda6a8..8a8e821 100644 --- a/AssetStudio/AssetStudioForm.cs +++ b/AssetStudio/AssetStudioForm.cs @@ -170,6 +170,12 @@ namespace AssetStudio private void BuildAssetStrucutres() { + if (assetsfileList.Count == 0) + { + StatusStripUpdate("No file was loaded."); + return; + } + bool optionLoadAssetsMenuItem = !dontLoadAssetsMenuItem.Checked; bool optionDisplayAll = displayAll.Checked; bool optionBuildHierarchyMenuItem = !dontBuildHierarchyMenuItem.Checked; @@ -231,7 +237,7 @@ namespace AssetStudio showTypeToolStripMenuItem.DropDownItems.Add(typeItem); } allToolStripMenuItem.Checked = true; - StatusStripUpdate(assetsfileList.Count == 0 ? "No file was loaded." : $"Finished loading {assetsfileList.Count} files with {assetListView.Items.Count} exportable assets."); + StatusStripUpdate($"Finished loading {assetsfileList.Count} files with {assetListView.Items.Count} exportable assets."); treeSearch.Select(); })); } @@ -1350,10 +1356,8 @@ namespace AssetStudio var savePath = saveFolderDialog1.Folder + "\\"; progressBar1.Value = 0; progressBar1.Maximum = sceneTreeView.Nodes.Count; - - ThreadPool.QueueUserWorkItem(state => ExportSplitObjects(savePath, sceneTreeView.Nodes)); + ExportSplitObjects(savePath, sceneTreeView.Nodes); } - } else { @@ -1734,12 +1738,14 @@ namespace AssetStudio { if (e.Button == MouseButtons.Right && assetListView.SelectedIndices.Count > 0) { + jumpToSceneHierarchyToolStripMenuItem.Visible = false; showOriginalFileToolStripMenuItem.Visible = false; exportAnimatorwithselectedAnimationClipMenuItem.Visible = false; exportobjectswithselectedAnimationClipMenuItem.Visible = false; if (assetListView.SelectedIndices.Count == 1) { + jumpToSceneHierarchyToolStripMenuItem.Visible = true; showOriginalFileToolStripMenuItem.Visible = true; } if (assetListView.SelectedIndices.Count >= 1) @@ -1809,11 +1815,45 @@ namespace AssetStudio private void exportSelectedObjectsToolStripMenuItem_Click(object sender, EventArgs e) { - var saveFolderDialog1 = new OpenFolderDialog(); - if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK) + if (sceneTreeView.Nodes.Count > 0) { - var exportPath = saveFolderDialog1.Folder + "\\GameObject\\"; - ThreadPool.QueueUserWorkItem(state => ForeachTreeNodes(sceneTreeView.Nodes, exportPath, o => { ExportObjectsWithAnimationClip(o, exportPath); })); + var saveFolderDialog1 = new OpenFolderDialog(); + if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK) + { + var exportPath = saveFolderDialog1.Folder + "\\GameObject\\"; + ExportObjectsWithAnimationClip(exportPath, sceneTreeView.Nodes); + } + } + else + { + StatusStripUpdate("No Objects available for export"); + } + } + + private void exportObjectswithAnimationClipMenuItem_Click(object sender, EventArgs e) + { + if (sceneTreeView.Nodes.Count > 0) + { + var saveFolderDialog1 = new OpenFolderDialog(); + if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK) + { + var exportPath = saveFolderDialog1.Folder + "\\GameObject\\"; + ExportObjectsWithAnimationClip(exportPath, sceneTreeView.Nodes, GetSelectedAssets()); + } + } + else + { + StatusStripUpdate("No Objects available for export"); + } + } + + private void jumpToSceneHierarchyToolStripMenuItem_Click(object sender, EventArgs e) + { + var selectasset = (AssetPreloadData)assetListView.Items[assetListView.SelectedIndices[0]]; + if (selectasset.gameObject != null) + { + sceneTreeView.SelectedNode = selectasset.gameObject; + tabControl1.SelectedTab = tabPage1; } } @@ -1827,8 +1867,7 @@ namespace AssetStudio var savePath = saveFolderDialog1.Folder + "\\"; progressBar1.Value = 0; progressBar1.Maximum = sceneTreeView.Nodes.Count; - - ThreadPool.QueueUserWorkItem(state => ExportSplitObjectsNew(savePath, sceneTreeView.Nodes)); + ExportSplitObjectsNew(savePath, sceneTreeView.Nodes); } } else @@ -1837,17 +1876,6 @@ namespace AssetStudio } } - private void exportObjectswithAnimationClipMenuItem_Click(object sender, EventArgs e) - { - var selectedAssets = GetSelectedAssets(); - var saveFolderDialog1 = new OpenFolderDialog(); - if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK) - { - var exportPath = saveFolderDialog1.Folder + "\\GameObject\\"; - ThreadPool.QueueUserWorkItem(state => ForeachTreeNodes(sceneTreeView.Nodes, exportPath, o => { ExportObjectsWithAnimationClip(o, exportPath, selectedAssets); })); - } - } - private List GetSelectedAssets() { var selectedAssets = new List(); diff --git a/AssetStudio/StudioClasses/AssetPreloadData.cs b/AssetStudio/StudioClasses/AssetPreloadData.cs index a3313b4..187d0fa 100644 --- a/AssetStudio/StudioClasses/AssetPreloadData.cs +++ b/AssetStudio/StudioClasses/AssetPreloadData.cs @@ -21,6 +21,7 @@ namespace AssetStudio public string extension; public AssetsFile sourceFile; + public GameObject gameObject; public string uniqueID; public EndianBinaryReader InitReader() diff --git a/AssetStudio/StudioClasses/ModelConverter.cs b/AssetStudio/StudioClasses/ModelConverter.cs index ecc0dc5..8194b65 100644 --- a/AssetStudio/StudioClasses/ModelConverter.cs +++ b/AssetStudio/StudioClasses/ModelConverter.cs @@ -30,10 +30,20 @@ namespace AssetStudio var animator = new Animator(m_Animator); InitWithAnimator(animator); CollectAnimationClip(animator); - ConvertAnimations(); } else InitWithGameObject(m_GameObject); + ConvertAnimations(); + } + + public ModelConverter(GameObject m_GameObject, List animationList) + { + InitWithGameObject(m_GameObject); + foreach (var assetPreloadData in animationList) + { + animationClipHashSet.Add(assetPreloadData); + } + ConvertAnimations(); } public ModelConverter(Animator m_Animator) @@ -53,16 +63,6 @@ namespace AssetStudio ConvertAnimations(); } - public ModelConverter(GameObject m_GameObject, List animationList) - { - InitWithGameObject(m_GameObject); - foreach (var assetPreloadData in animationList) - { - animationClipHashSet.Add(assetPreloadData); - } - ConvertAnimations(); - } - private void InitWithAnimator(Animator m_Animator) { //In fact, doesn't need this. diff --git a/AssetStudio/StudioClasses/Studio.cs b/AssetStudio/StudioClasses/Studio.cs index 7dfc739..b7e85d8 100644 --- a/AssetStudio/StudioClasses/Studio.cs +++ b/AssetStudio/StudioClasses/Studio.cs @@ -328,9 +328,8 @@ namespace AssetStudio fileNodes = new List(); if (buildHierarchyMenuItem) { - SetProgressBarMaximum(1); - SetProgressBarValue(1); - SetProgressBarMaximum(assetsfileList.Sum(x => x.GameObjectList.Values.Count) + 1); + SetProgressBarValue(0); + SetProgressBarMaximum(assetsfileList.Sum(x => x.GameObjectList.Values.Count)); StatusStripUpdate("Building tree structure..."); foreach (var assetsFile in assetsfileList) @@ -341,7 +340,6 @@ namespace AssetStudio foreach (var m_GameObject in assetsFile.GameObjectList.Values) { - //ParseGameObject foreach (var m_Component in m_GameObject.m_Components) { if (m_Component.m_FileID >= 0 && m_Component.m_FileID < assetsfileList.Count) @@ -364,11 +362,27 @@ namespace AssetStudio case ClassIDReference.MeshFilter: { m_GameObject.m_MeshFilter = m_Component; + if (assetsfileList.TryGetPD(m_Component, out var assetPreloadData)) + { + var m_MeshFilter = new MeshFilter(assetPreloadData); + if (assetsfileList.TryGetPD(m_MeshFilter.m_Mesh, out assetPreloadData)) + { + assetPreloadData.gameObject = m_GameObject; + } + } break; } case ClassIDReference.SkinnedMeshRenderer: { m_GameObject.m_SkinnedMeshRenderer = m_Component; + if (assetsfileList.TryGetPD(m_Component, out var assetPreloadData)) + { + var m_SkinnedMeshRenderer = new SkinnedMeshRenderer(assetPreloadData); + if (assetsfileList.TryGetPD(m_SkinnedMeshRenderer.m_Mesh, out assetPreloadData)) + { + assetPreloadData.gameObject = m_GameObject; + } + } break; } case ClassIDReference.Animator: @@ -381,7 +395,6 @@ namespace AssetStudio } } } - // var parentNode = fileNode; @@ -413,10 +426,10 @@ namespace AssetStudio { string matLine; using (StreamReader reader = File.OpenText(mainPath + "\\materials.json")) - { matLine = reader.ReadToEnd(); } - + { + matLine = reader.ReadToEnd(); + } jsonMats = new JavaScriptSerializer().Deserialize>>(matLine); - //var jsonMats = new JavaScriptSerializer().DeserializeObject(matLine); } } #endregion @@ -586,80 +599,86 @@ namespace AssetStudio public static void ExportSplitObjects(string savePath, TreeNodeCollection nodes) { - foreach (TreeNode node in nodes) + ThreadPool.QueueUserWorkItem(state => { - //遍历一级子节点 - foreach (TreeNode j in node.Nodes) + foreach (TreeNode node in nodes) { - //收集所有子节点 - var gameObjects = new List(); - CollectNode(j, gameObjects); - //跳过一些不需要导出的object - if (gameObjects.All(x => x.m_SkinnedMeshRenderer == null && x.m_MeshFilter == null)) - continue; - //处理非法文件名 - var filename = FixFileName(j.Text); - //每个文件存放在单独的文件夹 - var targetPath = $"{savePath}{filename}\\"; - //重名文件处理 - for (int i = 1; ; i++) + //遍历一级子节点 + foreach (TreeNode j in node.Nodes) { - if (Directory.Exists(targetPath)) + //收集所有子节点 + var gameObjects = new List(); + CollectNode(j, gameObjects); + //跳过一些不需要导出的object + if (gameObjects.All(x => x.m_SkinnedMeshRenderer == null && x.m_MeshFilter == null)) + continue; + //处理非法文件名 + var filename = FixFileName(j.Text); + //每个文件存放在单独的文件夹 + var targetPath = $"{savePath}{filename}\\"; + //重名文件处理 + for (int i = 1; ; i++) { - targetPath = $"{savePath}{filename} ({i})\\"; - } - else - { - break; + if (Directory.Exists(targetPath)) + { + targetPath = $"{savePath}{filename} ({i})\\"; + } + else + { + break; + } } + Directory.CreateDirectory(targetPath); + //导出FBX + StatusStripUpdate($"Exporting {filename}.fbx"); + FBXExporter.WriteFBX($"{targetPath}{filename}.fbx", gameObjects); + StatusStripUpdate($"Finished exporting {filename}.fbx"); } - Directory.CreateDirectory(targetPath); - //导出FBX - StatusStripUpdate($"Exporting {filename}.fbx"); - FBXExporter.WriteFBX($"{targetPath}{filename}.fbx", gameObjects); - StatusStripUpdate($"Finished exporting {filename}.fbx"); + ProgressBarPerformStep(); } - ProgressBarPerformStep(); - } + }); } public static void ExportSplitObjectsNew(string savePath, TreeNodeCollection nodes) { - foreach (TreeNode node in nodes) + ThreadPool.QueueUserWorkItem(state => { - //遍历一级子节点 - foreach (TreeNode j in node.Nodes) + foreach (TreeNode node in nodes) { - //收集所有子节点 - var gameObjects = new List(); - CollectNode(j, gameObjects); - //跳过一些不需要导出的object - if (gameObjects.All(x => x.m_SkinnedMeshRenderer == null && x.m_MeshFilter == null)) - continue; - //处理非法文件名 - var filename = FixFileName(j.Text); - //每个文件存放在单独的文件夹 - var targetPath = $"{savePath}{filename}\\"; - //重名文件处理 - for (int i = 1; ; i++) + //遍历一级子节点 + foreach (TreeNode j in node.Nodes) { - if (Directory.Exists(targetPath)) + //收集所有子节点 + var gameObjects = new List(); + CollectNode(j, gameObjects); + //跳过一些不需要导出的object + if (gameObjects.All(x => x.m_SkinnedMeshRenderer == null && x.m_MeshFilter == null)) + continue; + //处理非法文件名 + var filename = FixFileName(j.Text); + //每个文件存放在单独的文件夹 + var targetPath = $"{savePath}{filename}\\"; + //重名文件处理 + for (int i = 1; ; i++) { - targetPath = $"{savePath}{filename} ({i})\\"; - } - else - { - break; + if (Directory.Exists(targetPath)) + { + targetPath = $"{savePath}{filename} ({i})\\"; + } + else + { + break; + } } + Directory.CreateDirectory(targetPath); + //导出FBX + StatusStripUpdate($"Exporting {j.Text}.fbx"); + ExportGameObject((GameObject)j, targetPath); + StatusStripUpdate($"Finished exporting {j.Text}.fbx"); } - Directory.CreateDirectory(targetPath); - //导出FBX - StatusStripUpdate($"Exporting {j.Text}.fbx"); - ExportGameObject((GameObject)j, targetPath); - StatusStripUpdate($"Finished exporting {j.Text}.fbx"); + ProgressBarPerformStep(); } - ProgressBarPerformStep(); - } + }); } private static void CollectNode(TreeNode node, List gameObjects) @@ -690,32 +709,43 @@ namespace AssetStudio }); } - public static void ExportObjectsWithAnimationClip(GameObject gameObject, string exportPath, List animationList = null) + public static void ExportObjectsWithAnimationClip(string exportPath, TreeNodeCollection nodes, List animationList = null) { - StatusStripUpdate($"Exporting {gameObject.Text}"); - try + ThreadPool.QueueUserWorkItem(state => { - ExportGameObject(gameObject, exportPath, animationList); - StatusStripUpdate($"Finished exporting {gameObject.Text}"); - } - catch (Exception ex) - { - MessageBox.Show($"{ex.Message}\r\n{ex.StackTrace}"); - StatusStripUpdate("Error in export"); - } + var gameObjects = new List(); + GetSelectedParentNode(nodes, gameObjects); + SetProgressBarValue(0); + SetProgressBarMaximum(gameObjects.Count); + foreach (var gameObject in gameObjects) + { + StatusStripUpdate($"Exporting {gameObject.Text}"); + try + { + ExportGameObject(gameObject, exportPath, animationList); + StatusStripUpdate($"Finished exporting {gameObject.Text}"); + } + catch (Exception ex) + { + MessageBox.Show($"{ex.Message}\r\n{ex.StackTrace}"); + StatusStripUpdate("Error in export"); + } + ProgressBarPerformStep(); + } + }); } - public static void ForeachTreeNodes(TreeNodeCollection nodes, string exportPath, Action action) + private static void GetSelectedParentNode(TreeNodeCollection nodes, List gameObjects) { foreach (TreeNode i in nodes) { if (i.Checked) { - action((GameObject)i); + gameObjects.Add((GameObject)i); } else { - ForeachTreeNodes(i.Nodes, exportPath, action); + GetSelectedParentNode(i.Nodes, gameObjects); } } } diff --git a/AssetStudioFBX/AssetStudioFBX.h b/AssetStudioFBX/AssetStudioFBX.h index 95cf7b0..dbe0954 100644 --- a/AssetStudioFBX/AssetStudioFBX.h +++ b/AssetStudioFBX/AssetStudioFBX.h @@ -47,7 +47,6 @@ namespace AssetStudio { IImported^ imported; char* cDest; - char* cFormat; FbxManager* pSdkManager; FbxScene* pScene; FbxExporter* pExporter; diff --git a/AssetStudioFBX/AssetStudioFBXExporter.cpp b/AssetStudioFBX/AssetStudioFBXExporter.cpp index a4dfe22..c3b52d6 100644 --- a/AssetStudioFBX/AssetStudioFBXExporter.cpp +++ b/AssetStudioFBX/AssetStudioFBXExporter.cpp @@ -52,7 +52,6 @@ namespace AssetStudio this->boneSize = boneSize; cDest = NULL; - cFormat = NULL; pSdkManager = NULL; pScene = NULL; pExporter = NULL; @@ -166,10 +165,6 @@ namespace AssetStudio { pSdkManager->Destroy(); } - if (cFormat != NULL) - { - Marshal::FreeHGlobal((IntPtr)cFormat); - } if (cDest != NULL) { Marshal::FreeHGlobal((IntPtr)cDest);