private void Create(MyMesh mesh, Quadrangle quad, float[] points) { float x = quad.x + offsetX; float y = quad.y + offsetY - 1; float z = quad.z + offsetZ; MyColor[] color = quad.color; for (int j = 0; j < 4; j++) { var p = mesh.pcount++; var dx = points[j * 3 + 0] * quad.dx; var dy = points[j * 3 + 1] * quad.dy; var dz = points[j * 3 + 2] * quad.dz; mesh.vertices[p * 3 + 0] = (x + dx) * Voxels.VoxelSize; //x mesh.vertices[p * 3 + 1] = (y + dy) * Voxels.VoxelSize; //y mesh.vertices[p * 3 + 2] = (z + dz) * Voxels.VoxelSize; //z mesh.colors[p * 3 + 0] = color[j].R / 255f; mesh.colors[p * 3 + 1] = color[j].G / 255f; mesh.colors[p * 3 + 2] = color[j].B / 255f; } int ind = mesh.index++; if (color[1].Same(color[2], 8) || !color[0].Same(color[3], 8)) { mesh.indices[ind * 6 + 0] = ind * 4 + 0; mesh.indices[ind * 6 + 1] = ind * 4 + 2; mesh.indices[ind * 6 + 2] = ind * 4 + 1; mesh.indices[ind * 6 + 3] = ind * 4 + 2; mesh.indices[ind * 6 + 4] = ind * 4 + 3; mesh.indices[ind * 6 + 5] = ind * 4 + 1; } else { mesh.indices[ind * 6 + 0] = ind * 4 + 0; mesh.indices[ind * 6 + 1] = ind * 4 + 3; mesh.indices[ind * 6 + 2] = ind * 4 + 1; mesh.indices[ind * 6 + 3] = ind * 4 + 2; mesh.indices[ind * 6 + 4] = ind * 4 + 3; mesh.indices[ind * 6 + 5] = ind * 4 + 0; } }
//Создает новый меш, в котором объеденены одинаковые точки public MyMesh Optimize() { if (!bOptimize) { return(this); } int pointn = 0; var points = new Dictionary <string, int>(); var newMesh = new MyMesh(pcount, index); var newindices = new int[pcount]; for (int i = 0; i < pcount; i++) //пробегаем по всем точкам { var x = (int)Math.Round(vertices[i * 3 + 0] / Voxels.VoxelSize); var y = (int)Math.Round(vertices[i * 3 + 1] / Voxels.VoxelSize); var z = (int)Math.Round(vertices[i * 3 + 2] / Voxels.VoxelSize); int r, g, b; if (bOptimizeIgnoreColor) { r = g = b = 0; } else { r = (int)Math.Round(colors[i * 3 + 0] * 255); g = (int)Math.Round(colors[i * 3 + 1] * 255); b = (int)Math.Round(colors[i * 3 + 2] * 255); } int p; var key = string.Format("{0} {1} {2} {3} {4} {5}", x, y, z, r, g, b); if (points.ContainsKey(key)) { p = points[key]; } else { int vert = newMesh.pcount++; newMesh.vertices[vert * 3 + 0] = vertices[i * 3 + 0]; newMesh.vertices[vert * 3 + 1] = vertices[i * 3 + 1]; newMesh.vertices[vert * 3 + 2] = vertices[i * 3 + 2]; newMesh.colors[vert * 3 + 0] = colors[i * 3 + 0]; newMesh.colors[vert * 3 + 1] = colors[i * 3 + 1]; newMesh.colors[vert * 3 + 2] = colors[i * 3 + 2]; points[key] = p = pointn++; } newindices[i] = p; } newMesh.index = index; for (int i = 0; i < index * 6; i++) //пробегаем по всем индексам { newMesh.indices[i] = newindices[indices[i]]; } return(newMesh); }
public MyMesh Build(LocationCreator lc, int k = 4, int m = 4) { var qy1 = QuadGroup(quadranglesY1, q => q.y); var qx0 = QuadGroup(quadranglesX0, q => q.x); var qx1 = QuadGroup(quadranglesX1, q => q.x); var qz0 = QuadGroup(quadranglesZ0, q => q.z); var qz1 = QuadGroup(quadranglesZ1, q => q.z); if (bOptimizeEd) { if (k > 1) { qy1 = qy1.Select(x => QuadrangleOptimizeX(x, k, k).ToList()); qy1 = qy1.Select(x => QuadrangleOptimizeZ(x, k, k).ToList()); } if (m > 1) { qx0 = qx0.Select(x => QuadrangleOptimizeY(x, m, m).ToList()); qx0 = qx0.Select(x => QuadrangleOptimizeZ(x, m, m).ToList()); qx1 = qx1.Select(x => QuadrangleOptimizeY(x, m, m).ToList()); qx1 = qx1.Select(x => QuadrangleOptimizeZ(x, m, m).ToList()); qz0 = qz0.Select(x => QuadrangleOptimizeX(x, m, m).ToList()); qz0 = qz0.Select(x => QuadrangleOptimizeY(x, m, m).ToList()); qz1 = qz1.Select(x => QuadrangleOptimizeX(x, m, m).ToList()); qz1 = qz1.Select(x => QuadrangleOptimizeY(x, m, m).ToList()); } } if (bOptimize3) { qy1 = qy1.Select(x => QuadrangleOptimizeX(x, 4, 4).ToList()); qy1 = qy1.Select(x => QuadrangleOptimizeZ(x, 4, 4).ToList()); qx0 = qx0.Select(x => QuadrangleOptimizeY(x, 4, 4).ToList()); qx0 = qx0.Select(x => QuadrangleOptimizeZ(x, 4, 4).ToList()); qx1 = qx1.Select(x => QuadrangleOptimizeY(x, 4, 4).ToList()); qx1 = qx1.Select(x => QuadrangleOptimizeZ(x, 4, 4).ToList()); qz0 = qz0.Select(x => QuadrangleOptimizeX(x, 4, 4).ToList()); qz0 = qz0.Select(x => QuadrangleOptimizeY(x, 4, 4).ToList()); qz1 = qz1.Select(x => QuadrangleOptimizeX(x, 4, 4).ToList()); qz1 = qz1.Select(x => QuadrangleOptimizeY(x, 4, 4).ToList()); } if (k > 4) { if (bOptimize3) { qy1 = qy1.Select(x => QuadrangleOptimizeX(x, k, k).ToList()); qy1 = qy1.Select(x => QuadrangleOptimizeZ(x, k, k).ToList()); qx0 = qx0.Select(x => QuadrangleOptimizeY(x, k, k).ToList()); qx0 = qx0.Select(x => QuadrangleOptimizeZ(x, k, k).ToList()); qx1 = qx1.Select(x => QuadrangleOptimizeY(x, k, k).ToList()); qx1 = qx1.Select(x => QuadrangleOptimizeZ(x, k, k).ToList()); qz0 = qz0.Select(x => QuadrangleOptimizeX(x, k, k).ToList()); qz0 = qz0.Select(x => QuadrangleOptimizeY(x, k, k).ToList()); qz1 = qz1.Select(x => QuadrangleOptimizeX(x, k, k).ToList()); qz1 = qz1.Select(x => QuadrangleOptimizeY(x, k, k).ToList()); } } if (bOptimize2 && k > 1) { qy1 = qy1.Select(x => QuadrangleOptimizeX(x, 1, k).ToList()); qy1 = qy1.Select(x => QuadrangleOptimizeZ(x, 1, k).ToList()); qx0 = qx0.Select(x => QuadrangleOptimizeY(x, 1, k).ToList()); qx0 = qx0.Select(x => QuadrangleOptimizeZ(x, 1, k).ToList()); qx1 = qx1.Select(x => QuadrangleOptimizeY(x, 1, k).ToList()); qx1 = qx1.Select(x => QuadrangleOptimizeZ(x, 1, k).ToList()); qz0 = qz0.Select(x => QuadrangleOptimizeX(x, 1, k).ToList()); qz0 = qz0.Select(x => QuadrangleOptimizeY(x, 1, k).ToList()); qz1 = qz1.Select(x => QuadrangleOptimizeX(x, 1, k).ToList()); qz1 = qz1.Select(x => QuadrangleOptimizeY(x, 1, k).ToList()); } var _qy1 = qy1.ToList(); var _qx0 = qx0.ToList(); var _qx1 = qx1.ToList(); var _qz0 = qz0.ToList(); var _qz1 = qz1.ToList(); var count = _qy1.Sum(x => x.Count) + _qx0.Sum(x => x.Count) + _qx1.Sum(x => x.Count) + _qz0.Sum(x => x.Count) + _qz1.Sum(x => x.Count); if (count == 0) { return(null); } var mesh = new MyMesh(count * 4, count); foreach (var quads in _qy1) { foreach (var quad in quads) { Create(mesh, quad, orientVertices[QuadOrient.y1]); } } foreach (var quads in _qx0) { foreach (var quad in quads) { Create(mesh, quad, orientVertices[QuadOrient.x0]); } } foreach (var quads in _qx1) { foreach (var quad in quads) { Create(mesh, quad, orientVertices[QuadOrient.x1]); } } foreach (var quads in _qz0) { foreach (var quad in quads) { Create(mesh, quad, orientVertices[QuadOrient.z0]); } } foreach (var quads in _qz1) { foreach (var quad in quads) { Create(mesh, quad, orientVertices[QuadOrient.z1]); } } mesh = mesh.Optimize(); return(mesh); }