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);
        }
예제 #2
0
 public ObjectSnappingAddress(Snappable snappable, BaseSnapPoint point, ScoredHandPose pose)
 {
     this.snappable    = snappable;
     this.point        = point;
     this.pose         = pose;
     this.originalPose = snappable.transform.GetPose();
 }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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;
            }
        }
예제 #5
0
        /// <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;
            }
        }
예제 #6
0
        /// <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));
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
 /// <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);
 }