Ejemplo n.º 1
0
        public static Texture2D FromModel(VOX.Model model, int tileSizePx = 1, bool enableGrid = false)
        {
            Texture2D texture = new Texture2D(16, 16);

            texture.SetPixels(model.materials.Select(mat => mat.color).ToArray());
            TextureScale.Point(texture, tileSizePx * 16, tileSizePx * 16);
            texture.filterMode = FilterMode.Point;
            texture.wrapMode   = TextureWrapMode.Clamp;
            return(texture);
        }
Ejemplo n.º 2
0
        private static MeshDraft CreateMesh(VOX.Model model, Dictionary <ColorPlanePos, ColorPlane> planes, float scale = 1.0f, float halfTexelShift = 0.0f)
        {
            MeshDraft mesh = new MeshDraft();

            foreach (KeyValuePair <ColorPlanePos, ColorPlane> plane in planes)
            {
                mesh.Add(CreateOptimizedFaces(model, plane.Key, plane.Value, halfTexelShift));
            }

            mesh.Scale(scale);
            return(mesh);
        }
Ejemplo n.º 3
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));
        }
Ejemplo n.º 4
0
        public static void SetModel(UnityEngine.GameObject obj, VOX.Model model, Texture2D customTexture = null, bool enableGrid = false)
        {
            var mr = obj.GetComponent <MeshRenderer>();

            if (mr == null)
            {
                mr = obj.AddComponent <MeshRenderer>();
            }

            var mf = obj.GetComponent <MeshFilter>();

            if (mf == null)
            {
                mf = obj.AddComponent <MeshFilter>();
            }

            var       texture = customTexture != null ? customTexture : VOX.Texture.FromModel(model, 1, true);
            MeshDraft mesh    = VOX.Mesh.FromModel(model);

            mr.sharedMaterial = new UnityEngine.Material(Shader.Find("Standard"));
            mr.sharedMaterial.SetTexture("_MainTex", texture);

            if (enableGrid)
            {
                var hlines = Resources.Load("hlines_tr") as UnityEngine.Texture;
                mr.sharedMaterial.SetTexture("_DetailAlbedoMap", hlines);
                mr.sharedMaterial.SetTextureScale("_DetailAlbedoMap", new Vector2(16f, 16f));
                mr.sharedMaterial.EnableKeyword("_DETAIL_MULX2");
                mr.sharedMaterial.SetColor("_Color", new Color(0.5f, 0.5f, 0.5f)); // To lower brightness of additional hlines texture
            }
            else
            {
                mr.sharedMaterial.DisableKeyword("_DETAIL_MULX2");
                mr.sharedMaterial.SetTexture("_DetailAlbedoMap", null);
                mr.sharedMaterial.SetColor("_Color", Color.white);
            }
            mr.sharedMaterial.EnableKeyword("_SPECULARHIGHLIGHTS_OFF");
            mr.sharedMaterial.SetFloat("_SpecularHighlights", 0f);
            mf.sharedMesh = mesh.ToMesh();
            mf.sharedMesh.RecalculateNormals();
        }
Ejemplo n.º 5
0
        private static Dictionary <ColorPlanePos, ColorPlane> CreateColorPlanes(VOX.Model model, bool withoutEdge)
        {
            var        planes = new Dictionary <ColorPlanePos, ColorPlane>();
            ColorPlane plane;

            for (int x = 0; x < model.sizeX; x++)
            {
                for (int y = 0; y < model.sizeY; y++)
                {
                    for (int z = 0; z < model.sizeZ; z++)
                    {
                        if (model.VoxelAt(x, y, z) == null)
                        {
                            continue;
                        }
                        byte i = model.MaterialIDAt(x, y, z);
                        if (i == 0)
                        {
                            continue;
                        }
                        // top
                        plane = GetColorPlaneFor(planes, y, i, new Vector3(0, -1f, 0));
                        if (model.VoxelAt(x, y + 1, z) == null)
                        {
                            plane.AddDot(x, z);
                        }

                        // bottom
                        plane = GetColorPlaneFor(planes, y, i, new Vector3(0, 1f, 0));
                        if (model.VoxelAt(x, y - 1, z) == null)
                        {
                            plane.AddDot(x, z);
                        }

                        if (z > 0 || !withoutEdge)
                        {
                            // front
                            plane = GetColorPlaneFor(planes, z, i, new Vector3(0, 0, -1f));
                            if (model.VoxelAt(x, y, z - 1) == null)
                            {
                                plane.AddDot(x, y);
                            }
                        }

                        if (z < model.sizeZ - 1 || !withoutEdge)
                        {
                            // back
                            plane = GetColorPlaneFor(planes, z, i, new Vector3(0, 0, 1f));
                            if (model.VoxelAt(x, y, z + 1) == null)
                            {
                                plane.AddDot(x, y);
                            }
                        }

                        if (x > 0 || !withoutEdge)
                        {
                            // left
                            plane = GetColorPlaneFor(planes, x, i, new Vector3(-1f, 0, 0));
                            if (model.VoxelAt(x - 1, y, z) == null)
                            {
                                plane.AddDot(z, y);
                            }
                        }

                        if (x < model.sizeX - 1 || !withoutEdge)
                        {
                            // right
                            plane = GetColorPlaneFor(planes, x, i, new Vector3(1f, 0, 0));
                            if (model.VoxelAt(x + 1, y, z) == null)
                            {
                                plane.AddDot(z, y);
                            }
                        }
                    }
                }
            }
            return(planes);
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
        // halfTextShift - for better uv mapping
        public static MeshDraft FromModel(VOX.Model model, float scale = 1.0f, bool withoutEdge = false, float halfTexelShift = 0.0f)
        {
            var planes = CreateColorPlanes(model, withoutEdge);

            return(CreateMesh(model, planes, scale, halfTexelShift));
        }