private void ProcessRaycastData(RaycastJobHolder holder, List <Pair <byte, Point2D> > visibleNodes, Dictionary <Point2D, IFOWNode> nodes) { holder.Complete(); NativeArray <RaycastHit> results = holder.GetResults(); List <Pair <byte, Point2D> > localPoints = holder.GetPoints(); for (int j = 0; j < localPoints.Count; j++) { int index = j * 2; if (results[index].collider == null || results[index + 1].collider == null) { visibleNodes.Add(localPoints[j]); } } nodes.Add(holder.OriginPoint, new FOWNode(visibleNodes)); holder.Dispose(); visibleNodes.Clear(); }
private bool ConnectTiles(RaycastHit[] hits, Point2D[] points, Dictionary <Point2D, IFOWNode> nodes, Dictionary <Point2D, Pair <float, Collider> > tempCamoNodes, float tileHalf, int layerMask) { const int MaxBatches = 5; NavMeshHit navHit = default(NavMeshHit); List <Pair <byte, Point2D> > visibleNodes = new List <Pair <byte, Point2D> >(); List <RaycastCommand> rayCommands = new List <RaycastCommand>(); Queue <RaycastJobHolder> rayJobs = new Queue <RaycastJobHolder>(5); for (int i = 0; i < hits.Length; i++) { Vector3 current = hits[i].point; float progress = Mathf.Clamp(0.01f + ((float)i / hits.Length) * 0.98f, 0, 1); bool cancel = EditorUtility.DisplayCancelableProgressBar("FOW", "Baking fog of war. Please wait...", progress); if (cancel) { while (rayJobs.Count > 0) { RaycastJobHolder tempHolder = rayJobs.Dequeue(); tempHolder.Complete(); tempHolder.Dispose(); } return(true); } if (!NavMesh.SamplePosition(current, out navHit, tileHalf, NavMesh.AllAreas)) { tempCamoNodes.Remove(points[i]); continue; } current.y += info.eyeHeight; while (rayJobs.Count == MaxBatches) { while (rayJobs.Count > 0 && rayJobs.Peek().IsCompleted) { RaycastJobHolder currentHolder = rayJobs.Dequeue(); ProcessRaycastData(currentHolder, visibleNodes, nodes); } Thread.Sleep(1); } List <Pair <byte, Point2D> > nodePoints = new List <Pair <byte, Point2D> >(); for (int j = 0; j < hits.Length; j++) { Vector3 next = hits[j].point; next.y += info.eyeHeight; float dist = Vector3.Distance(current, next); Vector3 dir = (next - current).normalized; float camoDist = 0; if (tempCamoNodes.ContainsKey(points[j])) { if (tempCamoNodes.ContainsKey(points[i])) { Pair <float, Collider> currentPair = tempCamoNodes[points[i]]; Pair <float, Collider> nextPair = tempCamoNodes[points[j]]; if (currentPair.right != nextPair.right) { camoDist = nextPair.left; } } else { camoDist = tempCamoNodes[points[j]].left; } } int roundDist = Mathf.RoundToInt(dist + camoDist); if (roundDist > info.maxVisionRange) { continue; } rayCommands.Add(new RaycastCommand(current, dir, dist, layerMask)); rayCommands.Add(new RaycastCommand(next, -dir, dist, layerMask)); nodePoints.Add(new Pair <byte, Point2D>((byte)roundDist, points[j])); } RaycastJobHolder holder = new RaycastJobHolder(rayCommands, nodePoints, points[i]); holder.Schedule(rayCommands.Count / 5); rayJobs.Enqueue(holder); rayCommands.Clear(); } while (rayJobs.Count > 0) { RaycastJobHolder holder = rayJobs.Dequeue(); ProcessRaycastData(holder, visibleNodes, nodes); } return(false); }