private static bool CalcPathFromCell(AStarCell cellParent, Cell cellEnd, List<AStarCell> listCellClose, List<AStarCell> listCellOpen, bool useCost, float costMax) { foreach (Cell cell in cellParent.Cell.Neighbourghs.Values) { //---> La cellule n'est pas dans la liste fermée if (cell != null && !listCellClose.Exists(c => c.Cell == cell)) { AStarCell aStarCellPrev = listCellOpen.Find(c => c.Cell == cell); AStarCell aStarCell = new AStarCell(); aStarCell.Cell = cell; aStarCell.ParentCell = cellParent.Cell; aStarCell.G = cellParent.G + Tools.Distance(cell.Location, cellParent.Cell.Location); aStarCell.H = Tools.Distance(cell.Location, cellEnd.Location); aStarCell.F = aStarCell.G + aStarCell.H; if (useCost && cell.Height < costMax) { aStarCell.F = aStarCell.F * cell.Height; } if (aStarCellPrev != null && aStarCell.G < aStarCellPrev.G) { aStarCellPrev.ParentCell = cellParent.Cell; aStarCellPrev.G = aStarCell.G; aStarCellPrev.H = aStarCell.H; aStarCellPrev.F = aStarCell.F; } else if (aStarCellPrev == null) { listCellOpen.Add(aStarCell); } } } AStarCell aStarChoosenCell = null; foreach (AStarCell aStarCell in listCellOpen) { if (aStarChoosenCell == null) aStarChoosenCell = aStarCell; if (aStarCell.F < aStarChoosenCell.F) aStarChoosenCell = aStarCell; } //--- listCellOpen.Remove(aStarChoosenCell); listCellClose.Add(aStarChoosenCell); //--- //--- if (aStarChoosenCell == null) return false; else if (aStarChoosenCell.Cell == cellEnd) return true; else return CalcPathFromCell(aStarChoosenCell, cellEnd, listCellClose, listCellOpen, useCost, costMax); //--- }
public static List<int> CalcPath(Cell cellStart, Cell cellEnd, bool useCost, float costMax) { List<int> listCellPath = new List<int>(); List<AStarCell> listCellClose = new List<AStarCell>(); List<AStarCell> listCellOpen = new List<AStarCell>(); //--- Ajout de la case de départ AStarCell aStarCell = new AStarCell(); aStarCell.Cell = cellStart; //--- //--- listCellClose.Add(aStarCell); bool pathFound = CalcPathFromCell(aStarCell, cellEnd, listCellClose, listCellOpen, useCost, costMax); if (!pathFound) return listCellPath; //--- //--- Reconstitue le chemin bool pathCompleted = false; Cell cell = cellEnd; while (!pathCompleted) { if (listCellClose.Count == 0) pathCompleted = true; foreach (AStarCell aStarCellChild in listCellClose) { if (aStarCellChild.Cell == cell) { listCellPath.Add(aStarCellChild.Cell.IndexPosition); cell = aStarCellChild.ParentCell; if (aStarCellChild.Cell == cellStart) { pathCompleted = true; } } } } //--- listCellPath.Reverse(); return listCellPath; }
public void CalcMinionNewPath(MinionBase minion, Cell cell) { if (false) { minion.Path = PathFinding.CalcPath(minion.CurrentCell, cell, true, 10f); minion.PathLength = (minion.Path.Count - 1) * Map.R; minion.TraveledLength = 0f; } else { IPathFinder mPathFinder = new PathFinderFast(Map.Matrix); //IPathFinder mPathFinder = new PathFinder(Map.Matrix); mPathFinder.Formula = HeuristicFormula.Manhattan; mPathFinder.Diagonals = false; mPathFinder.HeavyDiagonals = false; mPathFinder.HeuristicEstimate = 1; mPathFinder.PunishChangeDirection = false; mPathFinder.TieBreaker = false; mPathFinder.SearchLimit = 5000; mPathFinder.DebugProgress = true; mPathFinder.DebugFoundPath = true; List<PathFinderNode> path = mPathFinder.FindPath(new System.Drawing.Point(minion.CurrentCell.Coord.X - 1, minion.CurrentCell.Coord.Y - 1), new System.Drawing.Point(cell.Coord.X - 1, cell.Coord.Y - 1)); minion.Path = new List<int>(); if (path != null) { path.Reverse(); for (int i = 0; i < path.Count; i++) { minion.Path.Add(path[i].X + path[i].Y * Map.Width); } } minion.PathLength = (minion.Path.Count - 1) * Map.R; minion.TraveledLength = 0f; } }
private Cell GetNeighborough(Cell cell, int offsetX, int offsetY) { if (cell.Coord.X + offsetX - 1 >= 0 && cell.Coord.X + offsetX <= this.Width && cell.Coord.Y + offsetY - 1 >= 0 && cell.Coord.Y + offsetY <= this.Height) { return Cells[(cell.Coord.Y + offsetY - 1) * this.Width + cell.Coord.X + offsetX - 1]; } return null; }
public void ElevateCell(Cell cell, float radius) { //System.Diagnostics.Stopwatch f = new System.Diagnostics.Stopwatch(); //f.Start(); List<Cell> cellsToCalcul = new List<Cell>(); cellsToCalcul.Add(cell); List<int> listIndexPoint = new List<int>(); foreach (Cell cell2 in Cells) { float distance = Tools.Distance(cell.Location, cell2.Location); if (distance < radius) { double value = Math.Abs(Tools.GetBellCurvePoint(1 - distance / radius, 0.25)); cellsToCalcul.Add(cell2); cell2.Height = (float)value * cell.Height; for (int i = 1; i <= 6; i++) { int index = cell2.Points[i]; if (!listIndexPoint.Contains(index)) listIndexPoint.Add(index); } } } //f.Stop(); //TimeSpan elapsed1 = f.Elapsed; //f.Restart(); /* foreach (Cell cell2 in cellsToCalcul) { //float distance = Tools.Distance(cell.Location, cell2.Location); //if (distance < radius) { CalcHeightPoint(cell2); } } */ CalcHeightPointNew(listIndexPoint); //f.Stop(); //TimeSpan elasped2 = f.Elapsed; //f.Restart(); CalcNormals(listIndexPoint); //f.Stop(); //TimeSpan elasped3 = f.Elapsed; }
public void CreateGrid() { Cells = new List<Cell>(); Random rnd = new Random(); float d = (float)Math.Sqrt(0.75); TimeSpan t = DateTime.Now.TimeOfDay; for (int y = 1; y <= Height / 2; y++) { for (int x = 1; x <= Width; x++) { float fx = (float)x; float fy = (float)y; Cell cell2 = new Cell(this, x, y * 2 - 1, (int)((2.5f + fx * 3f) * R), (int)((fy) * (2f * d * R))); //cell2.Coord = getHex(new Point((int)cell2.Location.X, (int)cell2.Location.Y)); Cells.Add(cell2); cell2.Height = (float)(rnd.NextDouble() * R * H); if (x == Height / 2 && y == Height / 2) cell2.Height = 100; if (x == Height / 2 && y + 1 == Height / 2) cell2.Height = 50; //if (x == Width && y == 1) // cell2.Height = 50; } for (int x = 1; x <= Width; x++) { float fx = (float)x; float fy = (float)y; Cell cell1 = new Cell(this, x, y * 2, (int)((1f + fx * 3f) * R), (int)((0.5f + fy) * (2f * d * R))); //cell1.Coord = getHex(new Point((int)cell1.Location.X, (int)cell1.Location.Y)); Cells.Add(cell1); cell1.Height = (float)(rnd.NextDouble() * R * H); } } TimeSpan r1 = t.Subtract(DateTime.Now.TimeOfDay); t = DateTime.Now.TimeOfDay; CalcNeighborough(); TimeSpan r2 = t.Subtract(DateTime.Now.TimeOfDay); t = DateTime.Now.TimeOfDay; CalcPoints(); TimeSpan r3 = t.Subtract(DateTime.Now.TimeOfDay); t = DateTime.Now.TimeOfDay; CalcHeightPoint(); CalcNormals(); TimeSpan r5 = t.Subtract(DateTime.Now.TimeOfDay); t = DateTime.Now.TimeOfDay; DrawMapIntoImageFile(); }
public void CalcHeightPoint(Cell cell) { foreach (int key in cell.Points.Keys) { Vector3 vector3 = Points[cell.Points[key]]; List<Cell> listCells = Cells.FindAll(cell2 => cell2.Points.ContainsValue(cell.Points[key])); vector3.Z = 0; foreach (Cell cell2 in listCells) { vector3.Z += (float)cell2.Height; } vector3.Z /= listCells.Count; //TODO : l'égalité ci-dessous est peut être inutile Points[cell.Points[key]] = vector3; } }
public static Vector3 NormalCell(Map map, Cell cell) { float? pickDistance = float.MaxValue; float pickCurDistance = 0f; float barycentricU = 0f; float barycentricV = 0f; Vector3 rayPosition = new Vector3(cell.Location,50f); Vector3 normal = Vector3.UnitZ; for (int i = 0; i < 4; i++) { bool intersect = RayIntersectTriangle(rayPosition, -Vector3.UnitZ, map.Points[cell.Points[listTriangle[i][0]]], map.Points[cell.Points[listTriangle[i][2]]], map.Points[cell.Points[listTriangle[i][1]]], ref pickCurDistance, ref barycentricU, ref barycentricV); if (intersect && pickCurDistance < pickDistance) { pickDistance = pickCurDistance; normal = NormalTriangle( map.Points[cell.Points[listTriangle[i][0]]], map.Points[cell.Points[listTriangle[i][1]]], map.Points[cell.Points[listTriangle[i][2]]]); } } return normal; }
public static float? RayIntersectCell(Vector3 rayPosition, Vector3 rayDirection, Map map, Cell cell) { float? pickDistance = float.MaxValue; float pickCurDistance = 0f; float barycentricU = 0f; float barycentricV = 0f; for (int i = 0; i < 4; i++) { bool intersect = RayIntersectTriangle(rayPosition, rayDirection, map.Points[cell.Points[listTriangle[i][0]]], map.Points[cell.Points[listTriangle[i][2]]], map.Points[cell.Points[listTriangle[i][1]]], ref pickCurDistance, ref barycentricU, ref barycentricV); if (intersect && pickCurDistance < pickDistance) { pickDistance = pickCurDistance; } } if (pickDistance == float.MaxValue) return null; else return pickDistance; }
private void AddVertex(int index1, int index2, int index3, List<VertexPositionNormalTexture> vertex, Cell cell) { Dictionary<int, Vector2> uv = new Dictionary<int, Vector2>(); if (cell.IsFlaged) { uv.Add(1, new Vector2(0f, 0f)); uv.Add(2, new Vector2(0f, 0f)); uv.Add(3, new Vector2(0f, 0f)); uv.Add(4, new Vector2(0f, 0f)); uv.Add(5, new Vector2(0f, 0f)); uv.Add(6, new Vector2(0f, 0f)); } else { uv.Add(1, new Vector2(0.75f, 0f)); uv.Add(2, new Vector2(1f, 0.5f)); uv.Add(3, new Vector2(0.75f, 1f)); uv.Add(4, new Vector2(0.26f, 1f)); uv.Add(5, new Vector2(0f, 0.5f)); uv.Add(6, new Vector2(0.26f, 0f)); } vertex.Add(new VertexPositionNormalTexture(Map.Points[cell.Points[index1]], Map.Normals[cell.Points[index1]], uv[index1])); vertex.Add(new VertexPositionNormalTexture(Map.Points[cell.Points[index2]], Map.Normals[cell.Points[index2]], uv[index2])); vertex.Add(new VertexPositionNormalTexture(Map.Points[cell.Points[index3]], Map.Normals[cell.Points[index3]], uv[index3])); }