示例#1
0
        public MovingEntity(Vector2D position,
                double      radius,
                Vector2D    velocity,
                double      max_speed,
                Vector2D    heading,
                double      mass,
                Vector2D    scale,
                double      turn_rate,
               double       max_force) : base(0, position, radius)
        {
            m_vHeading = heading;
            m_vVelocity = velocity;
            m_dMass = mass;
            m_vSide = m_vHeading.Perp();
            m_dMaxSpeed = max_speed;
            m_dMaxTurnRate = turn_rate;
            m_dMaxForce = max_force;
            m_vScale = scale;

            m_OldPos = new Vector2D();
            m_vSmoothedHeading = new Vector2D();

            m_intOldCellID = -1;

            m_pSteering = new SteeringBehavior(this);

            m_HeadingHistory = new List<Vector2D>(SteerParams.Instance.NumSamplesForSmoothing);
            m_intNextHeadingSlot = 0;
        }
示例#2
0
        public void CreateRandomPath(int   NumWaypoints,
								           double MinX,
								           double MinY,
								           double MaxX,
								           double MaxY)
        {

            m_WayPoints.Clear();

            double midX = (MaxX+MinX)/2.0;
            double midY = (MaxY+MinY)/2.0;

            double smaller = Math.Min(midX, midY);

            double spacing = Utils.TwoPi / (double)NumWaypoints;

            for (int i=0; i<NumWaypoints; ++i)
            {
                double RadialDist = Utils.RandInRange(smaller*0.2f, smaller);

                Vector2D temp = new Vector2D(RadialDist, 0.0f);

                Utils.Vec2DRotateAroundOrigin(temp, i * spacing);

                temp.X += midX; 
                temp.Y += midY;

                m_WayPoints.Add(temp);

            }            

            m_curWaypoint = m_WayPoints.GetEnumerator();
            m_curWaypoint.MoveNext(); // set the first item ready to go
        }
示例#3
0
        public Wall2D(Vector2D A, Vector2D B)
        {
            m_vA = A;
            m_vB = B;

            m_vN = new Vector2D();
            CalculateNormal();
        }
示例#4
0
        public InvertedAABBox2D(Vector2D topLeft, Vector2D bottomRight)
        {
            m_vTopLeft = topLeft; 
            m_vBottomRight = bottomRight;
            m_vCenter = (topLeft + bottomRight) * 0.5;

            m_Rectangle = new Rectangle((int)m_vTopLeft.X, (int)m_vTopLeft.Y, (int)(m_vBottomRight.X - m_vTopLeft.X), (int)(m_vBottomRight.Y - m_vTopLeft.Y));
        }
示例#5
0
 public BaseGameEntity()
 {             
     m_ID = NextValidID();
     m_dBoundingRadius=0.0;
     m_vPos = new Vector2D();
     m_vScale = new Vector2D(1.0,1.0);
     m_EntityType = default_entity_type;
     m_bTag = false;
 }
示例#6
0
 //this can be used to create an entity with a 'forced' ID. It can be used
 //when a previously created entity has been removed and deleted from the
 //game for some reason. For example, The Raven map editor uses this ctor 
 //in its undo/redo operations. 
 //USE WITH CAUTION!
 public BaseGameEntity(int entity_type, int ForcedID)
 {
     m_ID = ForcedID;
     m_dBoundingRadius = 0.0;
     m_vPos = new Vector2D();
     m_vScale = new Vector2D(1.0, 1.0);
     m_EntityType = entity_type;
     m_bTag = false;
 }
示例#7
0
 public BaseGameEntity(int entity_type, Vector2D pos, double r)
 {
     m_ID = NextValidID();
     m_dBoundingRadius = r;
     m_vPos = pos;
     m_vScale = new Vector2D(1.0, 1.0);
     m_EntityType = entity_type;
     m_bTag = false;
 }
        //given a position in the game space this method determines the relevant cell's index
        private int PositionToIndex(Vector2D pos)
        {
            int idx = (int)(m_iNumCellsX * pos.X / m_dSpaceWidth) + 
                    ((int)((m_iNumCellsY) * pos.Y / m_dSpaceHeight) * m_iNumCellsX);

            //if the entity's position is equal to vector2d(m_dSpaceWidth, m_dSpaceHeight)
            //then the index will overshoot. We need to check for this and adjust
            if (idx > m_Cells.Count - 1) idx = m_Cells.Count - 1;

            return idx;
        }
