Beispiel #1
0
        private PokeInteractable ComputeBestHoverInteractable()
        {
            PokeInteractable closestInteractable = null;
            float            closestSqrDist      = float.MaxValue;

            IEnumerable <PokeInteractable> interactables = PokeInteractable.Registry.List(this);

            // We check that we're above the surface first as we don't
            // care about hovers that originate below the surface
            foreach (PokeInteractable interactable in interactables)
            {
                if (!PassesEnterHoverDistanceCheck(interactable))
                {
                    continue;
                }

                Vector3 closestSurfacePoint  = interactable.ClosestSurfacePoint(Origin);
                Vector3 closestSurfaceNormal = interactable.ClosestSurfaceNormal(Origin);

                Vector3 surfaceToPoint = Origin - closestSurfacePoint;
                float   magnitude      = surfaceToPoint.magnitude;
                if (magnitude != 0f)
                {
                    // Check if our position is above the surface
                    if (Vector3.Dot(surfaceToPoint, closestSurfaceNormal) > 0f)
                    {
                        // Check if our position lies outside of the optional volume mask
                        if (interactable.VolumeMask != null &&
                            !Collisions.IsPointWithinCollider(Origin, interactable.VolumeMask))
                        {
                            continue;
                        }

                        // We're above the surface so now we must rank this
                        // interactable versus others that also pass this test this frame
                        // but may be at a closer proximity.
                        Vector3 closestPoint = interactable.ComputeClosestPoint(Origin);

                        float sqrDistanceFromPoint = (closestPoint - Origin).sqrMagnitude;

                        if (sqrDistanceFromPoint > interactable.MaxDistance * interactable.MaxDistance)
                        {
                            continue;
                        }

                        if (sqrDistanceFromPoint < closestSqrDist)
                        {
                            closestSqrDist      = sqrDistanceFromPoint;
                            closestInteractable = interactable;
                            ClosestPoint        = closestPoint;
                            TouchPoint          = ClosestPoint;
                        }
                    }
                }
            }
            return(closestInteractable);
        }
Beispiel #2
0
        public Pose GetGrabSourceForTarget(Pose target)
        {
            if (_grabSource == null && !_useClosestPointAsGrabSource)
            {
                return(target);
            }

            if (_useClosestPointAsGrabSource)
            {
                return(new Pose(
                           Collisions.ClosestPointToColliders(target.position, _colliders),
                           target.rotation));
            }

            return(_grabSource.GetPose());
        }
Beispiel #3
0
        protected override GrabInteractable ComputeCandidate()
        {
            GrabInteractable closestInteractable = null;
            float            bestScore           = float.NegativeInfinity;
            float            score = bestScore;

            IEnumerable <GrabInteractable> interactables = GrabInteractable.Registry.List(this);

            foreach (GrabInteractable interactable in interactables)
            {
                Collider[] colliders = interactable.Colliders;
                foreach (Collider collider in colliders)
                {
                    if (Collisions.IsPointWithinCollider(Rigidbody.transform.position, collider))
                    {
                        // Points within a collider are always weighted better than those outside
                        float sqrDistanceFromCenter =
                            (Rigidbody.transform.position - collider.bounds.center).magnitude;
                        score = float.MaxValue - sqrDistanceFromCenter;
                    }
                    else
                    {
                        var     position = Rigidbody.transform.position;
                        Vector3 closestPointOnInteractable = collider.ClosestPoint(position);
                        score = -1f * (position - closestPointOnInteractable).magnitude;
                    }

                    if (score > bestScore)
                    {
                        bestScore           = score;
                        closestInteractable = interactable;
                    }
                }
            }

            BestInteractableWeight = bestScore;
            return(closestInteractable);
        }
        public static Vector3 ClosestPointToColliders(Vector3 point, Collider[] colliders)
        {
            Vector3 closestPoint    = point;
            float   closestDistance = float.MaxValue;

            foreach (Collider collider in colliders)
            {
                if (Collisions.IsPointWithinCollider(point, collider))
                {
                    return(point);
                }

                Vector3 closest  = collider.ClosestPoint(point);
                float   distance = (closest - point).magnitude;
                if (distance < closestDistance)
                {
                    closestDistance = distance;
                    closestPoint    = closest;
                }
            }

            return(closestPoint);
        }
Beispiel #5
0
        private PokeInteractable ComputeSelectCandidate()
        {
            PokeInteractable closestInteractable = null;
            float            closestSqrDist      = float.MaxValue;

            IEnumerable <PokeInteractable> interactables = PokeInteractable.Registry.List(this);

            Vector3 moveDirection = Origin - _previousOrigin;
            float   magnitude     = moveDirection.magnitude;

            if (magnitude == 0f)
            {
                return(null);
            }

            moveDirection /= magnitude;
            Ray ray = new Ray(_previousOrigin, moveDirection);

            // Check the surface first as a movement through this will
            // automatically put us in a "active" state. We expect the raycast
            // to happen only in one direction
            foreach (PokeInteractable interactable in interactables)
            {
                if (!PassesEnterHoverDistanceCheck(interactable))
                {
                    continue;
                }

                Vector3 closestSurfaceNormal = interactable.ClosestSurfaceNormal(Origin);

                // First check that we are moving towards the surface by checking
                // the direction of our position delta with the forward direction of the surface normal.
                // This is to not allow presses from "behind" the surface.

                // Check if we are moving toward the surface
                if (Vector3.Dot(moveDirection, closestSurfaceNormal) < 0f)
                {
                    // Then do a raycast against the surface
                    bool hit = interactable.Surface.Raycast(ray, out SurfaceHit surfaceHit);
                    if (hit && surfaceHit.Distance <= magnitude)
                    {
                        // We collided against the surface and now we must rank this
                        // interactable versus others that also pass this test this frame
                        // but may be at a closer proximity. For this we use the closest
                        // point compute against the surface intersection point

                        // Check if our collision lies outside of the optional volume mask
                        if (interactable.VolumeMask != null &&
                            !Collisions.IsPointWithinCollider(surfaceHit.Point, interactable.VolumeMask))
                        {
                            continue;
                        }

                        Vector3 closestPointToHitPoint = interactable.ComputeClosestPoint(surfaceHit.Point);

                        float sqrDistanceFromPoint = (closestPointToHitPoint - surfaceHit.Point).sqrMagnitude;

                        if (sqrDistanceFromPoint > interactable.MaxDistance * interactable.MaxDistance)
                        {
                            continue;
                        }

                        if (sqrDistanceFromPoint < closestSqrDist)
                        {
                            closestSqrDist      = sqrDistanceFromPoint;
                            closestInteractable = interactable;
                            ClosestPoint        = closestPointToHitPoint;
                            TouchPoint          = ClosestPoint;
                        }
                    }
                }
            }
            return(closestInteractable);
        }