mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-13 14:29:38 -05:00
Bind bone before normalization
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user