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); }
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); }
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); }
/// <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); }
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); } }
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)); }
public override bool IsConditionOccuring(SDK_BaseGestureLibrary.Hand specificHand, AdvancedGesture advancedGestureInfo) { return(Time.time >= advancedGestureInfo.gestureStartTime + gestureHoldTime); }
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); } }
/// <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); }
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); }