diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs
index 5f3da4974..6c29a1270 100644
--- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs
+++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs
@@ -9,6 +9,7 @@ namespace UniVRM10
Capsule,
Plane,
SphereInside,
+ CapsuleInside,
}
[Serializable]
@@ -44,28 +45,46 @@ namespace UniVRM10
break;
case VRM10SpringBoneColliderTypes.Capsule:
- Gizmos.color = new Color(1.0f, 0.1f, 0.1f);
- Gizmos.DrawWireSphere(Offset, Radius);
- Gizmos.DrawWireSphere(Tail, Radius);
- Gizmos.DrawLine(Offset, Tail);
+ Gizmos.color = Color.magenta;
+ DrawCapsuleGizmo(transform.localToWorldMatrix.MultiplyPoint(Offset), transform.localToWorldMatrix.MultiplyPoint(Tail), Radius);
break;
case VRM10SpringBoneColliderTypes.Plane:
Gizmos.color = new Color(1.0f, 0.5f, 0.0f);
- // normal offset
DrawPlane(transform.localToWorldMatrix, Offset, Normal, Radius);
break;
case VRM10SpringBoneColliderTypes.SphereInside:
- Gizmos.color = Color.cyan;
+ Gizmos.color = new Color(0.5f, 0, 1.0f);
Gizmos.DrawWireSphere(Offset, Radius);
break;
+ case VRM10SpringBoneColliderTypes.CapsuleInside:
+ Gizmos.color = new Color(0.5f, 0, 1.0f);
+ DrawCapsuleGizmo(transform.localToWorldMatrix.MultiplyPoint(Offset), transform.localToWorldMatrix.MultiplyPoint(Tail), Radius);
+ break;
+
default:
throw new NotImplementedException();
}
}
+ 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 static void DrawPlane(in Matrix4x4 m, in Vector3 offset, in Vector3 _n, float radius)
{
var n = _n.normalized;
diff --git a/Assets/VRM10/Runtime/FastSpringBone/Blittables/BlittableColliderType.cs b/Assets/VRM10/Runtime/FastSpringBone/Blittables/BlittableColliderType.cs
index 93ddef69a..69ea0f91d 100644
--- a/Assets/VRM10/Runtime/FastSpringBone/Blittables/BlittableColliderType.cs
+++ b/Assets/VRM10/Runtime/FastSpringBone/Blittables/BlittableColliderType.cs
@@ -6,5 +6,6 @@ namespace UniVRM10.FastSpringBones.Blittables
Capsule,
Plane,
SphereInside,
+ CapsuleInside,
}
}
\ No newline at end of file
diff --git a/Assets/VRM10/Runtime/FastSpringBone/System/UpdateFastSpringBoneJob.cs b/Assets/VRM10/Runtime/FastSpringBone/System/UpdateFastSpringBoneJob.cs
index 5a442e35e..0dcd85281 100644
--- a/Assets/VRM10/Runtime/FastSpringBone/System/UpdateFastSpringBoneJob.cs
+++ b/Assets/VRM10/Runtime/FastSpringBone/System/UpdateFastSpringBoneJob.cs
@@ -92,11 +92,15 @@ namespace UniVRM10.FastSpringBones.System
break;
case BlittableColliderType.Plane:
- ResolvePlaneCollision(joint, collider, colliderTransform, logic, ref nextTail);
+ ResolvePlaneCollision(joint, collider, colliderTransform, ref nextTail);
break;
case BlittableColliderType.SphereInside:
- ResolveSphereCollisionInside(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail);
+ // ResolveSphereCollisionInside(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail);
+ break;
+
+ case BlittableColliderType.CapsuleInside:
+ // ResolveCapsuleCollisionInside(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail);
break;
default:
@@ -219,65 +223,27 @@ namespace UniVRM10.FastSpringBones.System
private static void ResolveSphereCollisionInside(
BlittableJoint joint,
BlittableCollider collider,
+ BlittableTransform colliderTransform,
Vector3 worldPosition,
BlittableTransform headTransform,
float maxColliderScale,
BlittableLogic logic,
ref Vector3 nextTail)
{
- var r = joint.radius + collider.radius * maxColliderScale;
- if (Vector3.SqrMagnitude(nextTail - worldPosition) <= (r * r))
- {
- // ヒット。Colliderの半径方向に押し出す
- var normal = (nextTail - worldPosition).normalized;
- var posFromCollider = worldPosition + normal * r;
- // 長さをboneLengthに強制
- nextTail = headTransform.position + (posFromCollider - headTransform.position).normalized * logic.length;
- }
-
- // let transformedOffset = colliderOffset * colliderTransform;
- // let transformedTail = colliderTail * colliderTransform;
- // let offsetToTail = transformedTail - transformedOffset;
- // let lengthSqCapsule = lengthSq(offsetToTail);
-
- // let dot = dot(offsetToTail, delta);
-
- // var delta = jointPosition - transformedOffset;
-
- // if (dot < 0.0) {
- // // ジョイントがカプセルの始点側にある場合
- // // なにもしない
- // } else if (dot > lengthSqCapsule) {
- // // ジョイントがカプセルの終点側にある場合
- // delta -= offsetToTail;
- // } else {
- // // ジョイントがカプセルの始点と終点の間にある場合
- // delta -= offsetToTail * (dot / lengthSqCapsule);
- // }
-
- // // ジョイントとコライダーの距離。負の値は衝突していることを示す
- // let distance = colliderRadius - jointRadius - length(delta);
-
- // // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す
- // let direction = -normalize(delta);
}
///
- /// SpringのJoint(head-tail)のとColliderの衝突処理。
- /// nextTail が変化しうる。
+ /// Collision with SpringJoint and PlaneCollider.
+ /// If collide update nextTail.
///
/// joint
/// collier
- /// colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.offset);
- /// jointのhead
- /// Mathf.Max(Mathf.Max(Mathf.Abs(colliderScale.x), Mathf.Abs(colliderScale.y)), Mathf.Abs(colliderScale.z));
- /// joint
- /// verlet 積分による tail の移動予定
+ /// colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.offset);
+ /// result of verlet integration
private static void ResolvePlaneCollision(
BlittableJoint joint,
BlittableCollider collider,
BlittableTransform colliderTransform,
- BlittableLogic logic,
ref Vector3 nextTail)
{
var transformedOffset = colliderTransform.localToWorldMatrix.MultiplyPoint(collider.offset);
diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs
index 86b753389..7a26cd8d5 100644
--- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs
+++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs
@@ -361,6 +361,17 @@ namespace UniVRM10
break;
}
+ case VRM10SpringBoneColliderTypes.CapsuleInside:
+ {
+ shape.Capsule = new UniGLTF.Extensions.VRMC_springBone_extended_collider.ExtendedColliderShapeCapsule
+ {
+ Radius = z.Radius,
+ Offset = ReverseX(z.Offset),
+ Tail = ReverseX(z.Tail),
+ };
+ break;
+ }
+
case VRM10SpringBoneColliderTypes.Plane:
{
shape.Plane = new UniGLTF.Extensions.VRMC_springBone_extended_collider.ExtendedColliderShapePlane
@@ -425,7 +436,10 @@ namespace UniVRM10
Node = getNodeIndexFromTransform(c.transform),
Shape = ExportShape(c),
};
- if (c.ColliderType == VRM10SpringBoneColliderTypes.SphereInside || c.ColliderType == VRM10SpringBoneColliderTypes.Plane)
+ if (c.ColliderType == VRM10SpringBoneColliderTypes.SphereInside
+ || c.ColliderType == VRM10SpringBoneColliderTypes.CapsuleInside
+ || c.ColliderType == VRM10SpringBoneColliderTypes.Plane
+ )
{
exportCollider.Extensions = new UniGLTF.Extensions.VRMC_springBone_extended_collider.VRMC_springBone_extended_collider
{
diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs
index f200a7dd0..98d7ac94b 100644
--- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs
+++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs
@@ -546,7 +546,7 @@ namespace UniVRM10
{
if (exCollider.Shape.Sphere is UniGLTF.Extensions.VRMC_springBone_extended_collider.ExtendedColliderShapeSphere exSphere)
{
- collider.ColliderType = VRM10SpringBoneColliderTypes.Sphere;
+ collider.ColliderType = exSphere.Inside.GetValueOrDefault() ? VRM10SpringBoneColliderTypes.SphereInside : VRM10SpringBoneColliderTypes.Sphere;
collider.Offset = Vector3InvertX(exSphere.Offset);
collider.Radius = exSphere.Radius.Value;
if (exSphere.Inside.HasValue && exSphere.Inside.Value)
@@ -556,7 +556,7 @@ namespace UniVRM10
}
else if (exCollider.Shape.Capsule is UniGLTF.Extensions.VRMC_springBone_extended_collider.ExtendedColliderShapeCapsule exCapsule)
{
- collider.ColliderType = VRM10SpringBoneColliderTypes.Capsule;
+ collider.ColliderType = exCapsule.Inside.GetValueOrDefault() ? VRM10SpringBoneColliderTypes.CapsuleInside : VRM10SpringBoneColliderTypes.Capsule;
collider.Offset = Vector3InvertX(exCapsule.Offset);
collider.Tail = Vector3InvertX(exCapsule.Tail);
collider.Radius = exCapsule.Radius.Value;