Пример #1
0
        public Chunk[] GetChunksInRange(int x, int z, int range, bool createInside, bool removeOutside)
        {
            #region Chunks min and max
            int visChunkSize = chunkSize-overlap*2;

            int csx = (int)(1.0f*(x-range-overlap) / visChunkSize);
            int cex = (int)(1.0f*(x+range-overlap) / visChunkSize);
            int csz = (int)(1.0f*(z-range-overlap) / visChunkSize);
            int cez = (int)(1.0f*(z+range-overlap) / visChunkSize);

            if (x-range<0) csx--; if (x+range<0) cex--;
            if (z-range<0) csz--; if (z+range<0) cez--;
            #endregion

            #region defining array dimensions and filling array
            int chunksCountX = Mathf.Abs(cex-csx)+1;
            int chunksCountZ = Mathf.Abs(cez-csz)+1;
            Chunk[] chunks = new Chunk[chunksCountX*chunksCountZ];
            #endregion

            #region filling existant chunks list (and removing outside)
            for (int i=activeChunks.Count-1; i>=0; i--)
            {
                if (activeChunks[i].coordX < csx || activeChunks[i].coordX > cex ||
                    activeChunks[i].coordZ < csz || activeChunks[i].coordZ > cez) //out of range
                {
                    if (removeOutside)
                    {
                        //DestroyImmediate(activeChunks[i].gameObject);
                        chunkPool.Add(activeChunks[i]);
                        activeChunks[i].Clear();

                        activeChunks.RemoveAt(i);
                    }
                }

                //if in range
                else chunks[ (activeChunks[i].coordZ-csz)*chunksCountX + (activeChunks[i].coordX-csx) ] = activeChunks[i];
            }
            #endregion

            #region creating non-existant chunks
            if (createInside)
                for (int cx=0; cx<chunksCountX; cx++)
                    for (int cz=0; cz<chunksCountZ; cz++)
            {
                int chunkCoord = cz*chunksCountX + cx;
                if (chunks[chunkCoord] == null)
                {
                    //taking from a pool
                    if (chunkPool.Count > 0)
                    {
                        chunks[cz*chunksCountX + cx] = chunkPool[chunkPool.Count-1];
                        chunkPool.RemoveAt(chunkPool.Count-1);
                    }

                    //or creating new
                    else chunks[chunkCoord] = Chunk.CreateChunk(this);

                    //and initializing
                    chunks[chunkCoord].Init(cx+csx,cz+csz);

                    if (!activeChunks.Contains(chunks[chunkCoord])) activeChunks.Add(chunks[chunkCoord]);
                }
            }
            #endregion

            return chunks;
        }
