Skip to content

Commit

Permalink
Merge pull request #1340 from anatawa12/error-when-nested-merge-skinn…
Browse files Browse the repository at this point in the history
…ed-mesh

Error with nested merge skinned mesh
  • Loading branch information
anatawa12 authored Nov 11, 2024
2 parents 243e8c3 + 5e03490 commit 9db48cb
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-PRERELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog].
### Removed

### Fixed
- Error with nested merge skinned mesh `#1340`

### Security

Expand Down
4 changes: 2 additions & 2 deletions Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,8 @@ TexCoordStatus TexCoordStatusMax(TexCoordStatus x, TexCoordStatus y) =>

foreach (var buffer in buffers)
{
buffer.Shapes[newName] = buffer.Shapes[name];
buffer.Shapes.Remove(name);
if (buffer.Shapes.Remove(name, out var shape))
buffer.Shapes[newName] = shape;
}

mappings.Add(($"blendShape.{name}", $"blendShape.{newName}"));
Expand Down
1 change: 1 addition & 0 deletions Runtime/assembly-info.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
[assembly:InternalsVisibleTo("com.anatawa12.avatar-optimizer.editor")]
[assembly:InternalsVisibleTo("com.anatawa12.avatar-optimizer.internal.trace-and-optimize-base")]
[assembly:InternalsVisibleTo("com.anatawa12.avatar-optimizer.test.basic")]
[assembly:InternalsVisibleTo("com.anatawa12.avatar-optimizer.test.utils")]
52 changes: 52 additions & 0 deletions Test~/Basic/MergeSkinnedMeshTest.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using Anatawa12.AvatarOptimizer.AnimatorParsersV2;
using Anatawa12.AvatarOptimizer.ndmf;
using Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes;
Expand Down Expand Up @@ -243,4 +244,55 @@ public void CopySourceAnimationErrorActivenessAnimationOfSourceMismatch()
new MergeSkinnedMeshProcessor(merged).Process(context, context.GetMeshInfoFor(mergedRenderer));
});
}

[Test]
public void NestedMergeSkinnedMeshWithPartialBlendShapes()
{
var mesh1 = TestUtils.NewCubeMesh();
mesh1.AddBlendShapeFrame("mesh1", 100, TestUtils.NewCubeBlendShapeFrame((0, Vector3.up)), null, null);
var mesh2 = TestUtils.NewCubeMesh();
mesh2.AddBlendShapeFrame("mesh2", 100, TestUtils.NewCubeBlendShapeFrame((0, Vector3.right)), null, null);
var mesh3 = TestUtils.NewCubeMesh();
mesh3.AddBlendShapeFrame("mesh3", 100, TestUtils.NewCubeBlendShapeFrame((0, Vector3.forward)), null, null);

var avatar = TestUtils.NewAvatar();
var renderer1GameObject = Utils.NewGameObject("Renderer1", avatar.transform);
var renderer1 = renderer1GameObject.AddComponent<SkinnedMeshRenderer>();
renderer1.sharedMesh = mesh1;
var renderer2GameObject = Utils.NewGameObject("Renderer2", avatar.transform);
var renderer2 = renderer2GameObject.AddComponent<SkinnedMeshRenderer>();
renderer2.sharedMesh = mesh2;
var renderer3GameObject = Utils.NewGameObject("Renderer3", avatar.transform);
var renderer3 = renderer3GameObject.AddComponent<SkinnedMeshRenderer>();
renderer3.sharedMesh = mesh3;
var mergedIntermediateGameObject = Utils.NewGameObject("MergedIntermediate", avatar.transform);
var mergedIntermediateRenderer = mergedIntermediateGameObject.AddComponent<SkinnedMeshRenderer>();
var mergedFinalGameObject = Utils.NewGameObject("MergedFinal", avatar.transform);
var mergedFinalRenderer = mergedFinalGameObject.AddComponent<SkinnedMeshRenderer>();

var context = new BuildContext(avatar, null);
context.ActivateExtensionContext<Processors.MeshInfo2Context>();
context.ActivateExtensionContext<ObjectMappingContext>();
context.ActivateExtensionContext<DestroyTracker.ExtensionContext>();

var meshInfo1 = context.GetMeshInfoFor(renderer1);
var meshInfo2 = context.GetMeshInfoFor(renderer2);
var meshInfo3 = context.GetMeshInfoFor(renderer3);
var meshInfoIntermediate = context.GetMeshInfoFor(mergedIntermediateRenderer);
var meshInfoFinal = context.GetMeshInfoFor(mergedFinalRenderer);

MergeSkinnedMeshProcessor.DoMerge(context,
meshInfoIntermediate,
new[] { meshInfo1, meshInfo2 },
new[] { new[] { 0 }, new[] { 0 } },
new List<(MeshTopology, Material)>() { (MeshTopology.Triangles, null) }
);

MergeSkinnedMeshProcessor.DoMerge(context,
meshInfoFinal,
new[] { meshInfoIntermediate, meshInfo3 },
new[] { new[] { 0 }, new[] { 0 } },
new List<(MeshTopology, Material)>() { (MeshTopology.Triangles, null) }
);
}
}
11 changes: 11 additions & 0 deletions Test~/Utils/TestUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace Anatawa12.AvatarOptimizer.Test
{
public static class TestUtils
{
class DummyAvatarTagComponent : AvatarTagComponent {}

public static GameObject NewAvatar(string name = null)
{
var root = new GameObject();
Expand All @@ -20,6 +22,8 @@ public static GameObject NewAvatar(string name = null)
#if AAO_VRCSDK3_AVATARS
var descriptor = root.AddComponent<VRC.SDK3.Avatars.Components.VRCAvatarDescriptor>();
#endif
// for any AvatarTagComponent checks on the avatar
root.AddComponent<DummyAvatarTagComponent>();
return root;
}

Expand Down Expand Up @@ -126,6 +130,13 @@ public static Mesh NewCubeMesh()
mesh.SetSubMesh(0, new SubMeshDescriptor(0, 12 * 3));
return mesh;
}

public static Vector3[] NewCubeBlendShapeFrame(params (int index, Vector3 delta)[] deltas)
{
var frame = new Vector3[8];
foreach (var (index, delta) in deltas) frame[index] = delta;
return frame;
}

public static SkinnedMeshRenderer NewSkinnedMeshRenderer(Mesh mesh)
{
Expand Down

0 comments on commit 9db48cb

Please sign in to comment.