Beispiel #1
0
 /// <summary>
 /// Tells the radar to no longer ignore the detectable object when filtering the vehicles or objects detected
 /// </summary>
 /// <param name="o">
 /// An object to remove from the ignore list<see cref="DetectableObject"/>
 /// </param>
 /// <returns>The radar</returns>
 public Radar DontIgnore(DetectableObject o)
 {
     if (_ignoredObjects.Contains(o))
     {
         _ignoredObjects.Remove(o);
     }
     return(this);
 }
Beispiel #2
0
 /// <summary>
 /// Tells the radar to ignore the detectable object when filtering the vehicles or objects detected
 /// </summary>
 /// <param name="o">
 /// An object to be ignored<see cref="DetectableObject"/>
 /// </param>
 /// <returns>The radar</returns>
 public Radar Ignore(DetectableObject o)
 {
     if (o != null)
     {
         _ignoredObjects.Add(o);
     }
     return(this);
 }
Beispiel #3
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 RemoveDetectableObject(DetectableObject obj)
 {
     return(_knownDetectableObjects.Remove(obj.Collider.GetInstanceID()));
 }
Beispiel #4
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 AddDetectableObject(DetectableObject obj)
 {
     _knownDetectableObjects[obj.Collider.GetInstanceID()] = obj;
 }
        protected override Vector3 CalculateForce()
        {
			//---added by Rose---
			potential_quarry = GameObject.FindGameObjectsWithTag("humanCreature");

			GameObject nearest = null;
			float nearest_dist = 100f;

			foreach (GameObject q in potential_quarry){
				float difference = Vector3.Distance(q.transform.position, transform.position);
				if (difference < nearest_dist) {
					nearest = q;
					nearest_dist = difference;
				}
			}

			if (nearest != null) {
				_quarry = nearest.GetComponent<DetectableObject> ();
			} else {
				Debug.Log ("nearest human creature is null");
			}

//			_quarry = GameObject.FindGameObjectWithTag("humanCreature").GetComponent<DetectableObject>();

			if (_quarry == null) {
				//---added by Rose---
				Debug.Log ("QUARRY IS NULL");
				//-----end-----------

				enabled = false;
				return Vector3.zero;
			} else {
				Debug.Log ("HUMAN CREATURE QUARRY FOUND: " + _quarry.gameObject.name);
			}
			//-----end-----------

            var force = Vector3.zero;
            var offset = _quarry.Position - Vehicle.Position;
            var distance = offset.magnitude;
            var radius = Vehicle.Radius + _quarry.Radius + _acceptableDistance;

            if (!(distance > radius)) return force;

            var unitOffset = offset / distance;

            // how parallel are the paths of "this" and the quarry
            // (1 means parallel, 0 is pependicular, -1 is anti-parallel)
            var parallelness = Vector3.Dot(transform.forward, _quarry.transform.forward);

            // how "forward" is the direction to the quarry
            // (1 means dead ahead, 0 is directly to the side, -1 is straight back)
            var forwardness = Vector3.Dot(transform.forward, unitOffset);

            var directTravelTime = distance / Vehicle.Speed;
            // While we could parametrize this value, if we care about forward/backwards
            // these values are appropriate enough.
            var f = OpenSteerUtility.IntervalComparison(forwardness, -0.707f, 0.707f);
            var p = OpenSteerUtility.IntervalComparison(parallelness, -0.707f, 0.707f);

            float timeFactor = 0; // to be filled in below

            // Break the pursuit into nine cases, the cross product of the
            // quarry being [ahead, aside, or behind] us and heading
            // [parallel, perpendicular, or anti-parallel] to us.
            switch (f)
            {
                case +1:
                    switch (p)
                    {
                        case +1: // ahead, parallel
                            timeFactor = 4;
                            break;
                        case 0: // ahead, perpendicular
                            timeFactor = 1.8f;
                            break;
                        case -1: // ahead, anti-parallel
                            timeFactor = 0.85f;
                            break;
                    }
                    break;
                case 0:
                    switch (p)
                    {
                        case +1: // aside, parallel
                            timeFactor = 1;
                            break;
                        case 0: // aside, perpendicular
                            timeFactor = 0.8f;
                            break;
                        case -1: // aside, anti-parallel
                            timeFactor = 4;
                            break;
                    }
                    break;
                case -1:
                    switch (p)
                    {
                        case +1: // behind, parallel
                            timeFactor = 0.5f;
                            break;
                        case 0: // behind, perpendicular
                            timeFactor = 2;
                            break;
                        case -1: // behind, anti-parallel
                            timeFactor = 2;
                            break;
                    }
                    break;
            }

            // estimated time until intercept of quarry
            var et = directTravelTime * timeFactor;
            var etl = (et > _maxPredictionTime) ? _maxPredictionTime : et;

            // estimated position of quarry at intercept
            var target = _quarry.PredictFuturePosition(etl);

            force = Vehicle.GetSeekVector(target, _slowDownOnApproach);

#if ANNOTATE_PURSUIT
            Debug.DrawRay(Vehicle.Position, force, Color.blue);
            Debug.DrawLine(Quarry.Position, target, Color.cyan);
            Debug.DrawRay(target, Vector3.up * 4, Color.cyan);
#endif

            return force;
        }
 public PathIntersection(DetectableObject 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(Vehicle vehicle, Vector3 futureVehiclePosition,
            DetectableObject 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 = Vector3.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;
        }
Beispiel #8
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 RemoveDetectableObject(DetectableObject obj)
 {
     return _knownDetectableObjects.Remove(obj.Collider.GetInstanceID());
 }
Beispiel #9
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 AddDetectableObject(DetectableObject obj)
 {
     _knownDetectableObjects[obj.Collider.GetInstanceID()] = obj;
 }
 public PathIntersection(DetectableObject 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(Vehicle vehicle, Vector3 futureVehiclePosition,
                                                                      DetectableObject 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 = Vector3.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);
        }