Example #1
0
        public void Update(float dt)
        {
            Position = entity.Position;
            Rotation = entity.Orientation;
            //Check out distance from the node at the front of the pathway
            float NodeDistance = Vector3.Distance(entity.Position, EntityPath[0].NodeLocation);

            //Once we are close enough to the next node, then we remove it from the list and proceed to the next one
            if (NodeDistance <= 0.05f)
            {
                //If we have reached the final node in the path, then we want to calculate a new path back were we just came from
                if (EntityPath.Count == 1)
                {
                    if (PreviousTargetNode == EndNode)
                    {
                        EntityPath         = AStarSearch.FindPath(EndNode, StartNode, new Vector2(9, 9));
                        PreviousTargetNode = StartNode;
                    }
                    else
                    {
                        EntityPath         = AStarSearch.FindPath(StartNode, EndNode, new Vector2(9, 9));
                        PreviousTargetNode = EndNode;
                    }
                }
                //Otherwise we remove this node from the list and move to the next one
                EntityPath.Remove(EntityPath[0]);
            }
            //Continue on towards out current target
            pathTime            += Globals.space.TimeStepSettings.TimeStepDuration;
            mover.TargetPosition = EntityPath[0].NodeLocation;
        }
Example #2
0
        public static List <NavMeshNode> GetNeighbours(NavMeshNode TargetNode, Vector2 MeshSize, bool IncludeDiagonals)
        {
            Vector2            TargetNodeLocation = TargetNode.NodeIndex;
            List <NavMeshNode> Neighbours         = new List <NavMeshNode>();

            //north neighbour
            if (TargetNodeLocation.Y + 1 < MeshSize.Y)
            {
                Neighbours.Add(MeshDictionary[new Vector2(TargetNodeLocation.X, TargetNodeLocation.Y + 1)]);
            }
            //east
            if (TargetNodeLocation.X + 1 < MeshSize.X)
            {
                Neighbours.Add(MeshDictionary[new Vector2(TargetNodeLocation.X + 1, TargetNodeLocation.Y)]);
            }
            //south
            if (TargetNodeLocation.Y - 1 > 0)
            {
                Neighbours.Add(MeshDictionary[new Vector2(TargetNodeLocation.X, TargetNodeLocation.Y - 1)]);
            }
            //west
            if (TargetNodeLocation.X - 1 > 0)
            {
                Neighbours.Add(MeshDictionary[new Vector2(TargetNodeLocation.X - 1, TargetNodeLocation.Y)]);
            }

            if (IncludeDiagonals)
            {
                //North-East
                if (TargetNodeLocation.Y + 1 < MeshSize.Y && TargetNodeLocation.X + 1 < MeshSize.X)
                {
                    Neighbours.Add(MeshDictionary[new Vector2(TargetNodeLocation.X + 1, TargetNodeLocation.Y + 1)]);
                }
                //South-East
                if (TargetNodeLocation.X + 1 < MeshSize.X && TargetNodeLocation.Y - 1 > 0)
                {
                    Neighbours.Add(MeshDictionary[new Vector2(TargetNodeLocation.X + 1, TargetNodeLocation.Y - 1)]);
                }
                //South-West
                if (TargetNodeLocation.X - 1 > 0 && TargetNodeLocation.Y - 1 > 0)
                {
                    Neighbours.Add(MeshDictionary[new Vector2(TargetNodeLocation.X - 1, TargetNodeLocation.Y - 1)]);
                }
                //North-West
                if (TargetNodeLocation.X - 1 > 0 && TargetNodeLocation.Y + 1 < MeshSize.Y)
                {
                    Neighbours.Add(MeshDictionary[new Vector2(TargetNodeLocation.X - 1, TargetNodeLocation.Y + 1)]);
                }
            }

            return(Neighbours);
        }
Example #3
0
        //Returns whatever nav mesh node is the closest to the target location
        public static NavMeshNode GetNearbyMeshNode(Vector3 NodeLocation)
        {
            NavMeshNode NearbyNode   = MeshNodes[0];
            float       NodeDistance = Vector3.Distance(NearbyNode.NodeLocation, NodeLocation);

            for (int i = 1; i < MeshNodes.Count; i++)
            {
                NavMeshNode NodeCompare     = MeshNodes[i];
                float       CompareDistance = Vector3.Distance(NodeCompare.NodeLocation, NodeLocation);
                if (CompareDistance < NodeDistance)
                {
                    NearbyNode   = NodeCompare;
                    NodeDistance = CompareDistance;
                }
            }
            return(NearbyNode);
        }
