示例#1
0
        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();
        }
示例#2
0
        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;
        }
示例#3
0
        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);
        }
示例#4
0
            public FingerGrabData(HandFinger fingerId)
            {
                _fingerID = fingerId;
                Vector2 range = CURL_RANGE[(int)_fingerID];

                _curlNormalizationParams = new Vector2(range.x, range.y - range.x);
            }
示例#5
0
        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;
                }
            }
        }
示例#6
0
        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;
                }
            }
        }
示例#7
0
 public void InitializeFinger(HandFinger finger,
                              FeatureStateProvider <FingerFeature, string> stateProvider)
 {
     _fingerState[(int)finger] = new HandFingerState
     {
         StateProvider = stateProvider
     };
 }
示例#8
0
        /// <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));
        }
示例#10
0
 public void Initialize(HandFinger handFinger,
                        ShapeRecognizer.FingerFeatureConfig config,
                        FingerFeatureStateProvider fingerFeatureState)
 {
     _initialized        = true;
     _handFinger         = handFinger;
     _featureConfig      = config;
     _fingerFeatureState = fingerFeatureState;
 }
示例#11
0
 public HandJointPoseMetaData(HandFinger finger,
                              HandJointId joint, int bufferLength)
 {
     Finger            = finger;
     JointId           = joint;
     Velocities        = new List <Vector3>();
     _previousPosition = null;
     _lastWritePos     = -1;
     _bufferLength     = bufferLength;
 }
示例#12
0
 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));
         }
     }
 }
示例#13
0
    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);
    }
示例#14
0
    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);
    }
示例#15
0
 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);
        }
示例#18
0
        /// <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
        }
示例#20
0
        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);
        }
示例#21
0
        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));
            }
        }
示例#22
0
        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);
            }
        }
示例#24
0
        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();
        }
示例#25
0
        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);
        }
示例#26
0
        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);
        }
示例#27
0
        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);
        }
示例#28
0
        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);
            }
        }
示例#29
0
 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);
        }