Пример #2
0
        public Mesh[] MarchChunk(object state)
        {
            Mesh[] result = new Mesh[2];

            Octree node = (Octree)state;
            //Debug.Log("MARCH: " + node.center);
            //Debug.Log("MARCH1: " + node.center);

            int id = Thread.CurrentThread.ManagedThreadId % THREAD_MAX;

            //Debug.Log("MARCH: " + id);

            ComputeBuffer noiseDataBuffer   = noiseBuffs[id];
            ComputeBuffer trianglesBuffer   = trigBuffs[id];
            ComputeBuffer PPTrianglesBuffer = trigBuffs_PP[id];
            ComputeBuffer counterBuffer     = countBuffs[id];

            int[] bufferCount = bufferCounts[id];
            //Debug.Log("MARCH2: " + node.center);



            perlin_shader.SetBuffer(PNkernel, "output", noiseDataBuffer);
            //Debug.Log("MARCH3: " + node.center);

            perlin_shader.SetVector("minCorner", new float4(node.bounds.min, 0));
            perlin_shader.SetInt("sampleSize", CHUNK_SIZE + 1);
            perlin_shader.SetInt("scale", node.level);
            //Debug.Log("MARCH4: " + node.center);

            int groupSize = Chunk.CHUNK_SIZE / 8;

            //Debug.Log("MARCH5: " + node.center);

            perlin_shader.Dispatch(PNkernel, groupSize + 1, groupSize + 1, groupSize + 1);

            //data = new float4[(size + 1) * (size + 1) * (size + 1)];
            //perlinBuffer.GetData(data);
            //this.hasMesh = HasMesh();
            //AsyncGPUReadbackRequest PVBrequest = AsyncGPUReadback.Request(noiseDataBuffer);
            //AsyncGPUReadbackRequest PPPVBrequest = AsyncGPUReadback.Request(PPNoiseDataBuffer);

            //StartCoroutine(GetNoiseDataCoroutine(PVBrequest, PPPVBrequest, node.chunk));
            Chunk chunk = node.chunk;

            //while (!PVBrequest.done || !PPPVBrequest.done) continue;
            //if (PVBrequest.hasError || PPPVBrequest.hasError) { yield break};
            //float4[] data = new float4[(CHUNK_SIZE + 1) * (CHUNK_SIZE + 1) * (CHUNK_SIZE + 1)];
            //noiseDataBuffer.GetData(data);
            //Debug.Log(data[0] + " " + data[data.Length - 1]);
            ////chunk.PPData = PPPVBrequest.GetData<float4>();
            //bool hasMesh = false;
            ////if (chunk.center.x == -128f && chunk.center.y == -128f && chunk.center.z == -128f) {
            //    float4[] d = data;
            //    for (int i = 0; i < d.Length; i++) {
            //        if (!(d[i].w > 0 && d[0].w > 0 || (d[i].w <= 0 && d[0].w <= 0))) {
            //            hasMesh = true;
            //            break;
            //        }
            //    }
            //    Debug.Log(hasMesh);
            ////}
            ////Debug.Log(result.Length + " " + chunk.data.Value.Length);
            //chunk.hasMesh = hasMesh;
            //chunk.data = data;
            //if (!hasMesh) yield break;
            //if (((Vector3)chunk.center + Vector3.one * chunk.size / 2).y < chunk.data.Value[0].y) Debug.LogError("Data out of NODE");
            //if (((Vector3)chunk.center + Vector3.one * chunk.size / 2).y < chunk.PPData.Value[0].y) Debug.LogError("PPData out of NODE");


            //Debug.Log("MARCH " + chunk.center);
            trianglesBuffer.SetCounterValue(0);
            PPTrianglesBuffer.SetCounterValue(0);

            mc_shader.SetBuffer(MCkernel, "dataBuffer", noiseDataBuffer);
            mc_shader.SetBuffer(MCkernel, "trianglesBuffer", trianglesBuffer);
            mc_shader.SetBuffer(MCkernel, "PPTrianglesBuffer", PPTrianglesBuffer);

            mc_shader.SetFloat("isolevel", MarchingCube.isolevel);
            mc_shader.SetInt("dataSize", CHUNK_SIZE + 1);
            //MCShader.SetInt("scale", node.level + 1);


            mc_shader.Dispatch(MCkernel, groupSize, groupSize, groupSize);

            ComputeBuffer.CopyCount(trianglesBuffer, counterBuffer, 0);
            counterBuffer.GetData(bufferCount);
            Triangle[] triangles = new Triangle[bufferCount[0]];
            trianglesBuffer.GetData(triangles);

            ComputeBuffer.CopyCount(PPTrianglesBuffer, counterBuffer, 0);
            counterBuffer.GetData(bufferCount);
            Triangle[] PPtriangles = new Triangle[bufferCount[0]];
            PPTrianglesBuffer.GetData(PPtriangles);

            result[0] = GenMesh(triangles);
            if (chunk.mesh != null && ((Vector3)chunk.center + Vector3.one * chunk.size / 2).y < chunk.mesh.vertices[0].y)
            {
                Debug.LogError("Mesh out of NODE" + chunk.center + " " + node.level);
            }
            result[1] = GenMesh(PPtriangles);

            if (result[1] == null && result[0] != null || result[0] == null && result[1] != null)
            {
                Debug.LogError("!!!!!!!!!!!!!!!!!!!");
            }

            if (result[0] != null && result[1] != null)
            {
                chunk.hasMesh = true;
            }
            chunk.calculated = true;
            //Debug.Log("MARCH: " + node.center);
            return(result);
        }