diff --git a/CHANGELOG-PRERELEASE.md b/CHANGELOG-PRERELEASE.md index a8871b890..7c67265fb 100644 --- a/CHANGELOG-PRERELEASE.md +++ b/CHANGELOG-PRERELEASE.md @@ -19,6 +19,15 @@ The format is based on [Keep a Changelog]. ### Security +## [1.5.6-rc.1] - 2023-10-17 +### Removed +- Error for Read/Write Mesh off Mesh [`#615`](https://github.com/anatawa12/AvatarOptimizer/pull/615) + - Since AAO creates Mesh every time, no more error is required! + +### Fixed +- BindPose Optimization may break mesh with scale 0 bone [`#612`](https://github.com/anatawa12/AvatarOptimizer/pull/612) +- Error from Preview System when opening inspector of GameObject without SkinnedMeshRenderer [`#613`](https://github.com/anatawa12/AvatarOptimizer/pull/613) + ## [1.5.6-beta.2] - 2023-10-16 ### Changed - Make no-op as possible if no AAO component attached for your avatar [`#603`](https://github.com/anatawa12/AvatarOptimizer/pull/603) @@ -911,7 +920,8 @@ This release is mistake. - Merge Bone - Clear Endpoint Position -[Unreleased]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.5.6-beta.2...HEAD +[Unreleased]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.5.6-rc.1...HEAD +[1.5.6-rc.1]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.5.6-beta.2...v1.5.6-rc.1 [1.5.6-beta.2]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.5.6-beta.1...v1.5.6-beta.2 [1.5.6-beta.1]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.5.5...v1.5.6-beta.1 [1.5.5]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.5.5-rc.1...v1.5.5 diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c5c20cec..c93c0083c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,11 +16,14 @@ The format is based on [Keep a Changelog]. ### Deprecated ### Removed +- Error for Read/Write Mesh off Mesh `#615` + - Since AAO creates Mesh every time, no more error is required! ### Fixed - Multi-frame BlendShape can be broken `#601` - Update notice may show incorrect version `#602` - `Preview` button is not disabled even if mesh is none `#605` +- BindPose Optimization may break mesh with scale 0 bone `#612` ### Security diff --git a/Editor/EditModePreview/MeshPreviewController.cs b/Editor/EditModePreview/MeshPreviewController.cs index 5df181b39..cbcfc4fbb 100644 --- a/Editor/EditModePreview/MeshPreviewController.cs +++ b/Editor/EditModePreview/MeshPreviewController.cs @@ -70,6 +70,7 @@ private void Update() { var editorObj = ActiveEditor(); if (editorObj is GameObject go && + go.GetComponent() && go.GetComponent().sharedMesh && RemoveMeshPreviewController.EditorTypes.Any(t => go.GetComponent(t))) { diff --git a/Editor/Math/Matrix3x3.cs b/Editor/Math/Matrix3x3.cs index 8435f996c..f593bd25e 100644 --- a/Editor/Math/Matrix3x3.cs +++ b/Editor/Math/Matrix3x3.cs @@ -13,6 +13,10 @@ struct Matrix3x3 : IEquatable public static Matrix3x3 zero = new Matrix3x3(0, 0, 0, 0, 0, 0, 0, 0, 0); public static Matrix3x3 identity = new Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); + public float determinant => + (m00 * m11 * m22) + (m01 * m12 * m20) + (m02 * m10 * m21) + - (m00 * m12 * m21) - (m01 * m10 * m22) - (m02 * m11 * m20); + // @formatter:off public float m00; public float m10; diff --git a/Editor/Processors/MergeBoneProcessor.cs b/Editor/Processors/MergeBoneProcessor.cs index 14a8acdd4..f4b8b22b3 100644 --- a/Editor/Processors/MergeBoneProcessor.cs +++ b/Editor/Processors/MergeBoneProcessor.cs @@ -124,7 +124,7 @@ private void DoBoneMap2(MeshInfo2 meshInfo2, Dictionary me else { // we assume fist bone we find is the most natural bone. - if (!primaryBones.ContainsKey(bone.Transform)) + if (!primaryBones.ContainsKey(bone.Transform) && ValidBindPose(bone.Bindpose)) primaryBones.Add(bone.Transform, bone); } } @@ -162,7 +162,7 @@ private void DoBoneMap2(MeshInfo2 meshInfo2, Dictionary me vertex.Tangent = new Vector4(tangentVec3.x, tangentVec3.y, tangentVec3.z, vertex.Tangent.w); foreach (var frames in vertex.BlendShapes.Values) { - for (var i = 0; i < frames.Length; i++) + for (var i = 0; i < frames.Length; i++) { var frame = frames[i]; frames[i] = new Vertex.BlendShapeFrame( @@ -205,6 +205,29 @@ private void DoBoneMap2(MeshInfo2 meshInfo2, Dictionary me } } + private bool ValidBindPose(Matrix4x4 matrix) + { + const float SMALL = 0.001f; + const float BIG = 10000; + + // if scaling part of bindpose is too small or too big, it can lead to invalid bind pose optimization + var scaling = Mathf.Abs(new Matrix3x3(matrix).determinant); + + if (float.IsInfinity(scaling)) return false; + if (float.IsNaN(scaling)) return false; + if (scaling < SMALL) return false; + if (scaling > BIG) return false; + + // if offset part of bindpose is too big, it may lead to invalid bind pose optimization + + var offset = matrix.offset; + if (Mathf.Abs(offset.x) > BIG) return false; + if (Mathf.Abs(offset.y) > BIG) return false; + if (Mathf.Abs(offset.z) > BIG) return false; + + return true; + } + private readonly struct BoneUniqKey : IEquatable { private readonly Matrix4x4 _bindPoseInfo; diff --git a/Editor/Processors/SkinnedMeshes/MeshInfo2.cs b/Editor/Processors/SkinnedMeshes/MeshInfo2.cs index 67f1756ba..5245b03fe 100644 --- a/Editor/Processors/SkinnedMeshes/MeshInfo2.cs +++ b/Editor/Processors/SkinnedMeshes/MeshInfo2.cs @@ -38,11 +38,6 @@ public MeshInfo2(SkinnedMeshRenderer renderer) { SourceRenderer = renderer; var mesh = renderer.sharedMesh; - if (mesh && !mesh.isReadable) - { - BuildReport.LogFatal("The Mesh is not readable. Please Check Read/Write")?.WithContext(mesh); - return; - } BuildReport.ReportingObject(renderer, true, () => { @@ -80,11 +75,6 @@ public MeshInfo2(MeshRenderer renderer) { var meshFilter = renderer.GetComponent(); var mesh = meshFilter ? meshFilter.sharedMesh : null; - if (mesh && !mesh.isReadable) - { - BuildReport.LogFatal("The Mesh is not readable. Please Check Read/Write")?.WithContext(mesh); - return; - } if (mesh) ReadStaticMesh(mesh);