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; }
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); }