Example #4
0
        public static NavMeshNode GetCurrentNode(List <NavMeshNode> OpenSet)
        {
            NavMeshNode CurrentNode   = OpenSet[0];
            float       CurrentFScore = CurrentNode.FScore;

            for (int i = 1; i < OpenSet.Count; i++)
            {
                NavMeshNode CompareNode   = OpenSet[i];
                float       CompareFScore = CompareNode.FScore;
                //We are trying to find which node has the lowest FScore value
                if (CompareFScore < CurrentFScore)
                {
                    CurrentNode   = CompareNode;
                    CurrentFScore = CompareFScore;
                }
            }
            return(CurrentNode);
        }
Example #5
0
        public FSMEntity(Vector3 StartPosition, Vector3 EndPosition)
        {
            StartNode          = NavMeshNodes.GetNearbyMeshNode(StartPosition);
            EndNode            = NavMeshNodes.GetNearbyMeshNode(EndPosition);
            EntityPath         = AStarSearch.FindPath(StartNode, EndNode, new Vector2(9, 9));
            PreviousTargetNode = EndNode;

            Position        = StartPosition;
            entity          = new Entity(new Box(StartPosition, 1, 1, 1, 1).CollisionInformation, 1);
            entity.Position = StartPosition;
            Globals.space.Add(entity);
            Globals.game.ModelDrawer.Add(entity);

            mover   = new EntityMover(entity);
            rotator = new EntityRotator(entity);
            Globals.space.Add(mover);
            Globals.space.Add(rotator);
        }
Example #6
0
 public static void AddNode(NavMeshNode Node, Vector2 Index)
 {
     MeshDictionary.Add(Index, Node);
 }
Example #7
0
        public static List <NavMeshNode> FindPath(NavMeshNode StartNode, NavMeshNode EndNode, Vector2 NavMeshSize)
        {
            //Initialize the Open and Closed sets
            ClosedSet = new List <NavMeshNode>();
            OpenSet   = new List <NavMeshNode>();
            OpenSet.Add(StartNode);
            //Reset nodes CameFrom references in preperation for finding our new pathway
            NavMeshDictionary.ResetPathfinding();
            //Cost of travelling from the start node to the start node is 0
            StartNode.GScore = 0;
            //The FScore for the starting node should be completely heuristic
            StartNode.FScore = Vector3.Distance(StartNode.NodeLocation, EndNode.NodeLocation);

            //Iterate over the OpenSet until there are no more nodes left to evaluate
            while (OpenSet.Count > 0)
            {
                //The current node each time will be the node in OpenSet with the lowest FScore
                NavMeshNode CurrentNode = GetCurrentNode(OpenSet);

                //If this is the end node then the path is ready
                if (CurrentNode == EndNode)
                {
                    //When the path is found, we start at the end node, and keep following back each nodes CameFrom reference, until we end up at the start node
                    List <NavMeshNode> FinishedPath = new List <NavMeshNode>();
                    FinishedPath.Add(EndNode);
                    NavMeshNode PathNode = EndNode;
                    while (PathNode != StartNode)
                    {
                        PathNode = PathNode.CameFrom;
                        FinishedPath.Add(PathNode);
                    }
                    FinishedPath.Add(StartNode);
                    FinishedPath.Reverse();
                    return(FinishedPath);
                }

                //Move the current node over to the closed set
                OpenSet.Remove(CurrentNode);
                ClosedSet.Add(CurrentNode);

                //Find all of the current nodes neighbours
                List <NavMeshNode> CurrentNeighbours = NavMeshDictionary.GetNeighbours(CurrentNode, new Vector2(9, 9), true);
                for (int i = 0; i < CurrentNeighbours.Count; i++)
                {
                    //Check through all of them
                    NavMeshNode CurrentNeighbour = CurrentNeighbours[i];

                    //Ignore neighbours in the closed set as they have already been evaluated
                    if (ClosedSet.Contains(CurrentNeighbour))
                    {
                        continue;
                    }

                    //Calculate the distance from start to this neighbour
                    float TentativeGScore = CurrentNode.GScore + Vector3.Distance(CurrentNode.NodeLocation, CurrentNeighbour.NodeLocation);

                    //Add all newly discovered nodes into the open set
                    if (!OpenSet.Contains(CurrentNeighbour))
                    {
                        OpenSet.Add(CurrentNeighbour);
                    }
                    //make sure this node isnt more expensive to travel from
                    else if (TentativeGScore >= CurrentNeighbour.GScore)
                    {
                        continue;
                    }

                    //If we get this far the current neighbour has been found to be the cheapest node to travel from
                    CurrentNeighbour.CameFrom = CurrentNode;
                    CurrentNeighbour.GScore   = TentativeGScore;
                    CurrentNeighbour.FScore   = CurrentNeighbour.GScore + Vector3.Distance(CurrentNeighbour.NodeLocation, EndNode.NodeLocation);
                }
            }

            return(new List <NavMeshNode>());
        }
