コード例 #1
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
 /// <summary>
 /// Release an object without throwing it.
 /// </summary>
 /// <param name="grabbable">Object to release</param>
 public virtual void OffhandGrabbed(Grabbable grabbable)
 {
     if (GrabbedObject == grabbable)
     {
         ReleaseGrabbedObject(Vector3.zero, Vector3.zero);
     }
 }
コード例 #2
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
 /// <summary>
 /// Unsuscribe an object from the list of touched grabbables.
 /// The object will not be a grabbing candidate until it is touched again.
 /// </summary>
 /// <param name="grabbable">The grabbable to be unsuscribed</param>
 public void ForceUntouch(Grabbable grabbable)
 {
     if (_grabCandidates.ContainsKey(grabbable))
     {
         _grabCandidates.Remove(grabbable);
     }
 }
コード例 #3
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
        public void OnTriggerExit(Collider otherCollider)
        {
            Grabbable grabbable = otherCollider.GetComponent <Grabbable>() ?? otherCollider.GetComponentInParent <Grabbable>();

            if (grabbable == null)
            {
                return;
            }

            bool found = _grabCandidates.TryGetValue(grabbable, out int refCount);

            if (!found)
            {
                return;
            }

            if (refCount > 1)
            {
                _grabCandidates[grabbable] = refCount - 1;
            }
            else
            {
                _grabCandidates.Remove(grabbable);

                if (_grabCandidates.Count == 0)
                {
                    _lastGrabCandidate     = grabbable;
                    _timeWithoutCandidates = Time.timeSinceLevelLoad;
                }
            }
        }
コード例 #4
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
 /// <summary>
 /// Unsuscribe all the objects grabbed by all hands.
 /// </summary>
 /// <param name="grabbable"></param>
 public static void ClearAllGrabs(Grabbable grabbable)
 {
     foreach (var grabber in allGrabbers)
     {
         grabber.ForceUntouch(grabbable);
         grabber.ForceRelease(grabbable);
     }
 }
コード例 #5
0
        /// <summary>
        /// Attach a given grabbable to the hand, storing the offset to the hand so it can be kept while holding.
        /// </summary>
        /// <param name="closestGrabbable">The object to be grabbed.</param>
        /// <param name="closestGrabbableCollider">The collider of the grabbable, not used.</param>
        protected virtual void Grab(Grabbable closestGrabbable, Collider closestGrabbableCollider)
        {
            GrabbedObject = closestGrabbable;
            GrabbedObject.GrabBegin(this, closestGrabbableCollider);

            OnGrabStarted?.Invoke(GrabbedObject?.gameObject);

            _grabbedObjectOffset          = new Pose();
            _grabbedObjectOffset.position = Quaternion.Inverse(transform.rotation) * (GrabbedObject.transform.position - transform.position);
            _grabbedObjectOffset.rotation = Quaternion.Inverse(transform.rotation) * GrabbedObject.transform.rotation;
        }
コード例 #6
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
        /// <summary>
        /// Search for a nearby object and grab it.
        /// </summary>
        protected virtual void GrabBegin()
        {
            Grabbable closestGrabbable = FindClosestGrabbable();

            GrabVolumeEnable(false);
            if (closestGrabbable != null)
            {
                _timeSinceLastRelease = Time.timeSinceLevelLoad;
                Grab(closestGrabbable);
            }
        }
コード例 #7
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
        /// <summary>
        /// Release a grabbable from this grabber.
        /// </summary>
        /// <param name="grabbable">The grabbable to be released.</param>
        public void ForceRelease(Grabbable grabbable)
        {
            bool canRelease = (
                (GrabbedObject != null) &&
                (GrabbedObject == grabbable || grabbable == null)
                );

            if (canRelease)
            {
                GrabEnd(false);
            }
        }
コード例 #8
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
        /// <summary>
        /// Attach a given grabbable to the hand, storing the offset to the hand so it can be kept while holding.
        /// </summary>
        /// <param name="closestGrabbable">The object to be grabbed.</param>
        protected virtual void Grab(Grabbable closestGrabbable)
        {
            _timeSinceLastGrab = Time.timeSinceLevelLoad;
            GrabbedObject      = closestGrabbable;
            GrabbedObject?.GrabBegin(this);
            OnGrabStarted?.Invoke(GrabbedObject?.gameObject);

            Transform grabedTransform = closestGrabbable.transform;

            _grabbedObjectOffset          = new Pose();
            _grabbedObjectOffset.position = Quaternion.Inverse(this.transform.rotation) * (grabedTransform.position - this.transform.position);
            _grabbedObjectOffset.rotation = Quaternion.Inverse(this.transform.rotation) * grabedTransform.rotation;
        }
コード例 #9
0
        private void BeginDistantGrab()
        {
            Grabbable distantGrabbable = FindDistantGrabbable();

            if (distantGrabbable != null)
            {
                ObjectSnappingAddress snapAddress = this.GetComponent <Snapper>()?.SnapForGrabbable(distantGrabbable.gameObject); //TODO reference to snapper?
                if (snapAddress != null &&
                    snapAddress.point.CanBeDistantGrabbed)
                {
                    _distantGrabAddress = snapAddress;
                }
            }
        }
コード例 #10
0
        private void OnTriggerEnter(Collider otherCollider)
        {
            Grabbable grabbable = otherCollider.GetComponent <Grabbable>() ?? otherCollider.GetComponentInParent <Grabbable>();

            if (grabbable == null)
            {
                return;
            }

            int refCount = 0;

            _grabCandidates.TryGetValue(grabbable, out refCount);
            _grabCandidates[grabbable] = refCount + 1;
        }
