| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- /*******************************************************************************
- Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
- NOTICE:All information contained herein is, and remains the property of
- PICO Technology Co., Ltd. The intellectual and technical concepts
- contained herein are proprietary to PICO Technology Co., Ltd. and may be
- covered by patents, patents in process, and are protected by trade secret or
- copyright law. Dissemination of this information or reproduction of this
- material is strictly forbidden unless prior written permission is obtained from
- PICO Technology Co., Ltd.
- *******************************************************************************/
- using System.Collections.Generic;
- using UnityEngine;
- using Unity.XR.PXR;
- using System;
- [ExecuteInEditMode]
- public class PXR_HandPosePreview : MonoBehaviour
- {
- [HideInInspector]public List<Transform> handJoints = new List<Transform>(new Transform[(int)HandJoint.JointMax]);
- [HideInInspector] public Vector3[] jointAngles = new Vector3[(int)HandJoint.JointMax];
- [HideInInspector] public Transform posePreviewX;
- [HideInInspector] public Transform posePreviewY;
- [HideInInspector] public Transform handModel;
- [HideInInspector] public SkinnedMeshRenderer handAxis;
- [HideInInspector] public Transform headModel;
- [HideInInspector] public Transform handShadow;
- [HideInInspector] public ModelFinger modelThumb = new ModelFinger(ModelFinger.FingerType.thumb);
- [HideInInspector] public ModelFinger modelIndex = new ModelFinger(ModelFinger.FingerType.index);
- [HideInInspector] public ModelFinger modelMiddle = new ModelFinger(ModelFinger.FingerType.middle);
- [HideInInspector] public ModelFinger modelRing = new ModelFinger(ModelFinger.FingerType.ring);
- [HideInInspector] public ModelFinger modelLittle = new ModelFinger(ModelFinger.FingerType.little);
- [HideInInspector] public Material openMaterial;
- [HideInInspector] public Material anyMaterial;
- [HideInInspector] public Material openFadeMaterial;
- [HideInInspector] public Material anyFadeMaterial;
- [HideInInspector] public Material highLightMaterial;
- private Vector4 highLightBlendPower;
- private int blendPower = Shader.PropertyToID("_BlendPower");
- public void UpdateShapeState(ShapesRecognizer shapesConfig)
- {
- var thumb = shapesConfig.thumb;
- var index = shapesConfig.index;
- var middle = shapesConfig.middle;
- var ring = shapesConfig.ring;
- var little = shapesConfig.pinky;
- int joint = 0;
- Vector3 angle = Vector3.zero;
- //thumb
- joint = (int)HandJoint.JointThumbProximal;
- angle =
- thumb.flexion == ShapesRecognizer.Flexion.Close ? new Vector3(52f, -37, -8) :
- thumb.abduction == ShapesRecognizer.Abduction.Close ? new Vector3(58f, 16, 1) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- joint = (int)HandJoint.JointThumbDistal;
- angle =
- thumb.curl == ShapesRecognizer.Curl.Close ? new Vector3(36, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- modelThumb.HighlightModelJoints(this,thumb.flexion, thumb.curl);
- //index
- joint = (int)HandJoint.JointIndexProximal;
- angle =
- index.flexion == ShapesRecognizer.Flexion.Close ? new Vector3(jointAngles[joint].x + 68, jointAngles[joint].y, jointAngles[joint].z) :
- index.abduction == ShapesRecognizer.Abduction.Close ? new Vector3(jointAngles[joint].x, 18, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- joint = (int)HandJoint.JointIndexIntermediate;
- angle = index.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 60, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- joint = (int)HandJoint.JointIndexDistal;
- angle = index.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 65, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- modelIndex.HighlightModelJoints(this, index.flexion, index.curl);
- //middle
- joint = (int)HandJoint.JointMiddleProximal;
- angle =
- middle.flexion == ShapesRecognizer.Flexion.Close ? new Vector3(jointAngles[joint].x + 68, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- joint = (int)HandJoint.JointMiddleIntermediate;
- angle = middle.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 60, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- joint = (int)HandJoint.JointMiddleDistal;
- angle = middle.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 65, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- modelMiddle.HighlightModelJoints(this, middle.flexion, middle.curl);
- //ring
- joint = (int)HandJoint.JointRingProximal;
- angle =
- ring.flexion == ShapesRecognizer.Flexion.Close ? new Vector3(jointAngles[joint].x + 68, jointAngles[joint].y, jointAngles[joint].z) :
- middle.abduction == ShapesRecognizer.Abduction.Close ? new Vector3(jointAngles[joint].x, -18, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- joint = (int)HandJoint.JointRingIntermediate;
- angle = ring.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 60, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- joint = (int)HandJoint.JointRingDistal;
- angle = ring.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 65, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- modelRing.HighlightModelJoints(this, ring.flexion, ring.curl);
- //little
- joint = (int)HandJoint.JointLittleProximal;
- angle =
- little.flexion == ShapesRecognizer.Flexion.Close ? new Vector3(jointAngles[joint].x + 68, jointAngles[joint].y, jointAngles[joint].z) :
- ring.abduction == ShapesRecognizer.Abduction.Close ? new Vector3(jointAngles[joint].x, -18, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- joint = (int)HandJoint.JointLittleIntermediate;
- angle = little.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 60, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- joint = (int)HandJoint.JointLittleDistal;
- angle = little.curl == ShapesRecognizer.Curl.Close ? new Vector3(jointAngles[joint].x + 65, jointAngles[joint].y, jointAngles[joint].z) : jointAngles[joint];
- handJoints[joint].localEulerAngles = angle;
- modelLittle.HighlightModelJoints(this, little.flexion, little.curl);
- //abduction highlight
- highLightBlendPower.w = thumb.abduction == ShapesRecognizer.Abduction.Any ? 0 : 1;
- highLightBlendPower.x = index.abduction == ShapesRecognizer.Abduction.Any ? 0 : 1;
- highLightBlendPower.y = middle.abduction == ShapesRecognizer.Abduction.Any ? 0 : 1;
- highLightBlendPower.z = ring.abduction == ShapesRecognizer.Abduction.Any ? 0 : 1;
- highLightMaterial.SetVector(blendPower, highLightBlendPower);
- }
- public void ResetShapeState()
- {
- for (int i = 0; i < handJoints.Count; i++)
- {
- handJoints[i].localEulerAngles = jointAngles[i];
- }
- modelThumb.HighlightModelJoints(this, ShapesRecognizer.Flexion.Any, ShapesRecognizer.Curl.Any);
- modelIndex.HighlightModelJoints(this, ShapesRecognizer.Flexion.Any, ShapesRecognizer.Curl.Any);
- modelMiddle.HighlightModelJoints(this, ShapesRecognizer.Flexion.Any, ShapesRecognizer.Curl.Any);
- modelRing.HighlightModelJoints(this, ShapesRecognizer.Flexion.Any, ShapesRecognizer.Curl.Any);
- modelLittle.HighlightModelJoints(this, ShapesRecognizer.Flexion.Any, ShapesRecognizer.Curl.Any);
- highLightMaterial.SetVector(blendPower, Vector4.zero);
- }
- public void ResetTransformState()
- {
- headModel.gameObject.SetActive(false);
- handAxis.gameObject.SetActive(false);
- handModel.localEulerAngles = new Vector3(-90, 180, 0);
- }
- public void UpdateTransformState(TransRecognizer transRecognizer)
- {
- handAxis.gameObject.SetActive(true);
- switch (transRecognizer.trackAxis)
- {
- case TransRecognizer.TrackAxis.Fingers:
- handAxis.SetBlendShapeWeight(0, 100);
- handAxis.SetBlendShapeWeight(1, 0);
- handAxis.SetBlendShapeWeight(2, 0);
- break;
- case TransRecognizer.TrackAxis.Palm:
- handAxis.SetBlendShapeWeight(0, 0);
- handAxis.SetBlendShapeWeight(1, 0);
- handAxis.SetBlendShapeWeight(2, 100);
- break;
- case TransRecognizer.TrackAxis.Thumb:
- handAxis.SetBlendShapeWeight(0, 0);
- handAxis.SetBlendShapeWeight(1, 100);
- handAxis.SetBlendShapeWeight(2, 0);
- break;
- default:
- break;
- }
- switch (transRecognizer.trackTarget)
- {
- case TransRecognizer.TrackTarget.TowardsFace:
- headModel.gameObject.SetActive(true);
- headModel.localPosition = new Vector3(0, 0.05f, -0.24f);
- headModel.localEulerAngles = Vector3.zero;
- handModel.localEulerAngles =
- transRecognizer.trackAxis == TransRecognizer.TrackAxis.Fingers ? new Vector3(0, 180, 0) :
- transRecognizer.trackAxis == TransRecognizer.TrackAxis.Palm ? new Vector3(-90, 180, 0) : new Vector3(-90, 0, -90);
- break;
- case TransRecognizer.TrackTarget.AwayFromFace:
- headModel.gameObject.SetActive(true);
- headModel.localPosition = new Vector3(0, 0.05f, 0.24f);
- headModel.localEulerAngles = new Vector3(0, 180, 0);
- handModel.localEulerAngles =
- transRecognizer.trackAxis == TransRecognizer.TrackAxis.Fingers ? new Vector3(0, 180, 0) :
- transRecognizer.trackAxis == TransRecognizer.TrackAxis.Palm ? new Vector3(-90, 180, 0) : new Vector3(-90, 0, -90);
- break;
- case TransRecognizer.TrackTarget.WorldUp:
- headModel.gameObject.SetActive(false);
- handModel.localEulerAngles =
- transRecognizer.trackAxis == TransRecognizer.TrackAxis.Fingers ? new Vector3(-90, 0, 0) :
- transRecognizer.trackAxis == TransRecognizer.TrackAxis.Palm ? new Vector3(0, 0, 180) : new Vector3(0, 0, -90);
- break;
- case TransRecognizer.TrackTarget.WorldDown:
- headModel.gameObject.SetActive(false);
- handModel.localEulerAngles =
- transRecognizer.trackAxis == TransRecognizer.TrackAxis.Fingers ? new Vector3(90, 0, 0) :
- transRecognizer.trackAxis == TransRecognizer.TrackAxis.Palm ? Vector3.zero : new Vector3(0, 0, 90);
- break;
- default:
- break;
- }
- if (handModel.localEulerAngles.x == 0)
- {
- handShadow.GetChild(0).gameObject.SetActive(false);
- handShadow.GetChild(1).gameObject.SetActive(true);
- }
- else
- {
- handShadow.GetChild(0).gameObject.SetActive(true);
- handShadow.GetChild(1).gameObject.SetActive(false);
- }
- }
- [Serializable]
- public class ModelFinger
- {
- public FingerType Type;
- public List<Transform> flexionTransforms = new List<Transform>();
- public List<MeshRenderer> flexionMeshRenderers = new List<MeshRenderer>();
- public List<Transform> curlTransforms = new List<Transform>();
- public List<MeshRenderer> curlMeshRenderers = new List<MeshRenderer>();
- public enum ModelJoint
- {
- metacarpal = 0,
- proximal = 1,
- intermediate = 2,
- distal = 3,
- tip = 4
- }
- public enum FingerType
- {
- thumb,
- index,
- middle,
- ring,
- little
- }
- public ModelFinger(FingerType type)
- {
- Type = type;
- }
- public void RefreshModelJoints(Transform transform)
- {
- if (flexionTransforms.Count == 0 || curlTransforms.Count == 0)
- {
- flexionTransforms.Clear();
- curlTransforms.Clear();
- flexionMeshRenderers.Clear();
- curlMeshRenderers.Clear();
- var baseTransform = transform.GetChild(1);
- for (int i = 0; i < baseTransform.childCount; i++)
- {
- if (baseTransform.GetChild(i).name.EndsWith($"{Type}_{ModelJoint.metacarpal}"))
- {
- baseTransform = baseTransform.GetChild(i);
- break;
- }
- }
- flexionTransforms.Add(GetModelJoint(baseTransform, ModelJoint.proximal));
- curlTransforms.Add(GetModelJoint(baseTransform, ModelJoint.intermediate));
- if (Type != FingerType.thumb)
- {
- curlTransforms.Add(GetModelJoint(baseTransform, ModelJoint.distal));
- }
- foreach (var flexionTransform in flexionTransforms)
- {
- flexionMeshRenderers.Add(flexionTransform.Find("Bone").GetComponent<MeshRenderer>());
- flexionMeshRenderers.Add(flexionTransform.Find("Pointer").GetComponent<MeshRenderer>());
- flexionMeshRenderers.Add(flexionTransform.parent.Find("Bone").GetComponent<MeshRenderer>());
- }
- foreach (var curlTransform in curlTransforms)
- {
- var mesh = curlTransform.Find("Bone").GetComponent<MeshRenderer>();
- if (!curlMeshRenderers.Contains(mesh)) curlMeshRenderers.Add(mesh);
- mesh = curlTransform.Find("Pointer").GetComponent<MeshRenderer>();
- if (!curlMeshRenderers.Contains(mesh)) curlMeshRenderers.Add(mesh);
- mesh = curlTransform.parent.Find("Bone").GetComponent<MeshRenderer>();
- if (!curlMeshRenderers.Contains(mesh)) curlMeshRenderers.Add(mesh);
- }
- if (Type != FingerType.thumb)
- {
- var m = GetModelJoint(baseTransform, ModelJoint.tip).Find("Pointer")
- .GetComponent<MeshRenderer>();
- if (!curlMeshRenderers.Contains(m)) curlMeshRenderers.Add(m);
- }
- else
- {
- var m = GetModelJoint(baseTransform, ModelJoint.distal).Find("Pointer")
- .GetComponent<MeshRenderer>();
- if (!curlMeshRenderers.Contains(m)) curlMeshRenderers.Add(m);
- }
- }
- }
- public void HighlightModelJoints(PXR_HandPosePreview handPosePreview, ShapesRecognizer.Flexion flexion, ShapesRecognizer.Curl curl)
- {
- foreach (var mesh in flexionMeshRenderers)
- {
- mesh.material = flexion != ShapesRecognizer.Flexion.Any ? handPosePreview.openMaterial : handPosePreview.anyMaterial;
- }
- foreach (var mesh in curlMeshRenderers)
- {
- mesh.material = curl != ShapesRecognizer.Curl.Any ? handPosePreview.openMaterial : handPosePreview.anyMaterial;
- }
- flexionMeshRenderers[2].material = flexion != ShapesRecognizer.Flexion.Any ? handPosePreview.openFadeMaterial : handPosePreview.anyFadeMaterial;
- }
- private Transform GetModelJoint(Transform tran, ModelJoint type)
- {
- for (int i = 0; i < (int)type; i++)
- {
- tran = tran.GetChild(2);
- }
- return tran;
- }
- }
- }
|