diff --git a/Scripts/Editor/Tests/MeshTests.cs b/Scripts/Editor/Tests/MeshTests.cs new file mode 100644 index 000000000..e496753c6 --- /dev/null +++ b/Scripts/Editor/Tests/MeshTests.cs @@ -0,0 +1,64 @@ +using NUnit.Framework; +using UnityEngine; +using System.Linq; + + +namespace VRM +{ + public class MeshTests + { + public static void MeshEquals(Mesh l, Mesh r) + { +#if UNITY_2017_3_OR_NEWER + Assert.AreEqual(l.indexFormat, r.indexFormat); +#endif + Assert.True(l.vertices.SequenceEqual(r.vertices)); + Assert.True(l.normals.SequenceEqual(r.normals)); + Assert.True(l.tangents.SequenceEqual(r.tangents)); + Assert.True(l.uv.SequenceEqual(r.uv)); + Assert.True(l.uv2.SequenceEqual(r.uv2)); + Assert.True(l.uv3.SequenceEqual(r.uv3)); + Assert.True(l.uv4.SequenceEqual(r.uv4)); + Assert.True(l.colors.SequenceEqual(r.colors)); + Assert.True(l.boneWeights.SequenceEqual(r.boneWeights)); + Assert.True(l.bindposes.SequenceEqual(r.bindposes)); + + Assert.AreEqual(l.subMeshCount, r.subMeshCount); + for (int i = 0; i < l.subMeshCount; ++i) + { + Assert.True(l.GetIndices(i).SequenceEqual(r.GetIndices(i))); + } + + Assert.AreEqual(l.blendShapeCount, r.blendShapeCount); + for (int i = 0; i < l.blendShapeCount; ++i) + { + Assert.AreEqual(l.GetBlendShapeName(i), r.GetBlendShapeName(i)); + Assert.AreEqual(l.GetBlendShapeFrameCount(i), r.GetBlendShapeFrameCount(i)); + Assert.AreEqual(l.GetBlendShapeFrameWeight(i, 0), r.GetBlendShapeFrameWeight(i, 0)); + + var lv = l.vertices; + var ln = l.vertices; + var lt = l.vertices; + var rv = r.vertices; + var rn = r.vertices; + var rt = r.vertices; + l.GetBlendShapeFrameVertices(i, 0, lv, ln, lt); + r.GetBlendShapeFrameVertices(i, 0, rv, rn, rt); + Assert.True(lv.SequenceEqual(rv)); + Assert.True(ln.SequenceEqual(rn)); + Assert.True(lt.SequenceEqual(rt)); + } + } + + [Test] + public void MeshCopyTest() + { + var src = new Mesh(); + src.AddBlendShapeFrame("blendShape", 100.0f, null, null, null); + + var dst = src.Copy(true); + + MeshEquals(src, dst); + } + } +} diff --git a/Scripts/Editor/Tests/MeshTests.cs.meta b/Scripts/Editor/Tests/MeshTests.cs.meta new file mode 100644 index 000000000..2b91dd684 --- /dev/null +++ b/Scripts/Editor/Tests/MeshTests.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0fa06e6e83b995a49a1357924b9ef23e +timeCreated: 1533274120 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/SkinnedMeshUtility/BoneNormalizer.cs b/Scripts/SkinnedMeshUtility/BoneNormalizer.cs index e5c77acdb..3b953c08d 100644 --- a/Scripts/SkinnedMeshUtility/BoneNormalizer.cs +++ b/Scripts/SkinnedMeshUtility/BoneNormalizer.cs @@ -153,7 +153,7 @@ namespace VRM // Before bake, bind no weight bones //Debug.LogFormat("no weight: {0}", srcMesh.name); - srcMesh = srcMesh.Copy(); + srcMesh = srcMesh.Copy(true); var bw = new BoneWeight { boneIndex0 = 0, @@ -175,7 +175,7 @@ namespace VRM } // BakeMesh - var mesh = srcMesh.Copy(); + var mesh = srcMesh.Copy(false); mesh.name = srcMesh.name + ".baked"; srcRenderer.BakeMesh(mesh); mesh.boneWeights = srcMesh.boneWeights; // restore weights. clear when BakeMesh @@ -328,7 +328,7 @@ namespace VRM // Meshに乗っているボーンの姿勢を適用する var dstFilter = dst.gameObject.AddComponent(); - var dstMesh = srcFilter.sharedMesh.Copy(); + var dstMesh = srcFilter.sharedMesh.Copy(false); dstMesh.ApplyRotationAndScale(src.localToWorldMatrix); dstFilter.sharedMesh = dstMesh; diff --git a/Scripts/SkinnedMeshUtility/MeshExtensions.cs b/Scripts/SkinnedMeshUtility/MeshExtensions.cs index df28c98ee..bf4a24cfe 100644 --- a/Scripts/SkinnedMeshUtility/MeshExtensions.cs +++ b/Scripts/SkinnedMeshUtility/MeshExtensions.cs @@ -6,7 +6,7 @@ namespace VRM { public static class MeshExtensions { - public static Mesh Copy(this Mesh src) + public static Mesh Copy(this Mesh src, bool copyBlendShape) { var dst = new Mesh(); dst.name = src.name + "(copy)"; @@ -33,6 +33,24 @@ namespace VRM dst.RecalculateBounds(); + if (copyBlendShape) + { + var vertices = src.vertices; + var normals = src.normals; + var tangents = src.tangents.Select(x => (Vector3)x).ToArray(); + for (int i = 0; i < src.blendShapeCount; ++i) + { + src.GetBlendShapeFrameVertices(i, 0, vertices, normals, tangents); + dst.AddBlendShapeFrame( + src.GetBlendShapeName(i), + src.GetBlendShapeFrameWeight(i, 0), + vertices, + normals, + tangents + ); + } + } + return dst; }