Beispiel #1
0
    // distance to hand in world scale
    private float HandDistance(InteractionHand hand)
    {
        if (!hand.isTracked)
        {
            return(float.PositiveInfinity);
        }

        var lossyScale = transform.lossyScale.x;

        switch (objectType)
        {
        case ObjectType.Point:
            return(transform.position.sqrDist(HandPointerPos(hand)));

        case ObjectType.Line:
            return(DistToLineSegment(HandPointerPos(hand), lineRenderer));

        case ObjectType.Circle:
            return(ClosestPointOnCircleToHand(hand).sqrDist(HandPointerPos(hand)));

        case ObjectType.Rect:
            Vector3 pointerInObjSpace;
            pointerInObjSpace = (transform.InverseTransformPoint(HandPointerPos(hand)) - buttonPivot) * lossyScale;
            Vector3 worldButtonSize = buttonSize * lossyScale;

            if (Mathf.Abs(pointerInObjSpace.x) < worldButtonSize.x / 2 &&
                Mathf.Abs(pointerInObjSpace.y) < worldButtonSize.y / 2 &&
                Mathf.Abs(pointerInObjSpace.z) < hoverDistance)
            {
                return(pointerInObjSpace.z * pointerInObjSpace.z);
            }
            else
            {
                return(float.PositiveInfinity);
            }
        }

        return(float.PositiveInfinity);
    }
        private void Awake()
        {
            userRig            = GetComponentInParent <UserRig>();
            platformManager    = GetComponent <PlatformManager>();
            interactionManager = Leap.Unity.Interaction.InteractionManager.instance;
            if (interactionManager != null)
            {
                controllerManager = interactionManager.GetComponent <PlatformControllerManager>();
            }

            if (interactionManager)
            {
                foreach (InteractionController controller in interactionManager.interactionControllers)
                {
                    if (controller is InteractionHand)
                    {
                        InteractionHand hand = (InteractionHand)controller;

                        if (hand.isLeft)
                        {
                            leftInteractionHand = hand;
                        }
                        else
                        {
                            rightInteractionHand = hand;
                        }

                        hand.leapProvider = defaultProvider;
                    }
                }
            }

            SkeletalControllerHand[] hands = transform.parent.GetComponentsInChildren <SkeletalControllerHand>(true);
            leftSkeletalControllerHand  = hands.First(item => item.IsLeft);
            rightSkeletalControllerHand = hands.First(item => !item.IsLeft);
        }
Beispiel #3
0
        protected override void WhileGestureActive(Hand hand)
        {
            base.WhileGestureActive(hand);

            Chirality chirality = Chirality.Right;
            //choose opposite hand for iHand;
            InteractionHand iHand = leapHandDataLogger.ins.currHands.rIhand;

            if (hand.IsLeft)
            {
                iHand     = leapHandDataLogger.ins.currHands.rIhand;
                chirality = Chirality.Left;
            }

            handColourManager.setHandColorMode(chirality, handColourManager.handModes.snappingPalm);

            if (iHand.isGraspingObject && iHand.graspedObject.gameObject.GetComponent <straightEdgeBehave>() == myStraightEdge)
            {
                Debug.Log("Trying to snap to floor");
                //iHand.ReleaseObject(myStraightEdge.GetComponent<InteractionBehaviour>());

                myStraightEdge.snapToFloor();
            }
        }
Beispiel #4
0
    private Tuple <InteractionHand, IPinchable> DetermineBestPinchable(IEnumerable <InteractionHand> hands)
    {
        IPinchable      best        = null;
        InteractionHand bestHand    = null;
        float           minDistance = float.MaxValue;

        foreach (var hand in hands)
        {
            var pos = hand.leapHand.GetPinchPosition();

            foreach (var pinchComponent in pinchables)
            {
                pinchComponent.CheckPinchStart(hand, out bool isValid, out float distance);
                if (isValid && distance < minDistance)
                {
                    minDistance = distance;
                    best        = pinchComponent;
                    bestHand    = hand;
                }
            }
        }

        return(Tuple.Create <InteractionHand, IPinchable>(bestHand, best));
    }
