diff --git a/AssetStudioCLI/Studio.cs b/AssetStudioCLI/Studio.cs index 86bb697..e7ada00 100644 --- a/AssetStudioCLI/Studio.cs +++ b/AssetStudioCLI/Studio.cs @@ -1164,10 +1164,13 @@ namespace AssetStudioCLI public static void ExportLive2D() { var baseDestPath = Path.Combine(CLIOptions.o_outputFolder.Value, "Live2DOutput"); - var motionMode = CLIOptions.o_l2dMotionMode.Value; - var forceBezier = CLIOptions.f_l2dForceBezier.Value; var modelGroupOption = CLIOptions.o_l2dGroupOption.Value; - var searchByFilename = CLIOptions.f_l2dAssetSearchByFilename.Value; + var l2dOptions = new Live2DOptions() + { + MotionMode = CLIOptions.o_l2dMotionMode.Value, + ForceBezier = CLIOptions.f_l2dForceBezier.Value, + SearchByFilename = CLIOptions.f_l2dAssetSearchByFilename.Value, + }; if (CLIOptions.filterBy == FilterBy.NameOrContainer) FilterMocDict(); if (l2dAssetManager.ModelDict.Count == 0) @@ -1198,30 +1201,30 @@ namespace AssetStudioCLI Logger.Info($"[{modelCounter + 1}/{totalModelCount}] Exporting Live2D from: \"{srcContainer.Color(Ansi.BrightCyan)}\"..."); try { - var cubismExtractor = new Live2DExtractor(assetGroupKvp); - var filename = string.IsNullOrEmpty(cubismExtractor.MocMono.assetsFile.originalPath) + var cubismExtractor = new Live2DExtractor(assetGroupKvp, l2dOptions); + var fileName = string.IsNullOrEmpty(cubismExtractor.MocMono.assetsFile.originalPath) ? Path.GetFileNameWithoutExtension(cubismExtractor.MocMono.assetsFile.fileName) : Path.GetFileNameWithoutExtension(cubismExtractor.MocMono.assetsFile.originalPath); var modelName = !string.IsNullOrEmpty(cubismExtractor.Model?.Name) ? cubismExtractor.Model.Name - : filename; + : fileName; Logger.Info($"Model name: \"{modelName}\""); string modelPath; switch (modelGroupOption) { case Live2DModelGroupOption.SourceFileName: - modelPath = filename; + modelPath = fileName; break; case Live2DModelGroupOption.ModelName: modelPath = modelName; break; default: //ContainerPath - var container = searchByFilename && cubismExtractor.Model != null + var container = l2dOptions.SearchByFilename && cubismExtractor.Model != null ? cubismExtractor.Model.Container : srcContainer; container = container == assetGroupKvp.Key.assetsFile.fullName - ? filename + ? fileName : container; modelPath = Path.HasExtension(container) ? container.Replace(Path.GetExtension(container), "") @@ -1230,7 +1233,7 @@ namespace AssetStudioCLI } var destPath = Exporter.SafePathCombine(baseDestPath, modelPath); - cubismExtractor.ExtractCubismModel(destPath, motionMode, forceBezier, parallelTaskCount); + cubismExtractor.ExtractCubismModel(destPath, parallelTaskCount); modelCounter++; } catch (Exception ex) diff --git a/AssetStudioGUI/Studio.cs b/AssetStudioGUI/Studio.cs index 6403026..9455e01 100644 --- a/AssetStudioGUI/Studio.cs +++ b/AssetStudioGUI/Studio.cs @@ -1138,14 +1138,20 @@ namespace AssetStudioGUI public static void ExportLive2D(string exportPath, List selMocs = null, List selClipMotions = null, List selFadeMotions = null, MonoBehaviour selFadeLst = null) { var baseDestPath = Path.Combine(exportPath, "Live2DOutput"); - var forceBezier = Properties.Settings.Default.l2dForceBezier; var modelGroupOption = Properties.Settings.Default.l2dModelGroupOption; - var searchByFilename = Properties.Settings.Default.l2dAssetSearchByFilename; - var motionMode = Properties.Settings.Default.l2dMotionMode; + var l2dOptions = new Live2DOptions() + { + SelectedClipMotions = selClipMotions, + SelectedFadeMotions = selFadeMotions, + SelectedFadeMotionList = selFadeLst, + MotionMode = Properties.Settings.Default.l2dMotionMode, + ForceBezier = Properties.Settings.Default.l2dForceBezier, + SearchByFilename = Properties.Settings.Default.l2dAssetSearchByFilename, + }; if (selClipMotions != null) - motionMode = Live2DMotionMode.AnimationClipV2; + l2dOptions.MotionMode = Live2DMotionMode.AnimationClipV2; else if (selFadeMotions != null || selFadeLst != null) - motionMode = Live2DMotionMode.MonoBehaviour; + l2dOptions.MotionMode = Live2DMotionMode.MonoBehaviour; var mocDict = selMocs != null ? selMocs.ToDictionary(moc => moc, moc => l2dAssetManager.ModelDict[moc]) : l2dAssetManager.ModelDict; @@ -1171,30 +1177,30 @@ namespace AssetStudioGUI Logger.Info($"[{modelCounter + 1}/{totalModelCount}] Exporting Live2D from: \"{srcContainer}\"..."); try { - var cubismExtractor = new Live2DExtractor(assetGroupKvp, selClipMotions, selFadeMotions, selFadeLst); - var filename = string.IsNullOrEmpty(cubismExtractor.MocMono.assetsFile.originalPath) + var cubismExtractor = new Live2DExtractor(assetGroupKvp, l2dOptions); + var fileName = string.IsNullOrEmpty(cubismExtractor.MocMono.assetsFile.originalPath) ? Path.GetFileNameWithoutExtension(cubismExtractor.MocMono.assetsFile.fileName) : Path.GetFileNameWithoutExtension(cubismExtractor.MocMono.assetsFile.originalPath); var modelName = !string.IsNullOrEmpty(cubismExtractor.Model?.Name) ? cubismExtractor.Model.Name - : filename; + : fileName; Logger.Info($"Model name: \"{modelName}\""); string modelPath; switch (modelGroupOption) { case Live2DModelGroupOption.SourceFileName: - modelPath = filename; + modelPath = fileName; break; case Live2DModelGroupOption.ModelName: modelPath = modelName; break; default: //ContainerPath - var container = searchByFilename && cubismExtractor.Model != null + var container = l2dOptions.SearchByFilename && cubismExtractor.Model != null ? cubismExtractor.Model.Container : srcContainer; container = container == assetGroupKvp.Key.assetsFile.fullName - ? filename + ? fileName : container; modelPath = Path.HasExtension(container) ? container.Replace(Path.GetExtension(container), "") @@ -1202,7 +1208,7 @@ namespace AssetStudioGUI break; } var destPath = Exporter.SafePathCombine(baseDestPath, modelPath); - cubismExtractor.ExtractCubismModel(destPath, motionMode, forceBezier, GetParallelExportCount()); + cubismExtractor.ExtractCubismModel(destPath, GetParallelExportCount()); modelCounter++; } catch (Exception ex) diff --git a/AssetStudioUtility/CubismLive2DExtractor/Live2DExtractor.cs b/AssetStudioUtility/CubismLive2DExtractor/Live2DExtractor.cs index e653c86..732c961 100644 --- a/AssetStudioUtility/CubismLive2DExtractor/Live2DExtractor.cs +++ b/AssetStudioUtility/CubismLive2DExtractor/Live2DExtractor.cs @@ -26,6 +26,7 @@ namespace CubismLive2DExtractor public static Dictionary MocDict { get; set; } public static AssemblyLoader Assembly { get; set; } public CubismModel Model { get; set; } + private Live2DOptions Options { get; } private List FadeMotions { get; set; } private List AnimationClips { get; set; } private List Expressions { get; set; } @@ -42,12 +43,13 @@ namespace CubismLive2DExtractor private HashSet EyeBlinkParameters { get; set; } private HashSet LipSyncParameters { get; set; } - public Live2DExtractor(KeyValuePair> assetGroupKvp, List selClipMotions = null, List selFadeMotions = null, MonoBehaviour selFadeMotionLst = null) + public Live2DExtractor(KeyValuePair> assetGroupKvp, Live2DOptions l2dOptions) { + Options = l2dOptions; Expressions = new List(); - FadeMotions = selFadeMotions ?? new List(); - AnimationClips = selClipMotions ?? new List(); - FadeMotionLst = selFadeMotionLst; + FadeMotions = Options.SelectedFadeMotions ?? new List(); + AnimationClips = Options.SelectedClipMotions ?? new List(); + FadeMotionLst = Options.SelectedFadeMotionList; Texture2Ds = new List(); EyeBlinkParameters = new HashSet(); LipSyncParameters = new HashSet(); @@ -63,9 +65,9 @@ namespace CubismLive2DExtractor var searchModelPartCdi = true; var searchPoseParts = true; var searchFadeMotions = - selClipMotions == null - && selFadeMotions == null - && selFadeMotionLst == null; + Options.SelectedClipMotions == null + && Options.SelectedFadeMotions == null + && Options.SelectedFadeMotionList == null; Logger.Debug("Sorting model assets.."); @@ -109,9 +111,9 @@ namespace CubismLive2DExtractor PoseParts = Model.PosePartList; searchPoseParts = false; } - if (Model.ClipMotionList.Count > 0 && selClipMotions == null) + if (Model.ClipMotionList.Count > 0 && Options.SelectedClipMotions == null) { - AnimationClips = Model.ClipMotionList; + AnimationClips.AddRange(Model.ClipMotionList); } } foreach (var asset in assetGroupKvp.Value) @@ -197,7 +199,7 @@ namespace CubismLive2DExtractor } break; case AnimationClip m_AnimationClip: - if (selClipMotions == null) + if (Options.SelectedClipMotions == null) { AnimationClips.Add(m_AnimationClip); } @@ -207,17 +209,23 @@ namespace CubismLive2DExtractor break; } } + if (renderTextureSet.Count > 0) { Texture2Ds = renderTextureSet.ToList(); } + else if (Options.SearchByFilename) + { + Texture2Ds = Texture2Ds.Where(x => x.m_Name.ToLower().StartsWith("texture")).ToList(); + } + if (AnimationClips.Count > 0) { AnimationClips = AnimationClips.Distinct().ToList(); } } - public void ExtractCubismModel(string destPath, Live2DMotionMode motionMode, bool forceBezier = false, int parallelTaskCount = 1) + public void ExtractCubismModel(string destPath, int parallelTaskCount = 1) { var modelName = Model?.Name ?? destPath.Split('/', '\\').Last(); destPath += Path.DirectorySeparatorChar; @@ -311,7 +319,7 @@ namespace CubismLive2DExtractor var destMotionPath = Path.Combine(destPath, "motions") + Path.DirectorySeparatorChar; var motionFps = 0f; - if (motionMode == Live2DMotionMode.MonoBehaviour) //Fade motions from MonoBehaviour + if (Options.MotionMode == Live2DMotionMode.MonoBehaviour) //Fade motions from MonoBehaviour { if (FadeMotionLst != null) //Fade motions from fadeMotionList { @@ -340,7 +348,7 @@ namespace CubismLive2DExtractor if (FadeMotions.Count > 0) { Logger.Debug("Motion export method: MonoBehaviour (Fade motion)"); - ExportFadeMotions(destMotionPath, forceBezier, motions, ref motionFps); + ExportFadeMotions(destMotionPath, motions, ref motionFps); } } @@ -348,7 +356,7 @@ namespace CubismLive2DExtractor { CubismMotion3Converter converter; var exportMethod = "AnimationClip"; - switch (motionMode) + switch (Options.MotionMode) { case Live2DMotionMode.AnimationClipV1 when Model?.ModelGameObject != null: exportMethod += "V1"; @@ -356,7 +364,7 @@ namespace CubismLive2DExtractor break; default: //AnimationClipV2 exportMethod += "V2"; - if (motionMode == Live2DMotionMode.MonoBehaviour) + if (Options.MotionMode == Live2DMotionMode.MonoBehaviour) { exportMethod = FadeMotions.Count > 0 ? exportMethod + " (unable to export motions using Fade motion method)" @@ -367,7 +375,7 @@ namespace CubismLive2DExtractor } Logger.Debug($"Motion export method: {exportMethod}"); - ExportClipMotions(destMotionPath, converter, forceBezier, motions, ref motionFps); + ExportClipMotions(destMotionPath, converter, motions, ref motionFps); } if (motions.Count == 0) @@ -520,7 +528,7 @@ namespace CubismLive2DExtractor #endregion } - private void ExportFadeMotions(string destMotionPath, bool forceBezier, SortedDictionary motions, ref float fps) + private void ExportFadeMotions(string destMotionPath, SortedDictionary motions, ref float fps) { Directory.CreateDirectory(destMotionPath); foreach (var fadeMotionMono in FadeMotions) @@ -533,7 +541,7 @@ namespace CubismLive2DExtractor if (fadeMotion.ParameterIds.Length == 0) continue; - var motionJson = new CubismMotion3Json(fadeMotion, ParameterNames, PartNames, forceBezier); + var motionJson = new CubismMotion3Json(fadeMotion, ParameterNames, PartNames, Options.ForceBezier); fps = motionJson.Meta.Fps; var animName = Path.GetFileNameWithoutExtension(fadeMotion.m_Name); @@ -549,7 +557,7 @@ namespace CubismLive2DExtractor } } - private static void ExportClipMotions(string destMotionPath, CubismMotion3Converter converter, bool forceBezier, SortedDictionary motions, ref float fps) + private void ExportClipMotions(string destMotionPath, CubismMotion3Converter converter, SortedDictionary motions, ref float fps) { if (converter == null) return; @@ -566,7 +574,7 @@ namespace CubismLive2DExtractor Logger.Warning($"Motion \"{animName}\" is empty. Export skipped"); continue; } - var motionJson = new CubismMotion3Json(animation, forceBezier); + var motionJson = new CubismMotion3Json(animation, Options.ForceBezier); fps = motionJson.Meta.Fps; if (motions.ContainsKey(animName)) diff --git a/AssetStudioUtility/CubismLive2DExtractor/Live2DOptions.cs b/AssetStudioUtility/CubismLive2DExtractor/Live2DOptions.cs new file mode 100644 index 0000000..c9c652b --- /dev/null +++ b/AssetStudioUtility/CubismLive2DExtractor/Live2DOptions.cs @@ -0,0 +1,15 @@ +using AssetStudio; +using System.Collections.Generic; + +namespace CubismLive2DExtractor +{ + public sealed class Live2DOptions + { + public List SelectedClipMotions { get; set; } + public List SelectedFadeMotions { get; set; } + public MonoBehaviour SelectedFadeMotionList { get; set; } + public Live2DMotionMode MotionMode { get; set; } = Live2DMotionMode.MonoBehaviour; + public bool ForceBezier { get; set; } + public bool SearchByFilename { get; set; } + } +}