示例#9
0
        private GameWorld()
        {
            m_bPaused = false;
            m_bWrap = false;
            m_blnSmoothing = true;
            m_bCellSpaceOn = false;

            m_dTimeElapsed = 0.0;

            m_Walls = null;
            m_pCellSpace = null;
            m_Obstacles = null;
            m_Agents = null;

            m_cxClient = 0;
            m_cyClient = 0;

            m_vTargetPos = new Vector2D();
        }
示例#10
0
        //applies a 2D transformation matrix to a single Vector2D
        public void TransformVector2D(Vector2D vPoint)
        {
            double tempX = (m_Matrix._11 * vPoint.X) + (m_Matrix._21 * vPoint.Y) + (m_Matrix._31);
            double tempY = (m_Matrix._12 * vPoint.X) + (m_Matrix._22 * vPoint.Y) + (m_Matrix._32);

            vPoint.X = tempX;
            vPoint.Y = tempY;
        }
示例#11
0
        //--------------------------- Wander -------------------------------------
        //
        //  This behavior makes the agent wander about randomly
        //------------------------------------------------------------------------
        public Vector2D Wander()
        {
            //this behavior is dependent on the update rate, so this line must
            //be included when using time independent framerate.
            double JitterThisTimeSlice = m_dWanderJitter * GameWorld.Instance.getTimeElapsed();

            //first, add a small random vector to the target's position
            m_vWanderTarget += new Vector2D(Utils.RandomClamped() * JitterThisTimeSlice,
                                        Utils.RandomClamped() * JitterThisTimeSlice);

            //reproject this new vector back on to a unit circle
            m_vWanderTarget.Normalize();

            //increase the length of the vector to the same as the radius
            //of the wander circle
            m_vWanderTarget *= m_dWanderRadius;

            //move the target into a position WanderDist in front of the agent
            Vector2D target = (m_vWanderTarget + new Vector2D(m_dWanderDistance, 0));

            //project the target into world space
            Vector2D Target = (Utils.PointToWorldSpace(target,
                                                 m_parentMovingEntity.Heading(),
                                                 m_parentMovingEntity.Side(),
                                                 m_parentMovingEntity.Pos));

            //and steer towards it
            return Target - m_parentMovingEntity.Pos;
        }
示例#12
0
        //----------------------------- Flee -------------------------------------
        //
        //  Does the opposite of Seek
        //------------------------------------------------------------------------
        public Vector2D Flee(Vector2D TargetPos)
        {
            //only flee if the target is within 'panic distance'. Work in distance
            //squared space.
            /* double PanicDistanceSq = 100.0f * 100.0;
             if (Vec2DDistanceSq(m_parentMovingEntity.Pos, target) > PanicDistanceSq)
             {
               return Vector2D(0,0);
             }
             */

            Vector2D DesiredVelocity = Vector2D.Vec2DNormalize(m_parentMovingEntity.Pos - TargetPos)
                                      * m_parentMovingEntity.MaxSpeed;

            return (DesiredVelocity - m_parentMovingEntity.Velocity);
        }
