void SetupOutline(ChunkConfig chunk, Vector2Int loc) { var terrainGen = chunk.terrainGen; using (ComputeBuffer outBuf = new ComputeBuffer(chunk.gridCount, sizeof(float))) { // Setup compute shader. int k = terrainGen.FindKernel("Main"); terrainGen.SetFloat("pi", PI); terrainGen.SetFloat("rdSeed", chunk.seed); terrainGen.SetFloats("resolution", chunk.resolution.x, chunk.resolution.y); terrainGen.SetFloat("caveShrinkY", chunk.caveShrinkY); terrainGen.SetFloat("caveEliminateY", chunk.caveEliminateY); terrainGen.SetFloats("roughness", chunk.roughness); terrainGen.SetFloats("localScale", chunk.localScale.x, chunk.localScale.y); terrainGen.SetFloats("freq", chunk.frequency.x, chunk.frequency.y); terrainGen.SetFloats("offset", chunk.OffsetBottomLeft(loc).x, chunk.OffsetBottomLeft(loc).y); terrainGen.SetFloats("amplitude", chunk.amplitude.x, chunk.amplitude.y); terrainGen.SetBuffer(k, "output", outBuf); // Draw chunk terrain. terrainGen.Dispatch(k, CeilToInt(chunk.resolution.x / 16.0f), CeilToInt(chunk.resolution.y / 16.0f), 1); // check the databuf and its size. if (dataBuf == null || dataBuf.Length != chunk.gridCount) { dataBuf = new float[chunk.gridCount]; } // get data from GPU back into main memory. outBuf.GetData(dataBuf); } // Check chunk points. // Mesh vertices should be in *local* space that relative to the bottom-left corner. if (segs == null) { segs = new List <Segment>(); } segs.Clear(); for (int x = 0; x < chunk.resolution.x; x++) { for (int y = 0; y < chunk.resolution.y; y++) { int val = RoundToInt(dataBuf[x + y * chunk.resolution.x]) ^ 0xF; MarchingCube.Get(val, new Vector2(x, y), segs); } } for (int i = 0; i < segs.Count; i++) { segs[i] = new Segment(segs[i].from * chunk.localScale, segs[i].to * chunk.localScale); } lks = segs.LinkUp().Smooth(Util.SmoothAverage).Smooth(Util.SmoothFill); }
// Take configurations and setup all components of this GameObject. public GameObject Setup(ChunkConfig config, Vector2Int loc) { this.gameObject.name = loc.EncodeChunkOffset(); // Setup verts and indices. SetupOutline(config, loc); // Prepare component builds. var verts = new List <Vector3>(); foreach (var lk in lks) { for (int i = 1; i < lk.Count; i++) { verts.Add(lk[i - 1]); verts.Add(lk[i]); } } // Build up mesh. // This mesh is used for rendering outlines. var ms = gameObject.GetComponent <MeshFilter>(); var indices = new List <int>(); indices.AddIntRange(0, verts.Count - 1); ms.mesh = new Mesh().SubmitData(verts, indices, MeshTopology.Lines); // Build up colliders. var col = new List <EdgeCollider2D>(GetComponentsInChildren <EdgeCollider2D>()); for (int i = 0; i < lks.Count; i++) { if (col.Count <= i) { col.Add(this.gameObject.AddComponent <EdgeCollider2D>()); } var cx = col[i]; cx.points = lks[i].ToArray(); cx.offset = Vector2.zero; cx.sharedMaterial = config.terrainMaterial; } transform.position = config.OffsetBottomLeft(loc); this.config = config; return(this.gameObject); }