示例#1
0
        // XXX 4-23-03: Temporary work around (see comment above)
        //
        // Checks for intersection of the given spherical obstacle with a
        // volume of "likely future vehicle positions": a cylinder along the
        // current path, extending minTimeToCollision seconds along the
        // forward axis from current position.
        //
        // If they intersect, a collision is imminent and this function returns
        // a steering force pointing laterally away from the obstacle's center.
        //
        // Returns a zero vector if the obstacle is outside the cylinder
        //
        // xxx couldn't this be made more compact using localizePosition?
        Vector3 steerToAvoid(Vehicle v, float minTimeToCollision)
        {
            // minimum distance to obstacle before avoidance is required
            float minDistanceToCollision = minTimeToCollision * v.Speed;
            float minDistanceToCenter = minDistanceToCollision + radius;

            // contact distance: sum of radii of obstacle and vehicle
             float totalRadius = radius + v.Radius;

            // obstacle center relative to vehicle position
             Vector3 localOffset = center - v.Position;

            // distance along vehicle's forward axis to obstacle's center
             float forwardComponent = Vector3.Dot(localOffset, v.Forward);
             Vector3 forwardOffset = forwardComponent * v.Forward;

            // offset from forward axis to obstacle's center
             Vector3 offForwardOffset = localOffset - forwardOffset;

            // test to see if sphere overlaps with obstacle-free corridor
             bool inCylinder = offForwardOffset.magnitude < totalRadius;
             bool nearby = forwardComponent < minDistanceToCenter;
             bool inFront = forwardComponent > 0;

            // if all three conditions are met, steer away from sphere center
            if (inCylinder && nearby && inFront)
            {
                return offForwardOffset * -1;
            }
            else
            {
                return Vector3.zero;
            }
        }
示例#2
0
 // constructor
 public tokenType(Vehicle parentObject, BruteForceProximityDatabase pd)
 {
     // store pointer to our associated database and the object this
     // token represents, and store this token on the database's vector
     bfpd = pd;
     tParentObject = parentObject;
     bfpd.group.Add(this);
 }
示例#3
0
 // type for the "tokens" manipulated by this spatial database
 //typedef AbstractTokenForProximityDatabase<ContentType> tokenType;
 // allocate a token to represent a given client object in this database
 public virtual AbstractTokenForProximityDatabase allocateToken(Vehicle parentObject)
 {
     return new AbstractTokenForProximityDatabase();
 }
示例#4
0
		// ----------------------------------------------------------------------------
		// evasion of another vehicle


	   
		public Vector3 steerForEvasion ( Vehicle menace, float maxPredictionTime)
		{
			// offset from this to menace, that distance, unit vector toward menace
			Vector3 offset = menace.Position - Position;
			float distance = offset.magnitude;

			float roughTime = distance / menace.Speed;
			float predictionTime = ((roughTime > maxPredictionTime) ?
										  maxPredictionTime :
										  roughTime);

			Vector3 target = menace.predictFuturePosition (predictionTime);

			return steerForFlee (target);
		}
示例#5
0
 // allocate a token to represent a given client object in this database
 //public override tokenType allocateToken (Object parentObject)
 public override AbstractTokenForProximityDatabase allocateToken(Vehicle parentObject)
 {
     tokenType tToken=new tokenType (parentObject, this);
     return (AbstractTokenForProximityDatabase)tToken;
 }
示例#6
0
		// ----------------------------------------------------------------------------
		// pursuit of another vehicle (& version with ceiling on prediction time)


	   
		public Vector3 steerForPursuit (Vehicle quarry)
		{
			return steerForPursuit (quarry, float.MaxValue);
		}
示例#7
0
		public Vector3 steerForPursuit (Vehicle quarry, float maxPredictionTime)
		{
			// offset from this to quarry, that distance, unit vector toward quarry
			Vector3 offset = quarry.Position - Position;
			float distance = offset.magnitude;
			Vector3 unitOffset = offset / distance;

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

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

			float directTravelTime = distance / Speed;
			int f = intervalComparison (forwardness,  -0.707f, 0.707f);
			int p = intervalComparison (parallelness, -0.707f, 0.707f);

			float timeFactor = 0;		// to be filled in below
			Color color = Color.black;	// to be filled in below (xxx just for debugging)

			// 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;
						color = Color.black;
						break;
					case 0:			  // ahead, perpendicular
						timeFactor = 1.8f;
						color = Color.gray;
						break;
					case -1:		  // ahead, anti-parallel
						timeFactor = 0.85f;
						color = Color.white;
						break;
					}
					break;
				case 0:
					switch (p)
					{
					case +1:		  // aside, parallel
						timeFactor = 1;
						color = Color.red;
						break;
					case 0:			  // aside, perpendicular
						timeFactor = 0.8f;
						color = Color.yellow;
						break;
					case -1:		  // aside, anti-parallel
						timeFactor = 4;
						color = Color.green;
						break;
					}
					break;
				case -1:
					switch (p)
					{
					case +1:		  // behind, parallel
						timeFactor = 0.5f;
						color = Color.cyan;
						break;
					case 0:			  // behind, perpendicular
						timeFactor = 2;
						color = Color.blue;
						break;
					case -1:		  // behind, anti-parallel
						timeFactor = 2;
						color = Color.magenta;
						break;
					}
					break;
			}

			// estimated time until intercept of quarry
			float et = directTravelTime * timeFactor;

			// xxx experiment, if kept, this limit should be an argument
			float etl = (et > maxPredictionTime) ? maxPredictionTime : et;

			// estimated position of quarry at intercept
			Vector3 target = quarry.predictFuturePosition (etl);

			// annotation
			#if DEBUG
			annotationLine (Position,
							target,
							gaudyPursuitAnnotation ? color : Color.gray);
			#endif

			return steerForSeek (target);
		}
