// "Wave SDK
// © 2020 HTC Corporation. All Rights Reserved.
//
// Unless otherwise required by copyright law and practice,
// upon the execution of HTC SDK license agreement,
// HTC grants you access to and use of the Wave SDK(s).
// You shall fully comply with all of HTC’s SDK license agreement terms and
// conditions signed by you and all SDK and API requirements,
// specifications, and documentation provided by HTC to You."
using UnityEngine;
namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
///
/// This class is designed to generate appropriately sized colliders for each joint.
///
public class JointCollider : MonoBehaviour
{
public enum CollisionState
{
Enter = 0,
Stay = 1,
Exit = 2,
}
private CapsuleCollider m_Collider = null;
public Collider Collider => m_Collider;
public delegate void OnJointCollision(Collision collision, CollisionState state);
private OnJointCollision onJointCollision;
private const float k_ColliderRadius = 1E-6f;
private const float k_ColliderHeight = 1E-6f;
private JointType jointType = JointType.Count;
private void OnEnable()
{
InitCollider();
}
///
/// Set the joint id and adjust collider size..
///
/// JointType of joint.
public void SetJointId(int id)
{
InitCollider();
jointType = (JointType)id;
switch (jointType)
{
case JointType.Palm:
m_Collider.center = new Vector3(0f, -0.006f, -0.0025f);
m_Collider.radius = 0.016f;
m_Collider.height = 0.075f;
m_Collider.direction = 0;
break;
case JointType.Wrist:
m_Collider.center = new Vector3(0f, -0.003f, 0f);
m_Collider.radius = 0.02f;
m_Collider.height = 0.055f;
m_Collider.direction = 0;
break;
case JointType.Thumb_Joint0:
m_Collider.center = new Vector3(0f, -0.005f, 0f);
m_Collider.radius = 0.02f;
m_Collider.height = 0.05f;
break;
case JointType.Thumb_Joint1:
m_Collider.center = Vector3.zero;
m_Collider.radius = 0.012f;
m_Collider.height = 0.040f;
break;
case JointType.Thumb_Joint2:
m_Collider.center = new Vector3(0f, -0.003f, 0f);
m_Collider.radius = 0.01f;
m_Collider.height = 0.01f;
break;
case JointType.Thumb_Tip:
m_Collider.center = new Vector3(0f, 0f, -0.005f);
m_Collider.radius = 0.01f;
m_Collider.height = 0.025f;
break;
case JointType.Index_Joint0:
m_Collider.center = new Vector3(0f, 0f, 0.02f);
m_Collider.radius = 0.012f;
m_Collider.height = 0.1f;
break;
case JointType.Index_Joint1:
m_Collider.center = new Vector3(0f, 0f, 0.01f);
m_Collider.radius = 0.01f;
m_Collider.height = 0.04f;
break;
case JointType.Index_Joint2:
m_Collider.center = Vector3.zero;
m_Collider.radius = 0.01f;
m_Collider.height = 0.01f;
break;
case JointType.Index_Joint3:
m_Collider.center = Vector3.zero;
m_Collider.radius = 0.01f;
m_Collider.height = 0.01f;
break;
case JointType.Index_Tip:
m_Collider.center = new Vector3(0f, -0.001f, -0.0025f);
m_Collider.radius = 0.008f;
m_Collider.height = 0.015f;
break;
case JointType.Middle_Joint0:
m_Collider.center = new Vector3(0f, 0f, 0.02f);
m_Collider.radius = 0.012f;
m_Collider.height = 0.1f;
break;
case JointType.Middle_Joint1:
m_Collider.center = new Vector3(0f, 0f, 0.01f);
m_Collider.radius = 0.01f;
m_Collider.height = 0.04f;
break;
case JointType.Middle_Joint2:
m_Collider.center = Vector3.zero;
m_Collider.radius = 0.01f;
m_Collider.height = 0.01f;
break;
case JointType.Middle_Joint3:
m_Collider.center = Vector3.zero;
m_Collider.radius = 0.01f;
m_Collider.height = 0.01f;
break;
case JointType.Middle_Tip:
m_Collider.center = new Vector3(0f, -0.002f, -0.0025f);
m_Collider.radius = 0.008f;
m_Collider.height = 0.015f;
break;
case JointType.Ring_Joint0:
m_Collider.center = new Vector3(0f, 0f, 0.02f);
m_Collider.radius = 0.012f;
m_Collider.height = 0.1f;
break;
case JointType.Ring_Joint1:
m_Collider.center = new Vector3(0f, 0f, 0.01f);
m_Collider.radius = 0.01f;
m_Collider.height = 0.04f;
break;
case JointType.Ring_Joint2:
m_Collider.center = Vector3.zero;
m_Collider.radius = 0.01f;
m_Collider.height = 0.01f;
break;
case JointType.Ring_Joint3:
m_Collider.center = Vector3.zero;
m_Collider.radius = 0.01f;
m_Collider.height = 0.01f;
break;
case JointType.Ring_Tip:
m_Collider.center = new Vector3(0f, -0.002f, -0.0025f);
m_Collider.radius = 0.008f;
m_Collider.height = 0.015f;
break;
case JointType.Pinky_Joint0:
m_Collider.center = new Vector3(0f, 0f, 0.02f);
m_Collider.radius = 0.012f;
m_Collider.height = 0.1f;
break;
case JointType.Pinky_Joint1:
m_Collider.center = new Vector3(0f, 0f, 0.01f);
m_Collider.radius = 0.01f;
m_Collider.height = 0.04f;
break;
case JointType.Pinky_Joint2:
m_Collider.center = Vector3.zero;
m_Collider.radius = 0.01f;
m_Collider.height = 0.01f;
break;
case JointType.Pinky_Joint3:
m_Collider.center = Vector3.zero;
m_Collider.radius = 0.01f;
m_Collider.height = 0.01f;
break;
case JointType.Pinky_Tip:
m_Collider.center = new Vector3(0f, -0.002f, -0.0025f);
m_Collider.radius = 0.006f;
m_Collider.height = 0.015f;
break;
}
}
public Rigidbody InitRigidbody(float mass)
{
Rigidbody rigidbody = gameObject.AddComponent();
rigidbody.mass = mass;
rigidbody.useGravity = false;
rigidbody.interpolation = RigidbodyInterpolation.Interpolate;
rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;
rigidbody.solverIterations = 100;
rigidbody.solverVelocityIterations = 15;
return rigidbody;
}
private void InitCollider()
{
if (m_Collider == null)
{
m_Collider = gameObject.AddComponent();
m_Collider.radius = k_ColliderRadius;
m_Collider.height = k_ColliderHeight;
m_Collider.direction = 2;
}
}
private void OnCollisionEnter(Collision collision)
{
if (!IsJointCollider(collision.collider))
{
onJointCollision?.Invoke(collision, CollisionState.Enter);
}
}
private void OnCollisionStay(Collision collision)
{
if (!IsJointCollider(collision.collider))
{
onJointCollision?.Invoke(collision, CollisionState.Stay);
}
}
private void OnCollisionExit(Collision collision)
{
if (!IsJointCollider(collision.collider))
{
onJointCollision?.Invoke(collision, CollisionState.Exit);
}
}
private bool IsJointCollider(Collider collider)
{
JointCollider jointCollider = collider.GetComponent();
return jointCollider != null;
}
public void AddJointCollisionListener(OnJointCollision handler)
{
onJointCollision += handler;
}
public void RemoveJointCollisionListener(OnJointCollision handler)
{
onJointCollision -= handler;
}
}
}