示例#13
0
        //---------------------- CalculateDithered ----------------------------
        //
        //  this method sums up the active behaviors by assigning a probabilty
        //  of being calculated to each behavior. It then tests the first priority
        //  to see if it should be calcukated this simulation-step. If so, it
        //  calculates the steering force resulting from this behavior. If it is
        //  more than zero it returns the force. If zero, or if the behavior is
        //  skipped it continues onto the next priority, and so on.
        //
        //  NOTE: Not all of the behaviors have been implemented in this method,
        //        just a few, so you get the general idea
        //------------------------------------------------------------------------
        public Vector2D CalculateDithered()
        {
            //reset the steering force
            m_vSteeringForce.Zero();

            if (On(behavior_type.wall_avoidance) && Utils.RandFloat() < SteerParams.Instance.PrWallAvoidance)
            {
                m_vSteeringForce = WallAvoidance(GameWorld.Instance.Walls) *
                                     m_dWeightWallAvoidance / SteerParams.Instance.PrWallAvoidance;

                if (!m_vSteeringForce.isZero())
                {
                    m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                    return m_vSteeringForce;
                }
            }

            if (On(behavior_type.obstacle_avoidance) && Utils.RandFloat() < SteerParams.Instance.PrObstacleAvoidance)
            {
                m_vSteeringForce += ObstacleAvoidance(GameWorld.Instance.Obstacles) *
                        m_dWeightObstacleAvoidance / SteerParams.Instance.PrObstacleAvoidance;

                if (!m_vSteeringForce.isZero())
                {
                    m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                    return m_vSteeringForce;
                }
            }

            if (!GameWorld.Instance.SpacePartitioningOn)
            {
                if (On(behavior_type.separation) && Utils.RandFloat() < SteerParams.Instance.PrSeparation)
                {
                    m_vSteeringForce += Separation(GameWorld.Instance.Agents) *
                                        m_dWeightSeparation / SteerParams.Instance.PrSeparation;

                    if (!m_vSteeringForce.isZero())
                    {
                        m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                        return m_vSteeringForce;
                    }
                }
            }

            else
            {
                if (On(behavior_type.separation) && Utils.RandFloat() < SteerParams.Instance.PrSeparation)
                {
                    m_vSteeringForce += SeparationPlus(GameWorld.Instance.Agents) *
                                        m_dWeightSeparation / SteerParams.Instance.PrSeparation;

                    if (!m_vSteeringForce.isZero())
                    {
                        m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                        return m_vSteeringForce;
                    }
                }
            }


            if (On(behavior_type.flee) && Utils.RandFloat() < SteerParams.Instance.PrFlee)
            {
                Debug.Assert(!Vector2D.IsNull(GameWorld.Instance.TargetPos), "TargetPos not assigned");
                m_vSteeringForce += Flee(GameWorld.Instance.TargetPos) * m_dWeightFlee / SteerParams.Instance.PrFlee;

                if (!m_vSteeringForce.isZero())
                {
                    m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                    return m_vSteeringForce;
                }
            }

            if (On(behavior_type.evade) && Utils.RandFloat() < SteerParams.Instance.PrEvade)
            {
                Debug.Assert(m_pTargetAgent1 != null, "Evade target not assigned");

                m_vSteeringForce += Evade(m_pTargetAgent1) * m_dWeightEvade / SteerParams.Instance.PrEvade;

                if (!m_vSteeringForce.isZero())
                {
                    m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                    return m_vSteeringForce;
                }
            }


            if (!GameWorld.Instance.SpacePartitioningOn)
            {
                if (On(behavior_type.allignment) && Utils.RandFloat() < SteerParams.Instance.PrAlignment)
                {
                    m_vSteeringForce += Alignment(GameWorld.Instance.Agents) *
                                        m_dWeightAlignment / SteerParams.Instance.PrAlignment;

                    if (!m_vSteeringForce.isZero())
                    {
                        m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                        return m_vSteeringForce;
                    }
                }

                if (On(behavior_type.cohesion) && Utils.RandFloat() < SteerParams.Instance.PrCohesion)
                {
                    m_vSteeringForce += Cohesion(GameWorld.Instance.Agents) *
                                        m_dWeightCohesion / SteerParams.Instance.PrCohesion;

                    if (!m_vSteeringForce.isZero())
                    {
                        m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                        return m_vSteeringForce;
                    }
                }
            }
            else
            {
                if (On(behavior_type.allignment) && Utils.RandFloat() < SteerParams.Instance.PrAlignment)
                {
                    m_vSteeringForce += AlignmentPlus(GameWorld.Instance.Agents) *
                                        m_dWeightAlignment / SteerParams.Instance.PrAlignment;

                    if (!m_vSteeringForce.isZero())
                    {
                        m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                        return m_vSteeringForce;
                    }
                }

                if (On(behavior_type.cohesion) && Utils.RandFloat() < SteerParams.Instance.PrCohesion)
                {
                    m_vSteeringForce += CohesionPlus(GameWorld.Instance.Agents) *
                                        m_dWeightCohesion / SteerParams.Instance.PrCohesion;

                    if (!m_vSteeringForce.isZero())
                    {
                        m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                        return m_vSteeringForce;
                    }
                }
            }

            if (On(behavior_type.wander) && Utils.RandFloat() < SteerParams.Instance.PrWander)
            {
                m_vSteeringForce += Wander() * m_dWeightWander / SteerParams.Instance.PrWander;

                if (!m_vSteeringForce.isZero())
                {
                    m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                    return m_vSteeringForce;
                }
            }

            if (On(behavior_type.seek) && Utils.RandFloat() < SteerParams.Instance.PrSeek)
            {
                Debug.Assert(!Vector2D.IsNull(GameWorld.Instance.TargetPos), "TargetPos not assigned");
                m_vSteeringForce += Seek(GameWorld.Instance.TargetPos) * m_dWeightSeek / SteerParams.Instance.PrSeek;

                if (!m_vSteeringForce.isZero())
                {
                    m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                    return m_vSteeringForce;
                }
            }

            if (On(behavior_type.arrive) && Utils.RandFloat() < SteerParams.Instance.PrArrive)
            {
                Debug.Assert(!Vector2D.IsNull(GameWorld.Instance.TargetPos), "TargetPos not assigned");
                m_vSteeringForce += Arrive(GameWorld.Instance.TargetPos, (int)m_Deceleration) *
                                    m_dWeightArrive / SteerParams.Instance.PrArrive;

                if (!m_vSteeringForce.isZero())
                {
                    m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

                    return m_vSteeringForce;
                }
            }

            return m_vSteeringForce;
        }
