From 37efd623b321fba3fb2a80c1be906a9607cc437a Mon Sep 17 00:00:00 2001 From: bd_ Date: Sun, 4 Aug 2024 19:09:43 -0700 Subject: [PATCH] feat: improvements to ParameterInfo (#312) * fix: some issues preventing preview overrides from changing object enable states * feat: add default value to ProvidedParameter * feat: Add support for ComputeContext invalidation to ParameterInfo * chore: CHANGELOG update --- CHANGELOG.md | 3 +++ Editor/ChangeStream/ObjectWatcher.cs | 1 + Editor/ChangeStream/ShadowGameObject.cs | 6 +++-- Editor/PreviewSystem/ComputeContext.cs | 13 +++++++++ Editor/PreviewSystem/ProxyManager.cs | 4 +-- .../Rendering/ProxyObjectController.cs | 4 ++- .../Rendering/ShadowBoneManager.cs | 5 +++- .../IParameterProvider.cs | 5 ++++ .../ParameterIntrospection/ParameterInfo.cs | 27 ++++++++++++++++--- .../AvatarDescriptorProvider.cs | 1 + 10 files changed, 60 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68617130..6ef41dc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- [#312] Added a default value field to ProvidedParameter +- [#312] Added support for invalidating ComputeContext to ParameterInfo ### Fixed +- [#312] Fix issues preventing preview overrides from changing object enable states ### Changed diff --git a/Editor/ChangeStream/ObjectWatcher.cs b/Editor/ChangeStream/ObjectWatcher.cs index 5549061d..0dc58f8f 100644 --- a/Editor/ChangeStream/ObjectWatcher.cs +++ b/Editor/ChangeStream/ObjectWatcher.cs @@ -315,6 +315,7 @@ public void Dispose() private void DoDispose() { + if (_orig == null) return; foreach (var orig in _orig) orig.Dispose(); } } diff --git a/Editor/ChangeStream/ShadowGameObject.cs b/Editor/ChangeStream/ShadowGameObject.cs index 547be1fa..cd60b199 100644 --- a/Editor/ChangeStream/ShadowGameObject.cs +++ b/Editor/ChangeStream/ShadowGameObject.cs @@ -58,6 +58,8 @@ internal class ShadowHierarchy internal IDisposable RegisterRootSetListener(ListenerSet.Filter filter, ComputeContext ctx) { + if (ctx.IsInvalidated) return new NullDisposable(); + return _rootSetListener.Register(filter, ctx); } @@ -67,7 +69,7 @@ internal IDisposable RegisterGameObjectListener( ComputeContext ctx ) { - if (targetObject == null) return new NullDisposable(); + if (targetObject == null || ctx.IsInvalidated) return new NullDisposable(); ShadowGameObject shadowObject = ActivateShadowObject(targetObject); @@ -79,7 +81,7 @@ internal IDisposable RegisterObjectListener(UnityObject targetComponent, ComputeContext ctx ) { - if (targetComponent == null) return new NullDisposable(); + if (targetComponent == null || ctx.IsInvalidated) return new NullDisposable(); if (!_otherObjects.TryGetValue(targetComponent.GetInstanceID(), out var shadowComponent)) { diff --git a/Editor/PreviewSystem/ComputeContext.cs b/Editor/PreviewSystem/ComputeContext.cs index c9280290..2602d580 100644 --- a/Editor/PreviewSystem/ComputeContext.cs +++ b/Editor/PreviewSystem/ComputeContext.cs @@ -2,6 +2,7 @@ using System; using System.Threading.Tasks; +using JetBrains.Annotations; #endregion @@ -13,8 +14,14 @@ namespace nadena.dev.ndmf.preview /// public sealed class ComputeContext { + [PublicAPI] public static ComputeContext NullContext { get; } private readonly TaskCompletionSource _invalidater = new(); + static ComputeContext() + { + NullContext = new ComputeContext(null); + } + /// /// An Action which can be used to invalidate this compute context (possibly triggering a recompute). /// @@ -34,6 +41,12 @@ internal ComputeContext() OnInvalidate = _invalidater.Task; } + private ComputeContext(object nullToken) + { + Invalidate = () => { }; + OnInvalidate = Task.CompletedTask; + } + /// /// Invalidate the `other` compute context when this compute context is invalidated. /// diff --git a/Editor/PreviewSystem/ProxyManager.cs b/Editor/PreviewSystem/ProxyManager.cs index a5056272..1626059c 100644 --- a/Editor/PreviewSystem/ProxyManager.cs +++ b/Editor/PreviewSystem/ProxyManager.cs @@ -41,8 +41,8 @@ private static void OnPreCull(Camera cam) foreach (var (original, replacement) in sess.GetReplacements()) { - if (original == null || replacement == null || !original.enabled || - !original.gameObject.activeInHierarchy) + // TODO: Optimize to cull meshes that don't have an active-state override registered + if (original == null || replacement == null || !original.enabled) { if (replacement != null) replacement.forceRenderingOff = true; continue; diff --git a/Editor/PreviewSystem/Rendering/ProxyObjectController.cs b/Editor/PreviewSystem/Rendering/ProxyObjectController.cs index e1aad861..8e0136df 100644 --- a/Editor/PreviewSystem/Rendering/ProxyObjectController.cs +++ b/Editor/PreviewSystem/Rendering/ProxyObjectController.cs @@ -122,6 +122,8 @@ internal bool OnPreFrame() var target = _replacementRenderer; var original = _originalRenderer; + target.gameObject.SetActive(original.enabled && original.gameObject.activeInHierarchy); + SkinnedMeshRenderer smr = null; if (_originalRenderer is SkinnedMeshRenderer smr_) { @@ -154,7 +156,7 @@ internal bool OnPreFrame() _replacementRenderer.sharedMaterials = _originalRenderer.sharedMaterials; if (target.gameObject.scene != original.gameObject.scene && - original.gameObject.scene.IsValid()) + original.gameObject.scene.IsValid() && target.transform.parent == null) { SceneManager.MoveGameObjectToScene(target.gameObject, original.gameObject.scene); } diff --git a/Editor/PreviewSystem/Rendering/ShadowBoneManager.cs b/Editor/PreviewSystem/Rendering/ShadowBoneManager.cs index 3d599ffb..86206369 100644 --- a/Editor/PreviewSystem/Rendering/ShadowBoneManager.cs +++ b/Editor/PreviewSystem/Rendering/ShadowBoneManager.cs @@ -155,7 +155,10 @@ private static Transform CopyState(BoneState entry) entry.proxy.localPosition = t.localPosition; entry.proxy.localRotation = t.localRotation; entry.proxy.localScale = t.localScale; - + + if (entry.proxy.parent == null && entry.proxy.gameObject.scene != t.gameObject.scene) + SceneManager.MoveGameObjectToScene(entry.proxy.gameObject, t.gameObject.scene); + return parent; } } diff --git a/Editor/VRChat/ParameterIntrospection/IParameterProvider.cs b/Editor/VRChat/ParameterIntrospection/IParameterProvider.cs index 3ebda322..050ae1f8 100644 --- a/Editor/VRChat/ParameterIntrospection/IParameterProvider.cs +++ b/Editor/VRChat/ParameterIntrospection/IParameterProvider.cs @@ -188,6 +188,11 @@ public bool IsAnimatorOnly /// public bool WantSynced { get; set; } + /// + /// The default value of this parameter, if known. + /// + public float? DefaultValue { get; set; } + public IEnumerable SubParameters() { if (Namespace == ParameterNamespace.Animator) diff --git a/Editor/VRChat/ParameterIntrospection/ParameterInfo.cs b/Editor/VRChat/ParameterIntrospection/ParameterInfo.cs index b611739b..5a5afcd9 100644 --- a/Editor/VRChat/ParameterIntrospection/ParameterInfo.cs +++ b/Editor/VRChat/ParameterIntrospection/ParameterInfo.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using nadena.dev.ndmf.preview; using nadena.dev.ndmf.runtime; using UnityEditor; using UnityEngine; @@ -17,14 +18,20 @@ namespace nadena.dev.ndmf /// public sealed class ParameterInfo { - public static readonly ParameterInfo ForUI = new ParameterInfo(null); + public static readonly ParameterInfo ForUI = new((BuildContext)null); public static ParameterInfo ForContext(BuildContext context) { return context.GetState(ctx => new ParameterInfo(ctx)); } + public static ParameterInfo ForPreview(ComputeContext context) + { + return new ParameterInfo(context); + } + private readonly BuildContext _context; + private readonly ComputeContext _computeContext; public enum ConflictType { @@ -46,6 +53,12 @@ static void Init() private ParameterInfo(BuildContext context) { _context = context; + _computeContext = ComputeContext.NullContext; + } + + private ParameterInfo(ComputeContext ctx) + { + _computeContext = ctx; } private long _parameterCount; // used to maintain declaration order @@ -95,13 +108,15 @@ public IEnumerable GetParametersForObject(GameObject obj, Con if (!RuntimeUtil.IsAvatarRoot(obj.transform)) { + _computeContext.ObservePath(obj.transform); mappings = GetParameterRemappingsAt(obj.transform.parent.gameObject); } - foreach (var component in obj.GetComponents(typeof(Component))) + foreach (var component in _computeContext.GetComponents(obj, typeof(Component))) { if (EnhancerDatabase.Query(component, out var provider)) { + _computeContext.Observe(component); // TODO: Can we add an extract condition here? provider.RemapParameters(ref mappings, _context); } } @@ -124,10 +139,11 @@ public IEnumerable GetParametersForObject(GameObject obj, Con if (!RuntimeUtil.IsAvatarRoot(c.transform)) { + _computeContext.ObservePath(c.transform); mappings = GetParameterRemappingsAt(c.transform.parent.gameObject); } - foreach (var component in c.GetComponents(typeof(Component))) + foreach (var component in _computeContext.GetComponents(c.gameObject, typeof(Component))) { if (component == c && !includeSelf) { @@ -136,6 +152,7 @@ public IEnumerable GetParametersForObject(GameObject obj, Con if (EnhancerDatabase.Query(component, out var provider)) { + _computeContext.Observe(component); // TODO: Can we add an extract condition here? provider.RemapParameters(ref mappings, _context); } @@ -158,6 +175,8 @@ private IEnumerable GetParametersForObject(GameObject root, continue; } + _computeContext.Observe(component); // TODO: Can we add an extract condition here? + // Apply mappings first provider.RemapParameters(ref remaps, _context); @@ -255,6 +274,8 @@ private void ResolveConflict(ConflictHandler onConflict, RegisteredParameter old oldP.Parameter.IsAnimatorOnly &= newP.IsAnimatorOnly; oldP.Parameter.IsHidden &= newP.IsHidden; oldP.Parameter.WantSynced = oldP.Parameter.WantSynced || newP.WantSynced; + + oldP.Parameter.DefaultValue = newP.DefaultValue ?? oldP.Parameter.DefaultValue; } } } \ No newline at end of file diff --git a/Editor/VRChat/ParameterIntrospection/VRChatProviders/AvatarDescriptorProvider.cs b/Editor/VRChat/ParameterIntrospection/VRChatProviders/AvatarDescriptorProvider.cs index e1324c6b..71a84fb1 100644 --- a/Editor/VRChat/ParameterIntrospection/VRChatProviders/AvatarDescriptorProvider.cs +++ b/Editor/VRChat/ParameterIntrospection/VRChatProviders/AvatarDescriptorProvider.cs @@ -38,6 +38,7 @@ public IEnumerable GetSuppliedParameters(BuildContext context ) { WantSynced = p.networkSynced, + DefaultValue = p.defaultValue }; }); }