mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-01-04 13:45:04 +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
|
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.
|
// 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.
|
// Avoid this issue by keeping a static reference to the controller for each MAMA component.
|
||||||
private static Dictionary<ModularAvatarMergeArmature, ArmatureLockController>
|
private static Dictionary<ModularAvatarMergeArmature, ArmatureLockController>
|
||||||
@ -32,11 +35,11 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
EditorApplication.update += VoidUpdate;
|
UpdateLoopController.OnArmatureLockUpdate += VoidUpdate;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EditorApplication.update -= VoidUpdate;
|
UpdateLoopController.OnArmatureLockUpdate -= VoidUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateActive = value;
|
_updateActive = value;
|
||||||
@ -121,6 +124,11 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
if (_curMode == _mode)
|
if (_curMode == _mode)
|
||||||
{
|
{
|
||||||
result = _lock?.Execute() ?? LockResult.Failed;
|
result = _lock?.Execute() ?? LockResult.Failed;
|
||||||
|
if (result == LockResult.Success)
|
||||||
|
{
|
||||||
|
lastMovedFrame = Time.frameCount;
|
||||||
|
}
|
||||||
|
|
||||||
if (result != LockResult.Failed) return true;
|
if (result != LockResult.Failed) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[BurstCompile]
|
//[BurstCompile]
|
||||||
struct ComputePosition : IJobParallelFor
|
struct ComputePosition : IJobParallelFor
|
||||||
{
|
{
|
||||||
[ReadOnly] public NativeArray<BoneStaticData> _boneStatic;
|
[ReadOnly] public NativeArray<BoneStaticData> _boneStatic;
|
||||||
@ -75,6 +75,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
|
|
||||||
if (TransformState.Differs(mergeSaved, mergeState))
|
if (TransformState.Differs(mergeSaved, mergeState))
|
||||||
{
|
{
|
||||||
|
TransformState.Differs(mergeSaved, mergeState);
|
||||||
_fault.Increment();
|
_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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using nadena.dev.modular_avatar.core.armature_lock;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using VRC.SDKBase;
|
using VRC.SDKBase;
|
||||||
|
|
||||||
@ -111,7 +112,7 @@ namespace nadena.dev.modular_avatar.core.ArmatureAwase
|
|||||||
var localRotation = child.localRotation;
|
var localRotation = child.localRotation;
|
||||||
var localScale = child.localScale;
|
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 deltaPos = localPosition - state.childLocalPos;
|
||||||
var deltaRot = Quaternion.Angle(localRotation, state.childLocalRot);
|
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)
|
if (deltaPos.sqrMagnitude < EPSILON && deltaRot < EPSILON && deltaScale < EPSILON)
|
||||||
{
|
{
|
||||||
Matrix4x4 childNewLocal = parent.worldToLocalMatrix * state.childWorld;
|
Matrix4x4 childNewLocal = parent.worldToLocalMatrix * state.childWorld;
|
||||||
|
|
||||||
|
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
|
#if UNITY_EDITOR
|
||||||
UnityEditor.Undo.RecordObject(child, UnityEditor.Undo.GetCurrentGroupName());
|
UnityEditor.Undo.RecordObject(child, UnityEditor.Undo.GetCurrentGroupName());
|
||||||
#endif
|
#endif
|
||||||
child.localPosition = childNewLocal.MultiplyPoint(Vector3.zero);
|
|
||||||
child.localRotation = childNewLocal.rotation;
|
child.localPosition = newPosition;
|
||||||
child.localScale = childNewLocal.lossyScale;
|
child.localRotation = newRotation;
|
||||||
|
child.localScale = newScale;
|
||||||
|
|
||||||
state.childLocalPos = child.localPosition;
|
state.childLocalPos = child.localPosition;
|
||||||
state.childLocalRot = child.localRotation;
|
state.childLocalRot = child.localRotation;
|
||||||
state.childLocalScale = child.localScale;
|
state.childLocalScale = child.localScale;
|
||||||
|
}
|
||||||
|
|
||||||
_children[child] = state;
|
_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 deltaPos = transform.position - _priorFrameState.MultiplyPoint(Vector3.zero);
|
||||||
var deltaRot = Quaternion.Angle(_priorFrameState.rotation, transform.rotation);
|
var deltaRot = Quaternion.Angle(_priorFrameState.rotation, transform.rotation);
|
||||||
var deltaScale = (transform.lossyScale - _priorFrameState.lossyScale).sqrMagnitude;
|
var deltaScale = (transform.lossyScale - _priorFrameState.lossyScale).sqrMagnitude;
|
||||||
|
Loading…
Reference in New Issue
Block a user