예제 #1
0
        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));
        }
예제 #2
0
        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);
        }