public void Add(VisibilityQueueJob job) { var currentAreasToGenerate = queue.SelectMany(p => p.AreasToGenerate).Distinct(); job.AreasToGenerate = job.AreasToGenerate.Except(currentAreasToGenerate).ToList(); var currentAreasToRender = queue.SelectMany(p => p.AreasToRender).Distinct(); job.AreasToRender = job.AreasToRender.Except(currentAreasToRender).ToList(); if (job.AreasToGenerate.Count > 0 || job.AreasToRender.Count > 0) { queue.Add(job); } }
private void ExpandVisibility() { AreaHelper.GetAreaRangeWithinViewDistance(view.Location, view.ViewDistanceCache, ref areaRange); // Remove any garbage areas outside the view area var areasOutsideRange = new List<Area>(); AreaHelper.GetAreasOutsideRange(ref areasOutsideRange, AreaCollection.Areas, areaRange); Logger.Log<TerrainVisibility>(LogLevel.Debug, "Caching {0} rendered areas", areasOutsideRange.Count); MoveVisibleAreasToCache(areasOutsideRange); Logger.Log<TerrainVisibility>(LogLevel.Debug, "Entering area {0} at location {1}", areaRange, view.Location); var job = new VisibilityQueueJob(areaRange); // Iterate all coordinates of the current view distance (including cached areas at the edge) for (int x = areaRange.Min.X; x <= areaRange.Max.X; x++) { for (int z = areaRange.Min.Z; z <= areaRange.Max.Z; z++) { for (int y = areaRange.Min.Y; y <= areaRange.Max.Y; y++) { var cachedArea = AreaCache.GetAreaAt(x, y, z); // If the current coordinates are located at the non-visible cached area edge if (areaRange.IsAtEdge(x, y, z)) { var visibleArea = AreaCollection.GetAreaAt(x, y, z); // Cache visible areas at the edge if (visibleArea != null) { MoveVisibleAreaToCache(visibleArea); } // Generate the area if missing else if (cachedArea == null) { job.AreasToGenerate.Add(new Vector3i(x, y, z)); } } // If the current coordinates are located within the visible area else { // Turn cached areas into visible areas if (cachedArea != null) { job.AreasToRender.Add(cachedArea); } } } } } visibilityQueue.Add(job); }