public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(position, label, property); InitializeUnfold(property); Rect rowRect = new Rect(position.x, position.y, position.width, EditorConstants.ROW_HEIGHT); _unfolds[property.propertyPath] = EditorGUI.Foldout(rowRect, _unfolds[property.propertyPath], label, true); if (_unfolds[property.propertyPath]) { EditorGUI.indentLevel++; for (int i = 0; i < Constants.NUM_FINGERS; i++) { rowRect.y += EditorConstants.ROW_HEIGHT; SerializedProperty finger = property.FindPropertyRelative(FINGER_PROPERTY_NAMES[i]); HandFinger fingerID = (HandFinger)i; FingerRequirement current = (FingerRequirement)finger.intValue; FingerRequirement selected = (FingerRequirement)EditorGUI.EnumPopup(rowRect, $"{fingerID}: ", current); finger.intValue = (int)selected; } rowRect.y += EditorConstants.ROW_HEIGHT; DrawFlagProperty <FingerUnselectMode>(property, rowRect, "Unselect Mode", "_unselectMode", false); EditorGUI.indentLevel--; } EditorGUI.EndProperty(); }
public bool GetFingerIsTouchingHand(HandFinger finger) { Transform t1 = GetOVRBoneTransform(finger, FingerPhalange.Proximal); Transform t2 = GetOVRBoneTransform(finger, FingerPhalange.Intermediate); Transform t3 = GetOVRBoneTransform(finger, FingerPhalange.Distal); Transform t4 = GetOVRBoneTransform(finger, FingerPhalange.Tip); Vector3 u = t4.position - t3.position; Vector3 v = t2.position - t3.position; return(Vector3.Angle(u, v) < 150); //QuickOVRHandBonePhysics tipBone = GetHandBonePhysics(GetHandBoneTip(finger)); //if (tipBone) //{ // Collider[] colliders = Physics.OverlapSphere(tipBone.transform.position, tipBone.GetCollider().radius); // foreach (Collider c in colliders) // { // if (c == _handCollider) // { // return true; // } // } //} //return false; //QuickOVRHandBonePhysics tipBone = GetHandBonePhysics(GetHandBoneTip(finger)); //QuickOVRHandBonePhysics proximalBone = GetHandBonePhysics(GetHandBoneProximal(finger)); //return Vector3.Distance(tipBone.transform.position, proximalBone.transform.position) < 0.05f; }
private void ReadStateThresholds() { Assert.IsNotNull(_fingerStateThresholds); Assert.IsNotNull(_timeProvider); Assert.AreEqual(Constants.NUM_FINGERS, _fingerStateThresholds.Count); HandFingerFlags seenFingers = HandFingerFlags.None; foreach (FingerStateThresholds fingerStateThresholds in _fingerStateThresholds) { seenFingers |= HandFingerUtils.ToFlags(fingerStateThresholds.Finger); HandFinger finger = fingerStateThresholds.Finger; var featureStateProvider = _state.GetStateProvider(finger); if (featureStateProvider == null) { featureStateProvider = new FeatureStateProvider <FingerFeature, string>( feature => GetFeatureValue(finger, feature), feature => (int)feature, _timeProvider); _state.InitializeFinger(fingerStateThresholds.Finger, featureStateProvider); } featureStateProvider.InitializeThresholds(fingerStateThresholds.StateThresholds); } Assert.AreEqual(seenFingers, HandFingerFlags.All); }
public FingerGrabData(HandFinger fingerId) { _fingerID = fingerId; Vector2 range = CURL_RANGE[(int)_fingerID]; _curlNormalizationParams = new Vector2(range.x, range.y - range.x); }
private void DrawBonesRotator(List <HandJointMap> bones) { foreach (HandJointMap bone in bones) { int metadataIndex = FingersMetadata.HandJointIdToIndex(bone.id); HandFinger finger = FingersMetadata.HAND_FINGER_ID[metadataIndex]; if (_handGrabPoint.HandPose.FingersFreedom[(int)finger] == JointFreedom.Free) { continue; } Handles.color = EditorConstants.PRIMARY_COLOR; Quaternion rotation = Handles.Disc(bone.transform.rotation, bone.transform.position, bone.transform.forward, GIZMO_SCALE, false, 0); if (FingersMetadata.HAND_JOINT_CAN_SPREAD[metadataIndex]) { Handles.color = EditorConstants.SECONDARY_COLOR; rotation = Handles.Disc(rotation, bone.transform.position, bone.transform.up, GIZMO_SCALE, false, 0); } if (bone.transform.rotation != rotation) { Undo.RecordObject(bone.transform, "Bone Rotation"); bone.transform.rotation = rotation; } } }
public FingerRequirement this[HandFinger fingerID] { get { switch (fingerID) { case HandFinger.Thumb: return(_thumbRequirement); case HandFinger.Index: return(_indexRequirement); case HandFinger.Middle: return(_middleRequirement); case HandFinger.Ring: return(_ringRequirement); case HandFinger.Pinky: return(_pinkyRequirement); } return(FingerRequirement.Ignored); } set { switch (fingerID) { case HandFinger.Thumb: _thumbRequirement = value; break; case HandFinger.Index: _indexRequirement = value; break; case HandFinger.Middle: _middleRequirement = value; break; case HandFinger.Ring: _ringRequirement = value; break; case HandFinger.Pinky: _pinkyRequirement = value; break; } } }
public void InitializeFinger(HandFinger finger, FeatureStateProvider <FingerFeature, string> stateProvider) { _fingerState[(int)finger] = new HandFingerState { StateProvider = stateProvider }; }
/// <summary> /// Returns the current value of the feature. If the finger joints are not populated with /// valid data (for instance, due to a disconnected hand), the method will return NaN. /// </summary> public float?GetFeatureValue(HandFinger finger, FingerFeature fingerFeature) { if (!IsDataValid()) { return(null); } return(_fingerShapes.GetValue(finger, fingerFeature, Hand)); }
public bool TryGetFingerBones(HandFinger finger, List <Bone> bonesOut) { if (bonesOut == null) { throw new ArgumentNullException("bonesOut"); } return(Hand_TryGetFingerBonesAsList(this, finger, bonesOut)); }
public void Initialize(HandFinger handFinger, ShapeRecognizer.FingerFeatureConfig config, FingerFeatureStateProvider fingerFeatureState) { _initialized = true; _handFinger = handFinger; _featureConfig = config; _fingerFeatureState = fingerFeatureState; }
public HandJointPoseMetaData(HandFinger finger, HandJointId joint, int bufferLength) { Finger = finger; JointId = joint; Velocities = new List <Vector3>(); _previousPosition = null; _lastWritePos = -1; _bufferLength = bufferLength; }
public void StripIrrelevant(ref HandFingerFlags fingerFlags) { for (int i = 0; i < Constants.NUM_FINGERS; i++) { HandFinger finger = (HandFinger)i; if (this[finger] == FingerRequirement.Ignored) { fingerFlags = (HandFingerFlags)((int)fingerFlags & ~(1 << i)); } } }
public TrackingConfidence GetFingerConfidence(HandFinger finger) { if (IsDataValid && _handState.FingerConfidences != null && _handState.FingerConfidences.Length == (int)OVRPlugin.HandFinger.Max) { return((TrackingConfidence)_handState.FingerConfidences[(int)finger]); } return(TrackingConfidence.Low); }
public float GetFingerPinchStrength(HandFinger finger) { if (IsDataValid && _handState.PinchStrength != null && _handState.PinchStrength.Length == (int)OVRPlugin.HandFinger.Max) { return(_handState.PinchStrength[(int)finger]); } return(0.0f); }
public bool GetCurrentState(HandFinger finger, FingerFeature fingerFeature, out string currentState) { if (!IsDataValid()) { currentState = default; return(false); } else { currentState = GetCurrentFingerFeatureState(finger, fingerFeature); return(currentState != default); } }
/// <summary> /// Get a float value the finger pinch strength based on the abstract input button /// </summary> /// <param name="h">Which hand is the axis on</param> /// <param name="b">Which button is being pressed</param> /// <returns>A float from 0-1 indicating how much the input has been pressed</returns> public override float GetAxis(Hand h, Button b) { GameObject handObj = (h == Hand.Left) ? leftHand : rightHand; OVRHand hand = handObj.GetComponent <OVRHand>(); HandFinger finger = FingerMap(b); if (hand && hand.GetFingerConfidence(finger) == TrackingConfidence.High) { return(hand.GetFingerPinchStrength(finger)); } return(0f); }
/// <summary> /// Get a float value the finger pinch strength based on the abstract input button /// </summary> /// <param name="h">Which hand is the axis on</param> /// <param name="b">Which button is being pressed</param> /// <returns>A float from 0-1 indicating how much the input has been pressed</returns> public override float GetAxis(Hand h, Button b) { var handObj = (h == Hand.Left) ? leftHand : rightHand; OVRHand hand = handObj.ActualOvrHand; HandFinger finger = FingerMap(b); if (hand && hand.GetFingerConfidence(finger) == TrackingConfidence.High) { return(hand.GetFingerPinchStrength(finger)); } return(0f); }
/// <inheritdoc /> public bool TryGetFingerCurlStrength(HandFinger handFinger, out float curlStrength) { var index = (int)handFinger; if (FingerCurlStrengths != null && FingerCurlStrengths.Length >= index) { curlStrength = FingerCurlStrengths[index]; return(true); } curlStrength = 0f; return(false); }
/// <summary> /// Get whether the correct finger has been pinched based on the abstract input button /// </summary> /// <param name="h">Which hand is the button on</param> /// <param name="b">Which button is being pressed</param> /// <returns>A bool indicating whether the given button has been pressed</returns> public override bool GetButton(Hand h, Button b) { var handObj = (h == Hand.Left) ? leftHand : rightHand; OVRHand hand = handObj.ActualOvrHand; HandFinger finger = FingerMap(b); if (hand && hand.GetFingerConfidence(finger) == TrackingConfidence.High) { return(hand.GetFingerIsPinching(finger)); } return(false); //null check for hand }
public float GetFingerGrabScore(HandFinger finger) { if (finger == HandFinger.Thumb) { float max = 0.0f; for (int i = 1; i < Constants.NUM_FINGERS; ++i) { max = Mathf.Max(max, _fingersPinchData[i].PinchStrength); } return(max); } return(_fingersPinchData[(int)finger].PinchStrength); }
GetFingerFeatureConfigs() { for (var fingerIdx = 0; fingerIdx < Constants.NUM_FINGERS; ++fingerIdx) { HandFinger finger = (HandFinger)fingerIdx; var configs = GetFingerFeatureConfigs(finger); if (configs.Count == 0) { continue; } yield return(new ValueTuple <HandFinger, IReadOnlyList <FingerFeatureConfig> >(finger, configs)); } }
public bool IsStateActive(HandFinger finger, FingerFeature feature, FeatureStateActiveMode mode, string stateId) { var currentState = GetCurrentFingerFeatureState(finger, feature); switch (mode) { case FeatureStateActiveMode.Is: return(currentState == stateId); case FeatureStateActiveMode.IsNot: return(currentState != stateId); default: return(false); } }
/// <summary> /// Converts a Unity finger bone into an MRTK hand joint. /// </summary> /// <remarks> /// For HoloLens 2, Unity provides four joints for the thumb and five joints for other fingers, in index order of metacarpal (0) to tip (4). /// The wrist joint is provided as the hand root bone. /// </remarks> /// <param name="finger">The Unity classification of the current finger.</param> /// <param name="index">The Unity index of the current finger bone.</param> /// <returns>The current Unity finger bone converted into an MRTK joint.</returns> private TrackedHandJoint ConvertToTrackedHandJoint(HandFinger finger, int index) { switch (finger) { case HandFinger.Thumb: return((index == 0) ? TrackedHandJoint.Wrist : TrackedHandJoint.ThumbMetacarpalJoint + index - 1); case HandFinger.Index: return(TrackedHandJoint.IndexMetacarpal + index); case HandFinger.Middle: return(TrackedHandJoint.MiddleMetacarpal + index); case HandFinger.Ring: return(TrackedHandJoint.RingMetacarpal + index); case HandFinger.Pinky: return(TrackedHandJoint.PinkyMetacarpal + index); default: return(TrackedHandJoint.None); } }
private void UpdateVisual() { bool isSelecting = Interactor.State == InteractorState.Select; bool isSelectingInteractable = Interactor.HasSelectedInteractable; bool hasHoverTarget = Interactor.HasCandidate; Color desiredGlowColor = isSelectingInteractable ? _fingerGlowColorWithInteractable : _fingerGlowColorWithNoInteractable; _currentGlowColor = Color.Lerp(_currentGlowColor, desiredGlowColor, Time.deltaTime * _glowColorLerpSpeed); _handMaterialPropertyBlockEditor.MaterialPropertyBlock.SetColor(_fingerGlowColorPropertyId, _currentGlowColor); for (int i = 0; i < Constants.NUM_FINGERS; ++i) { if ((isSelecting && !isSelectingInteractable) || (!isSelecting && !hasHoverTarget)) { UpdateGlowValue(i, 0f); continue; } float glowValue = 0f; HandFinger finger = (HandFinger)i; if ((HandGrab.SupportedGrabTypes & GrabTypeFlags.Pinch) != 0 && HandGrab.TargetInteractable != null && (HandGrab.TargetInteractable.SupportedGrabTypes & GrabTypeFlags.Pinch) != 0 && HandGrab.TargetInteractable.PinchGrabRules[finger] != GrabAPI.FingerRequirement.Ignored) { glowValue = Mathf.Max(glowValue, HandGrab.HandGrabApi.GetFingerPinchStrength(finger)); } if ((HandGrab.SupportedGrabTypes & GrabTypeFlags.Palm) != 0 && HandGrab.TargetInteractable != null && (HandGrab.TargetInteractable.SupportedGrabTypes & GrabTypeFlags.Palm) != 0 && HandGrab.TargetInteractable.PalmGrabRules[finger] != GrabAPI.FingerRequirement.Ignored) { glowValue = Mathf.Max(glowValue, HandGrab.HandGrabApi.GetFingerPalmStrength(finger)); } UpdateGlowValue(i, glowValue); } _handMaterialPropertyBlockEditor.UpdateMaterialPropertyBlock(); }
public bool GetFingerIsGrabbing(HandFinger finger) { if (finger == HandFinger.Thumb) { for (int i = 1; i < Constants.NUM_FINGERS; ++i) { if (_fingersPinchData[i].IsPinching) { return(true); } } return(false); } return(_fingersPinchData[(int)finger].IsPinching); }
private HandFingerFlags HandGrabbingFingers(IFingerAPI fingerAPI) { HandFingerFlags grabbingFingers = HandFingerFlags.None; for (int i = 0; i < Constants.NUM_FINGERS; i++) { HandFinger finger = (HandFinger)i; bool isGrabbing = fingerAPI.GetFingerIsGrabbing(finger); if (isGrabbing) { grabbingFingers |= (HandFingerFlags)(1 << i); } } return(grabbingFingers); }
public bool GetFingerIsGrabbingChanged(HandFinger finger, bool targetPinchState) { if (finger == HandFinger.Thumb) { // Thumb pinching changed logic only happens on // the first finger pinching changed when pinching, // or any finger pinching changed when not pinching bool pinching = GetFingerIsGrabbing(finger); if (pinching != targetPinchState) { return(false); } if (pinching) { for (int i = 1; i < Constants.NUM_FINGERS; ++i) { if (_fingersPinchData[i].IsPinching == pinching && !_fingersPinchData[i].IsPinchingChanged) { return(false); } } return(true); } else { for (int i = 1; i < Constants.NUM_FINGERS; ++i) { if (_fingersPinchData[i].IsPinchingChanged) { return(true); } } return(false); } } return(_fingersPinchData[(int)finger].IsPinchingChanged && _fingersPinchData[(int)finger].IsPinching == targetPinchState); }
public virtual float GetValue(HandFinger finger, FingerFeature feature, IHand hand) { switch (feature) { case FingerFeature.Curl: return(GetCurlValue(finger, hand)); case FingerFeature.Flexion: return(GetFlexionValue(finger, hand)); case FingerFeature.Abduction: return(GetAbductionValue(finger, hand)); case FingerFeature.Opposition: return(GetOppositionValue(finger, hand)); default: return(0.0f); } }
protected virtual OVRSkeleton.BoneId GetHandBoneTip(HandFinger finger) { if (finger == HandFinger.Thumb) { return(OVRSkeleton.BoneId.Hand_Thumb3); } if (finger == HandFinger.Index) { return(OVRSkeleton.BoneId.Hand_Index3); } if (finger == HandFinger.Middle) { return(OVRSkeleton.BoneId.Hand_Middle3); } if (finger == HandFinger.Ring) { return(OVRSkeleton.BoneId.Hand_Ring3); } return(OVRSkeleton.BoneId.Hand_Pinky3); }
/// <summary> /// Converts a Unity finger bone into an MRTK hand joint. /// </summary> /// <remarks> /// <para>For HoloLens 2, Unity provides four joints per finger, in index order of metacarpal (0) to tip (4). /// The first joint for the thumb is the wrist joint. Palm joint is not provided.</para> /// </remarks> /// <param name="finger">The Unity classification of the current finger.</param> /// <param name="index">The Unity index of the current finger bone.</param> /// <returns>The current Unity finger bone converted into an MRTK joint.</returns> private int ConvertToArrayIndex(HandFinger finger, int index) { TrackedHandJoint trackedHandJoint; switch (finger) { case HandFinger.Thumb: trackedHandJoint = (index == 0) ? TrackedHandJoint.Wrist : TrackedHandJoint.ThumbMetacarpalJoint + index - 1; break; case HandFinger.Index: trackedHandJoint = TrackedHandJoint.IndexMetacarpal + index; break; case HandFinger.Middle: trackedHandJoint = TrackedHandJoint.MiddleMetacarpal + index; break; case HandFinger.Ring: trackedHandJoint = TrackedHandJoint.RingMetacarpal + index; break; case HandFinger.Pinky: trackedHandJoint = TrackedHandJoint.PinkyMetacarpal + index; break; default: trackedHandJoint = TrackedHandJoint.None; break; } return((int)trackedHandJoint); }