2024-02-18 20:56:59 +08:00
|
|
|
|
#region
|
|
|
|
|
|
2023-09-24 15:59:43 +08:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using Unity.Burst;
|
|
|
|
|
using Unity.Collections;
|
2024-03-03 16:34:48 +08:00
|
|
|
|
using Unity.Collections.LowLevel.Unsafe;
|
2023-09-24 15:59:43 +08:00
|
|
|
|
using Unity.Jobs;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
2024-02-18 20:56:59 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
2023-09-24 15:59:43 +08:00
|
|
|
|
namespace nadena.dev.modular_avatar.core.armature_lock
|
|
|
|
|
{
|
2024-03-03 16:34:48 +08:00
|
|
|
|
internal class BidirectionalArmatureLockOperator : ArmatureLockOperator<BidirectionalArmatureLockOperator>
|
2023-09-24 15:59:43 +08:00
|
|
|
|
{
|
2024-03-03 16:34:48 +08:00
|
|
|
|
private NativeArray<TransformState> SavedState;
|
|
|
|
|
protected override bool WritesBaseBones => true;
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
protected override void Reinit(List<(Transform, Transform)> transforms, List<int> problems)
|
2023-09-24 15:59:43 +08:00
|
|
|
|
{
|
2024-03-03 16:34:48 +08:00
|
|
|
|
if (SavedState.IsCreated) SavedState.Dispose();
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
SavedState = new NativeArray<TransformState>(transforms.Count, Allocator.Persistent);
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
for (int i = 0; i < transforms.Count; i++)
|
2023-09-24 15:59:43 +08:00
|
|
|
|
{
|
2024-03-03 16:34:48 +08:00
|
|
|
|
var (baseBone, mergeBone) = transforms[i];
|
|
|
|
|
SavedState[i] = TransformState.FromTransform(mergeBone);
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
if (TransformState.Differs(TransformState.FromTransform(baseBone), SavedState[i]))
|
2023-09-24 15:59:43 +08:00
|
|
|
|
{
|
2024-03-03 16:34:48 +08:00
|
|
|
|
problems.Add(i);
|
2023-09-24 15:59:43 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
protected override JobHandle Compute(ArmatureLockJobAccessor accessor, int? jobIndex, JobHandle dependency)
|
2023-09-24 15:59:43 +08:00
|
|
|
|
{
|
2024-03-03 16:34:48 +08:00
|
|
|
|
return new ComputeOperator()
|
2023-09-24 15:59:43 +08:00
|
|
|
|
{
|
2024-03-03 16:34:48 +08:00
|
|
|
|
base_in = accessor._in_baseBone,
|
|
|
|
|
merge_in = accessor._in_targetBone,
|
|
|
|
|
base_out = accessor._out_baseBone,
|
|
|
|
|
merge_out = accessor._out_targetBone,
|
|
|
|
|
|
|
|
|
|
SavedState = SavedState,
|
|
|
|
|
baseDirty = accessor._out_dirty_baseBone,
|
|
|
|
|
mergeDirty = accessor._out_dirty_targetBone,
|
|
|
|
|
boneToJobIndex = accessor._boneToJobIndex,
|
|
|
|
|
wroteAny = accessor._didAnyWriteFlag,
|
|
|
|
|
|
|
|
|
|
singleJobIndex = jobIndex ?? -1
|
|
|
|
|
}.Schedule(accessor._in_baseBone.Length, 16, dependency);
|
2023-09-24 15:59:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
protected override void DerivedDispose()
|
2023-09-24 15:59:43 +08:00
|
|
|
|
{
|
2024-03-03 16:34:48 +08:00
|
|
|
|
SavedState.Dispose();
|
2023-09-24 15:59:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
[BurstCompile]
|
|
|
|
|
private struct ComputeOperator : IJobParallelFor
|
2023-09-24 15:59:43 +08:00
|
|
|
|
{
|
2024-03-03 16:34:48 +08:00
|
|
|
|
public int singleJobIndex;
|
2024-02-26 17:03:16 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
public NativeArray<TransformState> base_in, merge_in, base_out, merge_out;
|
2024-02-26 17:03:16 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
public NativeArray<TransformState> SavedState;
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
[WriteOnly] public NativeArray<int> baseDirty, mergeDirty;
|
|
|
|
|
[ReadOnly] public NativeArray<int> boneToJobIndex;
|
2024-02-17 18:20:08 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
[NativeDisableContainerSafetyRestriction] [NativeDisableParallelForRestriction] [WriteOnly]
|
|
|
|
|
public NativeArray<int> wroteAny;
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
[BurstCompile]
|
|
|
|
|
public void Execute(int index)
|
2023-09-24 15:59:43 +08:00
|
|
|
|
{
|
2024-03-03 16:34:48 +08:00
|
|
|
|
var jobIndex = boneToJobIndex[index];
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
if (singleJobIndex != -1 && jobIndex != singleJobIndex) return;
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
var baseBone = base_in[index];
|
|
|
|
|
var mergeBone = merge_in[index];
|
|
|
|
|
var saved = SavedState[index];
|
2024-02-26 17:03:16 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
if (TransformState.Differs(saved, mergeBone))
|
|
|
|
|
{
|
|
|
|
|
baseDirty[index] = 1;
|
|
|
|
|
mergeDirty[index] = 0;
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
SavedState[index] = base_out[index] = merge_in[index];
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
wroteAny[jobIndex] = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (TransformState.Differs(saved, baseBone))
|
|
|
|
|
{
|
|
|
|
|
mergeDirty[index] = 1;
|
|
|
|
|
baseDirty[index] = 0;
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
SavedState[index] = merge_out[index] = base_in[index];
|
2023-09-24 15:59:43 +08:00
|
|
|
|
|
2024-03-03 16:34:48 +08:00
|
|
|
|
wroteAny[jobIndex] = 1;
|
|
|
|
|
}
|
2023-09-24 15:59:43 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|