Example #8
0
        protected override void Update(GameTime gameTime)
        {
            PreviousKeyboardInput = KeyboardInput;
            KeyboardInput         = Keyboard.GetState();
            var dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

            PreviousMouseInput = MouseInput;
            MouseInput         = Mouse.GetState();

            //Keep the mouse within the screen
            if (!IsMouseVisible)
            {
                Mouse.SetPosition(200, 200);
            }

            //Allow quit with escape key
            if (KeyboardInput.IsKeyDown(Keys.Escape))
            {
                Exit();
            }

            //Display camera location and facing direction with F1
            if (WasKeyPressed(Keys.F1))
            {
                Vector3 CameraPosition = ServerSimulation.ServerCamera.Camera.Position;
                Console.WriteLine("Cam: " + CameraPosition);
            }

            ////raycast down to find terrain location
            //if (WasKeyPressed(Keys.F2))
            //{
            //    //Get the fox entity that we want to raycast from
            //    ServerEntity Fox = EntityManager.GetServerEntity("PrincessFox");
            //    Console.WriteLine("Fox is at " + Fox.entity.Position);
            //    Vector3 RaycastOrigin = Fox.entity.Position;
            //    Vector3 RaycastDirection = Vector3.Down;
            //    RayCastResult Results;
            //    bool RaycastHitSomething = Globals.space.RayCast(new Ray(RaycastOrigin, RaycastDirection), 10000, out Results);
            //    Vector3 HitLocation = Results.HitData.Location;
            //    Console.WriteLine("Ground raycast hit at " + HitLocation);
            //    Vector3[] TVerts = Globals.TerrainVerts;
            //    Console.WriteLine(TVerts.Length + " verts in the terrain");

            //    //Sort through the list of nav mesh node locations that we loaded from the terrain meshes vertex data
            //    for (int i = 0; i < TVerts.Length; i++)
            //    {
            //        //Make sure locations are unique before adding new
            //        if (!NavMeshManager.IsNodeLocationAvailable(TVerts[i]))
            //            continue;

            //        float VertDistance;
            //        if (i < TVerts.Length - 1)
            //            VertDistance = Vector3.Distance(TVerts[i], TVerts[i + 1]);
            //        else
            //            VertDistance = Vector3.Distance(TVerts[i], TVerts[i - 1]);
            //        //Check the location of each vertex to see if we should place a new nav mesh node here or not
            //        Vector3 NodeLocation = TVerts[i];
            //        NavMeshManager.AddNewNode(NodeLocation);

            //    }

            //    //Map all the nodes into the dictionary by their index in the navmesh
            //    List<NavMeshNode> NodeList = NavMeshManager.GetNodeList();
            //    //Dictionary<Vector2, NavMeshNode> NavMeshNodes = new Dictionary<Vector2, NavMeshNode>();

            //    //Add the first column of nav mesh nodes
            //    for (int i = 1; i < 10; i++)
            //    {
            //        Vector2 NavMeshIndex = new Vector2(i, 1);
            //        int MeshNodeIndex = (i - 1) * 2;
            //        NavMeshNode MeshNode = NodeList[MeshNodeIndex];
            //        MeshNode.NodeIndex = NavMeshIndex;
            //        NavMeshManager.AddNode(NavMeshIndex, MeshNode);
            //    }
            //    //Then add the second column of nodes
            //    int CurrentNodeIndex = 1;
            //    for (int i = 1; i < 10; i++)
            //    {
            //        Vector2 NavMeshIndex = new Vector2(i, 2);
            //        int MeshNodeIndex = CurrentNodeIndex;
            //        CurrentNodeIndex += 2;
            //        NavMeshNode MeshNode = NodeList[MeshNodeIndex];
            //        MeshNode.NodeIndex = NavMeshIndex;
            //        NavMeshManager.AddNode(NavMeshIndex, MeshNode);
            //    }
            //    //Now add the rest of the columns (columns 3-9)
            //    int NodeListIndex = 18;
            //    for (int CurrentColumn = 3; CurrentColumn < 10; CurrentColumn++)
            //    {
            //        for (int j = 1; j < 10; j++)
            //        {
            //            Vector2 NavMeshIndex = new Vector2(j, CurrentColumn);
            //            NavMeshNode MeshNode = NodeList[NodeListIndex];
            //            MeshNode.NodeIndex = NavMeshIndex;
            //            NodeListIndex++;
            //            NavMeshManager.AddNode(NavMeshIndex, MeshNode);
            //        }
            //    }

            //    //Get the path start and end nodes
            //    Vector2 PathStartIndex = new Vector2(3, 4);
            //    NavMeshNode PathStartNode = NavMeshManager.GetNode(PathStartIndex);
            //    //NavMeshNode PathStartNode = NavMeshNodes[PathStartIndex];
            //    Vector2 PathEndIndex = new Vector2(7, 8);
            //    //NavMeshNode PathEndNode = NavMeshNodes[PathEndIndex];
            //    NavMeshNode PathEndNode = NavMeshManager.GetNode(PathEndIndex);

            //    //Use A* Search to find a path between the start and end nodes
            //    List<NavMeshNode> NodePath = AStarSearch.FindPath(PathStartNode, PathEndNode, new Vector2(9, 9));
            //    //Assign this path to the princess fox entity, have it navigate along the path until it reaches its target

            //}

            //returns which nav mesh node in the list is closest to the given location
            NavMeshNode GetClosestNode(List <NavMeshNode> NodeList, Vector3 NodeLocation)
            {
                //Start off with the first node in the list being the closest node
                NavMeshNode ClosestNode  = NodeList[0];
                float       NodeDistance = Vector3.Distance(ClosestNode.NodeLocation, NodeLocation);

                //Compare all the others keep track of which is the closest of them all
                for (int i = 1; i < NodeList.Count; i++)
                {
                    NavMeshNode NodeCompare     = NodeList[i];
                    float       CompareDistance = Vector3.Distance(ClosestNode.NodeLocation, NodeCompare.NodeLocation);
                    if (CompareDistance < NodeDistance)
                    {
                        ClosestNode  = NodeCompare;
                        NodeDistance = CompareDistance;
                    }
                }
                return(ClosestNode);
            }

            //move fox forward
            if (WasKeyPressed(Keys.NumPad8))
            {
                ServerEntity Fox = EntityManager.GetServerEntity("PrincessFox");
            }

            //Tab toggle mouse lock
            if (WasKeyPressed(Keys.Tab))
            {
                IsMouseVisible = !IsMouseVisible;
            }

            //Toggle wireframe with G
            if (WasKeyPressed(Keys.G))
            {
                ModelDrawer.IsWireframe = !ModelDrawer.IsWireframe;
            }

            //Allow control console to do whatever it wants
            UpdateControlConsole(dt);

            //Update everything
            ServerSimulation.Update(dt);

            //Render everything
            if (displayConstraints)
            {
                ConstraintDrawer.Update();
            }
            if (displayEntities)
            {
                ModelDrawer.Update();
            }

            base.Update(gameTime);
        }
