From 84b64c0be28d37a189a648c2ab9a497007ef6ed4 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 18 Nov 2024 16:30:16 +0900 Subject: [PATCH 1/9] use spring.transformIndexOffset --- .../FastSpringBoneBufferCombiner.cs | 4 - .../FastSpringBoneConbinedBuffer.cs | 93 ++++++++++--------- .../InputPorts/FastSpringBoneBuffer.cs | 12 --- .../FastSpringBoneBufferFactory.cs | 3 +- 4 files changed, 49 insertions(+), 63 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs index cc4a9da2d..016cbcd96 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs @@ -60,10 +60,6 @@ namespace UniGLTF.SpringBoneJobs Profiler.BeginSample("FastSpringBone.ReconstructBuffers.DisposeBuffers"); if (_combinedBuffer is FastSpringBoneCombinedBuffer combined) { - Profiler.BeginSample("FastSpringBone.ReconstructBuffers.SaveToSourceBuffer"); - combined.SaveToSourceBuffer(); - Profiler.EndSample(); - // TODO: Dispose せずに再利用? combined.Dispose(); } diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs index d6bd83c05..34410ece7 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs @@ -97,7 +97,7 @@ namespace UniGLTF.SpringBoneJobs springsCount += buffer.Springs.Length; collidersCount += buffer.Colliders.Length; logicsCount += buffer.Logics.Length; - transformsCount += buffer.BlittableTransforms.Length; + transformsCount += buffer.Transforms.Length; } Profiler.EndSample(); @@ -112,6 +112,23 @@ namespace UniGLTF.SpringBoneJobs private JobHandle Batching(JobHandle handle) { + // TransformAccessArrayの構築 + Profiler.BeginSample("FastSpringBone.ReconstructBuffers.LoadTransformAccessArray"); + var transforms = new Transform[_transforms.Length]; + var transformAccessArrayOffset = 0; + foreach (var buffer in _batchedBuffers) + { + Array.Copy(buffer.Transforms, 0, transforms, transformAccessArrayOffset, buffer.Transforms.Length); + transformAccessArrayOffset += buffer.Transforms.Length; + } + _transformAccessArray = new TransformAccessArray(transforms); + Profiler.EndSample(); + + handle = new PullTransformJob + { + Transforms = Transforms + }.Schedule(TransformAccessArray, handle); + Profiler.BeginSample("FastSpringBone.ReconstructBuffers.ScheduleLoadBufferJobs"); var springsOffset = 0; var collidersOffset = 0; @@ -129,14 +146,6 @@ namespace UniGLTF.SpringBoneJobs _jointMap.Add(buffer.Transforms[head], logicsOffset + j); } - // バッファの読み込みをスケジュール - handle = new LoadTransformsJob - { - SrcTransforms = buffer.BlittableTransforms, - DestTransforms = new NativeSlice(_transforms, transformOffset, - buffer.BlittableTransforms.Length) - }.Schedule(buffer.BlittableTransforms.Length, 1, handle); - handle = new LoadSpringsJob { ModelIndex = i, @@ -165,26 +174,9 @@ namespace UniGLTF.SpringBoneJobs springsOffset += buffer.Springs.Length; collidersOffset += buffer.Colliders.Length; logicsOffset += buffer.Logics.Length; - transformOffset += buffer.BlittableTransforms.Length; + transformOffset += buffer.Transforms.Length; } - handle = InitCurrentTails(handle); - - // TransformAccessArrayの構築と並行してJobを行うため、この時点で走らせておく - JobHandle.ScheduleBatchedJobs(); - Profiler.EndSample(); - - // TransformAccessArrayの構築 - Profiler.BeginSample("FastSpringBone.ReconstructBuffers.LoadTransformAccessArray"); - var transforms = new Transform[_transforms.Length]; - var transformAccessArrayOffset = 0; - foreach (var buffer in _batchedBuffers) - { - Array.Copy(buffer.Transforms, 0, transforms, transformAccessArrayOffset, buffer.Transforms.Length); - transformAccessArrayOffset += buffer.BlittableTransforms.Length; - } - - _transformAccessArray = new TransformAccessArray(transforms); Profiler.EndSample(); return handle; @@ -328,29 +320,36 @@ namespace UniGLTF.SpringBoneJobs #endif private struct InitCurrentTailsJob : IJobParallelFor { + [ReadOnly] public NativeArray Springs; + [ReadOnly] public NativeArray Logics; [ReadOnly] public NativeArray Transforms; - [WriteOnly] public NativeSlice CurrentTails; - [WriteOnly] public NativeSlice PrevTails; - [WriteOnly] public NativeSlice NextTails; + [NativeDisableParallelForRestriction] public NativeSlice CurrentTails; + [NativeDisableParallelForRestriction] public NativeSlice PrevTails; + [NativeDisableParallelForRestriction] public NativeSlice NextTails; - public void Execute(int jointIndex) + public void Execute(int springIndex) { - var tailIndex = Logics[jointIndex].tailTransformIndex; - if (tailIndex == -1) + var spring = Springs[springIndex]; + for (int jointIndex = spring.logicSpan.startIndex; jointIndex < spring.logicSpan.EndIndex; ++jointIndex) { - // tail 無い - var tail = Transforms[Logics[jointIndex].headTransformIndex]; - CurrentTails[jointIndex] = tail.position; - PrevTails[jointIndex] = tail.position; - NextTails[jointIndex] = tail.position; - } - else - { - var tail = Transforms[tailIndex]; - CurrentTails[jointIndex] = tail.position; - PrevTails[jointIndex] = tail.position; - NextTails[jointIndex] = tail.position; + var tailIndex = Logics[jointIndex].tailTransformIndex; + if (tailIndex == -1) + { + // tail 無い + var index = springIndex + Logics[jointIndex].headTransformIndex; + var tail = Transforms[index]; + CurrentTails[jointIndex] = tail.position; + PrevTails[jointIndex] = tail.position; + NextTails[jointIndex] = tail.position; + } + else + { + var tail = Transforms[spring.transformIndexOffset + tailIndex]; + CurrentTails[jointIndex] = tail.position; + PrevTails[jointIndex] = tail.position; + NextTails[jointIndex] = tail.position; + } } } } @@ -365,12 +364,14 @@ namespace UniGLTF.SpringBoneJobs { return new InitCurrentTailsJob { + Springs = Springs, + Logics = Logics, Transforms = Transforms, CurrentTails = CurrentTails, PrevTails = PrevTails, NextTails = NextTails, - }.Schedule(Logics.Length, 1, handle); + }.Schedule(Springs.Length, 1, handle); } public void InitializeJointsLocalRotation(FastSpringBoneBuffer buffer) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs index 9e9887176..07c0de741 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs @@ -22,7 +22,6 @@ namespace UniGLTF.SpringBoneJobs.InputPorts public NativeArray Joints { get; } public NativeArray Colliders { get; } public NativeArray Logics { get; } - public NativeArray BlittableTransforms { get; } public Transform[] Transforms { get; } public bool IsDisposed { get; private set; } @@ -103,16 +102,6 @@ namespace UniGLTF.SpringBoneJobs.InputPorts Joints = new NativeArray(blittableJoints.ToArray(), Allocator.Persistent); Colliders = new NativeArray(blittableColliders.ToArray(), Allocator.Persistent); Logics = new NativeArray(blittableLogics.ToArray(), Allocator.Persistent); - BlittableTransforms = new NativeArray(Transforms.Select(transform => new BlittableTransform - { - position = transform.position, - rotation = transform.rotation, - localPosition = transform.localPosition, - localRotation = transform.localRotation, - localScale = transform.localScale, - localToWorldMatrix = transform.localToWorldMatrix, - worldToLocalMatrix = transform.worldToLocalMatrix - }).ToArray(), Allocator.Persistent); Profiler.EndSample(); } @@ -157,7 +146,6 @@ namespace UniGLTF.SpringBoneJobs.InputPorts IsDisposed = true; Springs.Dispose(); Joints.Dispose(); - BlittableTransforms.Dispose(); Colliders.Dispose(); Logics.Dispose(); } diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs index a6a03f23c..c84f58de0 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs @@ -26,6 +26,7 @@ namespace UniVRM10 if (fastSpringBoneBuffer != null) { fastSpringBoneBuffer.Dispose(); + fastSpringBoneBuffer = null; } Func GetOrAddDefaultTransformState = (Transform tf) => @@ -41,7 +42,7 @@ namespace UniVRM10 // create(Spring情報の再収集。設定変更の反映) var springs = vrm.SpringBone.Springs.Select(spring => new FastSpringBoneSpring - { + { center = spring.Center, colliders = spring.ColliderGroups .SelectMany(group => group.Colliders) From 8e259e20dd6898f94355a2bbcbe22406733df420 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 18 Nov 2024 16:38:17 +0900 Subject: [PATCH 2/9] comment --- .../Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs index 34410ece7..e067c07d4 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs @@ -124,6 +124,7 @@ namespace UniGLTF.SpringBoneJobs _transformAccessArray = new TransformAccessArray(transforms); Profiler.EndSample(); + // Transforms を更新。後続の InitCurrentTails で使う handle = new PullTransformJob { Transforms = Transforms @@ -176,6 +177,10 @@ namespace UniGLTF.SpringBoneJobs logicsOffset += buffer.Logics.Length; transformOffset += buffer.Transforms.Length; } + + // verlet の current, prev, next のバッファを今の transform の状態にする。 + // 速度は 0 にクリアする。 + // TODO: 速度の維持は SaveToSourceBuffer でされていたのだがデータ構造変更で場所が変わった handle = InitCurrentTails(handle); Profiler.EndSample(); @@ -345,7 +350,7 @@ namespace UniGLTF.SpringBoneJobs } else { - var tail = Transforms[spring.transformIndexOffset + tailIndex]; + var tail = Transforms[spring.transformIndexOffset + tailIndex]; CurrentTails[jointIndex] = tail.position; PrevTails[jointIndex] = tail.position; NextTails[jointIndex] = tail.position; From a8bd641bae98fa9c33c6378508a01da7ab13f05f Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 18 Nov 2024 16:44:15 +0900 Subject: [PATCH 3/9] fix tailIndex --- .../FastSpringBoneConbinedBuffer.cs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs index e067c07d4..c126c5e95 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs @@ -338,23 +338,21 @@ namespace UniGLTF.SpringBoneJobs var spring = Springs[springIndex]; for (int jointIndex = spring.logicSpan.startIndex; jointIndex < spring.logicSpan.EndIndex; ++jointIndex) { - var tailIndex = Logics[jointIndex].tailTransformIndex; - if (tailIndex == -1) + int tailIndex; + if (Logics[jointIndex].tailTransformIndex == -1) { // tail 無い - var index = springIndex + Logics[jointIndex].headTransformIndex; - var tail = Transforms[index]; - CurrentTails[jointIndex] = tail.position; - PrevTails[jointIndex] = tail.position; - NextTails[jointIndex] = tail.position; + tailIndex = spring.transformIndexOffset + Logics[jointIndex].headTransformIndex; } else { - var tail = Transforms[spring.transformIndexOffset + tailIndex]; - CurrentTails[jointIndex] = tail.position; - PrevTails[jointIndex] = tail.position; - NextTails[jointIndex] = tail.position; + tailIndex= spring.transformIndexOffset + Logics[jointIndex].tailTransformIndex; } + + var tail = Transforms[tailIndex]; + CurrentTails[jointIndex] = tail.position; + PrevTails[jointIndex] = tail.position; + NextTails[jointIndex] = tail.position; } } } From a78bf20884a5388492d3d2b4c03544a19611719e Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 19 Nov 2024 03:14:10 +0900 Subject: [PATCH 4/9] =?UTF-8?q?FastSpringBoneBuffer.=5FcurrentTailsBackup?= =?UTF-8?q?=20=E3=81=A7=E3=83=90=E3=83=83=E3=82=AF=E3=82=A2=E3=83=83?= =?UTF-8?q?=E3=83=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FastSpringBoneBufferCombiner.cs | 23 ++++++- .../FastSpringBoneConbinedBuffer.cs | 69 ++++++------------- .../InputPorts/FastSpringBoneBuffer.cs | 35 ++++++++++ 3 files changed, 76 insertions(+), 51 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs index 016cbcd96..813d8ae90 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs @@ -4,6 +4,7 @@ using Unity.Jobs; using UnityEngine.Profiling; using UniGLTF.SpringBoneJobs.InputPorts; using UnityEngine; +using Unity.Collections; namespace UniGLTF.SpringBoneJobs { @@ -29,9 +30,27 @@ namespace UniGLTF.SpringBoneJobs _isDirty = true; } - public void Unregister(FastSpringBoneBuffer buffer) + public void Unregister(FastSpringBoneBuffer remove) { - _buffers.Remove(buffer); + // index が変わる前に シミュレーションの状態を保存する。 + // 状態の保存場所が BlittableJoint から CurrentTails に移動しているのでここでやる。 + if (_combinedBuffer is FastSpringBoneCombinedBuffer combined) + { + var logicsIndex = 0; + foreach (var buffer in _buffers) + { + if (buffer == remove) + { + // 削除するので skip + // joint の位置が変わる可能性があるので状態を保存せずに速度を0にする方がよい + continue; + } + buffer.BackupCurrentTails(combined.CurrentTails, logicsIndex); + logicsIndex += buffer.Logics.Length; + } + } + + _buffers.Remove(remove); _isDirty = true; } diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs index c126c5e95..2e4c578ea 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs @@ -147,6 +147,9 @@ namespace UniGLTF.SpringBoneJobs _jointMap.Add(buffer.Transforms[head], logicsOffset + j); } + // 速度の維持 + buffer.RestoreCurrentTails(_currentTails, logicsOffset); + handle = new LoadSpringsJob { ModelIndex = i, @@ -205,25 +208,6 @@ namespace UniGLTF.SpringBoneJobs if (_transformAccessArray.isCreated) _transformAccessArray.Dispose(); } - /// - /// バッチングされたバッファから、個々のバッファへと値を戻す - /// Logics to _batchedBuffers[].Logics - /// バッファの再構築前にこの処理を行わないと、揺れの状態がリセットされてしまい、不自然な挙動になる - /// - internal void SaveToSourceBuffer() - { - var logicsIndex = 0; - for (var i = 0; i < _batchedBuffers.Length; ++i) - { - var length = _batchedBufferLogicSizes[i]; - if (!_batchedBuffers[i].IsDisposed && length > 0) - { - NativeArray.Copy(Logics, logicsIndex, _batchedBuffers[i].Logics, 0, length); - } - logicsIndex += length; - } - } - public void FlipBuffer() { var tmp = _prevTails; @@ -248,23 +232,6 @@ namespace UniGLTF.SpringBoneJobs } } -#if ENABLE_SPRINGBONE_BURST - [BurstCompile] -#endif - /// - /// - /// - private struct LoadTransformsJob : IJobParallelFor - { - [ReadOnly] public NativeArray SrcTransforms; - [WriteOnly] public NativeSlice DestTransforms; - - public void Execute(int index) - { - DestTransforms[index] = SrcTransforms[index]; - } - } - #if ENABLE_SPRINGBONE_BURST [BurstCompile] #endif @@ -338,21 +305,25 @@ namespace UniGLTF.SpringBoneJobs var spring = Springs[springIndex]; for (int jointIndex = spring.logicSpan.startIndex; jointIndex < spring.logicSpan.EndIndex; ++jointIndex) { - int tailIndex; - if (Logics[jointIndex].tailTransformIndex == -1) + if (float.IsNaN(CurrentTails[jointIndex].x)) { - // tail 無い - tailIndex = spring.transformIndexOffset + Logics[jointIndex].headTransformIndex; - } - else - { - tailIndex= spring.transformIndexOffset + Logics[jointIndex].tailTransformIndex; - } + // Transsform の現状を使う。velocity を zero にする + int tailIndex; + if (Logics[jointIndex].tailTransformIndex == -1) + { + // tail 無い + tailIndex = spring.transformIndexOffset + Logics[jointIndex].headTransformIndex; + } + else + { + tailIndex = spring.transformIndexOffset + Logics[jointIndex].tailTransformIndex; + } - var tail = Transforms[tailIndex]; - CurrentTails[jointIndex] = tail.position; - PrevTails[jointIndex] = tail.position; - NextTails[jointIndex] = tail.position; + var tail = Transforms[tailIndex]; + CurrentTails[jointIndex] = tail.position; + PrevTails[jointIndex] = tail.position; + NextTails[jointIndex] = tail.position; + } } } } diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs index 07c0de741..c1bf55ffb 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs @@ -22,6 +22,7 @@ namespace UniGLTF.SpringBoneJobs.InputPorts public NativeArray Joints { get; } public NativeArray Colliders { get; } public NativeArray Logics { get; } + private NativeArray _currentTailsBackup; public Transform[] Transforms { get; } public bool IsDisposed { get; private set; } @@ -140,6 +141,40 @@ namespace UniGLTF.SpringBoneJobs.InputPorts } } + public void BackupCurrentTails(NativeArray currentTails, int offset) + { + if (!IsDisposed) + { + return; + } + if (Logics.Length == 0) + { + return; + } + if (!_currentTailsBackup.IsCreated) + { + _currentTailsBackup = new(Logics.Length, Allocator.Persistent); + } + NativeArray.Copy(currentTails, offset, _currentTailsBackup, 0, Logics.Length); + } + + public void RestoreCurrentTails(NativeArray currentTails, int offset) + { + if (_currentTailsBackup.IsCreated) + { + NativeArray.Copy(_currentTailsBackup, 0, currentTails, offset, Logics.Length); + } + else + { + var end = offset + Logics.Length; + for (int i = offset; i < end; ++i) + { + // mark velocity zero + currentTails.GetSubArray(offset, Logics.Length).AsSpan().Fill(new Vector3(float.NaN, float.NaN, float.NaN)); + } + } + } + public void Dispose() { if (IsDisposed) return; From e85d332e5650b4c364ad737e7bf0acf8cbfacb55 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 19 Nov 2024 03:41:07 +0900 Subject: [PATCH 5/9] fix gizmo and assert --- .../FastSpringBoneConbinedBuffer.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs index 2e4c578ea..0e597b70d 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs @@ -354,9 +354,9 @@ namespace UniGLTF.SpringBoneJobs for (var i = 0; i < _batchedBuffers.Length; ++i) { var length = _batchedBufferLogicSizes[i]; - Debug.Assert(length == buffer.Logics.Length); if (_batchedBuffers[i] == buffer) { + Debug.Assert(length == buffer.Logics.Length); for (var j = 0; j < length; ++j) { var logic = buffer.Logics[j]; @@ -376,22 +376,23 @@ namespace UniGLTF.SpringBoneJobs public void DrawGizmos() { - foreach (var collider in _colliders) - { - collider.DrawGizmo(_transforms[collider.transformIndex]); - } - foreach (var spring in _springs) { + for (int i = spring.colliderSpan.startIndex; i < spring.colliderSpan.EndIndex; ++i) + { + var collider = _colliders[i]; + collider.DrawGizmo(_transforms[spring.transformIndexOffset + collider.transformIndex]); + } + for (int i = spring.logicSpan.startIndex; i < spring.logicSpan.EndIndex; ++i) { var joint = _logics[i]; - joint.DrawGizmo(_transforms[joint.tailTransformIndex], _joints[i]); + joint.DrawGizmo(_transforms[spring.transformIndexOffset + joint.tailTransformIndex], _joints[i]); Gizmos.matrix = Matrix4x4.identity; Gizmos.DrawLine( - _transforms[joint.tailTransformIndex].position, - _transforms[joint.headTransformIndex].position); + _transforms[spring.transformIndexOffset + joint.tailTransformIndex].position, + _transforms[spring.transformIndexOffset + joint.headTransformIndex].position); } } } From 5bda6740ff077b6d49c340597b46be82eb16e7dd Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 19 Nov 2024 03:53:34 +0900 Subject: [PATCH 6/9] =?UTF-8?q?buffer.BackupCurrentTails=20=E3=82=92=20buf?= =?UTF-8?q?fer=20=E5=A2=97=E6=B8=9B=E3=81=AE=E7=9B=B4=E5=89=8D=E3=81=AB?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FastSpringBoneBufferCombiner.cs | 70 +++++++++++-------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs index 813d8ae90..a43d5b439 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs @@ -5,6 +5,7 @@ using UnityEngine.Profiling; using UniGLTF.SpringBoneJobs.InputPorts; using UnityEngine; using Unity.Collections; +using System.Linq; namespace UniGLTF.SpringBoneJobs { @@ -21,37 +22,17 @@ namespace UniGLTF.SpringBoneJobs private FastSpringBoneCombinedBuffer _combinedBuffer; public FastSpringBoneCombinedBuffer Combined => _combinedBuffer; private readonly LinkedList _buffers = new LinkedList(); - private bool _isDirty; + private Queue<(bool isAdd, FastSpringBoneBuffer buffer)> _request = new(); public bool HasBuffer => _buffers.Count > 0 && _combinedBuffer != null; public void Register(FastSpringBoneBuffer buffer) { - _buffers.AddLast(buffer); - _isDirty = true; + _request.Enqueue((true, buffer)); } - public void Unregister(FastSpringBoneBuffer remove) + public void Unregister(FastSpringBoneBuffer buffer) { - // index が変わる前に シミュレーションの状態を保存する。 - // 状態の保存場所が BlittableJoint から CurrentTails に移動しているのでここでやる。 - if (_combinedBuffer is FastSpringBoneCombinedBuffer combined) - { - var logicsIndex = 0; - foreach (var buffer in _buffers) - { - if (buffer == remove) - { - // 削除するので skip - // joint の位置が変わる可能性があるので状態を保存せずに速度を0にする方がよい - continue; - } - buffer.BackupCurrentTails(combined.CurrentTails, logicsIndex); - logicsIndex += buffer.Logics.Length; - } - } - - _buffers.Remove(remove); - _isDirty = true; + _request.Enqueue((false, buffer)); } /// @@ -59,14 +40,45 @@ namespace UniGLTF.SpringBoneJobs /// public JobHandle ReconstructIfDirty(JobHandle handle) { - if (_isDirty) + if (_request.Count == 0) { - var result = ReconstructBuffers(handle); - _isDirty = false; - return result; + return handle; } - return handle; + if (_combinedBuffer is FastSpringBoneCombinedBuffer combined) + { + // index が変わる前に シミュレーションの状態を保存する。 + // 状態の保存場所が BlittableJoint から CurrentTails に移動しているのでここでやる。 + var logicsIndex = 0; + foreach (var buffer in _buffers) + { + if (_request.Any(x => !x.isAdd && x.buffer == buffer)) + { + // 削除するので skip + continue; + } + buffer.BackupCurrentTails(combined.CurrentTails, logicsIndex); + logicsIndex += buffer.Logics.Length; + } + } + + // buffer 増減 + while (_request.Count > 0) + { + var (isAdd, buffer) = _request.Dequeue(); + if (isAdd) + { + // 速度 0 にする + _buffers.AddLast(buffer); + } + else + { + _buffers.Remove(buffer); + } + } + + // 再構築 + return ReconstructBuffers(handle); } /// From 5ead212afa397ad9b7eeee05d2c41bf66906e2f1 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 19 Nov 2024 09:53:37 +0900 Subject: [PATCH 7/9] FastSpringBoneBuffer.Dispose --- .../InputPorts/FastSpringBoneBuffer.cs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs index c1bf55ffb..f17b068f2 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs @@ -24,7 +24,6 @@ namespace UniGLTF.SpringBoneJobs.InputPorts public NativeArray Logics { get; } private NativeArray _currentTailsBackup; public Transform[] Transforms { get; } - public bool IsDisposed { get; private set; } /// /// Joint, Collider, Center の Transform のリスト @@ -143,11 +142,7 @@ namespace UniGLTF.SpringBoneJobs.InputPorts public void BackupCurrentTails(NativeArray currentTails, int offset) { - if (!IsDisposed) - { - return; - } - if (Logics.Length == 0) + if (!Logics.IsCreated || Logics.Length == 0) { return; } @@ -177,12 +172,11 @@ namespace UniGLTF.SpringBoneJobs.InputPorts public void Dispose() { - if (IsDisposed) return; - IsDisposed = true; - Springs.Dispose(); - Joints.Dispose(); - Colliders.Dispose(); - Logics.Dispose(); + if (Springs.IsCreated) Springs.Dispose(); + if (Joints.IsCreated) Joints.Dispose(); + if (Colliders.IsCreated) Colliders.Dispose(); + if (Logics.IsCreated) Logics.Dispose(); + if (_currentTailsBackup.IsCreated) _currentTailsBackup.Dispose(); } } } \ No newline at end of file From eed18136be27c08350dfc0bf7e8030d2aa95f003 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 19 Nov 2024 10:17:30 +0900 Subject: [PATCH 8/9] _nextTailsBackup --- .../FastSpringBoneBufferCombiner.cs | 2 +- .../FastSpringBoneConbinedBuffer.cs | 2 +- .../InputPorts/FastSpringBoneBuffer.cs | 30 ++++++++++--------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs index a43d5b439..f22112b5e 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs @@ -57,7 +57,7 @@ namespace UniGLTF.SpringBoneJobs // 削除するので skip continue; } - buffer.BackupCurrentTails(combined.CurrentTails, logicsIndex); + buffer.BackupCurrentTails(combined.CurrentTails, combined.NextTails, logicsIndex); logicsIndex += buffer.Logics.Length; } } diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs index 0e597b70d..ae66220b6 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs @@ -148,7 +148,7 @@ namespace UniGLTF.SpringBoneJobs } // 速度の維持 - buffer.RestoreCurrentTails(_currentTails, logicsOffset); + buffer.RestoreCurrentTails(_currentTails, _nextTails, logicsOffset); handle = new LoadSpringsJob { diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs index c1bf55ffb..455e17dd6 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs @@ -23,8 +23,8 @@ namespace UniGLTF.SpringBoneJobs.InputPorts public NativeArray Colliders { get; } public NativeArray Logics { get; } private NativeArray _currentTailsBackup; + private NativeArray _nextTailsBackup; public Transform[] Transforms { get; } - public bool IsDisposed { get; private set; } /// /// Joint, Collider, Center の Transform のリスト @@ -141,13 +141,9 @@ namespace UniGLTF.SpringBoneJobs.InputPorts } } - public void BackupCurrentTails(NativeArray currentTails, int offset) + public void BackupCurrentTails(NativeArray currentTails, NativeArray nextTails, int offset) { - if (!IsDisposed) - { - return; - } - if (Logics.Length == 0) + if (!Logics.IsCreated || Logics.Length == 0) { return; } @@ -155,14 +151,20 @@ namespace UniGLTF.SpringBoneJobs.InputPorts { _currentTailsBackup = new(Logics.Length, Allocator.Persistent); } + if (!_nextTailsBackup.IsCreated) + { + _nextTailsBackup = new(Logics.Length, Allocator.Persistent); + } NativeArray.Copy(currentTails, offset, _currentTailsBackup, 0, Logics.Length); + NativeArray.Copy(nextTails, offset, _nextTailsBackup, 0, Logics.Length); } - public void RestoreCurrentTails(NativeArray currentTails, int offset) + public void RestoreCurrentTails(NativeArray currentTails, NativeArray nextTails, int offset) { if (_currentTailsBackup.IsCreated) { NativeArray.Copy(_currentTailsBackup, 0, currentTails, offset, Logics.Length); + NativeArray.Copy(_nextTailsBackup, 0, nextTails, offset, Logics.Length); } else { @@ -177,12 +179,12 @@ namespace UniGLTF.SpringBoneJobs.InputPorts public void Dispose() { - if (IsDisposed) return; - IsDisposed = true; - Springs.Dispose(); - Joints.Dispose(); - Colliders.Dispose(); - Logics.Dispose(); + if (Springs.IsCreated) Springs.Dispose(); + if (Joints.IsCreated) Joints.Dispose(); + if (Colliders.IsCreated) Colliders.Dispose(); + if (Logics.IsCreated) Logics.Dispose(); + if (_currentTailsBackup.IsCreated) _currentTailsBackup.Dispose(); + if (_nextTailsBackup.IsCreated) _nextTailsBackup.Dispose(); } } } \ No newline at end of file From c983367f40849d5d3604a9f8be685b3c7709c9fe Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 19 Nov 2024 13:15:55 +0900 Subject: [PATCH 9/9] update comment --- .../FastSpringBoneConbinedBuffer.cs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs index ae66220b6..f06f3f70a 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs @@ -181,9 +181,6 @@ namespace UniGLTF.SpringBoneJobs transformOffset += buffer.Transforms.Length; } - // verlet の current, prev, next のバッファを今の transform の状態にする。 - // 速度は 0 にクリアする。 - // TODO: 速度の維持は SaveToSourceBuffer でされていたのだがデータ構造変更で場所が変わった handle = InitCurrentTails(handle); Profiler.EndSample(); @@ -328,12 +325,21 @@ namespace UniGLTF.SpringBoneJobs } } - /// - /// Transform から currentTail を更新。 - /// prevTail も同じ内容にする(速度0)。 + /// + /// # CurrentTails[i] == NAN + /// + /// Transforms から Current, Prev, Next を代入する。 + /// 速度 0 で初期化することになる。 + /// + /// # CurrentTails[i] != NAN + /// + /// 本処理はスキップされて Current, Next の利用が継続されます。 + /// + /// # NAN + /// + /// Batching 関数内の FastSpringBoneBuffer.RestoreCurrentTails にて backup の Current, Next が無かったときに + /// 目印として NAN が代入されます。 /// - /// - /// public JobHandle InitCurrentTails(JobHandle handle) { return new InitCurrentTailsJob