public void Update(double elapsedTime) { _selectedPolygon = _navMesh.FindNearestPolygon(_input.Mouse.Position); _selectedVertexIndex = FindSelectedVertex(_input.Mouse.Position, _selectedPolygon, VertexEditRadius); if (_draggingVertex) { if (_input.Mouse.LeftHeld && _selectedVertexIndex != -1) { _selectedPolygon.TryToUpdateVertPosition(_selectedVertexIndex, _input.Mouse.Position); return; } else { _draggingVertex = false; } } if (_input.Keyboard.IsKeyPressed(System.Windows.Forms.Keys.A)) { _navMesh.AddPolygon(new ConvexPolygon(_input.Mouse.Position)); } if (_input.Mouse.LeftHeld && _selectedVertexIndex != -1) { _draggingVertex = true; } }
public PolygonLink(ConvexPolygon startPoly, IndexedEdge startEdge, ConvexPolygon endPoly, IndexedEdge endEdge) { StartPoly = startPoly; StartEdgeIndex = startEdge; EndPoly = endPoly; EndEdgeIndex = endEdge; }
/// <summary> /// Works out a graph of nodes on top of the navmesh. /// Each polygon is a node and a node is added a connecting edges of linked polygons. /// The node graph class member is filled in by running this method. /// It's quite likely this code isn't very optimal. /// </summary> /// <param name="polyStart">The polygon the entity is currently in.</param> /// <param name="polyEnd">The polygon the entity would like to be in.</param> /// <param name="from">The point in the entity is current positioned.</param> /// <param name="to">The point the entity would like to be positioned.</param> /// <param name="navMesh">The navigation mesh describing the polygons and their links.</param> /// <returns>The start and end nodes for the journey the player wants to take</returns> private Tuple <NavigationNode, NavigationNode> CreateNodeNetwork(ConvexPolygon polyStart, ConvexPolygon polyEnd, Point from, Point to, NavMesh navMesh) { _nodeGraph.Clear(); // Store a map poly -> node to make it simple to work out the connection nodes. Dictionary <ConvexPolygon, NavigationNode> polyToNodeMap = new Dictionary <ConvexPolygon, NavigationNode>(); NavigationNode startNode = null; NavigationNode endNode = null; // Create a node for the centroid of each polygon // Replace the postion of the start and end polygon. foreach (ConvexPolygon polygon in navMesh.PolygonList) { Point position; NavigationNode node; if (polyStart == polygon) { position = from; node = new NavigationNode(position); startNode = node; } else if (polyEnd == polygon) { position = to; node = new NavigationNode(position); endNode = node; } else { position = polygon.CalculateCentroid(); node = new NavigationNode(position); } _nodeGraph.Add(node); polyToNodeMap.Add(polygon, node); } // Create the edge nodes and add the links // !* This is where you'd add several nodes per edge, if you wanted. foreach (PolygonLink link in navMesh.Links) { LineSegment line = link.GetShortestEdge(); Point midPoint = line.GetMiddle(); NavigationNode connectionNode = new NavigationNode(midPoint); // Add bidirectional links to connected polys and edge polys. polyToNodeMap[link.StartPoly].Neighbours.Add(connectionNode); connectionNode.Neighbours.Add(polyToNodeMap[link.StartPoly]); polyToNodeMap[link.EndPoly].Neighbours.Add(connectionNode); connectionNode.Neighbours.Add(polyToNodeMap[link.EndPoly]); _nodeGraph.Add(connectionNode); } return(new Tuple <NavigationNode, NavigationNode>(startNode, endNode)); }
/// <summary> /// Works out a graph of nodes on top of the navmesh. /// Each polygon is a node and a node is added a connecting edges of linked polygons. /// The node graph class member is filled in by running this method. /// It's quite likely this code isn't very optimal. /// </summary> /// <param name="polyStart">The polygon the entity is currently in.</param> /// <param name="polyEnd">The polygon the entity would like to be in.</param> /// <param name="from">The point in the entity is current positioned.</param> /// <param name="to">The point the entity would like to be positioned.</param> /// <param name="navMesh">The navigation mesh describing the polygons and their links.</param> /// <returns>The start and end nodes for the journey the player wants to take</returns> private Tuple<NavigationNode, NavigationNode> CreateNodeNetwork(ConvexPolygon polyStart, ConvexPolygon polyEnd, Point from, Point to, NavMesh navMesh) { _nodeGraph.Clear(); // Store a map poly -> node to make it simple to work out the connection nodes. Dictionary<ConvexPolygon, NavigationNode> polyToNodeMap = new Dictionary<ConvexPolygon, NavigationNode>(); NavigationNode startNode = null; NavigationNode endNode = null; // Create a node for the centroid of each polygon // Replace the postion of the start and end polygon. foreach (ConvexPolygon polygon in navMesh.PolygonList) { Point position; NavigationNode node; if (polyStart == polygon) { position = from; node = new NavigationNode(position); startNode = node; } else if (polyEnd == polygon) { position = to; node = new NavigationNode(position); endNode = node; } else { position = polygon.CalculateCentroid(); node = new NavigationNode(position); } _nodeGraph.Add(node); polyToNodeMap.Add(polygon, node); } // Create the edge nodes and add the links // !* This is where you'd add several nodes per edge, if you wanted. foreach (PolygonLink link in navMesh.Links) { LineSegment line = link.GetShortestEdge(); Point midPoint = line.GetMiddle(); NavigationNode connectionNode = new NavigationNode(midPoint); // Add bidirectional links to connected polys and edge polys. polyToNodeMap[link.StartPoly].Neighbours.Add(connectionNode); connectionNode.Neighbours.Add(polyToNodeMap[link.StartPoly]); polyToNodeMap[link.EndPoly].Neighbours.Add(connectionNode); connectionNode.Neighbours.Add(polyToNodeMap[link.EndPoly]); _nodeGraph.Add(connectionNode); } return new Tuple<NavigationNode, NavigationNode>(startNode, endNode); }
public void Update(double elapsedTime) { _selectedPolygon = _navMesh.FindNearestPolygon(_input.Mouse.Position); if (_input.Mouse.LeftPressed) { if (_selectedPolygon != null) { _selectedPolygon.TryToAddVertex(_input.Mouse.Position); } } }
public ConvexPolygon FindNearestPolygon(Point mousePos) { ConvexPolygon nearestPolygon = null; float minDistance = float.MaxValue; foreach (ConvexPolygon poly in _polygonList) { float distance = poly.GetClosestEdgeDistance(mousePos); if (distance < minDistance) { minDistance = distance; nearestPolygon = poly; } } return(nearestPolygon); }
/// <summary> /// Checks all the vertices of a polygon and against a point. /// If that point is within the radius of a vertex, then the index to that vertex is returned. /// Otherwise -1 is returned. /// </summary> /// <param name="radius">The radius the position must come within for a vertex to be selected.</param> /// <param name="position">The poisition to check against the vertices</param> /// <param name="polygon">The polygon which will have it's vertices checked. A null polygon will return -1</param> /// <returns>Index to vertex in the radius of the position or minus one if no suitable vertex can be found.</returns> private int FindSelectedVertex(Point position, ConvexPolygon polygon, int radius) { if (polygon == null) { return -1; } for (int i = 0; i < polygon.Vertices.Count; i++) { Circle circle = new Circle(polygon.Vertices[i].X, polygon.Vertices[i].Y, radius); if (circle.Intersects(position)) { return i; } } return -1; }
public List <Point> GetPath(Point from, Point to, NavMesh navMesh) { List <Point> path = new List <Point>(); // First find the polygon they're in // !* May want a little overlapping so all screen can be clicked. // In that case this should check if all intersected options contain as same poly start/end ConvexPolygon polyStart = navMesh.PolygonList.First(x => x.Intersects(from)); ConvexPolygon polyEnd = navMesh.PolygonList.First(x => x.Intersects(to)); if (polyStart == null || polyEnd == null) { return(path); } else if (polyStart == polyEnd) { path.Add(from); path.Add(to); } else if (polyStart != polyEnd) { // This does not need doing every time but it's easier to code if is recreated. _astar = new AStar <NavigationNode>( delegate(NavigationNode startNode, NavigationNode endNode) { return(Math.Sqrt(startNode.Position.X * endNode.Position.X + startNode.Position.Y * endNode.Position.Y)); }); var startEndNodes = CreateNodeNetwork(polyStart, polyEnd, from, to, navMesh); _astar.FindPath(startEndNodes.Item1, startEndNodes.Item2); _astar.Path.Reverse(); foreach (var node in _astar.Path) { path.Add(node.Position); } } return(path); }
private static int FindPolygonIndex(NavMesh navMesh, ConvexPolygon convexPolygon) { return navMesh.PolygonList.FindIndex(convexPolygon.Equals); }
private static void LoadSinglePolygon(XmlTextReader xmlReader, NavMesh navMesh) { ConvexPolygon polygon = new ConvexPolygon(); xmlReader.MoveToContent(); while (xmlReader.Read()) { if ("point" == xmlReader.Name) { float x = float.Parse(xmlReader.GetAttribute("x")); float y = float.Parse(xmlReader.GetAttribute("y")); polygon.Vertices.Add(new Point(x, y)); } else if("polygon" == xmlReader.Name) { polygon.GenerateEdges(); navMesh.AddPolygon(polygon); return; } } }
public void AddPolygon(ConvexPolygon polygon) { _polygonList.Add(polygon); }
public PolygonEdgePair(ConvexPolygon polygon, IndexedEdge edge) { Polygon = polygon; Edge = edge; }