//Get the voxel gradient at a specific 3D point public float3 CalculateVoxelGradient(float3 point) { float3 normal = new Vector3(); normal.x = MarchingCubeHelper.Density(point + new float3(1, 0, 0), terrainGenerationData) - MarchingCubeHelper.Density(point - new float3(1, 0, 0), terrainGenerationData); normal.y = MarchingCubeHelper.Density(point + new float3(0, 1, 0), terrainGenerationData) - MarchingCubeHelper.Density(point - new float3(0, 1, 0), terrainGenerationData); normal.z = MarchingCubeHelper.Density(point + new float3(0, 0, 1), terrainGenerationData) - MarchingCubeHelper.Density(point - new float3(0, 0, 1), terrainGenerationData); return(normal); }
//Get the voxel gradient using the voxel grid public float3 CalculateVoxelGradientFromGrid(float3 point) { float3 normal = new Vector3(); normal.x = voxels[MarchingCubeHelper.VoxelToArr(point + new float3(1, 0, 0), resolution + 2)] - voxels[MarchingCubeHelper.VoxelToArr(point - new float3(1, 0, 0), resolution + 2)]; normal.y = voxels[MarchingCubeHelper.VoxelToArr(point + new float3(0, 1, 0), resolution + 2)] - voxels[MarchingCubeHelper.VoxelToArr(point - new float3(0, 1, 0), resolution + 2)]; normal.z = voxels[MarchingCubeHelper.VoxelToArr(point + new float3(0, 0, 1), resolution + 2)] - voxels[MarchingCubeHelper.VoxelToArr(point - new float3(0, 0, 1), resolution + 2)]; return(normal); }
// Start is called before the first frame update void Start() { int index = 0; for (int y = 0; y < 2; y++) { for (int z = 0; z < 2; z++) { for (int x = 0; x < 2; x++) { Debug.Log("Real: " + new float3(x, y, z) + " Estimate: " + MarchingCubeHelper.ArrToVoxel(MarchingCubeHelper.VoxelToArr(new float3(x, y, z), 2), 2)); index++; } } } }
//Generate mesh public void Execute(int index) { float3 pos = MarchingCubeHelper.ArrToVoxel(index, resolution); int caseNum = 0; if (!terrainGenerationData.usePregeneratedVoxelData) { caseNum += ((MarchingCubeHelper.Density(scale * (pos) + chunkPosition, terrainGenerationData) < 0) ? 1 : 0); caseNum += ((MarchingCubeHelper.Density(scale * (pos + new float3(0, 1, 0)) + chunkPosition, terrainGenerationData) < 0) ? 1 : 0) * 2; caseNum += ((MarchingCubeHelper.Density(scale * (pos + new float3(1, 1, 0)) + chunkPosition, terrainGenerationData) < 0) ? 1 : 0) * 4; caseNum += ((MarchingCubeHelper.Density(scale * (pos + new float3(1, 0, 0)) + chunkPosition, terrainGenerationData) < 0) ? 1 : 0) * 8; caseNum += ((MarchingCubeHelper.Density(scale * (pos + new float3(0, 0, 1)) + chunkPosition, terrainGenerationData) < 0) ? 1 : 0) * 16; caseNum += ((MarchingCubeHelper.Density(scale * (pos + new float3(0, 1, 1)) + chunkPosition, terrainGenerationData) < 0) ? 1 : 0) * 32; caseNum += ((MarchingCubeHelper.Density(scale * (pos + new float3(1, 1, 1)) + chunkPosition, terrainGenerationData) < 0) ? 1 : 0) * 64; caseNum += ((MarchingCubeHelper.Density(scale * (pos + new float3(1, 0, 1)) + chunkPosition, terrainGenerationData) < 0) ? 1 : 0) * 128; } else { //pos += new float3(1, 1, 1); caseNum += ((voxels[MarchingCubeHelper.VoxelToArr((pos), resolution + 2)] < 0) ? 1 : 0); caseNum += ((voxels[MarchingCubeHelper.VoxelToArr((pos + new float3(0, 1, 0)), resolution + 2)] < 0) ? 1 : 0) * 2; caseNum += ((voxels[MarchingCubeHelper.VoxelToArr((pos + new float3(1, 1, 0)), resolution + 2)] < 0) ? 1 : 0) * 4; caseNum += ((voxels[MarchingCubeHelper.VoxelToArr((pos + new float3(1, 0, 0)), resolution + 2)] < 0) ? 1 : 0) * 8; caseNum += ((voxels[MarchingCubeHelper.VoxelToArr((pos + new float3(0, 0, 1)), resolution + 2)] < 0) ? 1 : 0) * 16; caseNum += ((voxels[MarchingCubeHelper.VoxelToArr((pos + new float3(0, 1, 1)), resolution + 2)] < 0) ? 1 : 0) * 32; caseNum += ((voxels[MarchingCubeHelper.VoxelToArr((pos + new float3(1, 1, 1)), resolution + 2)] < 0) ? 1 : 0) * 64; caseNum += ((voxels[MarchingCubeHelper.VoxelToArr((pos + new float3(1, 0, 1)), resolution + 2)] < 0) ? 1 : 0) * 128; } int currentTriangleIndex; NativeList <int> trianglesTemp = new NativeList <int>(0, Allocator.Temp); for (int i = 0; i < 16; i++) { currentTriangleIndex = triangulationTable[caseNum * 16 + i]; if (currentTriangleIndex != -1) { trianglesTemp.Add(currentTriangleIndex);//Make triangle face triangles[index * 15 + i] = currentTriangleIndex + index * 12; } } float3 vertex; for (int i = 0; i < 12; i++) { if (trianglesTemp.Contains(i)) { float3 gradient = CalculateVoxelGradientFromGrid(pos + new float3(1, 1, 1)); if (terrainGenerationData.interpolation) { //Use interpolation when placing the current vertex float lerp = 0.5f; if (terrainGenerationData.usePregeneratedVoxelData) { lerp = Mathf.InverseLerp(voxels[MarchingCubeHelper.VoxelToArr(edgeTable[i] + pos, resolution + 2)], voxels[MarchingCubeHelper.VoxelToArr(edgeTable2[i] + pos, resolution + 2)], 0); vertex = (math.lerp(edgeTable[i], edgeTable2[i], lerp) + pos); gradient = math.lerp(CalculateVoxelGradientFromGrid(edgeTable[i] + pos), CalculateVoxelGradientFromGrid(edgeTable2[i] + pos), lerp); } else { lerp = Mathf.InverseLerp(MarchingCubeHelper.Density(scale * (edgeTable[i] + pos) + chunkPosition, terrainGenerationData), MarchingCubeHelper.Density(scale * (edgeTable2[i] + pos) + chunkPosition, terrainGenerationData), 0); vertex = (math.lerp(edgeTable[i], edgeTable2[i], lerp) + pos); if (terrainGenerationData.useVertexPosAsGradientSource) { gradient = CalculateVoxelGradient(vertex * scale + chunkPosition); } } //vertex = (math.lerp(edgeTable[i], edgeTable2[i], Mathf.InverseLerp(MarchingCubeHelper.Density(scale * (edgeTable[i] + pos) + chunkPosition, terrainGenerationData), MarchingCubeHelper.Density(scale * (edgeTable2[i] + pos) + chunkPosition, terrainGenerationData), 0)) + pos); vertices[index * 12 + i] = vertex * scale;//Add vertex at correct position colors[index * 12 + i] = MarchingCubeHelper.ColorDensity(vertex * scale + chunkPosition, gradient, terrainColorData); } else { //Do not use interpolation when placing the current vertex vertex = (math.lerp(edgeTable[i], edgeTable2[i], 0.5f)) + pos; if (terrainGenerationData.useVertexPosAsGradientSource && !terrainGenerationData.usePregeneratedVoxelData) { gradient = CalculateVoxelGradient(vertex * scale + chunkPosition); } vertices[index * 12 + i] = vertex * scale; colors[index * 12 + i] = MarchingCubeHelper.ColorDensity(vertex * scale + chunkPosition, gradient, terrainColorData); } } else { vertices[index * 12 + i] = -Vector3.one; //We dont need to make this unused vertex compute its position colors[index * 12 + i] = Color.clear; } } }
public void Execute(int index) { voxels[index] = MarchingCubeHelper.Density(scale * MarchingCubeHelper.ArrToVoxel(index, resolution) + chunkPosition - (new float3(1, 1, 1) * scale), terrainGenerationData); }