private static MeshDraft CreateOptimizedFaces(VOX.Model model, ColorPlanePos pos, ColorPlane plane, float halfTexelShift) { plane.vertices = new List <Vector3>(); plane.triangles = new List <int>(); int count = 0; bool[,] matrix = new bool[plane.sizeX, plane.sizeY]; foreach (Vector2Int dot in plane.dots) { matrix[dot.x - plane.minX, dot.y - plane.minY] = true; count++; } return(SplitToRects(model, matrix, pos, plane, count, halfTexelShift)); }
private static MeshDraft SplitToRects(VOX.Model model, bool[,] matrix, ColorPlanePos pos, ColorPlane plane, int count, float halfTexelShift) { MeshDraft mesh = new MeshDraft(); int matIdX = plane.matID % 16; int matIdY = plane.matID / 16; Vector2 uvStart = new Vector2(matIdX / 16.0f, matIdY / 16.0f); int[,] h, w; h = new int[plane.sizeX, plane.sizeY]; w = new int[plane.sizeX, plane.sizeY]; while (count > 0) { int minw = 0, area = 0; int maxArea = 0; int[] maxFace = new int[4] { 0, 0, 0, 0 }; for (int j = 0; j < plane.sizeX; j++) { for (int i = 0; i < plane.sizeY; i++) { if (!matrix[j, i]) { continue; } if (j == 0) { h[j, i] = 1; } else { h[j, i] = h[j - 1, i] + 1; } if (i == 0) { w[j, i] = 1; } else { w[j, i] = w[j, i - 1] + 1; } minw = w[j, i]; for (int dh = 0; dh < h[j, i]; dh++) { if (w[j - dh, i] < minw) { minw = w[j - dh, i]; } area = (dh + 1) * minw; if (area > maxArea) { maxArea = area; maxFace[0] = i - minw + 1; maxFace[1] = j - dh; maxFace[2] = i; maxFace[3] = j; } } } } int vi = mesh.vertices.Count; bool order = true; float x1 = maxFace[1]; float y1 = maxFace[0]; float x2 = maxFace[3] + 1; float y2 = maxFace[2] + 1; if (pos.normal.y == -1) { mesh.vertices.Add(new Vector3(maxFace[1], pos.pos + 1, maxFace[0])); mesh.vertices.Add(new Vector3(maxFace[3] + 1, pos.pos + 1, maxFace[0])); mesh.vertices.Add(new Vector3(maxFace[3] + 1, pos.pos + 1, maxFace[2] + 1)); mesh.vertices.Add(new Vector3(maxFace[1], pos.pos + 1, maxFace[2] + 1)); x1 *= 1.0f / model.sizeX / 16.0f; y1 *= 1.0f / model.sizeZ / 16.0f; x2 *= 1.0f / model.sizeX / 16.0f; y2 *= 1.0f / model.sizeZ / 16.0f; } else if (pos.normal.y == 1) { mesh.vertices.Add(new Vector3(maxFace[1], pos.pos, maxFace[0])); mesh.vertices.Add(new Vector3(maxFace[3] + 1, pos.pos, maxFace[0])); mesh.vertices.Add(new Vector3(maxFace[3] + 1, pos.pos, maxFace[2] + 1)); mesh.vertices.Add(new Vector3(maxFace[1], pos.pos, maxFace[2] + 1)); order = false; x1 *= 1.0f / model.sizeX / 16.0f; y1 *= 1.0f / model.sizeZ / 16.0f; x2 *= 1.0f / model.sizeX / 16.0f; y2 *= 1.0f / model.sizeZ / 16.0f; } else if (pos.normal.z == -1) { mesh.vertices.Add(new Vector3(maxFace[1], maxFace[0], pos.pos)); mesh.vertices.Add(new Vector3(maxFace[3] + 1, maxFace[0], pos.pos)); mesh.vertices.Add(new Vector3(maxFace[3] + 1, maxFace[2] + 1, pos.pos)); mesh.vertices.Add(new Vector3(maxFace[1], maxFace[2] + 1, pos.pos)); x1 *= 1.0f / model.sizeX / 16.0f; y1 *= 1.0f / model.sizeY / 16.0f; x2 *= 1.0f / model.sizeX / 16.0f; y2 *= 1.0f / model.sizeY / 16.0f; } else if (pos.normal.z == 1) { mesh.vertices.Add(new Vector3(maxFace[1], maxFace[0], pos.pos + 1)); mesh.vertices.Add(new Vector3(maxFace[3] + 1, maxFace[0], pos.pos + 1)); mesh.vertices.Add(new Vector3(maxFace[3] + 1, maxFace[2] + 1, pos.pos + 1)); mesh.vertices.Add(new Vector3(maxFace[1], maxFace[2] + 1, pos.pos + 1)); order = false; x1 *= 1.0f / model.sizeX / 16.0f; y1 *= 1.0f / model.sizeY / 16.0f; x2 *= 1.0f / model.sizeX / 16.0f; y2 *= 1.0f / model.sizeY / 16.0f; } else if (pos.normal.x == -1) { mesh.vertices.Add(new Vector3(pos.pos, maxFace[0], maxFace[1])); mesh.vertices.Add(new Vector3(pos.pos, maxFace[0], maxFace[3] + 1)); mesh.vertices.Add(new Vector3(pos.pos, maxFace[2] + 1, maxFace[3] + 1)); mesh.vertices.Add(new Vector3(pos.pos, maxFace[2] + 1, maxFace[1])); order = false; x1 *= 1.0f / model.sizeY / 16.0f; y1 *= 1.0f / model.sizeY / 16.0f; x2 *= 1.0f / model.sizeY / 16.0f; y2 *= 1.0f / model.sizeY / 16.0f; } else if (pos.normal.x == 1) { mesh.vertices.Add(new Vector3(pos.pos + 1, maxFace[0], maxFace[1])); mesh.vertices.Add(new Vector3(pos.pos + 1, maxFace[0], maxFace[3] + 1)); mesh.vertices.Add(new Vector3(pos.pos + 1, maxFace[2] + 1, maxFace[3] + 1)); mesh.vertices.Add(new Vector3(pos.pos + 1, maxFace[2] + 1, maxFace[1])); x1 *= 1.0f / model.sizeY / 16.0f; y1 *= 1.0f / model.sizeY / 16.0f; x2 *= 1.0f / model.sizeY / 16.0f; y2 *= 1.0f / model.sizeY / 16.0f; } x1 += uvStart.x + halfTexelShift; y1 += uvStart.y + halfTexelShift; x2 += uvStart.x - halfTexelShift; y2 += uvStart.y - halfTexelShift; mesh.uv.Add(new Vector2(x1, y1)); mesh.uv.Add(new Vector2(x2, y1)); mesh.uv.Add(new Vector2(x2, y2)); mesh.uv.Add(new Vector2(x1, y2)); if (order) { mesh.triangles.Add(vi); mesh.triangles.Add(vi + 2); mesh.triangles.Add(vi + 1); mesh.triangles.Add(vi + 2); mesh.triangles.Add(vi); mesh.triangles.Add(vi + 3); } else { mesh.triangles.Add(vi); mesh.triangles.Add(vi + 1); mesh.triangles.Add(vi + 2); mesh.triangles.Add(vi + 2); mesh.triangles.Add(vi + 3); mesh.triangles.Add(vi); } for (int j = maxFace[1]; j <= maxFace[3]; j++) { for (int i = maxFace[0]; i <= maxFace[2]; i++) { matrix[j, i] = false; count--; } } for (int j = 0; j < plane.sizeX; j++) { for (int i = 0; i < plane.sizeY; i++) { w[j, i] = 0; h[j, i] = 0; } } } return(mesh); }