public SteeringBehaviours(Fighter entity)
        {
            this.fighter = entity;
            calculationMethod = CalculationMethods.WeightedTruncatedRunningSumWithPrioritisation;
            sphere = new Sphere(0.2f);
            XNAGame.Instance().Children.Add(sphere);
            wanderTarget = new Vector3(randomClamped(), randomClamped(), randomClamped());
            wanderTarget.Normalize();

            weights.Add(behaviour_type.allignment, 1.0f);
            weights.Add(behaviour_type.cohesion, 2.0f);
            weights.Add(behaviour_type.obstacle_avoidance, 20.0f);
            weights.Add(behaviour_type.wall_avoidance, 20.0f);
            weights.Add(behaviour_type.wander, 1.0f);
            weights.Add(behaviour_type.seek, 1.0f);
            weights.Add(behaviour_type.flee, 1.0f);
            weights.Add(behaviour_type.arrive, 1.0f);
            weights.Add(behaviour_type.pursuit, 1.0f);
            weights.Add(behaviour_type.offset_pursuit, 1.0f);
            weights.Add(behaviour_type.interpose, 1.0f);
            weights.Add(behaviour_type.hide, 1.0f);
            weights.Add(behaviour_type.evade, 0.01f);
            weights.Add(behaviour_type.follow_path, 1.0f);
            weights.Add(behaviour_type.separation, 1.0f);
        }
        public SteeringBehaviours(Fighter entity)
        {
            this.fighter = entity;
            calculationMethod = CalculationMethods.WeightedTruncatedRunningSumWithPrioritisation;
            sphere = new Sphere(0.2f);
            wanderSphere = new Sphere(1);
            wanderSphere.ShouldDraw = false;
            sphere.ShouldDraw = false;
            XNAGame.Instance().Children.Add(sphere);
            XNAGame.Instance().Children.Add(wanderSphere);

            wanderTarget = new Vector3(RandomClamped(), RandomClamped(), RandomClamped());
            wanderTarget.Normalize();
            wanderTarget *= Params.GetFloat("wander_radius");
        }
        Vector3 obstacleAvoidance()
        {
            Vector3 force = Vector3.Zero;
            makeFeelers();
            List<Sphere> tagged = new List<Sphere>();
            float minBoxLength = 20.0f;
            float boxLength = minBoxLength + ((fighter.velocity.Length()/fighter.maxSpeed) * minBoxLength * 2.0f);

            if (float.IsNaN(boxLength))
            {
                System.Console.WriteLine("NAN");
            }
            // Matt Bucklands Obstacle avoidance
            // First tag obstacles in range
            foreach (Entity child in XNAGame.Instance().Children)
            {
                if (child is Obstacle)
                {
                    Obstacle obstacle = (Obstacle)child;

                    Vector3 toCentre = fighter.pos - obstacle.pos;
                    float dist = toCentre.Length();
                    if (dist < boxLength)
                    {
                        tagged.Add(obstacle);
                    }
                }
            }

            float distToClosestIP = float.MaxValue;
            Sphere closestIntersectingObstacle = null;
            Vector3 localPosOfClosestObstacle = Vector3.Zero;
            Vector3 intersection = Vector3.Zero;

            Matrix localTransform = Matrix.Invert(fighter.worldTransform);
            foreach (Obstacle o in tagged)
            {
                Vector3 localPos = Vector3.Transform(o.pos, localTransform);
                //Vector3 localPos = o.pos - fighter.pos;

                // If the local position has a positive Z value then it must lay
                // behind the agent. (in which case it can be ignored)
                if (localPos.Z <=0)
                {
                    // If the distance from the x axis to the object's position is less
                    // than its radius + half the width of the detection box then there
                    // is a potential intersection.
                    float expandedRadius = fighter.BoundingSphere.Radius + o.Radius;
                    if ((Math.Abs(localPos.Y) < expandedRadius) && (Math.Abs(localPos.X) < expandedRadius))
                    {
                        // Now to do a ray/sphere intersection test. The center of the
                        // Create a temp Entity to hold the sphere in local space
                        Sphere tempSphere = new Sphere(expandedRadius);
                        tempSphere.pos = localPos;

                        // Create a ray
                        Ray ray = new Ray();
                        ray.pos = new Vector3(0, 0, 0);
                        ray.look = fighter.basis;

                        // Find the point of intersection
                        if (tempSphere.closestRayIntersects(ray, Vector3.Zero, ref intersection) == false)
                        {
                            return Vector3.Zero;
                        }

                        // Now see if its the closest, there may be other intersecting spheres
                        float dist = intersection.Length();
                        if (dist < distToClosestIP)
                        {
                            dist = distToClosestIP;
                            closestIntersectingObstacle = o;
                            localPosOfClosestObstacle = localPos;
                        }
                    }
                }
                if (closestIntersectingObstacle != null)
                {
                    // Now calculate the force
                    // Calculate Z Axis braking  force
                    float multiplier = 200 * (1.0f + (boxLength - localPosOfClosestObstacle.Z) / boxLength);

                    //calculate the lateral force
                    float expandedRadius = fighter.BoundingSphere.Radius + o.Radius;
                    force.X = (expandedRadius - Math.Abs(localPosOfClosestObstacle.X))  * multiplier;

                    force.Y = (expandedRadius - -Math.Abs(localPosOfClosestObstacle.X)) * multiplier;

                    if (localPosOfClosestObstacle.X > 0)
                    {
                        force.X = -force.X;
                    }

                    if (localPosOfClosestObstacle.Y > 0)
                    {
                        force.Y = -force.Y;
                    }

                    /*if (fighter.pos.X < o.pos.X)
                    {
                        force.X = -force.X;
                    }

                    if (fighter.pos.Y < o.pos.Y)
                    {
                        force.Y = -force.Y;
                    }*/

                    Line.DrawLine(fighter.pos, fighter.pos + fighter.look * boxLength, Color.BlueViolet);
                    //apply a braking force proportional to the obstacle's distance from
                    //the vehicle.
                    const float brakingWeight = 40.0f;
                    force.Z = (closestIntersectingObstacle.Radius -
                                       localPosOfClosestObstacle.Z) *
                                       brakingWeight;

                    //finally, convert the steering vector from local to world space
                    force = Vector3.Transform(force, fighter.worldTransform);
                }
            }

            fighter.DrawFeelers = false;
            fighter.DrawAxis = false;
            checkNaN(force);

            return force;
        }