Beispiel #5
0
    // How closed is the pinch : fully open 0 .. 1 fully closed
    public static float pinchCloseness(this InteractionHand hand, float maxWidth = 0.06f)
    {
        float activateDistance = 0.02f;         //HandUIManager.pinchRight.pinchActivateDistance;

        return(Mathf.InverseLerp(activateDistance * activateDistance, maxWidth * maxWidth, hand.pinchSqrWidth()));
    }
Beispiel #6
0
 private void Start()
 {
     hand = HandUIManager.GetHand(whichHand);
     Hide();
 }
Beispiel #7
0
 public Vector3 ClosestPointOnCircleToHand(InteractionHand hand)
 {
     return(closestPointOnCircle(transform.position, circleRadius * transform.lossyScale.x, HandPointerPos(hand)));
 }
Beispiel #8
0
 public static float pinchSqrWidth(this InteractionHand hand, float maxWidth = 0.06f)
 {
     return(!hand.isTracked ? maxWidth : hand.indexPos().sqrDist(hand.leapHand.GetThumb().TipPosition.ToVector3()));
 }
 private Vector3 GetObjectSpaceGrabPoint(InteractionHand hand)
 {
     return(this.transform.InverseTransformVector(_intObj.GetGraspPoint(hand) - this.transform.position));
 }
Beispiel #10
0
    private void HandleActiveMode()
    {
        bool hasHoverHand = false;

        foreach (var controller in leap.hoveringControllers)
        {
            if (controller.isGraspingObject)
            {
                continue;
            }
            hasHoverHand |= IsHandInActivationPose(controller.intHand);
        }
        if (hasHoverHand)
        {
            hoverTime += Time.deltaTime;
        }
        else
        {
            hoverTime = 0f;
        }

        if (graspedPoseHandler.InteractingHands == 0)
        {
            inactiveTime += Time.deltaTime;
            if (inactiveTime > InactiveTimeout)
            {
                ChangeMode(ManipulationMode.Hover);
                graspedPoseHandler.SetEnabled(false);
            }
            else
            {
                ChangeMode(ManipulationMode.Active);
            }
        }
        else if (graspedPoseHandler.InteractingHands == 1)
        {
            inactiveTime = 0f;
            // Don't allow going from Translating into anchoring
            if (Mode == ManipulationMode.Translating)
            {
                hasHoverHand = false;
            }
            // Have slight delay on anchoring start as not to trigger it on rotation/scaling
            if (hasHoverHand && hoverTime > 0.2f)
            {
                anchorHand           = leap.graspingController.intHand;
                anchoringStart       = anchorHand.isGraspingObject ? anchorHand.GetGraspPoint() : anchorHand.position;
                anchoringStopTimer   = 0f;
                lineRenderer.enabled = true;
                ChangeMode(ManipulationMode.Anchoring);
                Player.Instance?.ShowAnchoringTarget();
                graspedPoseHandler.SetEnabled(false);
            }
            else
            {
                ChangeMode(ManipulationMode.Translating);
            }
        }
        else if (graspedPoseHandler.InteractingHands == 2)
        {
            inactiveTime = 0f;
            if (proxyNode.Radius < MINIMIZE_THRESHOLD)
            {
                graspedPoseHandler.SetEnabled(false);
                proxyNode.Minimize();
                ChangeMode(ManipulationMode.Minimized);
            }
            else
            {
                ChangeMode(ManipulationMode.ScalingAndRotating);
            }
        }
    }
Beispiel #11
0
 public static Chirality chirality(this InteractionHand hand)
 {
     return(hand.isLeft ? Chirality.Left : Chirality.Right);
 }
Beispiel #12
0
 public static Vector3 stablePinchPos(this InteractionHand hand)
 {
     return(HandUIManager.GetPinchGesture(hand.chirality()).stablePinch.position);
 }
