diff --git a/CHANGELOG-PRERELEASE.md b/CHANGELOG-PRERELEASE.md index 8c3dd6aa6..27954450b 100644 --- a/CHANGELOG-PRERELEASE.md +++ b/CHANGELOG-PRERELEASE.md @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog]. ### Removed ### Fixed +- Remove Zero Sized Polygon may remove small polygons `#1098` ### Security diff --git a/CHANGELOG.md b/CHANGELOG.md index abb50c546..54565caa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The format is based on [Keep a Changelog]. ### Fixed - BlendTree with NormalizedBlendValues Broken with MergeBlendTree `#1096` +- Remove Zero Sized Polygon may remove small polygons `#1098` ### Security diff --git a/Editor/Processors/RemoveZeroSizedPolygonProcessor.cs b/Editor/Processors/RemoveZeroSizedPolygonProcessor.cs index 43a0da659..efed92bed 100644 --- a/Editor/Processors/RemoveZeroSizedPolygonProcessor.cs +++ b/Editor/Processors/RemoveZeroSizedPolygonProcessor.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes; using nadena.dev.ndmf; using UnityEngine; @@ -24,40 +25,14 @@ private static void Process(MeshInfo2 meshInfo2, RemoveZeroSizedPolygon _) { foreach (var subMesh in meshInfo2.SubMeshes) { - var dstI = 0; - for (var srcI = 0; srcI < subMesh.Triangles.Count; srcI += 3) + subMesh.RemovePrimitives("RemoveZeroSizedPolygon", poly => { - if (!IsPolygonEmpty(subMesh.Triangles[srcI], subMesh.Triangles[srcI + 1], subMesh.Triangles[srcI + 2])) - { - subMesh.Triangles[dstI] = subMesh.Triangles[srcI]; - subMesh.Triangles[dstI + 1] = subMesh.Triangles[srcI + 1]; - subMesh.Triangles[dstI + 2] = subMesh.Triangles[srcI + 2]; - dstI += 3; - } - } - - subMesh.Triangles.RemoveRange(dstI, subMesh.Triangles.Count - dstI); + if (poly.Any(v => v.BlendShapes.Count != 0)) return false; + var first = poly[0]; + var firstWeights = new HashSet<(Bone bone, float weight)>(first.BoneWeights); + return poly.Skip(1).All(v => first.Position.Equals(v.Position) && firstWeights.SetEquals(v.BoneWeights)); + }); } } - - private static bool IsPolygonEmpty(Vertex a, Vertex b, Vertex c) - { - // BlendShapes are hard to check so disallow it - // TODO: check BlendShape delta is same - if (a.BlendShapes.Count != 0) return false; - if (b.BlendShapes.Count != 0) return false; - if (c.BlendShapes.Count != 0) return false; - - // check three points are at same position - // TODO: should we use cross product instead? - if (a.Position != b.Position) return false; - if (a.Position != c.Position) return false; - - // check bone and bone weights are same - var aWeights = new HashSet<(Bone bone, float weight)>(a.BoneWeights); - if (!aWeights.SetEquals(b.BoneWeights)) return false; - if (!aWeights.SetEquals(c.BoneWeights)) return false; - return true; - } } -} \ No newline at end of file +}