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 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); }
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); } }