Beispiel #13
0
 public static InteractionHand otherHand(this InteractionHand hand)
 {
     return(hand.isLeft ? HandUIManager.handRight : HandUIManager.handLeft);
 }
Beispiel #14
0
 public static Vector3 pinchPos(this InteractionHand hand)
 {
     return((hand.indexPos() + hand.thumbPos()) / 2);
 }
Beispiel #15
0
 public static bool isPinched(this InteractionHand hand)
 {
     return(HandUIManager.GetPinchGesture(hand.chirality()).isActive&& hand.isTracked);
 }
Beispiel #16
0
    private void Update()
    {
        closestHand = null;

        //find closest hand
        dL = HandDistance(HandUIManager.handLeft);
        dR = HandDistance(HandUIManager.handRight);

        if (dL <= dR)
        {
            closestHand = HandUIManager.handLeft;
        }
        else if (dR < dL)
        {
            closestHand = HandUIManager.handRight;
        }

        closestHandDist = Mathf.Min(dL, dR);

        dist        = closestHandDist;
        handIsClose = dist < hoverDistance * hoverDistance;

        if (handIsClose && !hovered && canBeHovered && !isClosestPinching())
        {
            BeginHover();
        }

        if (!handIsClose && !pinched && hovered)
        {
            EndHover();
        }

        reset = false;

        if (hovered && !pinched && isClosestPinching() && !isClosestHandHolding())
        {
            BeginPinch();
        }

        if (pinched && !isClosestPinching())
        {
            EndPinch();
        }

        if (!bothHandsPinched && pinched && closestHand.otherHand().isPinched() && isHandClose(closestHand.otherHand()))
        {
            // start double pinch
            bothHandsPinched = true;

            onGrabDistanceBetweenHands = Vector3.Distance(HandUIManager.pinchLeft.pose.position,
                                                          HandUIManager.pinchRight.pose.position);
            onGrabScale       = transform.localScale;
            onGrabEulerAngles = transform.eulerAngles;

            var midpoint = (HandUIManager.pinchLeft.pose.position + HandUIManager.pinchLeft.pose.position) / 2;
            prevMidpointPos = midpoint;
            deltaAngle      = 0;
            reset           = true;

            onGrabMidpointOffset = midpoint - transform.position;
            onGrabRightToLeft    = HandUIManager.pinchLeft.pose.position - HandUIManager.pinchRight.pose.position;
            onGrabRightToLeft.y  = 0;
        }

        if (bothHandsPinched && !(closestHand.isPinched() && closestHand.otherHand().isPinched()))
        {
            //end double pinch
            bothHandsPinched     = false;
            onGrabMidpointOffset = HandPointerPos(closestHand) - transform.position;
        }

        if (pinched)
        {
            var currentPinchPos = HandPointerPos(closestHand);
            currentDeltaPinchPos     = currentPinchPos - prevPinchPos;
            distanceFromInitPinchPos = currentPinchPos - initPositionWhenPinched;
            prevPinchPos             = currentPinchPos;
        }

        if (pinched && moveWithPinch)
        {
            if (twoHandedTRS && bothHandsPinched)
            {
                // TRS with 2 hands
                var midpoint = (HandUIManager.pinchLeft.pose.position + HandUIManager.pinchLeft.pose.position) / 2;

                var currentDistance = Vector3.Distance(HandUIManager.pinchLeft.pose.position,
                                                       HandUIManager.pinchRight.pose.position);
                var currentRightToLeft = HandUIManager.pinchLeft.pose.position - HandUIManager.pinchRight.pose.position;
                currentRightToLeft.y = 0;

                var angle = Vector3.SignedAngle(currentRightToLeft, onGrabRightToLeft, Vector3.up);
                if (!reset)
                {
                    deltaAngle = prevAngle - angle;
                }
                else
                {
                    reset = false;
                }

                prevAngle            = angle;
                onGrabMidpointOffset = Quaternion.Euler(0, deltaAngle, 0) * onGrabMidpointOffset;
                transform.Rotate(deltaAngle * Vector3.up);

                transform.position   = midpoint - onGrabMidpointOffset * currentDistance / onGrabDistanceBetweenHands;
                transform.localScale = onGrabScale * currentDistance / onGrabDistanceBetweenHands;
            }
            else
            {
                // move with one hand
                transform.position = HandPointerPos(closestHand) - onGrabMidpointOffset;
            }
        }
    }
    protected virtual INTERACTION_HAND_RESULT getHandResults(InteractionHand hand) {
      if (!_graspingEnabled) {
        INTERACTION_HAND_RESULT result = new INTERACTION_HAND_RESULT();
        result.classification = ManipulatorMode.Contact;
        result.handFlags = HandResultFlags.ManipulatorMode;
        result.instanceHandle = new INTERACTION_SHAPE_INSTANCE_HANDLE();
        return result;
      }

      INTERACTION_HAND_RESULT handResult;
      InteractionC.GetHandResult(ref _scene,
                                     (uint)hand.hand.Id,
                                 out handResult);
      return handResult;
    }
