Improve model export

This commit is contained in:
Perfare 2018-04-18 08:19:30 +08:00
parent ed569bfaf8
commit 5354506315
7 changed files with 115 additions and 37 deletions

View File

@ -56,6 +56,8 @@
this.exportAllAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportAllAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportSelectedAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportSelectedAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportFilteredAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportFilteredAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.showTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.showTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.allToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.allToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.debugMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.debugMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -111,8 +113,7 @@
this.exportAnimatorwithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportAnimatorwithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportobjectswithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportobjectswithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); this.exportAllObjectssplitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip1.SuspendLayout(); this.menuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel1.SuspendLayout();
@ -283,6 +284,7 @@
this.exportallobjectssplitToolStripMenuItem, this.exportallobjectssplitToolStripMenuItem,
this.exportselectedobjectsMenuItem, this.exportselectedobjectsMenuItem,
this.toolStripSeparator1, this.toolStripSeparator1,
this.exportAllObjectssplitToolStripMenuItem1,
this.exportSelectedObjectsToolStripMenuItem, this.exportSelectedObjectsToolStripMenuItem,
this.exportSelectedObjectsWithAnimationClipToolStripMenuItem}); this.exportSelectedObjectsWithAnimationClipToolStripMenuItem});
this.modelToolStripMenuItem.Name = "modelToolStripMenuItem"; this.modelToolStripMenuItem.Name = "modelToolStripMenuItem";
@ -362,6 +364,18 @@
this.exportFilteredAssetsMenuItem.Text = "Filtered assets"; this.exportFilteredAssetsMenuItem.Text = "Filtered assets";
this.exportFilteredAssetsMenuItem.Click += new System.EventHandler(this.ExportAssets_Click); this.exportFilteredAssetsMenuItem.Click += new System.EventHandler(this.ExportAssets_Click);
// //
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
this.toolStripSeparator3.Size = new System.Drawing.Size(331, 6);
//
// exportAnimatorWithSelectedAnimationClipToolStripMenuItem
//
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Name = "exportAnimatorWithSelectedAnimationClipToolStripMenuItem";
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Size = new System.Drawing.Size(334, 22);
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Text = "Export Animator with selected AnimationClip";
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Click += new System.EventHandler(this.exportAnimatorwithAnimationClipMenuItem_Click);
//
// showTypeToolStripMenuItem // showTypeToolStripMenuItem
// //
this.showTypeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.showTypeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -917,17 +931,12 @@
this.showOriginalFileToolStripMenuItem.Visible = false; this.showOriginalFileToolStripMenuItem.Visible = false;
this.showOriginalFileToolStripMenuItem.Click += new System.EventHandler(this.showOriginalFileToolStripMenuItem_Click); this.showOriginalFileToolStripMenuItem.Click += new System.EventHandler(this.showOriginalFileToolStripMenuItem_Click);
// //
// toolStripSeparator3 // exportAllObjectssplitToolStripMenuItem1
// //
this.toolStripSeparator3.Name = "toolStripSeparator3"; this.exportAllObjectssplitToolStripMenuItem1.Name = "exportAllObjectssplitToolStripMenuItem1";
this.toolStripSeparator3.Size = new System.Drawing.Size(331, 6); this.exportAllObjectssplitToolStripMenuItem1.Size = new System.Drawing.Size(323, 22);
// this.exportAllObjectssplitToolStripMenuItem1.Text = "Export all objects (split)";
// exportAnimatorWithSelectedAnimationClipToolStripMenuItem this.exportAllObjectssplitToolStripMenuItem1.Click += new System.EventHandler(this.exportAllObjectssplitToolStripMenuItem1_Click);
//
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Name = "exportAnimatorWithSelectedAnimationClipToolStripMenuItem";
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Size = new System.Drawing.Size(334, 22);
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Text = "Export Animator with selected AnimationClip";
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Click += new System.EventHandler(this.exportAnimatorwithAnimationClipMenuItem_Click);
// //
// AssetStudioForm // AssetStudioForm
// //
@ -1059,6 +1068,7 @@
private System.Windows.Forms.ToolStripMenuItem exportSelectedObjectsWithAnimationClipToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem exportSelectedObjectsWithAnimationClipToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
private System.Windows.Forms.ToolStripMenuItem exportAnimatorWithSelectedAnimationClipToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem exportAnimatorWithSelectedAnimationClipToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem exportAllObjectssplitToolStripMenuItem1;
} }
} }

View File

