public static void MeshSplit(SVGMesh mesh, Vector2 origin, Vector2 direction)
        {
            Mesh inputMesh = new Mesh();
            inputMesh.vertices = mesh.vertices;
            inputMesh.triangles = mesh.triangles;
            inputMesh.colors32 = mesh.colors;
            inputMesh.uv = (Vector2[])mesh.uvs;
            inputMesh.uv2 = (Vector2[])mesh.uvs2;

            MeshSplit(inputMesh, origin, direction);
            SVGMeshUtils.AutoWeldVertices(inputMesh, 0f);

            mesh.vertices = inputMesh.vertices;
            mesh.triangles = inputMesh.triangles;
            mesh.colors = inputMesh.colors32;
            mesh.uvs = inputMesh.uv;
            mesh.uvs2 = inputMesh.uv2;
        }
        public static void MeshSplit(SVGMesh mesh, Vector2 origin, Vector2 direction)
        {
            Mesh inputMesh = new Mesh();

            inputMesh.vertices  = mesh.vertices;
            inputMesh.triangles = mesh.triangles;
            inputMesh.colors32  = mesh.colors;
            inputMesh.uv        = (Vector2[])mesh.uvs;
            inputMesh.uv2       = (Vector2[])mesh.uvs2;

            MeshSplit(inputMesh, origin, direction);
            SVGMeshUtils.AutoWeldVertices(inputMesh, 0f);

            mesh.vertices  = inputMesh.vertices;
            mesh.triangles = inputMesh.triangles;
            mesh.colors    = inputMesh.colors32;
            mesh.uvs       = inputMesh.uv;
            mesh.uvs2      = inputMesh.uv2;
        }
