332 lines
15 KiB
C#
332 lines
15 KiB
C#
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
* All rights reserved.
|
|
*
|
|
* Licensed under the Oculus SDK License Agreement (the "License");
|
|
* you may not use the Oculus SDK except in compliance with the License,
|
|
* which is provided at the time of installation or download, or which
|
|
* otherwise accompanies this software in either electronic or hard copy form.
|
|
*
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* https://developer.oculus.com/licenses/oculussdk/
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
using Oculus.Interaction.Input;
|
|
using System;
|
|
using UnityEngine;
|
|
|
|
namespace Oculus.Interaction.PoseDetection
|
|
{
|
|
public enum TransformFeature
|
|
{
|
|
WristUp,
|
|
WristDown,
|
|
PalmDown,
|
|
PalmUp,
|
|
PalmTowardsFace,
|
|
PalmAwayFromFace,
|
|
FingersUp,
|
|
FingersDown,
|
|
PinchClear
|
|
};
|
|
|
|
public class TransformFeatureValueProvider
|
|
{
|
|
public struct TransformProperties
|
|
{
|
|
public TransformProperties(Pose centerEyePos,
|
|
Pose wristPose,
|
|
Handedness handedness,
|
|
Vector3 trackingSystemUp,
|
|
Vector3 trackingSystemForward)
|
|
{
|
|
CenterEyePose = centerEyePos;
|
|
WristPose = wristPose;
|
|
Handedness = handedness;
|
|
TrackingSystemUp = trackingSystemUp;
|
|
TrackingSystemForward = trackingSystemForward;
|
|
}
|
|
|
|
public readonly Pose CenterEyePose;
|
|
public readonly Pose WristPose;
|
|
public readonly Handedness Handedness;
|
|
public readonly Vector3 TrackingSystemUp;
|
|
public readonly Vector3 TrackingSystemForward;
|
|
}
|
|
|
|
public static float GetValue(TransformFeature transformFeature, TransformJointData transformJointData,
|
|
TransformConfig transformConfig)
|
|
{
|
|
TransformProperties transformProps =
|
|
new TransformProperties(transformJointData.CenterEyePose, transformJointData.WristPose,
|
|
transformJointData.Handedness, transformJointData.TrackingSystemUp,
|
|
transformJointData.TrackingSystemForward);
|
|
switch (transformFeature)
|
|
{
|
|
case TransformFeature.WristDown:
|
|
return GetWristDownValue(in transformProps, in transformConfig);
|
|
case TransformFeature.WristUp:
|
|
return GetWristUpValue(in transformProps, in transformConfig);
|
|
case TransformFeature.PalmDown:
|
|
return GetPalmDownValue(in transformProps, in transformConfig);
|
|
case TransformFeature.PalmUp:
|
|
return GetPalmUpValue(in transformProps, in transformConfig);
|
|
case TransformFeature.PalmTowardsFace:
|
|
return GetPalmTowardsFaceValue(in transformProps, in transformConfig);
|
|
case TransformFeature.PalmAwayFromFace:
|
|
return GetPalmAwayFromFaceValue(in transformProps, in transformConfig);
|
|
case TransformFeature.FingersUp:
|
|
return GetFingersUpValue(in transformProps, in transformConfig);
|
|
case TransformFeature.FingersDown:
|
|
return GetFingersDownValue(in transformProps, in transformConfig);
|
|
case TransformFeature.PinchClear:
|
|
default:
|
|
return GetPinchClearValue(in transformProps, in transformConfig);
|
|
}
|
|
}
|
|
|
|
[Obsolete("The " + nameof(TransformConfig) + " parameter is obsolete")]
|
|
public static Vector3 GetHandVectorForFeature(TransformFeature transformFeature,
|
|
in TransformJointData transformJointData,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
return GetHandVectorForFeature(transformFeature, in transformJointData);
|
|
}
|
|
|
|
public static Vector3 GetHandVectorForFeature(TransformFeature transformFeature,
|
|
in TransformJointData transformJointData)
|
|
{
|
|
TransformProperties transformProps =
|
|
new TransformProperties(transformJointData.CenterEyePose, transformJointData.WristPose,
|
|
transformJointData.Handedness, transformJointData.TrackingSystemUp,
|
|
transformJointData.TrackingSystemForward);
|
|
return GetHandVectorForFeature(transformFeature, in transformProps);
|
|
}
|
|
|
|
private static Vector3 GetHandVectorForFeature(TransformFeature transformFeature,
|
|
in TransformProperties transformProps)
|
|
{
|
|
Vector3 handVector;
|
|
Quaternion rotation = transformProps.WristPose.rotation;
|
|
bool isLeft = transformProps.Handedness == Handedness.Left;
|
|
|
|
switch (transformFeature)
|
|
{
|
|
case TransformFeature.WristDown:
|
|
handVector = rotation * (isLeft ? Constants.LeftPinkySide : Constants.RightPinkySide);
|
|
break;
|
|
case TransformFeature.WristUp:
|
|
handVector = rotation * (isLeft ? Constants.LeftThumbSide : Constants.RightThumbSide);
|
|
break;
|
|
case TransformFeature.PalmDown:
|
|
handVector = rotation * (isLeft ? Constants.LeftDorsal : Constants.RightDorsal);
|
|
break;
|
|
case TransformFeature.PalmUp:
|
|
handVector = rotation * (isLeft ? Constants.LeftPalmar : Constants.RightPalmar);
|
|
break;
|
|
case TransformFeature.PalmTowardsFace:
|
|
handVector = rotation * (isLeft ? Constants.LeftDorsal : Constants.RightDorsal);
|
|
break;
|
|
case TransformFeature.PalmAwayFromFace:
|
|
handVector = rotation * (isLeft ? Constants.LeftPalmar : Constants.RightPalmar);
|
|
break;
|
|
case TransformFeature.FingersUp:
|
|
handVector = rotation * (isLeft ? Constants.LeftDistal : Constants.RightDistal);
|
|
break;
|
|
case TransformFeature.FingersDown:
|
|
handVector = rotation * (isLeft ? Constants.LeftProximal : Constants.RightProximal);
|
|
break;
|
|
case TransformFeature.PinchClear:
|
|
handVector = rotation * (isLeft ? Constants.LeftPinkySide : Constants.RightPinkySide);
|
|
break;
|
|
default:
|
|
handVector = rotation * (isLeft ? Constants.LeftPinkySide : Constants.RightPinkySide);
|
|
break;
|
|
}
|
|
return handVector;
|
|
}
|
|
|
|
public static Vector3 GetTargetVectorForFeature(TransformFeature transformFeature,
|
|
in TransformJointData transformJointData,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
TransformProperties transformProps =
|
|
new TransformProperties(transformJointData.CenterEyePose, transformJointData.WristPose,
|
|
transformJointData.Handedness, transformJointData.TrackingSystemUp,
|
|
transformJointData.TrackingSystemForward);
|
|
return GetTargetVectorForFeature(transformFeature, in transformProps, in transformConfig);
|
|
}
|
|
|
|
private static Vector3 GetTargetVectorForFeature(TransformFeature transformFeature,
|
|
in TransformProperties transformProps,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
Vector3 targetVector = Vector3.zero;
|
|
switch (transformFeature)
|
|
{
|
|
case TransformFeature.WristDown:
|
|
case TransformFeature.PalmDown:
|
|
case TransformFeature.FingersDown:
|
|
case TransformFeature.WristUp:
|
|
case TransformFeature.PalmUp:
|
|
case TransformFeature.FingersUp:
|
|
targetVector = OffsetVectorWithRotation(transformProps,
|
|
GetVerticalVector(transformProps.CenterEyePose,
|
|
transformProps.TrackingSystemUp,
|
|
in transformConfig),
|
|
in transformConfig);
|
|
break;
|
|
case TransformFeature.PalmTowardsFace:
|
|
case TransformFeature.PalmAwayFromFace:
|
|
case TransformFeature.PinchClear:
|
|
targetVector = OffsetVectorWithRotation(transformProps,
|
|
transformProps.CenterEyePose.forward,
|
|
in transformConfig);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return targetVector;
|
|
}
|
|
|
|
private static float GetWristDownValue(in TransformProperties transformProps,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
Vector3 handVector = GetHandVectorForFeature(TransformFeature.WristDown,
|
|
in transformProps);
|
|
Vector3 targetVector = GetTargetVectorForFeature(TransformFeature.WristDown,
|
|
in transformProps, in transformConfig);
|
|
return Vector3.Angle(handVector, targetVector);
|
|
}
|
|
|
|
private static float GetWristUpValue(in TransformProperties transformProps,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
Vector3 handVector = GetHandVectorForFeature(TransformFeature.WristUp,
|
|
in transformProps);
|
|
Vector3 targetVector = GetTargetVectorForFeature(TransformFeature.WristUp,
|
|
in transformProps, in transformConfig);
|
|
return Vector3.Angle(handVector, targetVector);
|
|
}
|
|
|
|
private static float GetPalmDownValue(in TransformProperties transformProps,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
Vector3 handVector = GetHandVectorForFeature(TransformFeature.PalmDown,
|
|
in transformProps);
|
|
Vector3 targetVector = GetTargetVectorForFeature(TransformFeature.PalmDown,
|
|
in transformProps, in transformConfig);
|
|
return Vector3.Angle(handVector, targetVector);
|
|
}
|
|
|
|
private static float GetPalmUpValue(in TransformProperties transformProps,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
Vector3 handVector = GetHandVectorForFeature(TransformFeature.PalmUp,
|
|
in transformProps);
|
|
Vector3 targetVector = GetTargetVectorForFeature(TransformFeature.PalmUp,
|
|
in transformProps, in transformConfig);
|
|
return Vector3.Angle(handVector, targetVector);
|
|
}
|
|
|
|
private static float GetPalmTowardsFaceValue(in TransformProperties transformProps,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
Vector3 handVector = GetHandVectorForFeature(TransformFeature.PalmTowardsFace,
|
|
in transformProps);
|
|
Vector3 targetVector = GetTargetVectorForFeature(TransformFeature.PalmTowardsFace,
|
|
in transformProps, in transformConfig);
|
|
return Vector3.Angle(handVector, targetVector);
|
|
}
|
|
|
|
private static float GetPalmAwayFromFaceValue(in TransformProperties transformProps,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
Vector3 handVector = GetHandVectorForFeature(TransformFeature.PalmAwayFromFace,
|
|
in transformProps);
|
|
Vector3 targetVector = GetTargetVectorForFeature(TransformFeature.PalmAwayFromFace,
|
|
in transformProps, in transformConfig);
|
|
return Vector3.Angle(handVector, targetVector);
|
|
}
|
|
|
|
private static float GetFingersUpValue(in TransformProperties transformProps,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
Vector3 handVector = GetHandVectorForFeature(TransformFeature.FingersUp,
|
|
in transformProps);
|
|
Vector3 targetVector = GetTargetVectorForFeature(TransformFeature.FingersUp,
|
|
in transformProps, in transformConfig);
|
|
return Vector3.Angle(handVector, targetVector);
|
|
}
|
|
|
|
private static float GetFingersDownValue(in TransformProperties transformProps,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
Vector3 handVector = GetHandVectorForFeature(TransformFeature.FingersDown,
|
|
in transformProps);
|
|
Vector3 targetVector = GetTargetVectorForFeature(TransformFeature.FingersDown,
|
|
in transformProps, in transformConfig);
|
|
return Vector3.Angle(handVector, targetVector);
|
|
}
|
|
|
|
private static float GetPinchClearValue(in TransformProperties transformProps,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
Vector3 handVector = GetHandVectorForFeature(TransformFeature.PinchClear,
|
|
in transformProps);
|
|
Vector3 targetVector = GetTargetVectorForFeature(TransformFeature.PinchClear,
|
|
in transformProps, in transformConfig);
|
|
return Vector3.Angle(handVector, targetVector);
|
|
}
|
|
|
|
private static Vector3 GetVerticalVector(in Pose centerEyePose,
|
|
in Vector3 trackingSystemUp,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
switch (transformConfig.UpVectorType)
|
|
{
|
|
case UpVectorType.Head:
|
|
return centerEyePose.up;
|
|
case UpVectorType.Tracking:
|
|
return trackingSystemUp;
|
|
case UpVectorType.World:
|
|
return Vector3.up;
|
|
default:
|
|
return Vector3.up;
|
|
}
|
|
}
|
|
|
|
private static Vector3 OffsetVectorWithRotation(in TransformProperties transformProps,
|
|
in Vector3 originalVector,
|
|
in TransformConfig transformConfig)
|
|
{
|
|
Quaternion baseRotation;
|
|
switch (transformConfig.UpVectorType)
|
|
{
|
|
case UpVectorType.Head:
|
|
baseRotation = transformProps.CenterEyePose.rotation;
|
|
break;
|
|
case UpVectorType.Tracking:
|
|
baseRotation =
|
|
Quaternion.LookRotation(transformProps.TrackingSystemForward,
|
|
transformProps.TrackingSystemUp);
|
|
break;
|
|
case UpVectorType.World:
|
|
default:
|
|
baseRotation = Quaternion.identity;
|
|
break;
|
|
}
|
|
|
|
Quaternion offset = Quaternion.Euler(transformConfig.RotationOffset);
|
|
return baseRotation * offset * Quaternion.Inverse(baseRotation) * originalVector;
|
|
}
|
|
}
|
|
}
|