@ -1392,7 +1392,9 @@ namespace AssetStudio
toolStripStatusLabel1.Text = "Nothing exported."; toolStripStatusLabel1.Text = "Nothing exported.";
return; return;
} }
toolStripStatusLabel1.Text = $"Exporting {Path.GetFileName(saveFileDialog1.FileName)}.fbx";
FBXExporter.WriteFBX(saveFileDialog1.FileName, gameObjects); FBXExporter.WriteFBX(saveFileDialog1.FileName, gameObjects);
toolStripStatusLabel1.Text = $"Finished exporting {Path.GetFileName(saveFileDialog1.FileName)}.fbx";
progressBar1.PerformStep(); progressBar1.PerformStep();
if (openAfterExport.Checked && File.Exists(saveFileDialog1.FileName)) if (openAfterExport.Checked && File.Exists(saveFileDialog1.FileName))
{ {
@ -1816,6 +1818,26 @@ namespace AssetStudio
} }
} }
private void exportAllObjectssplitToolStripMenuItem1_Click(object sender, EventArgs e)
{
if (sceneTreeView.Nodes.Count > 0)
{
var saveFolderDialog1 = new OpenFolderDialog();
if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK)
{
var savePath = saveFolderDialog1.Folder + "\\";
progressBar1.Value = 0;
progressBar1.Maximum = sceneTreeView.Nodes.Count;
ThreadPool.QueueUserWorkItem(state => ExportSplitObjectsNew(savePath, sceneTreeView.Nodes));
}
}
else
{
StatusStripUpdate("No Objects available for export");
}
}
private void exportObjectswithAnimationClipMenuItem_Click(object sender, EventArgs e) private void exportObjectswithAnimationClipMenuItem_Click(object sender, EventArgs e)
{ {
var selectedAssets = GetSelectedAssets(); var selectedAssets = GetSelectedAssets();

View File

@ -10,10 +10,6 @@ namespace AssetStudio
{ {
public AssetPreloadData asset; public AssetPreloadData asset;
public List<PPtr> m_Components = new List<PPtr>(); public List<PPtr> m_Components = new List<PPtr>();
public PPtr m_Transform;
public PPtr m_MeshRenderer;
public PPtr m_MeshFilter;
public PPtr m_SkinnedMeshRenderer;
public int m_Layer; public int m_Layer;
public string m_Name; public string m_Name;
public ushort m_Tag; public ushort m_Tag;
@ -21,6 +17,12 @@ namespace AssetStudio
public string uniqueID = "0";//this way file and folder TreeNodes will be treated as FBX scene public string uniqueID = "0";//this way file and folder TreeNodes will be treated as FBX scene
public PPtr m_Transform;
public PPtr m_MeshRenderer;
public PPtr m_MeshFilter;
public PPtr m_SkinnedMeshRenderer;
public PPtr m_Animator;
public GameObject(AssetPreloadData preloadData) public GameObject(AssetPreloadData preloadData)
{ {
if (preloadData != null) if (preloadData != null)

View File

@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("AssetStudio")] [assembly: AssemblyTitle("AssetStudio")]
[assembly: AssemblyDescription("AssetStudio is a tool for exploring, extracting and exporting assets and assetBundles.")] [assembly: AssemblyDescription("AssetStudio is a tool for exploring, extracting and exporting assets and assetbundles.")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssetStudio")] [assembly: AssemblyProduct("AssetStudio")]
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.0.0")] [assembly: AssemblyVersion("0.10.0.0")]
[assembly: AssemblyFileVersion("0.9.0.0")] [assembly: AssemblyFileVersion("0.10.0.0")]

View File

@ -149,7 +149,6 @@ namespace AssetStudio
#endregion #endregion
#region write Materials, collect Texture objects #region write Materials, collect Texture objects
//StatusStripUpdate("Writing Materials");
foreach (var MaterialPD in Materials) foreach (var MaterialPD in Materials)
{ {
Material m_Material = new Material(MaterialPD); Material m_Material = new Material(MaterialPD);
@ -381,7 +380,6 @@ namespace AssetStudio
#endregion #endregion
#region write Model nodes and connections #region write Model nodes and connections
//StatusStripUpdate("Writing Nodes and hierarchy");
foreach (var m_GameObject in GameObjects) foreach (var m_GameObject in GameObjects)
{ {
if (m_GameObject.m_MeshFilter == null && m_GameObject.m_SkinnedMeshRenderer == null) if (m_GameObject.m_MeshFilter == null && m_GameObject.m_SkinnedMeshRenderer == null)
@ -451,7 +449,6 @@ namespace AssetStudio
#endregion #endregion
#region write non-skinnned Geometry #region write non-skinnned Geometry
//StatusStripUpdate("Writing Geometry");
foreach (var MeshPD in Meshes) foreach (var MeshPD in Meshes)
{ {
Mesh m_Mesh = new Mesh(MeshPD, true); Mesh m_Mesh = new Mesh(MeshPD, true);
@ -681,8 +678,6 @@ namespace AssetStudio
cb.Append("\n}");//Connections end cb.Append("\n}");//Connections end
FBXwriter.Write(cb); FBXwriter.Write(cb);
cb.Clear(); cb.Clear();
StatusStripUpdate("Finished exporting " + Path.GetFileName(FBXfile));
} }
} }
@ -690,8 +685,6 @@ namespace AssetStudio
{ {
if (m_Mesh.m_VertexCount > 0)//general failsafe if (m_Mesh.m_VertexCount > 0)//general failsafe
{ {
//StatusStripUpdate("Writing Geometry: " + m_Mesh.m_Name);
ob.AppendFormat("\n\tGeometry: 3{0}, \"Geometry::\", \"Mesh\" {{", MeshID); ob.AppendFormat("\n\tGeometry: 3{0}, \"Geometry::\", \"Mesh\" {{", MeshID);
ob.Append("\n\t\tProperties70: {"); ob.Append("\n\t\tProperties70: {");
var randomColor = RandomColorGenerator(m_Mesh.m_Name); var randomColor = RandomColorGenerator(m_Mesh.m_Name);

View File

@ -25,6 +25,14 @@ namespace AssetStudio
public ModelConverter(GameObject m_GameObject) public ModelConverter(GameObject m_GameObject)
{ {
if (assetsfileList.TryGetPD(m_GameObject.m_Animator, out var m_Animator))
{
var animator = new Animator(m_Animator);
InitWithAnimator(animator);
CollectAnimationClip(animator);
ConvertAnimations();
}
else
InitWithGameObject(m_GameObject); InitWithGameObject(m_GameObject);
} }
@ -65,7 +73,6 @@ namespace AssetStudio
InitWithGameObject(m_GameObject); InitWithGameObject(m_GameObject);
} }
private void InitWithGameObject(GameObject m_GameObject) private void InitWithGameObject(GameObject m_GameObject)
{ {
assetsfileList.TryGetTransform(m_GameObject.m_Transform, out var m_Transform); assetsfileList.TryGetTransform(m_GameObject.m_Transform, out var m_Transform);

View File

@ -85,12 +85,13 @@ namespace AssetStudio
{ {
SetProgressBarValue(0); SetProgressBarValue(0);
SetProgressBarMaximum(assetsfileList.Sum(x => x.preloadTable.Values.Count)); SetProgressBarMaximum(assetsfileList.Sum(x => x.preloadTable.Values.Count));
StatusStripUpdate("Building asset list...");
string fileIDfmt = "D" + assetsfileList.Count.ToString().Length; string fileIDfmt = "D" + assetsfileList.Count.ToString().Length;
for (var i = 0; i < assetsfileList.Count; i++) for (var i = 0; i < assetsfileList.Count; i++)
{ {
var assetsFile = assetsfileList[i]; var assetsFile = assetsfileList[i];
StatusStripUpdate("Building asset list from " + Path.GetFileName(assetsFile.filePath));
string fileID = i.ToString(fileIDfmt); string fileID = i.ToString(fileIDfmt);
AssetBundle ab = null; AssetBundle ab = null;
@ -254,9 +255,10 @@ namespace AssetStudio
SetProgressBarMaximum(1); SetProgressBarMaximum(1);
SetProgressBarValue(1); SetProgressBarValue(1);
SetProgressBarMaximum(assetsfileList.Sum(x => x.GameObjectList.Values.Count) + 1); SetProgressBarMaximum(assetsfileList.Sum(x => x.GameObjectList.Values.Count) + 1);
StatusStripUpdate("Building tree structure...");
foreach (var assetsFile in assetsfileList) foreach (var assetsFile in assetsfileList)
{ {
StatusStripUpdate("Building tree structure from " + Path.GetFileName(assetsFile.filePath));
GameObject fileNode = new GameObject(null); GameObject fileNode = new GameObject(null);
fileNode.Text = Path.GetFileName(assetsFile.filePath); fileNode.Text = Path.GetFileName(assetsFile.filePath);
fileNode.m_Name = "RootNode"; fileNode.m_Name = "RootNode";
@ -295,7 +297,8 @@ namespace AssetStudio
} }
case ClassIDReference.Animator: case ClassIDReference.Animator:
{ {
asset.Text = m_GameObject.asset.Text;//TODO m_GameObject.m_Animator = m_Component;
asset.Text = m_GameObject.asset.Text;
break; break;
} }
} }
@ -520,23 +523,64 @@ namespace AssetStudio
continue; continue;
//处理非法文件名 //处理非法文件名
var filename = FixFileName(j.Text); var filename = FixFileName(j.Text);
//每个文件单独文件夹 //每个文件存放在单独文件夹
var saveName = $"{savePath}{filename}\\{filename}.fbx"; var targetPath = $"{savePath}{filename}\\";
//重名文件处理 //重名文件处理
for (int i = 1; ; i++) for (int i = 1; ; i++)
{ {
if (File.Exists(saveName)) if (Directory.Exists(targetPath))
{ {
saveName = $"{savePath}{filename} ({i})\\{filename}.fbx"; targetPath = $"{savePath}{filename} ({i})\\";
} }
else else
{ {
break; break;
} }
} }
Directory.CreateDirectory(Path.GetDirectoryName(saveName)); Directory.CreateDirectory(targetPath);
//导出FBX //导出FBX
FBXExporter.WriteFBX(saveName, gameObjects); StatusStripUpdate($"Exporting {filename}.fbx");
FBXExporter.WriteFBX($"{targetPath}{filename}.fbx", gameObjects);
StatusStripUpdate($"Finished exporting {filename}.fbx");
}
ProgressBarPerformStep();
}
}
public static void ExportSplitObjectsNew(string savePath, TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes)
{
//遍历一级子节点
foreach (TreeNode j in node.Nodes)
{
//收集所有子节点
var gameObjects = new List<GameObject>();
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++)
{
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");
} }
ProgressBarPerformStep(); ProgressBarPerformStep();
} }