mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-01-01 20:25:07 +08:00
37b0f3c036
* opti: fix perf regressions in new armature lock system ... by avoiding reinitializing everything whenever any target bone moves. * chore: fixing unity 2019 issues
104 lines
2.9 KiB
C#
104 lines
2.9 KiB
C#
#region
|
|
|
|
using System;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
#endregion
|
|
|
|
namespace nadena.dev.modular_avatar.core.armature_lock
|
|
{
|
|
internal sealed class ArmatureLockJob : IDisposable
|
|
{
|
|
private bool _didLoop = false;
|
|
|
|
private Action _dispose;
|
|
|
|
private bool _isValid = true;
|
|
private long _lastHierarchyCheck = -1;
|
|
private Action _update;
|
|
|
|
internal ImmutableList<(Transform, Transform)> RecordedParents;
|
|
internal ImmutableList<(Transform, Transform)> Transforms;
|
|
|
|
internal ISegment Segment { get; private set; }
|
|
|
|
internal ArmatureLockJob(ISegment Segment, ImmutableList<(Transform, Transform)> transforms, Action dispose,
|
|
Action update)
|
|
{
|
|
this.Segment = Segment;
|
|
Transforms = transforms;
|
|
RecordedParents = transforms.Select(((tuple, _) => (tuple.Item1.parent, tuple.Item2.parent)))
|
|
.ToImmutableList();
|
|
_dispose = dispose;
|
|
_update = update;
|
|
}
|
|
|
|
internal bool FailedOnStartup => !_isValid && !_didLoop;
|
|
|
|
internal bool HierarchyChanged
|
|
{
|
|
get
|
|
{
|
|
var unchanged = RecordedParents.Zip(Transforms,
|
|
(p, t) =>
|
|
{
|
|
return t.Item1 != null && t.Item2 != null && t.Item1.parent == p.Item1 &&
|
|
t.Item2.parent == p.Item2;
|
|
}).All(b => b);
|
|
|
|
return !unchanged;
|
|
}
|
|
}
|
|
|
|
internal bool IsValid
|
|
{
|
|
get => _isValid;
|
|
set
|
|
{
|
|
var transitioned = (_isValid && !value);
|
|
_isValid = value;
|
|
|
|
if (transitioned)
|
|
{
|
|
Debug.Log("Invalidated job!");
|
|
#if UNITY_EDITOR
|
|
EditorApplication.delayCall += () => OnInvalidation?.Invoke();
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
internal bool WroteAny { get; set; }
|
|
|
|
public void Dispose()
|
|
{
|
|
_dispose?.Invoke();
|
|
_dispose = null;
|
|
_update = null;
|
|
}
|
|
|
|
internal event Action OnInvalidation;
|
|
|
|
internal void MarkLoop()
|
|
{
|
|
_didLoop = _didLoop || _isValid;
|
|
}
|
|
|
|
internal bool BoneChanged(int boneIndex)
|
|
{
|
|
return Transforms[boneIndex].Item1 == null || Transforms[boneIndex].Item2 == null
|
|
|| Transforms[boneIndex].Item1.parent !=
|
|
RecordedParents[boneIndex].Item1
|
|
|| Transforms[boneIndex].Item2.parent !=
|
|
RecordedParents[boneIndex].Item2;
|
|
}
|
|
|
|
public void UpdateNow()
|
|
{
|
|
_update?.Invoke();
|
|
}
|
|
}
|
|
} |