public void Apply(SVGAssetSnapshot snapshot) { this.format = snapshot.format; this.useGradients = snapshot.useGradients; this.antialiasing = snapshot.antialiasing; this.meshCompression = snapshot.meshCompression; this.scale = snapshot.scale; this.vpm = snapshot.vpm; this.depthOffset = snapshot.depthOffset; this.compressDepth = snapshot.compressDepth; this.customPivotPoint = snapshot.customPivotPoint; this.pivotPoint = snapshot.pivotPoint; this.border = snapshot.border; this.sliceMesh = snapshot.sliceMesh; this.generateCollider = snapshot.generateCollider; this.keepSVGFile = snapshot.keepSVGFile; this.useLayers = snapshot.useLayers; this.ignoreSVGCanvas = snapshot.ignoreSVGCanvas; this.optimizeMesh = snapshot.optimizeMesh; this.generateNormals = snapshot.generateNormals; this.generateTangents = snapshot.generateTangents; }
public void Apply(SerializedObject serializedObject) { this.format = (SVGAssetFormat)serializedObject.FindProperty("_format").enumValueIndex; this.useGradients = (SVGUseGradients)serializedObject.FindProperty("_useGradients").enumValueIndex; this.antialiasing = serializedObject.FindProperty("_antialiasing").boolValue; this.meshCompression = (SVGMeshCompression)serializedObject.FindProperty("_meshCompression").enumValueIndex; this.scale = serializedObject.FindProperty("_scale").floatValue; this.vpm = serializedObject.FindProperty("_vpm").floatValue; this.depthOffset = serializedObject.FindProperty("_depthOffset").floatValue; this.compressDepth = serializedObject.FindProperty("_compressDepth").boolValue; this.customPivotPoint = serializedObject.FindProperty("_customPivotPoint").boolValue; this.pivotPoint = serializedObject.FindProperty("_pivotPoint").vector2Value; this.border = serializedObject.FindProperty("_border").vector4Value; this.sliceMesh = serializedObject.FindProperty("_sliceMesh").boolValue; this.generateCollider = serializedObject.FindProperty("_generateCollider").boolValue; this.keepSVGFile = serializedObject.FindProperty("_keepSVGFile").boolValue; this.useLayers = serializedObject.FindProperty("_useLayers").boolValue; this.ignoreSVGCanvas = serializedObject.FindProperty("_ignoreSVGCanvas").boolValue; this.optimizeMesh = serializedObject.FindProperty("_optimizeMesh").boolValue; this.generateNormals = serializedObject.FindProperty("_generateNormals").boolValue; this.generateTangents = serializedObject.FindProperty("_generateTangents").boolValue; }
public void Apply(SVGAsset svgAsset) { this.format = svgAsset.format; this.useGradients = svgAsset.useGradients; this.antialiasing = svgAsset.antialiasing; this.antialiasingWidth = svgAsset.antialiasingWidth; this.meshCompression = svgAsset.meshCompression; this.scale = svgAsset.scale; this.vpm = svgAsset.vpm; this.depthOffset = svgAsset.depthOffset; this.compressDepth = svgAsset.compressDepth; this.customPivotPoint = svgAsset.customPivotPoint; this.pivotPoint = svgAsset.pivotPoint; this.border = svgAsset.border; this.sliceMesh = svgAsset.sliceMesh; this.generateCollider = svgAsset.generateCollider; this.keepSVGFile = svgAsset.keepSVGFile; this.ignoreSVGCanvas = svgAsset.ignoreSVGCanvas; this.optimizeMesh = svgAsset.optimizeMesh; this.generateNormals = svgAsset.generateNormals; this.generateTangents = svgAsset.generateTangents; }
public static Mesh CombineMeshes(List <SVGLayer> layers, out Shader[] shaders, SVGUseGradients useGradients = SVGUseGradients.Always, SVGAssetFormat format = SVGAssetFormat.Transparent, bool compressDepth = true) { #if DEBUG_IMPORT long timeStart = System.DateTime.Now.Ticks; #endif shaders = new Shader[0]; //if(SVGAssetImport.sliceMesh) Create9Slice(); SVGFill fill; bool useOpaqueShader = false; bool useTransparentShader = false; bool hasGradients = (useGradients == SVGUseGradients.Always); int totalLayers = layers.Count, totalTriangles = 0, opaqueTriangles = 0, transparentTriangles = 0; FILL_BLEND lastBlendType = FILL_BLEND.ALPHA_BLENDED; // Z Sort meshes if (format == SVGAssetFormat.Opaque) { SVGLayer layer; if (compressDepth) { SVGBounds quadTreeBounds = SVGBounds.InfiniteInverse; for (int i = 0; i < totalLayers; i++) { layer = layers[i]; if (layer.bounds.size.sqrMagnitude == 0f) { continue; } quadTreeBounds.Encapsulate(layer.bounds.center, layer.bounds.size); } quadTreeBounds.size *= 1.2f; if (!quadTreeBounds.isInfiniteInverse) { SVGDepthTree depthTree = new SVGDepthTree(quadTreeBounds); for (int i = 0; i < totalLayers; i++) { layer = layers[i]; int[] nodes = depthTree.TestDepthAdd(i, new SVGBounds(layer.bounds.center, layer.bounds.size)); int nodesLength = 0; if (nodes == null || nodes.Length == 0) { layer.depth = 0; } else { nodesLength = nodes.Length; int highestDepth = 0; int highestLayer = -1; for (int j = 0; j < nodesLength; j++) { if (layers[nodes[j]].depth > highestDepth) { highestDepth = layers[nodes[j]].depth; highestLayer = nodes[j]; } } if (layers[i].fill.blend == FILL_BLEND.OPAQUE) { layer.depth = highestDepth + 1; } else { if (highestDepth != -1 && layers[highestLayer].fill.blend == FILL_BLEND.OPAQUE) { layer.depth = highestDepth + 1; } else { layer.depth = highestDepth; } } } layers[i] = layer; } } } else { int highestDepth = 0; for (int i = 0; i < totalLayers; i++) { layer = layers[i]; fill = layer.fill; if (fill.blend == FILL_BLEND.OPAQUE || lastBlendType == FILL_BLEND.OPAQUE) { layer.depth = ++highestDepth; } else { layer.depth = highestDepth; } lastBlendType = fill.blend; layers[i] = layer; } } } int totalVertices = 0, vertexCount, vertexStart = 0, currentVertex; for (int i = 0; i < totalLayers; i++) { fill = layers[i].fill; if (fill.blend == FILL_BLEND.OPAQUE) { opaqueTriangles += layers[i].triangles.Length; useOpaqueShader = true; } else if (fill.blend == FILL_BLEND.ALPHA_BLENDED) { transparentTriangles += layers[i].triangles.Length; useTransparentShader = true; } if (fill.fillType == FILL_TYPE.GRADIENT) { hasGradients = true; } vertexCount = layers[i].vertices.Length; 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; List <Shader> outputShaders = new List <Shader>(); if (hasGradients) { uv = new Vector2[totalVertices]; uv2 = new Vector2[totalVertices]; 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); } } for (int i = 0; i < totalLayers; i++) { vertexCount = layers[i].vertices.Length; // Debug.Log("Layer: "+i+", depth: "+layers[i].depth); for (int j = 0; j < vertexCount; j++) { currentVertex = vertexStart + j; vertices[currentVertex] = layers[i].vertices[j]; vertices[currentVertex].z = layers[i].depth * -SVGAssetImport.minDepthOffset; colors32[currentVertex] = layers[i].fill.finalColor; } if (hasGradients && layers[i].fill.fillType == FILL_TYPE.GRADIENT && layers[i].fill.gradientColors != null) { SVGMatrix svgFillTransform = layers[i].fill.transform; Rect viewport = layers[i].fill.viewport; Vector2 uvPoint = Vector2.zero; Vector2 uv2Value = new Vector2(layers[i].fill.gradientColors.index, (int)layers[i].fill.gradientType); for (int j = 0; j < vertexCount; j++) { currentVertex = vertexStart + j; uvPoint.x = vertices [currentVertex].x; uvPoint.y = vertices [currentVertex].y; uvPoint = svgFillTransform.Transform(uvPoint); uv[currentVertex].x = (uvPoint.x - viewport.x) / viewport.width; uv[currentVertex].y = (uvPoint.y - viewport.y) / viewport.height; uv2[currentVertex] = uv2Value; } } vertexStart += vertexCount; } /* * for(int i = 0; i < totalVertices; i++) * { * vertices[i] *= SVGAssetImport.meshScale; * } */ 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 < totalLayers; i++) { triangleCount = layers[i].triangles.Length; if (layers[i].fill.blend == FILL_BLEND.OPAQUE) { for (int j = 0; j < triangleCount; j++) { triangles[0][lastOpauqeTriangleIndex++] = lastVertexIndex + layers[i].triangles[j]; } } else { for (int j = 0; j < triangleCount; j++) { triangles[1][lastTransparentTriangleIndex++] = lastVertexIndex + layers[i].triangles[j]; } } lastVertexIndex += layers[i].vertices.Length; } } else { triangles = new int[1][] { new int[totalTriangles] }; int lastVertexIndex = 0; int triangleCount; int lastTriangleIndex = 0; for (int i = 0; i < totalLayers; i++) { triangleCount = layers[i].triangles.Length; for (int j = 0; j < triangleCount; j++) { triangles[0][lastTriangleIndex++] = lastVertexIndex + layers[i].triangles[j]; } lastVertexIndex += layers[i].vertices.Length; } } if (outputShaders.Count != 0) { shaders = outputShaders.ToArray(); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * Mesh Creation * * * * * * * * * * * * * * * * * * * * * * * * * * */ 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); } } #if DEBUG_IMPORT System.TimeSpan timeSpan = new System.TimeSpan(System.DateTime.Now.Ticks - timeStart); Debug.Log("Mesh combination took: " + timeSpan.TotalSeconds + "s"); #endif return(output); }
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); }
public void Apply(SerializedObject serializedObject) { this.format = (SVGAssetFormat)serializedObject.FindProperty("_format").enumValueIndex; this.useGradients = (SVGUseGradients)serializedObject.FindProperty("_useGradients").enumValueIndex; this.antialiasing = serializedObject.FindProperty("_antialiasing").boolValue; this.antialiasingWidth = serializedObject.FindProperty("_antialiasingWidth").floatValue; this.meshCompression = (SVGMeshCompression)serializedObject.FindProperty("_meshCompression").enumValueIndex; this.scale = serializedObject.FindProperty("_scale").floatValue; this.vpm = serializedObject.FindProperty("_vpm").floatValue; this.depthOffset = serializedObject.FindProperty("_depthOffset").floatValue; this.compressDepth = serializedObject.FindProperty("_compressDepth").boolValue; this.customPivotPoint = serializedObject.FindProperty("_customPivotPoint").boolValue; this.pivotPoint = serializedObject.FindProperty("_pivotPoint").vector2Value; this.border = serializedObject.FindProperty("_border").vector4Value; this.sliceMesh = serializedObject.FindProperty("_sliceMesh").boolValue; this.generateCollider = serializedObject.FindProperty("_generateCollider").boolValue; this.keepSVGFile = serializedObject.FindProperty("_keepSVGFile").boolValue; this.ignoreSVGCanvas = serializedObject.FindProperty("_ignoreSVGCanvas").boolValue; this.optimizeMesh = serializedObject.FindProperty("_optimizeMesh").boolValue; this.generateNormals = serializedObject.FindProperty("_generateNormals").boolValue; this.generateTangents = serializedObject.FindProperty("_generateTangents").boolValue; }
public static bool CombineMeshes(SVGLayer[] layers, Mesh mesh, out Shader[] shaders, SVGUseGradients useGradients = SVGUseGradients.Always, SVGAssetFormat format = SVGAssetFormat.Transparent, bool compressDepth = true, bool antialiased = false) { #if DEBUG_IMPORT long timeStart = System.DateTime.Now.Ticks; #endif shaders = new Shader[0]; //if(SVGAssetImport.sliceMesh) Create9Slice(); SVGFill fill; bool useOpaqueShader = false; bool useTransparentShader = false; bool hasGradients = (useGradients == SVGUseGradients.Always); if (layers == null) { return(false); } int totalLayers = layers.Length, totalTriangles = 0, opaqueTriangles = 0, transparentTriangles = 0; FILL_BLEND lastBlendType = FILL_BLEND.ALPHA_BLENDED; // Z Sort meshes if (format == SVGAssetFormat.Opaque) { SVGShape shape; if (compressDepth) { SVGBounds quadTreeBounds = SVGBounds.InfiniteInverse; for (int i = 0; i < totalLayers; i++) { int totalShapes = layers[i].shapes.Length; for (int j = 0; j < totalShapes; j++) { shape = layers[i].shapes[j]; if (shape.bounds.size.sqrMagnitude == 0f) { continue; } quadTreeBounds.Encapsulate(shape.bounds.center, shape.bounds.size); } } quadTreeBounds.size *= 1.2f; if (!quadTreeBounds.isInfiniteInverse) { SVGDepthTree depthTree = new SVGDepthTree(quadTreeBounds); for (int i = 0; i < totalLayers; i++) { int totalShapes = layers[i].shapes.Length; for (int j = 0; j < totalShapes; j++) { shape = layers[i].shapes[j]; int[] nodes = depthTree.TestDepthAdd(j, new SVGBounds(shape.bounds.center, shape.bounds.size)); int nodesLength = 0; if (nodes == null || nodes.Length == 0) { shape.depth = 0; } else { nodesLength = nodes.Length; int highestDepth = 0; int highestLayer = -1; for (int k = 0; k < nodesLength; k++) { if ((int)layers[i].shapes[nodes[k]].depth > highestDepth) { highestDepth = (int)layers[i].shapes[nodes[k]].depth; highestLayer = nodes[k]; } } if (layers[i].shapes[j].fill.blend == FILL_BLEND.OPAQUE) { shape.depth = highestDepth + 1; } else { if (highestLayer != -1 && layers[i].shapes[highestLayer].fill.blend == FILL_BLEND.OPAQUE) { shape.depth = highestDepth + 1; } else { shape.depth = highestDepth; } } } layers[i].shapes[j] = shape; } } } } else { int highestDepth = 0; for (int i = 0; i < totalLayers; i++) { int totalShapes = layers[i].shapes.Length; for (int j = 0; j < totalShapes; j++) { shape = layers[i].shapes[j]; fill = shape.fill; if (fill.blend == FILL_BLEND.OPAQUE || lastBlendType == FILL_BLEND.OPAQUE) { shape.depth = ++highestDepth; } else { shape.depth = highestDepth; } lastBlendType = fill.blend; layers[i].shapes[j] = shape; } } } } int totalVertices = 0, vertexCount, vertexStart = 0, currentVertex; for (int i = 0; i < totalLayers; i++) { int totalShapes = layers[i].shapes.Length; for (int j = 0; j < totalShapes; j++) { fill = layers[i].shapes[j].fill; if (fill.blend == FILL_BLEND.OPAQUE) { opaqueTriangles += layers[i].shapes[j].triangles.Length; useOpaqueShader = true; } else if (fill.blend == FILL_BLEND.ALPHA_BLENDED) { transparentTriangles += layers[i].shapes[j].triangles.Length; useTransparentShader = true; } if (fill.fillType == FILL_TYPE.GRADIENT) { hasGradients = true; } vertexCount = layers[i].shapes[j].vertices.Length; totalVertices += vertexCount; } } totalTriangles = opaqueTriangles + transparentTriangles; if (useGradients == SVGUseGradients.Never) { hasGradients = false; } if (format != SVGAssetFormat.Opaque) { useOpaqueShader = false; useTransparentShader = true; } opaqueTriangles = totalVertices = 65000; Vector3[] vertices = new Vector3[totalVertices]; Color32[] colors32 = new Color32[totalVertices]; Vector2[] uv = null; Vector2[] uv2 = null; Vector3[] normals = null; int[][] triangles = null; List <Shader> outputShaders = new List <Shader>(); if (antialiased) { normals = new Vector3[totalVertices]; } if (hasGradients) { uv = new Vector2[totalVertices]; uv2 = new Vector2[totalVertices]; if (useOpaqueShader) { outputShaders.Add(SVGShader.GradientColorOpaque); } if (useTransparentShader) { if (antialiased) { outputShaders.Add(SVGShader.GradientColorAlphaBlendedAntialiased); } else { outputShaders.Add(SVGShader.GradientColorAlphaBlended); } } } else { if (useOpaqueShader) { outputShaders.Add(SVGShader.SolidColorOpaque); } if (useTransparentShader) { if (antialiased) { outputShaders.Add(SVGShader.SolidColorAlphaBlendedAntialiased); } else { outputShaders.Add(SVGShader.SolidColorAlphaBlended); } } } for (int i = 0; i < totalLayers; i++) { int totalShapes = layers[i].shapes.Length; for (int j = 0; j < totalShapes; j++) { vertexCount = layers[i].shapes[j].vertices.Length; if (vertexStart + vertexCount >= 65000) { break; } if (layers[i].shapes[j].colors != null && layers[i].shapes[j].colors.Length == vertexCount) { Color32 finalColor = layers[i].shapes[j].fill.finalColor; for (int k = 0; k < vertexCount; k++) { currentVertex = vertexStart + k; vertices[currentVertex] = layers[i].shapes[j].vertices[k]; if (useOpaqueShader) { vertices[currentVertex].z = layers[i].shapes[j].depth * -SVGAssetImport.minDepthOffset; } else { vertices[currentVertex].z = layers[i].shapes[j].depth; } colors32[currentVertex].r = (byte)(finalColor.r * layers[i].shapes[j].colors[k].r / 255); colors32[currentVertex].g = (byte)(finalColor.g * layers[i].shapes[j].colors[k].g / 255); colors32[currentVertex].b = (byte)(finalColor.b * layers[i].shapes[j].colors[k].b / 255); colors32[currentVertex].a = (byte)(finalColor.a * layers[i].shapes[j].colors[k].a / 255); } } else { Color32 finalColor = layers[i].shapes[j].fill.finalColor; for (int k = 0; k < vertexCount; k++) { currentVertex = vertexStart + k; vertices[currentVertex] = layers[i].shapes[j].vertices[k]; if (useOpaqueShader) { vertices[currentVertex].z = layers[i].shapes[j].depth * -SVGAssetImport.minDepthOffset; } else { vertices[currentVertex].z = layers[i].shapes[j].depth; } colors32[currentVertex] = finalColor; } } if (hasGradients) { if (layers[i].shapes[j].fill.fillType == FILL_TYPE.GRADIENT && layers[i].shapes[j].fill.gradientColors != null) { SVGMatrix svgFillTransform = layers[i].shapes[j].fill.transform; Rect viewport = layers[i].shapes[j].fill.viewport; Vector2 uvPoint = Vector2.zero; Vector2 uv2Value = new Vector2(layers[i].shapes[j].fill.gradientColors.index, (int)layers[i].shapes[j].fill.gradientType); if (layers[i].shapes[j].angles != null && layers[i].shapes[j].angles.Length == vertexCount) { for (int k = 0; k < vertexCount; k++) { currentVertex = vertexStart + k; uvPoint.x = vertices [currentVertex].x; uvPoint.y = vertices [currentVertex].y; uvPoint = svgFillTransform.Transform(uvPoint); uv[currentVertex].x = (uvPoint.x - viewport.x) / viewport.width; uv[currentVertex].y = (uvPoint.y - viewport.y) / viewport.height; uv2[currentVertex] = uv2Value; normals[currentVertex].x = layers[i].shapes[j].angles[k].x; normals[currentVertex].y = layers[i].shapes[j].angles[k].y; } } else { for (int k = 0; k < vertexCount; k++) { currentVertex = vertexStart + k; uvPoint.x = vertices [currentVertex].x; uvPoint.y = vertices [currentVertex].y; uvPoint = svgFillTransform.Transform(uvPoint); uv[currentVertex].x = (uvPoint.x - viewport.x) / viewport.width; uv[currentVertex].y = (uvPoint.y - viewport.y) / viewport.height; uv2[currentVertex] = uv2Value; } } } else if (layers[i].shapes[j].fill.fillType == FILL_TYPE.TEXTURE) { SVGMatrix svgFillTransform = layers[i].shapes[j].fill.transform; Vector2 uvPoint = Vector2.zero; if (layers[i].shapes[j].angles != null && layers[i].shapes[j].angles.Length == vertexCount) { for (int k = 0; k < vertexCount; k++) { currentVertex = vertexStart + k; uvPoint.x = vertices [currentVertex].x; uvPoint.y = vertices [currentVertex].y; uv[currentVertex] = svgFillTransform.Transform(uvPoint); normals[currentVertex].x = layers[i].shapes[j].angles[k].x; normals[currentVertex].y = layers[i].shapes[j].angles[k].y; } } else { for (int k = 0; k < vertexCount; k++) { currentVertex = vertexStart + k; uvPoint.x = vertices [currentVertex].x; uvPoint.y = vertices [currentVertex].y; uv[currentVertex] = svgFillTransform.Transform(uvPoint); } } } else { if (layers[i].shapes[j].angles != null && layers[i].shapes[j].angles.Length == vertexCount) { for (int k = 0; k < vertexCount; k++) { currentVertex = vertexStart + k; normals[currentVertex].x = layers[i].shapes[j].angles[k].x; normals[currentVertex].y = layers[i].shapes[j].angles[k].y; } } } } else { if (antialiased) { if (layers[i].shapes[j].angles != null && layers[i].shapes[j].angles.Length == vertexCount) { for (int k = 0; k < vertexCount; k++) { currentVertex = vertexStart + k; normals[currentVertex] = layers[i].shapes[j].angles[k]; } } } } vertexStart += vertexCount; } } // Submesh Order 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 < totalLayers; i++) { int totalShapes = layers[i].shapes.Length; if (lastTransparentTriangleIndex + totalShapes > 56000) { break; } for (int j = 0; j < totalShapes; j++) { triangleCount = layers[i].shapes[j].triangles.Length; if (layers[i].shapes[j].fill.blend == FILL_BLEND.OPAQUE) { for (int k = 0; k < triangleCount; k++) { triangles[0][lastOpauqeTriangleIndex++] = lastVertexIndex + layers[i].shapes[j].triangles[k]; } } else { for (int k = 0; k < triangleCount; k++) { triangles[1][lastTransparentTriangleIndex++] = lastVertexIndex + layers[i].shapes[j].triangles[k]; } } lastVertexIndex += layers[i].shapes[j].vertices.Length; } } } else { triangles = new int[1][] { new int[totalTriangles] }; int lastVertexIndex = 0; int triangleCount; int lastTriangleIndex = 0; for (int i = 0; i < totalLayers; i++) { int totalShapes = layers[i].shapes.Length; if (lastTriangleIndex + totalShapes > 56000) { break; } for (int j = 0; j < totalShapes; j++) { triangleCount = layers[i].shapes[j].triangles.Length; for (int k = 0; k < triangleCount; k++) { triangles[0][lastTriangleIndex++] = lastVertexIndex + layers[i].shapes[j].triangles[k]; } lastVertexIndex += layers[i].shapes[j].vertices.Length; } } } if (outputShaders.Count != 0) { shaders = outputShaders.ToArray(); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * Mesh Creation * * * * * * * * * * * * * * * * * * * * * * * * * * */ mesh.Clear(); mesh.MarkDynamic(); if (vertices != null) { if (vertices.Length > 65000) { Debug.LogError("A mesh may not have more than 65000 vertices. Please try to reduce quality or split SVG file."); return(false); } } else { return(false); } mesh.vertices = vertices; mesh.colors32 = colors32; if (uv != null) { mesh.uv = uv; } if (uv2 != null) { mesh.uv2 = uv2; } if (normals != null) { mesh.normals = normals; } if (triangles.Length == 1) { mesh.triangles = triangles[0]; } else { mesh.subMeshCount = triangles.Length; for (int i = 0; i < triangles.Length; i++) { mesh.SetTriangles(triangles[i], i); } } #if DEBUG_IMPORT System.TimeSpan timeSpan = new System.TimeSpan(System.DateTime.Now.Ticks - timeStart); Debug.Log("Mesh combination took: " + timeSpan.TotalSeconds + "s"); #endif return(true); }
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; }