Bind bone before normalization

This commit is contained in:
ousttrue
2018-07-30 16:40:14 +09:00
parent 92501ae8ab
commit 2cd29895ab
2 changed files with 56 additions and 42 deletions

View File

@@ -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<SkinnedMeshRenderer>();
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;
}
}
/// <summary>

View File

@@ -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)
{