Пример #1
0
        public virtual bool IsGestureOccuring(SDK_BaseGestureLibrary.Hand handToCheck)
        {
            // if not detected, it cannot be gesturing
            if (!VRTK_SDK_Bridge.GetHandSDK().GetGestureLibrary().IsHandDetected(handToCheck))
            {
                return(false);
            }

            bool isGestureOccuring = true;

            if (handSpecific && specificHand != handToCheck)
            {
                return(false);
            }

            for (int gestureConditionIndex = 0; gestureConditionIndex < gestureConditionList.Count; gestureConditionIndex++)
            {
                GestureCondition condition          = gestureConditionList[gestureConditionIndex];
                bool             thisConditionIsMet = true;
                thisConditionIsMet = GetBoolValue(condition.featureToCheck, handToCheck) == condition.featureValue;
                isGestureOccuring  = isGestureOccuring && thisConditionIsMet;
                // Quick return, if at any time one is false, then it would not execute
                if (!isGestureOccuring)
                {
                    return(isGestureOccuring);
                }
            }

            return(isGestureOccuring);
        }
Пример #2
0
        public override bool IsConditionOccuring(SDK_BaseGestureLibrary.Hand specificHand, AdvancedGesture advancedGestureInfo)
        {
            Vector3 palmPosition;
            Vector3 previousPalmPosition;

            if (specificHand == SDK_BaseGestureLibrary.Hand.Left)
            {
                previousPalmPosition = advancedGestureInfo.prevLeftPalmPosition;
                palmPosition         = advancedGestureInfo.GetLeftHandPosition();
            }
            else
            {
                previousPalmPosition = advancedGestureInfo.prevRightPalmPosition;
                palmPosition         = advancedGestureInfo.GetRightHandPosition();
            }

            if (palmPosition == Vector3.zero)
            {
                // vector3 zero is the 'null' for vectors
                return(false);
            }

            float palmMovementDistance = Vector3.Distance(palmPosition, previousPalmPosition);

            // switch statement effectively controls which operator is used when comparing the actual palm movement amount to the desired palm movement amount
            switch (distanceOperator)
            {
            case MovementOperator.LessThan:
            {
                if (palmMovementDistance < distanceFromPreviousGesture)
                {
                    return(true);
                }
                break;
            }

            case MovementOperator.GreaterThan:
            {
                if (palmMovementDistance > distanceFromPreviousGesture)
                {
                    return(true);
                }
                break;
            }

            case MovementOperator.EqualTo:
            {
                if ((distanceFromPreviousGesture - distanceTolerance <= palmMovementDistance && palmMovementDistance <= distanceFromPreviousGesture + distanceTolerance))
                {
                    return(true);
                }
                break;
            }
            }
            return(false);
        }
Пример #3
0
        public override bool IsGestureOccuring(SDK_BaseGestureLibrary.Hand specificHand)
        {
            // if not detected, it cannot be gesturing
            if (!VRTK_SDK_Bridge.GetHandSDK().GetGestureLibrary().IsHandDetected(specificHand))
            {
                return(false);
            }

            // OpenMG has a habit of claiming gestures are occuring at the start of the scene before hands are even detected.
            // this delay ensures that no gesture fire until the system is fully started
            if (Time.time < startupDelayTime)
            {
                return(false);
            }

            if (!allowedWhileHoldingObjects)
            {
                if (IsHoldingObject(SDK_BaseGestureLibrary.Hand.Left) || IsHoldingObject(SDK_BaseGestureLibrary.Hand.Right))
                {
                    return(false);
                }
            }

            bool isCooldownActive       = Time.time <= (gestureCooldownStartTime + gestureCooldown);
            bool isCurrentStateOccuring = advancedGestureStateList[currentGestureStateIndex].coreGesture.IsGestureOccuring(specificHand);

            foreach (AdvancedGestureCondition advCondition in advancedGestureStateList[currentGestureStateIndex].AdvancedGestureConditionList)
            {
                isCurrentStateOccuring = isCurrentStateOccuring && advCondition.IsConditionOccuring(specificHand, this);
            }
            if (isCurrentStateOccuring && advancedGestureStateList.Count == currentGestureStateIndex + 1)
            {
                if (isCooldownActive == false)
                {
                    gestureCooldownStartTime = Time.time;
                }
                return(true);
            }
            else if (isCurrentStateOccuring)
            {
                currentGestureStateIndex++;
                gestureStartTime      = Time.time;
                prevLeftPalmPosition  = GetLeftHandPosition();
                prevRightPalmPosition = GetRightHandPosition();
            }
            else
            {
                if (advancedGestureStateList[currentGestureStateIndex].holdTime != 0 && advancedGestureStateList[currentGestureStateIndex].holdTime + gestureStartTime <= Time.time)
                {
                    ResetGestureChain();
                }
            }
            return(isCooldownActive);
        }