示例#14
0
        //--------------------- AccumulateForce ----------------------------------
        //
        //  This function calculates how much of its max steering force the 
        //  vehicle has left to apply and then applies that amount of the
        //  force to add.
        //------------------------------------------------------------------------
        public bool AccumulateForce(ref Vector2D RunningTot, Vector2D ForceToAdd)
        {

            //calculate how much steering force the vehicle has used so far
            double MagnitudeSoFar = RunningTot.Length();

            //calculate how much steering force remains to be used by this vehicle
            double MagnitudeRemaining = m_parentMovingEntity.MaxForce - MagnitudeSoFar;

            //return false if there is no more force left to use
            if (MagnitudeRemaining <= 0.0) return false;

            //calculate the magnitude of the force we want to add
            double MagnitudeToAdd = ForceToAdd.Length();

            //if the magnitude of the sum of ForceToAdd and the running total
            //does not exceed the maximum force available to this vehicle, just
            //add together. Otherwise add as much of the ForceToAdd vector is
            //possible without going over the max.
            if (MagnitudeToAdd < MagnitudeRemaining)
            {
                RunningTot += ForceToAdd;
            }
            else
            {
                //add it to the steering force
                RunningTot += (Vector2D.Vec2DNormalize(ForceToAdd) * MagnitudeRemaining);
            }

            return true;
        }
示例#15
0
        //-------------------------------- Cohesion ------------------------------
        //
        //  returns a steering force that attempts to move the agent towards the
        //  center of mass of the agents in its immediate area
        //------------------------------------------------------------------------
        public Vector2D Cohesion(List<MovingEntity> neighbors)
        {
            //first find the center of mass of all the agents
            Vector2D CenterOfMass = new Vector2D(0.0, 0.0);
            Vector2D SteeringForce = new Vector2D(0.0, 0.0);

            int NeighborCount = 0;

            //iterate through the neighbors and sum up all the position vectors
            foreach (MovingEntity neighbor in neighbors)
            {
                //make sure *this* agent isn't included in the calculations and that
                //the agent being examined is close enough ***also make sure it doesn't
                //include the evade target ***
                if ((neighbor != m_parentMovingEntity) && neighbor.IsTagged() &&
                  (neighbor != m_pTargetAgent1))
                {
                    CenterOfMass += neighbor.Pos;

                    ++NeighborCount;
                }
            }

            if (NeighborCount > 0)
            {
                //the center of mass is the average of the sum of positions
                CenterOfMass /= (double)NeighborCount;

                //now seek towards that position
                SteeringForce = Seek(CenterOfMass);
            }

            //the magnitude of cohesion is usually much larger than separation or
            //allignment so it usually helps to normalize it.
            return Vector2D.Vec2DNormalize(SteeringForce);
        }
示例#16
0
 public void OffsetPursuitOn(MovingEntity v1, Vector2D offset) { m_iFlags |= (int)behavior_type.offset_pursuit; m_vOffset = offset; m_pTargetAgent1 = v1; }
