From 40ca051a936421af434dace7729df780ca51cf3e Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Tue, 3 Oct 2023 16:31:51 +0900 Subject: [PATCH 1/4] perf: reduce number of BlendShapes to be saved Since this commit, MeshInfo2.Vertices no longer save meaningless blendShapes in the vertices --- Editor/Processors/SkinnedMeshes/MeshInfo2.cs | 23 ++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Editor/Processors/SkinnedMeshes/MeshInfo2.cs b/Editor/Processors/SkinnedMeshes/MeshInfo2.cs index 8c1744889..f993bbd6a 100644 --- a/Editor/Processors/SkinnedMeshes/MeshInfo2.cs +++ b/Editor/Processors/SkinnedMeshes/MeshInfo2.cs @@ -161,7 +161,7 @@ public void ReadSkinnedMesh([NotNull] Mesh mesh) BlendShapes.Add((shapeName, 0.0f)); - var frames = Vertices.Select(v => v.BlendShapes[shapeName] = new List()).ToArray(); + var shapes = new List[Vertices.Count]; for (int frame = 0; frame < mesh.GetBlendShapeFrameCount(i); frame++) { @@ -169,8 +169,19 @@ public void ReadSkinnedMesh([NotNull] Mesh mesh) var weight = mesh.GetBlendShapeFrameWeight(i, frame); for (var vertex = 0; vertex < deltaNormals.Length; vertex++) - frames[vertex].Add(new Vertex.BlendShapeFrame(weight, deltaVertices[vertex], deltaNormals[vertex], deltaTangents[vertex])); + { + if (deltaVertices[vertex] == Vector3.zero && deltaNormals[vertex] == Vector3.zero && deltaTangents[vertex] == Vector3.zero) + continue; + if (shapes[vertex] == null) + shapes[vertex] = new List(); + shapes[vertex].Add(new Vertex.BlendShapeFrame(weight, deltaVertices[vertex], + deltaNormals[vertex], deltaTangents[vertex])); + } } + + for (var vertex = 0; vertex < shapes.Length; vertex++) + if (shapes[vertex] is List shapeFrames) + Vertices[vertex].BlendShapes[shapeName] = shapeFrames; } } @@ -601,6 +612,14 @@ public bool TryGetBlendShape(string name, float weight, out Vector3 position, ou return false; } + if (frames.Count == 0) + { + position = default; + normal = default; + tangent = default; + return false; + } + if (Mathf.Abs(weight) <= 0.0001f && ZeroForWeightZero()) { position = Vector3.zero; From 986b19de8e29b4094e86af1152e06e85d72bdd23 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Tue, 3 Oct 2023 16:35:24 +0900 Subject: [PATCH 2/4] chore: optimize InternalAutoFreezeMeaninglessBlendShapeProcessor with new MeshInfo2 implementation --- .../InternalAutoFreezeMeaninglessBlendShapeProcessor.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Editor/Processors/SkinnedMeshes/InternalAutoFreezeMeaninglessBlendShapeProcessor.cs b/Editor/Processors/SkinnedMeshes/InternalAutoFreezeMeaninglessBlendShapeProcessor.cs index 00f98b4ca..70d255bf1 100644 --- a/Editor/Processors/SkinnedMeshes/InternalAutoFreezeMeaninglessBlendShapeProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/InternalAutoFreezeMeaninglessBlendShapeProcessor.cs @@ -17,8 +17,7 @@ public override void Process(OptimizerSession session, MeshInfo2 target) var meaningfulBlendShapes = new HashSet(); foreach (var vertex in target.Vertices) - foreach (var kvp in vertex.BlendShapes.Where(kvp => kvp.Value != default)) - meaningfulBlendShapes.Add(kvp.Key); + meaningfulBlendShapes.UnionWith(vertex.BlendShapes.Keys); var freezeBlendShape = Target.GetComponent(); var serialized = new SerializedObject(freezeBlendShape); From d707fbf3ae9ed8b940133811150d3db093daa28f Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Tue, 3 Oct 2023 16:45:53 +0900 Subject: [PATCH 3/4] chore: Directly set to PrefabSafeSet in InternalAutoFreezeMeaninglessBlendShapeProcessor --- ...nternalAutoFreezeMeaninglessBlendShapeProcessor.cs | 10 +++------- Internal/PrefabSafeSet/Runtime/PrefabSafeSet.cs | 11 +++++++++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Editor/Processors/SkinnedMeshes/InternalAutoFreezeMeaninglessBlendShapeProcessor.cs b/Editor/Processors/SkinnedMeshes/InternalAutoFreezeMeaninglessBlendShapeProcessor.cs index 70d255bf1..d5190d5a5 100644 --- a/Editor/Processors/SkinnedMeshes/InternalAutoFreezeMeaninglessBlendShapeProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/InternalAutoFreezeMeaninglessBlendShapeProcessor.cs @@ -20,13 +20,9 @@ public override void Process(OptimizerSession session, MeshInfo2 target) meaningfulBlendShapes.UnionWith(vertex.BlendShapes.Keys); var freezeBlendShape = Target.GetComponent(); - var serialized = new SerializedObject(freezeBlendShape); - var editorUtil = PrefabSafeSet.EditorUtil.Create( - serialized.FindProperty(nameof(FreezeBlendShape.shapeKeysSet)), - 0, p => p.stringValue, (p, v) => p.stringValue = v); - foreach (var (meaningLess, _) in target.BlendShapes.Where(x => !meaningfulBlendShapes.Contains(x.name))) - editorUtil.GetElementOf(meaningLess).EnsureAdded(); - serialized.ApplyModifiedPropertiesWithoutUndo(); + var set = freezeBlendShape.shapeKeysSet.GetAsSet(); + set.UnionWith(target.BlendShapes.Where(x => !meaningfulBlendShapes.Contains(x.name)).Select(x => x.name)); + freezeBlendShape.shapeKeysSet.SetValueNonPrefab(set); } // nothing to do diff --git a/Internal/PrefabSafeSet/Runtime/PrefabSafeSet.cs b/Internal/PrefabSafeSet/Runtime/PrefabSafeSet.cs index 81936bcaf..1f0ca42e2 100644 --- a/Internal/PrefabSafeSet/Runtime/PrefabSafeSet.cs +++ b/Internal/PrefabSafeSet/Runtime/PrefabSafeSet.cs @@ -81,6 +81,17 @@ protected PrefabSafeSet(Object outerObject) #endif } + public void SetValueNonPrefab(IEnumerable values) + { +#if UNITY_EDITOR + if (OuterObject && UnityEditor.PrefabUtility.IsPartOfPrefabInstance(OuterObject) + && UnityEditor.PrefabUtility.IsPartOfAnyPrefab(OuterObject)) + throw new InvalidOperationException("You cannot set value to Prefab Instance or Prefab"); + Debug.Assert(prefabLayers.Length == 0); +#endif + mainSet = values.ToArray(); + } + public HashSet GetAsSet() { var result = new HashSet(mainSet.Where(x => x.IsNotNull())); From 8977980e264228ed88d12811bcb2ebbf9116d4ef Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Tue, 3 Oct 2023 16:57:04 +0900 Subject: [PATCH 4/4] docs(changelog): Significant Performance Improvements with small code changes --- CHANGELOG-PRERELEASE.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-PRERELEASE.md b/CHANGELOG-PRERELEASE.md index 1544db7eb..97a5bfe25 100644 --- a/CHANGELOG-PRERELEASE.md +++ b/CHANGELOG-PRERELEASE.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog]. ## [Unreleased] ### Added +- Significant Performance Improvements with small code changes `#523` ### Changed diff --git a/CHANGELOG.md b/CHANGELOG.md index 97f81ccde..b8a658484 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ The format is based on [Keep a Changelog]. - In this section, there are for debugging GC Objects `#464` - Avoid Name Conflict in MergeBone `#467` - Full EditMode Preview of RemoveMesh Components `#500` +- Significant Performance Improvements with small code changes `#523` ### Changed - Improved 'Remove Unused Objects' `#401`