diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs index 685b5a389..cbfcd6b5e 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs @@ -54,7 +54,7 @@ namespace UniVRM10.ClothWarp.Jobs NativeArray _nextRotations; NativeArray _strandCollision; - NativeArray _clothCollisionCount; + // NativeArray _clothCollisionCount; NativeArray _clothCollision; NativeArray _forces; @@ -92,7 +92,7 @@ namespace UniVRM10.ClothWarp.Jobs if (_nextPositions.IsCreated) _nextPositions.Dispose(); if (_nextRotations.IsCreated) _nextRotations.Dispose(); if (_strandCollision.IsCreated) _strandCollision.Dispose(); - if (_clothCollisionCount.IsCreated) _clothCollisionCount.Dispose(); + // if (_clothCollisionCount.IsCreated) _clothCollisionCount.Dispose(); if (_clothCollision.IsCreated) _clothCollision.Dispose(); if (_forces.IsCreated) _forces.Dispose(); @@ -303,7 +303,7 @@ namespace UniVRM10.ClothWarp.Jobs _nextRotations = new(pos.Length, Allocator.Persistent); _info = new(info.ToArray(), Allocator.Persistent); _strandCollision = new(pos.Length, Allocator.Persistent); - _clothCollisionCount = new(pos.Length, Allocator.Persistent); + // _clothCollisionCount = new(pos.Length, Allocator.Persistent); _clothCollision = new(pos.Length, Allocator.Persistent); _forces = new(pos.Length, Allocator.Persistent); @@ -388,7 +388,7 @@ namespace UniVRM10.ClothWarp.Jobs CurrentPositions = _currentPositions, Forces = _forces, - CollisionCount = _clothCollisionCount, + // CollisionCount = _clothCollisionCount, CollisionDelta = _clothCollision, }.Schedule(_transformAccessArray, handle); @@ -448,7 +448,7 @@ namespace UniVRM10.ClothWarp.Jobs Info = _info, NextPositions = _nextPositions, - CollisionCount = _clothCollisionCount, + // CollisionCount = _clothCollisionCount, ClothCollision = _clothCollision, ClothRects = _clothRects, @@ -465,7 +465,7 @@ namespace UniVRM10.ClothWarp.Jobs { ClothUsedParticles = _clothUsedParticles, StrandCollision = _strandCollision, - ClothCollisionCount = _clothCollisionCount, + // ClothCollisionCount = _clothCollisionCount, ClothCollision = _clothCollision, NextPosition = _nextPositions, }.Schedule(_info.Length, 1, handle); diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Collision.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Collision.cs index edc995957..24d64376b 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Collision.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Collision.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using SphereTriangle; using UniGLTF.SpringBoneJobs.Blittables; using Unity.Collections; @@ -63,7 +62,7 @@ namespace UniVRM10.ClothWarp.Jobs if (c.colliderType == BlittableColliderType.Capsule) { - if (TryCollideCapsuleAndSphere(m.MultiplyPoint(c.offset), m.MultiplyPoint(c.tailOrNormal), c.radius, + 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); @@ -71,7 +70,7 @@ namespace UniVRM10.ClothWarp.Jobs } else { - if (TryCollideSphereAndSphere(m.MultiplyPoint(c.offset), c.radius, + if (SphereSphereCollision.TryCollideSphereAndSphere(m.MultiplyPoint(c.offset), c.radius, pos, info.Settings.radius, out var l)) { pos += l.GetDelta(c.radius); @@ -82,72 +81,6 @@ namespace UniVRM10.ClothWarp.Jobs StrandCollision[particleIndex] = pos; } } - - /// - /// collide sphere a and sphere b. - /// move sphere b to resolved if collide. - /// - /// - /// - /// - /// - /// - /// - static bool TryCollideSphereAndSphere( - in Vector3 from, float ra, - in Vector3 to, float rb, - out LineSegment resolved - ) - { - var d = Vector3.Distance(from, to); - if (d > (ra + rb)) - { - resolved = default; - return false; - } - Vector3 normal = (to - from).normalized; - resolved = new(from, from + normal * (d - rb)); - return true; - } - - /// - /// collide capsule and sphere b. - /// move sphere b to resolved if collide. - /// - /// - /// - /// - /// - /// - static bool TryCollideCapsuleAndSphere( - in Vector3 capsuleHead, - in Vector3 capsuleTail, - float capsuleRadius, - in Vector3 b, - float rb, - out LineSegment resolved - ) - { - var P = (capsuleTail - capsuleHead); - var Q = b - capsuleHead; - var dot = Vector3.Dot(P.normalized, Q); - if (dot <= 0) - { - // head側半球の球判定 - return TryCollideSphereAndSphere(capsuleHead, capsuleRadius, b, rb, out resolved); - } - - var t = dot / P.magnitude; - if (t >= 1.0f) - { - // tail側半球の球判定 - return TryCollideSphereAndSphere(capsuleTail, capsuleRadius, b, rb, out resolved); - } - - // head-tail上の m_transform.position との最近点 - var p = capsuleHead + P * t; - return TryCollideSphereAndSphere(p, capsuleRadius, b, rb, out resolved); - } } public struct ClothCollisionJob : IJobParallelFor @@ -159,7 +92,7 @@ namespace UniVRM10.ClothWarp.Jobs // particle [ReadOnly] public NativeArray Info; [ReadOnly] public NativeArray NextPositions; - [NativeDisableParallelForRestriction] public NativeArray CollisionCount; + // [NativeDisableParallelForRestriction] public NativeArray CollisionCount; [NativeDisableParallelForRestriction] public NativeArray ClothCollision; // cloth @@ -171,41 +104,10 @@ namespace UniVRM10.ClothWarp.Jobs [ReadOnly] public NativeArray ColliderGroup; [ReadOnly] public NativeArray ColliderRef; - private void CollisionMove(int particleIndex, LineSegment l, BlittableCollider c) - { -#if false - CollisionCount[particleIndex] = 1; - ClothCollision[particleIndex] = l.GetPoint(c.radius); -#else - var delta = l.GetDelta(c.radius); - -#if false - // 足して割る - CollisionCount[particleIndex] += 1; - CollisionDelta[particleIndex] += delta; -#elif false - // 足す - CollisionCount[particleIndex] = 1; - CollisionDelta[particleIndex] += delta; -#else - // max - if (delta.sqrMagnitude > ClothCollision[particleIndex].sqrMagnitude) - { - CollisionCount[particleIndex] = 1; - ClothCollision[particleIndex] = delta; - } -#endif -#endif - } - public void Execute(int rectIndex) { var (clothGridIndex, spring, rect) = ClothRects[rectIndex]; - // using (new ProfileSample("Rect: Prepare")) - // _s0.BeginFrame(); - // _s1.BeginFrame(); - var a = NextPositions[rect._a]; var b = NextPositions[rect._b]; var c = NextPositions[rect._c]; @@ -222,6 +124,7 @@ namespace UniVRM10.ClothWarp.Jobs var _triangle0 = new Triangle(a, b, c); var cloth = Cloths[clothGridIndex]; + for (int groupRefIndex = cloth.ColliderGroupRefRange.Start; groupRefIndex < cloth.ColliderGroupRefRange.End; ++groupRefIndex) { var groupIndex = ColliderGroupRef[groupRefIndex]; @@ -247,20 +150,34 @@ namespace UniVRM10.ClothWarp.Jobs // continue; // } - if (TryCollide(collider, collider_matrix, _triangle0, out var l0)) + var abc = TryCollide(collider, collider_matrix, _triangle0, out var l0); + var cda = TryCollide(collider, collider_matrix, _triangle1, out var l1); + if (abc && cda) { - CollisionMove(rect._a, l0, collider); - CollisionMove(rect._b, l0, collider); - CollisionMove(rect._c, l0, collider); + a += l0.GetDelta(collider.radius); + b += l0.GetDelta(collider.radius); + c += l1.GetDelta(collider.radius); + d += l1.GetDelta(collider.radius); } - if (TryCollide(collider, collider_matrix, _triangle1, out var l1)) + else if (abc) { - CollisionMove(rect._c, l1, collider); - CollisionMove(rect._d, l1, collider); - CollisionMove(rect._a, l1, collider); + a += l0.GetDelta(collider.radius); + b += l0.GetDelta(collider.radius); + c += l0.GetDelta(collider.radius); + } + else if (cda) + { + c += l1.GetDelta(collider.radius); + d += l1.GetDelta(collider.radius); + a += l1.GetDelta(collider.radius); } } } + + ClothCollision[rect._a] = a; + ClothCollision[rect._b] = b; + ClothCollision[rect._c] = c; + ClothCollision[rect._d] = d; } static bool TryCollide(BlittableCollider collider, in Matrix4x4 colliderMatrix, in Triangle t, out LineSegment l) @@ -351,7 +268,7 @@ namespace UniVRM10.ClothWarp.Jobs { [ReadOnly] public NativeArray ClothUsedParticles; [ReadOnly] public NativeArray StrandCollision; - [ReadOnly] public NativeArray ClothCollisionCount; + // [ReadOnly] public NativeArray ClothCollisionCount; [ReadOnly] public NativeArray ClothCollision; [NativeDisableParallelForRestriction] public NativeArray NextPosition; @@ -359,10 +276,10 @@ namespace UniVRM10.ClothWarp.Jobs { if (ClothUsedParticles[particleIndex]) { - if (ClothCollisionCount[particleIndex] > 0) + // if (ClothCollisionCount[particleIndex] > 0) { - NextPosition[particleIndex] += (ClothCollision[particleIndex] / ClothCollisionCount[particleIndex]); - // NextPosition[particleIndex] = ClothCollision[particleIndex]; + // NextPosition[particleIndex] += (ClothCollision[particleIndex] / ClothCollisionCount[particleIndex]); + NextPosition[particleIndex] = ClothCollision[particleIndex]; } } else diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Particle.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Particle.cs index a538655e2..a0923aaa5 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/SphereTriangle/SphereCapsuleCollision.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/SphereTriangle/SphereCapsuleCollision.cs new file mode 100644 index 000000000..864f48f89 --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/SphereTriangle/SphereCapsuleCollision.cs @@ -0,0 +1,74 @@ +using UnityEngine; + + +namespace SphereTriangle +{ + public static class SphereSphereCollision + { + /// + /// collide sphere a and sphere b. + /// move sphere b to resolved if collide. + /// + /// + /// + /// + /// + /// + /// + public static bool TryCollideSphereAndSphere( + in Vector3 from, float ra, + in Vector3 to, float rb, + out LineSegment resolved + ) + { + var d = Vector3.Distance(from, to); + if (d > (ra + rb)) + { + resolved = default; + return false; + } + Vector3 normal = (to - from).normalized; + resolved = new(from, from + normal * (d - rb)); + return true; + } + + /// + /// collide capsule and sphere b. + /// move sphere b to resolved if collide. + /// + /// + /// + /// + /// + /// + public static bool TryCollideCapsuleAndSphere( + in Vector3 capsuleHead, + in Vector3 capsuleTail, + float capsuleRadius, + in Vector3 b, + float rb, + out LineSegment resolved + ) + { + var P = (capsuleTail - capsuleHead); + var Q = b - capsuleHead; + var dot = Vector3.Dot(P.normalized, Q); + if (dot <= 0) + { + // head側半球の球判定 + return TryCollideSphereAndSphere(capsuleHead, capsuleRadius, b, rb, out resolved); + } + + var t = dot / P.magnitude; + if (t >= 1.0f) + { + // tail側半球の球判定 + return TryCollideSphereAndSphere(capsuleTail, capsuleRadius, b, rb, out resolved); + } + + // head-tail上の m_transform.position との最近点 + var p = capsuleHead + P * t; + return TryCollideSphereAndSphere(p, capsuleRadius, b, rb, out resolved); + } + } +} \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/SphereTriangle/SphereCapsuleCollision.cs.meta b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/SphereTriangle/SphereCapsuleCollision.cs.meta new file mode 100644 index 000000000..84898a359 --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/SphereTriangle/SphereCapsuleCollision.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 990d1e921d604e348ab7fd04216b01d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: