//Internal & accessory methods static List <Vector3> InternalPathOptimization(List <Vector3> path, int level) { if (OnLineOfSight(SpaceGraph.GetCellIndexFromCoordOnLevel(path[0], level), SpaceGraph.GetCellIndexFromCoordOnLevel(path[path.Count - 1], level), level)) { return new List <Vector3> { path[0], path[path.Count - 1] } } ; for (int j = 2; j <= path.Count - 3; j++) { for (int i = 2; i < path.Count; i += 2) { if (i >= path.Count) { return(path); } if (OnLineOfSight(SpaceGraph.GetCellIndexFromCoordOnLevel(path[i - 2], level), SpaceGraph.GetCellIndexFromCoordOnLevel(path[i], level), level)) { path.RemoveAt(i - 1); return(InternalPathOptimization(path, level)); } } } return(path); }
public void TestInitialize() { testGraph = new SpaceGraph(); for (int i = 0; i < 5; i++) { testGraph.CreateNode(i); int cpd = (i < 3) ? 0 : i; int depth = (i == 0) ? 0 : i; int maxN = (i == 0 || i == 4) ? 1 : 2; testGraph.Node(i).CPDistance = cpd; testGraph.Node(i).Depth = depth; testGraph.Node(i).MaxNeighbours = maxN; } //node: neighbours // 1 : 1 // 2 : 2 // 3 : 2 // 4 : 1 testGraph.Connect(0, 1); testGraph.Connect(1, 2); testGraph.Connect(2, 3); testGraph.Connect(3, 4); }
List <Vector3> BuildSpline(List <Vector3> way) { //accessory extreme points adding way.Insert(0, way[0] + (way[0] - way[1]).normalized); way.Insert(way.Count, way[way.Count - 1] + (way[way.Count - 1] - way[way.Count - 2]).normalized); List <Vector3> splinePoints = new List <Vector3>((way.Count - 3) * segmentsCount); float step = 1f / (float)segmentsCount; Vector3 nextPoint; //spline points obtaining for (int i = 1; i <= way.Count - 3; i++) { for (float t = 0; t <= 1; t += step) { nextPoint = CatmullRomEq(way[i - 1], way[i], way[i + 1], way[i + 2], t); if (!SpaceGraph.IsCellOccAtCoordOnLevel(nextPoint, 0)) { splinePoints.Add(nextPoint); } } } // if (way[way.Count - 1] != endPoint) way.Add(endPoint); return(splinePoints); }
public void BidirectionalDisconnectTest() { SpaceGraph basic = new SpaceGraph(); basic.CreateNode(0); basic.CreateNode(1); //0->1 basic.Connect(0, 1); basic.Connect(1, 0); Assert.IsTrue(basic.Node(0).IsConnected(basic.Node(1))); Assert.IsTrue(basic.Node(1).IsConnected(basic.Node(0))); basic.Disconnect(0, 1); Assert.AreEqual(0, basic.Node(0).Edges.Count); Assert.AreEqual(0, basic.Node(1).Edges.Count); //1->0 basic.Connect(0, 1); basic.Connect(1, 0); Assert.IsTrue(basic.Node(0).IsConnected(basic.Node(1))); Assert.IsTrue(basic.Node(1).IsConnected(basic.Node(0))); basic.Disconnect(1, 0); Assert.AreEqual(0, basic.Node(0).Edges.Count); Assert.AreEqual(0, basic.Node(1).Edges.Count); }
/// <summary> /// Injects instanceID into the cells of the graph occupied by a triangle /// consisting of points <paramref name="p0" />, <paramref name="p1" />, <paramref name="p2" />. /// </summary> /// <param name="p0">First triangle point.</param> /// <param name="p1">Second triangle point.</param> /// <param name="p2">Third triangle point.</param> /// <param name="instanceID">Specific ID of the transform instance of the game object, whose triangle is handling.</param> void OccupyCellsForATriangle(Vector3 p0, Vector3 p1, Vector3 p2, int instanceID) { if (!isPrimaryProcessingCompleted) { Interlocked.Increment(ref processedTrisCount); } float dist12 = Vector3.Distance(p2, p1); float offs12 = 0; float offs012; Vector3 point12 = p1; Vector3 point012; while (offs12 < dist12) { point12 = p1 + ((p2 - p1).normalized) * offs12; SpaceGraph.OccupyCellsInCoordAtAllLevels(point12, instanceID); offs012 = 0; while (offs012 * offs012 < Vector3.SqrMagnitude(p0 - point12)) { point012 = p0 + ((point12 - p0).normalized) * offs012; SpaceGraph.OccupyCellsInCoordAtAllLevels(point012, instanceID); offs012 += shiftStep; } offs12 += shiftStep; } }
public bool RefinePath(Vector3 newPos) { ThrowUniversalEvent("EventPathRefiningRequested"); if (curCond == Movement) { if (isRefiningInProgress || !IsAtConstraintsArea(newPos) || !IsAtConstraintsArea(thisTransformInstance.position) || SpaceGraph.IsCellOccStaticOnLevel(thisTransformInstance.position, 0) || SpaceGraph.IsCellOccStaticOnLevel(newPos, 0)) { return(false); } LeavePathfindingQueue(); isRefiningInProgress = true; refinedTargetCoord = newPos; Action failureAct = () => { ThrowUniversalEvent("EventPathWasNotRefined"); isRefiningInProgress = false; }; Action succesAct = () => { ThrowUniversalEvent("EventPathWasRefined"); }; ThrowUniversalEvent("EventPathRefiningStarted"); FindWay(thisTransformInstance.position, newPos, pathfindingLevel, refinedPath, selectedPFAlg, failureAct, succesAct, trajectoryOptimization, trajectorySmoothing); return(true); } return(false); }
static void GenerateMap(SpaceGraph graph, int seed = 0) { var mapDescription = new MapDescription <int>(); //Add rooms graph.AllNodes.ForEach(node => mapDescription.AddRoom(node.Id)); //Add connections List <List <int> > connections = graph.ConvertToAdjList(false); for (int node = 0; node < connections.Count; node++) { for (int link = 0; link < connections[node].Count; link++) { mapDescription.AddPassage(node, connections[node][link]); } } //Add room descriptions using (var reader = new StreamReader(@"Resources\Rooms\SMB.yml")) { var roomLoader = cfloader.LoadRoomDescriptionsSetModel(reader); foreach (var roomDescription in roomLoader.RoomDescriptions) { GridPolygon shape = new GridPolygon(roomDescription.Value.Shape); RoomDescription roomShape = new RoomDescription(shape, (roomDescription.Value.DoorMode == null) ? roomLoader.Default.DoorMode : roomDescription.Value.DoorMode); mapDescription.AddRoomShapes(roomShape); } } // Generate bitmap SaveBitmap(mapDescription, seed); }
void Awake() { //Core classes initiation (learn more about system calls in “Additional options” of “User’s guide.pdf” document ClearResorces(); constraints = new SpaceConstraints(xMin, xMax, yMin, yMax, zMin, zMax); spaceGraph = new SpaceGraph(constraints, spaceFragmentation, 0.7d, this); }
public void ReducePotentialValuesTest() { SpaceGraph valueGraph = new SpaceGraph(); for (int i = 0; i < 6; i++) { valueGraph.CreateNode(i); } List <(int, int, int)> roomParams = new List <(int, int, int)>() { (0, 0, 1), (0, 1, 4), (2, 3, 1), (1, 2, 1), (1, 2, 1), (0, 2, 1) }; valueGraph.AllNodes.ForEach(node => { node.CPDistance = roomParams[node.Id].Item1; node.Depth = roomParams[node.Id].Item2; node.MaxNeighbours = roomParams[node.Id].Item3; }); //map CP valueGraph.Connect(0, 1); valueGraph.Connect(1, 5); valueGraph.ReducePotentialValues(); List <int> actual = valueGraph.AllNodes.SelectMany(x => x.Values.SelectMany(y => y.Select(z => z.Id))).ToList(); valueGraph.AllNodes.ForEach(node => Trace.WriteLine(node.PrintConnections())); Trace.WriteLine(string.Join(", ", actual)); /////////////////////////////////// [0][ 1 ][ 2 ][ 3 ][ 4 ][5] CollectionAssert.AreEqual(new int[] { 1, 0, 2, 3, 5, 0, 2, 4, 5, 0, 3, 4, 5, 0, 1, 3, 4, 5, 0, 1, 2, 4, 5, 0, 1, 2, 3, 5, 1 }.ToList(), actual); }
public static List <Vector3> PathSmoothing(List <Vector3> path, int level) { //Interpolation with the Catmull-Rom spline CatmullRom catmullRomInstance = new CatmullRom(path, SpaceGraph.GetLevelSideLength(level)); return(catmullRomInstance.GetSplineCall()); }
public WaveTrace(SpaceConstraints spaceConstraintsInp, object cTInstance, Vector3 start, Vector3 goal) { this.cTInstance = (CancellationToken)cTInstance; spaceConstarintsInst = spaceConstraintsInp; this.start = SpaceGraph.GetCellIndexFromCoordOnLevel(start, 0); this.goal = SpaceGraph.GetCellIndexFromCoordOnLevel(goal, 0); waves = new List <HashSet <Vector3> >(); }
/// <summary> /// Builds the navigation graph for obstacle. /// If updateObstc is set to true cond., firstly, remove occuranse of obstacle in the graph. /// </summary> /// <param name="obstacleGOToUpdate">GameObject-obstacle, for which you want to update the graph.</param> /// <param name="cancToken">Cancellation token for controll to async handeling</param> /// <param name="entitiesTasksToParallelize">List, you want to put handelling task in (if you want)</param> /// <param name="updateObstc">Is obstc graph updating for, already was handeled once.</param> public void UpdateGraphForObstacle(GameObject obstacleGOToUpdate, CancellationToken cancToken, bool updateObstc = false) { MeshCollider meshColliderInst = obstacleGOToUpdate.GetComponent <MeshCollider>(); MeshFilter meshFilterInst = obstacleGOToUpdate.GetComponent <MeshFilter>(); Terrain terrainInst = obstacleGOToUpdate.GetComponent <Terrain>(); if (updateObstc) { SpaceGraph.ReleaseCellsFromObstcID(obstacleGOToUpdate.transform.GetInstanceID()); } MeshDataContainer mDCInst = new MeshDataContainer() { gameObjectName = obstacleGOToUpdate.name, transformData = obstacleGOToUpdate.transform, instanceID = obstacleGOToUpdate.transform.GetInstanceID(), CTInstance = cancToken }; if (meshColliderInst && meshColliderInst.sharedMesh) { mDCInst.triangles = meshColliderInst.sharedMesh.triangles; mDCInst.vertices = meshColliderInst.sharedMesh.vertices; HandleEntity(mDCInst, EntityType.Mesh); } if (meshFilterInst && meshFilterInst.sharedMesh) { mDCInst.triangles = meshFilterInst.sharedMesh.triangles; mDCInst.vertices = meshFilterInst.sharedMesh.vertices; HandleEntity(mDCInst, EntityType.Mesh); } if (terrainInst) { float[,] hmArr = terrainInst.terrainData.GetHeights(0, 0, terrainInst.terrainData.heightmapResolution, terrainInst.terrainData.heightmapResolution); TerrainDataContainer tDCInst = new TerrainDataContainer() { gameObjectName = obstacleGOToUpdate.name, maxH = terrainInst.terrainData.size.y, hMArray = hmArr, hMWidth = terrainInst.terrainData.heightmapResolution, xStart = 1, xEnd = terrainInst.terrainData.heightmapResolution, zStart = 1, zEnd = terrainInst.terrainData.heightmapResolution, hX = terrainInst.terrainData.size.x, hZ = terrainInst.terrainData.size.z, terrainPos = terrainInst.GetPosition(), hMapScaleX = terrainInst.terrainData.heightmapScale.x, hMapScaleZ = terrainInst.terrainData.heightmapScale.z, instanceID = terrainInst.transform.GetInstanceID(), CTInstance = cancToken }; HandleEntity(tDCInst, EntityType.Terrain); } }
public void TestInitialize() { testGraph = new SpaceGraph(); for (int i = 0; i < rooms; i++) { testGraph.CreateNode(i); } generator = new BayesianSpaceGenerator(); testGraph = generator.CriticalPathMapper(testGraph, cpl); }
static List <Vector3> ChooseFreeAdjacents(List <Vector3> path, int level) { List <Vector3> newPath = new List <Vector3>(); newPath.Add(path[0]); for (int i = 1; i < path.Count - 1; i++) { newPath.Add(GetFreeAdjacentCellCoord(SpaceGraph.GetCellIndexFromCoordOnLevel(path[i], level), level)); } newPath.Distinct(); newPath.Add(path[path.Count - 1]); return(newPath); }
public bool RedefineConstraints(float XMin, float XMax, float YMin, float YMax, float ZMin, float ZMax, float SideLength, double heur_fact) { if (XMin < XMax && YMin < YMax && ZMin < ZMax && SideLength > 0 && heur_fact >= 0.5f && heur_fact <= 1) { constraints = new SpaceConstraints(XMin, XMax, YMin, YMax, ZMin, ZMax); spaceGraph = new SpaceGraph(constraints, SideLength, heur_fact, this); return(true); } else { return(false); } }
/// <summary> /// Highlights all occupied cells, if appropriate toggle is active at inspector. /// </summary> public void OnDrawGizmos() { if (traceCellsInEditor && spaceHandlerInstance != null) { Gizmos.color = new Color(1, .46f, .46f, 1); float cellSize = SpaceGraph.GetLevelSideLength(levelToTrace); foreach (Vector3 index in SpaceGraph.occCellsLevels[levelToTrace].Keys) { Gizmos.DrawWireCube(SpaceGraph.GetCellCenterCoordFromIndexOnLevel(index, levelToTrace), new Vector3(cellSize * .99f, cellSize * .99f, cellSize * .99f)); } } }
public void DisconnectTest() { SpaceGraph basic = new SpaceGraph(); basic.CreateNode(0); basic.CreateNode(1); basic.Connect(0, 1); Assert.IsTrue(basic.Node(0).IsConnected(basic.Node(1))); Assert.IsTrue(basic.Node(1).IsConnected(basic.Node(0))); basic.Disconnect(0, 1); Assert.IsFalse(basic.Node(0).IsConnected(basic.Node(1))); Assert.IsFalse(basic.Node(1).IsConnected(basic.Node(0))); }
public Graph(SpaceManager spaceManagerInstance, object cTInstance, Vector3 start, Vector3 goal, int pathfindingLevel, SpaceConstraints constraints, double omega, bool diags = false) { if (!constraints.Check(start) || !constraints.Check(goal)) { throw new ArgumentOutOfRangeException(); } this.goal = new Cube(SpaceGraph.GetCellIndexFromCoordOnLevel(goal, pathfindingLevel)); this.start = new Cube(SpaceGraph.GetCellIndexFromCoordOnLevel(start, pathfindingLevel), this.goal); this.constraints = constraints; this.omega = omega; this.diags = diags; this.cTInstance = cTInstance; this.spaceManagerInstance = spaceManagerInstance; this.pathfindingLevel = pathfindingLevel; }
public void ConnectTest() { SpaceGraph basic = new SpaceGraph(); basic.CreateNode(0); basic.CreateNode(1); basic.CreateNode(2); basic.Connect(0, 1); Assert.IsTrue(basic.Node(0).IsConnected(basic.Node(1))); Assert.IsTrue(basic.Node(1).IsConnected(basic.Node(0))); Assert.IsFalse(basic.Node(0).IsConnected(basic.Node(2))); Assert.AreEqual(basic.Node(0).Edges.Count, 1); Assert.AreEqual(basic.Node(1).Edges.Count, 1); }
//Is thre is no any adjacents occupied cells static bool IsAdjacentsFree(Vector3 index, int level) { for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { for (int z = -1; z <= 1; z++) { if (SpaceGraph.IsCellOccAtIndexOnLevel(new Vector3(index.x + x, index.y + y, index.z + z), level)) { return(false); } } } } return(true); }
public SpaceHandler(SpaceManager spaceManagerInstance, float minSideLength, int gridLevelsCount, List <string> staticObstacleTags, object cancellationTokenInstance, int maxAliveThreadsCount, bool agressiveUseOfMultithreading) { processedTrisCount = 0; SpaceGraph.SetFields(minSideLength, gridLevelsCount, maxAliveThreadsCount); tmCallback = StartAsyncTasks; internalTimer = new Timer(tmCallback, null, 0, 4); inUpdateInvocationsQueue = new Queue <Action>(); asyncTasksQueue = new ConcurrentQueue <object[]>(); aliveTasksDict = new ConcurrentDictionary <int, AsyncTaskDataContainer>(); this.staticObstacleTags = staticObstacleTags; this.spaceManagerInstance = spaceManagerInstance; this.maxAliveAsyncTasksCount = maxAliveThreadsCount; broadcastCancToken = (CancellationToken)cancellationTokenInstance; shiftStep = Mathf.Min(minSideLength * minSideLength, minSideLength * .5f); agressiveUseMultithreading = agressiveUseOfMultithreading; }
public static void Main() { Debug.WriteLine("Starting Bayesian Space Generator..."); if (enableUserInput) { BayesianSpaceGenerator spaceGen = new BayesianSpaceGenerator(); string value = "10"; if (Dialog.InputBox("Bayesian PDG", "Enter a Dungeon size between 2-27:", ref value) == DialogResult.OK) { SpaceGraph graph = spaceGen.RunInference(Int32.Parse(value), defaultNetPath); if (graph != null) { GenerateMap(graph); } else { MessageBox.Show("Constraints imposed by the sample could not be satisfied. Try again.", "Error: Bad Sample", 0); } } } else { for (int i = 2; i < 27; i++) { Stopwatch netWatch = new Stopwatch(); BayesianSpaceGenerator spaceGen = new BayesianSpaceGenerator(); netWatch.Start(); SpaceGraph experimentGraph = spaceGen.RunInference(i, defaultNetPath); netWatch.Stop(); if (experimentGraph != null) { netGenerationTime = netWatch.Elapsed.TotalSeconds; GenerateMap(experimentGraph); } } } //FileInfo[] files = new DirectoryInfo("Resources\\Maps").GetFiles("*.yaml"); //foreach (var map in files) //{ // GenerateStaticMap(map.Name); //} }
// Pathfinding public List <Vector3> GetWay() { Open = new PriorityQueue(); Close = new List <IVertex>(); var s = new List <IVertex>(); s.Add(start); Open.Add(FFunction(s), s); while (Open.Count != 0) { if (CheckForCancellationRequested()) { return(null); } var p = Open.First(); Open.RemoveFirst(); var x = p.Last(); if (Close.Contains(x)) { continue; } if (x.Equals(goal)) { spaceManagerInstance.pathfindingThreadsCurCount--; return(p.Select(el => SpaceGraph.GetCellCenterCoordFromIndexOnLevel(((Cube)el).index, pathfindingLevel)).ToList()); //converting List<IVertex> to Lis<Vector3> } Close.Add(x); foreach (var y in graph.Adjacent(x)) { if (CheckForCancellationRequested()) { return(null); } if (!Close.Contains(y)) { var newPath = new List <IVertex>(p); newPath.Add(y); Open.Add(FFunction(newPath), newPath); } } } spaceManagerInstance.pathfindingThreadsCurCount--; return(null); }
List <Vector3> BackwardDescent() { List <Vector3> way = new List <Vector3>(waves.Count + 1); way.Add(goal); for (int waveI = waves.Count - 1; waveI >= 0; waveI--) { if (cTInstance.IsCancellationRequested) { return(null); } for (int i = -1; i <= 1; i += 2) { Vector3 cell = new Vector3(way[way.Count - 1].x + i, way[way.Count - 1].y, way[way.Count - 1].z); if (waves[waveI].Contains(cell)) { way.Add(cell); goto exitLabel; } } for (int j = -1; j <= 1; j += 2) { Vector3 cell = new Vector3(way[way.Count - 1].x, way[way.Count - 1].y + j, way[way.Count - 1].z); if (waves[waveI].Contains(cell)) { way.Add(cell); goto exitLabel; } } for (int k = -1; k <= 1; k += 2) { Vector3 cell = new Vector3(way[way.Count - 1].x, way[way.Count - 1].y, way[way.Count - 1].z + k); if (waves[waveI].Contains(cell)) { way.Add(cell); goto exitLabel; } } exitLabel :; } way = way.Select(index => SpaceGraph.GetCellCenterCoordFromIndexOnLevel(index, 0)).ToList(); way.Reverse(); return(way); }
public void IsCompletedTest() { SpaceGraph incomplete = new SpaceGraph(); Trace.WriteLine(testGraph.ToString()); Assert.IsTrue(testGraph.isComplete); incomplete.CreateNode(0); incomplete.CreateNode(1); incomplete.CreateNode(2); incomplete.CreateNode(3); incomplete.Connect(0, 3); incomplete.Connect(1, 2); Trace.WriteLine(incomplete.ToString()); Assert.IsFalse(incomplete.isComplete); }
public static List <Vector3> PathFancification(List <Vector3> path, int level) { path = ChooseFreeAdjacents(path, level); if (SpaceGraph.amountOfSpatialGraphLevels == 1) { return(path); } List <Vector3> newPath = new List <Vector3>(); newPath.Add(path[0]); for (int i = 1; i < path.Count - 1; i++) { newPath.Add(SpaceGraph.FindCoordMaxCellCenter(path[i], level)); } newPath.Distinct(); newPath.Add(path[path.Count - 1]); return(newPath); }
public void PathToTest() { SpaceGraph validGraph = new SpaceGraph(); for (int i = 0; i < 6; i++) { validGraph.CreateNode(i); } validGraph.Connect(0, 2); validGraph.Connect(0, 5); validGraph.Connect(1, 4); validGraph.Connect(3, 5); validGraph.Connect(4, 5); Trace.WriteLine(validGraph.ToString()); Assert.AreEqual(4, validGraph.PathTo(0, 1).Count); CollectionAssert.AreEqual(new int[] { 0, 5, 4, 1 }.ToList(), validGraph.PathTo(0, 1)); }
//Is line from i cell to j cell free? static bool OnLineOfSight(Vector3 i, Vector3 j, int level) { var n = (int)Vector3.Distance(i, j) / Math.Min(1f, deltaDistCheck); var tempVector = new Vector3(); var direction = (j - i).normalized; for (var k = 0; k < n; k++) { i += direction * Math.Min(1f, deltaDistCheck); tempVector.Set((int)(i.x), (int)(i.y), (int)(i.z)); // lock (spaceGraphInstance.occCells) if (SpaceGraph.IsCellOccAtIndexOnLevel(tempVector, level)) { return(false); } } return(true); }
static Vector3 GetFreeAdjacentCellCoord(Vector3 index, int level) { if (IsAdjacentsFree(index, level)) { return(SpaceGraph.GetCellCenterCoordFromIndexOnLevel(index, level)); } for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { for (int z = -1; z <= 1; z++) { Vector3 tmpIndex = new Vector3(index.x + x, index.y + y, index.z + z); if (IsAdjacentsFree(tmpIndex, level)) { return(SpaceGraph.GetCellCenterCoordFromIndexOnLevel(tmpIndex, level)); } } } } return(SpaceGraph.GetCellCenterCoordFromIndexOnLevel(index, level)); }
/// <summary> /// In-editor highlighting of the wave-trace algorithm executing. /// </summary> #region Pathfinding trace #if UNITY_EDITOR private void OnDrawGizmos() { if (showPathfindingZone) { Gizmos.color = Color.green; Vector3 zoneCenter = new Vector3(xMin + .5f * (xMax - xMin), yMin + .5f * (yMax - yMin), zMin + .5f * (zMax - zMin)); Gizmos.DrawWireCube(zoneCenter, new Vector3((xMax - xMin), (yMax - yMin), (zMax - zMin))); } if (!inEditorPathfindingTraverce) { return; } Gizmos.color = Color.cyan; if (waves == null) { return; } lock (waves) { if (waves.Count <= 0) { return; } foreach (Vector3 cell in waves[waves.Count - 1]) { Vector3 coord = SpaceGraph.GetCellCenterCoordFromIndexOnLevel(cell, 0); Gizmos.DrawWireCube(coord, new Vector3(spaceManagerInstance.cellMinSize, spaceManagerInstance.cellMinSize, spaceManagerInstance.cellMinSize)); } } }