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 }); } } }
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 }); } } }
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(); }
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(); }