示例#8
0
		// ----------------------------------------------------------------------------
		// used by boid behaviors: is a given vehicle within this boid's neighborhood?


	   
		bool inBoidNeighborhood ( Vehicle other, float minDistance, float maxDistance, float cosMaxAngle)
		{
			if (other == this)
			{
				return false;
			}
			else
			{
				Vector3 offset = other.Position - Position;
				float distanceSquared = offset.sqrMagnitude;

				// definitely in neighborhood if inside minDistance sphere
				if (distanceSquared < (minDistance * minDistance))
				{
					return true;
				}
				else
				{
					// definitely not in neighborhood if outside maxDistance sphere
					if (distanceSquared > (maxDistance * maxDistance))
					{
						return false;
					}
					else
					{
						// otherwise, test angular offset from forward axis
						Vector3 unitOffset = offset / (float) System.Math.Sqrt (distanceSquared);
						float forwardness = Vector3.Dot(Forward, unitOffset);
						return forwardness > cosMaxAngle;
					}
				}
			}
		}
示例#9
0
		// Given the time until nearest approach (predictNearestApproachTime)
		// determine position of each vehicle at that time, and the distance
		// between them
		float computeNearestApproachPositions(Vehicle other, float time, 
											  ref Vector3 ourPosition, 
											  ref Vector3 hisPosition)
		{
			Vector3	   myTravel =		Forward *		Speed * time;
			Vector3 otherTravel = other.Forward * other.Speed * time;

			ourPosition =		Position + myTravel;
			hisPosition = other.Position + otherTravel;

			return Vector3.Distance(ourPosition, hisPosition);
		}
示例#10
0
		// Given two vehicles, based on their current positions and velocities,
		// determine the time until nearest approach
		//
		// XXX should this return zero if they are already in contact?

	   
		float predictNearestApproachTime (Vehicle other)
		{
			// imagine we are at the origin with no velocity,
			// compute the relative velocity of the other vehicle
			Vector3 myVelocity = Velocity;
			Vector3 otherVelocity = other.Velocity;
			Vector3 relVelocity = otherVelocity - myVelocity;
			float relSpeed = relVelocity.magnitude;

			// for parallel paths, the vehicles will always be at the same distance,
			// so return 0 (aka "now") since "there is no time like the present"
			if (relSpeed == 0) return 0;

			// Now consider the path of the other vehicle in this relative
			// space, a line defined by the relative position and velocity.
			// The distance from the origin (our vehicle) to that line is
			// the nearest approach.

			// Take the unit tangent along the other vehicle's path
			Vector3 relTangent = relVelocity / relSpeed;

			// find distance from its path to origin (compute offset from
			// other to us, find length of projection onto path)
			Vector3 relPosition = Position - other.Position;
			float projection = Vector3.Dot(relTangent, relPosition);

			return projection / relSpeed;
		}
示例#11
0
		// called when steerToAvoidNeighbors decides steering is required
		// (default action is to do nothing, layered classes can overload it)
		public virtual void annotateAvoidNeighbor (	 Vehicle vehicle, float steer, Vector3 position, Vector3 threatPosition)
		{
			Debug.DrawLine(Position, vehicle.Position, Color.red); // Neighbor position
			Debug.DrawLine(Position, position, Color.green);	   // Position we're aiming for
		}
示例#12
0
		// called when steerToAvoidCloseNeighbors decides steering is required
		// (default action is to do nothing, layered classes can overload it)
		public virtual void annotateAvoidCloseNeighbor(Vehicle otherVehicle, Vector3 component)
		{
			Debug.DrawLine(Position, otherVehicle.Position, Color.red);
			Debug.DrawRay (Position, component*3, Color.yellow);
		}