示例#17
0
        //----------------------- Calculate --------------------------------------
        //
        //  calculates the accumulated steering force according to the method set
        //  in m_SummingMethod
        //------------------------------------------------------------------------
        public Vector2D Calculate()
        {
            //reset the steering force
            m_vSteeringForce.Zero();

            //use space partitioning to calculate the neighbours of this vehicle
            //if switched on. If not, use the standard tagging system
            if (!GameWorld.Instance.SpacePartitioningOn)
            {
                //tag neighbors if any of the following 3 group behaviors are switched on
                if (On(behavior_type.separation) || On(behavior_type.allignment) || On(behavior_type.cohesion))
                {
                    GameWorld.Instance.TagAgentsWithinViewRange(m_parentMovingEntity, m_dViewDistance);
                }
            }
            else
            {
                //calculate neighbours in cell-space if any of the following 3 group
                //behaviors are switched on
                if (On(behavior_type.separation) || On(behavior_type.allignment) || On(behavior_type.cohesion))
                {
                    GameWorld.Instance.CellSpaces.CalculateNeighbors(m_parentMovingEntity.Pos, m_dViewDistance);
                }
            }

            switch (m_SummingMethod)
            {
                case summing_method.weighted_average:

                    m_vSteeringForce = CalculateWeightedSum(); break;

                case summing_method.prioritized:

                    m_vSteeringForce = CalculatePrioritized(); break;

                case summing_method.dithered:

                    m_vSteeringForce = CalculateDithered(); break;

                default:

                    m_vSteeringForce = new Vector2D(0, 0); break;

            }//end switch

            return m_vSteeringForce;
        }
示例#18
0
        /* NOTE: the next three behaviors are the same as the above three, except
                  that they use a cell-space partition to find the neighbors
        */


        //---------------------------- Separation --------------------------------
        //
        // this calculates a force repelling from the other neighbors
        //
        //  USES SPACIAL PARTITIONING
        //------------------------------------------------------------------------
        public Vector2D SeparationPlus(List<MovingEntity> neighbors)
        {
            Vector2D SteeringForce = new Vector2D(0.0, 0.0);

            //iterate through the neighbors and sum up all the position vectors
            foreach (MovingEntity pV in GameWorld.Instance.CellSpaces.ListOfNeighbours())
            {
                //make sure this agent isn't included in the calculations and that
                //the agent being examined is close enough
                if (pV != m_parentMovingEntity)
                {
                    Vector2D ToAgent = (m_parentMovingEntity.Pos - pV.Pos);

                    //scale the force inversely proportional to the agents distance  
                    //from its neighbor.
                    SteeringForce += Vector2D.Vec2DNormalize(ToAgent) / ToAgent.Length();
                }

            }

            return SteeringForce;
        }