Example #9
0
 //Adds a new mesh node objects to the list
 public static void AddNode(NavMeshNode Node)
 {
     MeshNodes.Add(Node);
 }
Example #10
0
        //public ServerEntity WaypointTest;

        public WorldSimulator(WorldRenderer game)
        {
            Game           = game;
            parallelLooper = new ParallelLooper();
            if (Environment.ProcessorCount > 1)
            {
                for (int i = 0; i < Environment.ProcessorCount; i++)
                {
                    parallelLooper.AddThread();
                }
            }
            Globals.space             = new Space(parallelLooper);
            game.Camera.LockedUp      = Vector3.Up;
            game.Camera.ViewDirection = new Vector3(0, -1.5f, 1);
            game.Camera.Position      = new Vector3(-19.55f, 39.25f, -10.35f);
            ServerCamera = new FreeCamera(100, game.Camera, game);

            //Add some force of gravity to the simulation
            Globals.space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0);


            //Load the world terrain mesh data
            Vector3[] TerrainVertices;
            int[]     TerrainIndices;
            Model     TerrainCollision = Globals.game.Content.Load <Model>("LowDetailTerrain");

            ModelDataExtractor.GetVerticesAndIndicesFromModel(TerrainCollision, out TerrainVertices, out TerrainIndices);
            StaticMesh TerrainMesh = new StaticMesh(TerrainVertices, TerrainIndices, new AffineTransform(new Vector3(0, 0, 0)));

            Globals.TerrainVerts = TerrainVertices;
            Globals.TerrainInds  = TerrainIndices;
            Globals.space.Add(TerrainMesh);
            Globals.game.ModelDrawer.Add(TerrainMesh);

            //Create a new mesh node object for each unique location in the navigation mesh
            for (int i = 0; i < Globals.TerrainVerts.Length; i++)
            {
                //Dont create mesh nodes at locations already been used
                if (!NavMeshNodes.IsLocationAvailable(Globals.TerrainVerts[i]))
                {
                    continue;
                }

                //Add a new mesh node object to every other space in the terrain verts that we find to be available
                NavMeshNodes.AddNode(new NavMeshNode(Globals.TerrainVerts[i]));
            }

            //Now sort all of the mesh nodes into a dictionary sorted by their index in the level
            //Start with the first column of mesh nodes
            for (int i = 1; i < 10; i++)
            {
                Vector2     MeshIndex     = new Vector2(i, 1);
                int         MeshNodeIndex = (i - 1) * 2;
                NavMeshNode MeshNode      = NavMeshNodes.MeshNodes[MeshNodeIndex];
                NavMeshDictionary.AddNode(MeshNode, MeshIndex);
            }
            //Then the second column of mesh nodes
            int CurrentNodeIndex = 1;

            for (int i = 1; i < 10; i++)
            {
                Vector2 MeshIndex = new Vector2(i, 2);
                int     NodeIndex = CurrentNodeIndex;
                CurrentNodeIndex += 2;
                NavMeshNode MeshNode = NavMeshNodes.MeshNodes[NodeIndex];
                MeshNode.NodeIndex = MeshIndex;
                NavMeshDictionary.AddNode(MeshNode, MeshIndex);
            }
            //Add the other remaining columns
            int ListIndex = 18;

            for (int Column = 3; Column < 10; Column++)
            {
                for (int j = 1; j < 10; j++)
                {
                    Vector2     MeshIndex = new Vector2(j, Column);
                    NavMeshNode MeshNode  = NavMeshNodes.MeshNodes[ListIndex];
                    MeshNode.NodeIndex = MeshIndex;
                    ListIndex++;
                    NavMeshDictionary.AddNode(MeshNode, MeshIndex);
                }
            }

            //Add two game entities into the scene, the first entity will pathfind its way to the 2nd entity
            PrincessFox    = new GameEntity(new Vector3(-17.74f, 2.15f, 10.54f));
            PrincessTarget = new GameEntity(new Vector3(-41.17f, 0.89f, 24.15f));
            //Figure out which node each of these entities is closest two, these will be the ends of the pathway
            NavMeshNode StartNode = NavMeshDictionary.MeshDictionary[new Vector2(3, 4)];
            NavMeshNode EndNode   = NavMeshDictionary.MeshDictionary[new Vector2(7, 8)];

            //Find our pathway between the two entities
            List <NavMeshNode> NodePath = AStarSearch.FindPath(StartNode, EndNode, new Vector2(9, 9));
            //Now assign this path to the princess fox entity and have her navigate along to reach her target
        }