From 4cfa199cd7e62c4f741a6dccc7b07a5fe065d3d1 Mon Sep 17 00:00:00 2001 From: bd_ Date: Mon, 18 Sep 2023 04:59:55 +0900 Subject: [PATCH] feat: implement NDMF integration --- CHANGELOG-PRERELEASE.md | 1 + Editor/OptimizerProcessor.cs | 5 +- Editor/OptimizerSession.cs | 9 +++ Editor/Processors/OptimizerPlugin.cs | 73 +++++++++++++++++++ Editor/Processors/OptimizerPlugin.cs.meta | 3 + Editor/Utils.cs | 6 +- ...m.anatawa12.avatar-optimizer.editor.asmdef | 11 ++- .../Editor/ApplyOnPlayCallbackRegistry.cs | 4 +- .../ApplyOnPlay/Editor/ApplyOnPlayCaller.cs | 4 +- .../Editor/ApplyOnPlayConfiguration.cs | 4 +- .../Editor/IApplyOnPlayCallback.cs | 2 + Internal/ApplyOnPlay/Editor/ManualBake.cs | 2 + .../Editor/ManualBakeFinallizer.cs | 2 + .../Editor/RemoveEditorOnlyOnPlay.cs | 4 +- ...mizer.internal.apply-on-play.editor.asmdef | 7 +- .../ErrorReportingInitializerProcessor.cs | 11 ++- ...izer.internal.error-reporter.editor.asmdef | 8 +- 17 files changed, 143 insertions(+), 13 deletions(-) create mode 100644 Editor/Processors/OptimizerPlugin.cs create mode 100644 Editor/Processors/OptimizerPlugin.cs.meta diff --git a/CHANGELOG-PRERELEASE.md b/CHANGELOG-PRERELEASE.md index afe3f9043..b2b6eb803 100644 --- a/CHANGELOG-PRERELEASE.md +++ b/CHANGELOG-PRERELEASE.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog]. ## [Unreleased] ### Added - Support for Multi Frame BlendShapes `#333` +- Support for [NDMF](https://ndmf.nadena.dev) integration `#375` ### Changed - Auto FreezeBlendShape now freezes meaningless BlendShape `#334` diff --git a/Editor/OptimizerProcessor.cs b/Editor/OptimizerProcessor.cs index 56e6e955f..d899c0603 100644 --- a/Editor/OptimizerProcessor.cs +++ b/Editor/OptimizerProcessor.cs @@ -1,10 +1,10 @@ - +#if !NADEMOFU using System; -using Anatawa12.ApplyOnPlay; using Anatawa12.AvatarOptimizer.ErrorReporting; using UnityEngine; using VRC.SDK3.Avatars.Components; using VRC.SDKBase.Editor.BuildPipeline; +using Anatawa12.ApplyOnPlay; namespace Anatawa12.AvatarOptimizer { @@ -150,3 +150,4 @@ private static void DoProcessObject(OptimizerSession session) } } } +#endif \ No newline at end of file diff --git a/Editor/OptimizerSession.cs b/Editor/OptimizerSession.cs index 4ada56b55..ef3607160 100644 --- a/Editor/OptimizerSession.cs +++ b/Editor/OptimizerSession.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using Anatawa12.AvatarOptimizer.ndmf; +using nadena.dev.ndmf; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; @@ -15,6 +17,13 @@ internal class OptimizerSession public bool IsTest { get; } public ObjectMappingBuilder MappingBuilder { get; } +#if NADEMOFU + + public static implicit operator OptimizerSession(BuildContext context) + => context.Extension().session; + +#endif + public OptimizerSession(GameObject rootObject, bool addToAsset, bool isTest) : this(rootObject, addToAsset ? Utils.CreateAssetFile() : null, isTest) { diff --git a/Editor/Processors/OptimizerPlugin.cs b/Editor/Processors/OptimizerPlugin.cs new file mode 100644 index 000000000..050d0de08 --- /dev/null +++ b/Editor/Processors/OptimizerPlugin.cs @@ -0,0 +1,73 @@ +using System; +using Anatawa12.AvatarOptimizer.ErrorReporting; +using Anatawa12.AvatarOptimizer.ndmf; +using nadena.dev.ndmf; +using nadena.dev.ndmf.builtin; + +[assembly: ExportsPlugin(typeof(OptimizerPlugin))] + +namespace Anatawa12.AvatarOptimizer.ndmf +{ + internal class OptimizerContext : IExtensionContext + { + private IDisposable buildReportScope; + internal OptimizerSession session; + + public void OnActivate(BuildContext context) + { + buildReportScope = BuildReport.ReportingOnAvatar(context.AvatarDescriptor); + session = new OptimizerSession(context.AvatarRootObject, context.AssetContainer, + false); + } + + public void OnDeactivate(BuildContext context) + { + session.MarkDirtyAll(); + buildReportScope.Dispose(); + } + } + + internal class OptimizerPlugin : Plugin + { + public override string DisplayName => "Anatawa12's Avatar Optimizer"; + + public override string QualifiedName => "com.anatawa12.avatar-optimizer"; + + protected override void Configure() + { + // Run early steps before EditorOnly objects are purged + InPhase(BuildPhase.Resolving) + .WithRequiredExtension(typeof(OptimizerContext), seq => + { + seq.Run("Early: UnusedBonesByReference", + ctx => new Processors.UnusedBonesByReferencesToolEarlyProcessor().Process(ctx) + ) + .Then.Run("Early: MakeChildren", + ctx => new Processors.MakeChildrenProcessor(early: true).Process(ctx) + ) + .BeforePass(RemoveEditorOnlyPass.Instance); + }); + + // Run everything else in the optimize phase + InPhase(BuildPhase.Optimizing) + .WithRequiredExtension(typeof(OptimizerContext), seq => + { + seq.Run("TraceAndOptimize", + ctx => new Processors.TraceAndOptimizeProcessor().Process(ctx) + ) + .Then.Run("ClearEndpointPosition", + ctx => new Processors.ClearEndpointPositionProcessor().Process(ctx) + ) + .Then.Run("MergePhysBone", + ctx => new Processors.MergePhysBoneProcessor().Process(ctx) + ) + .Then.Run("MakeChildrenProcessor", + ctx => new Processors.MakeChildrenProcessor(early: false).Process(ctx) + ) + .Then.Run("ApplyObjectMapping", + ctx => new Processors.ApplyObjectMapping().Apply(ctx) + ); + }); + } + } +} \ No newline at end of file diff --git a/Editor/Processors/OptimizerPlugin.cs.meta b/Editor/Processors/OptimizerPlugin.cs.meta new file mode 100644 index 000000000..8e4e60072 --- /dev/null +++ b/Editor/Processors/OptimizerPlugin.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3509899322ab44619ca3b2c10e0e673c +timeCreated: 1694975631 \ No newline at end of file diff --git a/Editor/Utils.cs b/Editor/Utils.cs index 9df8a85a6..2e9e0a653 100644 --- a/Editor/Utils.cs +++ b/Editor/Utils.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; +#if !NADEMOFU using Anatawa12.ApplyOnPlay; +#endif using JetBrains.Annotations; using Unity.Collections; using UnityEditor; @@ -321,7 +323,8 @@ public static void DeleteTemporalDirectory() AssetDatabase.DeleteAsset(TemporalDirPath); FileUtil.DeleteFileOrDirectory(TemporalDirPath); } - + +#if !NADEMOFU [CanBeNull] public static DummyObject CreateOutputAssetFile(GameObject avatarGameObject, ApplyReason reason) { @@ -334,6 +337,7 @@ public static DummyObject CreateOutputAssetFile(GameObject avatarGameObject, App return CreateOutputAssetFile(avatarGameObject); } } +#endif public static DummyObject CreateAssetFile() { diff --git a/Editor/com.anatawa12.avatar-optimizer.editor.asmdef b/Editor/com.anatawa12.avatar-optimizer.editor.asmdef index a84e39da3..e97bd2309 100644 --- a/Editor/com.anatawa12.avatar-optimizer.editor.asmdef +++ b/Editor/com.anatawa12.avatar-optimizer.editor.asmdef @@ -9,7 +9,8 @@ "GUID:f69eeb3e25674f4a9bd20e6d7e69e0e6", "GUID:2633ab9fa94544a69517fc9a1bc143c9", "GUID:b9880ca0b6584453a2627bd3c038759f", - "GUID:8542dbf824204440a818dbc2377cb4d6" + "GUID:8542dbf824204440a818dbc2377cb4d6", + "GUID:62ced99b048af7f4d8dfe4bed8373d76" ], "includePlatforms": [ "Editor" @@ -29,6 +30,12 @@ ], "autoReferenced": false, "defineConstraints": [], - "versionDefines": [], + "versionDefines": [ + { + "name": "nadena.dev.ndmf", + "expression": "[0.3.0,999.999.999]", + "define": "NADEMOFU" + } + ], "noEngineReferences": false } \ No newline at end of file diff --git a/Internal/ApplyOnPlay/Editor/ApplyOnPlayCallbackRegistry.cs b/Internal/ApplyOnPlay/Editor/ApplyOnPlayCallbackRegistry.cs index 03c60464c..ee0e7ab6a 100644 --- a/Internal/ApplyOnPlay/Editor/ApplyOnPlayCallbackRegistry.cs +++ b/Internal/ApplyOnPlay/Editor/ApplyOnPlayCallbackRegistry.cs @@ -1,3 +1,4 @@ +#if !NADEMOFU using System; using System.Collections.Generic; using System.Linq; @@ -101,4 +102,5 @@ private static void LogException(string message, params Exception[] exceptions) } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Internal/ApplyOnPlay/Editor/ApplyOnPlayCaller.cs b/Internal/ApplyOnPlay/Editor/ApplyOnPlayCaller.cs index 96d361435..8f83c409a 100644 --- a/Internal/ApplyOnPlay/Editor/ApplyOnPlayCaller.cs +++ b/Internal/ApplyOnPlay/Editor/ApplyOnPlayCaller.cs @@ -1,3 +1,4 @@ +#if !NADEMOFU using System; using System.Diagnostics; using System.Linq; @@ -143,4 +144,5 @@ public static void CallManualBakeFinalizer(IManualBakeFinalizer[] finalizers, Ga } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Internal/ApplyOnPlay/Editor/ApplyOnPlayConfiguration.cs b/Internal/ApplyOnPlay/Editor/ApplyOnPlayConfiguration.cs index 11059f9db..515e73650 100644 --- a/Internal/ApplyOnPlay/Editor/ApplyOnPlayConfiguration.cs +++ b/Internal/ApplyOnPlay/Editor/ApplyOnPlayConfiguration.cs @@ -1,3 +1,4 @@ +#if !NADEMOFU using System.Linq; using CustomLocalization4EditorExtension; using UnityEditor; @@ -64,4 +65,5 @@ private void OnGUI() GUILayout.EndHorizontal(); } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Internal/ApplyOnPlay/Editor/IApplyOnPlayCallback.cs b/Internal/ApplyOnPlay/Editor/IApplyOnPlayCallback.cs index ee76df431..b92fd8ef0 100644 --- a/Internal/ApplyOnPlay/Editor/IApplyOnPlayCallback.cs +++ b/Internal/ApplyOnPlay/Editor/IApplyOnPlayCallback.cs @@ -1,3 +1,4 @@ +#if !NADEMOFU using UnityEditor.Build; using UnityEngine; @@ -33,3 +34,4 @@ public enum ApplyReason ManualBake, } } +#endif \ No newline at end of file diff --git a/Internal/ApplyOnPlay/Editor/ManualBake.cs b/Internal/ApplyOnPlay/Editor/ManualBake.cs index 6e5e45b12..111e0da77 100644 --- a/Internal/ApplyOnPlay/Editor/ManualBake.cs +++ b/Internal/ApplyOnPlay/Editor/ManualBake.cs @@ -1,3 +1,4 @@ +#if !NADEMOFU using UnityEditor; using UnityEngine; using VRC.SDK3.Avatars.Components; @@ -45,3 +46,4 @@ private static void ExecuteManualBake() } } } +#endif \ No newline at end of file diff --git a/Internal/ApplyOnPlay/Editor/ManualBakeFinallizer.cs b/Internal/ApplyOnPlay/Editor/ManualBakeFinallizer.cs index ea76f10c8..aaf44a9d5 100644 --- a/Internal/ApplyOnPlay/Editor/ManualBakeFinallizer.cs +++ b/Internal/ApplyOnPlay/Editor/ManualBakeFinallizer.cs @@ -1,3 +1,4 @@ +#if !NADEMOFU using UnityEditor.Build; using UnityEngine; @@ -27,3 +28,4 @@ public interface IManualBakeFinalizer : IOrderedCallback void FinalizeManualBake(GameObject original, GameObject cloned); } } +#endif \ No newline at end of file diff --git a/Internal/ApplyOnPlay/Editor/RemoveEditorOnlyOnPlay.cs b/Internal/ApplyOnPlay/Editor/RemoveEditorOnlyOnPlay.cs index 875610e24..6596e46b5 100644 --- a/Internal/ApplyOnPlay/Editor/RemoveEditorOnlyOnPlay.cs +++ b/Internal/ApplyOnPlay/Editor/RemoveEditorOnlyOnPlay.cs @@ -1,3 +1,4 @@ +#if !NADEMOFU using UnityEngine; using Object = UnityEngine.Object; @@ -17,4 +18,5 @@ public bool ApplyOnPlay(GameObject avatarGameObject, ApplyReason reason) return true; } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Internal/ApplyOnPlay/Editor/com.anatawa12.avatar-optimizer.internal.apply-on-play.editor.asmdef b/Internal/ApplyOnPlay/Editor/com.anatawa12.avatar-optimizer.internal.apply-on-play.editor.asmdef index 155f5a192..0864c8e1e 100644 --- a/Internal/ApplyOnPlay/Editor/com.anatawa12.avatar-optimizer.internal.apply-on-play.editor.asmdef +++ b/Internal/ApplyOnPlay/Editor/com.anatawa12.avatar-optimizer.internal.apply-on-play.editor.asmdef @@ -21,8 +21,13 @@ "versionDefines": [ { "name": "nadena.dev.modular-avatar", - "expression": "[1.0.0,2.0.0)", + "expression": "[1.0.0,1.7.99999)", "define": "MODULAR_AVATAR" + }, + { + "name": "nadena.dev.ndmf", + "expression": "[0.3.0,99999.0.0)", + "define": "NADEMOFU" } ], "noEngineReferences": false diff --git a/Internal/ErrorReporter/Editor/ErrorReportingInitializerProcessor.cs b/Internal/ErrorReporter/Editor/ErrorReportingInitializerProcessor.cs index 603545a69..d634c58de 100644 --- a/Internal/ErrorReporter/Editor/ErrorReportingInitializerProcessor.cs +++ b/Internal/ErrorReporter/Editor/ErrorReportingInitializerProcessor.cs @@ -1,22 +1,29 @@ using System.Collections.Generic; -using Anatawa12.ApplyOnPlay; using UnityEngine; using VRC.SDK3.Avatars.Components; using VRC.SDKBase.Editor.BuildPipeline; +#if !NADEMOFU +using Anatawa12.ApplyOnPlay; +#endif namespace Anatawa12.AvatarOptimizer.ErrorReporting { /// /// Initializes Error Reporting System /// - internal class ErrorReportingInitializerProcessor : IVRCSDKPreprocessAvatarCallback, IApplyOnPlayCallback, IManualBakeFinalizer + internal class ErrorReportingInitializerProcessor : IVRCSDKPreprocessAvatarCallback +#if !NADEMOFU + , IApplyOnPlayCallback, IManualBakeFinalizer +#endif { public int callbackOrder => int.MinValue; public string CallbackName => "Error Reporting Initialization"; public string CallbackId => "com.anatawa12.error-reporting"; +#if !NADEMOFU public bool ApplyOnPlay(GameObject avatarGameObject, ApplyReason reason) => OnPreprocessAvatar(avatarGameObject); +#endif public bool OnPreprocessAvatar(GameObject avatarGameObject) { diff --git a/Internal/ErrorReporter/Editor/com.anatawa12.avatar-optimizer.internal.error-reporter.editor.asmdef b/Internal/ErrorReporter/Editor/com.anatawa12.avatar-optimizer.internal.error-reporter.editor.asmdef index 726a9350d..93c4042e1 100644 --- a/Internal/ErrorReporter/Editor/com.anatawa12.avatar-optimizer.internal.error-reporter.editor.asmdef +++ b/Internal/ErrorReporter/Editor/com.anatawa12.avatar-optimizer.internal.error-reporter.editor.asmdef @@ -19,6 +19,12 @@ ], "autoReferenced": false, "defineConstraints": [], - "versionDefines": [], + "versionDefines": [ + { + "name": "nadena.dev.ndmf", + "expression": "[0.3.0,99999.0.0)", + "define": "NADEMOFU" + } + ], "noEngineReferences": false } \ No newline at end of file