From 7dfb44c5146b112cf4ef46ae88bcdd5a58d678ba Mon Sep 17 00:00:00 2001 From: poi-vrc <77053052+poi-vrc@users.noreply.github.com> Date: Mon, 4 Sep 2023 23:12:32 +0800 Subject: [PATCH] feat: animator merging --- .../VRChat/VRCMergeAnimLayerWearableModule.cs | 136 ++++++++++++++++++ .../VRCMergeAnimLayerWearableModule.cs.meta | 11 ++ 2 files changed, 147 insertions(+) create mode 100644 Packages/com.chocopoi.vrc.dressingtools/Editor/Integrations/VRChat/VRCMergeAnimLayerWearableModule.cs create mode 100644 Packages/com.chocopoi.vrc.dressingtools/Editor/Integrations/VRChat/VRCMergeAnimLayerWearableModule.cs.meta diff --git a/Packages/com.chocopoi.vrc.dressingtools/Editor/Integrations/VRChat/VRCMergeAnimLayerWearableModule.cs b/Packages/com.chocopoi.vrc.dressingtools/Editor/Integrations/VRChat/VRCMergeAnimLayerWearableModule.cs new file mode 100644 index 00000000..6178dd34 --- /dev/null +++ b/Packages/com.chocopoi.vrc.dressingtools/Editor/Integrations/VRChat/VRCMergeAnimLayerWearableModule.cs @@ -0,0 +1,136 @@ +/* + * File: VRCMergeAnimLayerWearableModule.cs + * Project: DressingTools + * Created Date: Tuesday, 29th Aug 2023, 02:53:11 pm + * Author: chocopoi (poi@chocopoi.com) + * ----- + * Copyright (c) 2023 chocopoi + * + * This file is part of DressingTools. + * + * DressingTools is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * DressingTools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with DressingTools. If not, see . + */ + +#if VRC_SDK_VRCSDK3 +using System.Diagnostics.CodeAnalysis; +using Chocopoi.DressingTools.Lib; +using Chocopoi.DressingTools.Lib.Extensibility.Providers; +using Chocopoi.DressingTools.Lib.Serialization; +using Chocopoi.DressingTools.Lib.Wearable.Modules; +using Newtonsoft.Json.Linq; +using UnityEditor; +using VRC.SDK3.Avatars.Components; + +namespace Chocopoi.DressingTools.Integration.VRChat.Modules +{ + internal class VRCMergeAnimLayerWearableModuleConfig : IModuleConfig + { + public enum AnimLayer + { + Base = 0, + Additive = 1, + Gesture = 2, + Action = 3, + FX = 4, + Sitting = 5, + TPose = 6, + IKPose = 7 + } + + public enum PathMode + { + Relative = 0, + Absolute = 1 + } + + public static readonly SerializationVersion CurrentConfigVersion = new SerializationVersion(1, 0, 0); + + public SerializationVersion version; + public AnimLayer animLayer; + public PathMode pathMode; + public bool removeAnimatorAfterApply; + public bool matchLayerWriteDefaults; + + public VRCMergeAnimLayerWearableModuleConfig() + { + version = CurrentConfigVersion; + animLayer = AnimLayer.FX; + pathMode = PathMode.Relative; + removeAnimatorAfterApply = true; + matchLayerWriteDefaults = true; + } + + private static VRCAvatarDescriptor.AnimLayerType? ToAnimLayerType(AnimLayer type) + { + switch (type) + { + case AnimLayer.Base: + return VRCAvatarDescriptor.AnimLayerType.Base; + case AnimLayer.Additive: + return VRCAvatarDescriptor.AnimLayerType.Additive; + case AnimLayer.Gesture: + return VRCAvatarDescriptor.AnimLayerType.Gesture; + case AnimLayer.Action: + return VRCAvatarDescriptor.AnimLayerType.Action; + case AnimLayer.FX: + return VRCAvatarDescriptor.AnimLayerType.FX; + case AnimLayer.Sitting: + return VRCAvatarDescriptor.AnimLayerType.Sitting; + case AnimLayer.TPose: + return VRCAvatarDescriptor.AnimLayerType.TPose; + case AnimLayer.IKPose: + return VRCAvatarDescriptor.AnimLayerType.IKPose; + } + return null; + } + } + + [InitializeOnLoad] + internal class VRCMergeAnimLayerWearableModuleProvider : WearableModuleProviderBase + { + public const string MODULE_IDENTIFIER = "com.chocopoi.dressingtools.integration.vrchat.wearable.merge-anim-layer"; + + [ExcludeFromCodeCoverage] public override string ModuleIdentifier => MODULE_IDENTIFIER; + [ExcludeFromCodeCoverage] public override string FriendlyName => "VRChat: Merge Animation Layer"; + [ExcludeFromCodeCoverage] public override int CallOrder => 6; + [ExcludeFromCodeCoverage] public override bool AllowMultiple => false; + + static VRCMergeAnimLayerWearableModuleProvider() + { + WearableModuleProviderLocator.Instance.Register(new VRCMergeAnimLayerWearableModuleProvider()); + } + + public override IModuleConfig DeserializeModuleConfig(JObject jObject) + { + // TODO: do schema check + + var version = jObject["version"].ToObject(); + if (version.Major > VRCMergeAnimLayerWearableModuleConfig.CurrentConfigVersion.Major) + { + throw new System.Exception("Incompatible VRCMergeAnimLayerWearableModuleConfig version: " + version.Major + " > " + VRCMergeAnimLayerWearableModuleConfig.CurrentConfigVersion.Major); + } + + return jObject.ToObject(); + } + + public override IModuleConfig NewModuleConfig() => new VRCMergeAnimLayerWearableModuleConfig(); + + public override bool OnApplyWearable(ApplyCabinetContext cabCtx, ApplyWearableContext wearCtx, WearableModule module) + { + var malm = (VRCMergeAnimLayerWearableModuleConfig)module.config; + + if (malm == null) + { + // no merge anim layer module + return true; + } + + return true; + } + } +} +#endif diff --git a/Packages/com.chocopoi.vrc.dressingtools/Editor/Integrations/VRChat/VRCMergeAnimLayerWearableModule.cs.meta b/Packages/com.chocopoi.vrc.dressingtools/Editor/Integrations/VRChat/VRCMergeAnimLayerWearableModule.cs.meta new file mode 100644 index 00000000..3ad4e62e --- /dev/null +++ b/Packages/com.chocopoi.vrc.dressingtools/Editor/Integrations/VRChat/VRCMergeAnimLayerWearableModule.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bdbcebd3d680646479d17ad8d8a842fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: