mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2024-12-29 18:55:06 +08:00
fix: Move Independently breaks armature lock (#457)
This commit is contained in:
parent
587084ffb7
commit
bef17bbaf8
@ -10,6 +10,9 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
||||
{
|
||||
internal class ArmatureLockController : IDisposable
|
||||
{
|
||||
private static long lastMovedFrame = 0;
|
||||
public static bool MovedThisFrame => Time.frameCount == lastMovedFrame;
|
||||
|
||||
// Undo operations can reinitialize the MAMA component, which destroys critical lock controller state.
|
||||
// Avoid this issue by keeping a static reference to the controller for each MAMA component.
|
||||
private static Dictionary<ModularAvatarMergeArmature, ArmatureLockController>
|
||||
@ -32,11 +35,11 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
||||
#if UNITY_EDITOR
|
||||
if (value)
|
||||
{
|
||||
EditorApplication.update += VoidUpdate;
|
||||
UpdateLoopController.OnArmatureLockUpdate += VoidUpdate;
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorApplication.update -= VoidUpdate;
|
||||
UpdateLoopController.OnArmatureLockUpdate -= VoidUpdate;
|
||||
}
|
||||
|
||||
_updateActive = value;
|
||||
@ -121,6 +124,11 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
||||
if (_curMode == _mode)
|
||||
{
|
||||
result = _lock?.Execute() ?? LockResult.Failed;
|
||||
if (result == LockResult.Success)
|
||||
{
|
||||
lastMovedFrame = Time.frameCount;
|
||||
}
|
||||
|
||||
if (result != LockResult.Failed) return true;
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
//[BurstCompile]
|
||||
struct ComputePosition : IJobParallelFor
|
||||
{
|
||||
[ReadOnly] public NativeArray<BoneStaticData> _boneStatic;
|
||||
@ -75,6 +75,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
||||
|
||||
if (TransformState.Differs(mergeSaved, mergeState))
|
||||
{
|
||||
TransformState.Differs(mergeSaved, mergeState);
|
||||
_fault.Increment();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.armature_lock
|
||||
{
|
||||
internal static class UpdateLoopController
|
||||
{
|
||||
internal static event Action OnArmatureLockUpdate;
|
||||
internal static event Action OnMoveIndependentlyUpdate;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.InitializeOnLoadMethod]
|
||||
private static void Init()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorApplication.update += () =>
|
||||
{
|
||||
OnArmatureLockUpdate?.Invoke();
|
||||
OnMoveIndependentlyUpdate?.Invoke();
|
||||
};
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f22557c7545402e89ebceae70132d85
|
||||
timeCreated: 1695811856
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using nadena.dev.modular_avatar.core.armature_lock;
|
||||
using UnityEngine;
|
||||
using VRC.SDKBase;
|
||||
|
||||
@ -111,7 +112,7 @@ namespace nadena.dev.modular_avatar.core.ArmatureAwase
|
||||
var localRotation = child.localRotation;
|
||||
var localScale = child.localScale;
|
||||
|
||||
if (_children.TryGetValue(child, out var state))
|
||||
if (!ArmatureLockController.MovedThisFrame && _children.TryGetValue(child, out var state))
|
||||
{
|
||||
var deltaPos = localPosition - state.childLocalPos;
|
||||
var deltaRot = Quaternion.Angle(localRotation, state.childLocalRot);
|
||||
@ -120,16 +121,27 @@ namespace nadena.dev.modular_avatar.core.ArmatureAwase
|
||||
if (deltaPos.sqrMagnitude < EPSILON && deltaRot < EPSILON && deltaScale < EPSILON)
|
||||
{
|
||||
Matrix4x4 childNewLocal = parent.worldToLocalMatrix * state.childWorld;
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.Undo.RecordObject(child, UnityEditor.Undo.GetCurrentGroupName());
|
||||
#endif
|
||||
child.localPosition = childNewLocal.MultiplyPoint(Vector3.zero);
|
||||
child.localRotation = childNewLocal.rotation;
|
||||
child.localScale = childNewLocal.lossyScale;
|
||||
|
||||
state.childLocalPos = child.localPosition;
|
||||
state.childLocalRot = child.localRotation;
|
||||
state.childLocalScale = child.localScale;
|
||||
var newPosition = childNewLocal.MultiplyPoint(Vector3.zero);
|
||||
var newRotation = childNewLocal.rotation;
|
||||
var newScale = childNewLocal.lossyScale;
|
||||
|
||||
if ((newPosition - localPosition).sqrMagnitude > EPSILON
|
||||
|| Quaternion.Angle(newRotation, localRotation) > EPSILON
|
||||
|| (newScale - localScale).sqrMagnitude > EPSILON)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.Undo.RecordObject(child, UnityEditor.Undo.GetCurrentGroupName());
|
||||
#endif
|
||||
|
||||
child.localPosition = newPosition;
|
||||
child.localRotation = newRotation;
|
||||
child.localScale = newScale;
|
||||
|
||||
state.childLocalPos = child.localPosition;
|
||||
state.childLocalRot = child.localRotation;
|
||||
state.childLocalScale = child.localScale;
|
||||
}
|
||||
|
||||
_children[child] = state;
|
||||
|
||||
@ -151,8 +163,24 @@ namespace nadena.dev.modular_avatar.core.ArmatureAwase
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
private void OnEnable()
|
||||
{
|
||||
UpdateLoopController.OnMoveIndependentlyUpdate += OnUpdate;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
UpdateLoopController.OnMoveIndependentlyUpdate -= OnUpdate;
|
||||
}
|
||||
|
||||
void OnUpdate()
|
||||
{
|
||||
if (this == null)
|
||||
{
|
||||
UpdateLoopController.OnMoveIndependentlyUpdate -= OnUpdate;
|
||||
return;
|
||||
}
|
||||
|
||||
var deltaPos = transform.position - _priorFrameState.MultiplyPoint(Vector3.zero);
|
||||
var deltaRot = Quaternion.Angle(_priorFrameState.rotation, transform.rotation);
|
||||
var deltaScale = (transform.lossyScale - _priorFrameState.lossyScale).sqrMagnitude;
|
||||
|
Loading…
Reference in New Issue
Block a user