Пример #4
0
        /// <summary>
        /// Returns true if the specified hand is holding an object and false otherwise.
        /// </summary>
        public bool IsHoldingObject(SDK_BaseGestureLibrary.Hand hand)
        {
            Transform handRoot = VRTK_SDK_Bridge.GetHandSDK().GetRootTransform();

            if (handRoot == null)
            {
                // if the hand is not visible, the user isn't holding an object
                return(false);
            }

            if (hand == SDK_BaseGestureLibrary.Hand.Left && IsInteractGrabValid(cachedLeftHandGrabber))
            {
                // if not null, an object is being held
                return(cachedLeftHandGrabber.GetGrabbedObject() != null);
            }

            if (hand == SDK_BaseGestureLibrary.Hand.Right && IsInteractGrabValid(cachedRightHandGrabber))
            {
                // if not null, an object is being held
                return(cachedRightHandGrabber.GetGrabbedObject() != null);
            }

            // either caches aren't set up, or hands are no longer being tracked
            VRTK_InteractGrab[] handGrabbers = handRoot.GetComponentsInChildren <VRTK_InteractGrab>();
            foreach (VRTK_InteractGrab grabber in handGrabbers)
            {
                if (!IsInteractGrabValid(grabber))
                {
                    continue;
                }
                if (grabber.controllerEvents is GestureControllerEvent)
                {
                    GestureControllerEvent gestureController = (GestureControllerEvent)grabber.controllerEvents;
                    if (gestureController.controllerHandId == SDK_BaseGestureLibrary.Hand.Left)
                    {
                        cachedLeftHandGrabber = grabber;
                    }
                    else if (gestureController.controllerHandId == SDK_BaseGestureLibrary.Hand.Right)
                    {
                        cachedRightHandGrabber = grabber;
                    }

                    if (gestureController.controllerHandId == hand)
                    {
                        return(grabber.GetGrabbedObject() != null);
                    }
                }
            }
            // fell through because hand was not found
            return(false);
        }
Пример #5
0
        public virtual bool GetBoolValue(BasicGesture givenGesture, SDK_BaseGestureLibrary.Hand handIndex)
        {
            SDK_BaseGestureLibrary currentLibrary = VRTK.VRTK_SDK_Bridge.GetHandSDK().GetGestureLibrary();

            if (currentLibrary == null)
            {
                // preventing a null exception, but this really should use some error handling
                // since currently it doesn't differentiate between a gesture not happening and a hand not existing
                // does not print a warning because it would flood the log
                return(false);
            }

            switch (givenGesture)
            {
            case BasicGesture.IsThumbBent:
                return(currentLibrary.IsFingerBent(handIndex, SDK_BaseGestureLibrary.Finger.Thumb));

            case BasicGesture.IsIndexFingerBent:
                return(currentLibrary.IsFingerBent(handIndex, SDK_BaseGestureLibrary.Finger.Index));

            case BasicGesture.IsMiddleFingerBent:
                return(currentLibrary.IsFingerBent(handIndex, SDK_BaseGestureLibrary.Finger.Middle));

            case BasicGesture.IsRingFingerBent:
                return(currentLibrary.IsFingerBent(handIndex, SDK_BaseGestureLibrary.Finger.Ring));

            case BasicGesture.IsPinkyFingerBent:
                return(currentLibrary.IsFingerBent(handIndex, SDK_BaseGestureLibrary.Finger.Pinky));

            case BasicGesture.IsHandOpen:
                return(currentLibrary.IsHandOpen(handIndex));

            case BasicGesture.IsHandClosed:
                return(currentLibrary.IsHandClosed(handIndex));

            case BasicGesture.IsHandPinching:
                return(currentLibrary.IsHandPinched(handIndex));

            default:
                return(false);
            }
        }
