Exemplo n.º 1
0
        /// <summary>
        /// Instructs Vehicle Entity to always stay on the provided path. Entity will move to the nearest point
        /// </summary>
        /// <param name="vehicle"></param>
        /// <param name="predictionTime"></param>
        /// <param name="path"></param>
        /// <returns>The Vector to move to</returns>
        public static Vector3 StayOnPath(VehicleActor vehicle, float predictionTime, Pathway path)
        {
            // predict our future position
            Vector3 futurePosition = vehicle.PredictFuturePosition(predictionTime);

            // find the point on the path nearest the predicted future position
            Vector3 tangent;
            float   outside;
            Vector3 onPath = path.MapPointToPath(futurePosition, out tangent, out outside);

            if (outside < 0)
            {
                // our predicted future position was in the path,
                // return zero steering.
                return(Vector3.Zero);
            }
            else
            {
                // our predicted future position was outside the path, need to
                // steer towards it.  Use onPath projection of futurePosition
                // as seek target
                //log PathFollowing(futurePosition, onPath, onPath, outside);
                return(Seek(vehicle, onPath));
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Determine evasion vector between two vehicle entities
        /// Often used by the target of a pursuit to aid in avoidance of pursuing vehicle
        /// </summary>
        /// <param name="vehicle"></param>
        /// <param name="menace"></param>
        /// <param name="maxPredictionTime"></param>
        /// <returns></returns>
        public static Vector3 Evasion(VehicleActor vehicle, VehicleActor menace, float maxPredictionTime)
        {
            // offset from this to menace, that distance, unit vector toward menace
            Vector3 offset   = menace.Position - vehicle.Position;
            float   distance = offset.Length();

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

            Vector3 target = menace.PredictFuturePosition(predictionTime);

            return(Flee(vehicle, target));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Instructs a Vehicle Entity to follow a defined path (pathway), within the defined predicted timeframe
        /// </summary>
        /// <param name="vehicle"></param>
        /// <param name="direction"></param>
        /// <param name="predictionTime"></param>
        /// <param name="path"></param>
        /// <returns>The Vector to move to</returns>
        public static Vector3 FollowPath(VehicleActor vehicle, int direction, float predictionTime, Pathway path)
        {
            // our goal will be offset from our path distance by this amount
            float pathDistanceOffset = direction * predictionTime * vehicle.Velocity;

            // predict our future position
            Vector3 futurePosition = vehicle.PredictFuturePosition(predictionTime);

            // measure distance along path of our current and predicted positions
            float nowPathDistance    = path.MapPointToPathDistance(vehicle.Position);
            float futurePathDistance = path.MapPointToPathDistance(futurePosition);

            // are we facing in the correction direction?
            bool rightway = ((pathDistanceOffset > 0) ?
                             (nowPathDistance < futurePathDistance) :
                             (nowPathDistance > futurePathDistance));

            // find the point on the path nearest the predicted future position
            // XXX need to improve calling sequence, maybe change to return a
            // XXX special path-defined object which includes two Vector3s and a
            // XXX bool (onPath,tangent (ignored), withinPath)
            Vector3 tangent;
            float   outside;
            Vector3 onPath = path.MapPointToPath(futurePosition, out tangent, out outside);

            // no steering is required if (a) our future position is inside
            // the path tube and (b) we are facing in the correct direction
            if ((outside < 0) && rightway)
            {
                // all is well, return zero steering
                return(Vector3.Zero);
            }
            else
            {
                // otherwise we need to steer towards a target point obtained
                // by adding pathDistanceOffset to our current path position

                float   targetPathDistance = nowPathDistance + pathDistanceOffset;
                Vector3 target             = path.MapPathDistanceToPoint(targetPathDistance);

                //log PathFollowing(futurePosition, onPath, target, outside);

                // return steering to seek target on path
                return(Seek(vehicle, target));
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Calculate target pursuit vector between two vehicle entities, within a maximum time
        /// </summary>
        /// <param name="vehicle"></param>
        /// <param name="target"></param>
        /// <param name="maxPredictionTime"></param>
        /// <returns></returns>
        public static Vector3 Pursuit(VehicleActor vehicle, VehicleActor target, float maxPredictionTime)
        {
            // offset from this to quarry, that distance, unit vector toward quarry
            Vector3 offset     = target.Position - vehicle.Position;
            float   distance   = offset.Length();
            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(vehicle.Forward, target.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(vehicle.Forward, unitOffset);

            float directTravelTime = distance / vehicle.Velocity;
            int   f = Utilities.IntervalComparison(forwardness, -0.707f, 0.707f);
            int   p = Utilities.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 target
            float et = directTravelTime * timeFactor;

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

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

            return(Seek(vehicle, targetLocation));
        }