示例#1
0
        //----------------------- 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;
        }
示例#2
0
 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);
 }
示例#3
0
        //----------------------- 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;
        }
示例#4
0
 public void SetTargetAgent2(MovingEntity Agent) { m_pTargetAgent2 = Agent; }
示例#5
0
        //------------------------- 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);
        }
示例#6
0
        //--------------------------- 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);
        }
示例#7
0
        //--------------------------- 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);
        }
示例#8
0
        //------------------------------ 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);
        }
示例#9
0
 public void HideOn(MovingEntity v) { m_iFlags |= (int)behavior_type.hide; m_pTargetAgent1 = v; }
示例#10
0
        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);
        }
示例#11
0
        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]);
        }
示例#12
0
        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;
        }
示例#13
0
 public void NonPenetrationContraint(MovingEntity v)
 {
     MovingEntity.EnforceNonPenetrationConstraint(v, m_Agents);
 }
示例#14
0
 public void NonPenetrationContraint(MovingEntity v) { MovingEntity.EnforceNonPenetrationConstraint(v, m_Agents); }
示例#15
0
 public void PursuitOn(MovingEntity v) { m_iFlags |= (int)behavior_type.pursuit; m_pTargetAgent1 = v; }
示例#16
0
 public void InterposeOn(MovingEntity v1, MovingEntity v2) { m_iFlags |= (int)behavior_type.interpose; m_pTargetAgent1 = v1; m_pTargetAgent2 = v2; }
示例#17
0
        //----------------------- 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;
        }
示例#18
0
 public void OffsetPursuitOn(MovingEntity v1, Vector2D offset) { m_iFlags |= (int)behavior_type.offset_pursuit; m_vOffset = offset; m_pTargetAgent1 = v1; }
示例#19
0
        //----------------------- 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;
        }
示例#20
0
        //----------------------------- 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);
        }
示例#21
0
        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();

        }