156 lines
5.6 KiB
C#
156 lines
5.6 KiB
C#
|
|
#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;
|
|||
|
|
|
|||
|
|
public class PXR_Hand : MonoBehaviour
|
|||
|
|
{
|
|||
|
|
public HandType handType;
|
|||
|
|
public Transform Basemesh;
|
|||
|
|
[HideInInspector]
|
|||
|
|
public List<Transform> handJoints = new List<Transform>(new Transform[(int)HandJoint.JointMax]);
|
|||
|
|
|
|||
|
|
public bool Computed { get; private set; }
|
|||
|
|
public Posef RayPose { get; private set; }
|
|||
|
|
public bool RayValid { get; private set; }
|
|||
|
|
public bool Pinch { get; private set; }
|
|||
|
|
public float PinchStrength { get; private set; }
|
|||
|
|
|
|||
|
|
private HandJointLocations handJointLocations = new HandJointLocations();
|
|||
|
|
private HandAimState aimState = new HandAimState();
|
|||
|
|
[SerializeField]
|
|||
|
|
private Transform rayPose;
|
|||
|
|
[SerializeField]
|
|||
|
|
private GameObject defaultRay;
|
|||
|
|
private SkinnedMeshRenderer[] touchRenders;
|
|||
|
|
private bool isaAdaptiveScales = false;
|
|||
|
|
PXR_VstModelPosCheck mOffsetPos=null;
|
|||
|
|
private void Awake()
|
|||
|
|
{
|
|||
|
|
mOffsetPos= GetComponent<PXR_VstModelPosCheck>();
|
|||
|
|
}
|
|||
|
|
private void Start()
|
|||
|
|
{
|
|||
|
|
isaAdaptiveScales = PXR_ProjectSetting.GetProjectConfig().adaptiveHand;
|
|||
|
|
|
|||
|
|
if (defaultRay != null)
|
|||
|
|
{
|
|||
|
|
touchRenders = defaultRay.GetComponentsInChildren<SkinnedMeshRenderer>();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
protected void OnEnable() => Application.onBeforeRender += OnBeforeRender;
|
|||
|
|
|
|||
|
|
|
|||
|
|
protected void OnDisable() => Application.onBeforeRender -= OnBeforeRender;
|
|||
|
|
|
|||
|
|
private void OnBeforeRender()
|
|||
|
|
{
|
|||
|
|
UpdateHandJoints();
|
|||
|
|
UpdateAimState();
|
|||
|
|
UpdateRayPose();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateHandJoints()
|
|||
|
|
{
|
|||
|
|
if (PXR_HandTracking.GetJointLocations(handType, ref handJointLocations))
|
|||
|
|
{
|
|||
|
|
if (isaAdaptiveScales)
|
|||
|
|
{
|
|||
|
|
float scale = 0;
|
|||
|
|
PXR_HandTracking.GetHandScale(handType,ref scale);
|
|||
|
|
Basemesh.localScale = Vector3.one*scale;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < handJoints.Count; ++i)
|
|||
|
|
{
|
|||
|
|
if (handJoints[i] == null) continue;
|
|||
|
|
|
|||
|
|
if (i == (int)HandJoint.JointWrist)
|
|||
|
|
{
|
|||
|
|
handJoints[i].localPosition = handJointLocations.jointLocations[i].pose.Position.ToVector3();
|
|||
|
|
handJoints[i].localRotation = handJointLocations.jointLocations[i].pose.Orientation.ToQuat();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Pose parentPose = Pose.identity;
|
|||
|
|
|
|||
|
|
if (i == (int)HandJoint.JointPalm ||
|
|||
|
|
i == (int)HandJoint.JointThumbMetacarpal ||
|
|||
|
|
i == (int)HandJoint.JointIndexMetacarpal ||
|
|||
|
|
i == (int)HandJoint.JointMiddleMetacarpal ||
|
|||
|
|
i == (int)HandJoint.JointRingMetacarpal ||
|
|||
|
|
i == (int)HandJoint.JointLittleMetacarpal)
|
|||
|
|
{
|
|||
|
|
parentPose = new Pose(handJointLocations.jointLocations[1].pose.Position.ToVector3(), handJointLocations.jointLocations[1].pose.Orientation.ToQuat());
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
parentPose = new Pose(handJointLocations.jointLocations[i-1].pose.Position.ToVector3(), handJointLocations.jointLocations[i-1].pose.Orientation.ToQuat());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var inverseParentRotation = Quaternion.Inverse(parentPose.rotation);
|
|||
|
|
handJoints[i].localRotation = inverseParentRotation * handJointLocations.jointLocations[i].pose.Orientation.ToQuat();
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (mOffsetPos)
|
|||
|
|
{
|
|||
|
|
Basemesh.localPosition = handJointLocations.jointLocations[(int)Unity.XR.PXR.HandJoint.JointWrist].pose.Position.ToVector3()+ mOffsetPos.GetHandPosOffset();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateAimState()
|
|||
|
|
{
|
|||
|
|
if (PXR_HandTracking.GetAimState(handType, ref aimState))
|
|||
|
|
{
|
|||
|
|
Computed = (aimState.aimStatus&HandAimStatus.AimComputed) != 0;
|
|||
|
|
|
|||
|
|
RayPose = aimState.aimRayPose;
|
|||
|
|
RayValid = (aimState.aimStatus&HandAimStatus.AimRayValid) != 0;
|
|||
|
|
Pinch = (aimState.aimStatus&HandAimStatus.AimRayTouched) != 0;
|
|||
|
|
PinchStrength = aimState.touchStrengthRay;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateRayPose()
|
|||
|
|
{
|
|||
|
|
if (rayPose == null) return;
|
|||
|
|
|
|||
|
|
if (RayValid)
|
|||
|
|
{
|
|||
|
|
rayPose.gameObject.SetActive(true);
|
|||
|
|
rayPose.localPosition = RayPose.Position.ToVector3();
|
|||
|
|
rayPose.localRotation = RayPose.Orientation.ToQuat();
|
|||
|
|
|
|||
|
|
if (defaultRay != null)
|
|||
|
|
{
|
|||
|
|
foreach (var touchRender in touchRenders)
|
|||
|
|
{
|
|||
|
|
touchRender.SetBlendShapeWeight(0, aimState.touchStrengthRay*100);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
rayPose.gameObject.SetActive(false);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#endif
|