Add option to export Live2D Cubism models

This commit is contained in:
VaDiM
2023-07-02 03:10:11 +03:00
parent 6d41693b85
commit aea6cbc97f
17 changed files with 1256 additions and 31 deletions

View File

@ -66,6 +66,8 @@
this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem9 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
this.allLive2DModelsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripMenuItem10 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem11 = new System.Windows.Forms.ToolStripMenuItem();
@ -354,6 +356,8 @@
this.toolStripSeparator4,
this.toolStripMenuItem2,
this.toolStripMenuItem3,
this.toolStripSeparator6,
this.allLive2DModelsToolStripMenuItem,
this.toolStripSeparator2,
this.toolStripMenuItem10});
this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
@ -460,6 +464,18 @@
this.toolStripMenuItem9.Text = "Filtered assets";
this.toolStripMenuItem9.Click += new System.EventHandler(this.toolStripMenuItem9_Click);
//
// toolStripSeparator6
//
this.toolStripSeparator6.Name = "toolStripSeparator6";
this.toolStripSeparator6.Size = new System.Drawing.Size(263, 6);
//
// allLive2DModelsToolStripMenuItem
//
this.allLive2DModelsToolStripMenuItem.Name = "allLive2DModelsToolStripMenuItem";
this.allLive2DModelsToolStripMenuItem.Size = new System.Drawing.Size(266, 22);
this.allLive2DModelsToolStripMenuItem.Text = "Live2D Cubism models";
this.allLive2DModelsToolStripMenuItem.Click += new System.EventHandler(this.allLive2DModelsToolStripMenuItem_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
@ -510,7 +526,7 @@
this.allToolStripMenuItem.CheckOnClick = true;
this.allToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.allToolStripMenuItem.Name = "allToolStripMenuItem";
this.allToolStripMenuItem.Size = new System.Drawing.Size(88, 22);
this.allToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.allToolStripMenuItem.Text = "All";
this.allToolStripMenuItem.Click += new System.EventHandler(this.typeToolStripMenuItem_Click);
//
@ -1368,6 +1384,8 @@
private System.Windows.Forms.ComboBox listSearchFilterMode;
private System.Windows.Forms.ComboBox listSearchHistory;
private System.Windows.Forms.RichTextBox listSearch;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
private System.Windows.Forms.ToolStripMenuItem allLive2DModelsToolStripMenuItem;
}
}

View File

@ -1880,6 +1880,40 @@ namespace AssetStudioGUI
listSearch.SelectionStart = listSearch.Text.Length;
}
private void allLive2DModelsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (exportableAssets.Count > 0)
{
var cubismMocs = exportableAssets.Where(x =>
{
if (x.Type == ClassIDType.MonoBehaviour)
{
((MonoBehaviour)x.Asset).m_Script.TryGet(out var m_Script);
return m_Script?.m_ClassName == "CubismMoc";
}
return false;
}).Select(x => x.Asset).ToArray();
if (cubismMocs.Length == 0)
{
Logger.Info("Live2D Cubism models were not found.");
return;
}
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{
timer.Stop();
saveDirectoryBackup = saveFolderDialog.Folder;
Studio.ExportLive2D(cubismMocs, saveFolderDialog.Folder);
}
}
else
{
Logger.Info("No exportable assets loaded");
}
}
#region FMOD
private void FMODinit()
{

View File

@ -9,6 +9,7 @@ using System.Threading;
using System.Windows.Forms;
using System.Xml.Linq;
using static AssetStudioGUI.Exporter;
using static CubismLive2DExtractor.Live2DExtractor;
using Object = AssetStudio.Object;
namespace AssetStudioGUI
@ -54,6 +55,7 @@ namespace AssetStudioGUI
public static AssemblyLoader assemblyLoader = new AssemblyLoader();
public static List<AssetItem> exportableAssets = new List<AssetItem>();
public static List<AssetItem> visibleAssets = new List<AssetItem>();
private static Dictionary<Object, string> allContainers = new Dictionary<Object, string>();
internal static Action<string> StatusStripUpdate = x => { };
public static int ExtractFolder(string path, string savePath)
@ -262,6 +264,7 @@ namespace AssetStudioGUI
if (pptr.TryGet(out var obj))
{
objectAssetItemDic[obj].Container = container;
allContainers[obj] = container;
}
}
foreach (var tmp in exportableAssets)
@ -738,5 +741,66 @@ namespace AssetStudioGUI
info.UseShellExecute = true;
Process.Start(info);
}
public static void ExportLive2D(Object[] cubismMocs, string exportPath)
{
var baseDestPath = Path.Combine(exportPath, "Live2DOutput");
ThreadPool.QueueUserWorkItem(state =>
{
Progress.Reset();
Logger.Info($"Searching for Live2D files...");
var useFullContainerPath = false;
if (cubismMocs.Length > 1)
{
var basePathSet = cubismMocs.Select(x => allContainers[x].Substring(0, allContainers[x].LastIndexOf("/"))).ToHashSet();
if (basePathSet.Count != cubismMocs.Length)
{
useFullContainerPath = true;
}
}
var basePathList = useFullContainerPath ?
cubismMocs.Select(x => allContainers[x]).ToList() :
cubismMocs.Select(x => allContainers[x].Substring(0, allContainers[x].LastIndexOf("/"))).ToList();
var lookup = allContainers.ToLookup(
x => basePathList.Find(b => x.Value.Contains(b) && x.Value.Split('/').Any(y => y == b.Substring(b.LastIndexOf("/") + 1))),
x => x.Key
);
var totalModelCount = lookup.LongCount(x => x.Key != null);
var name = "";
var modelCounter = 0;
foreach (var assets in lookup)
{
var container = assets.Key;
if (container == null)
continue;
name = container;
Logger.Info($"[{modelCounter + 1}/{totalModelCount}] Exporting Live2D: \"{container}\"...");
try
{
var modelName = useFullContainerPath ? Path.GetFileNameWithoutExtension(container) : container.Substring(container.LastIndexOf('/') + 1);
container = Path.HasExtension(container) ? container.Replace(Path.GetExtension(container), "") : container;
var destPath = Path.Combine(baseDestPath, container) + Path.DirectorySeparatorChar;
ExtractLive2D(assets, destPath, modelName);
modelCounter++;
}
catch (Exception ex)
{
Logger.Error($"Live2D model export error: \"{name}\"", ex);
}
Progress.Report(modelCounter, (int)totalModelCount);
}
Logger.Info($"Finished exporting [{modelCounter}/{totalModelCount}] Live2D model(s).");
if (Properties.Settings.Default.openAfterExport && modelCounter > 0)
{
OpenFolderInExplorer(exportPath);
}
});
}
}
}