diff --git a/.github/ProjectRoot/vpm-manifest-2022.json b/.github/ProjectRoot/vpm-manifest-2022.json index 9e7156ec..fd2822c3 100644 --- a/.github/ProjectRoot/vpm-manifest-2022.json +++ b/.github/ProjectRoot/vpm-manifest-2022.json @@ -19,7 +19,7 @@ "dependencies": {} }, "nadena.dev.ndmf": { - "version": "1.5.0-alpha.2" + "version": "1.5.0-alpha.3" } } } \ No newline at end of file diff --git a/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs b/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs index f3a08032..5177a872 100644 --- a/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs +++ b/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs @@ -37,37 +37,30 @@ private static GameObject FindAvatarRootObserving(ComputeContext ctx, GameObject return null; } - public ReactiveValue<ImmutableList<RenderGroup>> TargetGroups { get; } = - ReactiveValue<ImmutableList<RenderGroup>>.Create( - "Scale Adjuster: Find targets", - async ctx => + public ImmutableList<RenderGroup> GetTargetGroups(ComputeContext ctx) + { + var scaleAdjusters = ctx.GetComponentsByType<ModularAvatarScaleAdjuster>(); + + var result = ImmutableList.CreateBuilder<RenderGroup>(); + + foreach (var adjuster in scaleAdjusters) { - var scaleAdjusters = await ctx.Observe(CommonQueries.GetComponentsByType<ModularAvatarScaleAdjuster>()); + if (adjuster == null) continue; - ImmutableList<RenderGroup>.Builder result = ImmutableList.CreateBuilder<RenderGroup>(); - - foreach (var adjuster in scaleAdjusters) - { - if (adjuster == null) continue; - - // Find parent object - // TODO: Reactive helper - var root = FindAvatarRootObserving(ctx, adjuster.gameObject); - if (root == null) continue; - - var renderers = ctx.GetComponentsInChildren<Renderer>(root, true); - - foreach (var renderer in renderers) - { - if (renderer is SkinnedMeshRenderer smr) - { - result.Add(RenderGroup.For(renderer)); - } - } - } - - return result.ToImmutable(); - }); + // Find parent object + // TODO: Reactive helper + var root = FindAvatarRootObserving(ctx, adjuster.gameObject); + if (root == null) continue; + + var renderers = ctx.GetComponentsInChildren<Renderer>(root, true); + + foreach (var renderer in renderers) + if (renderer is SkinnedMeshRenderer smr) + result.Add(RenderGroup.For(renderer)); + } + + return result.ToImmutable(); + } public Task<IRenderFilterNode> Instantiate(RenderGroup group, IEnumerable<(Renderer, Renderer)> proxyPairs, ComputeContext context) diff --git a/Editor/ShapeChanger/ShapeChangerPreview.cs b/Editor/ShapeChanger/ShapeChangerPreview.cs index 5932705e..c737439d 100644 --- a/Editor/ShapeChanger/ShapeChangerPreview.cs +++ b/Editor/ShapeChanger/ShapeChangerPreview.cs @@ -17,40 +17,38 @@ namespace nadena.dev.modular_avatar.core.editor { public class ShapeChangerPreview : IRenderFilter { - public ReactiveValue<ImmutableList<RenderGroup>> TargetGroups { get; } - = ReactiveValue<ImmutableList<RenderGroup>>.Create( - "ShapeChangerPreview.TargetGroups", async ctx => - { - var allChangers = - await ctx.Observe(CommonQueries.GetComponentsByType<ModularAvatarShapeChanger>()); + public ImmutableList<RenderGroup> GetTargetGroups(ComputeContext ctx) + { + var allChangers = ctx.GetComponentsByType<ModularAvatarShapeChanger>(); - Dictionary<Renderer, ImmutableList<ModularAvatarShapeChanger>.Builder> groups = - new Dictionary<Renderer, ImmutableList<ModularAvatarShapeChanger>.Builder>( - new ObjectIdentityComparer<Renderer>()); + var groups = + new Dictionary<Renderer, ImmutableList<ModularAvatarShapeChanger>.Builder>( + new ObjectIdentityComparer<Renderer>()); - foreach (var changer in allChangers) - { - // TODO: observe avatar root - ctx.Observe(changer); - if (!ctx.ActiveAndEnabled(changer)) continue; + foreach (var changer in allChangers) + { + if (changer == null) continue; - var target = ctx.Observe(changer.targetRenderer.Get(changer)); - var renderer = ctx.GetComponent<SkinnedMeshRenderer>(target); + // TODO: observe avatar root + if (!ctx.ActiveAndEnabled(changer)) continue; - if (renderer == null) continue; + var target = ctx.Observe(changer.targetRenderer.Get(changer)); + var renderer = ctx.GetComponent<SkinnedMeshRenderer>(target); - if (!groups.TryGetValue(renderer, out var group)) - { - group = ImmutableList.CreateBuilder<ModularAvatarShapeChanger>(); - groups[renderer] = group; - } + if (renderer == null) continue; - group.Add(changer); - } + if (!groups.TryGetValue(renderer, out var group)) + { + group = ImmutableList.CreateBuilder<ModularAvatarShapeChanger>(); + groups[renderer] = group; + } - return groups.Select(g => RenderGroup.For(g.Key).WithData(g.Value.ToImmutable())) - .ToImmutableList(); - }); + group.Add(changer); + } + + return groups.Select(g => RenderGroup.For(g.Key).WithData(g.Value.ToImmutable())) + .ToImmutableList(); + } public async Task<IRenderFilterNode> Instantiate( RenderGroup group, @@ -104,15 +102,24 @@ private HashSet<int> GetToDeleteSet(SkinnedMeshRenderer proxy, ComputeContext co _changers = _group.GetData<ImmutableList<ModularAvatarShapeChanger>>(); var toDelete = new HashSet<int>(); - var mesh = context.Observe(proxy.sharedMesh); + var mesh = context.Observe(proxy, p => p.sharedMesh, (a, b) => + { + if (a != b) + { + Debug.Log($"mesh changed {a.GetInstanceID()} -> {b.GetInstanceID()}"); + return false; + } + + return true; + }); foreach (var changer in _changers) { - context.Observe(changer); + var shapes = context.Observe(changer, c => c.Shapes.ToImmutableList(), Enumerable.SequenceEqual); if (!IsChangerActive(changer, context)) continue; - foreach (var shape in changer.Shapes) + foreach (var shape in shapes) if (shape.ChangeType == ShapeChangeType.Delete) { var index = mesh.GetBlendShapeIndex(shape.ShapeName); diff --git a/Runtime/ModularAvatarShapeChanger.cs b/Runtime/ModularAvatarShapeChanger.cs index c4f7ffdb..0b0bb8e5 100644 --- a/Runtime/ModularAvatarShapeChanger.cs +++ b/Runtime/ModularAvatarShapeChanger.cs @@ -22,6 +22,26 @@ public struct ChangedShape public string ShapeName; public ShapeChangeType ChangeType; public float Value; + + public bool Equals(ChangedShape other) + { + return ShapeName == other.ShapeName && ChangeType == other.ChangeType && Value.Equals(other.Value); + } + + public override bool Equals(object obj) + { + return obj is ChangedShape other && Equals(other); + } + + public override int GetHashCode() + { + return HashCode.Combine(ShapeName, (int)ChangeType, Value); + } + + public override string ToString() + { + return $"{ShapeName} {ChangeType} {Value}"; + } } [AddComponentMenu("Modular Avatar/MA Shape Changer")] diff --git a/package.json b/package.json index e5af1a48..8a722c98 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,6 @@ }, "vpmDependencies": { "com.vrchat.avatars": ">=3.4.0", - "nadena.dev.ndmf": ">=1.5.0-alpha.2 <2.0.0-a" + "nadena.dev.ndmf": ">=1.5.0-alpha.3 <2.0.0-a" } }