diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs index cbfcd6b5e..dd89344f3 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs @@ -53,9 +53,9 @@ namespace UniVRM10.ClothWarp.Jobs NativeArray _nextPositions; NativeArray _nextRotations; - NativeArray _strandCollision; - // NativeArray _clothCollisionCount; - NativeArray _clothCollision; + NativeArray _warpCollision; + NativeArray _rectCollisionCount; + NativeArray _rectCollisionDelta; NativeArray _forces; // @@ -68,6 +68,7 @@ namespace UniVRM10.ClothWarp.Jobs // NativeArray _clothUsedParticles; NativeArray<(int ClothGridIndex, SpringConstraint SpringConstraint, SphereTriangle.ClothRect Rect)> _clothRects; + NativeArray<(Vector3, Vector3, Vector3, Vector3)> _clothRectResults; // // cloth grid @@ -91,9 +92,9 @@ namespace UniVRM10.ClothWarp.Jobs if (_prevPositions.IsCreated) _prevPositions.Dispose(); if (_nextPositions.IsCreated) _nextPositions.Dispose(); if (_nextRotations.IsCreated) _nextRotations.Dispose(); - if (_strandCollision.IsCreated) _strandCollision.Dispose(); - // if (_clothCollisionCount.IsCreated) _clothCollisionCount.Dispose(); - if (_clothCollision.IsCreated) _clothCollision.Dispose(); + if (_warpCollision.IsCreated) _warpCollision.Dispose(); + if (_rectCollisionCount.IsCreated) _rectCollisionCount.Dispose(); + if (_rectCollisionDelta.IsCreated) _rectCollisionDelta.Dispose(); if (_forces.IsCreated) _forces.Dispose(); if (_warps.IsCreated) _warps.Dispose(); @@ -101,6 +102,7 @@ namespace UniVRM10.ClothWarp.Jobs if (_clothUsedParticles.IsCreated) _clothUsedParticles.Dispose(); if (_clothRects.IsCreated) _clothRects.Dispose(); + if (_clothRectResults.IsCreated) _clothRectResults.Dispose(); } (int index, bool isNew) GetTransformIndex(Transform t, @@ -302,9 +304,9 @@ namespace UniVRM10.ClothWarp.Jobs _nextPositions = new(pos.Length, Allocator.Persistent); _nextRotations = new(pos.Length, Allocator.Persistent); _info = new(info.ToArray(), Allocator.Persistent); - _strandCollision = new(pos.Length, Allocator.Persistent); - // _clothCollisionCount = new(pos.Length, Allocator.Persistent); - _clothCollision = new(pos.Length, Allocator.Persistent); + _warpCollision = new(pos.Length, Allocator.Persistent); + _rectCollisionCount = new(pos.Length, Allocator.Persistent); + _rectCollisionDelta = new(pos.Length, Allocator.Persistent); _forces = new(pos.Length, Allocator.Persistent); // @@ -312,6 +314,7 @@ namespace UniVRM10.ClothWarp.Jobs // var clothRects = new ClothRectList(_transforms, vrm); _clothRects = new(clothRects.List.ToArray(), Allocator.Persistent); + _clothRectResults = new(clothRects.List.Count, Allocator.Persistent); _clothUsedParticles = new(clothRects.ClothUsedParticles, Allocator.Persistent); _building = false; @@ -388,8 +391,8 @@ namespace UniVRM10.ClothWarp.Jobs CurrentPositions = _currentPositions, Forces = _forces, - // CollisionCount = _clothCollisionCount, - CollisionDelta = _clothCollision, + CollisionCount = _rectCollisionCount, + CollisionDelta = _rectCollisionDelta, }.Schedule(_transformAccessArray, handle); // spring(cloth weft) @@ -425,7 +428,7 @@ namespace UniVRM10.ClothWarp.Jobs // collision { - var handle0 = new StrandCollisionJob + var handle0 = new WarpCollisionJob { Colliders = _colliderInfo, CurrentColliders = _currentColliders, @@ -433,7 +436,7 @@ namespace UniVRM10.ClothWarp.Jobs Info = _info, NextPositions = _nextPositions, ClothUsedParticles = _clothUsedParticles, - StrandCollision = _strandCollision, + StrandCollision = _warpCollision, Warps = _warps, ColliderGroupRef = _colliderGroupRef, @@ -441,17 +444,16 @@ namespace UniVRM10.ClothWarp.Jobs ColliderRef = _colliderRef, }.Schedule(_info.Length, 1, handle); - var handle1 = new ClothCollisionJob + var handle1 = new RectCollisionJob { + ClothRects = _clothRects, + ClothRectResults = _clothRectResults, + Colliders = _colliderInfo, CurrentColliders = _currentColliders, Info = _info, NextPositions = _nextPositions, - // CollisionCount = _clothCollisionCount, - ClothCollision = _clothCollision, - - ClothRects = _clothRects, Cloths = _cloths, ColliderGroupRef = _colliderGroupRef, @@ -459,14 +461,24 @@ namespace UniVRM10.ClothWarp.Jobs ColliderRef = _colliderRef, }.Schedule(_clothRects.Length, 1, handle); + handle1 = new RectCollisionReduceJob + { + ClothRects = _clothRects, + ClothRectResults = _clothRectResults, + NextPositions = _nextPositions, + + RectCollisionCount = _rectCollisionCount, + RectCollisionDelta = _rectCollisionDelta, + }.Schedule(handle1); + handle = JobHandle.CombineDependencies(handle0, handle1); handle = new CollisionApplyJob { ClothUsedParticles = _clothUsedParticles, - StrandCollision = _strandCollision, - // ClothCollisionCount = _clothCollisionCount, - ClothCollision = _clothCollision, + StrandCollision = _warpCollision, + RectCollisionCount = _rectCollisionCount, + RectCollisionDelta = _rectCollisionDelta, NextPosition = _nextPositions, }.Schedule(_info.Length, 1, handle); } diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/CollisionJobs.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/CollisionJobs.cs new file mode 100644 index 000000000..92e488dee --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/CollisionJobs.cs @@ -0,0 +1,51 @@ +using Unity.Collections; +using Unity.Jobs; +using UnityEngine; +using UnityEngine.Jobs; + + +namespace UniVRM10.ClothWarp.Jobs +{ + public struct ClothInfo + { + public ArrayRange ColliderGroupRefRange; + } + + public struct InputColliderJob : IJobParallelForTransform + { + [WriteOnly] public NativeArray CurrentCollider; + + public void Execute(int colliderIndex, TransformAccess transform) + { + CurrentCollider[colliderIndex] = transform.localToWorldMatrix; + } + } + + public struct CollisionApplyJob : IJobParallelFor + { + [ReadOnly] public NativeArray ClothUsedParticles; + [ReadOnly] public NativeArray StrandCollision; + + [ReadOnly] public NativeArray RectCollisionCount; + [ReadOnly] public NativeArray RectCollisionDelta; + public NativeArray NextPosition; + + public void Execute(int particleIndex) + { + if (ClothUsedParticles[particleIndex]) + { + var count = RectCollisionCount[particleIndex]; + if (count > 0) + { + // 一つの頂点が最大で近接する4つの rect で当たり判定をされる + // 衝突結果を足して割る + NextPosition[particleIndex] += RectCollisionDelta[particleIndex] / count; + } + } + else + { + NextPosition[particleIndex] = StrandCollision[particleIndex]; + } + } + } +} \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Collision.cs.meta b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/CollisionJobs.cs.meta similarity index 100% rename from Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Collision.cs.meta rename to Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/CollisionJobs.cs.meta diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Particle.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Particle.cs index a0923aaa5..a538655e2 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Particle.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Particle.cs @@ -43,7 +43,7 @@ namespace UniVRM10.ClothWarp.Jobs [WriteOnly] public NativeArray InputData; [WriteOnly] public NativeArray CurrentPositions; - // [WriteOnly] public NativeArray CollisionCount; + [WriteOnly] public NativeArray CollisionCount; [WriteOnly] public NativeArray CollisionDelta; [WriteOnly] public NativeArray Forces; @@ -59,7 +59,7 @@ namespace UniVRM10.ClothWarp.Jobs } // clear cloth - // CollisionCount[particleIndex] = 0; + CollisionCount[particleIndex] = 0; CollisionDelta[particleIndex] = Vector3.zero; Forces[particleIndex] = Vector3.zero; } diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Collision.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/RectCollisionJob.cs similarity index 62% rename from Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Collision.cs rename to Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/RectCollisionJob.cs index 24d64376b..cbaff22d8 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Collision.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/RectCollisionJob.cs @@ -4,99 +4,23 @@ using UniGLTF.SpringBoneJobs.Blittables; using Unity.Collections; using Unity.Jobs; using UnityEngine; -using UnityEngine.Jobs; namespace UniVRM10.ClothWarp.Jobs { - public struct ClothInfo + public struct RectCollisionJob : IJobParallelFor { - public ArrayRange ColliderGroupRefRange; - } - - public struct InputColliderJob : IJobParallelForTransform - { - [WriteOnly] public NativeArray CurrentCollider; - - public void Execute(int colliderIndex, TransformAccess transform) - { - CurrentCollider[colliderIndex] = transform.localToWorldMatrix; - } - } - - public struct StrandCollisionJob : IJobParallelFor - { - // collider - [ReadOnly] public NativeArray Colliders; - [ReadOnly] public NativeArray CurrentColliders; - - // particle - [ReadOnly] public NativeArray Info; - [ReadOnly] public NativeArray NextPositions; - [ReadOnly] public NativeArray ClothUsedParticles; - [WriteOnly] public NativeArray StrandCollision; - - // collider group - [ReadOnly] public NativeArray Warps; - [ReadOnly] public NativeArray ColliderGroupRef; - [ReadOnly] public NativeArray ColliderGroup; - [ReadOnly] public NativeArray ColliderRef; - - public void Execute(int particleIndex) - { - if (!ClothUsedParticles[particleIndex]) - { - var info = Info[particleIndex]; - var pos = NextPositions[particleIndex]; - var warp = Warps[info.WarpIndex]; - - for (int groupRefIndex = warp.ColliderGroupRefRange.Start; groupRefIndex < warp.ColliderGroupRefRange.End; ++groupRefIndex) - { - var groupIndex = ColliderGroupRef[groupRefIndex]; - var group = ColliderGroup[groupIndex]; - for (int colliderRefIndex = group.Start; colliderRefIndex < group.End; ++colliderRefIndex) - { - var colliderIndex = ColliderRef[colliderRefIndex]; - var c = Colliders[colliderIndex]; - var m = CurrentColliders[c.transformIndex]; - - if (c.colliderType == BlittableColliderType.Capsule) - { - if (SphereSphereCollision.TryCollideCapsuleAndSphere(m.MultiplyPoint(c.offset), m.MultiplyPoint(c.tailOrNormal), c.radius, - pos, info.Settings.radius, out var l)) - { - pos += l.GetDelta(c.radius); - } - } - else - { - if (SphereSphereCollision.TryCollideSphereAndSphere(m.MultiplyPoint(c.offset), c.radius, - pos, info.Settings.radius, out var l)) - { - pos += l.GetDelta(c.radius); - } - } - } - } - StrandCollision[particleIndex] = pos; - } - } - } - - public struct ClothCollisionJob : IJobParallelFor - { - // collider - [ReadOnly] public NativeArray Colliders; - [ReadOnly] public NativeArray CurrentColliders; - - // particle - [ReadOnly] public NativeArray Info; - [ReadOnly] public NativeArray NextPositions; - // [NativeDisableParallelForRestriction] public NativeArray CollisionCount; - [NativeDisableParallelForRestriction] public NativeArray ClothCollision; - // cloth [ReadOnly] public NativeArray<(int, SpringConstraint, ClothRect)> ClothRects; + [WriteOnly] public NativeArray<(Vector3, Vector3, Vector3, Vector3)> ClothRectResults; + + // collider + [ReadOnly] public NativeArray Colliders; + [ReadOnly] public NativeArray CurrentColliders; + + // particle + [ReadOnly] public NativeArray Info; + [ReadOnly] public NativeArray NextPositions; // collider group [ReadOnly] public NativeArray Cloths; @@ -174,10 +98,7 @@ namespace UniVRM10.ClothWarp.Jobs } } - ClothCollision[rect._a] = a; - ClothCollision[rect._b] = b; - ClothCollision[rect._c] = c; - ClothCollision[rect._d] = d; + ClothRectResults[rectIndex] = (a, b, c, d); } static bool TryCollide(BlittableCollider collider, in Matrix4x4 colliderMatrix, in Triangle t, out LineSegment l) @@ -261,30 +182,43 @@ namespace UniVRM10.ClothWarp.Jobs throw new NotImplementedException(); } } - } - public struct CollisionApplyJob : IJobParallelFor + public struct RectCollisionReduceJob : IJob { - [ReadOnly] public NativeArray ClothUsedParticles; - [ReadOnly] public NativeArray StrandCollision; - // [ReadOnly] public NativeArray ClothCollisionCount; - [ReadOnly] public NativeArray ClothCollision; - [NativeDisableParallelForRestriction] public NativeArray NextPosition; + [ReadOnly] public NativeArray<(int, SpringConstraint, ClothRect)> ClothRects; + [ReadOnly] public NativeArray<(Vector3, Vector3, Vector3, Vector3)> ClothRectResults; + [ReadOnly] public NativeArray NextPositions; - public void Execute(int particleIndex) + public NativeArray RectCollisionCount; + public NativeArray RectCollisionDelta; + public void Execute() { - if (ClothUsedParticles[particleIndex]) + for (int rectIndex = 0; rectIndex < ClothRects.Length; ++rectIndex) { - // if (ClothCollisionCount[particleIndex] > 0) + var (clothGridIndex, spring, rect) = ClothRects[rectIndex]; + var (a, b, c, d) = ClothRectResults[rectIndex]; + + if (a != NextPositions[rect._a]) { - // NextPosition[particleIndex] += (ClothCollision[particleIndex] / ClothCollisionCount[particleIndex]); - NextPosition[particleIndex] = ClothCollision[particleIndex]; + RectCollisionDelta[rect._a] += a - NextPositions[rect._a]; + RectCollisionCount[rect._a] += 1; + } + if (b != NextPositions[rect._b]) + { + RectCollisionDelta[rect._b] += b - NextPositions[rect._b]; + RectCollisionCount[rect._b] += 1; + } + if (c != NextPositions[rect._c]) + { + RectCollisionDelta[rect._c] += c - NextPositions[rect._c]; + RectCollisionCount[rect._c] += 1; + } + if (d != NextPositions[rect._d]) + { + RectCollisionDelta[rect._d] += d - NextPositions[rect._d]; + RectCollisionCount[rect._d] += 1; } - } - else - { - NextPosition[particleIndex] = StrandCollision[particleIndex]; } } } diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/RectCollisionJob.cs.meta b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/RectCollisionJob.cs.meta new file mode 100644 index 000000000..05a6d562a --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/RectCollisionJob.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 127d372d227187449960f33a08791017 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/WarpCollisionJob.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/WarpCollisionJob.cs new file mode 100644 index 000000000..e8905c32e --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/WarpCollisionJob.cs @@ -0,0 +1,68 @@ +using SphereTriangle; +using UniGLTF.SpringBoneJobs.Blittables; +using Unity.Collections; +using Unity.Jobs; +using UnityEngine; + + +namespace UniVRM10.ClothWarp.Jobs +{ + public struct WarpCollisionJob : IJobParallelFor + { + // collider + [ReadOnly] public NativeArray Colliders; + [ReadOnly] public NativeArray CurrentColliders; + + // particle + [ReadOnly] public NativeArray Info; + [ReadOnly] public NativeArray NextPositions; + [ReadOnly] public NativeArray ClothUsedParticles; + [WriteOnly] public NativeArray StrandCollision; + + // collider group + [ReadOnly] public NativeArray Warps; + [ReadOnly] public NativeArray ColliderGroupRef; + [ReadOnly] public NativeArray ColliderGroup; + [ReadOnly] public NativeArray ColliderRef; + + public void Execute(int particleIndex) + { + if (!ClothUsedParticles[particleIndex]) + { + var info = Info[particleIndex]; + var pos = NextPositions[particleIndex]; + var warp = Warps[info.WarpIndex]; + + for (int groupRefIndex = warp.ColliderGroupRefRange.Start; groupRefIndex < warp.ColliderGroupRefRange.End; ++groupRefIndex) + { + var groupIndex = ColliderGroupRef[groupRefIndex]; + var group = ColliderGroup[groupIndex]; + for (int colliderRefIndex = group.Start; colliderRefIndex < group.End; ++colliderRefIndex) + { + var colliderIndex = ColliderRef[colliderRefIndex]; + var c = Colliders[colliderIndex]; + var m = CurrentColliders[c.transformIndex]; + + if (c.colliderType == BlittableColliderType.Capsule) + { + if (SphereSphereCollision.TryCollideCapsuleAndSphere(m.MultiplyPoint(c.offset), m.MultiplyPoint(c.tailOrNormal), c.radius, + pos, info.Settings.radius, out var l)) + { + pos += l.GetDelta(c.radius); + } + } + else + { + if (SphereSphereCollision.TryCollideSphereAndSphere(m.MultiplyPoint(c.offset), c.radius, + pos, info.Settings.radius, out var l)) + { + pos += l.GetDelta(c.radius); + } + } + } + } + StrandCollision[particleIndex] = pos; + } + } + } +} \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/WarpCollisionJob.cs.meta b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/WarpCollisionJob.cs.meta new file mode 100644 index 000000000..c9e81c334 --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/WarpCollisionJob.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80e53200fa3841748ad1d1416efdd53b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: