예제 #1
0
 private void checkInteractionHandStatus(InteractionHand intHand,
                                         List <ControllerStatusMessage> messages)
 {
     if (!Application.isPlaying)
     {
         // Check for a LeapProvider in the scene somewhere.
         if (_provider == null)
         {
             _provider = FindObjectOfType <LeapProvider>();
         }
         if (_provider == null)
         {
             messages.Add(new ControllerStatusMessage()
             {
                 message = "No LeapProvider",
                 tooltip = "No LeapProvider object was found in your scene. "
                           + "InteractionHands require a LeapProvider to function; consider "
                           + "dragging in the LeapHeadMountedRig prefab or creating and "
                           + "configuring a LeapServiceProvider.",
                 color = Colors.Warning
             });
         }
     }
 }
예제 #2
0
        private void checkInteractionHandStatus(InteractionHand intHand,
                                                List <ControllerStatusMessage> messages)
        {
            if (!Application.isPlaying)
            {
                // Check for valid InteractionHand data state.
                if (intHand.handDataMode == HandDataMode.Custom)
                {
                    messages.Add(new ControllerStatusMessage()
                    {
                        message = "HandDataMode: Custom",
                        tooltip = "This interaction hand has its data mode set to Custom. "
                                  + "A custom script will be required to ensure hand data gets to "
                                  + "the interaction hand properly. Upon pressing play, an error will "
                                  + "be raised by the hand itself if it is misconfigured.",
                        color = Colors.Caution
                    });
                }
                else
                {
                    // Check for a LeapProvider in the scene somewhere.
                    if (_provider == null)
                    {
                        _provider = FindObjectOfType <LeapProvider>();
                    }
                    if (_provider == null)
                    {
                        messages.Add(new ControllerStatusMessage()
                        {
                            message = "No LeapProvider",
                            tooltip = "No LeapProvider object was found in your scene. "
                                      + "InteractionHands require a LeapProvider to function; consider "
                                      + "dragging in the LeapHeadMountedRig prefab or creating and "
                                      + "configuring a LeapServiceProvider.",
                            color = Colors.Warning
                        });
                    }
                }
            }

            // Check if the player has multiple left hands or multiple right hands.
            if (intHand.handDataMode != HandDataMode.Custom)
            {
                int index = target.interactionControllers.Query().IndexOf(intHand);

                if (target.interactionControllers.Query().
                    Take(index).
                    OfType <InteractionHand>().
                    Where(h => h.handDataMode == intHand.handDataMode).
                    Where(h => h.leapProvider == intHand.leapProvider).
                    Any())
                {
                    messages.Add(new ControllerStatusMessage()
                    {
                        message = "Duplicate Hand",
                        tooltip = "You already have a hand with this data mode in your scene. "
                                  + "You should remove one of the duplicates.",
                        color = Colors.Problem
                    });
                }
            }
        }
예제 #3
0
        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();
        }
예제 #4
0
        protected virtual void updateInteractionStateChanges(Frame frame)
        {
            var hands = frame.Hands;

            //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];

                //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;
                    for (var it = _idToInteractionHand.GetEnumerator(); it.MoveNext();)
                    {
                        var pair = it.Current;
                        //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;
                        }
                    }
                    else
                    {
                        //Otherwise just create a new one
                        interactionHand = new InteractionHand(hand);
                        _idToInteractionHand[hand.Id] = interactionHand;
                    }
                }

                interactionHand.UpdateHand(hand);
                if (_graspingEnabled)
                {
                    _grabClassifier.UpdateHeuristicClassifier(interactionHand.hand);
                }
            }

            //Loop through all ieHands to check for timeouts and loss of tracking
            for (var it = _idToInteractionHand.GetEnumerator(); it.MoveNext();)
            {
                var pair   = it.Current;
                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();
        }