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; }