public override ScoredHandPose CalculateBestPose(HandPose userPose, float?scoreWeight = null, SnapDirection direction = SnapDirection.Any, float scale = 1f) { SnapPoint under = null; SnapPoint over = null; float t = 0f; (under, over, t) = FindRange(scale); ScoredHandPose?result = null; if (t >= 0f) { result = ScoredHandPose.Lerp( under.CalculateBestPose(userPose, scoreWeight, direction), over.CalculateBestPose(userPose, scoreWeight, direction), t); } if (!result.HasValue) { Debug.LogError("Invalid range"); return(points[0].CalculateBestPose(userPose, scoreWeight, direction)); } return(result.Value); }
public ObjectSnappingAddress(Snappable snappable, BaseSnapPoint point, ScoredHandPose pose) { this.snappable = snappable; this.point = point; this.pose = pose; this.originalPose = snappable.transform.GetPose(); }
/// <summary> /// Find the Snap Point on this Snappabe with the best score to the given hand pose. /// </summary> /// <param name="userPose">The hand pose to be compared with this snappable.</param> /// <param name="bestHandPose">The most similar Hand Pose that snaps to the object, with its score.</param> /// <returns>The SnapPoint that is closer to the hand</returns> public BaseSnapPoint FindBestSnapPose(HandPose userPose, out ScoredHandPose bestHandPose) { BaseSnapPoint bestSnap = null; bestHandPose = ScoredHandPose.Null(); foreach (var snapPose in this.snapPoints) { ScoredHandPose pose = snapPose.CalculateBestPose(userPose); if (pose.Score > bestHandPose.Score) { bestSnap = snapPose; bestHandPose = pose; } } return(bestSnap); }
/// <summary> /// From IGrabNotifier. Called every frame as the user approaches a grabbable while /// performing the grabbing pose. /// Depending on how closed the grab-gesture is, the hand is interpolated more from /// the user-data to the snap-pose data, generating an "approach" animation directly /// controlled by the gesture. /// </summary> /// <param name="grabbable">The object that is intended to be grabbed.</param> /// <param name="amount">How much the user is performing the grabbing pose (normalised)</param> private void GrabAttemp(GameObject grabbable, float amount) { var ghostPose = SnapForGrabbable(grabbable); if (ghostPose.HasValue) { _grabSnap = ghostPose.Value.Item1; _grabPose = ghostPose.Value.Item2; _offsetOverrideFactor = _bonesOverrideFactor = amount; } else { _grabSnap = null; _offsetOverrideFactor = _bonesOverrideFactor = 0f; } }
/// <summary> /// From IGrabNotifier, called when the hand starts grabbing and object. /// Finds the best snap point and overrides the hand to it. /// </summary> /// <param name="grabbable">The grabbed object.</param> private void GrabStarted(GameObject grabbable) { var ghostPose = SnapForGrabbable(grabbable); if (ghostPose.HasValue) { _grabSnap = ghostPose.Value.Item1; _grabPose = ghostPose.Value.Item2; _offsetOverrideFactor = _bonesOverrideFactor = 1f; this.puppet.LerpGripOffset(_grabPose.Pose, _offsetOverrideFactor, _grabSnap.RelativeTo); _trackOffset = this.puppet.TrackedGripOffset; _grabStartTime = Time.timeSinceLevelLoad; _isGrabbing = true; } }
/// <summary> /// Interpolate between two ScoredHandPose. Both ScoredHandPoses must have the same direction. /// This method does not only moves the hands, but also adjusts the score linearly. /// </summary> /// <param name="from">The base ScoredHandPose to interpolate from.</param> /// <param name="to">The target ScoredHandPose to interpolate to.</param> /// <param name="t">The interpolation factor, 0 for the base, 1 for the target value.</param> /// <returns>A ScoredHandPose between base and target, null if they are not interpolable.</returns> public static ScoredHandPose?Lerp(ScoredHandPose from, ScoredHandPose to, float t) { if (from.Direction != to.Direction) { UnityEngine.Debug.LogError("ScoredHandPose must have same direction for interpolation"); return(null); } float score = UnityEngine.Mathf.Lerp(from.Score, to.Score, t); HandPose?pose = HandPose.Lerp(from.Pose, to.Pose, t); if (!pose.HasValue) { UnityEngine.Debug.LogError("ScoredHandPose interpolation error"); return(null); } return(new ScoredHandPose(pose.Value, score, from.Direction)); }
/// <summary> /// Assings a new valid target position/rotation for the hand in the current snapping pose. /// </summary> private void SlidePose() { HandPose handPose = this.puppet.TrackedPose(_grabSnap.RelativeTo); _grabPose = _grabSnap.CalculateBestPose(handPose, null, _grabPose.Direction); }
/// <summary> /// Check if the given ScoredHandPose is valid. /// </summary> /// <param name="pose">The ScoredHandPose to check.</param> /// <returns>True for an invalid pose.</returns> public static bool IsNull(ScoredHandPose pose) { return(pose.Score == -1f); }