public SVGMatrix ViewBoxTransform() { if(this._cachedViewBoxTransform == null) { SVGMatrix matrix = new SVGMatrix(); float x = 0.0f; float y = 0.0f; float w = 0.0f; float h = 0.0f; float attrWidth = this._width.value; float attrHeight = this._height.value; if(_attrList.GetValue("viewBox") != "") { Rect r = this._viewport; x += -r.x; y += -r.y; w = r.width; h = r.height; } else { w = attrWidth; h = attrHeight; } float x_ratio = attrWidth / w; float y_ratio = attrHeight / h; matrix = matrix.ScaleNonUniform(x_ratio, y_ratio); matrix = matrix.Translate(x, y); _cachedViewBoxTransform = matrix; } return this._cachedViewBoxTransform; }
public SVGPoint MatrixTransform(SVGMatrix matrix) { float a,b,c,d,e,f; a = matrix.a; b = matrix.b; c = matrix.c; d = matrix.d; e = matrix.e; f = matrix.f; return new SVGPoint(a*x + c*y + e, b*x + d*y +f); }
//--------------------------------------- public SVGMatrix Multiply(SVGMatrix secondMatrix) { float sa, sb, sc, sd, se, sf; sa = secondMatrix.a; sb = secondMatrix.b; sc = secondMatrix.c; sd = secondMatrix.d; se = secondMatrix.e; sf = secondMatrix.f; return new SVGMatrix(a*sa + c*sb, b*sa + d*sb, a*sc + c*sd, b*sc + d*sd, a*se + c*sf + e, b*se + d*sf + f); }
public void SetScale(float sx, float sy) { this._type = SVGTransformMode.Scale; this._matrix = new SVGMatrix().ScaleNonUniform(sx, sy); }
public void SetRotate(float angle, float cx, float cy) { this._type = SVGTransformMode.Rotate; this._angle = angle; this._matrix = new SVGMatrix().Translate(cx, cy).Rotate(angle).Translate(-cx,-cy); }
/*********************************************************************************************/ public void Clear() { _listTransform.Clear(); _totalMatrix = null; }
/// <summary> /// Performs matrix multiplication. This matrix is post-multiplied by another matrix, returning /// the resulting new matrix. /// </summary> public virtual SVGMatrix Multiply(SVGMatrix secondMatrix) { return null; }
/// <summary> /// This method uses an SVGMatrix object as the pattern's transformation matrix and invokes /// it on the pattern. /// </summary> /// <remarks>This is experimental API that should not be used in production code.</remarks> public virtual void SetTransform(SVGMatrix matrix) { return; }
//*********************************************************************************** public SVGTransform() { this._matrix = new SVGMatrix(); this._type = SVGTransformMode.Matrix; }
public void AppendItems(SVGTransformList newListItem) { _listTransform.AddRange(newListItem._listTransform); _totalMatrix = null; }
public void AppendItem(SVGTransform newItem) { _listTransform.Add(newItem); _totalMatrix = null; }
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; } 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 (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; 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; 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 void SetSkewY(float angle) { this._type = SVGTransformMode.SkewY; this._angle = angle; this._matrix = new SVGMatrix().SkewY(angle); }
public void SetTranslate(float tx, float ty) { this._type = SVGTransformMode.Translate; this._matrix = new SVGMatrix().Translate(tx, ty); }
public SVGTransform(SVGMatrix matrix) { this._type = SVGTransformMode.Matrix; this._matrix = matrix; }
/// <summary> /// Adds a path to the current path. /// </summary> /// <param name="path"></param> /// <param name="transform"></param> public void AddPath(Path2D path, SVGMatrix transform = null) { return; }
public SVGMatrix ViewBoxTransform() { if (this._cachedViewBoxTransform == null) { Rect viewport = _paintable.viewport; if(_rootElement) { _cachedViewBoxTransform = SVGTransformable.GetRootViewBoxTransform(_attrList, ref viewport); } else { _cachedViewBoxTransform = SVGTransformable.GetViewBoxTransform(_attrList, ref viewport, true); } //Debug.Log(viewport); //Debug.Log(_xmlImp.node.name); paintable.SetViewport(viewport); } return this._cachedViewBoxTransform; }
/// <summary> /// Performs matrix multiplication. This matrix is post-multiplied by another matrix, returning /// the resulting new matrix. /// </summary> public virtual extern SVGMatrix Multiply(SVGMatrix secondMatrix);
//*********************************************************************************** public void SetMatrix(SVGMatrix matrix) { this._type = SVGTransformMode.Matrix; this._matrix = matrix; }
public static Vector2 TransformPoint(Vector2 point, SVGMatrix matrix) { point = matrix.Transform(point); return point; }
public void SetRotate(float angle) { this._type = SVGTransformMode.Rotate; this._angle = angle; this._matrix = new SVGMatrix().Rotate(angle); }