diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs index 482707acc..a63d513fd 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs @@ -28,12 +28,36 @@ namespace UniVRM10 public Vector3 Normal = Vector3.up; + public Vector3 HeadWorldPosition => transform.TransformPoint(Offset); + public Vector3 TailWorldPosition => transform.TransformPoint(TailOrNormal); public Vector3 TailOrNormal => ColliderType == VRM10SpringBoneColliderTypes.Plane ? Normal : Tail; public static int SelectedGuid; public bool IsSelected => GetInstanceID() == SelectedGuid; + public Bounds GetBounds() + { + switch (ColliderType) + { + case VRM10SpringBoneColliderTypes.Capsule: + { + var h = HeadWorldPosition; + var t = TailWorldPosition; + var d = h - t; + var aabb = new Bounds((h + t) * 0.5f, new Vector3(Mathf.Abs(d.x), Mathf.Abs(d.y), Mathf.Abs(d.z))); + aabb.Expand(Radius * 2); + return aabb; + } + + case VRM10SpringBoneColliderTypes.Sphere: + return new Bounds(HeadWorldPosition, new Vector3(Radius, Radius, Radius)); + + default: + throw new NotImplementedException(); + } + } + void OnDrawGizmosSelected() { DrawGizmos(); diff --git a/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewerUI.cs b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewerUI.cs index 98aee7693..15c8b982b 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewerUI.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewerUI.cs @@ -552,7 +552,11 @@ namespace UniVRM10.Cloth.Viewer void OnInit(RotateParticle.RotateParticleSystem system, Vrm10Instance vrm) { var animator = vrm.GetComponent(); - HumanoidCollider.AddColliders(system._colliderGroups, animator); + if (vrm.SpringBone.ColliderGroups.Count == 0) + { + HumanoidCollider.AddColliders(animator); + } + try { ClothGuess.Guess(animator); diff --git a/Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs b/Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs index 4cc67093d..f10d943d0 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs @@ -23,51 +23,31 @@ namespace UniVRM10.Cloth.Viewer ("Arm", HumanBodyBones.RightHand, HumanBodyBones.RightMiddleProximal, 0.02f), }; - public static void AddColliders(List _colliderGroups, Animator animator) + public static void AddColliders(Animator animator) { - foreach (var (group, head, tail, radius) in Capsules) - { - AddColliderIfNotExists(_colliderGroups, group, - animator.GetBoneTransform(head), - animator.GetBoneTransform(tail), - radius); - } - } + Dictionary map = new(); - static void AddColliderIfNotExists(List _colliderGroups, string groupName, - Transform head, Transform tail, float radius) - { - ColliderGroup group = default; - foreach (var g in _colliderGroups) + foreach (var (group, _head, _tail, radius) in Capsules) { - if (g.Name == groupName) + if (!map.ContainsKey(group)) { - group = g; - break; + var g = animator.gameObject.AddComponent(); + map.Add(group, g); + } + + + var head = animator.GetBoneTransform(_head); + var vrmCollider = head.gameObject.AddComponent(); + if (vrmCollider != null) + { + vrmCollider.Radius = radius; + vrmCollider.ColliderType = VRM10SpringBoneColliderTypes.Capsule; + var tail = animator.GetBoneTransform(_tail); + vrmCollider.Tail = head.worldToLocalMatrix.MultiplyPoint(tail.position); + + map[group].Colliders.Add(vrmCollider); } } - if (group == null) - { - group = new ColliderGroup { Name = groupName }; - _colliderGroups.Add(group); - } - - foreach (var collider in group.Colliders) - { - if (collider._vrm.transform == head) - { - return; - } - } - - var vrmCollider = head.gameObject.AddComponent(); - vrmCollider.Radius = radius; - vrmCollider.ColliderType = VRM10SpringBoneColliderTypes.Capsule; - vrmCollider.Tail = head.worldToLocalMatrix.MultiplyPoint(tail.position); - - var c = new SphereCapsuleCollider(vrmCollider); - // c.GizmoColor = GetGizmoColor(group); - group.Colliders.Add(c); } static T GetOrAddComponent(GameObject o) where T : Component diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/Components/RotateParticleRuntimeProvider.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/Components/RotateParticleRuntimeProvider.cs index 56f1b3ed3..5ee13cbde 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/Components/RotateParticleRuntimeProvider.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/Components/RotateParticleRuntimeProvider.cs @@ -15,9 +15,11 @@ namespace RotateParticle.Components [SerializeField] public List Cloths = new(); + IVrm10SpringBoneRuntime m_runtime; public IVrm10SpringBoneRuntime CreateSpringBoneRuntime() { - return new RotateParticleSpringboneRuntime(); + m_runtime = new RotateParticleSpringboneRuntime(); + return m_runtime; } public void Reset() @@ -25,5 +27,14 @@ namespace RotateParticle.Components Warps = GetComponentsInChildren().ToList(); Cloths = GetComponentsInChildren().ToList(); } + + void OnDrawGizmos() + { + if (m_runtime == null) + { + return; + } + m_runtime.DrawGizmos(); + } } } \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSpringboneRuntime.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSpringboneRuntime.cs index 63acfb025..4561decad 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSpringboneRuntime.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSpringboneRuntime.cs @@ -58,6 +58,14 @@ namespace RotateParticle _system._cloths.Add(cloth); } + foreach (var g in instance.SpringBone.ColliderGroups) + { + foreach (var vrmCollider in g.Colliders) + { + _system.AddColliderIfNotExists(g.name, vrmCollider); + } + } + await awaitCaller.NextFrame(); _system.Initialize(); } diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSystem.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSystem.cs index c53272aca..9a23efd70 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSystem.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSystem.cs @@ -4,6 +4,7 @@ using System.Linq; using RotateParticle.Components; using SphereTriangle; using UnityEngine; +using UniVRM10; namespace RotateParticle @@ -254,7 +255,7 @@ namespace RotateParticle foreach (var c in g.Colliders) { // strand - if (c != null && c.TryCollide(p, particle.Init.Radius, out var resolved)) + if (c != null && TryCollide(c, p, particle.Init.Radius, out var resolved)) { _newPos.CollisionMove(particle.Init.Index, resolved, c.Radius); } @@ -286,6 +287,123 @@ namespace RotateParticle } } + public ColliderGroup GetOrAddColliderGroup(string groupName) + { + foreach (var g in _colliderGroups) + { + if (g.Name == groupName) + { + return g; + } + } + + var group = new ColliderGroup { Name = groupName }; + _colliderGroups.Add(group); + return group; + } + + public void AddColliderIfNotExists(string groupName, + VRM10SpringBoneCollider c) + { + var group = GetOrAddColliderGroup(groupName); + + foreach (var collider in group.Colliders) + { + if (collider == c) + { + return; + } + } + + // c.GizmoColor = GetGizmoColor(group); + group.Colliders.Add(c); + } + + /// + /// 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).normalized; + var Q = b - capsuleHead; + var dot = Vector3.Dot(P, 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); + } + + /// + /// collision for strand + /// + /// + /// + /// + /// + public bool TryCollide(UniVRM10.VRM10SpringBoneCollider c, in Vector3 p, float radius, out LineSegment resolved) + { + if (c.ColliderType == UniVRM10.VRM10SpringBoneColliderTypes.Capsule) + { + return TryCollideCapsuleAndSphere(c.HeadWorldPosition, c.TailWorldPosition, c.Radius, p, radius, out resolved); + } + else + { + return TryCollideSphereAndSphere(c.HeadWorldPosition, c.Radius, p, radius, out resolved); + } + } + public void DrawGizmos() { _list.DrawGizmos(); diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/CapsuleInfo.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/CapsuleInfo.cs index cde732b02..9da7d551e 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/CapsuleInfo.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/CapsuleInfo.cs @@ -1,10 +1,11 @@ using UnityEngine; +using UniVRM10; namespace SphereTriangle { struct CapsuleInfo { - public SphereCapsuleCollider Collider; + public VRM10SpringBoneCollider Collider; public Triangle Triangle; public Vector3 MinOnPlane; @@ -28,7 +29,7 @@ namespace SphereTriangle public bool Intersected; - public CapsuleInfo(in Triangle t, SphereCapsuleCollider collider) + public CapsuleInfo(in Triangle t, VRM10SpringBoneCollider collider) { Collider = collider; Triangle = t; diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/ClothRectCollision.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/ClothRectCollision.cs index d1a63d4a5..fa26fdeca 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/ClothRectCollision.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/ClothRectCollision.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using UnityEngine; +using UniVRM10; namespace SphereTriangle { @@ -23,7 +24,7 @@ namespace SphereTriangle TriangleCapsuleCollisionSolver _s1 = new(); // 各コライダーが初期姿勢で三角形ABCの法線の正か負のどちらにあるのかを記録する - Dictionary _initialColliderNormalSide = new(); + Dictionary _initialColliderNormalSide = new(); /// /// two triangles @@ -81,7 +82,7 @@ namespace SphereTriangle return GetBoundsFrom4(list.Get(_a), list.Get(_b), list.Get(_c), list.Get(_d)); } - public void Collide(PositionList list, IReadOnlyCollection colliders) + public void Collide(PositionList list, IReadOnlyCollection colliders) { using (new ProfileSample("Rect: Prepare")) { @@ -160,9 +161,9 @@ namespace SphereTriangle /// /// /// - static bool TryCollide(TriangleCapsuleCollisionSolver solver, SphereCapsuleCollider collider, in Triangle t, out LineSegment l) + static bool TryCollide(TriangleCapsuleCollisionSolver solver, VRM10SpringBoneCollider collider, in Triangle t, out LineSegment l) { - if (collider.IsCapsule) + if (collider.ColliderType == VRM10SpringBoneColliderTypes.Capsule) { // capsule TriangleCapsuleCollisionSolver.Result result = default; @@ -207,15 +208,9 @@ namespace SphereTriangle return true; } - // p を三辺に投影し t を得る - // var proj = triangle.Project(p); - // if (proj.TryGetClosest(collider, out var x)) - // { - // // 最近点の距離 - // // TODO: - // return new LineSegment(collider, x); - // } - throw new System.NotImplementedException(); + var closestPoint = triangle.GetClosest(collider); + l = new LineSegment(collider, closestPoint); + return true; } public void DrawGizmos() diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/ColliderGroup.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/ColliderGroup.cs index 401d4d866..989942dae 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/ColliderGroup.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/ColliderGroup.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using UnityEngine; +using UniVRM10; namespace SphereTriangle { @@ -11,6 +12,6 @@ namespace SphereTriangle public string Name; [SerializeField] - public List Colliders = new List(); + public List Colliders = new(); } } \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/LineDistanceGizmo.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/LineDistanceGizmo.cs index 6b7bdd469..963e6f0b8 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/LineDistanceGizmo.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/LineDistanceGizmo.cs @@ -1,23 +1,24 @@ using UnityEngine; +using UniVRM10; namespace SphereTriangle { public class LineDistanceGizmo : MonoBehaviour { - public SphereCapsuleCollider LineA; - public SphereCapsuleCollider LineB; + public VRM10SpringBoneCollider LineA; + public VRM10SpringBoneCollider LineB; void Reset() { if (LineA == null) { - LineA = GetComponent(); + LineA = GetComponent(); } } public void OnDrawGizmos() { - if (LineA.IsCapsule && LineB.IsCapsule) + if (LineA.ColliderType == VRM10SpringBoneColliderTypes.Capsule && LineB.ColliderType == VRM10SpringBoneColliderTypes.Capsule) { var a = new LineSegment(LineA.HeadWorldPosition, LineA.TailWorldPosition); var b = new LineSegment(LineB.HeadWorldPosition, LineB.TailWorldPosition); diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/SphereCapsuleCollider.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/SphereCapsuleCollider.cs deleted file mode 100644 index 4eaf61794..000000000 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/SphereCapsuleCollider.cs +++ /dev/null @@ -1,173 +0,0 @@ -using UnityEngine; -using UniVRM10; - - -namespace SphereTriangle -{ - public class SphereCapsuleCollider - { - public readonly VRM10SpringBoneCollider _vrm; - public Color GizmoColor = Color.yellow; - public bool SolidGizmo = false; - - public float Radius => _vrm.Radius; - public bool IsCapsule => _vrm.ColliderType == VRM10SpringBoneColliderTypes.Capsule; - public Vector3 HeadWorldPosition => _vrm.transform.TransformPoint(_vrm.Offset); - public Vector3 TailWorldPosition => _vrm.transform.TransformPoint(_vrm.TailOrNormal); - public Ray? HeadTailRay => IsCapsule ? new Ray { origin = HeadWorldPosition, direction = TailWorldPosition - HeadWorldPosition } : null; - public float CapsuleLength => !IsCapsule ? 0 : Vector3.Distance(TailWorldPosition, HeadWorldPosition); - - public SphereCapsuleCollider(VRM10SpringBoneCollider vrmCollider) - { - _vrm = vrmCollider; - } - - public Bounds GetBounds() - { - if (IsCapsule) - { - var h = HeadWorldPosition; - var t = TailWorldPosition; - var d = h - t; - var aabb = new Bounds((h + t) * 0.5f, new Vector3(Mathf.Abs(d.x), Mathf.Abs(d.y), Mathf.Abs(d.z))); - aabb.Expand(_vrm.Radius * 2); - return aabb; - } - else - { - return new Bounds(HeadWorldPosition, new Vector3(_vrm.Radius, _vrm.Radius, _vrm.Radius)); - } - } - - /// - /// 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).normalized; - var Q = b - capsuleHead; - var dot = Vector3.Dot(P, 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); - } - - /// - /// collision for strand - /// - /// - /// - /// - /// - public bool TryCollide(in Vector3 p, float radius, out LineSegment resolved) - { - if (IsCapsule) - { - return TryCollideCapsuleAndSphere(HeadWorldPosition, TailWorldPosition, this.Radius, p, radius, out resolved); - } - else - { - return TryCollideSphereAndSphere(HeadWorldPosition, this.Radius, p, radius, out resolved); - } - } - - public static void DrawCapsuleGizmo(Vector3 start, Vector3 end, float radius) - { - var tail = end - start; - var distance = (end - start).magnitude; - Gizmos.matrix = Matrix4x4.TRS(start, Quaternion.FromToRotation(Vector3.forward, tail), Vector3.one); - Gizmos.DrawWireSphere(Vector3.zero, radius); - Gizmos.DrawWireSphere(Vector3.forward * distance, radius); - var capsuleEnd = Vector3.forward * distance; - var offsets = new Vector3[] { new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f), new Vector3(0.0f, -1.0f, 0.0f) }; - for (int i = 0; i < offsets.Length; i++) - { - Gizmos.DrawLine(offsets[i] * radius, capsuleEnd + offsets[i] * radius); - } - Gizmos.matrix = Matrix4x4.identity; - } - - public void OnDrawGizmos() - { - if (SolidGizmo) - { - Gizmos.color = Color.white; - Gizmos.DrawSphere(HeadWorldPosition, Radius); - } - - Gizmos.color = GizmoColor; - if (_vrm.transform.parent != null) - { - Gizmos.DrawLine(HeadWorldPosition, HeadWorldPosition); - } - if (IsCapsule) - { - DrawCapsuleGizmo(HeadWorldPosition, TailWorldPosition, Radius); - } - else - { - Gizmos.DrawWireSphere(HeadWorldPosition, Radius); - } - -#if AABB_DEBUG - Gizmos.matrix = Matrix4x4.identity; - Gizmos.color = Color.magenta; - var aabb = GetBounds(); - Gizmos.DrawWireCube(aabb.center, aabb.size); -#endif - } - } -} \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/SphereCapsuleCollider.cs.meta b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/SphereCapsuleCollider.cs.meta deleted file mode 100644 index eb2d57d39..000000000 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/SphereCapsuleCollider.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4d8072930ebf6d34ea30547c75dfb378 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/Triangle.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/Triangle.cs index 082007891..3b69a018c 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/Triangle.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/Triangle.cs @@ -36,6 +36,10 @@ namespace SphereTriangle public Vector3 b => Points[1]; public Vector3 c => Points[2]; + public LineSegment AB => new LineSegment(a, b); + public LineSegment BC => new LineSegment(b, c); + public LineSegment CA => new LineSegment(c, a); + public Triangle(Vector3 a, Vector3 b, Vector3 c) { Plane = new Plane(a, b, c); @@ -269,6 +273,47 @@ namespace SphereTriangle // }; // } + public Vector3 GetClosest(in Vector3 p) + { + var ab = AB; + var t_ab = ab.Project(p); + var p_ab = ab.GetPoint(t_ab); + var d_ab = Vector3.Distance(p, p_ab); + + var bc = BC; + var t_bc = bc.Project(p); + var p_bc = bc.GetPoint(t_bc); + var d_bc = Vector3.Distance(p, p_bc); + + var ca = CA; + var t_ca = ca.Project(p); + var p_ca = ca.GetPoint(t_ca); + var d_ca = Vector3.Distance(p, p_ca); + + if (d_ab < d_bc) + { + if (d_ab < d_ca) + { + return p_ab; + } + else + { + return p_ca; + } + } + else + { + if (d_bc < d_ca) + { + return p_bc; + } + else + { + return p_ca; + } + } + } + public void DrawGizmos() { #if UNITY_2022_3_OR_NEWER diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/TriangleCapsuleCollisionSolver.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/TriangleCapsuleCollisionSolver.cs index 63d1cee79..0ce7ad4f6 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/TriangleCapsuleCollisionSolver.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/TriangleCapsuleCollisionSolver.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using UnityEngine; +using UniVRM10; namespace SphereTriangle { @@ -129,14 +130,14 @@ namespace SphereTriangle public Result Result; } // 複数コライダーのデバッグ表示のため - public Dictionary collider_status_map = new(); + public Dictionary collider_status_map = new(); public void BeginFrame() { collider_status_map.Clear(); } - public Result Collide(in Triangle t, SphereCapsuleCollider collider, in LineSegment capsule, float radius) + public Result Collide(in Triangle t, VRM10SpringBoneCollider collider, in LineSegment capsule, float radius) { if (collider == null) { diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/TriangleCapsuleGizmo.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/TriangleCapsuleGizmo.cs index 40f20711c..f842d4594 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/TriangleCapsuleGizmo.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/SphereTriangle/TriangleCapsuleGizmo.cs @@ -1,4 +1,5 @@ using UnityEngine; +using UniVRM10; namespace SphereTriangle @@ -7,7 +8,7 @@ namespace SphereTriangle { public Transform B; public Transform C; - public SphereCapsuleCollider Capsule; + public VRM10SpringBoneCollider Capsule; void Reset() { @@ -35,7 +36,7 @@ namespace SphereTriangle if (C == null) return; var t = new Triangle(transform.position, B.position, C.position); - if (!Capsule.IsCapsule) return; + if (Capsule.ColliderType != VRM10SpringBoneColliderTypes.Capsule) return; var capsule = new LineSegment(Capsule.HeadWorldPosition, Capsule.TailWorldPosition); _solver.BeginFrame();