From 2cd29895abfe20fe0de0a3366283a00293636b5b Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 30 Jul 2018 16:40:14 +0900 Subject: [PATCH] Bind bone before normalization --- Scripts/SkinnedMeshUtility/BoneNormalizer.cs | 79 ++++++++++++-------- Scripts/SkinnedMeshUtility/MeshExtensions.cs | 19 ++--- 2 files changed, 56 insertions(+), 42 deletions(-) diff --git a/Scripts/SkinnedMeshUtility/BoneNormalizer.cs b/Scripts/SkinnedMeshUtility/BoneNormalizer.cs index 48e3cb661..f8f213584 100644 --- a/Scripts/SkinnedMeshUtility/BoneNormalizer.cs +++ b/Scripts/SkinnedMeshUtility/BoneNormalizer.cs @@ -140,42 +140,20 @@ namespace VRM // clear blendShape var srcMesh = srcRenderer.sharedMesh; + var originalSrcMesh = srcMesh; for (int i = 0; i < srcMesh.blendShapeCount; ++i) { srcRenderer.SetBlendShapeWeight(i, 0); } - // BakeMesh - var mesh = srcMesh.Copy(); - mesh.name = srcMesh.name + ".baked"; - srcRenderer.BakeMesh(mesh); - - //var m = src.localToWorldMatrix; - var m = default(Matrix4x4); - m.SetTRS(Vector3.zero, src.rotation, Vector3.one); - - mesh.vertices = mesh.vertices.Select(x => m.MultiplyPoint(x)).ToArray(); - mesh.normals = mesh.normals.Select(x => m.MultiplyVector(x).normalized).ToArray(); - - mesh.uv = srcMesh.uv; - mesh.tangents = srcMesh.tangents; - mesh.subMeshCount = srcMesh.subMeshCount; - for (int i = 0; i < srcMesh.subMeshCount; ++i) - { - mesh.SetIndices(srcMesh.GetIndices(i), srcMesh.GetTopology(i), i); - } - - // boneweights var bones = srcRenderer.bones.Select(x => boneMap[x]).ToArray(); - var hasBoneWeight = bones.Length > 0; - if (hasBoneWeight) + var hasBoneWeight = srcRenderer.bones!=null && srcRenderer.bones.Length > 0; + if (!hasBoneWeight) { - mesh.boneWeights = srcMesh.boneWeights; - } - else - { - Debug.LogFormat("no weight: {0}", srcMesh.name); - bones = new[] { boneMap[srcRenderer.transform] }; + // Before bake, bind no weight bones + //Debug.LogFormat("no weight: {0}", srcMesh.name); + + srcMesh = srcMesh.Copy(); var bw = new BoneWeight { boneIndex0 = 0, @@ -187,9 +165,38 @@ namespace VRM weight2 = 0.0f, weight3 = 0.0f, }; - mesh.boneWeights = Enumerable.Range(0, srcMesh.vertexCount).Select(x => bw).ToArray(); + srcMesh.boneWeights = Enumerable.Range(0, srcMesh.vertexCount).Select(x => bw).ToArray(); + srcMesh.bindposes = new Matrix4x4[] { Matrix4x4.identity }; + + srcRenderer.rootBone = srcRenderer.transform; + srcRenderer.bones = new[] { srcRenderer.transform }; + srcRenderer.sharedMesh = srcMesh; } + // BakeMesh + var mesh = srcMesh.Copy(); + mesh.name = srcMesh.name + ".baked"; + srcRenderer.BakeMesh(mesh); + + //var m = src.localToWorldMatrix; // include scaling + var m = default(Matrix4x4); + m.SetTRS(Vector3.zero, src.rotation, Vector3.one); // without scaling + + mesh.vertices = mesh.vertices.Select(x => m.MultiplyPoint(x)).ToArray(); + mesh.normals = mesh.normals.Select(x => m.MultiplyVector(x).normalized).ToArray(); + + mesh.uv = srcMesh.uv; + mesh.tangents = srcMesh.tangents; + mesh.subMeshCount = srcMesh.subMeshCount; + for (int i = 0; i < srcMesh.subMeshCount; ++i) + { + mesh.SetIndices(srcMesh.GetIndices(i), srcMesh.GetTopology(i), i); + } + mesh.boneWeights = srcMesh.boneWeights; + + // + // BlendShapes + // var meshVertices = mesh.vertices; var meshNormals = mesh.normals; var meshTangents = mesh.tangents.Select(x => (Vector3)x).ToArray(); @@ -290,17 +297,23 @@ namespace VRM // recalc bindposes mesh.bindposes = bones.Select(x => x.worldToLocalMatrix * dst.transform.localToWorldMatrix).ToArray(); - mesh.RecalculateBounds(); var dstRenderer = dst.gameObject.AddComponent(); dstRenderer.sharedMaterials = srcRenderer.sharedMaterials; - dstRenderer.sharedMesh = mesh; - dstRenderer.bones = bones; if (srcRenderer.rootBone != null) { dstRenderer.rootBone = boneMap[srcRenderer.rootBone]; } + dstRenderer.bones = bones; + dstRenderer.sharedMesh = mesh; + + if (!hasBoneWeight) + { + // restore bones + srcRenderer.bones = new Transform[] { }; + srcRenderer.sharedMesh = originalSrcMesh; + } } /// diff --git a/Scripts/SkinnedMeshUtility/MeshExtensions.cs b/Scripts/SkinnedMeshUtility/MeshExtensions.cs index e95143feb..df28c98ee 100644 --- a/Scripts/SkinnedMeshUtility/MeshExtensions.cs +++ b/Scripts/SkinnedMeshUtility/MeshExtensions.cs @@ -17,12 +17,13 @@ namespace VRM dst.vertices = src.vertices; dst.normals = src.normals; dst.tangents = src.tangents; - - if (src.colors != null && src.colors.Length > 0) dst.colors = src.colors; - if (src.uv != null && src.uv.Length > 0) dst.uv = src.uv; - if (src.uv2 != null && src.uv2.Length > 0) dst.uv2 = src.uv2; - if (src.uv3 != null && src.uv3.Length > 0) dst.uv3 = src.uv3; - if (src.uv4 != null && src.uv4.Length > 0) dst.uv4 = src.uv4; + dst.colors = src.colors; + dst.uv = src.uv; + dst.uv2 = src.uv2; + dst.uv3 = src.uv3; + dst.uv4 = src.uv4; + dst.boneWeights = src.boneWeights; + dst.bindposes = src.bindposes; dst.subMeshCount = src.subMeshCount; for (int i = 0; i < dst.subMeshCount; ++i) @@ -30,19 +31,19 @@ namespace VRM dst.SetIndices(src.GetIndices(i), src.GetTopology(i), i); } + dst.RecalculateBounds(); + return dst; } public static void ApplyRotationAndScale(this Mesh src, Matrix4x4 m) { - m.SetColumn(3, new Vector4(0, 0, 0, 1)); + m.SetColumn(3, new Vector4(0, 0, 0, 1)); // remove translation src.ApplyMatrix(m); } public static void ApplyMatrix(this Mesh src, Matrix4x4 m) { - m.SetColumn(3, new Vector4(0, 0, 0, 1)); - src.vertices = src.vertices.Select(x => m.MultiplyPoint(x)).ToArray(); if (src.normals != null && src.normals.Length > 0) {