Example #3
0
        public static Mesh CombineMeshes(List <SVGMesh> meshes, out SVGLayer[] layers, out Shader[] shaders, SVGUseGradients useGradients = SVGUseGradients.Always, SVGAssetFormat format = SVGAssetFormat.Transparent, bool compressDepth = true)
        {
            layers  = new SVGLayer[0];
            shaders = new Shader[0];

            //if(SVGAssetImport.sliceMesh) Create9Slice();

            SVGFill fill;
            bool    useOpaqueShader      = false;
            bool    useTransparentShader = false;
            bool    hasGradients         = (useGradients == SVGUseGradients.Always);

            int totalMeshes = meshes.Count, totalTriangles = 0, opaqueTriangles = 0, transparentTriangles = 0;

            // Z Sort meshes
            if (format == SVGAssetFormat.Opaque)
            {
                if (compressDepth)
                {
                    SVGBounds meshBounds = SVGBounds.InfiniteInverse;
                    for (int i = 0; i < totalMeshes; i++)
                    {
                        if (meshes [i] == null)
                        {
                            continue;
                        }
                        meshBounds.Encapsulate(meshes [i].bounds);
                    }

                    if (!meshBounds.isInfiniteInverse)
                    {
                        SVGGraphics.depthTree.Clear();
                        SVGGraphics.depthTree = new SVGDepthTree(meshBounds);

                        for (int i = 0; i < totalMeshes; i++)
                        {
                            fill = meshes [i]._fill;
                            SVGMesh[] nodes       = SVGGraphics.depthTree.TestDepthAdd(meshes [i], new SVGBounds(meshes [i]._bounds));
                            int       nodesLength = 0;
                            if (nodes == null || nodes.Length == 0)
                            {
                                meshes [i]._depth = 0;
                            }
                            else
                            {
                                nodesLength = nodes.Length;
                                int     highestDepth = 0;
                                SVGMesh highestMesh  = null;
                                for (int j = 0; j < nodesLength; j++)
                                {
                                    if (nodes[j].depth > highestDepth)
                                    {
                                        highestDepth = nodes[j].depth;
                                        highestMesh  = nodes[j];
                                    }
                                }

                                if (fill.blend == FILL_BLEND.OPAQUE)
                                {
                                    meshes [i]._depth = highestDepth + 1;
                                }
                                else
                                {
                                    if (highestMesh != null && highestMesh.fill.blend == FILL_BLEND.OPAQUE)
                                    {
                                        meshes [i]._depth = highestDepth + 1;
                                    }
                                    else
                                    {
                                        meshes [i]._depth = highestDepth;
                                    }
                                }
                            }

                            meshes [i].UpdateDepth();
                        }
                    }
                }
                else
                {
                    int highestDepth = 0;
                    for (int i = 0; i < totalMeshes; i++)
                    {
                        fill = meshes [i]._fill;
                        if (fill.blend == FILL_BLEND.OPAQUE || lastBlendType == FILL_BLEND.OPAQUE)
                        {
                            meshes[i]._depth = ++highestDepth;
                        }
                        else
                        {
                            meshes[i]._depth = highestDepth;
                        }

                        lastBlendType = fill.blend;
                        meshes[i].UpdateDepth();
                    }
                }
            }

            layers = new SVGLayer[totalMeshes];
            int totalVertices = 0, vertexCount, vertexStart, currentVertex;

            for (int i = 0; i < totalMeshes; i++)
            {
                fill = meshes[i]._fill;
                if (fill.blend == FILL_BLEND.OPAQUE)
                {
                    opaqueTriangles += meshes[i]._triangles.Length;
                    useOpaqueShader  = true;
                }
                else if (fill.blend == FILL_BLEND.ALPHA_BLENDED)
                {
                    transparentTriangles += meshes[i]._triangles.Length;
                    useTransparentShader  = true;
                }
                if (fill.fillType == FILL_TYPE.GRADIENT)
                {
                    hasGradients = true;
                }

                vertexCount = meshes[i]._vertices.Length;
                Bounds bounds = meshes[i]._bounds;
                layers[i]      = new SVGLayer(meshes[i]._name, totalVertices, vertexCount, bounds.center, bounds.size);
                totalVertices += vertexCount;
            }

            totalTriangles = opaqueTriangles + transparentTriangles;

            if (useGradients == SVGUseGradients.Never)
            {
                hasGradients = false;
            }
            if (format != SVGAssetFormat.Opaque)
            {
                useOpaqueShader      = false;
                useTransparentShader = true;
            }

            Vector3[] vertices  = new Vector3[totalVertices];
            Color32[] colors32  = new Color32[totalVertices];
            Vector2[] uv        = null;
            Vector2[] uv2       = null;
            int[][]   triangles = null;

            for (int i = 0; i < totalMeshes; i++)
            {
                vertexStart = layers[i].vertexStart;
                vertexCount = layers[i].vertexCount;
                for (int j = 0; j < vertexCount; j++)
                {
                    currentVertex           = vertexStart + j;
                    vertices[currentVertex] = meshes[i]._vertices[j];
                    colors32[currentVertex] = meshes[i]._colors[j];
                }
            }

            List <Shader> outputShaders = new List <Shader>();

//            Debug.Log("hasGradients: "+hasGradients);
            if (hasGradients)
            {
                uv  = new Vector2[totalVertices];
                uv2 = new Vector2[totalVertices];

                for (int i = 0; i < totalMeshes; i++)
                {
                    vertexStart = layers[i].vertexStart;
                    vertexCount = layers[i].vertexCount;
                    for (int j = 0; j < vertexCount; j++)
                    {
                        currentVertex      = vertexStart + j;
                        uv[currentVertex]  = meshes[i]._uvs[j];
                        uv2[currentVertex] = meshes[i]._uvs2[j];
                    }
                }

                if (useOpaqueShader)
                {
                    outputShaders.Add(SVGShader.GradientColorOpaque);
                }
                if (useTransparentShader)
                {
                    outputShaders.Add(SVGShader.GradientColorAlphaBlended);
                }
            }
            else
            {
                if (useOpaqueShader)
                {
                    outputShaders.Add(SVGShader.SolidColorOpaque);
                }
                if (useTransparentShader)
                {
                    outputShaders.Add(SVGShader.SolidColorAlphaBlended);
                }
            }

            if (useOpaqueShader && useTransparentShader)
            {
                triangles = new int[2][] { new int[opaqueTriangles], new int[transparentTriangles] };

                int lastVertexIndex = 0;
                int triangleCount;
                int lastOpauqeTriangleIndex      = 0;
                int lastTransparentTriangleIndex = 0;

                for (int i = 0; i < totalMeshes; i++)
                {
                    triangleCount = meshes[i]._triangles.Length;
                    if (meshes[i]._fill.blend == FILL_BLEND.OPAQUE)
                    {
                        for (int j = 0; j < triangleCount; j++)
                        {
                            triangles[0][lastOpauqeTriangleIndex++] = lastVertexIndex + meshes[i]._triangles[j];
                        }
                    }
                    else
                    {
                        for (int j = 0; j < triangleCount; j++)
                        {
                            triangles[1][lastTransparentTriangleIndex++] = lastVertexIndex + meshes[i]._triangles[j];
                        }
                    }

                    lastVertexIndex += layers[i].vertexCount;
                }
            }
            else
            {
                triangles = new int[1][] { new int[totalTriangles] };

                int lastVertexIndex = 0;
                int triangleCount;
                int lastTriangleIndex = 0;

                for (int i = 0; i < totalMeshes; i++)
                {
                    triangleCount = meshes[i]._triangles.Length;
                    for (int j = 0; j < triangleCount; j++)
                    {
                        triangles[0][lastTriangleIndex++] = lastVertexIndex + meshes[i]._triangles[j];
                    }
                    lastVertexIndex += layers[i].vertexCount;
                }
            }

            if (outputShaders.Count != 0)
            {
                shaders = outputShaders.ToArray();
            }

            Mesh output = new Mesh();

            output.vertices = vertices;
            output.colors32 = colors32;

            if (hasGradients)
            {
                output.uv  = uv;
                output.uv2 = uv2;
            }

            if (triangles.Length == 1)
            {
                output.triangles = triangles[0];
            }
            else
            {
                output.subMeshCount = triangles.Length;
                for (int i = 0; i < triangles.Length; i++)
                {
                    output.SetTriangles(triangles[i], i);
                }
            }

            return(output);
        }