Beispiel #18
0
 private bool ShakaIsShown(InteractionHand hand)
 {
     return(hand.isTracked && hand.leapHand.GetThumb().IsExtended&& hand.leapHand.GetPinky().IsExtended&&
            !hand.leapHand.GetIndex().IsExtended&& !hand.leapHand.GetMiddle().IsExtended&&
            !hand.leapHand.GetRing().IsExtended);
 }
Beispiel #19
0
 private void GrabSphereGraspedEnd()
 {
     grabHand = null;
     grabSphereMaterial.DOColor(GrabSphereDefaultColor, 0.1f);
 }
Beispiel #20
0
    private void Awake()
    {
        uiColorMode   = _uiColorMode;
        whitePoint    = _whitePoint;
        colorGradient = _colorGradient;

        head = Hands.Provider.transform;

        var pinchGestures = FindObjectsOfType <PinchGesture>();

        if (pinchGestures.Length > 1)
        {
            foreach (var item in pinchGestures)
            {
                if (item.whichHand == Chirality.Left)
                {
                    pinchLeft = item;
                }
                else if (item.whichHand == Chirality.Right)
                {
                    pinchRight = item;
                }
                else
                {
                    Warn("Both left and right PinchGestures are required in the scene", this);
                }
            }
        }

        var interactionHands = FindObjectsOfType <InteractionHand>();

        if (interactionHands.Length > 1)
        {
            foreach (var item in interactionHands)
            {
                if (item.isLeft)
                {
                    handLeft = item;
                }
                else
                {
                    handRight = item;
                }
            }
        }
        else
        {
            Warn("Both left and right InteractionHands are required in the scene", this);
        }

        var raycasts = FindObjectsOfType <HandRaycast>();

        if (raycasts.Length > 1)
        {
            foreach (var item in raycasts)
            {
                if (item.whichHand == Chirality.Left)
                {
                    rayLeft = item;
                }
                else if (item.whichHand == Chirality.Right)
                {
                    rayRight = item;
                }
                else
                {
                    Warn("Couldn't find both left and right HandRaycasts in the scene", this);
                }
            }
        }

        prevPosR = handRight.leapHand.GetIndex().TipPosition.ToVector3();
        prevPosL = handLeft.leapHand.GetIndex().TipPosition.ToVector3();

        prevHeadRot = head.rotation;
    }
        /// <summary>
        /// Call this at the start of an Interaction engine test with the name of a stage
        /// object and the name of a rig object to load those objects and fill utility
        /// parameters such as manager, leftHand, box0, etc. for testing.
        /// </summary>
        protected void InitTest(string rigObjName, string stageObjName)
        {
            // Load test rig objects.
            base.InitTest(rigObjName);
            rigObj    = testObj;
            recording = rigObj.GetComponentInChildren <PlayableDirector>();
            provider  = rigObj.GetComponentInChildren <LeapProvider>();
            manager   = rigObj.GetComponentInChildren <InteractionManager>();

            foreach (var controller in manager.interactionControllers)
            {
                if (controller.intHand != null && controller.isLeft)
                {
                    leftHand = controller.intHand;
                    continue;
                }
                if (controller.intHand != null && !controller.isLeft)
                {
                    rightHand = controller.intHand;
                    continue;
                }

                var vrController = controller as InteractionXRController;
                if (vrController != null && vrController.isLeft)
                {
                    leftVRController = vrController;
                    continue;
                }
                if (vrController != null && !vrController.isLeft)
                {
                    rightVRController = vrController;
                    continue;
                }
            }

            // Load stage objects.
            stageObj = LoadObject(stageObjName);

            var intObjs = Pool <List <InteractionBehaviour> > .Spawn();

            try {
                stageObj.GetComponentsInChildren <InteractionBehaviour>(true, intObjs);

                // Load "simple box" interaction objects.
                foreach (var simpleBoxObj in intObjs
                         .Query()
                         .Where(o => o.primaryHoverColliders.Count == 1 &&
                                o.primaryHoverColliders[0] is BoxCollider &&
                                !o.ignoreContact &&
                                !o.ignoreGrasping))
                {
                    if (box0 == null)
                    {
                        box0 = simpleBoxObj; continue;
                    }
                    if (box1 == null)
                    {
                        box1 = simpleBoxObj; continue;
                    }
                    if (box2 == null)
                    {
                        box2 = simpleBoxObj; continue;
                    }
                }

                foreach (var interactionButtonObj in intObjs.Query()
                         .Where(o => o is InteractionButton))
                {
                    if (button == null)
                    {
                        button = interactionButtonObj as InteractionButton;
                    }
                }
            }
            finally {
                intObjs.Clear();
                Pool <List <InteractionBehaviour> > .Recycle(intObjs);
            }
        }
        private void updateForHand(Hand hand, out bool areFingertipsOutsideSurface)
        {
            InteractionHand intHand = null;

            if (hand != null && InteractionManager.instance != null)
            {
                intHand = getIntHand(InteractionManager.instance, hand.IsLeft);
            }

            areFingertipsOutsideSurface = true;
            if (hand != null && (intHand == null || !intHand.isGraspingObject))
            {
                for (int i = 0; i < hand.Fingers.Count; i++)
                {
                    int fingerArrayBaseIdx = hand.IsLeft ? 0 : 5;

                    var finger            = hand.Fingers[i];
                    var fingertipPosition = finger.TipPosition.ToVector3();
                    _fingertipPositions[fingerArrayBaseIdx + i] = fingertipPosition;

                    var portalPose = portalObj.transform.ToPose() + new Pose(portalObj.transform.forward * depthOffset);
                    var isFingertipProjectionInRect = false;
                    var sqrDistToRect    = 0f;
                    var clampedFingertip = fingertipPosition
                                           .ClampedToRect(portalPose, portalObj.width, portalObj.height,
                                                          out sqrDistToRect, out isFingertipProjectionInRect);

                    // Check whether we should 'pop' because the user reached too far.
                    var fingertipPlaneSpace = fingertipPosition.GetLocalPlanePosition(portalPose);
                    var fingertipDepth      = fingertipPlaneSpace.z;
                    var popDepth            = 0.02f; // TODO: Turn into param
                    if (fingertipDepth > popDepth)
                    {
                        _popped = true;
                    }

                    // We detect whether all fingertips "leave the portal surface" either sideways or depth-wise
                    // to eventually reset the "popped" state of the portal surface.
                    if (isFingertipProjectionInRect && !(fingertipDepth < depthOffset - thickness))
                    {
                        areFingertipsOutsideSurface = false;
                    }

                    if (!_popped)
                    {
                        var pressStrength = sqrDistToRect.Map(0f, thickness * thickness, 1f, 0f);

                        if (pressStrength > 0f && isFingertipProjectionInRect)
                        {
                            _touchingFingerPositions[fingerArrayBaseIdx + i] = clampedFingertip;
                            _fingerStrengths[fingerArrayBaseIdx + i]         = pressStrength;

                            if (drawInteractionDebug)
                            {
                                //DebugPing.Ping(clampedFingertip, LeapColor.amber, 0.10f);
                            }
                        }
                    }
                }
            }

            if (intHand != null && intHand.isGraspingObject)
            {
                areFingertipsOutsideSurface = false;
            }
        }
    private void updateHands()
    {
        foreach (Hand hand in mostRecentFrame.Hands) {
            InteractionHand matchingHand = _trackingHands.FirstOrDefault(h => h.leapHand.Id == hand.Id);

            if (matchingHand == null) {
                //If the new hand does not have the same ID as any hand we have been tracking
                //See if it matches the handedness of a hand that has been untracked for a little bit of time
                InteractionHand matchingStaleHand = _trackingHands.FirstOrDefault(h => h.timeSinceUpdated > 0.1f && h.leapHand.IsRight == hand.IsRight);
                if (matchingStaleHand != null) {
                    //if it does, the new hand assumes control of the abandonded hand
                    matchingStaleHand.updateInfo(hand);
                } else {
                    //otherwise we create a new hand to be tracked
                    InteractionHand newHand = new InteractionHand();
                    newHand.updateInfo(hand);
                    _trackingHands.Add(newHand);
                }
            } else {
                //We found the match, simply update it
                matchingHand.updateInfo(hand);
            }
        }

        HandModel[] physicsModels = HandControllerUtil.handController.GetAllPhysicsHands();

        //All hands that haven't been updated for too long
        foreach (InteractionHand kHand in _trackingHands.Where(h =>
            h.timeSinceUpdated > handDisapearDelay &&
            h.grabbedObject != null &&
            h.cachedRigidbody != null &&
            h.cachedRigidbody.isKinematic)) {
            kHand.cachedRigidbody.isKinematic = false;
            foreach (HandModel model in physicsModels) {
                Leap.Utils.IgnoreCollisions(kHand.grabbedObject.gameObject, model.gameObject, false);
            }
        }

        //Remove all the stale hands from the set
        _trackingHands.RemoveWhere(h => h.timeSinceUpdated > handDisapearDelay);
    }
