mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-06-03 06:24:46 -05:00
SphereCapsuleCollider to VRM10SpringBoneCollider
This commit is contained in:
parent
a249fc7f37
commit
0732779721
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -552,7 +552,11 @@ namespace UniVRM10.Cloth.Viewer
|
|||
void OnInit(RotateParticle.RotateParticleSystem system, Vrm10Instance vrm)
|
||||
{
|
||||
var animator = vrm.GetComponent<Animator>();
|
||||
HumanoidCollider.AddColliders(system._colliderGroups, animator);
|
||||
if (vrm.SpringBone.ColliderGroups.Count == 0)
|
||||
{
|
||||
HumanoidCollider.AddColliders(animator);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ClothGuess.Guess(animator);
|
||||
|
|
|
|||
|
|
@ -23,51 +23,31 @@ namespace UniVRM10.Cloth.Viewer
|
|||
("Arm", HumanBodyBones.RightHand, HumanBodyBones.RightMiddleProximal, 0.02f),
|
||||
};
|
||||
|
||||
public static void AddColliders(List<ColliderGroup> _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<string, VRM10SpringBoneColliderGroup> map = new();
|
||||
|
||||
static void AddColliderIfNotExists(List<ColliderGroup> _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<VRM10SpringBoneColliderGroup>();
|
||||
map.Add(group, g);
|
||||
}
|
||||
|
||||
|
||||
var head = animator.GetBoneTransform(_head);
|
||||
var vrmCollider = head.gameObject.AddComponent<VRM10SpringBoneCollider>();
|
||||
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<VRM10SpringBoneCollider>();
|
||||
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<T>(GameObject o) where T : Component
|
||||
|
|
|
|||
|
|
@ -15,9 +15,11 @@ namespace RotateParticle.Components
|
|||
[SerializeField]
|
||||
public List<RectCloth> 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<Warp>().ToList();
|
||||
Cloths = GetComponentsInChildren<RectCloth>().ToList();
|
||||
}
|
||||
|
||||
void OnDrawGizmos()
|
||||
{
|
||||
if (m_runtime == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_runtime.DrawGizmos();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// collide sphere a and sphere b.
|
||||
/// move sphere b to resolved if collide.
|
||||
/// </summary>
|
||||
/// <param name="from"></param>
|
||||
/// <param name="ra"></param>
|
||||
/// <param name="to"></param>
|
||||
/// <param name="ba"></param>
|
||||
/// <param name="resolved"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// collide capsule and sphere b.
|
||||
/// move sphere b to resolved if collide.
|
||||
/// </summary>
|
||||
/// <param name="capsuleHead"></param>
|
||||
/// <param name="capsuleTail"></param>
|
||||
/// <param name="capsuleRadius"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <param name="rb"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// collision for strand
|
||||
/// </summary>
|
||||
/// <param name="p"></param>
|
||||
/// <param name="radius"></param>
|
||||
/// <param name="resolved"></param>
|
||||
/// <returns></returns>
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<SphereCapsuleCollider, float> _initialColliderNormalSide = new();
|
||||
Dictionary<VRM10SpringBoneCollider, float> _initialColliderNormalSide = new();
|
||||
|
||||
/// <summary>
|
||||
/// 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<SphereCapsuleCollider> colliders)
|
||||
public void Collide(PositionList list, IReadOnlyCollection<VRM10SpringBoneCollider> colliders)
|
||||
{
|
||||
using (new ProfileSample("Rect: Prepare"))
|
||||
{
|
||||
|
|
@ -160,9 +161,9 @@ namespace SphereTriangle
|
|||
/// <param name="t"></param>
|
||||
/// <param name="l"></param>
|
||||
/// <returns></returns>
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -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<SphereCapsuleCollider> Colliders = new List<SphereCapsuleCollider>();
|
||||
public List<VRM10SpringBoneCollider> Colliders = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -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<SphereCapsuleCollider>();
|
||||
LineA = GetComponent<VRM10SpringBoneCollider>();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// collide sphere a and sphere b.
|
||||
/// move sphere b to resolved if collide.
|
||||
/// </summary>
|
||||
/// <param name="from"></param>
|
||||
/// <param name="ra"></param>
|
||||
/// <param name="to"></param>
|
||||
/// <param name="ba"></param>
|
||||
/// <param name="resolved"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// collide capsule and sphere b.
|
||||
/// move sphere b to resolved if collide.
|
||||
/// </summary>
|
||||
/// <param name="capsuleHead"></param>
|
||||
/// <param name="capsuleTail"></param>
|
||||
/// <param name="capsuleRadius"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <param name="rb"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// collision for strand
|
||||
/// </summary>
|
||||
/// <param name="p"></param>
|
||||
/// <param name="radius"></param>
|
||||
/// <param name="resolved"></param>
|
||||
/// <returns></returns>
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4d8072930ebf6d34ea30547c75dfb378
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<SphereCapsuleCollider, Status> collider_status_map = new();
|
||||
public Dictionary<VRM10SpringBoneCollider, Status> 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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user