fix: Scale Adjuster preview breaks after changing scale of avatar root (#1172)

Closes: #1171
This commit is contained in:
bd_ 2024-09-17 23:26:26 -04:00 committed by GitHub
parent a98ef213ff
commit 9b4e76e053
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -129,28 +129,37 @@ namespace nadena.dev.modular_avatar.core.editor
var priorScene = SceneManager.GetActiveScene(); var priorScene = SceneManager.GetActiveScene();
var bonesSet = GetSourceBonesSet(context, proxyPairList); var bonesSet = GetSourceBonesSet(context, proxyPairList);
var bones = bonesSet.ToArray(); var bones = bonesSet.OrderBy(k => k.gameObject.name).ToArray();
Transform[] sourceBones;
Transform[] destinationBones; Transform[] destinationBones;
try try
{ {
SceneManager.SetActiveScene(scene); SceneManager.SetActiveScene(scene);
VirtualAvatarRoot = new GameObject(avatarRoot.name + " [ScaleAdjuster]"); VirtualAvatarRoot = new GameObject(avatarRoot.name + " [ScaleAdjuster]");
_srcBones = new TransformAccessArray(bones.ToArray());
destinationBones = CreateShadowBones(bones); _shadowBoneMap = CreateShadowBones(bones);
sourceBones = new Transform[_shadowBoneMap.Count];
destinationBones = new Transform[_shadowBoneMap.Count];
var i = 0;
foreach (var (src, dst) in _shadowBoneMap)
{
sourceBones[i] = src;
destinationBones[i] = dst;
i++;
}
} }
finally finally
{ {
SceneManager.SetActiveScene(priorScene); SceneManager.SetActiveScene(priorScene);
} }
_shadowBoneMap = new Dictionary<Transform, Transform>(new ObjectIdentityComparer<Transform>()); _srcBones = new TransformAccessArray(sourceBones);
for (var i = 0; i < bones.Length; i++) _shadowBoneMap[bones[i]] = destinationBones[i];
_dstBones = new TransformAccessArray(destinationBones); _dstBones = new TransformAccessArray(destinationBones);
_boneIsValid = new NativeArray<bool>(bones.Length, Allocator.Persistent); _boneIsValid = new NativeArray<bool>(sourceBones.Length, Allocator.Persistent);
_boneStates = new NativeArray<TransformState>(bones.Length, Allocator.Persistent); _boneStates = new NativeArray<TransformState>(sourceBones.Length, Allocator.Persistent);
FindScaleAdjusters(context); FindScaleAdjusters(context);
TransferBoneStates(); TransferBoneStates();
@ -170,8 +179,12 @@ namespace nadena.dev.modular_avatar.core.editor
if (smr == null) continue; if (smr == null) continue;
foreach (var b in context.Observe(smr, smr_ => smr_.bones, Enumerable.SequenceEqual)) foreach (var b in context.Observe(smr, smr_ => smr_.bones, Enumerable.SequenceEqual))
{
if (b != null) if (b != null)
{
bonesSet.Add(b); bonesSet.Add(b);
}
}
} }
return bonesSet; return bonesSet;
@ -182,10 +195,14 @@ namespace nadena.dev.modular_avatar.core.editor
_finalBonesMap.Clear(); _finalBonesMap.Clear();
foreach (var (sa, proxy) in _scaleAdjusters.ToList()) foreach (var (sa, proxy) in _scaleAdjusters.ToList())
{
// Note: We leak the proxy here, as destroying it can cause visual artifacts. They'll eventually get // Note: We leak the proxy here, as destroying it can cause visual artifacts. They'll eventually get
// cleaned up whenever the pipeline is fully reset, or when the scene is reloaded. // cleaned up whenever the pipeline is fully reset, or when the scene is reloaded.
if (sa == null) if (sa == null)
{
_scaleAdjusters.Remove(sa); _scaleAdjusters.Remove(sa);
}
}
_scaleAdjusters.Clear(); _scaleAdjusters.Clear();
@ -224,14 +241,13 @@ namespace nadena.dev.modular_avatar.core.editor
return Task.FromResult<IRenderFilterNode>(this); return Task.FromResult<IRenderFilterNode>(this);
} }
private Transform[] CreateShadowBones(Transform[] srcBones) private Dictionary<Transform, Transform> CreateShadowBones(Transform[] srcBones)
{ {
var srcToDst = new Dictionary<Transform, Transform>(new ObjectIdentityComparer<Transform>()); var srcToDst = new Dictionary<Transform, Transform>(new ObjectIdentityComparer<Transform>());
var dstBones = new Transform[srcBones.Length]; for (var i = 0; i < srcBones.Length; i++) GetShadowBone(srcBones[i]);
for (var i = 0; i < srcBones.Length; i++) dstBones[i] = GetShadowBone(srcBones[i]);
return dstBones; return srcToDst;
Transform GetShadowBone(Transform srcBone) Transform GetShadowBone(Transform srcBone)
{ {
@ -278,12 +294,14 @@ namespace nadena.dev.modular_avatar.core.editor
BoneIsValid[index] = transform.isValid; BoneIsValid[index] = transform.isValid;
if (transform.isValid) if (transform.isValid)
{
BoneStates[index] = new TransformState BoneStates[index] = new TransformState
{ {
localPosition = transform.position, localPosition = transform.position,
localRotation = transform.rotation, localRotation = transform.rotation,
localScale = transform.localScale localScale = transform.localScale
}; };
}
} }
} }