Beispiel #24
0
 public static Transform stablePinchTransform(this InteractionHand hand)
 {
     return(HandUIManager.GetPinchGesture(hand.chirality()).stablePinch);
 }
    protected virtual void updateInteractionStateChanges(Frame frame) {
      var hands = frame.Hands;

      INTERACTION_HAND_RESULT handResult = new INTERACTION_HAND_RESULT();

      //First loop through all the hands and get their classifications from the engine
      for (int i = 0; i < hands.Count; i++) {
        Hand hand = hands[i];

        bool handResultForced = false;

        //Get the InteractionHand associated with this hand id
        InteractionHand interactionHand;
        if (!_idToInteractionHand.TryGetValue(hand.Id, out interactionHand)) {

          //First we see if there is an untracked interactionHand that can be re-connected using this one
          InteractionHand untrackedInteractionHand = null;
          foreach (var pair in _idToInteractionHand) {
            //If the old ieHand is untracked, and the handedness matches, we re-connect it
            if (pair.Value.isUntracked && pair.Value.hand.IsLeft == hand.IsLeft) {
              untrackedInteractionHand = pair.Value;
              break;
            }
          }

          if (untrackedInteractionHand != null) {
            //If we found an untrackedIeHand, use it!
            interactionHand = untrackedInteractionHand;
            //Remove the old id from the mapping
            _idToInteractionHand.Remove(untrackedInteractionHand.hand.Id);
            _idToInteractionHand[hand.Id] = interactionHand;

            try {
              //This also dispatched InteractionObject.OnHandRegainedTracking()
              interactionHand.RegainTracking(hand);

              if (interactionHand.graspedObject == null) {
                continue;
              }

              // NotifyHandRegainedTracking() did not throw, continue on to NotifyHandsHoldPhysics().
              dispatchOnHandsHolding(hands, interactionHand.graspedObject, isPhysics: true);
            } catch (Exception e) {
              _activityManager.NotifyMisbehaving(interactionHand.graspedObject);
              Debug.LogException(e);
              continue;
            }

            //Override the existing classification to force the hand to grab the old object
            handResultForced = true;
            handResult.classification = ManipulatorMode.Grasp;
            handResult.handFlags = HandResultFlags.ManipulatorMode;
            handResult.instanceHandle = interactionHand.graspedObject.ShapeInstanceHandle;

            if (_graspingEnabled) {
              InteractionC.OverrideHandResult(ref _scene, (uint)hand.Id, ref handResult);
            }
          } else {
            //Otherwise just create a new one
            interactionHand = new InteractionHand(hand);
            _idToInteractionHand[hand.Id] = interactionHand;
          }
        }

        if (!handResultForced) {
          handResult = getHandResults(interactionHand);
        }

        interactionHand.UpdateHand(hand);

        if (!interactionHand.isUserGrasp) {
          switch (handResult.classification) {
            case ManipulatorMode.Grasp:
              {
                IInteractionBehaviour interactionBehaviour;
                if (_instanceHandleToBehaviour.TryGetValue(handResult.instanceHandle, out interactionBehaviour)) {
                  if (interactionHand.graspedObject == null) {
                    if (!interactionBehaviour.IsBeingGrasped) {
                      _graspedBehaviours.Add(interactionBehaviour);
                    }

                    try {
                      interactionHand.GraspObject(interactionBehaviour, isUserGrasp: false);

                      //the grasp callback might have caused the object to become ungrasped
                      //the component might have also destroyed itself!
                      if (interactionHand.graspedObject == interactionBehaviour && interactionBehaviour != null) {
                        dispatchOnHandsHolding(hands, interactionBehaviour, isPhysics: true);
                      }
                    } catch (Exception e) {
                      _activityManager.NotifyMisbehaving(interactionBehaviour);
                      Debug.LogException(e);
                      continue;
                    }
                  }
                } else {
                  Debug.LogError("Recieved a hand result with an unkown handle " + handResult.instanceHandle.handle);
                }
                break;
              }
            case ManipulatorMode.Contact:
              {
                if (interactionHand.graspedObject != null) {
                  if (interactionHand.graspedObject.GraspingHandCount == 1) {
                    _graspedBehaviours.Remove(interactionHand.graspedObject);
                  }

                  try {
                    interactionHand.ReleaseObject();
                  } catch (Exception e) {
                    _activityManager.NotifyMisbehaving(interactionHand.graspedObject);
                    Debug.LogException(e);
                    continue;
                  }
                }
                break;
              }
            default:
              throw new InvalidOperationException("Unexpected classification " + handResult.classification);
          }
        }
      }

      //Loop through all ieHands to check for timeouts and loss of tracking
      foreach (var pair in _idToInteractionHand) {
        var id = pair.Key;
        var ieHand = pair.Value;

        float handAge = Time.unscaledTime - ieHand.lastTimeUpdated;
        //Check to see if the hand is at least 1 frame old
        //We assume it has become untracked if this is the case
        if (handAge > 0) {
          //If the hand isn't grasping anything, just remove it
          if (ieHand.graspedObject == null) {
            _handIdsToRemove.Add(id);
            continue;
          }

          //If is isn't already marked as untracked, mark it as untracked
          if (!ieHand.isUntracked) {
            try {
              //This also dispatches InteractionObject.OnHandLostTracking()
              ieHand.MarkUntracked();
            } catch (Exception e) {
              _activityManager.NotifyMisbehaving(ieHand.graspedObject);
              Debug.LogException(e);
            }
          }

          //If the age is longer than the timeout, we also remove it from the list
          if (handAge >= ieHand.maxSuspensionTime) {
            _handIdsToRemove.Add(id);

            try {
              if (ieHand.graspedObject.GraspingHandCount == 1) {
                _graspedBehaviours.Remove(ieHand.graspedObject);
              }

              //This also dispatched InteractionObject.OnHandTimeout()
              ieHand.MarkTimeout();
            } catch (Exception e) {
              _activityManager.NotifyMisbehaving(ieHand.graspedObject);
              Debug.LogException(e);
            }
          }
        }
      }

      //Loop through the stale ids and remove them from the map
      for (int i = 0; i < _handIdsToRemove.Count; i++) {
        _idToInteractionHand.Remove(_handIdsToRemove[i]);
      }
      _handIdsToRemove.Clear();
    }
