public static SafeMesh BuildMesh(float[,,] voxels) { List <Vector3> vector3s = new List <Vector3>(); List <int> nums = new List <int>(); float[] singleArray = new float[8]; Vector3[] vector3Array = new Vector3[12]; // Iterate aka march through every voxel in the 3d space for (int i = 0; i < voxels.GetLength(0) - 1; i++) { for (int j = 0; j < voxels.GetLength(1) - 1; j++) { for (int k = 0; k < voxels.GetLength(2) - 1; k++) { FillCube(i, j, k, voxels, singleArray); MarchCube(new Vector3((float)i, (float)j, (float)k), singleArray, vector3s, nums, vector3Array); } } } // Build mesh SafeMesh safeMesh = new SafeMesh() { Vertices = vector3s.ToArray(), Triangles = nums.ToArray() }; return(safeMesh); }
private SafeMesh GenerateCaveMap(Vector3 offsets) { int size = WorldBuilder.CHUNK_SIZE + 1; Tile currentTile = WorldBuilder.GetTile(offsets); // Gets added to coordinates, is a decimal to make sure it does not end up at an integer float addendum = 1000.17777f; // Coordinates are divided by scale, larger scale = larger/more spread out caves float scale = 20f; float[,,] caveMap = new float[size, CAVE_DEPTH * 2, size]; for (int x = 0; x < size; x++) { for (int z = 0; z < size; z++) { // -5 to make the amount of rocks sticking out of the terrain lower int coordinateHeight = Mathf.FloorToInt(currentTile.HeightMap[x, z]) - 5; int caveHeight = coordinateHeight + CAVE_DEPTH; // Cave height make height dynamic based on heightmap[x,z] for (int y = 0; y < caveHeight; y++) { if (y == 0) { caveMap[x, y, z] = 1; } else if (y <= 2) { double tempVal = ridgedMultifractal.GetValue((z + offsets.z + addendum) / scale, (y + addendum) / scale, (x + offsets.x + addendum) / scale); int isCave = tempVal < 0 ? 0 : 1; caveMap[x, y, z] = isCave; } else { double tempVal = ridgedMultifractal.GetValue((x + offsets.x + addendum) / scale, (y + addendum) / scale, (z + offsets.z + addendum) / scale); int isCave = tempVal < 0.35 ? 0 : 1; caveMap[x, y, z] = isCave; } } } } SafeMesh safeMesh = MarchingCubes.BuildMesh(caveMap); safeMesh.position = offsets; return(safeMesh); }
private void OnCaveDataReceived(SafeMesh safeMesh) { Tile currentTile = WorldBuilder.GetTile(safeMesh.position); // Check if currentTile is not already unloaded if (currentTile != null) { Mesh mesh = new Mesh(); mesh.vertices = safeMesh.Vertices; mesh.triangles = safeMesh.Triangles; currentTile.Cave.MeshFilter.mesh = mesh; mesh.uv = GenerateUV.CalculateUVs(safeMesh.Vertices, 1); mesh.RecalculateNormals(); currentTile.Cave.MeshCollider.sharedMesh = mesh; currentTile.Cave.GameObject.SetActive(true); } }
private void CaveDataThread(Action <SafeMesh> callback, Vector3 offsets) { SafeMesh safeMesh = GenerateCaveMap(offsets); caveDataThreadInfoQueue.Enqueue(new CaveThreadInfo <SafeMesh>(callback, safeMesh)); }