示例#19
0
        //---------------------- CalculateWeightedSum ----------------------------
        //
        //  this simply sums up all the active behaviors X their weights and 
        //  truncates the result to the max available steering force before 
        //  returning
        //------------------------------------------------------------------------
        public Vector2D CalculateWeightedSum()
        {
            if (On(behavior_type.wall_avoidance))
            {
                m_vSteeringForce += WallAvoidance(GameWorld.Instance.Walls) * m_dWeightWallAvoidance;
            }

            if (On(behavior_type.obstacle_avoidance))
            {
                m_vSteeringForce += ObstacleAvoidance(GameWorld.Instance.Obstacles) * m_dWeightObstacleAvoidance;
            }

            if (On(behavior_type.evade))
            {
                Debug.Assert(m_pTargetAgent1 != null, "Evade target not assigned");

                m_vSteeringForce += Evade(m_pTargetAgent1) * m_dWeightEvade;
            }

            //these next three can be combined for flocking behavior (wander is
            //also a good behavior to add into this mix)
            if (!GameWorld.Instance.SpacePartitioningOn)
            {
                if (On(behavior_type.separation))
                {
                    m_vSteeringForce += Separation(GameWorld.Instance.Agents) * m_dWeightSeparation;
                }

                if (On(behavior_type.allignment))
                {
                    m_vSteeringForce += Alignment(GameWorld.Instance.Agents) * m_dWeightAlignment;
                }

                if (On(behavior_type.cohesion))
                {
                    m_vSteeringForce += Cohesion(GameWorld.Instance.Agents) * m_dWeightCohesion;
                }
            }
            else
            {
                if (On(behavior_type.separation))
                {
                    m_vSteeringForce += SeparationPlus(GameWorld.Instance.Agents) * m_dWeightSeparation;
                }

                if (On(behavior_type.allignment))
                {
                    m_vSteeringForce += AlignmentPlus(GameWorld.Instance.Agents) * m_dWeightAlignment;
                }

                if (On(behavior_type.cohesion))
                {
                    m_vSteeringForce += CohesionPlus(GameWorld.Instance.Agents) * m_dWeightCohesion;
                }
            }

            if (On(behavior_type.wander))
            {
                m_vSteeringForce += Wander() * m_dWeightWander;
            }

            if (On(behavior_type.seek))
            {
                Debug.Assert(!Vector2D.IsNull(GameWorld.Instance.TargetPos), "TargetPos not assigned");
                m_vSteeringForce += Seek(GameWorld.Instance.TargetPos) * m_dWeightSeek;
            }

            if (On(behavior_type.flee))
            {
                Debug.Assert(!Vector2D.IsNull(GameWorld.Instance.TargetPos), "TargetPos not assigned");
                m_vSteeringForce += Flee(GameWorld.Instance.TargetPos) * m_dWeightFlee;
            }

            if (On(behavior_type.arrive))
            {
                Debug.Assert(!Vector2D.IsNull(GameWorld.Instance.TargetPos), "TargetPos not assigned");
                m_vSteeringForce += Arrive(GameWorld.Instance.TargetPos, (int)m_Deceleration) * m_dWeightArrive;
            }

            if (On(behavior_type.pursuit))
            {
                Debug.Assert(m_pTargetAgent1 != null, "pursuit target not assigned");

                m_vSteeringForce += Pursuit(m_pTargetAgent1) * m_dWeightPursuit;
            }

            if (On(behavior_type.offset_pursuit))
            {
                Debug.Assert(m_pTargetAgent1 != null, "pursuit target not assigned");
                Debug.Assert(!Vector2D.IsNull(m_vOffset), "No offset assigned");

                m_vSteeringForce += OffsetPursuit(m_pTargetAgent1, m_vOffset) * m_dWeightOffsetPursuit;
            }

            if (On(behavior_type.interpose))
            {
                Debug.Assert(m_pTargetAgent1 != null && m_pTargetAgent2 != null, "Interpose agents not assigned");

                m_vSteeringForce += Interpose(m_pTargetAgent1, m_pTargetAgent2) * m_dWeightInterpose;
            }

            if (On(behavior_type.hide))
            {
                Debug.Assert(m_pTargetAgent1 != null, "Hide target not assigned");

                m_vSteeringForce += Hide(m_pTargetAgent1, GameWorld.Instance.Obstacles) * m_dWeightHide;
            }

            if (On(behavior_type.follow_path))
            {
                m_vSteeringForce += FollowPath() * m_dWeightFollowPath;
            }

            m_vSteeringForce.Truncate(m_parentMovingEntity.MaxForce);

            return m_vSteeringForce;
        }
示例#20
0
        //---------------------------- Alignment ---------------------------------
        //
        //  returns a force that attempts to align this agents heading with that
        //  of its neighbors
        //
        //  USES SPACIAL PARTITIONING
        //------------------------------------------------------------------------
        public Vector2D AlignmentPlus(List<MovingEntity> neighbors)
        {
            //This will record the average heading of the neighbors
            Vector2D AverageHeading = new Vector2D();

            //This count the number of vehicles in the neighborhood
            double NeighborCount = 0.0;

            //iterate through the neighbors and sum up all the position vectors
            foreach (MovingEntity pV in GameWorld.Instance.CellSpaces.ListOfNeighbours())
            {
                //make sure *this* agent isn't included in the calculations and that
                //the agent being examined  is close enough
                if (pV != m_parentMovingEntity)
                {
                    AverageHeading += pV.Heading();

                    ++NeighborCount;
                }

            }

            //if the neighborhood contained one or more vehicles, average their
            //heading vectors.
            if (NeighborCount > 0.0)
            {
                AverageHeading /= NeighborCount;

                AverageHeading -= m_parentMovingEntity.Heading();
            }

            return AverageHeading;
        }
示例#21
0
        /////////////////////////////////////////////////////////////////////////////// START OF BEHAVIORS

        //------------------------------- Seek -----------------------------------
        //
        //  Given a target, this behavior returns a steering force which will
        //  direct the agent towards the target
        //------------------------------------------------------------------------
        public Vector2D Seek(Vector2D TargetPos)
        {
            Vector2D DesiredVelocity = Vector2D.Vec2DNormalize(TargetPos - m_parentMovingEntity.Pos)
                                      * m_parentMovingEntity.MaxSpeed;

            return (DesiredVelocity - m_parentMovingEntity.Velocity);
        }