コード例 #11
0
 /// <summary>
 /// Search for a nearby object and grab it.
 /// </summary>
 protected virtual void GrabBegin(Grabbable closestGrabbable = null)
 {
     closestGrabbable = closestGrabbable ?? FindClosestGrabbable();
     GrabVolumeEnable(false);
     if (closestGrabbable != null)
     {
         CancelDistantGrab();
         _timeSinceLastRelease = Time.timeSinceLevelLoad;
         Grab(closestGrabbable);
     }
     else
     {
         BeginDistantGrab();
     }
 }
コード例 #12
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
        public void OnTriggerEnter(Collider otherCollider)
        {
            Grabbable grabbable = otherCollider.GetComponent <Grabbable>() ?? otherCollider.GetComponentInParent <Grabbable>();

            if (grabbable == null)
            {
                return;
            }

            _grabCandidates.TryGetValue(grabbable, out int refCount);
            _grabCandidates[grabbable] = refCount + 1;

            _timeWithoutCandidates = null;
            _lastGrabCandidate     = null;
        }
コード例 #13
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
        protected virtual void GrabFailed()
        {
            bool sentFailedEventRecently = _timeSinceLastFail.HasValue &&
                                           Time.timeSinceLevelLoad - _timeSinceLastFail.Value < GRAB_ATTEMPT_DURATION;

            if (!sentFailedEventRecently)
            {
                Grabbable failedGrabbable = _lastGrabCandidate;
                if (failedGrabbable == null)
                {
                    failedGrabbable = FindClosestGrabbable();
                }
                OnGrabAttemptFail?.Invoke(failedGrabbable?.gameObject);
                _timeSinceLastFail = Time.timeSinceLevelLoad;
            }
        }
コード例 #14
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
        protected Grabbable FindClosestGrabbable()
        {
            float     closestMagSq     = float.MaxValue;
            Grabbable closestGrabbable = null;

            foreach (Grabbable grabbable in _grabCandidates.Keys)
            {
                Collider collider = FindClosestCollider(grabbable, out float distance);
                if (distance < closestMagSq)
                {
                    closestMagSq     = distance;
                    closestGrabbable = grabbable;
                }
            }
            return(closestGrabbable);
        }
コード例 #15
0
        private Grabbable FindDistantGrabbable()
        {
            Vector3 origin = gripTransform.position + gripTransform.forward * minMaxDistanceGrab.x;
            float   lenght = Mathf.Abs(minMaxDistanceGrab.x - minMaxDistanceGrab.y);

            if (Physics.SphereCast(origin, DISTANT_SEARCH_RADIOUS, gripTransform.forward, out RaycastHit hit, lenght, ~(distantIgnoreLayers.value), QueryTriggerInteraction.Ignore))
            {
                Grabbable grabbable = hit.transform.GetComponentInParent <Grabbable>();
                if (grabbable != null &&
                    !grabbable.IsGrabbed)
                {
                    return(grabbable);
                }
            }
            return(null);
        }
コード例 #16
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
        /// <summary>
        /// Triggers how close the grabber is to start grabbing a nearby object, informing the snapping system.
        /// </summary>
        /// <param name="factor">Current normalised value for the grab attemp, 1 indicates a grab.</param>
        protected void NearGrab(float factor)
        {
            if (factor == 0f)
            {
                OnGrabAttemp?.Invoke(null, 0f);
                return;
            }

            Grabbable closestGrabbable = FindClosestGrabbable();

            if (closestGrabbable != null)
            {
                OnGrabAttemp?.Invoke(closestGrabbable.gameObject, factor);
            }
            else
            {
                OnGrabAttemp?.Invoke(null, 0f);
            }
        }
コード例 #17
0
ファイル: BaseGrabber.cs プロジェクト: tangentlab/HandPosing
        private Collider FindClosestCollider(Grabbable grabbable, out float score)
        {
            float    closestMagSq             = float.MaxValue;
            Collider closestGrabbableCollider = null;

            for (int j = 0; j < grabbable.GrabPoints.Length; ++j)
            {
                Collider grabbableCollider = grabbable.GrabPoints[j];
                if (grabbableCollider == null)
                {
                    continue;
                }
                Vector3 closestPointOnBounds = grabbableCollider.ClosestPointOnBounds(gripTransform.position);
                float   grabbableMagSq       = (gripTransform.position - closestPointOnBounds).sqrMagnitude;
                if (grabbableMagSq < closestMagSq)
                {
                    closestMagSq             = grabbableMagSq;
                    closestGrabbableCollider = grabbableCollider;
                }
            }
            score = closestMagSq;
            return(closestGrabbableCollider);
        }
コード例 #18
0
        private void OnTriggerExit(Collider otherCollider)
        {
            Grabbable grabbable = otherCollider.GetComponent <Grabbable>() ?? otherCollider.GetComponentInParent <Grabbable>();

            if (grabbable == null)
            {
                return;
            }
            bool found = _grabCandidates.TryGetValue(grabbable, out int refCount);

            if (!found)
            {
                return;
            }
            if (refCount > 1)
            {
                _grabCandidates[grabbable] = refCount - 1;
            }
            else
            {
                _grabCandidates.Remove(grabbable);
            }
        }