Example #4
0
        protected static Mesh CreateAutomaticMesh(out Material[] materials)
        {
            materials = new Material[0];

            if (sliceMesh)
            {
                Create9Slice();
            }

            // Z Sort meshes
            if (SVGMesh.format == SVGAssetFormat.Opaque)
            {
                int     meshCount = SVGGraphics.meshes.Count;
                SVGFill fill;

                if (compressDepth)
                {
                    SVGBounds meshBounds = SVGBounds.InfiniteInverse;
                    for (int i = 0; i < meshCount; i++)
                    {
                        if (SVGGraphics.meshes [i] == null)
                        {
                            continue;
                        }
                        meshBounds.Encapsulate(SVGGraphics.meshes [i].bounds);
                    }

                    if (!meshBounds.isInfiniteInverse)
                    {
                        SVGGraphics.depthTree.Clear();
                        SVGGraphics.depthTree = new SVGDepthTree(meshBounds);
                    }

                    for (int i = 0; i < meshCount; i++)
                    {
                        if (SVGGraphics.meshes [i] == null)
                        {
                            continue;
                        }

                        fill = SVGGraphics.meshes [i]._fill;
                        if (fill != null)
                        {
                            SVGMesh[] nodes       = SVGGraphics.depthTree.TestDepthAdd(SVGGraphics.meshes [i], new SVGBounds(SVGGraphics.meshes [i]._bounds));
                            int       nodesLength = 0;
                            if (nodes == null || nodes.Length == 0)
                            {
                                SVGGraphics.meshes [i]._depth = 0;
                            }
                            else
                            {
                                nodesLength = nodes.Length;
                                int     highestDepth = 0;
                                SVGMesh highestMesh  = null;
                                for (int j = 0; j < nodesLength; j++)
                                {
                                    if (nodes[j].depth > highestDepth)
                                    {
                                        highestDepth = nodes[j].depth;
                                        highestMesh  = nodes[j];
                                    }
                                }

                                if (fill.blend == FILL_BLEND.OPAQUE)
                                {
                                    SVGGraphics.meshes [i]._depth = highestDepth + 1;
                                }
                                else
                                {
                                    if (highestMesh != null && highestMesh.fill.blend == FILL_BLEND.OPAQUE)
                                    {
                                        SVGGraphics.meshes [i]._depth = highestDepth + 1;
                                    }
                                    else
                                    {
                                        SVGGraphics.meshes [i]._depth = highestDepth;
                                    }
                                }
                            }

                            SVGGraphics.meshes [i].UpdateDepth();
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < meshCount; i++)
                    {
                        if (SVGGraphics.meshes [i] == null)
                        {
                            continue;
                        }

                        fill = SVGGraphics.meshes [i]._fill;
                        if (fill != null)
                        {
                            if (fill.blend == FILL_BLEND.OPAQUE || lastBlendType == FILL_BLEND.OPAQUE)
                            {
                                SVGGraphics.meshes [i]._depth = SVGGraphics.IncreaseDepth();
                            }
                            else
                            {
                                SVGGraphics.meshes [i]._depth = SVGGraphics.currentDepthOffset;
                            }

                            lastBlendType = fill.blend;
                            SVGGraphics.meshes [i].UpdateDepth();
                        }
                    }
                }
            }

            // Combine Meshes
            List <CombineInstance> combineInstancesOpaque      = new List <CombineInstance>();
            List <CombineInstance> combineInstancesTransparent = new List <CombineInstance>();

            GetCombineInstances(combineInstancesOpaque,
                                combineInstancesTransparent);

            int count = combineInstancesOpaque.Count + combineInstancesTransparent.Count;

            if (count == 0)
            {
                return(null);
            }

            List <Material> outputMaterials = new List <Material>(count);

            List <CombineInstance> combineInstances = new List <CombineInstance>();

            if (combineInstancesOpaque.Count > 0)
            {
                outputMaterials.Add(SVGAtlas.Instance.opaqueGradient);
                combineInstances.Add(GetCombinedInstance(combineInstancesOpaque));
            }

            if (combineInstancesTransparent.Count > 0)
            {
                outputMaterials.Add(SVGAtlas.Instance.transparentGradient);
                combineInstances.Add(GetCombinedInstance(combineInstancesTransparent));
            }

            if (outputMaterials.Count != 0)
            {
                materials = outputMaterials.ToArray();
            }

            if (combineInstances.Count > 1)
            {
                Mesh output = new Mesh();
                output.CombineMeshes(combineInstances.ToArray(), false, false);
                return(output);
            }
            else if (combineInstances.Count == 1)
            {
                return(combineInstances [0].mesh);
            }
            else
            {
                return(null);
            }
        }