Exemplo n.º 1
0
 /// <summary>
 /// Must be called when a detectable object is disabled to remove it from the list of known objects
 /// </summary>
 /// <param name="obj">Detectable object</param>
 /// <returns>True if the call to Remove succeeded</returns>
 public static bool RemoveDetectableObject2D(DetectableObject2D obj)
 {
     return(_knownDetectableObjects.Remove(obj.Collider.GetInstanceID()));
 }
 public PathIntersection(DetectableObject2D obstacle)
 {
     Obstacle = obstacle;
     Intersect = false;
     Distance = float.MaxValue;
 }
Exemplo n.º 3
0
 /// <summary>
 /// Must be called when a detectable object is enabled so they can be easily identified
 /// </summary>
 /// <param name="obj">Detectable object</param>
 public static void AddDetectableObject2D(DetectableObject2D obj)
 {
     _knownDetectableObjects[obj.Collider.GetInstanceID()] = obj;
 }
        /// <summary>
        /// Finds a vehicle's next intersection with a spherical obstacle
        /// </summary>
        /// <param name="vehicle">
        /// The vehicle to evaluate.
        /// </param>
        /// <param name="futureVehiclePosition">
        /// The position where we expect the vehicle to be soon
        /// </param>
        /// <param name="obstacle">
        /// A spherical obstacle to check against <see cref="DetectableObject"/>
        /// </param>
        /// <returns>
        /// A PathIntersection with the intersection details <see cref="PathIntersection"/>
        /// </returns>
        /// <remarks>We could probably spin out this function to an independent tool class</remarks>
        public static PathIntersection FindNextIntersectionWithSphere(Vehicle2D vehicle, Vector2 futureVehiclePosition,
            DetectableObject2D obstacle)
        {
            // this mainly follows http://www.lighthouse3d.com/tutorials/maths/ray-sphere-intersection/

            var intersection = new PathIntersection(obstacle);

            var combinedRadius = vehicle.Radius + obstacle.Radius;
            var movement = futureVehiclePosition - vehicle.Position;
            var direction = movement.normalized;

            var vehicleToObstacle = obstacle.Position - vehicle.Position;

            // this is the length of vehicleToObstacle projected onto direction
            var projectionLength = Vector2.Dot(direction, vehicleToObstacle);

            // if the projected obstacle center lies further away than our movement + both radius, we're not going to collide
            if (projectionLength > movement.magnitude + combinedRadius)
            {
                //print("no collision - 1");
                return intersection;
            }

            // the foot of the perpendicular
            var projectedObstacleCenter = vehicle.Position + projectionLength * direction;

            // distance of the obstacle to the pathe the vehicle is going to take
            var obstacleDistanceToPath = (obstacle.Position - projectedObstacleCenter).magnitude;
            //print("obstacleDistanceToPath: " + obstacleDistanceToPath);

            // if the obstacle is further away from the movement, than both radius, there's no collision
            if (obstacleDistanceToPath > combinedRadius)
            {
                //print("no collision - 2");
                return intersection;
            }

            // use pythagorean theorem to calculate distance out of the sphere (if you do it 2D, the line through the circle would be a chord and we need half of its length)
            var halfChord = Mathf.Sqrt(combinedRadius * combinedRadius + obstacleDistanceToPath * obstacleDistanceToPath);

            // if the projected obstacle center lies opposite to the movement direction (aka "behind")
            if (projectionLength < 0)
            {
                // behind and further away than both radius -> no collision (we already passed)
                if (vehicleToObstacle.magnitude > combinedRadius)
                    return intersection;

                var intersectionPoint = projectedObstacleCenter - direction * halfChord;
                intersection.Intersect = true;
                intersection.Distance = (intersectionPoint - vehicle.Position).magnitude;
                return intersection;
            }

            // calculate both intersection points
            var intersectionPoint1 = projectedObstacleCenter - direction * halfChord;
            var intersectionPoint2 = projectedObstacleCenter + direction * halfChord;

            // pick the closest one
            var intersectionPoint1Distance = (intersectionPoint1 - vehicle.Position).magnitude;
            var intersectionPoint2Distance = (intersectionPoint2 - vehicle.Position).magnitude;

            intersection.Intersect = true;
            intersection.Distance = Mathf.Min(intersectionPoint1Distance, intersectionPoint2Distance);

            return intersection;
        }
