From 7b8c784accd02bff6f5ea74090791eb06012672e Mon Sep 17 00:00:00 2001 From: d4rkc0d3r <1735522+d4rkc0d3r@users.noreply.github.com> Date: Wed, 17 May 2023 18:11:37 +0200 Subject: [PATCH] Add safeguards around bind pose & bone count mismatch. #34 --- CHANGELOG.md | 1 + Editor/d4rkAvatarOptimizer.cs | 15 +++++++++++++-- package.json | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8672a9a..a21b7eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Fix crash when the avatar has multiple non skinned meshes that try to get merged together without any material that can get merged or no skinned mesh in the merge target. [(more)](https://github.com/d4rkc0d3r/d4rkAvatarOptimizer/issues/34) * Fix parser not recognizing `#include` directives with `<>` instead of `""`. [(more)](https://github.com/d4rkc0d3r/d4rkAvatarOptimizer/issues/35) * Fix optimizer ignoring `[gamma]` tags for properties. [(more)](https://github.com/d4rkc0d3r/d4rkAvatarOptimizer/issues/33) +* Add safeguards around bindpose & bone count mismatch. [(more)](https://github.com/d4rkc0d3r/d4rkAvatarOptimizer/issues/34) ## v2.1.1 ### Bug Fixes diff --git a/Editor/d4rkAvatarOptimizer.cs b/Editor/d4rkAvatarOptimizer.cs index 9f220e3..8cedb0d 100644 --- a/Editor/d4rkAvatarOptimizer.cs +++ b/Editor/d4rkAvatarOptimizer.cs @@ -2553,7 +2553,13 @@ private void CombineSkinnedMeshes() if (sourceBones[i] == null) sourceBones[i] = rootBone; } - var toWorldArray = Enumerable.Range(0, skinnedMesh.bones.Length).Select(i => + var bindPoseCount = mesh.bindposes.Length; + if (sourceBones.Length != bindPoseCount) + { + Debug.LogWarning($"Bone count ({sourceBones.Length}) does not match bind pose count ({bindPoseCount}) on {skinnedMesh.name}"); + bindPoseCount = Math.Min(sourceBones.Length, bindPoseCount); + } + var toWorldArray = Enumerable.Range(0, bindPoseCount).Select(i => sourceBones[i].localToWorldMatrix * skinnedMesh.sharedMesh.bindposes[i] ).ToArray(); var aabb = skinnedMesh.localBounds; @@ -2567,7 +2573,7 @@ private void CombineSkinnedMeshes() targetBounds.Encapsulate(m.MultiplyPoint3x4(aabb.extents.Multiply(-1, -1, 1) + aabb.center)); targetBounds.Encapsulate(m.MultiplyPoint3x4(aabb.extents.Multiply(-1, -1, -1) + aabb.center)); - if (sourceWeights.Length != sourceVertices.Length) + if (sourceWeights.Length != sourceVertices.Length || bindPoseCount == 0) { var defaultWeight = new BoneWeight { @@ -2584,6 +2590,7 @@ private void CombineSkinnedMeshes() sourceBones = new Transform[1] { skinnedMesh.transform }; toWorldArray = new Matrix4x4[1] { skinnedMesh.transform.localToWorldMatrix }; keepTransforms.Add(skinnedMesh.transform); + bindPoseCount = 1; } for (int i = 1; i < 8; i++) @@ -2653,6 +2660,10 @@ private void CombineSkinnedMeshes() { targetUv[0].Add(new Vector4(sourceUv[vertIndex].x, sourceUv[vertIndex].y, meshID << 12, 0)); var boneWeight = sourceWeights[vertIndex]; + boneWeight.boneIndex0 = boneWeight.boneIndex0 >= bindPoseCount ? 0 : boneWeight.boneIndex0; + boneWeight.boneIndex1 = boneWeight.boneIndex1 >= bindPoseCount ? 0 : boneWeight.boneIndex1; + boneWeight.boneIndex2 = boneWeight.boneIndex2 >= bindPoseCount ? 0 : boneWeight.boneIndex2; + boneWeight.boneIndex3 = boneWeight.boneIndex3 >= bindPoseCount ? 0 : boneWeight.boneIndex3; Matrix4x4 toWorld = Matrix4x4.zero; toWorld = AddWeighted(toWorld, toWorldArray[boneWeight.boneIndex0], boneWeight.weight0); toWorld = AddWeighted(toWorld, toWorldArray[boneWeight.boneIndex1], boneWeight.weight1); diff --git a/package.json b/package.json index c6cdb94..a7e02d8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "d4rkpl4y3r.d4rkavataroptimizer", "displayName": "d4rkAvatarOptimizer", - "version": "2.2.0-beta.3", + "version": "2.2.0-beta.4", "unity": "2019.4", "description": "An optimizer aiming to reduce mesh & material count and more of VRChat 3.0 avatars.", "dependencies": {},