public void FixedUpdateClassifierHandState() { using (new ProfilerSample("Update Classifier Hand State")) { var hand = interactionHand.leapHand; if (interactionHand.isTracked) { // Ensure that all scale dependent variables are properly set. _scaledGrabParams.FINGERTIP_RADIUS = _defaultGrabParams.FINGERTIP_RADIUS * interactionHand.manager.SimulationScale; _scaledGrabParams.THUMBTIP_RADIUS = _defaultGrabParams.THUMBTIP_RADIUS * interactionHand.manager.SimulationScale; _scaledGrabParams.MAXIMUM_DISTANCE_FROM_HAND = _defaultGrabParams.MAXIMUM_DISTANCE_FROM_HAND * interactionHand.manager.SimulationScale; // Ensure layer mask is up-to-date. _scaledGrabParams.LAYER_MASK = interactionHand.manager.GetInteractionLayerMask(); for (int i = 0; i < hand.Fingers.Count; i++) { _fingerTipPositions[i] = hand.Fingers[i].TipPosition.ToVector3(); } GrabClassifierHeuristics.UpdateAllProbeColliders(_fingerTipPositions, ref _collidingCandidates, ref _numberOfColliders, _scaledGrabParams); } } }
public void UpdateBehaviour(IInteractionBehaviour behaviour, Hand _hand) { using (new ProfilerSample("Update Individual Classifier", behaviour.gameObject)) { GrabClassifierHeuristics.GrabClassifier classifier; Dictionary <IInteractionBehaviour, GrabClassifierHeuristics.GrabClassifier> classifiers = (_hand.IsLeft ? leftGrabClassifiers : rightGrabClassifiers); if (!classifiers.TryGetValue(behaviour, out classifier)) { classifier = new GrabClassifierHeuristics.GrabClassifier(behaviour.gameObject); classifiers.Add(behaviour, classifier); } //Do the actual grab classification logic fillClassifier(_hand, ref classifier); GrabClassifierHeuristics.UpdateClassifier(classifier, collidingCandidates, numberOfColliders, scaledGrabParams); if (classifier.isGrabbing != classifier.prevGrabbing) { if (classifier.isGrabbing) { if (!_manager.TwoHandedGrasping) { _manager.ReleaseObject(behaviour); } _manager.GraspWithHand(_hand, behaviour); } else if (behaviour.IsBeingGraspedByHand(_hand.Id)) { _manager.ReleaseHand(_hand.Id); classifier.coolDownProgress = 0f; } } classifier.prevGrabbing = classifier.isGrabbing; } }
public void FixedUpdateClassifierHandState(Transform headTransform = null) { using (new ProfilerSample("Update Classifier Hand State")) { var hand = interactionHand.leapHand; if (interactionHand.isTracked) { // Ensure that all scale dependent variables are properly set. _scaledGrabParams.FINGERTIP_RADIUS = _defaultGrabParams.FINGERTIP_RADIUS * interactionHand.manager.SimulationScale; _scaledGrabParams.THUMBTIP_RADIUS = _defaultGrabParams.THUMBTIP_RADIUS * interactionHand.manager.SimulationScale; _scaledGrabParams.MAXIMUM_DISTANCE_FROM_HAND = _defaultGrabParams.MAXIMUM_DISTANCE_FROM_HAND * interactionHand.manager.SimulationScale; // Ensure layer mask is up-to-date. _scaledGrabParams.LAYER_MASK = interactionHand.manager.GetInteractionLayerMask(); /*if (headTransform != null) { * //SERIOUS HACKS: Have the collider for the grab classifier stretch along the camera's projective axis * //This will make it easier for users to grab far away objects (while being uncertain of their depth) * for (int i = 0; i < hand.Fingers.Count; i++) { * Vector3 fingerTipPosition = hand.Fingers[i].TipPosition.ToVector3(); * Vector3 stretchDirection = (fingerTipPosition - headTransform.position) * 0.1f; * _fingerTipPositions[i] = fingerTipPosition + stretchDirection; * _fingerKnucklePositions[i] = fingerTipPosition - stretchDirection; * } * } else {*/ for (int i = 0; i < hand.Fingers.Count; i++) { _fingerTipPositions[i] = hand.Fingers[i].TipPosition.ToVector3(); _fingerKnucklePositions[i] = hand.Fingers[i].Bone(Bone.BoneType.TYPE_METACARPAL).NextJoint.ToVector3(); } // } GrabClassifierHeuristics.UpdateAllProbeColliders(_fingerTipPositions, _fingerKnucklePositions, ref _collidingCandidates, ref _numberOfColliders, _scaledGrabParams); } } }
/// <summary> /// Returns true if the behaviour reflects the state-change (grasped or released) as specified by /// the graspMode. /// </summary> private bool updateBehaviour(IInteractionBehaviour behaviour, Hand hand, GraspUpdateMode graspMode, bool ignoreTemporal = false) { using (new ProfilerSample("Update Individual Grab Classifier", behaviour.gameObject)) { // Ensure a classifier exists for this Interaction Behaviour. GrabClassifierHeuristics.GrabClassifier classifier; if (!_classifiers.TryGetValue(behaviour, out classifier)) { classifier = new GrabClassifierHeuristics.GrabClassifier(behaviour.gameObject); _classifiers.Add(behaviour, classifier); } // Do the actual grab classification logic. FillClassifier(behaviour, hand, ref classifier); GrabClassifierHeuristics.UpdateClassifier(classifier, _scaledGrabParams, ref _collidingCandidates, ref _numberOfColliders, ignoreTemporal); // Determine whether there was a state change. bool didStateChange = false; if (!classifier.prevThisControllerGrabbing && classifier.isThisControllerGrabbing && graspMode == GraspUpdateMode.BeginGrasp) { didStateChange = true; classifier.prevThisControllerGrabbing = classifier.isThisControllerGrabbing; } else if (classifier.prevThisControllerGrabbing && !classifier.isThisControllerGrabbing && interactionHand.graspedObject == behaviour && graspMode == GraspUpdateMode.ReleaseGrasp) { didStateChange = true; classifier.coolDownProgress = 0f; classifier.prevThisControllerGrabbing = classifier.isThisControllerGrabbing; } return(didStateChange); } }
//Classifier bookkeeping public void UpdateHeuristicClassifier(Hand hand) { if (hand != null) { //Ensure that all scale dependent variables are properly set scaledGrabParams.FINGERTIP_RADIUS = defaultGrabParams.FINGERTIP_RADIUS * _manager.SimulationScale; scaledGrabParams.THUMBTIP_RADIUS = defaultGrabParams.THUMBTIP_RADIUS * _manager.SimulationScale; scaledGrabParams.MAXIMUM_DISTANCE_FROM_HAND = defaultGrabParams.MAXIMUM_DISTANCE_FROM_HAND * _manager.SimulationScale; //Ensure that the temporally variant variables are updated //scaledGrabParams.LAYER_MASK = 1<<_manager.InteractionLayer; for (int i = 0; i < hand.Fingers.Count; i++) { fingerTipPositions[i] = hand.Fingers[i].TipPosition.ToVector3(); } using (new ProfilerSample("Update All Grab Classifiers", _manager)) { GrabClassifierHeuristics.UpdateAllProbeColliders(fingerTipPositions, ref collidingCandidates, ref numberOfColliders, scaledGrabParams); //First check if already holding an object and only process that one var graspedBehaviours = _manager.GraspedObjects; for (int i = 0; i < graspedBehaviours.Count; i++) { if (graspedBehaviours[i].IsBeingGraspedByHand(hand.Id)) { UpdateBehaviour(graspedBehaviours[i], hand); return; } } //If not, process all objects var activeBehaviours = _manager._activityManager.ActiveBehaviours; for (int i = 0; i < activeBehaviours.Count; i++) { UpdateBehaviour(activeBehaviours[i], hand); } } } }