Init
This commit is contained in:
@@ -0,0 +1,363 @@
|
||||
#if !PICO_OPENXR_SDK
|
||||
/*******************************************************************************
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user