mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-12 13:59:21 -05:00
import
This commit is contained in:
@@ -27,6 +27,8 @@ namespace UniVRM10
|
||||
|
||||
public Vector3 Normal = Vector3.up;
|
||||
|
||||
public Vector3 TailOrNormal => ColliderType == VRM10SpringBoneColliderTypes.Plane ? Normal : Tail;
|
||||
|
||||
public static int SelectedGuid;
|
||||
|
||||
public bool IsSelected => GetInstanceID() == SelectedGuid;
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace UniVRM10
|
||||
{
|
||||
offset = collider.Offset,
|
||||
radius = collider.Radius,
|
||||
tail = collider.Tail,
|
||||
tailOrNormal = collider.TailOrNormal,
|
||||
colliderType = TranslateColliderType(collider.ColliderType)
|
||||
}
|
||||
}).ToArray(),
|
||||
|
||||
@@ -9,11 +9,12 @@ namespace UniVRM10.FastSpringBones.Blittables
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct BlittableCollider
|
||||
{
|
||||
{
|
||||
public BlittableColliderType colliderType;
|
||||
public Vector3 offset;
|
||||
public float radius;
|
||||
public Vector3 tail;
|
||||
// capsule tail or plane normal
|
||||
public Vector3 tailOrNormal;
|
||||
public int transformIndex;
|
||||
}
|
||||
}
|
||||
@@ -4,5 +4,7 @@ namespace UniVRM10.FastSpringBones.Blittables
|
||||
{
|
||||
Sphere,
|
||||
Capsule,
|
||||
Plane,
|
||||
SphereInside,
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace UniVRM10.FastSpringBones.System
|
||||
[NativeDisableParallelForRestriction] public NativeArray<BlittableTransform> Transforms;
|
||||
|
||||
public float DeltaTime;
|
||||
|
||||
|
||||
public unsafe void Execute(int index)
|
||||
{
|
||||
var spring = Springs[index];
|
||||
@@ -79,16 +79,28 @@ namespace UniVRM10.FastSpringBones.System
|
||||
var colliderScale = colliderTransform.localToWorldMatrix.lossyScale;
|
||||
var maxColliderScale = Mathf.Max(Mathf.Max(Mathf.Abs(colliderScale.x), Mathf.Abs(colliderScale.y)), Mathf.Abs(colliderScale.z));
|
||||
var worldPosition = colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.offset);
|
||||
var worldTail = colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.tail);
|
||||
|
||||
var worldTail = colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.tailOrNormal);
|
||||
|
||||
switch (collider.colliderType)
|
||||
{
|
||||
case BlittableColliderType.Sphere:
|
||||
ResolveSphereCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail);
|
||||
ResolveSphereCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail);
|
||||
break;
|
||||
|
||||
case BlittableColliderType.Capsule:
|
||||
ResolveCapsuleCollision(worldTail, worldPosition, headTransform, joint, collider, maxColliderScale, logic, ref nextTail);
|
||||
break;
|
||||
|
||||
case BlittableColliderType.Plane:
|
||||
ResolvePlaneCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail);
|
||||
break;
|
||||
|
||||
case BlittableColliderType.SphereInside:
|
||||
ResolveSphereCollisionInside(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,5 +215,71 @@ namespace UniVRM10.FastSpringBones.System
|
||||
nextTail = headTransform.position + (posFromCollider - headTransform.position).normalized * logic.length;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ResolveSphereCollisionInside(
|
||||
BlittableJoint joint,
|
||||
BlittableCollider collider,
|
||||
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);
|
||||
}
|
||||
|
||||
private static void ResolvePlaneCollision(
|
||||
BlittableJoint joint,
|
||||
BlittableCollider collider,
|
||||
Vector3 worldPosition,
|
||||
BlittableTransform headTransform,
|
||||
float maxColliderScale,
|
||||
BlittableLogic logic,
|
||||
ref Vector3 nextTail)
|
||||
{
|
||||
// let transformedOffset = colliderOffset * colliderTransform;
|
||||
// let transformedNormal = normalize(colliderNormal * normalMatrixFrom(colliderTransform));
|
||||
// let delta = jointPosition - transformedOffset;
|
||||
|
||||
// // ジョイントとコライダーの距離。負の値は衝突していることを示す
|
||||
// let distance = dot(delta, transformedNormal) - jointRadius;
|
||||
|
||||
// // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す
|
||||
// let direction = transformedNormal;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -538,6 +538,41 @@ namespace UniVRM10
|
||||
{
|
||||
throw new Vrm10Exception("unknown shape");
|
||||
}
|
||||
|
||||
// https://github.com/vrm-c/vrm-specification/tree/master/specification/VRMC_springBone_extended_collider-1.0
|
||||
// VRMC_springBone_extended_collider
|
||||
if (UniGLTF.Extensions.VRMC_springBone_extended_collider.GltfDeserializer.TryGet(c.Extensions as glTFExtension,
|
||||
out UniGLTF.Extensions.VRMC_springBone_extended_collider.VRMC_springBone_extended_collider exCollider))
|
||||
{
|
||||
if (exCollider.Shape.Sphere is UniGLTF.Extensions.VRMC_springBone_extended_collider.ExtendedColliderShapeSphere exSphere)
|
||||
{
|
||||
collider.ColliderType = VRM10SpringBoneColliderTypes.Sphere;
|
||||
collider.Offset = Vector3InvertX(exSphere.Offset);
|
||||
collider.Radius = exSphere.Radius.Value;
|
||||
if (exSphere.Inside.HasValue && exSphere.Inside.Value)
|
||||
{
|
||||
collider.ColliderType = VRM10SpringBoneColliderTypes.SphereIside;
|
||||
}
|
||||
}
|
||||
else if (exCollider.Shape.Capsule is UniGLTF.Extensions.VRMC_springBone_extended_collider.ExtendedColliderShapeCapsule exCapsule)
|
||||
{
|
||||
collider.ColliderType = VRM10SpringBoneColliderTypes.Capsule;
|
||||
collider.Offset = Vector3InvertX(exCapsule.Offset);
|
||||
collider.Tail = Vector3InvertX(exCapsule.Tail);
|
||||
collider.Radius = exCapsule.Radius.Value;
|
||||
}
|
||||
else if (exCollider.Shape.Plane is UniGLTF.Extensions.VRMC_springBone_extended_collider.ExtendedColliderShapePlane exPlane)
|
||||
{
|
||||
collider.ColliderType = VRM10SpringBoneColliderTypes.Plane;
|
||||
collider.Offset = Vector3InvertX(exPlane.Offset);
|
||||
collider.Normal = Vector3InvertX(exPlane.Normal);
|
||||
collider.Radius = 0.1f; // gizmo visualize. 10cm
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Vrm10Exception("VRMC_springBone_extended_collider: unknown shape");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user