private List <Vector3D> GetBestPathFromManagers(MyPlanet planet, Vector3D initialPosition, Vector3D targetPosition) { bool flag; List <Vector3D> list; Vector3D? nullable; List <MyNavmeshManager> list2 = (from m in this.m_planetManagers[planet] where m.ContainsPosition(initialPosition) select m).ToList <MyNavmeshManager>(); if (list2.Count <= 0) { nullable = null; this.CreateManager(initialPosition, nullable).TilesToGenerate(initialPosition, targetPosition); return(new List <Vector3D>()); } using (List <MyNavmeshManager> .Enumerator enumerator = list2.GetEnumerator()) { while (true) { if (!enumerator.MoveNext()) { break; } MyNavmeshManager current = enumerator.Current; if (current.ContainsPosition(targetPosition) && (current.GetPathPoints(initialPosition, targetPosition, out list, out flag) || !flag)) { return(list); } } } MyNavmeshManager manager = null; double maxValue = double.MaxValue; foreach (MyNavmeshManager manager3 in list2) { double num2 = (manager3.Center - initialPosition).LengthSquared(); if (maxValue > num2) { maxValue = num2; manager = manager3; } } if (((!manager.GetPathPoints(initialPosition, targetPosition, out list, out flag) & flag) && (list.Count <= 2)) && (maxValue > this.MIN_NAVMESH_MANAGER_SQUARED_DISTANCE)) { double num3 = (initialPosition - targetPosition).LengthSquared(); if (((manager.Center - targetPosition).LengthSquared() - num3) > this.MIN_NAVMESH_MANAGER_SQUARED_DISTANCE) { nullable = null; this.CreateManager(initialPosition, nullable).TilesToGenerate(initialPosition, targetPosition); } } return(list); }
private MyNavmeshManager CreateManager(Vector3D center, Vector3D?forwardDirection = new Vector3D?()) { if (forwardDirection == null) { Vector3D v = -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(center)); forwardDirection = new Vector3D?(Vector3D.CalculatePerpendicularVector(v)); } int tileSize = 0x10; MyNavmeshManager item = new MyNavmeshManager(this, center, forwardDirection.Value, tileSize, 70, 0x19, this.GetRecastOptions(null)) { DrawNavmesh = this.m_drawNavmesh }; this.m_planetManagers[item.Planet].Add(item); return(item); }
/// <summary> /// Creates a new manager centered in targetPosition and adds it to the list of managers /// </summary> /// <param name="initialPosition"></param> /// <param name="targetPosition"></param> private MyNavmeshManager CreateManager(Vector3D center, Vector3D?forwardDirection = null) { //TODO: Will this work badly with Artifical Gravity? if (!forwardDirection.HasValue) { Vector3D gravityVector = -Vector3D.Normalize(GameSystems.MyGravityProviderSystem.CalculateTotalGravityInPoint(center)); forwardDirection = Vector3D.CalculatePerpendicularVector(gravityVector); } int tileSize = TILE_SIZE; int tileHeight = TILE_HEIGHT; int tileLineCount = TILE_LINE_COUNT; //TODO: this must receive the agent that is requesting a path so the options are setting appropriately var recastOptions = GetRecastOptions(null); //TODO: For now, it creates a manager with both points inside, if possible... Is this the best way? MyNavmeshManager manager = new MyNavmeshManager(this, center, forwardDirection.Value, tileSize, tileHeight, tileLineCount, recastOptions); //TODO: If a character has specific options for navmesh generation, there should be different manager lists for each character type manager.DrawNavmesh = m_drawNavmesh; m_planetManagers[manager.Planet].Add(manager); return(manager); }
/// <summary> /// Returns the best path from managers according to both initial and target positions /// </summary> /// <param name="planet"></param> /// <param name="initialPosition"></param> /// <param name="targetPosition"></param> /// <returns></returns> private List <Vector3D> GetBestPathFromManagers(MyPlanet planet, Vector3D initialPosition, Vector3D targetPosition) { bool noTilesToGenerated, pathContainsTarget; List <Vector3D> pathPoints; var managersContainingInitialPosition = m_planetManagers[planet].Where(m => m.ContainsPosition(initialPosition)).ToList(); if (managersContainingInitialPosition.Count > 0) { //TODO: Check if a manager has both positions // In that case, if the returned path is final, check if the last position is reached foreach (var manager in managersContainingInitialPosition) { if (manager.ContainsPosition(targetPosition)) { pathContainsTarget = manager.GetPathPoints(initialPosition, targetPosition, out pathPoints, out noTilesToGenerated); //TODO: if there is path to target if (pathContainsTarget || !noTilesToGenerated) { return(pathPoints); } } } // Choose the manager that is closer to the initial position MyNavmeshManager closestManager = null; double smallestDistance = double.MaxValue; foreach (var manager in managersContainingInitialPosition) { double distanceToInitialPosition = (manager.Center - initialPosition).LengthSquared(); if (smallestDistance > distanceToInitialPosition) { smallestDistance = distanceToInitialPosition; closestManager = manager; } } pathContainsTarget = closestManager.GetPathPoints(initialPosition, targetPosition, out pathPoints, out noTilesToGenerated); //if (!finalPath || pathPoints.Count >= 2) // return pathPoints; // It's the final path (all needed tiles generated) if (!pathContainsTarget && noTilesToGenerated && pathPoints.Count <= 2 && smallestDistance > MIN_NAVMESH_MANAGER_SQUARED_DISTANCE) { var currentPositionDistanceToTarget = (initialPosition - targetPosition).LengthSquared(); var currentManagerDistanceToTarget = (closestManager.Center - targetPosition).LengthSquared(); // Generates new manager if the one available is far enough if (currentManagerDistanceToTarget - currentPositionDistanceToTarget > MIN_NAVMESH_MANAGER_SQUARED_DISTANCE) { ProfilerShort.Begin("MyRDPathfinding.CreateManager2"); var manager = CreateManager(initialPosition); manager.TilesToGenerate(initialPosition, targetPosition); ProfilerShort.End(); } } return(pathPoints); } else // No manager contains the initial position, bummer.... { ProfilerShort.Begin("MyRDPathfinding.CreateManager1"); var manager = CreateManager(initialPosition); manager.TilesToGenerate(initialPosition, targetPosition); ProfilerShort.End(); return(new List <Vector3D>()); } }