Beispiel #26
0
 public static Vector3 indexPos(this InteractionHand hand)
 {
     return(hand.leapHand.GetIndex().TipPosition.ToVector3());
 }
Beispiel #27
0
 public static Vector3 thumbPos(this InteractionHand hand)
 {
     return(hand.leapHand.GetThumb().TipPosition.ToVector3());
 }
Beispiel #28
0
        /// <summary>
        /// To be called at the start of an Interaction Engine test. Loads the named object
        /// by finding it in the current scene or otherwise by spawning it by prefab name.
        ///
        /// After calling this method, the following fields are set:
        ///
        /// PROVIDERS
        /// - testProvider: The LeapProvider designed for IE unit tests.
        ///
        /// MANAGERS
        /// - manager: The Interaction Manager.
        ///
        /// CONTROLLERS
        /// - leftHand: The left Interaction Hand, if there is one.
        /// - rightHand: The right Interaction Hand, if there is one.
        /// - leftVRController: The left VR controller, if there is one.
        /// - rightVRController: The right VR Controller, if there is one.
        ///
        /// OBJECTS
        /// - box0: An InteractionBehaviour with an attached BoxCollider, if there is one.
        /// - box1: Another InteractionBehaviour with an attached BoxCollider, if it exists.
        /// - box2: Yet another InteractionBehaviour with a BoxCollider, if it exists.
        /// </summary>
        protected override void InitTest(string objectName)
        {
            base.InitTest(objectName);

            testProvider = testObj.GetComponentInChildren <StationaryTestLeapProvider>();

            manager = testObj.GetComponentInChildren <InteractionManager>();

            foreach (var controller in manager.interactionControllers)
            {
                if (controller.intHand != null && controller.isLeft)
                {
                    leftHand = controller.intHand;
                    continue;
                }
                if (controller.intHand != null && !controller.isLeft)
                {
                    rightHand = controller.intHand;
                    continue;
                }

                var vrController = controller as InteractionVRController;
                if (vrController != null && vrController.isLeft)
                {
                    leftVRController = vrController;
                    continue;
                }
                if (vrController != null && !vrController.isLeft)
                {
                    rightVRController = vrController;
                    continue;
                }
            }

            var intObjs = Pool <List <InteractionBehaviour> > .Spawn();

            try {
                testObj.GetComponentsInChildren <InteractionBehaviour>(true, intObjs);

                // Load "simple box" interaction objects.
                foreach (var simpleBoxObj in intObjs.Query().Where(o => o.primaryHoverColliders.Count == 1 &&
                                                                   o.primaryHoverColliders[0] is BoxCollider))
                {
                    if (box0 == null)
                    {
                        box0 = simpleBoxObj; continue;
                    }
                    if (box1 == null)
                    {
                        box1 = simpleBoxObj; continue;
                    }
                    if (box2 == null)
                    {
                        box2 = simpleBoxObj; continue;
                    }
                }
            }
            finally {
                intObjs.Clear();
                Pool <List <InteractionBehaviour> > .Recycle(intObjs);
            }
        }
Beispiel #29
0
 public void BeginPinch(InteractionHand hand)
 {
     tether.enabled = true;
     UpdatePinch(hand);
     OnAnchoringStart?.Invoke(this, null);
 }