예제 #1
0
        public void TestSpiralForEach3d()
        {
            var spi = SpiralIterators.Cube(new Vector3Int(1, 1, 1));

            String             assume = "(0, 0, 0), (1, 0, 0), (1, -1, 0), (0, -1, 0), (-1, -1, 0), (-1, 0, 0), (-1, 1, 0), (0, 1, 0), (1, 1, 0), (0, 0, -1), (1, 0, -1), (1, -1, -1), (0, -1, -1), (-1, -1, -1), (-1, 0, -1), (-1, 1, -1), (0, 1, -1), (1, 1, -1), (0, 0, 1), (1, 0, 1), (1, -1, 1), (0, -1, 1), (-1, -1, 1), (-1, 0, 1), (-1, 1, 1), (0, 1, 1), (1, 1, 1)";
            IList <Vector3Int> test   = new List <Vector3Int>();

            foreach (Vector3Int v in spi)
            {
                test.Add(v);
            }

            string result = String.Join(", ", test);

            Assert.IsTrue(assume.SequenceEqual(result), $"Lists not equal:\n\tAssumed:{assume}\n\tTest:{result}");
        }
예제 #2
0
    void InitVisibleChunks()
    {
        if (chunks == null)
        {
            return;
        }
        CreateChunkHolder();

        Vector3    p           = viewer.position;
        Vector3    ps          = p / boundsSize;
        Vector3Int viewerCoord = new Vector3Int(Mathf.RoundToInt(ps.x), Mathf.RoundToInt(ps.y), Mathf.RoundToInt(ps.z));

        int   maxChunksInView = Mathf.CeilToInt(viewDistance / boundsSize);
        float sqrViewDistance = viewDistance * viewDistance;

        // Go through all existing chunks and flag for recyling if outside of max view dst
        float t0 = Time.realtimeSinceStartup;

        Chunk   chunk;
        Vector3 centre;
        Vector3 viewerOffset;
        Vector3 o;
        float   sqrDst;

        for (int i = chunks.Count - 1; i >= 0; i--)
        {
            if (Time.realtimeSinceStartup - t0 > (1.0 / fpsBreakout))
            {
                return;
            }

            chunk        = chunks[i];
            centre       = CentreFromCoord(chunk.coord);
            viewerOffset = p - centre;
            o            = new Vector3(Mathf.Abs(viewerOffset.x), Mathf.Abs(viewerOffset.y), Mathf.Abs(viewerOffset.z)) - Vector3.one * boundsSize / 2;
            sqrDst       = new Vector3(Mathf.Max(o.x, 0), Mathf.Max(o.y, 0), Mathf.Max(o.z, 0)).sqrMagnitude;
            if (sqrDst > sqrViewDistance)
            {
                existingChunks.Remove(chunk.coord);
                recycleableChunks.Enqueue(chunk);
                chunks.RemoveAt(i);
            }
        }

        collect_countdown -= 1;
        if (collect_countdown == 0)
        {
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized, blocking: false);
            collect_countdown = 10;
        }

        Vector3Int coord;

        foreach (Vector3Int spi in SpiralIterators.Cube(new Vector3Int(maxChunksInView, maxChunksInView, maxChunksInView)))
        {
            if (Time.realtimeSinceStartup - t0 > (1.0 / fpsBreakout))
            {
                return;
            }

            coord = spi + viewerCoord;

            if (existingChunks.ContainsKey(coord))
            {
                if (!blockingGpu && (((!existingChunks[coord].asyncOp0?.done) ?? true) ||
                                     ((!existingChunks[coord].asyncOp1?.done) ?? true) ||
                                     ((!existingChunks[coord].asyncOp2?.done) ?? true)))
                {
                    // wait for centermost chunks to finish
                    return;
                }
                else
                {
                    continue;
                }
            }

            centre       = CentreFromCoord(coord);
            viewerOffset = p - centre;
            o            = new Vector3(Mathf.Abs(viewerOffset.x), Mathf.Abs(viewerOffset.y), Mathf.Abs(viewerOffset.z)) - Vector3.one * boundsSize / 2;
            sqrDst       = new Vector3(Mathf.Max(o.x, 0), Mathf.Max(o.y, 0), Mathf.Max(o.z, 0)).sqrMagnitude;

            // Chunk is within view distance and should be created (if it doesn't already exist)
            if (sqrDst <= sqrViewDistance)
            {
                Bounds bounds = new Bounds(CentreFromCoord(coord), Vector3.one * boundsSize);
                if (IsVisibleFrom(bounds, Camera.main))
                {
                    if (recycleableChunks.Count > 0)
                    {
                        chunk       = recycleableChunks.Dequeue();
                        chunk.coord = coord;
                        existingChunks.Add(coord, chunk);
                        chunks.Add(chunk);
                        UpdateChunkMesh(chunk, blockingGpu);
                    }
                    else
                    {
                        chunk       = CreateChunk(coord);
                        chunk.coord = coord;
                        chunk.SetUp(mat, generateColliders);
                        existingChunks.Add(coord, chunk);
                        chunks.Add(chunk);
                        UpdateChunkMesh(chunk, blockingGpu);
                    }
                }
            }
        }
    }