Exemplo n.º 5
0
 /// <summary>
 /// Must be called when a detectable object is disabled to remove it from the list of known objects
 /// </summary>
 /// <param name="obj">Detectable object</param>
 /// <returns>True if the call to Remove succeeded</returns>
 public static bool RemoveDetectableObject2D(DetectableObject2D obj)
 {
     return _knownDetectableObjects.Remove(obj.Collider.GetInstanceID());
 }
Exemplo n.º 6
0
 /// <summary>
 /// Must be called when a detectable object is enabled so they can be easily identified
 /// </summary>
 /// <param name="obj">Detectable object</param>
 public static void AddDetectableObject2D(DetectableObject2D obj)
 {
     _knownDetectableObjects[obj.Collider.GetInstanceID()] = obj;
 }
 public PathIntersection(DetectableObject2D obstacle)
 {
     Obstacle  = obstacle;
     Intersect = false;
     Distance  = float.MaxValue;
 }
        /// <summary>
        /// Finds a vehicle's next intersection with a spherical obstacle
        /// </summary>
        /// <param name="vehicle">
        /// The vehicle to evaluate.
        /// </param>
        /// <param name="futureVehiclePosition">
        /// The position where we expect the vehicle to be soon
        /// </param>
        /// <param name="obstacle">
        /// A spherical obstacle to check against <see cref="DetectableObject"/>
        /// </param>
        /// <returns>
        /// A PathIntersection with the intersection details <see cref="PathIntersection"/>
        /// </returns>
        /// <remarks>We could probably spin out this function to an independent tool class</remarks>
        public static PathIntersection FindNextIntersectionWithSphere(Vehicle2D vehicle, Vector2 futureVehiclePosition,
                                                                      DetectableObject2D obstacle)
        {
            // this mainly follows http://www.lighthouse3d.com/tutorials/maths/ray-sphere-intersection/

            var intersection = new PathIntersection(obstacle);

            var combinedRadius = vehicle.Radius + obstacle.Radius;
            var movement       = futureVehiclePosition - vehicle.Position;
            var direction      = movement.normalized;

            var vehicleToObstacle = obstacle.Position - vehicle.Position;

            // this is the length of vehicleToObstacle projected onto direction
            var projectionLength = Vector2.Dot(direction, vehicleToObstacle);

            // if the projected obstacle center lies further away than our movement + both radius, we're not going to collide
            if (projectionLength > movement.magnitude + combinedRadius)
            {
                //print("no collision - 1");
                return(intersection);
            }

            // the foot of the perpendicular
            var projectedObstacleCenter = vehicle.Position + projectionLength * direction;

            // distance of the obstacle to the pathe the vehicle is going to take
            var obstacleDistanceToPath = (obstacle.Position - projectedObstacleCenter).magnitude;

            //print("obstacleDistanceToPath: " + obstacleDistanceToPath);

            // if the obstacle is further away from the movement, than both radius, there's no collision
            if (obstacleDistanceToPath > combinedRadius)
            {
                //print("no collision - 2");
                return(intersection);
            }

            // use pythagorean theorem to calculate distance out of the sphere (if you do it 2D, the line through the circle would be a chord and we need half of its length)
            var halfChord = Mathf.Sqrt(combinedRadius * combinedRadius + obstacleDistanceToPath * obstacleDistanceToPath);

            // if the projected obstacle center lies opposite to the movement direction (aka "behind")
            if (projectionLength < 0)
            {
                // behind and further away than both radius -> no collision (we already passed)
                if (vehicleToObstacle.magnitude > combinedRadius)
                {
                    return(intersection);
                }

                var intersectionPoint = projectedObstacleCenter - direction * halfChord;
                intersection.Intersect = true;
                intersection.Distance  = (intersectionPoint - vehicle.Position).magnitude;
                return(intersection);
            }

            // calculate both intersection points
            var intersectionPoint1 = projectedObstacleCenter - direction * halfChord;
            var intersectionPoint2 = projectedObstacleCenter + direction * halfChord;

            // pick the closest one
            var intersectionPoint1Distance = (intersectionPoint1 - vehicle.Position).magnitude;
            var intersectionPoint2Distance = (intersectionPoint2 - vehicle.Position).magnitude;

            intersection.Intersect = true;
            intersection.Distance  = Mathf.Min(intersectionPoint1Distance, intersectionPoint2Distance);

            return(intersection);
        }