fix: MA MeshSettings forget to keep the inverse root bone. (#1356)

* fix: Forget to keep the inverse root bone.

* fix: inverted root bone position is offset from original

---------

Co-authored-by: bd_ <bd_@nadena.dev>
This commit is contained in:
Reina_Sakiria 2024-11-25 11:02:10 +09:00 committed by GitHub
parent fd59c3e910
commit 0606311f51
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,5 +1,8 @@
using System.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Object = UnityEngine.Object;
namespace nadena.dev.modular_avatar.core.editor
{
@ -50,12 +53,12 @@ namespace nadena.dev.modular_avatar.core.editor
or ModularAvatarMeshSettings.InheritMode.Inherit
or ModularAvatarMeshSettings.InheritMode.DontSet
or ModularAvatarMeshSettings.InheritMode.SetOrInherit), _):
throw new System.InvalidOperationException($"Logic failure: invalid InheritMode: {currentMode}");
throw new InvalidOperationException($"Logic failure: invalid InheritMode: {currentMode}");
case (_, not (ModularAvatarMeshSettings.InheritMode.Set
or ModularAvatarMeshSettings.InheritMode.Inherit
or ModularAvatarMeshSettings.InheritMode.DontSet
or ModularAvatarMeshSettings.InheritMode.SetOrInherit)):
throw new System.ArgumentOutOfRangeException(nameof(srcMode), $"Invalid InheritMode: {srcMode}");
throw new ArgumentOutOfRangeException(nameof(srcMode), $"Invalid InheritMode: {srcMode}");
// If current value is came from Set or DontSet, it should not be changed
case (ModularAvatarMeshSettings.InheritMode.Set, _):
@ -144,9 +147,56 @@ namespace nadena.dev.modular_avatar.core.editor
if (newMesh) context.SaveAsset(newMesh);
}
smr.rootBone = settings.RootBone;
smr.localBounds = settings.Bounds;
var settingsRootBone = settings.RootBone;
settingsRootBone = settingsRootBone == null ? smr.transform : settingsRootBone;
var smrRootBone = smr.rootBone;
smrRootBone = smrRootBone == null ? smr.transform : smrRootBone;
if (IsInverted(smrRootBone) != IsInverted(settingsRootBone))
{
smr.rootBone = GetInvertedRootBone(settingsRootBone);
var bounds = settings.Bounds;
var center = bounds.center;
center.x *= -1;
bounds.center = center;
smr.localBounds = bounds;
}
else
{
smr.rootBone = settings.RootBone;
smr.localBounds = settings.Bounds;
}
}
}
private bool IsInverted(Transform bone)
{
var inverseCount = 0;
var scale = bone.lossyScale;
if (scale.x < 0) inverseCount += 1;
if (scale.y < 0) inverseCount += 1;
if (scale.z < 0) inverseCount += 1;
return (inverseCount % 2) != 0;
}
private Dictionary<Transform, Transform> invertedRootBoneCache = new();
private Transform GetInvertedRootBone(Transform rootBone)
{
if (invertedRootBoneCache.TryGetValue(rootBone, out var cache)) { return cache; }
var cloned = Object.Instantiate(rootBone.gameObject, rootBone, true);
cloned.name = rootBone.gameObject.name + "-InvertedRootBone";
var invertedRootBone = cloned.transform;
var scale = invertedRootBone.localScale;
scale.x *= -1;
invertedRootBone.localScale = scale;
invertedRootBoneCache[rootBone] = invertedRootBone;
return invertedRootBone;
}
}
}
}