public static void GenerateChunkInterior(List <Vector3> vertices, List <int> triangles, sbyte[][][][] data, int res) { for (int x = 2; x < res - 2; x++) { for (int y = 2; y < res - 2; y++) { for (int z = 2; z < res - 2; z++) { Util.GridCell cell = new Util.GridCell(); cell.points = new Util.Point[8]; for (int i = 0; i < 8; i++) { Vector3Int offset = new Vector3Int((int)Tables.CellOffsets[i].x, (int)Tables.CellOffsets[i].y, (int)Tables.CellOffsets[i].z) + new Vector3Int(x, y, z); sbyte density = data[(int)offset.x][offset.y][offset.z][0]; cell.points[i].density = density; cell.points[i].position = offset; } GenerateRegularCell(cell, vertices, triangles, 0); } } } }
public static void GenerateRegularCell(Util.GridCell cell, List <Vector3> vertices, List <int> triangles, float isovalue) { Vector3[] vertlist = new Vector3[12]; int i, ntriang; int cubeindex; cubeindex = 0; if (cell.points[0].density < isovalue) { cubeindex |= 1; } if (cell.points[1].density < isovalue) { cubeindex |= 2; } if (cell.points[2].density < isovalue) { cubeindex |= 4; } if (cell.points[3].density < isovalue) { cubeindex |= 8; } if (cell.points[4].density < isovalue) { cubeindex |= 16; } if (cell.points[5].density < isovalue) { cubeindex |= 32; } if (cell.points[6].density < isovalue) { cubeindex |= 64; } if (cell.points[7].density < isovalue) { cubeindex |= 128; } /* Cube is entirely in/out of the surface */ if (Tables.edgeTable[cubeindex] == 0) { return; } /* Find the vertices where the surface intersects the cube */ if ((Tables.edgeTable[cubeindex] & 1) == 1) { vertlist[0] = UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[1]); } if ((Tables.edgeTable[cubeindex] & 2) == 2) { vertlist[1] = UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2]); } if ((Tables.edgeTable[cubeindex] & 4) == 4) { vertlist[2] = UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[3]); } if ((Tables.edgeTable[cubeindex] & 8) == 8) { vertlist[3] = UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0]); } if ((Tables.edgeTable[cubeindex] & 16) == 16) { vertlist[4] = UtilFuncs.Lerp(isovalue, cell.points[4], cell.points[5]); } if ((Tables.edgeTable[cubeindex] & 32) == 32) { vertlist[5] = UtilFuncs.Lerp(isovalue, cell.points[5], cell.points[6]); } if ((Tables.edgeTable[cubeindex] & 64) == 64) { vertlist[6] = UtilFuncs.Lerp(isovalue, cell.points[6], cell.points[7]); } if ((Tables.edgeTable[cubeindex] & 128) == 128) { vertlist[7] = UtilFuncs.Lerp(isovalue, cell.points[7], cell.points[4]); } if ((Tables.edgeTable[cubeindex] & 256) == 256) { vertlist[8] = UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[4]); } if ((Tables.edgeTable[cubeindex] & 512) == 512) { vertlist[9] = UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[5]); } if ((Tables.edgeTable[cubeindex] & 1024) == 1024) { vertlist[10] = UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[6]); } if ((Tables.edgeTable[cubeindex] & 2048) == 2048) { vertlist[11] = UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[7]); } /* Create the triangle */ ntriang = 0; for (i = 0; Tables.triTable[cubeindex][i] != -1; i += 3) { ntriang++; } for (i = 0; Tables.triTable[cubeindex][i] != -1; i++) { triangles.Add(vertices.Count); vertices.Add(vertlist[Tables.triTable[cubeindex][i]]); } }
public static void GenerateChunkExterior(List <Vector3> vertices, List <int> triangles, sbyte[][][][] data, byte chunkLod, int res) { int rm2 = res - 2; int rm4 = res - 4; for (int x = 0; x < res; x += 2) { for (int y = 0; y < res; y += 2) { for (int z = 0; z < res; z += 2) { bool isMinimal = x == 0 || y == 0 || z == 0; bool isMaximal = x == rm2 || y == rm2 || z == rm2; if (!isMinimal && !isMaximal) { continue; } byte cellLod = 0; if (x == 0) { cellLod |= 1; } if (x == rm2) { cellLod |= 2; } if (y == 0) { cellLod |= 4; } if (y == rm2) { cellLod |= 8; } if (z == 0) { cellLod |= 16; } if (z == rm2) { cellLod |= 32; } cellLod = (byte)(cellLod & chunkLod); byte cellLod2 = 0; if (x == 2) { cellLod2 |= 1; } if (x == rm4) { cellLod2 |= 2; } if (y == 2) { cellLod2 |= 4; } if (y == rm4) { cellLod2 |= 8; } if (z == 2) { cellLod2 |= 16; } if (z == rm4) { cellLod2 |= 32; } cellLod2 = (byte)(cellLod2 & chunkLod); int iPos = -1; int numOnes = 0; for (int i = 0; i < 6; i++) { if (((cellLod >> i) & 1) == 1) { numOnes++; iPos = i; } } if (numOnes == 1) { GenerateTransitionCell(new Vector3Int(x, y, z), vertices, triangles, cellLod2, data, tvCellRotations[iPos]); } else { Util.GridCell cell = new Util.GridCell(); cell.points = new Util.Point[8]; for (int i = 0; i < 8; i++) { Vector3Int offset = (new Vector3Int((int)Tables.CellOffsets[i].x, (int)Tables.CellOffsets[i].y, (int)Tables.CellOffsets[i].z)) * 2 + new Vector3Int(x, y, z); sbyte density = data[(int)offset.x][offset.y][offset.z][0]; cell.points[i].density = density; cell.points[i].position = offset; } GenerateRegularCell(cell, vertices, triangles, 0); } } } } }
public static void PolyganiseTetrahedron(Util.GridCell cell, List <Vector3> vertices, float isovalue) { int triangleIndex = 0; if (cell.points[0].density < isovalue) { triangleIndex |= 1; } if (cell.points[1].density < isovalue) { triangleIndex |= 2; } if (cell.points[2].density < isovalue) { triangleIndex |= 4; } if (cell.points[3].density < isovalue) { triangleIndex |= 8; } // these cases were taken from https://github.com/Calvin-L/MarchingTetrahedrons/blob/master/Decimate.cpp switch (triangleIndex) { case 0: case 15: break; case 0x01: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[1])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2])); break; case 0x02: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3])); break; case 0x04: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[1])); break; case 0x08: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[1])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0])); break; case 0x03: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[1])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3])); break; case 0x05: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[3])); break; case 0x09: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[1])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2])); break; case 0x06: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[1])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[2])); break; case 0x0C: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[1])); break; case 0x0A: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0])); break; case 0x07: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[3], cell.points[1])); break; case 0x0B: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[1])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[2], cell.points[0])); break; case 0x0D: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[0])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[3])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[1], cell.points[2])); break; case 0x0E: vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[1])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[2])); vertices.Add(UtilFuncs.Lerp(isovalue, cell.points[0], cell.points[3])); break; } }