/** Return the next column that should be added to the scene */ public ColumnInstantiateTask GetNextInstantiateColumn() { lock (instantiateQueue) { if (instantiateQueue.Count > 0) { ColumnInstantiateTask result = instantiateQueue[0]; instantiateQueue.RemoveAt(0); return(result); } else { return(null); } } }
/** Given a rectangle with corners 'min' and 'max', load 'count' columns within the rectangle, prioritizing the ones closer to the center */ public void LoadNextColsInRange(Vector2i min, Vector2i max, int count) { // helper variables int xMin = min.x; int zMin = min.z; int xMax = max.x; int zMax = max.z; Vector2i center = new Vector2i((xMin + xMax) / 2, (zMin + zMax) / 2); List <Vector2i> candidates = new List <Vector2i>(); List <Vector2i> addition = new List <Vector2i>(); List <Vector2i> render = new List <Vector2i>(); // build an ordered list of all the col positions for (int x = xMin; x <= xMax; x++) { for (int z = zMin; z <= zMax; z++) { candidates.Add(new Vector2i(x, z)); } } candidates.Sort(new Vector2i.DistanceComparer(center)); // pick the next ones to render foreach (Vector2i pos in candidates) { lock (this) { if (!renderedData.Contains(pos)) { render.Add(pos); if (render.Count >= count) { break; } } } } // pick the columns we need to load to support the render picks foreach (Vector2i pos in render) { for (int x = pos.x - 1; x <= pos.x + 1; x++) { for (int z = pos.z - 1; z <= pos.z + 1; z++) { Vector2i loadPos = new Vector2i(x, z); lock (this) { if (!loadedData.ContainsKey(loadPos) && !addition.Contains(loadPos)) { addition.Add(loadPos); } } } } } // load columns foreach (Vector2i pos in addition) { // load from file if available Column col = Load(pos); // generate terrain if (col == null) { col = TerrainGen.Generate(worldType, pos); } // add to loaded world lock (this) { loadedData.Add(pos, col); } } // render columns and queue for mesh update foreach (Vector2i pos in render) { // notify main thread if (pos.x >= xMin && pos.z >= zMin && pos.x <= xMax && pos.z <= zMax) { ColumnInstantiateTask loadTask = new ColumnInstantiateTask(pos, RenderColumn(pos)); lock (instantiateQueue) instantiateQueue.Add(loadTask); lock (this) renderedData.Add(pos); } } }