//----------------------- AddEntity -------------------------------------- // // Used to add the entitys to the data structure //------------------------------------------------------------------------ public void AddEntity(MovingEntity ent) { Debug.Assert(ent != null); int NewIdx = PositionToIndex(ent.Pos); m_Cells[NewIdx].Members.Add(ent); ent.OldCellID = NewIdx; }
public override bool Equals(object obj) { if (obj is MovingEntity && obj != null) { MovingEntity objMoveingEntity = (MovingEntity)obj; if (objMoveingEntity.ID() == this.ID()) { return(true); } } return(false); }
//----------------------- UpdateEntity ----------------------------------- // // Checks to see if an entity has moved cells. If so the data structure // is updated accordingly //------------------------------------------------------------------------ public void UpdateEntity(MovingEntity ent) { Debug.Assert(ent != null); int NewIdx = PositionToIndex(ent.Pos); int OldIdx = ent.OldCellID; if (NewIdx == OldIdx) { return; } //the entity has moved into another cell so delete from current cell //and add to new one m_Cells[NewIdx].Members.Add(ent); m_Cells[OldIdx].Members.Remove(ent); ent.OldCellID = NewIdx; }
public void SetTargetAgent2(MovingEntity Agent) { m_pTargetAgent2 = Agent; }
//------------------------- Offset Pursuit ------------------------------- // // Produces a steering force that keeps a vehicle at a specified offset // from a leader vehicle //------------------------------------------------------------------------ public Vector2D OffsetPursuit(MovingEntity leader, Vector2D offset) { //calculate the offset's position in world space Vector2D WorldOffsetPos = Utils.PointToWorldSpace(offset, leader.Heading(), leader.Side(), leader.Pos); Vector2D ToOffset = WorldOffsetPos - m_parentMovingEntity.Pos; //the lookahead time is propotional to the distance between the leader //and the pursuer; and is inversely proportional to the sum of both //agent's velocities double LookAheadTime = ToOffset.Length() / (m_parentMovingEntity.MaxSpeed + leader.Speed()); //now Arrive at the predicted future position of the offset return Arrive(WorldOffsetPos + leader.Velocity * LookAheadTime, (int)Deceleration.fast); }
//--------------------------- Hide --------------------------------------- // //------------------------------------------------------------------------ public Vector2D Hide(MovingEntity hunter, List<BaseGameEntity> obstacles) { double DistToClosest = Double.MaxValue; Vector2D BestHidingSpot = new Vector2D(0.0, 0.0); foreach (BaseGameEntity curOb in obstacles) { //calculate the position of the hiding spot for this obstacle Vector2D HidingSpot = GetHidingPosition(curOb.Pos, curOb.BRadius, hunter.Pos); //work in distance-squared space to find the closest hiding //spot to the agent double dist = Vector2D.Vec2DDistanceSq(HidingSpot, m_parentMovingEntity.Pos); if (dist < DistToClosest) { DistToClosest = dist; BestHidingSpot = HidingSpot; } }//end while //if no suitable obstacles found then Evade the hunter if (DistToClosest == Double.MaxValue) { return Evade(hunter); } //else use Arrive on the hiding spot return Arrive(BestHidingSpot, (int)Deceleration.fast); }
//--------------------------- Interpose ---------------------------------- // // Given two agents, this method returns a force that attempts to // position the vehicle between them //------------------------------------------------------------------------ public Vector2D Interpose(MovingEntity AgentA, MovingEntity AgentB) { //first we need to figure out where the two agents are going to be at //time T in the future. This is approximated by determining the time //taken to reach the mid way point at the current time at at max speed. Vector2D MidPoint = (AgentA.Pos + AgentB.Pos) * 0.5; double TimeToReachMidPoint = Vector2D.Vec2DDistance(m_parentMovingEntity.Pos, MidPoint) / m_parentMovingEntity.MaxSpeed; //now we have T, we assume that agent A and agent B will continue on a //straight trajectory and extrapolate to get their future positions Vector2D APos = AgentA.Pos + AgentA.Velocity * TimeToReachMidPoint; Vector2D BPos = AgentB.Pos + AgentB.Velocity * TimeToReachMidPoint; //calculate the mid point of these predicted positions MidPoint = (APos + BPos) / 2.0; //then steer to Arrive at it return Arrive(MidPoint, (int)Deceleration.fast); }
//------------------------------ Pursuit --------------------------------- // // this behavior creates a force that steers the agent towards the // evader //------------------------------------------------------------------------ public Vector2D Pursuit(MovingEntity evader) { //if the evader is ahead and facing the agent then we can just seek //for the evader's current position. Vector2D ToEvader = evader.Pos - m_parentMovingEntity.Pos; double RelativeHeading = m_parentMovingEntity.Heading().Dot(evader.Heading()); if ((ToEvader.Dot(m_parentMovingEntity.Heading()) > 0) && (RelativeHeading < -0.95)) //acos(0.95)=18 degs { return Seek(evader.Pos); } //Not considered ahead so we predict where the evader will be. //the lookahead time is propotional to the distance between the evader //and the pursuer; and is inversely proportional to the sum of the //agent's velocities double LookAheadTime = ToEvader.Length() / (m_parentMovingEntity.MaxSpeed + evader.Speed()); //now seek to the predicted future position of the evader return Seek(evader.Pos + evader.Velocity * LookAheadTime); }
public void HideOn(MovingEntity v) { m_iFlags |= (int)behavior_type.hide; m_pTargetAgent1 = v; }
private void RenderVehicle(MovingEntity objVehicle, Graphics objGraphics, Pen objPen) { PointF pntLeft,pntFront,pntRight; if (UseSmoothing) { Vector2D SmoothedPerp = objVehicle.SmoothedHeading().Perp(); pntLeft = (PointF)(objVehicle.Pos + (SmoothedPerp * objVehicle.BRadius)); pntFront = (PointF)(objVehicle.Pos + (objVehicle.SmoothedHeading() * (objVehicle.BRadius * 2))); pntRight = (PointF)(objVehicle.Pos - (SmoothedPerp * objVehicle.BRadius)); } else { pntLeft = (PointF)(objVehicle.Pos + (objVehicle.Side() * objVehicle.BRadius)); pntFront = (PointF)(objVehicle.Pos + (objVehicle.Heading() * (objVehicle.BRadius * 2))); pntRight = (PointF)(objVehicle.Pos - (objVehicle.Side() * objVehicle.BRadius)); } PointF[] points = new PointF[4]; points[0] = pntLeft; points[1] = pntFront; points[2] = pntRight; points[3] = pntLeft; objGraphics.DrawPolygon(objPen, points); }
private void renderDetectionBox(MovingEntity objVehicle, Graphics objGraphics, Pen objPen) { List<Vector2D> points = new List<Vector2D>(); points.Add(new Vector2D(0, objVehicle.BRadius)); points.Add(new Vector2D(objVehicle.Steering().DBoxLength(), objVehicle.BRadius)); points.Add(new Vector2D(objVehicle.Steering().DBoxLength(), -objVehicle.BRadius)); points.Add(new Vector2D(0, -objVehicle.BRadius)); if (UseSmoothing) { points = Utils.WorldTransform(points, objVehicle.Pos, objVehicle.SmoothedHeading(), objVehicle.SmoothedHeading().Perp()); } else { points = Utils.WorldTransform(points, objVehicle.Pos, objVehicle.Heading(), objVehicle.Side()); } objGraphics.DrawLine(objPen, (PointF)points[0], (PointF)points[1]); objGraphics.DrawLine(objPen, (PointF)points[1], (PointF)points[2]); objGraphics.DrawLine(objPen, (PointF)points[2], (PointF)points[3]); }
public SteeringScenario(int cx, int cy) { m_cxClient = cx; m_cyClient = cy; m_Vehicles.Clear(); m_Obstacles.Clear(); m_Walls.Clear(); GameWorld.Instance.cxClient = m_cxClient; GameWorld.Instance.cyClient = m_cyClient; GameWorld.Instance.Wrap = true; GameWorld.Instance.SpacePartitioningOn = true; objVehiclePen = new Pen(Color.Black); objDarkPen = new Pen(Color.SeaGreen, 2); objWallPen = new Pen(Color.DarkOrange); objObstaclePen = new Pen(Color.Orange); objTargetPen = new Pen(Color.Blue, 1); objRedPen = new Pen(Color.Red, 2); objCellPen = new Pen(Color.LightSkyBlue, 1); objGrayPen = new Pen(Color.LightSlateGray, 2); objPathPen = new Pen(Color.Blue, 2); objPathPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor; objPathPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; m_pCellSpace = new CellSpacePartition(m_cxClient, m_cyClient, SteerParams.Instance.NumCellsX, SteerParams.Instance.NumCellsY, SteerParams.Instance.NumAgents); CreateObstacles(); CreateWalls(); CreateRandomPath(); //setup the agents for (int a = 0; a < SteerParams.Instance.NumAgents; ++a) { //determine a random starting position Vector2D SpawnPos = new Vector2D(cx / 2.0 + Utils.RandomClamped() * cx / 2.0, cy / 2.0 + Utils.RandomClamped() * cy / 2.0); double rotation = Utils.RandFloat() * Utils.TwoPi; MovingEntity pVehicle = new MovingEntity(SpawnPos, //initial position SteerParams.Instance.VehicleScale, new Vector2D(0, 0), SteerParams.Instance.MaxSpeed, new Vector2D(Math.Sin(rotation), -Math.Cos(rotation)), SteerParams.Instance.VehicleMass, new Vector2D(SteerParams.Instance.VehicleScale, SteerParams.Instance.VehicleScale), SteerParams.Instance.MaxTurnRatePerSecond, SteerParams.Instance.AppliedMaxSteeringForce()); pVehicle.Steering().FlockingOn(); pVehicle.Steering().WallAvoidanceOn(); pVehicle.Steering().ObstacleAvoidanceOn(); m_Vehicles.Add(pVehicle); //add it to the cell subdivision m_pCellSpace.AddEntity(pVehicle); } // Turn the last one into a shark! int sharkie = SteerParams.Instance.NumAgents - 1; m_Vehicles[sharkie].Steering().FlockingOff(); m_Vehicles[sharkie].SetScale(new Vector2D(6, 6)); m_Vehicles[sharkie].MaxSpeed = 80; m_intSharkieID = m_Vehicles[sharkie].ID(); setNextPursuitTarget(); for (int a = 0; a < SteerParams.Instance.NumAgents - 1; ++a) { m_Vehicles[a].Steering().EvadeOn(m_Vehicles[sharkie]); } GameWorld.Instance.Agents = m_Vehicles; GameWorld.Instance.Walls = m_Walls; GameWorld.Instance.Obstacles = m_Obstacles; GameWorld.Instance.CellSpaces = m_pCellSpace; }
public void NonPenetrationContraint(MovingEntity v) { MovingEntity.EnforceNonPenetrationConstraint(v, m_Agents); }
public void NonPenetrationContraint(MovingEntity v) { MovingEntity.EnforceNonPenetrationConstraint(v, m_Agents); }
public void PursuitOn(MovingEntity v) { m_iFlags |= (int)behavior_type.pursuit; m_pTargetAgent1 = v; }
public void InterposeOn(MovingEntity v1, MovingEntity v2) { m_iFlags |= (int)behavior_type.interpose; m_pTargetAgent1 = v1; m_pTargetAgent2 = v2; }
//----------------------- AddEntity -------------------------------------- // // Used to add the entitys to the data structure //------------------------------------------------------------------------ public void AddEntity(MovingEntity ent) { Debug.Assert(ent != null); int NewIdx = PositionToIndex(ent.Pos); m_Cells[NewIdx].Members.Add(ent); ent.OldCellID = NewIdx; }
public void OffsetPursuitOn(MovingEntity v1, Vector2D offset) { m_iFlags |= (int)behavior_type.offset_pursuit; m_vOffset = offset; m_pTargetAgent1 = v1; }
//----------------------- UpdateEntity ----------------------------------- // // Checks to see if an entity has moved cells. If so the data structure // is updated accordingly //------------------------------------------------------------------------ public void UpdateEntity(MovingEntity ent) { Debug.Assert(ent != null); int NewIdx = PositionToIndex(ent.Pos); int OldIdx = ent.OldCellID; if (NewIdx == OldIdx) return; //the entity has moved into another cell so delete from current cell //and add to new one m_Cells[NewIdx].Members.Add(ent); m_Cells[OldIdx].Members.Remove(ent); ent.OldCellID = NewIdx; }
//----------------------------- Evade ------------------------------------ // // similar to pursuit except the agent Flees from the estimated future // position of the pursuer //------------------------------------------------------------------------ public Vector2D Evade(MovingEntity pursuer) { /* Not necessary to include the check for facing direction this time */ Vector2D ToPursuer = (pursuer.Pos - m_parentMovingEntity.Pos); //uncomment the following two lines to have Evade only consider pursuers //within a 'threat range' double ThreatRange = 100.0; if (ToPursuer.LengthSq() > ThreatRange * ThreatRange) return new Vector2D(0.0, 0.0); //the lookahead time is propotional to the distance between the pursuer //and the pursuer; and is inversely proportional to the sum of the //agents' velocities double LookAheadTime = ToPursuer.Length() / (m_parentMovingEntity.MaxSpeed + pursuer.Speed()); //now flee away from predicted future position of the pursuer return Flee(pursuer.Pos + pursuer.Velocity * LookAheadTime); }
public SteeringBehavior(MovingEntity agent) { m_parentMovingEntity = agent; m_iFlags = 0; m_dDBoxLength = SteerParams.Instance.MinDetectionBoxLength; m_dWeightCohesion = SteerParams.Instance.AppliedCohesionWeight(); m_dWeightAlignment = SteerParams.Instance.AppliedAlignmentWeight(); m_dWeightSeparation = SteerParams.Instance.AppliedSeparationWeight(); m_dWeightObstacleAvoidance = SteerParams.Instance.AppliedObstacleAvoidanceWeight(); m_dWeightWander = SteerParams.Instance.AppliedWanderWeight(); m_dWeightWallAvoidance = SteerParams.Instance.AppliedWallAvoidanceWeight(); m_dViewDistance = SteerParams.Instance.ViewDistance; m_dWallDetectionFeelerLength = SteerParams.Instance.WallDetectionFeelerLength; m_Feelers = new List<Vector2D>(3); m_Deceleration = Deceleration.normal; m_pTargetAgent1 = null; m_pTargetAgent2 = null; m_dWanderDistance = WanderDist; m_dWanderJitter = WanderJitterPerSec; m_dWanderRadius = WanderRad; m_dWaypointSeekDistSq = WaypointSeekDist * WaypointSeekDist; m_dWeightSeek = SteerParams.Instance.AppliedSeekWeight(); m_dWeightFlee = SteerParams.Instance.AppliedFleeWeight(); m_dWeightArrive = SteerParams.Instance.AppliedArriveWeight(); m_dWeightPursuit = SteerParams.Instance.AppliedPursuitWeight(); m_dWeightOffsetPursuit = SteerParams.Instance.AppliedOffsetPursuitWeight(); m_dWeightInterpose = SteerParams.Instance.AppliedInterposeWeight(); m_dWeightHide = SteerParams.Instance.AppliedHideWeight(); m_dWeightEvade = SteerParams.Instance.AppliedEvadeWeight(); m_dWeightFollowPath = SteerParams.Instance.AppliedFollowPathWeight(); m_SummingMethod = summing_method.prioritized; //stuff for the wander behavior double theta = Utils.RandFloat() * Utils.TwoPi; //create a vector to a target position on the wander circle m_vWanderTarget = new Vector2D(m_dWanderRadius * Math.Cos(theta), m_dWanderRadius * Math.Sin(theta)); //create a Path m_pPath = new Path2D(true); m_vSteeringForce = new Vector2D(); }