diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs
index 6e9f77614..b043f0133 100644
--- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs
+++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneBufferCombiner.cs
@@ -1,67 +1,26 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using Unity.Collections;
using Unity.Jobs;
-using UnityEngine;
-using UnityEngine.Jobs;
using UnityEngine.Profiling;
-using UniGLTF.SpringBoneJobs.Blittables;
using UniGLTF.SpringBoneJobs.InputPorts;
-#if ENABLE_SPRINGBONE_BURST
-using Unity.Burst;
-#endif
namespace UniGLTF.SpringBoneJobs
{
///
- /// FastSpringBoneの処理に利用するバッファを全て結合して持つクラス
+ /// CombinedBuffer 構築を管理する
+ ///
+ /// - FastSpringBoneBuffer(Vrm-1.0 一体分の情報)を登録・削除する。
+ /// - 再構築する。登録・削除後に反映するために呼び出す。
+ /// - (TODO) FastSpringBoneBuffer一体分の回転初期化を実行する。
+ ///
///
public sealed class FastSpringBoneBufferCombiner : IDisposable
{
- // 長さと index 同じ
- private NativeArray _logics;
- private NativeArray _joints;
-
- private NativeArray _prevTails;
- private NativeArray _currentTails;
- private NativeArray _nextTails;
-
- private NativeArray _springs;
-
- private NativeArray _colliders;
-
- private NativeArray _transforms;
- private TransformAccessArray _transformAccessArray;
-
+ private FastSpringBoneCombinedBuffer _combinedBuffer;
+ public FastSpringBoneCombinedBuffer Combined => _combinedBuffer;
private readonly LinkedList _buffers = new LinkedList();
- private FastSpringBoneBuffer[] _batchedBuffers;
- private int[] _batchedBufferLogicSizes;
-
private bool _isDirty;
-
- public NativeArray Logics => _logics;
- public NativeArray Joints => _joints;
- public NativeArray PrevTails => _prevTails;
- public NativeArray CurrentTails => _currentTails;
- public NativeArray NextTails => _nextTails;
-
- public NativeArray Springs => _springs;
-
- public NativeArray Colliders => _colliders;
-
- public NativeArray Transforms => _transforms;
- public TransformAccessArray TransformAccessArray => _transformAccessArray;
-
- public bool HasBuffer => _batchedBuffers != null && _batchedBuffers.Length > 0;
-
- public void FlipBuffer()
- {
- var tmp = _prevTails;
- _prevTails = _currentTails;
- _currentTails = _nextTails;
- _nextTails = tmp;
- }
+ public bool HasBuffer => _buffers.Count > 0 && _combinedBuffer != null;
public void Register(FastSpringBoneBuffer buffer)
{
@@ -90,27 +49,6 @@ namespace UniGLTF.SpringBoneJobs
return handle;
}
- ///
- /// バッチングされたバッファから、個々のバッファへと値を戻す
- /// バッファの再構築前にこの処理を行わないと、揺れの状態がリセットされてしまい、不自然な挙動になる
- ///
- private void SaveToSourceBuffer()
- {
- if (_batchedBuffers == null) return;
-
- 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;
- }
- }
-
///
/// バッファを再構築する
///
@@ -118,254 +56,31 @@ namespace UniGLTF.SpringBoneJobs
{
Profiler.BeginSample("FastSpringBone.ReconstructBuffers");
- Profiler.BeginSample("FastSpringBone.ReconstructBuffers.SaveToSourceBuffer");
- SaveToSourceBuffer();
- Profiler.EndSample();
-
Profiler.BeginSample("FastSpringBone.ReconstructBuffers.DisposeBuffers");
- DisposeAllBuffers();
- Profiler.EndSample();
-
- var springsCount = 0;
- var collidersCount = 0;
- var logicsCount = 0;
- var transformsCount = 0;
-
- Profiler.BeginSample("FastSpringBone.ReconstructBuffers.CopyToBatchedBuffers");
- _batchedBuffers = _buffers.ToArray();
- _batchedBufferLogicSizes = _batchedBuffers.Select(buffer => buffer.Logics.Length).ToArray();
- Profiler.EndSample();
-
- // バッファを数える
- Profiler.BeginSample("FastSpringBone.ReconstructBuffers.CountBufferSize");
- foreach (var buffer in _buffers)
+ if (_combinedBuffer is FastSpringBoneCombinedBuffer combined)
{
- springsCount += buffer.Springs.Length;
- collidersCount += buffer.Colliders.Length;
- logicsCount += buffer.Logics.Length;
- transformsCount += buffer.BlittableTransforms.Length;
+ Profiler.BeginSample("FastSpringBone.ReconstructBuffers.SaveToSourceBuffer");
+ combined.SaveToSourceBuffer();
+ Profiler.EndSample();
+
+ // TODO: Dispose せずに再利用?
+ combined.Dispose();
}
Profiler.EndSample();
- // バッファの構築
- Profiler.BeginSample("FastSpringBone.ReconstructBuffers.CreateBuffers");
-
- _logics = new NativeArray(logicsCount, Allocator.Persistent);
- _joints = new NativeArray(logicsCount, Allocator.Persistent);
- _prevTails = new NativeArray(logicsCount, Allocator.Persistent);
- _currentTails = new NativeArray(logicsCount, Allocator.Persistent);
- _nextTails = new NativeArray(logicsCount, Allocator.Persistent);
-
- _springs = new NativeArray(springsCount, Allocator.Persistent);
-
- _colliders = new NativeArray(collidersCount, Allocator.Persistent);
-
- _transforms = new NativeArray(transformsCount, Allocator.Persistent);
- Profiler.EndSample();
-
- Profiler.BeginSample("FastSpringBone.ReconstructBuffers.ScheduleLoadBufferJobs");
- var springsOffset = 0;
- var collidersOffset = 0;
- var logicsOffset = 0;
- var transformOffset = 0;
- for (var i = 0; i < _batchedBuffers.Length; i++)
- {
- var buffer = _batchedBuffers[i];
-
- // バッファの読み込みをスケジュール
- handle = new LoadTransformsJob
- {
- SrcTransforms = buffer.BlittableTransforms,
- DestTransforms = new NativeSlice(_transforms, transformOffset,
- buffer.BlittableTransforms.Length)
- }.Schedule(buffer.BlittableTransforms.Length, 1, handle);
-
- handle = new LoadSpringsJob
- {
- SrcSprings = buffer.Springs,
- DestSprings = new NativeSlice(_springs, springsOffset, buffer.Springs.Length),
- CollidersOffset = collidersOffset,
- LogicsOffset = logicsOffset,
- TransformOffset = transformOffset,
- }.Schedule(buffer.Springs.Length, 1, handle);
-
- handle = new LoadCollidersJob
- {
- SrcColliders = buffer.Colliders,
- DestColliders = new NativeSlice(_colliders, collidersOffset, buffer.Colliders.Length)
- }.Schedule(buffer.Colliders.Length, 1, handle);
-
- handle = new OffsetLogicsJob
- {
- SrcLogics = buffer.Logics,
- SrcJoints = buffer.Joints,
-
- DestLogics = new NativeSlice(_logics, logicsOffset, buffer.Logics.Length),
- DestJoints = new NativeSlice(_joints, logicsOffset, buffer.Logics.Length),
- }.Schedule(buffer.Logics.Length, 1, handle);
-
- springsOffset += buffer.Springs.Length;
- collidersOffset += buffer.Colliders.Length;
- logicsOffset += buffer.Logics.Length;
- transformOffset += buffer.BlittableTransforms.Length;
- }
-
- handle = InitCurrentTails(handle);
-
- // TransformAccessArrayの構築と並行してJobを行うため、この時点で走らせておく
- JobHandle.ScheduleBatchedJobs();
- Profiler.EndSample();
-
- // TransformAccessArrayの構築
- Profiler.BeginSample("FastSpringBone.ReconstructBuffers.LoadTransformAccessArray");
- var transforms = new Transform[transformsCount];
- 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();
+ handle = FastSpringBoneCombinedBuffer.Create(handle, _buffers, out _combinedBuffer);
Profiler.EndSample();
return handle;
}
- ///
- /// Transform から currentTail を更新。
- /// prevTail も同じ内容にする(速度0)。
- ///
- ///
- ///
- public JobHandle InitCurrentTails(JobHandle handle)
- {
- return new InitCurrentTailsJob
- {
- Logics = Logics,
- Transforms = Transforms,
- CurrentTails = CurrentTails,
- PrevTails = PrevTails,
- NextTails = NextTails,
- }.Schedule(Logics.Length, 1, handle);
- }
-
- private void DisposeAllBuffers()
- {
- if (_logics.IsCreated) _logics.Dispose();
- if (_joints.IsCreated) _joints.Dispose();
- if (_prevTails.IsCreated) _prevTails.Dispose();
- if (_currentTails.IsCreated) _currentTails.Dispose();
- if (_nextTails.IsCreated) _nextTails.Dispose();
- if (_springs.IsCreated) _springs.Dispose();
- if (_colliders.IsCreated) _colliders.Dispose();
- if (_transforms.IsCreated) _transforms.Dispose();
- if (_transformAccessArray.isCreated) _transformAccessArray.Dispose();
- }
-
public void Dispose()
{
- DisposeAllBuffers();
- }
-
-#if ENABLE_SPRINGBONE_BURST
- [BurstCompile]
-#endif
- private struct LoadTransformsJob : IJobParallelFor
- {
- [ReadOnly] public NativeArray SrcTransforms;
- [WriteOnly] public NativeSlice DestTransforms;
-
- public void Execute(int index)
+ if (_combinedBuffer is FastSpringBoneCombinedBuffer combined)
{
- DestTransforms[index] = SrcTransforms[index];
- }
- }
-
-#if ENABLE_SPRINGBONE_BURST
- [BurstCompile]
-#endif
- private struct LoadSpringsJob : IJobParallelFor
- {
- [ReadOnly] public NativeArray SrcSprings;
- [WriteOnly] public NativeSlice DestSprings;
-
- public int CollidersOffset;
- public int LogicsOffset;
- public int TransformOffset;
-
- public void Execute(int index)
- {
- var spring = SrcSprings[index];
- spring.colliderSpan.startIndex += CollidersOffset;
- spring.logicSpan.startIndex += LogicsOffset;
- spring.transformIndexOffset = TransformOffset;
- DestSprings[index] = spring;
- }
- }
-
-#if ENABLE_SPRINGBONE_BURST
- [BurstCompile]
-#endif
- private struct LoadCollidersJob : IJobParallelFor
- {
- [ReadOnly] public NativeArray SrcColliders;
- [WriteOnly] public NativeSlice DestColliders;
-
- public void Execute(int index)
- {
- DestColliders[index] = SrcColliders[index];
- }
- }
-
-#if ENABLE_SPRINGBONE_BURST
- [BurstCompile]
-#endif
- private struct OffsetLogicsJob : IJobParallelFor
- {
- [ReadOnly] public NativeSlice SrcLogics;
- [ReadOnly] public NativeSlice SrcJoints;
- [WriteOnly] public NativeSlice DestLogics;
- [WriteOnly] public NativeSlice DestJoints;
-
- public void Execute(int index)
- {
- DestLogics[index] = SrcLogics[index];
- DestJoints[index] = SrcJoints[index];
- }
- }
-
-#if ENABLE_SPRINGBONE_BURST
- [BurstCompile]
-#endif
- private struct InitCurrentTailsJob : IJobParallelFor
- {
- [ReadOnly] public NativeArray Logics;
- [ReadOnly] public NativeArray Transforms;
- [WriteOnly] public NativeSlice CurrentTails;
- [WriteOnly] public NativeSlice PrevTails;
- [WriteOnly] public NativeSlice NextTails;
-
- public void Execute(int jointIndex)
- {
- var tailIndex = Logics[jointIndex].tailTransformIndex;
- if (tailIndex == -1)
- {
- // 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;
- }
+ combined.Dispose();
+ _combinedBuffer = null;
}
}
}
diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs
new file mode 100644
index 000000000..e0d48ee78
--- /dev/null
+++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs
@@ -0,0 +1,334 @@
+#if ENABLE_SPRINGBONE_BURST
+using Unity.Burst;
+#endif
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UniGLTF.SpringBoneJobs.Blittables;
+using UniGLTF.SpringBoneJobs.InputPorts;
+using Unity.Collections;
+using Unity.Jobs;
+using UnityEngine;
+using UnityEngine.Jobs;
+using UnityEngine.Profiling;
+
+namespace UniGLTF.SpringBoneJobs
+{
+ ///
+ /// FastSpringBoneの処理に利用するバッファを全て結合して持つクラス
+ ///
+ public class FastSpringBoneCombinedBuffer : IDisposable
+ {
+ // 長さと index 同じ
+ private NativeArray _logics;
+ private NativeArray _joints;
+ private NativeArray _prevTails;
+ private NativeArray _currentTails;
+ private NativeArray _nextTails;
+
+ private NativeArray _springs;
+
+ private NativeArray _colliders;
+
+ private NativeArray _transforms;
+ private TransformAccessArray _transformAccessArray;
+
+ public NativeArray Logics => _logics;
+ public NativeArray Joints => _joints;
+ public NativeArray PrevTails => _prevTails;
+ public NativeArray CurrentTails => _currentTails;
+ public NativeArray NextTails => _nextTails;
+
+ public NativeArray Springs => _springs;
+
+ public NativeArray Colliders => _colliders;
+
+ public NativeArray Transforms => _transforms;
+ public TransformAccessArray TransformAccessArray => _transformAccessArray;
+
+ // 構築情報
+ private FastSpringBoneBuffer[] _batchedBuffers;
+ private int[] _batchedBufferLogicSizes;
+
+ private FastSpringBoneCombinedBuffer(int logicsCount, int springsCount, int collidersCount, int transformsCount,
+ FastSpringBoneBuffer[] batchedBuffers,
+ int[] batchedBufferLogicSizes
+ )
+ {
+ _logics = new NativeArray(logicsCount, Allocator.Persistent);
+ _joints = new NativeArray(logicsCount, Allocator.Persistent);
+ _prevTails = new NativeArray(logicsCount, Allocator.Persistent);
+ _currentTails = new NativeArray(logicsCount, Allocator.Persistent);
+ _nextTails = new NativeArray(logicsCount, Allocator.Persistent);
+ _springs = new NativeArray(springsCount, Allocator.Persistent);
+ _colliders = new NativeArray(collidersCount, Allocator.Persistent);
+ _transforms = new NativeArray(transformsCount, Allocator.Persistent);
+ _batchedBuffers = batchedBuffers;
+ _batchedBufferLogicSizes = batchedBufferLogicSizes;
+ }
+
+ internal static JobHandle Create(JobHandle handle,
+ LinkedList _buffers, out FastSpringBoneCombinedBuffer combined)
+ {
+ Profiler.BeginSample("FastSpringBone.ReconstructBuffers.CopyToBatchedBuffers");
+ var batchedBuffers = _buffers.ToArray();
+ var batchedBufferLogicSizes = batchedBuffers.Select(buffer => buffer.Logics.Length).ToArray();
+ Profiler.EndSample();
+
+ // バッファを数える
+ Profiler.BeginSample("FastSpringBone.ReconstructBuffers.CountBufferSize");
+ var springsCount = 0;
+ var collidersCount = 0;
+ var logicsCount = 0;
+ var transformsCount = 0;
+ foreach (var buffer in _buffers)
+ {
+ springsCount += buffer.Springs.Length;
+ collidersCount += buffer.Colliders.Length;
+ logicsCount += buffer.Logics.Length;
+ transformsCount += buffer.BlittableTransforms.Length;
+ }
+ Profiler.EndSample();
+
+ // バッファの構築
+ Profiler.BeginSample("FastSpringBone.ReconstructBuffers.CreateBuffers");
+ combined = new FastSpringBoneCombinedBuffer(logicsCount, springsCount, collidersCount, transformsCount,
+ batchedBuffers, batchedBufferLogicSizes);
+ Profiler.EndSample();
+
+ return combined.Batching(handle);
+ }
+
+ private JobHandle Batching(JobHandle handle)
+ {
+ Profiler.BeginSample("FastSpringBone.ReconstructBuffers.ScheduleLoadBufferJobs");
+ var springsOffset = 0;
+ var collidersOffset = 0;
+ var logicsOffset = 0;
+ var transformOffset = 0;
+ for (var i = 0; i < _batchedBuffers.Length; i++)
+ {
+ var buffer = _batchedBuffers[i];
+
+ // バッファの読み込みをスケジュール
+ handle = new LoadTransformsJob
+ {
+ SrcTransforms = buffer.BlittableTransforms,
+ DestTransforms = new NativeSlice(_transforms, transformOffset,
+ buffer.BlittableTransforms.Length)
+ }.Schedule(buffer.BlittableTransforms.Length, 1, handle);
+
+ handle = new LoadSpringsJob
+ {
+ SrcSprings = buffer.Springs,
+ DestSprings = new NativeSlice(_springs, springsOffset, buffer.Springs.Length),
+ CollidersOffset = collidersOffset,
+ LogicsOffset = logicsOffset,
+ TransformOffset = transformOffset,
+ }.Schedule(buffer.Springs.Length, 1, handle);
+
+ handle = new LoadCollidersJob
+ {
+ SrcColliders = buffer.Colliders,
+ DestColliders = new NativeSlice(_colliders, collidersOffset, buffer.Colliders.Length)
+ }.Schedule(buffer.Colliders.Length, 1, handle);
+
+ handle = new OffsetLogicsJob
+ {
+ SrcLogics = buffer.Logics,
+ SrcJoints = buffer.Joints,
+
+ DestLogics = new NativeSlice(_logics, logicsOffset, buffer.Logics.Length),
+ DestJoints = new NativeSlice(_joints, logicsOffset, buffer.Logics.Length),
+ }.Schedule(buffer.Logics.Length, 1, handle);
+
+ springsOffset += buffer.Springs.Length;
+ collidersOffset += buffer.Colliders.Length;
+ logicsOffset += buffer.Logics.Length;
+ transformOffset += buffer.BlittableTransforms.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;
+ }
+
+ public void Dispose()
+ {
+ if (_logics.IsCreated) _logics.Dispose();
+ if (_joints.IsCreated) _joints.Dispose();
+ if (_prevTails.IsCreated) _prevTails.Dispose();
+ if (_currentTails.IsCreated) _currentTails.Dispose();
+ if (_nextTails.IsCreated) _nextTails.Dispose();
+ if (_springs.IsCreated) _springs.Dispose();
+ if (_colliders.IsCreated) _colliders.Dispose();
+ if (_transforms.IsCreated) _transforms.Dispose();
+ 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;
+ _prevTails = _currentTails;
+ _currentTails = _nextTails;
+ _nextTails = tmp;
+ }
+
+#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
+ private struct LoadSpringsJob : IJobParallelFor
+ {
+ [ReadOnly] public NativeArray SrcSprings;
+ [WriteOnly] public NativeSlice DestSprings;
+
+ public int CollidersOffset;
+ public int LogicsOffset;
+ public int TransformOffset;
+
+ public void Execute(int index)
+ {
+ var spring = SrcSprings[index];
+ spring.colliderSpan.startIndex += CollidersOffset;
+ spring.logicSpan.startIndex += LogicsOffset;
+ spring.transformIndexOffset = TransformOffset;
+ DestSprings[index] = spring;
+ }
+ }
+
+#if ENABLE_SPRINGBONE_BURST
+ [BurstCompile]
+#endif
+ private struct LoadCollidersJob : IJobParallelFor
+ {
+ [ReadOnly] public NativeArray SrcColliders;
+ [WriteOnly] public NativeSlice DestColliders;
+
+ public void Execute(int index)
+ {
+ DestColliders[index] = SrcColliders[index];
+ }
+ }
+
+#if ENABLE_SPRINGBONE_BURST
+ [BurstCompile]
+#endif
+ private struct OffsetLogicsJob : IJobParallelFor
+ {
+ [ReadOnly] public NativeSlice SrcLogics;
+ [ReadOnly] public NativeSlice SrcJoints;
+ [WriteOnly] public NativeSlice DestLogics;
+ [WriteOnly] public NativeSlice DestJoints;
+
+ public void Execute(int index)
+ {
+ DestLogics[index] = SrcLogics[index];
+ DestJoints[index] = SrcJoints[index];
+ }
+ }
+
+#if ENABLE_SPRINGBONE_BURST
+ [BurstCompile]
+#endif
+ private struct InitCurrentTailsJob : IJobParallelFor
+ {
+ [ReadOnly] public NativeArray Logics;
+ [ReadOnly] public NativeArray Transforms;
+ [WriteOnly] public NativeSlice CurrentTails;
+ [WriteOnly] public NativeSlice PrevTails;
+ [WriteOnly] public NativeSlice NextTails;
+
+ public void Execute(int jointIndex)
+ {
+ var tailIndex = Logics[jointIndex].tailTransformIndex;
+ if (tailIndex == -1)
+ {
+ // 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;
+ }
+ }
+ }
+
+ ///
+ /// Transform から currentTail を更新。
+ /// prevTail も同じ内容にする(速度0)。
+ ///
+ ///
+ ///
+ public JobHandle InitCurrentTails(JobHandle handle)
+ {
+ return new InitCurrentTailsJob
+ {
+ Logics = Logics,
+ Transforms = Transforms,
+ CurrentTails = CurrentTails,
+ PrevTails = PrevTails,
+ NextTails = NextTails,
+ }.Schedule(Logics.Length, 1, handle);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs.meta
new file mode 100644
index 000000000..b87ad2247
--- /dev/null
+++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0485fe3392c9d0246bfb6b44720b8153
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneScheduler.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneScheduler.cs
index b35e7ec99..825707b48 100644
--- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneScheduler.cs
+++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneScheduler.cs
@@ -26,30 +26,33 @@ namespace UniGLTF.SpringBoneJobs
return handle;
}
- handle = new PullTransformJob
+ if (_bufferCombiner.Combined is FastSpringBoneCombinedBuffer combined)
{
- Transforms = _bufferCombiner.Transforms
- }.Schedule(_bufferCombiner.TransformAccessArray, handle);
+ handle = new PullTransformJob
+ {
+ Transforms = combined.Transforms
+ }.Schedule(combined.TransformAccessArray, handle);
- _bufferCombiner.FlipBuffer();
+ combined.FlipBuffer();
- handle = new UpdateFastSpringBoneJob
- {
- Joints = _bufferCombiner.Joints,
- Logics = _bufferCombiner.Logics,
- CurrentTail = _bufferCombiner.CurrentTails,
- PrevTail = _bufferCombiner.PrevTails,
- NextTail = _bufferCombiner.NextTails,
- Springs = _bufferCombiner.Springs,
- Colliders = _bufferCombiner.Colliders,
- Transforms = _bufferCombiner.Transforms,
- DeltaTime = deltaTime,
- }.Schedule(_bufferCombiner.Springs.Length, 1, handle);
+ handle = new UpdateFastSpringBoneJob
+ {
+ Joints = combined.Joints,
+ Logics = combined.Logics,
+ CurrentTail = combined.CurrentTails,
+ PrevTail = combined.PrevTails,
+ NextTail = combined.NextTails,
+ Springs = combined.Springs,
+ Colliders = combined.Colliders,
+ Transforms = combined.Transforms,
+ DeltaTime = deltaTime,
+ }.Schedule(combined.Springs.Length, 1, handle);
- handle = new PushTransformJob
- {
- Transforms = _bufferCombiner.Transforms
- }.Schedule(_bufferCombiner.TransformAccessArray, handle);
+ handle = new PushTransformJob
+ {
+ Transforms = combined.Transforms
+ }.Schedule(combined.TransformAccessArray, handle);
+ }
return handle;
}