private VertexList GenerateVertexList(VoxelCorners <float> voxelDensities, VoxelCorners <int3> voxelCorners, int edgeIndex, float isolevel) { var vertexList = new VertexList(); for (int i = 0; i < 12; i++) { if ((edgeIndex & (1 << i)) == 0) { continue; } int edgeStartIndex = Tables.EdgeIndexTable[2 * i + 0]; int edgeEndIndex = Tables.EdgeIndexTable[2 * i + 1]; int3 corner1 = voxelCorners[edgeStartIndex]; int3 corner2 = voxelCorners[edgeEndIndex]; float density1 = voxelDensities[edgeStartIndex]; float density2 = voxelDensities[edgeEndIndex]; vertexList[i] = VertexInterpolate(corner1, corner2, density1, density2, isolevel); } return(vertexList); }
private VoxelCorners <int3> GetCorners(int3 position) { VoxelCorners <int3> corners = new VoxelCorners <int3>(); for (int i = 0; i < 8; i++) { corners[i] = position + Tables.CubeCorners[i]; } return(corners); }
private VoxelCorners <float> GetDensities(int3 localPosition) { VoxelCorners <float> densities = new VoxelCorners <float>(); for (int i = 0; i < 8; i++) { int3 voxelCorner = localPosition + Tables.CubeCorners[i]; int densityIndex = voxelCorner.x * (chunkSize + 1) * (chunkSize + 1) + voxelCorner.y * (chunkSize + 1) + voxelCorner.z; densities[i] = this.densities[densityIndex]; } return(densities); }
/// <summary> /// The execute method required by the Unity Job System's IJobParallelFor /// </summary> /// <param name="index">The iteration index</param> public void Execute(int index) { // Voxel's position inside the chunk. Goes from (0, 0, 0) to (chunkSize-1, chunkSize-1, chunkSize-1) int3 voxelLocalPosition = new int3( index / (chunkSize * chunkSize), index / chunkSize % chunkSize, index % chunkSize); VoxelCorners <float> densities = GetDensities(voxelLocalPosition); int cubeIndex = CalculateCubeIndex(densities, isolevel); if (cubeIndex == 0 || cubeIndex == 255) { return; } VoxelCorners <int3> corners = GetCorners(voxelLocalPosition); int edgeIndex = Tables.EdgeTable[cubeIndex]; VertexList vertexList = GenerateVertexList(densities, corners, edgeIndex, isolevel); // Index at the beginning of the row int rowIndex = 15 * cubeIndex; for (int i = 0; Tables.TriangleTable[rowIndex + i] != -1 && i < 15; i += 3) { int triangleIndex = counter.Increment() * 3; vertices[triangleIndex + 0] = vertexList[Tables.TriangleTable[rowIndex + i + 0]]; triangles[triangleIndex + 0] = triangleIndex + 0; vertices[triangleIndex + 1] = vertexList[Tables.TriangleTable[rowIndex + i + 1]]; triangles[triangleIndex + 1] = triangleIndex + 1; vertices[triangleIndex + 2] = vertexList[Tables.TriangleTable[rowIndex + i + 2]]; triangles[triangleIndex + 2] = triangleIndex + 2; } }
private int CalculateCubeIndex(VoxelCorners <float> voxelDensities, float isolevel) { int cubeIndex = 0; if (voxelDensities.Corner1 < isolevel) { cubeIndex |= 1; } if (voxelDensities.Corner2 < isolevel) { cubeIndex |= 2; } if (voxelDensities.Corner3 < isolevel) { cubeIndex |= 4; } if (voxelDensities.Corner4 < isolevel) { cubeIndex |= 8; } if (voxelDensities.Corner5 < isolevel) { cubeIndex |= 16; } if (voxelDensities.Corner6 < isolevel) { cubeIndex |= 32; } if (voxelDensities.Corner7 < isolevel) { cubeIndex |= 64; } if (voxelDensities.Corner8 < isolevel) { cubeIndex |= 128; } return(cubeIndex); }