public List <List <Vector2> > GetPath() { List <Vector2> output = new List <Vector2>(); float widthValue = width.value, heightValue = height.value; float xValue = x.value, yValue = y.value, rxValue = rx.value, ryValue = ry.value; Vector2 p1 = new Vector2(xValue, yValue), p2 = new Vector2(xValue + widthValue, yValue), p3 = new Vector2(xValue + widthValue, yValue + heightValue), p4 = new Vector2(xValue, yValue + heightValue); if (rxValue == 0.0f && ryValue == 0.0f) { output = new List <Vector2>(new Vector2[] { transformMatrix.Transform(p1), transformMatrix.Transform(p2), transformMatrix.Transform(p3), transformMatrix.Transform(p4) }); } else { float t_rx = (rxValue == 0.0f) ? ryValue : rxValue; float t_ry = (ryValue == 0.0f) ? rxValue : ryValue; t_rx = (t_rx > (widthValue * 0.5f - 2f)) ? (widthValue * 0.5f - 2f) : t_rx; t_ry = (t_ry > (heightValue * 0.5f - 2f)) ? (heightValue * 0.5f - 2f) : t_ry; float angle = transformAngle; Vector2 t_p1 = transformMatrix.Transform(new Vector2(p1.x + t_rx, p1.y)); Vector2 t_p2 = transformMatrix.Transform(new Vector2(p2.x - t_rx, p2.y)); Vector2 t_p3 = transformMatrix.Transform(new Vector2(p2.x, p2.y + t_ry)); Vector2 t_p4 = transformMatrix.Transform(new Vector2(p3.x, p3.y - t_ry)); Vector2 t_p5 = transformMatrix.Transform(new Vector2(p3.x - t_rx, p3.y)); Vector2 t_p6 = transformMatrix.Transform(new Vector2(p4.x + t_rx, p4.y)); Vector2 t_p7 = transformMatrix.Transform(new Vector2(p4.x, p4.y - t_ry)); Vector2 t_p8 = transformMatrix.Transform(new Vector2(p1.x, p1.y + t_ry)); output = SVGGeomUtils.RoundedRect(t_p1, t_p2, t_p3, t_p4, t_p5, t_p6, t_p7, t_p8, t_rx, t_ry, angle); } output.Add(output[0]); return(new List <List <Vector2> >() { output }); }
public static List <Vector2> GetPath(SVGMatrix matrix, SVGRectElement svgElement) { List <Vector2> output = new List <Vector2>(); float width = svgElement.width.value, height = svgElement.height.value; float x = svgElement.x.value, y = svgElement.y.value, rx = svgElement.rx.value, ry = svgElement.ry.value; Vector2 p1 = new Vector2(x, y), p2 = new Vector2(x + width, y), p3 = new Vector2(x + width, y + height), p4 = new Vector2(x, y + height); if (rx == 0.0f && ry == 0.0f) { output = new List <Vector2>(new Vector2[] { matrix.Transform(p1), matrix.Transform(p2), matrix.Transform(p3), matrix.Transform(p4) }); } else { float t_rx = (rx == 0.0f) ? ry : rx; float t_ry = (ry == 0.0f) ? rx : ry; t_rx = (t_rx > (width * 0.5f - 2f)) ? (width * 0.5f - 2f) : t_rx; t_ry = (t_ry > (height * 0.5f - 2f)) ? (height * 0.5f - 2f) : t_ry; float angle = svgElement.transformAngle; Vector2 t_p1 = matrix.Transform(new Vector2(p1.x + t_rx, p1.y)); Vector2 t_p2 = matrix.Transform(new Vector2(p2.x - t_rx, p2.y)); Vector2 t_p3 = matrix.Transform(new Vector2(p2.x, p2.y + t_ry)); Vector2 t_p4 = matrix.Transform(new Vector2(p3.x, p3.y - t_ry)); Vector2 t_p5 = matrix.Transform(new Vector2(p3.x - t_rx, p3.y)); Vector2 t_p6 = matrix.Transform(new Vector2(p4.x + t_rx, p4.y)); Vector2 t_p7 = matrix.Transform(new Vector2(p4.x, p4.y - t_ry)); Vector2 t_p8 = matrix.Transform(new Vector2(p1.x, p1.y + t_ry)); output = SVGGeomUtils.RoundedRect(t_p1, t_p2, t_p3, t_p4, t_p5, t_p6, t_p7, t_p8, t_rx, t_ry, angle); } output.Add(output[0]); return(output); }
public static List <Vector2> Ellipse(float cx, float cy, float rx, float ry, SVGMatrix matrix) { List <Vector2> output = new List <Vector2>(); cx -= rx; cy -= ry; float handleDistanceX = circleConstant * rx; float handleDistanceY = circleConstant * ry; Vector2 handleRight = new Vector2(handleDistanceX, 0f); Vector2 handleLeft = new Vector2(-handleDistanceX, 0f); Vector2 handleUp = new Vector2(0f, -handleDistanceY); Vector2 handleDown = new Vector2(0f, handleDistanceY); Vector2 topCenter = new Vector2(cx + rx, cy); Vector2 left = new Vector2(cx, cy + ry); // Vector2 center = new Vector2(cx + rx, cy + ry); Vector2 right = new Vector2(cx + rx * 2f, cy + ry); Vector2 bottomCenter = new Vector2(cx + rx, cy + ry * 2f); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(topCenter), matrix.Transform(topCenter + handleRight), matrix.Transform(right + handleUp), matrix.Transform(right))); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(right), matrix.Transform(right + handleDown), matrix.Transform(bottomCenter + handleRight), matrix.Transform(bottomCenter))); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(bottomCenter), matrix.Transform(bottomCenter + handleLeft), matrix.Transform(left + handleDown), matrix.Transform(left))); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(left), matrix.Transform(left + handleUp), matrix.Transform(topCenter + handleLeft), matrix.Transform(topCenter))); return(output); }
public static List <Vector2> Circle(float x0, float y0, float radius, SVGMatrix matrix) { List <Vector2> output = new List <Vector2>(); x0 -= radius; y0 -= radius; float handleDistance = circleConstant * radius; Vector2 handleRight = new Vector2(handleDistance, 0f); Vector2 handleLeft = new Vector2(-handleDistance, 0f); Vector2 handleUp = new Vector2(0f, -handleDistance); Vector2 handleDown = new Vector2(0f, handleDistance); Vector2 topCenter = new Vector2(x0 + radius, y0); Vector2 left = new Vector2(x0, y0 + radius); Vector2 right = new Vector2(x0 + radius * 2f, y0 + radius); Vector2 bottomCenter = new Vector2(x0 + radius, y0 + radius * 2f); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(topCenter), matrix.Transform(topCenter + handleRight), matrix.Transform(right + handleUp), matrix.Transform(right))); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(right), matrix.Transform(right + handleDown), matrix.Transform(bottomCenter + handleRight), matrix.Transform(bottomCenter))); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(bottomCenter), matrix.Transform(bottomCenter + handleLeft), matrix.Transform(left + handleDown), matrix.Transform(left))); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(left), matrix.Transform(left + handleUp), matrix.Transform(topCenter + handleLeft), matrix.Transform(topCenter))); return(output); }
bool GetSegment(SVGPathElement svgElement, SVGPathSeg segment, List <List <Vector2> > output, List <Vector2> positionBuffer, SVGMatrix matrix) { if (segment == null) { return(false); } // Debug.Log("command: "+segment.type+", lastCommand: "+lastCommand); switch (segment.type) { case SVGPathSegTypes.Arc_Abs: SVGPathSegArcAbs arcAbs = segment as SVGPathSegArcAbs; #if PATH_COMMAND_DEBUG Debug.Log("arcAbs"); #endif positionBuffer.AddRange(SVGGeomUtils.Arc(SVGGeomUtils.TransformPoint(arcAbs.previousPoint, matrix), arcAbs.r1, arcAbs.r2, arcAbs.angle, arcAbs.largeArcFlag, arcAbs.sweepFlag, SVGGeomUtils.TransformPoint(arcAbs.currentPoint, matrix))); break; case SVGPathSegTypes.Arc_Rel: SVGPathSegArcRel arcRel = segment as SVGPathSegArcRel; #if PATH_COMMAND_DEBUG Debug.Log("arcRel"); #endif positionBuffer.AddRange(SVGGeomUtils.Arc(SVGGeomUtils.TransformPoint(arcRel.previousPoint, matrix), arcRel.r1, arcRel.r2, arcRel.angle, arcRel.largeArcFlag, arcRel.sweepFlag, SVGGeomUtils.TransformPoint(arcRel.currentPoint, matrix))); break; case SVGPathSegTypes.Close: #if PATH_COMMAND_DEBUG Debug.Log("Close"); #endif //Debug.Log("Close"); if (positionBuffer.Count > 0) { output.Add(new List <Vector2>(positionBuffer.ToArray())); } positionBuffer.Clear(); break; case SVGPathSegTypes.CurveTo_Cubic_Abs: SVGPathSegCurvetoCubicAbs curvetoCubicAbs = segment as SVGPathSegCurvetoCubicAbs; #if PATH_COMMAND_DEBUG Debug.Log("curvetoCubicAbs"); #endif positionBuffer.AddRange(SVGGeomUtils.CubicCurve(SVGGeomUtils.TransformPoint(curvetoCubicAbs.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoCubicAbs.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoCubicAbs.controlPoint2, matrix), SVGGeomUtils.TransformPoint(curvetoCubicAbs.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Cubic_Rel: SVGPathSegCurvetoCubicRel curvetoCubicRel = segment as SVGPathSegCurvetoCubicRel; #if PATH_COMMAND_DEBUG Debug.Log("curvetoCubicRel"); #endif positionBuffer.AddRange(SVGGeomUtils.CubicCurve(SVGGeomUtils.TransformPoint(curvetoCubicRel.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoCubicRel.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoCubicRel.controlPoint2, matrix), SVGGeomUtils.TransformPoint(curvetoCubicRel.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Cubic_Smooth_Abs: SVGPathSegCurvetoCubicSmoothAbs curvetoCubicSmoothAbs = segment as SVGPathSegCurvetoCubicSmoothAbs; #if PATH_COMMAND_DEBUG Debug.Log("curvetoCubicSmoothAbs"); #endif positionBuffer.AddRange(SVGGeomUtils.CubicCurve(SVGGeomUtils.TransformPoint(curvetoCubicSmoothAbs.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothAbs.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothAbs.controlPoint2, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothAbs.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Cubic_Smooth_Rel: SVGPathSegCurvetoCubicSmoothRel curvetoCubicSmoothRel = segment as SVGPathSegCurvetoCubicSmoothRel; #if PATH_COMMAND_DEBUG Debug.Log("curvetoCubicSmoothRel"); #endif positionBuffer.AddRange(SVGGeomUtils.CubicCurve(SVGGeomUtils.TransformPoint(curvetoCubicSmoothRel.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothRel.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothRel.controlPoint2, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothRel.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Quadratic_Abs: SVGPathSegCurvetoQuadraticAbs curvetoQuadraticAbs = segment as SVGPathSegCurvetoQuadraticAbs; #if PATH_COMMAND_DEBUG Debug.Log("curvetoQuadraticAbs"); #endif positionBuffer.AddRange(SVGGeomUtils.QuadraticCurve(SVGGeomUtils.TransformPoint(curvetoQuadraticAbs.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticAbs.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticAbs.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Quadratic_Rel: SVGPathSegCurvetoQuadraticRel curvetoQuadraticRel = segment as SVGPathSegCurvetoQuadraticRel; #if PATH_COMMAND_DEBUG Debug.Log("curvetoQuadraticRel"); #endif positionBuffer.AddRange(SVGGeomUtils.QuadraticCurve(SVGGeomUtils.TransformPoint(curvetoQuadraticRel.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticRel.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticRel.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Quadratic_Smooth_Abs: SVGPathSegCurvetoQuadraticSmoothAbs curvetoQuadraticSmoothAbs = segment as SVGPathSegCurvetoQuadraticSmoothAbs; #if PATH_COMMAND_DEBUG Debug.Log("curvetoQuadraticSmoothAbs"); #endif positionBuffer.AddRange(SVGGeomUtils.QuadraticCurve(SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothAbs.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothAbs.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothAbs.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Quadratic_Smooth_Rel: SVGPathSegCurvetoQuadraticSmoothRel curvetoQuadraticSmoothRel = segment as SVGPathSegCurvetoQuadraticSmoothRel; #if PATH_COMMAND_DEBUG Debug.Log("curvetoQuadraticSmoothRel"); #endif positionBuffer.AddRange(SVGGeomUtils.QuadraticCurve(SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothRel.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothRel.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothRel.currentPoint, matrix))); break; case SVGPathSegTypes.LineTo_Abs: SVGPathSegLinetoAbs linetoAbs = segment as SVGPathSegLinetoAbs; #if PATH_COMMAND_DEBUG Debug.Log("linetoAbs"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoAbs.currentPoint, matrix)); break; case SVGPathSegTypes.LineTo_Horizontal_Abs: #if PATH_COMMAND_DEBUG Debug.Log("linetoHorizontalAbs"); #endif SVGPathSegLinetoHorizontalAbs linetoHorizontalAbs = segment as SVGPathSegLinetoHorizontalAbs; positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoHorizontalAbs.currentPoint, matrix)); break; case SVGPathSegTypes.LineTo_Horizontal_Rel: #if PATH_COMMAND_DEBUG Debug.Log("linetoHorizontalRel"); #endif SVGPathSegLinetoHorizontalRel linetoHorizontalRel = segment as SVGPathSegLinetoHorizontalRel; positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoHorizontalRel.currentPoint, matrix)); break; case SVGPathSegTypes.LineTo_Rel: SVGPathSegLinetoRel linetoRel = segment as SVGPathSegLinetoRel; #if PATH_COMMAND_DEBUG Debug.Log("linetoRel"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoRel.currentPoint, matrix)); break; case SVGPathSegTypes.LineTo_Vertical_Abs: SVGPathSegLinetoVerticalAbs linetoVerticalAbs = segment as SVGPathSegLinetoVerticalAbs; #if PATH_COMMAND_DEBUG Debug.Log("linetoVerticalAbs"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoVerticalAbs.currentPoint, matrix)); break; case SVGPathSegTypes.LineTo_Vertical_Rel: SVGPathSegLinetoVerticalRel linetoVerticalRel = segment as SVGPathSegLinetoVerticalRel; #if PATH_COMMAND_DEBUG Debug.Log("linetoVerticalRel"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoVerticalRel.currentPoint, matrix)); break; case SVGPathSegTypes.MoveTo_Abs: if (lastCommand != SVGPathSegTypes.Close && lastCommand != SVGPathSegTypes.MoveTo_Abs && lastCommand != SVGPathSegTypes.MoveTo_Rel) { if (positionBuffer.Count > 0) { output.Add(new List <Vector2>(positionBuffer.ToArray())); positionBuffer.Clear(); } } SVGPathSegMovetoAbs movetoAbs = segment as SVGPathSegMovetoAbs; #if PATH_COMMAND_DEBUG Debug.Log("movetoAbs"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(movetoAbs.currentPoint, matrix)); break; case SVGPathSegTypes.MoveTo_Rel: if (lastCommand != SVGPathSegTypes.Close && lastCommand != SVGPathSegTypes.MoveTo_Abs && lastCommand != SVGPathSegTypes.MoveTo_Rel) { if (positionBuffer.Count > 0) { output.Add(new List <Vector2>(positionBuffer.ToArray())); positionBuffer.Clear(); } } SVGPathSegMovetoRel movetoRel = segment as SVGPathSegMovetoRel; #if PATH_COMMAND_DEBUG Debug.Log("movetoRel"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(movetoRel.currentPoint, matrix)); break; } lastCommand = segment.type; return(true); }
protected virtual void UpdateCollider() { if (svgRenderer == null) { svgRenderer = GetComponent <SVGRenderer>(); } if (polygonCollider2D == null) { polygonCollider2D = GetComponent <PolygonCollider2D>(); } if (svgRenderer.vectorGraphics == null || svgRenderer.vectorGraphics.colliderShape == null || svgRenderer.vectorGraphics.colliderShape.Length == 0) { polygonCollider2D.pathCount = 0; polygonCollider2D.points = null; } else { SVGPath[] colliderShape = svgRenderer.vectorGraphics.colliderShape; polygonCollider2D.pathCount = 0; if (_quality < 1f) { Bounds bounds = svgRenderer.vectorGraphics.bounds; float finQuality = _quality; if (finQuality < 0.001f) { finQuality = 0.001f; } precision = Mathf.Max(bounds.size.x, bounds.size.y) / finQuality; if (precision < 0.001f) { precision = 0.001f; } precision *= 0.05f; } List <Vector2[]> optimisedPaths = new List <Vector2[]>(); Vector2[] points; for (int i = 0; i < colliderShape.Length; i++) { if (_quality < 1f) { points = SVGBezier.Optimise(colliderShape[i].points, precision); } else { points = (Vector2[])colliderShape[i].points.Clone(); } //bool clockwiseWinding = SVGGeomUtils.IsWindingClockWise(points); if (_offset != 0f) { points = SVGGeomUtils.OffsetVerts(points, _offset); } if (points != null && points.Length > 2) { optimisedPaths.Add(points); } } if (optimisedPaths.Count > 0) { polygonCollider2D.pathCount = optimisedPaths.Count; for (int i = 0; i < optimisedPaths.Count; i++) { polygonCollider2D.SetPath(i, optimisedPaths[i]); } } } }