示例#22
0
        //-------------------------------- Cohesion ------------------------------
        //
        //  returns a steering force that attempts to move the agent towards the
        //  center of mass of the agents in its immediate area
        //
        //  USES SPACIAL PARTITIONING
        //------------------------------------------------------------------------
        public Vector2D CohesionPlus(List<MovingEntity> neighbors)
        {
            //first find the center of mass of all the agents
            Vector2D CenterOfMass = new Vector2D();
            Vector2D SteeringForce = new Vector2D();

            int NeighborCount = 0;

            //iterate through the neighbors and sum up all the position vectors
            foreach (MovingEntity pV in GameWorld.Instance.CellSpaces.ListOfNeighbours())
            {
                //make sure *this* agent isn't included in the calculations and that
                //the agent being examined is close enough
                if (pV != m_parentMovingEntity)
                {
                    CenterOfMass += pV.Pos;

                    ++NeighborCount;
                }
            }

            if (NeighborCount > 0)
            {
                //the center of mass is the average of the sum of positions
                CenterOfMass /= (double)NeighborCount;

                //now seek towards that position
                SteeringForce = Seek(CenterOfMass);
            }

            //the magnitude of cohesion is usually much larger than separation or
            //allignment so it usually helps to normalize it.
            return Vector2D.Vec2DNormalize(SteeringForce);
        }
示例#23
0
        //--------------------------- Arrive -------------------------------------
        //
        //  This behavior is similar to seek but it attempts to arrive at the
        //  target with a zero velocity
        //------------------------------------------------------------------------
        public Vector2D Arrive(Vector2D TargetPos, int decelerationStep)
        {
            Vector2D ToTarget = TargetPos - m_parentMovingEntity.Pos;

            //calculate the distance to the target
            double dist = ToTarget.Length();

            if (dist > 0)
            {
                //because Deceleration is enumerated as an int, this value is required
                //to provide fine tweaking of the deceleration..
                double DecelerationTweaker = 0.3;

                //calculate the speed required to reach the target given the desired
                //deceleration
                double speed = dist / ((double)decelerationStep * DecelerationTweaker);

                //make sure the velocity does not exceed the max
                speed = Math.Min(speed, m_parentMovingEntity.MaxSpeed);

                //from here proceed just like Seek except we don't need to normalize 
                //the ToTarget vector because we have already gone to the trouble
                //of calculating its length: dist. 
                Vector2D DesiredVelocity = (ToTarget * speed / dist);

                return (DesiredVelocity - m_parentMovingEntity.Velocity);
            }

            return new Vector2D(0, 0);
        }
示例#24
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);
        }
示例#25
0
 public Wall2D()
 {
     m_vN = new Vector2D();
 }
示例#26
0
        //------------------------- GetHidingPosition ----------------------------
        //
        //  Given the position of a hunter, and the position and radius of
        //  an obstacle, this method calculates a position DistanceFromBoundary 
        //  away from its bounding radius and directly opposite the hunter
        //------------------------------------------------------------------------
        public Vector2D GetHidingPosition(Vector2D posOb, double radiusOb, Vector2D posHunter)
        {
            //calculate how far away the agent is to be from the chosen obstacle's
            //bounding radius
            double DistanceFromBoundary = 30.0;
            double DistAway = radiusOb + DistanceFromBoundary;

            //calculate the heading toward the object from the hunter
            Vector2D ToOb = Vector2D.Vec2DNormalize(posOb - posHunter);

            //scale it to size and add to the obstacles position to get
            //the hiding spot.
            return (ToOb * DistAway) + posOb;
        }
示例#27
0
 public Wall2D(Vector2D A, Vector2D B, Vector2D N)
 { 
     m_vA = A;
     m_vB = B;
     m_vN = N;
 }        
示例#28
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);
        }
示例#29
0
        //create a rotation matrix from a 2D vector
        public void Rotate(Vector2D fwd, Vector2D side)
        {
            Matrix mat = new Matrix();

            mat._11 = fwd.X;  
            mat._12 = fwd.Y; 
            mat._13 = 0;
            mat._21 = side.X; 
            mat._22 = side.Y; 
            mat._23 = 0;
            mat._31 = 0; 
            mat._32 = 0;
            mat._33 = 1;

            //and multiply
            MatrixMultiply(mat);
        }
示例#30
0
 public void SetOffset(Vector2D offset) { m_vOffset = offset; }