//private static int getX(int index, int dimension) { // return (y * VERTEX_DIMENSION + z) * VERTEX_DIMENSION + x; //} //private static int getY(int index, int dimension) { // return ((VERTEX_DIMENSION + x) * VERTEX_DIMENSION + z) * VERTEX_DIMENSION + y; //} //private static int getZ(int index, int dimension) { // return ((VERTEX_DIMENSION * 2 + x) * VERTEX_DIMENSION + y) * VERTEX_DIMENSION + z; //} //private static int getDimension(int index) { // return index / (VERTEX_DIMENSION * VERTEX_DIMENSION * VERTEX_DIMENSION); //} private Voxel[, ,] createVoxelArray(VoxelUpdateInfo info) { setDimensions(info); Voxel[, ,] voxels = new Voxel[VERTEX_DIMENSION, VERTEX_DIMENSION, VERTEX_DIMENSION]; for (byte y = (byte)(1 - yExtend); y < yDim; ++y) { for (byte z = (byte)(1 - zExtend); z < zDim; ++z) { voxels[1 - xExtend, y, z] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - xExtend, VOXEL_DIMENSION - 1 + y, VOXEL_DIMENSION - 1 + z).toVoxel(); } } for (byte x = (byte)(2 - xExtend); x < xDim; ++x) { for (byte z = (byte)(1 - zExtend); z < zDim; ++z) { voxels[x, 1 - yExtend, z] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + x, VOXEL_DIMENSION - yExtend, VOXEL_DIMENSION - 1 + z).toVoxel(); } } for (byte x = (byte)(2 - xExtend); x < xDim; ++x) { for (byte y = (byte)(2 - yExtend); y < yDim; ++y) { voxels[x, y, 1 - zExtend] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + x, VOXEL_DIMENSION - 1 + y, VOXEL_DIMENSION - zExtend).toVoxel(); } } return(voxels); }
public VoxelUpdateInfo(VoxelUpdateInfo super, byte xi, byte yi, byte zi) : this() { size = super.size / VoxelBlock.CHILD_DIMENSION; detailLevel = (byte)(super.detailLevel + 1); control = super.control; x = super.x * VoxelBlock.CHILD_DIMENSION + xi; y = super.y * VoxelBlock.CHILD_DIMENSION + yi; z = super.z * VoxelBlock.CHILD_DIMENSION + zi; for (byte xii = 0; xii < DIMENSION; ++xii) { for (byte yii = 0; yii < DIMENSION; ++yii) { for (byte zii = 0; zii < DIMENSION; ++zii) { blocks[xii, yii, zii] = super.getSub(VoxelBlock.CHILD_COUNT_POWER, (byte)(xii + xi + VoxelBlock.CHILD_DIMENSION - 1), (byte)(yii + yi + VoxelBlock.CHILD_DIMENSION - 1), (byte)(zii + zi + VoxelBlock.CHILD_DIMENSION - 1)); renderers[xii, yii, zii] = super.renderers[(int)((xii + xi + 1) * 0.5), (int)((yii + yi + 1) * 0.5), (int)((zii + zi + 1) * 0.5)]; if (renderers[xii, yii, zii] == null || renderers[xii, yii, zii].old) { renderers[xii, yii, zii] = super.blocks[(int)((xii + xi + 1) * 0.5), (int)((yii + yi + 1) * 0.5), (int)((zii + zi + 1) * 0.5)].getRenderer(0, 0, 0, 0); if (renderers[xii, yii, zii] == null || renderers[xii, yii, zii].old) renderers[xii, yii, zii] = blocks[xii, yii, zii].getRenderer(0, 0, 0, 0); if (renderers[xii, yii, zii] != null && renderers[xii, yii, zii].old) renderers[xii, yii, zii] = null; } } } } }
public VoxelUpdateInfo(VoxelUpdateInfo super, byte xi, byte yi, byte zi) : this() { size = super.size / VoxelBlock.CHILD_DIMENSION; detailLevel = (byte)(super.detailLevel + 1); control = super.control; x = super.x * VoxelBlock.CHILD_DIMENSION + xi; y = super.y * VoxelBlock.CHILD_DIMENSION + yi; z = super.z * VoxelBlock.CHILD_DIMENSION + zi; for (byte xii = 0; xii < DIMENSION; ++xii) { for (byte yii = 0; yii < DIMENSION; ++yii) { for (byte zii = 0; zii < DIMENSION; ++zii) { blocks[xii, yii, zii] = super.getSub(VoxelBlock.CHILD_COUNT_POWER, (byte)(xii + xi + VoxelBlock.CHILD_DIMENSION - 1), (byte)(yii + yi + VoxelBlock.CHILD_DIMENSION - 1), (byte)(zii + zi + VoxelBlock.CHILD_DIMENSION - 1)); renderers[xii, yii, zii] = super.renderers[(int)((xii + xi + 1) * 0.5), (int)((yii + yi + 1) * 0.5), (int)((zii + zi + 1) * 0.5)]; if (renderers[xii, yii, zii] == null || renderers[xii, yii, zii].old) { renderers[xii, yii, zii] = super.blocks[(int)((xii + xi + 1) * 0.5), (int)((yii + yi + 1) * 0.5), (int)((zii + zi + 1) * 0.5)].getRenderer(0, 0, 0, 0); if (renderers[xii, yii, zii] == null || renderers[xii, yii, zii].old) { renderers[xii, yii, zii] = blocks[xii, yii, zii].getRenderer(0, 0, 0, 0); } if (renderers[xii, yii, zii] != null && renderers[xii, yii, zii].old) { renderers[xii, yii, zii] = null; } } } } } }
public void genMesh(VoxelUpdateInfo info) { if (control == null) { return; } size = info.size; Queue <int[]> triangleSet = new Queue <int[]>(); vertices = new Dictionary <int, object>(); vertexSubstances = new Dictionary <int, byte>(); Voxel[, ,] voxels = createVoxelArray(info); MarchingCubes.setup(info.size / VOXEL_DIMENSION, control.isoLevel, ref vertices, ref vertexSubstances, ref voxels, position - new Vector3(0.5f, 0.5f, 0.5f) * size / VOXEL_DIMENSION, null); int totalTris = 0; for (byte x = (byte)(1 - xExtend), x1 = (byte)(x + 1); x1 < xDim; x = x1++) { for (byte y = (byte)(1 - yExtend), y1 = (byte)(y + 1); y1 < yDim; y = y1++) { for (byte z = (byte)(1 - zExtend), z1 = (byte)(z + 1); z1 < zDim; z = z1++) { lock (control) { VoxelHolder block = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION + x, VOXEL_DIMENSION + y, VOXEL_DIMENSION + z); voxels[x1, y1, z1] = block.toVoxel(); int[] tris = MarchingCubes.lookupTriangles(x, y, z, x1, y1, z1); if (tris == null) { continue; } triangleSet.Enqueue(tris); totalTris += tris.Length; } } } } if (vertices.Count < 1) { applied = true; return; } List <int> triangles = new List <int>(); List <Vector3> finalVertices = new List <Vector3>(vertices.Count); //List<byte> finalMats = new List<byte>(vertices.Count); while (triangleSet.Count > 0) { int[] triangleList = triangleSet.Dequeue(); for (int i = 0; i < triangleList.Length; ++i) { if (vertices[triangleList[i]].GetType() == typeof(Vector3)) { finalVertices.Add((Vector3)vertices[triangleList[i]]); //finalMats.Add(vertexSubstances[triangleList[i]]); vertices[triangleList[i]] = finalVertices.Count - 1; } triangles.Add((int)vertices[triangleList[i]]); } } VERTS = finalVertices.ToArray(); TRIS = triangles.ToArray(); //MATS = finalMats.ToArray(); calcNorms(); alignEdge(info, 0, 1, 1); alignEdge(info, 2, 1, 1); alignEdge(info, 1, 0, 1); alignEdge(info, 1, 2, 1); alignEdge(info, 1, 1, 0); alignEdge(info, 1, 1, 2); lock (control) { control.enqueueJob(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z)); } }
public void addEdge(VoxelUpdateInfo info, byte x, byte y, byte z) { if (vertices == null) { return; } bool recalculate = false; Voxel[, ,] voxels = new Voxel[VERTEX_DIMENSION, VERTEX_DIMENSION, VERTEX_DIMENSION]; if (x == 0 /* && xExtend == 0*/) { recalculate = true; xExtend = 1; for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[0, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - xExtend, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[1, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (x == 2 /* && xDim < VERTEX_DIMENSION*/) { recalculate = true; xDim = VERTEX_DIMENSION; for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[VOXEL_DIMENSION + 1, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION * 2, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[VOXEL_DIMENSION, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION * 2 - 1, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (y == 0 /* && yExtend == 0*/) { recalculate = true; yExtend = 1; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[xi, 0, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - yExtend, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[xi, 1, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (y == 2 /* && yDim < VERTEX_DIMENSION*/) { recalculate = true; yDim = VERTEX_DIMENSION; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[xi, VOXEL_DIMENSION + 1, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION * 2, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[xi, VOXEL_DIMENSION, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION * 2 - 1, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (z == 0 /* && zExtend == 0*/) { recalculate = true; zExtend = 1; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { voxels[xi, yi, 0] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - zExtend).toVoxel(); voxels[xi, yi, 1] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION).toVoxel(); } } } else if (z == 2 /* && zDim < VERTEX_DIMENSION*/) { recalculate = true; zDim = VERTEX_DIMENSION; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { voxels[xi, yi, VOXEL_DIMENSION + 1] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION * 2).toVoxel(); voxels[xi, yi, VOXEL_DIMENSION] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION * 2 - 1).toVoxel(); } } } if (recalculate) { Queue <int[]> triangleSet = new Queue <int[]>(); MarchingCubes.setup(info.size / VOXEL_DIMENSION, control.isoLevel, ref vertices, ref vertexSubstances, ref voxels, position - new Vector3(0.5f, 0.5f, 0.5f) * size / VOXEL_DIMENSION, VERTS); byte xStart = (byte)(1 - xExtend + (VOXEL_DIMENSION + xExtend - 1) * (x / 2)); byte xEnd = (byte)(2 + (xDim - 2) * ((x + 1) / 2)); byte yStart = (byte)(1 - yExtend + (VOXEL_DIMENSION + yExtend - 1) * (y / 2)); byte yEnd = (byte)(2 + (yDim - 2) * ((y + 1) / 2)); byte zStart = (byte)(1 - zExtend + (VOXEL_DIMENSION + zExtend - 1) * (z / 2)); byte zEnd = (byte)(2 + (zDim - 2) * ((z + 1) / 2)); for (byte xi = xStart, x1 = (byte)(xi + 1); x1 < xEnd; xi = x1++) { for (byte yi = yStart, y1 = (byte)(yi + 1); y1 < yEnd; yi = y1++) { for (byte zi = zStart, z1 = (byte)(zi + 1); z1 < zEnd; zi = z1++) { int[] tris = MarchingCubes.lookupTriangles(xi, yi, zi, x1, y1, z1); if (tris == null) { continue; } triangleSet.Enqueue(tris); } } } if (vertices.Count < 1) { return; } List <int> newTriangles = new List <int>(TRIS); List <Vector3> newVertices = new List <Vector3>(VERTS); int tri = 0; while (triangleSet.Count > 0) { int[] triangleList = triangleSet.Dequeue(); for (int i = 0; i < triangleList.Length; ++i) { if (vertices[triangleList[i]].GetType() == typeof(Vector3)) { newVertices.Add((Vector3)vertices[triangleList[i]]); vertices[triangleList[i]] = newVertices.Count - 1; } newTriangles.Add((int)vertices[triangleList[i]]); } tri += triangleList.Length; } Vector3[] finalNorms = new Vector3[newVertices.Count]; Array.Copy(NORMS, finalNorms, NORMS.Length); int oldNormCount = NORMS.Length; VERTS = newVertices.ToArray(); TRIS = newTriangles.ToArray(); calcNorms(); Array.Copy(NORMS, oldNormCount, finalNorms, oldNormCount, finalNorms.Length - oldNormCount); NORMS = finalNorms; } alignEdge(info, x, y, z); control.enqueueJob(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z)); }
public void addEdge(VoxelUpdateInfo info, byte x, byte y, byte z) { if (vertices == null) return; bool recalculate = false; Voxel[, ,] voxels = new Voxel[VERTEX_DIMENSION, VERTEX_DIMENSION, VERTEX_DIMENSION]; if (x == 0/* && xExtend == 0*/) { recalculate = true; xExtend = 1; for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[0, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - xExtend, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[1, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (x == 2/* && xDim < VERTEX_DIMENSION*/) { recalculate = true; xDim = VERTEX_DIMENSION; for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[VOXEL_DIMENSION + 1, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION * 2, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[VOXEL_DIMENSION, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION * 2 - 1, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (y == 0/* && yExtend == 0*/) { recalculate = true; yExtend = 1; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[xi, 0, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - yExtend, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[xi, 1, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (y == 2/* && yDim < VERTEX_DIMENSION*/) { recalculate = true; yDim = VERTEX_DIMENSION; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[xi, VOXEL_DIMENSION + 1, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION * 2, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[xi, VOXEL_DIMENSION, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION * 2 - 1, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (z == 0/* && zExtend == 0*/) { recalculate = true; zExtend = 1; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { voxels[xi, yi, 0] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - zExtend).toVoxel(); voxels[xi, yi, 1] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION).toVoxel(); } } } else if (z == 2/* && zDim < VERTEX_DIMENSION*/) { recalculate = true; zDim = VERTEX_DIMENSION; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { voxels[xi, yi, VOXEL_DIMENSION + 1] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION * 2).toVoxel(); voxels[xi, yi, VOXEL_DIMENSION] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION * 2 - 1).toVoxel(); } } } if (recalculate) { Queue<int[]> triangleSet = new Queue<int[]>(); MarchingCubes.setup(info.size / VOXEL_DIMENSION, control.isoLevel, ref vertices, ref vertexSubstances, ref voxels, position - new Vector3(0.5f, 0.5f, 0.5f) * size / VOXEL_DIMENSION, VERTS); byte xStart = (byte)(1 - xExtend + (VOXEL_DIMENSION + xExtend - 1) * (x / 2)); byte xEnd = (byte)(2 + (xDim - 2) * ((x + 1) / 2)); byte yStart = (byte)(1 - yExtend + (VOXEL_DIMENSION + yExtend - 1) * (y / 2)); byte yEnd = (byte)(2 + (yDim - 2) * ((y + 1) / 2)); byte zStart = (byte)(1 - zExtend + (VOXEL_DIMENSION + zExtend - 1) * (z / 2)); byte zEnd = (byte)(2 + (zDim - 2) * ((z + 1) / 2)); for (byte xi = xStart, x1 = (byte)(xi + 1); x1 < xEnd; xi = x1++) { for (byte yi = yStart, y1 = (byte)(yi + 1); y1 < yEnd; yi = y1++) { for (byte zi = zStart, z1 = (byte)(zi + 1); z1 < zEnd; zi = z1++) { int[] tris = MarchingCubes.lookupTriangles(xi, yi, zi, x1, y1, z1); if (tris == null) continue; triangleSet.Enqueue(tris); } } } if (vertices.Count < 1) { return; } List<int> newTriangles = new List<int>(TRIS); List<Vector3> newVertices = new List<Vector3>(VERTS); List<Vector3> newNorms = new List<Vector3>(NORMS); int tri = 0; while (triangleSet.Count > 0) { int[] triangleList = triangleSet.Dequeue(); for (int i = 0; i < triangleList.Length; ++i) { if (vertices[triangleList[i]].GetType() == typeof(Vector3)) { newVertices.Add((Vector3)vertices[triangleList[i]]); newNorms.Add(Vector3.zero); vertices[triangleList[i]] = newVertices.Count - 1; } newTriangles.Add((int)vertices[triangleList[i]]); } tri += triangleList.Length; } Vector3[] finalNorms = new Vector3[newNorms.Count]; Array.Copy(NORMS, finalNorms, NORMS.Length); int oldNormCount = NORMS.Length; VERTS = newVertices.ToArray(); TRIS = newTriangles.ToArray(); calcNorms(); Array.Copy(NORMS, oldNormCount, finalNorms, oldNormCount, finalNorms.Length - oldNormCount); NORMS = finalNorms; } alignEdge(info, x, y, z); control.enqueueMeshApply(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z)); }
//private static int getX(int index, int dimension) { // return (y * VERTEX_DIMENSION + z) * VERTEX_DIMENSION + x; //} //private static int getY(int index, int dimension) { // return ((VERTEX_DIMENSION + x) * VERTEX_DIMENSION + z) * VERTEX_DIMENSION + y; //} //private static int getZ(int index, int dimension) { // return ((VERTEX_DIMENSION * 2 + x) * VERTEX_DIMENSION + y) * VERTEX_DIMENSION + z; //} //private static int getDimension(int index) { // return index / (VERTEX_DIMENSION * VERTEX_DIMENSION * VERTEX_DIMENSION); //} private Voxel[, ,] createVoxelArray(VoxelUpdateInfo info) { setDimensions(info); Voxel[, ,] voxels = new Voxel[VERTEX_DIMENSION, VERTEX_DIMENSION, VERTEX_DIMENSION]; for (byte y = (byte)(1 - yExtend); y < yDim; ++y) { for (byte z = (byte)(1 - zExtend); z < zDim; ++z) { voxels[1 - xExtend, y, z] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - xExtend, VOXEL_DIMENSION - 1 + y, VOXEL_DIMENSION - 1 + z).toVoxel(); } } for (byte x = (byte)(2 - xExtend); x < xDim; ++x) { for (byte z = (byte)(1 - zExtend); z < zDim; ++z) { voxels[x, 1 - yExtend, z] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + x, VOXEL_DIMENSION - yExtend, VOXEL_DIMENSION - 1 + z).toVoxel(); } } for (byte x = (byte)(2 - xExtend); x < xDim; ++x) { for (byte y = (byte)(2 - yExtend); y < yDim; ++y) { voxels[x, y, 1 - zExtend] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + x, VOXEL_DIMENSION - 1 + y, VOXEL_DIMENSION - zExtend).toVoxel(); } } return voxels; }
// ~VoxelRenderer() { // clear(); // } public void genMesh(VoxelUpdateInfo info) { size = info.size; Queue<int[]> triangleSet = new Queue<int[]>(); vertices = new Dictionary<int, object>(); vertexSubstances = new Dictionary<int, byte>(); Voxel[, ,] voxels = createVoxelArray(info); MarchingCubes.setup(info.size / VOXEL_DIMENSION, control.isoLevel, ref vertices, ref vertexSubstances, ref voxels, position - new Vector3(0.5f, 0.5f, 0.5f) * size / VOXEL_DIMENSION, null); int totalTris = 0; for (byte x = (byte)(1 - xExtend), x1 = (byte)(x + 1); x1 < xDim; x = x1++) { for (byte y = (byte)(1 - yExtend), y1 = (byte)(y + 1); y1 < yDim; y = y1++) { for (byte z = (byte)(1 - zExtend), z1 = (byte)(z + 1); z1 < zDim; z = z1++) { lock (control) { VoxelHolder block = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION + x, VOXEL_DIMENSION + y, VOXEL_DIMENSION + z); voxels[x1, y1, z1] = block.toVoxel(); int[] tris = MarchingCubes.lookupTriangles(x, y, z, x1, y1, z1); if (tris == null) continue; triangleSet.Enqueue(tris); totalTris += tris.Length; } } } } if (vertices.Count < 1) { applied = true; return; } List<int> triangles = new List<int>(); List<Vector3> finalVertices = new List<Vector3>(vertices.Count); //List<byte> finalMats = new List<byte>(vertices.Count); while (triangleSet.Count > 0) { int[] triangleList = triangleSet.Dequeue(); for (int i = 0; i < triangleList.Length; ++i) { if (vertices[triangleList[i]].GetType() == typeof(Vector3)) { finalVertices.Add((Vector3)vertices[triangleList[i]]); //finalMats.Add(vertexSubstances[triangleList[i]]); vertices[triangleList[i]] = finalVertices.Count - 1; } triangles.Add((int)vertices[triangleList[i]]); } } VERTS = finalVertices.ToArray(); TRIS = triangles.ToArray(); //MATS = finalMats.ToArray(); calcNorms(); alignEdge(info, 0, 1, 1); alignEdge(info, 2, 1, 1); alignEdge(info, 1, 0, 1); alignEdge(info, 1, 2, 1); alignEdge(info, 1, 1, 0); alignEdge(info, 1, 1, 2); lock (control) { control.enqueueMeshApply(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z)); } }