Пример #6
0
 public override bool IsConditionOccuring(SDK_BaseGestureLibrary.Hand specificHand, AdvancedGesture advancedGestureInfo)
 {
     SDK_BaseGestureLibrary.Hand otherHand = specificHand == SDK_BaseGestureLibrary.Hand.Left ? SDK_BaseGestureLibrary.Hand.Right : SDK_BaseGestureLibrary.Hand.Left;
     return(simultaneousGesture.IsGestureOccuring(otherHand));
 }
Пример #7
0
 public override bool IsConditionOccuring(SDK_BaseGestureLibrary.Hand specificHand, AdvancedGesture advancedGestureInfo)
 {
     return(Time.time >= advancedGestureInfo.gestureStartTime + gestureHoldTime);
 }
Пример #8
0
        public override bool IsConditionOccuring(SDK_BaseGestureLibrary.Hand specificHand, AdvancedGesture advancedGestureInfo)
        {
            SDK_BaseGestureLibrary currentLibrary = VRTK.VRTK_SDK_Bridge.GetHandSDK().GetGestureLibrary();

            if (currentLibrary == null)
            {
                Debug.LogWarning("No gesture library detected for the current Hand SDK");
                return(false);
            }
            Vector3 palmNormal = currentLibrary.GetHandNormal(specificHand);

            if (palmNormal == Vector3.zero)
            {
                // hand tracking lost
                return(false);
            }
            // otherVec is a normal vector that will be compared to the palm vector
            Vector3    otherVec;
            Quaternion rotationToUse = Quaternion.Euler(eulerRotationFromOtherVector);

            if (otherVectorToUse == OtherVector.World)
            {
                switch (otherVectorDirection)
                {
                case VectorType.Forward:
                {
                    otherVec = rotationToUse * Vector3.forward;
                    break;
                }

                case VectorType.Up:
                {
                    otherVec = rotationToUse * Vector3.up;
                    break;
                }

                default:
                {
                    otherVec = rotationToUse * Vector3.up;
                    break;
                }
                }
            }
            else if (otherVectorToUse == OtherVector.Hmd)
            {
                Transform hmd = VRTK_SDK_Bridge.GetHeadset();
                switch (otherVectorDirection)
                {
                case VectorType.Forward:
                {
                    otherVec = hmd.TransformDirection(rotationToUse * Vector3.forward);
                    break;
                }

                case VectorType.Up:
                {
                    otherVec = hmd.TransformDirection(rotationToUse * Vector3.up);
                    break;
                }

                default:
                {
                    otherVec = hmd.TransformDirection(rotationToUse * Vector3.up);
                    break;
                }
                }
            }
            else
            {
                // for whatever reason, otherVec is undefined. return false
                return(false);
            }

            float dotProduct = Vector3.Dot(otherVec, palmNormal);

            // close to 1 -> similar direction
            if (dotProduct >= 1 - tolerance)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #9
0
 /// <summary>
 /// Returns true if the condition is occuring and false otherwise, except in the base version which will always return false.
 /// This method is not marked as abstract because Unity cannot serialize classes that have abstract base classes. New Advanced Gesture Conditions
 /// should implement this method.
 /// </summary>
 public virtual bool IsConditionOccuring(SDK_BaseGestureLibrary.Hand specificHand, AdvancedGesture advancedGestureInfo)
 {
     return(false);
 }
Пример #10
0
 public GestureEventArgs(GameObject gameObject, string name, SDK_BaseGestureLibrary.Hand hand)
 {
     gestureObject = gameObject;
     gestureName   = name;
     gestureHand   = hand;
 }
        public override bool IsGestureOccuring(SDK_BaseGestureLibrary.Hand specificHand)
        {
            // if not detected, it cannot be gesturing
            if (VRTK_SDK_Bridge.GetHandSDK().GetGestureLibrary() != null && !VRTK_SDK_Bridge.GetHandSDK().GetGestureLibrary().IsHandDetected(specificHand))
            {
                return(false);
            }

            // OpenMG has a habit of claiming gestures are occuring at the start of the scene before hands are even detected.
            // this delay ensures that no gesture fire until the system is fully started
            if (Time.time < startupDelayTime)
            {
                return(false);
            }

            // If this is not the specified hand, then the gesture cannot be occuring
            if (advancedGestureStateList[currentGestureStateIndex].coreGesture.handSpecific &&
                advancedGestureStateList[currentGestureStateIndex].coreGesture.specificHand != specificHand)
            {
                return(false);
            }

            if (!allowedWhileHoldingObjects)
            {
                if (IsHoldingObject(SDK_BaseGestureLibrary.Hand.Left) || IsHoldingObject(SDK_BaseGestureLibrary.Hand.Right))
                {
                    return(false);
                }
            }

            bool isCooldownActive = Time.time <= (gestureCooldownStartTime + gestureCooldown);

            // Condition for cooldown has not been met
            if (!isCooldownActive)
            {
                cooldownHasStarted = false;
            }

            // Check core gesture first
            bool isCurrentStateOccuring = advancedGestureStateList[currentGestureStateIndex].coreGesture.IsGestureOccuring(specificHand);

            // If the core gesture is occuring, then start checking the rest of the avanced gesture states
            if (isCurrentStateOccuring)
            {
                if (!gestureHasStarted)
                {
                    gestureHasStarted = true;
                    gestureStartTime  = Time.time;
                }

                // Check every Advanced Gesture Condition for the current Gesture State
                foreach (AdvancedGestureCondition advCondition in advancedGestureStateList[currentGestureStateIndex].AdvancedGestureConditionList)
                {
                    isCurrentStateOccuring = isCurrentStateOccuring && advCondition.IsConditionOccuring(specificHand, this);
                }

                // Core gesture and all advanced Gesture States have been satisifed
                if (isCurrentStateOccuring && advancedGestureStateList.Count == currentGestureStateIndex + 1)
                {
                    // Gesture hasn't triggered the cool down yet, after this frame, that will change
                    if (!isCooldownActive && !cooldownHasStarted)
                    {
                        gestureCooldownStartTime = Time.time;
                        cooldownHasStarted       = true;

                        return(true);
                    }
                    // Gesture is in cooldown, but the user hasn't released the first occurrence of the gesture
                    else if (gestureStartTime <= gestureCooldownStartTime)
                    {
                        return(true);
                    }
                    // Gesture is in cooldown, so the gesture cannot occur
                    else
                    {
                        return(false);
                    }
                }
                // Core gesture has occured, but not every Gesture State has occured yet
                else if (isCurrentStateOccuring)
                {
                    currentGestureStateIndex++;
                    prevLeftPalmPosition  = GetLeftHandPosition();
                    prevRightPalmPosition = GetRightHandPosition();
                }
                else
                {
                    if (advancedGestureStateList[currentGestureStateIndex].holdTime != 0 && advancedGestureStateList[currentGestureStateIndex].holdTime + gestureStartTime <= Time.time)
                    {
                        ResetGestureChain();
                    }

                    return(false);
                }
            }
            // Core gesture is not occuring
            else
            {
                gestureHasStarted = false;

                return(false);
            }

            // The advanced gesture is not occuring
            return(false);
        }