using UnityEngine; using System.Collections.Generic; using Rokid.UXR.Utility; namespace Rokid.UXR.Interaction { public class HandVisual : MonoBehaviour { /// /// HandType /// [SerializeField] private HandType hand; /// /// Bone Coordinate Axis Transformation" /// [SerializeField] private Vector3 axisRot = Vector3.zero; /// /// The root joint of the hand is generally the "Wrist." /// [SerializeField] private Transform handRootSkeleton; /// /// Hand MeshRender /// [SerializeField] private SkinnedMeshRenderer handMesh; /// /// Hand Skeleton /// /// /// [SerializeField] private List handSkeletons = new List(); private bool pokeSelect = false; private Vector3 pokeClosePoint = Vector3.zero; #if UNITY_EDITOR private float index_mcp_pip_dis; private float middle_mcp_pip_dis; private float ring_mcp_pip_dis; private float pinky_mcp_pip_dis; private float index_dip_pip_dis; private float middle_dip_pip_dis; private float ring_dip_pip_dis; private float pinky_dip_pip_dis; private float index_dip_tip_dis; private float middle_dip_tip_dis; private float ring_dip_tip_dis; private float pinky_dip_tip_dis; private float wrist_middle_cmp_dis; [SerializeField] private float[] boneDis = new float[13]; #endif private void Start() { if (!Utils.IsAndroidPlatfrom()) { if (Utils.IsAndroidPlatfrom()) { RKLog.Error("====HandVisual==== Error Destory Switch Active!!!"); } Destroy(GetComponent()); this.gameObject.SetActive(false); } InteractorStateChange.OnPokeSelectUpdate += OnPokeSelectUpdate; InteractorStateChange.OnPokeUnSelectUpdate += OnPokeUnSelectUpdate; } private void OnDestroy() { InteractorStateChange.OnPokeSelectUpdate -= OnPokeSelectUpdate; InteractorStateChange.OnPokeUnSelectUpdate -= OnPokeUnSelectUpdate; } private void OnEnable() { if (Utils.IsAndroidPlatfrom()) GesEventInput.OnRenderHand += OnRenderHand; } private void OnDisable() { if (Utils.IsAndroidPlatfrom()) GesEventInput.OnRenderHand -= OnRenderHand; } private void OnPokeUnSelectUpdate(HandType handType) { if (handType == this.hand) { pokeSelect = false; } } private void OnPokeSelectUpdate(HandType handType, Vector3 pokeClosePoint) { if (handType == this.hand) { this.pokeClosePoint = pokeClosePoint; pokeSelect = true; } } #if UNITY_EDITOR [ContextMenu("AutoSetSkeletons")] private void AutoSetSkeletons() { handSkeletons.Add(handRootSkeleton); for (int i = 0; i < handRootSkeleton.childCount; i++) { AutoSetSkeletons(handRootSkeleton.GetChild(i), handSkeletons); } index_mcp_pip_dis = Vector3.Distance(handSkeletons[5].position, handSkeletons[6].position); middle_mcp_pip_dis = Vector3.Distance(handSkeletons[9].position, handSkeletons[10].position); ring_mcp_pip_dis = Vector3.Distance(handSkeletons[13].position, handSkeletons[14].position); pinky_mcp_pip_dis = Vector3.Distance(handSkeletons[17].position, handSkeletons[18].position); index_dip_pip_dis = Vector3.Distance(handSkeletons[7].position, handSkeletons[6].position); middle_dip_pip_dis = Vector3.Distance(handSkeletons[11].position, handSkeletons[10].position); ring_dip_pip_dis = Vector3.Distance(handSkeletons[15].position, handSkeletons[14].position); pinky_dip_pip_dis = Vector3.Distance(handSkeletons[19].position, handSkeletons[18].position); index_dip_tip_dis = Vector3.Distance(handSkeletons[7].position, handSkeletons[8].position); middle_dip_tip_dis = Vector3.Distance(handSkeletons[11].position, handSkeletons[12].position); ring_dip_tip_dis = Vector3.Distance(handSkeletons[15].position, handSkeletons[16].position); pinky_dip_tip_dis = Vector3.Distance(handSkeletons[19].position, handSkeletons[20].position); wrist_middle_cmp_dis = Vector3.Distance(handSkeletons[0].position, handSkeletons[9].position); boneDis[0] = wrist_middle_cmp_dis; boneDis[1] = index_mcp_pip_dis; boneDis[2] = middle_mcp_pip_dis; boneDis[3] = ring_mcp_pip_dis; boneDis[4] = pinky_mcp_pip_dis; boneDis[5] = index_dip_pip_dis; boneDis[6] = middle_dip_pip_dis; boneDis[7] = ring_dip_pip_dis; boneDis[8] = pinky_dip_pip_dis; boneDis[9] = index_dip_tip_dis; boneDis[10] = middle_dip_tip_dis; boneDis[11] = ring_dip_tip_dis; boneDis[12] = pinky_dip_tip_dis; } /// /// auto find skeletons /// /// /// private void AutoSetSkeletons(Transform skeleton, List handSkeletons) { handSkeletons.Add(skeleton); if (skeleton.childCount > 0) { for (int i = 0; i < skeleton.childCount; i++) { AutoSetSkeletons(skeleton.GetChild(i), handSkeletons); } } } #endif private void OnRenderHand(HandType hand, GestureBean data) { Quaternion[] rotations = data.skeletonsRot; if (hand == this.hand) { for (int i = 0; i < handSkeletons.Count; i++) { handSkeletons[i].rotation = rotations[i] * Quaternion.Euler(axisRot); Vector3 offset = pokeClosePoint - GesEventInput.Instance.GetSkeletonPose(SkeletonIndexFlag.INDEX_FINGER_TIP, hand).position; if (pokeSelect) { handSkeletons[i].position = data.skeletons[i] + offset; } else { handSkeletons[i].position = data.skeletons[i]; } } } } /// /// Update hand mesh materials /// /// public void UpdateHandMeshMaterials(Material[] materials) { handMesh.materials = materials; } public void SetHandMeshActive(bool active) { handMesh.gameObject.SetActive(active); } } }