From 76d5f882ebe29e63f3620f52f76c075a46eee8dd Mon Sep 17 00:00:00 2001 From: bd_ Date: Sun, 23 Jun 2024 10:09:51 +0900 Subject: [PATCH] chore: implement preview refresh (#893) * chore: implement refresh for ScaleAdjusterPreview * chore: implement refresh in ShapeChangerPreview --- Editor/ScaleAdjuster/ScaleAdjusterPreview.cs | 17 ++++- Editor/ShapeChanger/ShapeChangerPreview.cs | 79 ++++++++++++++++---- 2 files changed, 78 insertions(+), 18 deletions(-) diff --git a/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs b/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs index d2625888..046495d8 100644 --- a/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs +++ b/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs @@ -82,8 +82,21 @@ namespace nadena.dev.modular_avatar.core.editor { } - public RenderAspects Reads => RenderAspects.Shapes; - public RenderAspects WhatChanged => RenderAspects.Shapes; + public RenderAspects Reads => 0; + + // We only change things in OnFrame, so downstream nodes will need to keep track of changes to these bones and + // blendshapes themselves. + public RenderAspects WhatChanged => 0; + + public Task Refresh + ( + IEnumerable<(Renderer, Renderer)> proxyPairs, + ComputeContext context, + RenderAspects updatedAspects + ) + { + return Task.FromResult((IRenderFilterNode)this); + } public void OnFrame(Renderer original, Renderer proxy) { diff --git a/Editor/ShapeChanger/ShapeChangerPreview.cs b/Editor/ShapeChanger/ShapeChangerPreview.cs index 96940d65..5932705e 100644 --- a/Editor/ShapeChanger/ShapeChangerPreview.cs +++ b/Editor/ShapeChanger/ShapeChangerPreview.cs @@ -57,11 +57,11 @@ namespace nadena.dev.modular_avatar.core.editor IEnumerable<(Renderer, Renderer)> proxyPairs, ComputeContext context) { - var node = new Node(); + var node = new Node(group); try { - await node.Init(group, proxyPairs, context); + await node.Init(proxyPairs, context); } catch (Exception e) { @@ -74,9 +74,17 @@ namespace nadena.dev.modular_avatar.core.editor private class Node : IRenderFilterNode { + private readonly RenderGroup _group; + private Mesh _generatedMesh = null; private ImmutableList _changers; + private HashSet _toDelete; + internal Node(RenderGroup group) + { + _group = group; + } + private bool IsChangerActive(ModularAvatarShapeChanger changer, ComputeContext context) { if (changer == null) return false; @@ -91,34 +99,74 @@ namespace nadena.dev.modular_avatar.core.editor } } - public async Task Init(RenderGroup group, IEnumerable<(Renderer, Renderer)> renderers, - ComputeContext context) + private HashSet GetToDeleteSet(SkinnedMeshRenderer proxy, ComputeContext context) { - var (original, proxy) = renderers.First(); + _changers = _group.GetData>(); - if (original == null || proxy == null) return; - if (!(proxy is SkinnedMeshRenderer smr)) return; - - _changers = group.GetData>(); - - HashSet toDelete = new HashSet(); - var mesh = smr.sharedMesh; + var toDelete = new HashSet(); + var mesh = context.Observe(proxy.sharedMesh); foreach (var changer in _changers) { + context.Observe(changer); + if (!IsChangerActive(changer, context)) continue; foreach (var shape in changer.Shapes) - { if (shape.ChangeType == ShapeChangeType.Delete) { var index = mesh.GetBlendShapeIndex(shape.ShapeName); if (index < 0) continue; toDelete.Add(index); } - } } + return toDelete; + } + + public async Task Init( + IEnumerable<(Renderer, Renderer)> renderers, + ComputeContext context + ) + { + var (original, proxy) = renderers.First(); + + if (original == null || proxy == null) return; + if (!(proxy is SkinnedMeshRenderer smr)) return; + + await Init(smr, context, GetToDeleteSet(smr, context)); + } + + public async Task Refresh(IEnumerable<(Renderer, Renderer)> proxyPairs, + ComputeContext context, RenderAspects updatedAspects) + { + if ((updatedAspects & RenderAspects.Mesh) != 0) return null; + + var (original, proxy) = proxyPairs.First(); + + if (original == null || proxy == null) return null; + if (!(proxy is SkinnedMeshRenderer smr)) return null; + + var toDelete = GetToDeleteSet(smr, context); + if (toDelete.Count == _toDelete.Count && toDelete.All(_toDelete.Contains)) + { + return this; + } + + var node = new Node(_group); + await node.Init(smr, context, toDelete); + return node; + } + + public async Task Init( + SkinnedMeshRenderer proxy, + ComputeContext context, + HashSet toDelete + ) + { + _toDelete = toDelete; + var mesh = proxy.sharedMesh; + if (toDelete.Count > 0) { mesh = Object.Instantiate(mesh); @@ -162,8 +210,7 @@ namespace nadena.dev.modular_avatar.core.editor mesh.SetTriangles(tris, subMesh, false, baseVertex: baseVertex); } - - smr.sharedMesh = mesh; + _generatedMesh = mesh; } }