/// <summary> /// Internal method. /// Performs trajectory processing procedures. /// (asynchronous execution is assumed) /// </summary> /// <param name="inpData"></param> void PathProcessThreadMethod(object inpData) { CancellationToken cTInstance = cTSInstance.Token; PathProcessParamContainer pPPCInstance = (PathProcessParamContainer)inpData; List <Vector3> newPath = new List <Vector3>(); lock (pPPCInstance.pathToProcess) newPath.AddRange(pPPCInstance.pathToProcess); newPath[newPath.Count - 1] = targetCoord; newPath.Insert(0, pPPCInstance.startPos); if (cTInstance.IsCancellationRequested) { return; } //call optimization functions and smooth trajectory if (pPPCInstance.trajectoryOptimization) { newPath = PathHandler.PathFancification(newPath, pPPCInstance.pathfindingLevel); newPath = PathHandler.PathOptimization(newPath, pPPCInstance.pathfindingLevel); } if (pPPCInstance.trajectorySmoothing) { newPath = PathHandler.PathSmoothing(newPath, pPPCInstance.pathfindingLevel); } if (cTInstance.IsCancellationRequested) { return; } for (int i = 1; i <= newPath.Count - 1; i++) { totalLength += Vector3.Distance(newPath[i - 1], newPath[i]); } lock (finalPath) { finalPath.AddRange(newPath); } if (cTInstance.IsCancellationRequested) { return; } lock (actionsQueue) actionsQueue.Enqueue(pPPCInstance.furtherActions); }
/// <summary> /// Internal method. /// Performs pathfinding. /// (asynchronous execution is assumed) /// </summary> /// <param name="inpData"></param> void PathfindingThreadMethod(object inpData) { PathfindingParamContainer paramsData = (PathfindingParamContainer)inpData; try { if (paramsData.generateEvents) { if (!IsAtConstraintsArea(paramsData.target)) { lock (actionsQueue) actionsQueue.Enqueue(new Action(() => { curCond = WaitingForRequest; ThrowUniversalEvent("EventPathfindingToOutwardPointRequested"); })); return; } if (!IsAtConstraintsArea(paramsData.start)) { actionsQueue.Enqueue(new Action(() => { curCond = WaitingForRequest; ThrowUniversalEvent("EventPathfindingFromOutwardPointRequested"); })); return; } if (SpaceGraph.IsCellOccStaticOnLevel(paramsData.start, 0)) { actionsQueue.Enqueue(new Action(() => { curCond = WaitingForRequest; ThrowUniversalEvent("EventPathfindingFromStaticOccupiedCellRequested"); })); return; } if (SpaceGraph.IsCellOccStaticOnLevel(paramsData.target, 0)) { actionsQueue.Enqueue(new Action(() => { curCond = WaitingForRequest; ThrowUniversalEvent("EventPathfindingToStaticOccupiedCellRequested"); })); return; } } List <Vector3> foundPath; // поиск пути, результат кладется в переменную foundPath if (paramsData.usingAlg == PathfindingAlgorithm.AStar) { Graph graph = new Graph(spaceManagerInstance, cTSInstance.Token, paramsData.start, paramsData.target, paramsData.pathfindingLevel, new SpaceConstraints { xMin = xMin, xMax = xMax, yMin = yMin, yMax = yMax, zMin = zMin, zMax = zMax }, heuristicFactor ); foundPath = graph.GetWay(); } else { WaveTrace waveTraceInst = new WaveTrace( new SpaceConstraints { xMin = xMin, xMax = xMax, yMin = yMin, yMax = yMax, zMin = zMin, zMax = zMax }, cTSInstance.Token, paramsData.start, paramsData.target); waves = waveTraceInst.waves; foundPath = waveTraceInst.GetWay(); } if (foundPath == null) { lock (actionsQueue) actionsQueue.Enqueue(paramsData.failureActions); return; } if (paramsData.inThreadOptimizePath) { foundPath = PathHandler.PathFancification(foundPath, paramsData.pathfindingLevel); foundPath = PathHandler.PathOptimization(foundPath, paramsData.pathfindingLevel); } if (paramsData.inThreadSmoothPath) { foundPath = PathHandler.PathSmoothing(foundPath, paramsData.pathfindingLevel); } if (paramsData.inThreadOptimizePath || paramsData.inThreadSmoothPath) { totalLength = 0; for (int i = 0; i < foundPath.Count - 1; i++) { totalLength += Vector3.Distance(foundPath[i], foundPath[i + 1]); } } lock (paramsData.outPath) { paramsData.outPath.Clear(); paramsData.outPath.AddRange(foundPath); } lock (actionsQueue) actionsQueue.Enqueue(paramsData.succesActions); } catch (Exception ex) { UnityEngine.Debug.Log(ex.Message); } }