/// <summary>
    /// Create a Sprite icon of a SVG image.
    /// </summary>
    /// <param name="svgContent">String containing svg content.</param>
    /// <remarks>
    /// Standard header and footer will be included if not found in svgContent
    /// </remarks>
    public static Sprite GetSprite(string svgContent)
    {
        string svg;

        if (svgContent.StartsWith("<?xml version = \"1.0\" encoding=\"UTF - 8\"?>"))
        {
            svg = svgContent;
        }
        else
        {
            svg = svgIconHeader + svgContent;
        }

        if (!svg.EndsWith(svgIconFooter))
        {
            svg = svg + svgIconFooter;
        }

        // Parse the SVG
        SVGParser.SceneInfo sceneInfo = SVGParser.ImportSVG(new System.IO.StringReader(svg));
        int width  = Mathf.CeilToInt(sceneInfo.SceneViewport.width);
        int height = Mathf.CeilToInt(sceneInfo.SceneViewport.height);

        if ((width > 64) || (height > 64))
        {
            Debug.LogWarning("SVG icon of unusual size!");
        }

        List <VectorUtils.Geometry> iconGeometry = VectorUtils.TessellateScene(sceneInfo.Scene, tessellationOptions);

        Sprite sprite = VectorUtils.BuildSprite(iconGeometry, 100f, VectorUtils.Alignment.Center, Vector2.zero, 128, true);

        return(sprite);
    }
        private void ComputeTessellationOptions(SVGParser.SceneInfo sceneInfo, int targetResolution, float multiplier, out float stepDist, out float maxCord, out float maxTangent)
        {
            // These tessellation options were found by trial and error to find values that made
            // visual sense with a variety of SVG assets.

            // "Pixels per Unit" doesn't make sense for UI Toolkit since it will be displayed in
            // a pixels space.  We adjust the magic values below accordingly.
            #if UNITY_2019_3_OR_NEWER
            float ppu = (SvgType == SVGType.UIToolkit) ? 1.0f : SvgPixelsPerUnit;
            #else
            float ppu = SvgPixelsPerUnit;
            #endif

            var   bbox   = VectorUtils.ApproximateSceneNodeBounds(sceneInfo.Scene.Root);
            float maxDim = Mathf.Max(bbox.width, bbox.height) / ppu;

            // The scene ratio gives a rough estimate of coverage % of the vector scene on the screen.
            // Higher values should result in a more dense tessellation.
            float sceneRatio = maxDim / (targetResolution * multiplier);

            stepDist = float.MaxValue; // No need for uniform step distance
            #if UNITY_2019_3_OR_NEWER
            if (SvgType == SVGType.UIToolkit)
            {
                maxCord    = Mathf.Max(0.01f, 2.0f * sceneRatio);
                maxTangent = Mathf.Max(0.1f, 3.0f * sceneRatio);
            }
            else
            #endif
            {
                maxCord    = Mathf.Max(0.01f, 75.0f * sceneRatio);
                maxTangent = Mathf.Max(0.1f, 100.0f * sceneRatio);
            }
        }
    /// <summary>
    /// Create a Texture2D icon of a SVG image.
    /// </summary>
    /// <param name="svg">String containing svg content.</param>
    public static Texture2D GetIcon(string svg)
    {
        // Parse the SVG
        SVGParser.SceneInfo sceneInfo = SVGParser.ImportSVG(new System.IO.StringReader(svg));
        int width  = Mathf.CeilToInt(sceneInfo.SceneViewport.width);
        int height = Mathf.CeilToInt(sceneInfo.SceneViewport.height);

        if ((width > 64) || (height > 64))
        {
            Debug.LogWarning("SVG icon of unusual size!");
        }

        VectorUtils.TessellationOptions tessellationOptions = new VectorUtils.TessellationOptions()
        {
            StepDistance         = 0.05f,
            MaxCordDeviation     = float.MaxValue,
            MaxTanAngleDeviation = Mathf.PI / 2.0f,
            SamplingStepSize     = 0.01f
        };
        List <VectorUtils.Geometry> iconGeometry = VectorUtils.TessellateScene(sceneInfo.Scene, tessellationOptions);

        Sprite    sprite      = VectorUtils.BuildSprite(iconGeometry, 1f, VectorUtils.Alignment.Center, Vector2.zero, 128, true);
        Texture2D iconTexture = VectorUtils.RenderSpriteToTexture2D(sprite, width, height, renderMaterial);

        return(iconTexture);
    }
    /// <summary>
    /// Create a Texture2D icon of a SVG image (editor only version).
    /// </summary>
    /// <param name="svg">String containing svg content.</param>
    /// <param name="renderUtil">PreviewRenderUtility to use for drawing</param>
    public static Texture2D GetIcon(string svg, PreviewRenderUtility renderUtil)
    {
        // Parse the SVG
        SVGParser.SceneInfo sceneInfo = SVGParser.ImportSVG(new System.IO.StringReader(svg));
        int width  = Mathf.CeilToInt(sceneInfo.SceneViewport.width);
        int height = Mathf.CeilToInt(sceneInfo.SceneViewport.height);

        if ((width > 64) || (height > 64))
        {
            Debug.LogWarning("SVG icon of unusual size!");
        }

        // Save the render state and get a temporary render texture
        RenderTexture activeTexture = RenderTexture.active;

        renderUtil.camera.targetTexture   = RenderTexture.GetTemporary(width, height, 8, RenderTextureFormat.ARGB32);
        renderUtil.camera.backgroundColor = Color.clear;

        // Generate the mesh
        Mesh iconMesh = new Mesh();

        VectorUtils.TessellationOptions tessellationOptions = new VectorUtils.TessellationOptions()
        {
            StepDistance         = 0.05f,
            MaxCordDeviation     = float.MaxValue,
            MaxTanAngleDeviation = Mathf.PI / 2.0f,
            SamplingStepSize     = 0.01f
        };
        List <VectorUtils.Geometry> iconGeometry = VectorUtils.TessellateScene(sceneInfo.Scene, tessellationOptions);

        VectorUtils.FillMesh(iconMesh, iconGeometry, 1f);

        // Activate the render texture and draw the mesh into it
        RenderTexture.active = renderUtil.camera.targetTexture;
        float   cameraSize     = renderUtil.camera.orthographicSize;
        Vector3 cameraPosition = renderUtil.camera.transform.position;

        renderUtil.camera.orthographicSize   = sceneInfo.SceneViewport.height / 2;
        renderUtil.camera.transform.position = new Vector3(sceneInfo.SceneViewport.center.x, sceneInfo.SceneViewport.center.y, -1);
        // HACK until FillMesh() flpYAxis is fixed
        renderUtil.camera.transform.Rotate(0, 0, 180f);
        renderUtil.DrawMesh(iconMesh, Matrix4x4.identity, renderMaterial, 0);
        renderUtil.camera.Render();
        renderUtil.camera.transform.Rotate(0, 0, 180f);
        renderUtil.camera.orthographicSize   = cameraSize;
        renderUtil.camera.transform.position = cameraPosition;
        Texture2D iconTexture = new Texture2D(width, height);

        iconTexture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
        iconTexture.Apply();

        // Restore the render state and release the temporary render texture
        RenderTexture.active = activeTexture;
        RenderTexture.ReleaseTemporary(renderUtil.camera.targetTexture);

        return(iconTexture);
    }
Exemple #5
0
    /// <summary>
    /// Parse SVG into VectorShape list.
    /// </summary>
    public static List <VectorShape> ReadSVG(System.IO.TextReader svg)
    {
        List <VectorShape> shapes = new List <VectorShape>();

        SVGParser.SceneInfo sceneInfo = SVGParser.ImportSVG(svg);
        //Debug.Log(sceneInfo.SceneViewport);

        Matrix2D rootTransform = Matrix2D.Scale(new Vector2(0.01f, -0.01f)) * sceneInfo.Scene.Root.Transform;

        RecurseSVGNodes(sceneInfo.Scene.Root, rootTransform, shapes);

        return(shapes);
    }
Exemple #6
0
        private void ComputeTessellationOptions(SVGParser.SceneInfo sceneInfo, int targetResolution, float multiplier, out float stepDist, out float maxCord, out float maxTangent)
        {
            var   bbox   = VectorUtils.ApproximateSceneNodeBounds(sceneInfo.Scene.Root);
            float maxDim = Mathf.Max(bbox.width, bbox.height) / SvgPixelsPerUnit;

            // The scene ratio gives a rough estimate of coverage % of the vector scene on the screen.
            // Higher values should result in a more dense tessellation.
            float sceneRatio = maxDim / (targetResolution * multiplier);

            stepDist   = float.MaxValue; // No need for uniform step distance
            maxCord    = Mathf.Max(0.01f, 75.0f * sceneRatio);
            maxTangent = Mathf.Max(0.1f, 100.0f * sceneRatio);
        }
Exemple #7
0
    public void SetAppearance()
    {
        worldController = WorldController.GetWorldController;
        citizen         = GetComponent <Citizen>();

        skinTone = worldController.skinTones[Random.Range(0, worldController.skinTones.Length)];
        skinTone = ChangeColorBrightness(skinTone);

        string svg =
            @"<svg xmlns=""http://www.w3.org/2000/svg"" viewBox=""0 0 30.11 27.39"">
                <g><path id=""Body"" d=""M30.81,17.36c0,7.43-6.63,13.45-14.81,13.45s-14.81-6-14.81-13.45a12.56,12.56,0,0,1,.36-3C3,8.4,8.94,3.92,16,3.92,24.18,3.92,30.81,9.94,30.81,17.36Z"" transform=""translate(-0.94 -3.67)"" fill=""#fff"" stroke=""#000"" stroke-miterlimit=""10"" stroke-width=""0.5""/></g>";

        Hand(0);
        Hand(1);

        int hairChance = Random.Range(0, citizen.gender ? 100 : 55);

        SVGParser.SceneInfo sceneInfo = default;
        if (hairChance < 70)
        {
            SetHair(ref svg, ref sceneInfo);
        }
        else
        {
            svg += "</svg>";

            sceneInfo = SVGParser.ImportSVG(new StringReader(svg));
        }

        var shape = sceneInfo.NodeIDs["Body"].Shapes[0];

        shape.Fill = new SolidFill()
        {
            Color = skinTone
        };

        var tessOptions = new VectorUtils.TessellationOptions()
        {
            StepDistance         = 100f,
            MaxCordDeviation     = 0.5f,
            MaxTanAngleDeviation = 0.1f,
            SamplingStepSize     = 0.01f
        };

        var geoms  = VectorUtils.TessellateScene(sceneInfo.Scene, tessOptions);
        var sprite = VectorUtils.BuildSprite(geoms, 26, VectorUtils.Alignment.Center, Vector2.zero, 128, true);

        GetComponent <SpriteRenderer>().sprite = sprite;
    }
Exemple #8
0
    public bool ImportSVG(TextReader textReader, ViewportOptions viewportOptions, float dpi = 0, float pixelsPerUnit = 1, int windowWidth = 0, int windowHeight = 0)
    {
        bool ret = false;

        try
        {
            _scene = SVGParser.ImportSVG(textReader, viewportOptions, dpi, pixelsPerUnit, windowWidth, windowHeight);
            ret    = true;
        }
        catch (System.Exception e)
        {
            Debug.LogError(e);
        }
        return(ret);
    }
Exemple #9
0
    void ApplySVGPath()
    {
        string svgPath = "Assets/RouteData/drawsvg.svg";

        SVGParser.SceneInfo sceneInfo = SVGParser.ImportSVG(new StreamReader(svgPath));
        Shape path = sceneInfo.NodeIDs["e1_polyline"].Shapes[0];

        Debug.Log(path);

        BezierContour[] cs = path.Contours;
        BezierContour   c  = cs[0];

        //Debug.Log(c);

        BezierPathSegment[] ss = c.Segments;
        Debug.Log($"SVGRoute segments count: {ss.Length}");
        for (int i = 0; i < ss.Length; i++)
        {
            BezierPathSegment s = ss[i];
            Debug.Log($"SVGRoute Segment points: {s.P0} -> {s.P1} -> {s.P2}");

            var debug1 = GameObject.Find($"SVGTarget{(i * 3) + 1}");
            var debug2 = GameObject.Find($"SVGTarget{(i * 3) + 2}");
            var debug3 = GameObject.Find($"SVGTarget{(i * 3) + 3}");
            debug1.transform.localPosition = s.P0;
            debug2.transform.localPosition = s.P1;
            debug3.transform.localPosition = s.P2;
            Debug.Log(debug3);
        }


        // debug1.transform.position = new Vector3(s.P0.x, 0.1f, s.P0.y);
        //     //(s.P0.x / 10) - 10f, 0.1f, (s.P0.y / 10) + 4.3f);
        // debug2.transform.position = new Vector3(s.P1.x, 0.1f, s.P1.y);
        // debug3.transform.position = new Vector3(s.P2.x, 0.1f, s.P2.y);
        var debug0 = GameObject.Find("SVGTarget0");

        debug0.transform.localPosition = Vector3.zero;

        //path.
        //var fill = shape.Fill as SolidFill;
        //fill.Color = Color.red;

        // ...
        //var geoms = VectorUtils.TessellateScene(sceneInfo.Scene, tessOptions);
        //var sprite = VectorUtils.BuildSprite(geoms, 100.0f, VectorUtils.Alignment.Center, Vector2.zero, 128, true);
    }
Exemple #10
0
    void SetHair(ref string svg, ref SVGParser.SceneInfo sceneInfo)
    {
        if (citizen.age >= 55)
        {
            hairColour = Color.grey;
        }
        else
        {
            hairColour = worldController.hairColours[Random.Range(0, worldController.hairColours.Length)];
        }
        hairColour = ChangeColorBrightness(hairColour);

        //string hairSvg =
        //    @"<svg xmlns=""http://www.w3.org/2000/svg"" viewBox=""0 0 30.21 14.6"">";

        int style = 0;

        if (!citizen.gender)
        {
            RandomHairStyle(ref svg, out style);
        }
        svg      += @"<g><path id=""Hair1"" d=""M30.82,16.71c.29,7.6-6.42,14-14.57,14.1-8.33.12-15.34-6.33-15-14.1"" transform=""translate(-1 -2.6)"" fill=""#fff"" stroke=""#040000"" stroke-linecap=""round"" stroke-miterlimit=""10"" stroke-width=""0.5""/></g>
                        <g><path id=""Hair2"" d=""M1.12,16.71a29.34,29.34,0,0,0,14.88,4,29.25,29.25,0,0,0,14.75-4"" transform=""translate(-1 -2.6)"" fill=""#fff"" stroke=""#000"" stroke-linecap=""round"" stroke-miterlimit=""10"" stroke-width=""0.5""/></g>
                        </svg>";
        sceneInfo = SVGParser.ImportSVG(new StringReader(svg));
        var hairShape = sceneInfo.NodeIDs["Hair1"].Shapes[0];

        hairShape.Fill = new SolidFill()
        {
            Color = hairColour
        };
        hairShape      = sceneInfo.NodeIDs["Hair2"].Shapes[0];
        hairShape.Fill = new SolidFill()
        {
            Color = skinTone
        };
        if (!citizen.gender)
        {
            switch (style)
            {
            case 0:
                hairShape      = sceneInfo.NodeIDs["PonyTail"].Shapes[0];
                hairShape.Fill = new SolidFill()
                {
                    Color = hairColour
                };
                hairShape      = sceneInfo.NodeIDs["PonyTail2"].Shapes[0];
                hairShape.Fill = new SolidFill()
                {
                    Color = hairColour
                };
                break;

            case 1:
                hairShape      = sceneInfo.NodeIDs["PonyTail"].Shapes[0];
                hairShape.Fill = new SolidFill()
                {
                    Color = hairColour
                };
                break;
            }
        }

        //var tessOptions = new VectorUtils.TessellationOptions()
        //{
        //    StepDistance = 100f,
        //    MaxCordDeviation = 0.5f,
        //    MaxTanAngleDeviation = 0.1f,
        //    SamplingStepSize = 0.01f
        //};

        //var geoms = VectorUtils.TessellateScene(hairSceneInfo.Scene, tessOptions);
        //var sprite = VectorUtils.BuildSprite(geoms, 26, VectorUtils.Alignment.Center, Vector2.zero, 128, true);
        //GameObject go = new GameObject("Hair");
        //go.transform.SetParent(transform);
        //transform.GetChild(0).gameObject.SetActive(true);
        //go.AddComponent<SpriteRenderer>();
        //go.transform.localPosition = new Vector3(0, citizen.gender ? -.25f : -.355f, 0);
        //SpriteRenderer sr = go.GetComponent<SpriteRenderer>();
        //sr.sprite = sprite;
        //sr.sortingLayerID = GetComponent<SpriteRenderer>().sortingLayerID;
        //sr.sortingOrder = GetComponent<SpriteRenderer>().sortingOrder;
    }
    void Start()
    {
        // Prepare the vector path, add it to the vector scene.
        m_Path = new Shape()
        {
            Contours = new BezierContour[] {
                new BezierContour()
                {
                    Segments = new BezierPathSegment[2]
                },
                new BezierContour()
                {
                    Segments = new BezierPathSegment[2]
                }
            },
            PathProps = new PathProperties()
            {
                Stroke = new Stroke()
                {
                    Color         = Color.white,
                    HalfThickness = 0.1f
                }
            }
        };

        m_Scene = new Scene()
        {
            Root = new SceneNode()
            {
                Shapes = new List <Shape> {
                    //m_Path
                }
            }
        };

        m_Options = new VectorUtils.TessellationOptions()
        {
            StepDistance         = 1000.0f,
            MaxCordDeviation     = 0.05f,
            MaxTanAngleDeviation = 0.05f,
            SamplingStepSize     = 0.01f
        };

        // Instantiate a new mesh, it will be filled with data in Update()
        m_Mesh = new Mesh();
        GetComponent <MeshFilter>().mesh = m_Mesh;


        // =======================================================================
        string path = string.Format(@"D:\WriteByHand\svgs\{0}.svg", 20986);
        string svg  = SVGHelper.readSVG(path);

        SVGParser.SceneInfo scene_info = SVGParser.ImportSVG(new StringReader(svg));
        Scene     scene = scene_info.Scene;
        SceneNode word  = scene.Root.Children[1];

        // 前半為背景(無 Clipper),後半為寫字筆劃(有 Clipper)
        List <SceneNode> bg_and_stroke = word.Children;
        int double_stroke_number       = bg_and_stroke.Count;
        int stroke_number = double_stroke_number / 2;

        // 筆劃第一筆
        SceneNode    test_node         = bg_and_stroke[stroke_number];
        List <Shape> test_shapes       = test_node.Shapes;
        SceneNode    test_clipper_node = (test_node.Clipper == null) ? null : test_node.Clipper;
        List <Shape> test_clippers     = new List <Shape>();

        if (test_clipper_node != null)
        {
            test_clippers = test_clipper_node.Children[0].Shapes;
            if (test_clippers != null)
            {
                print("test_clippers len:" + test_clippers.Count);
                Shape test_clipper_shape = test_clippers[0];
            }
            else
            {
                print("test_clippers is null");
            }
        }
        else
        {
            print("test_clipper_node is null");
        }

        Shape test_stroke = test_shapes[0];

        BezierContour[]     bezierContours     = test_stroke.Contours;
        BezierPathSegment[] bezierPathSegments = bezierContours[0].Segments;
        BezierPathSegment   point1             = bezierPathSegments[0];
        BezierPathSegment   point2             = bezierPathSegments[bezierPathSegments.Length - 1];

        #region Word scene
        // 遮罩嘗試
        display_scene = new Scene()
        {
            Root = new SceneNode()
            {
                Children = new List <SceneNode>()
                {
                    #region One stroke
                    new SceneNode()
                    {
                        Shapes = new List <Shape>()
                        {
                            #region Piece of stroke
                            new Shape()
                            {
                                Contours = new BezierContour[] {
                                    new BezierContour()
                                    {
                                        Segments = new BezierPathSegment[]
                                        {
                                            point1,
                                            point2
                                        }
                                    },
                                    //new BezierContour() {
                                    //    Segments = new BezierPathSegment[2]
                                    //}
                                },
                                PathProps = new PathProperties()
                                {
                                    Stroke = new Stroke()
                                    {
                                        Color         = Color.white,
                                        HalfThickness = 10f
                                    }
                                }
                            }
                            #endregion Piece of stroke end
                        },
                        Clipper = new SceneNode()
                        {
                            Shapes = new List <Shape>()
                            {
                                #region Piece of clipper
                                test_clippers[0]
                                #endregion Piece of clipper end
                            }
                        }
                    }
                    #endregion One stroke end
                }
            }
        };
        #endregion Word scene end

        StartCoroutine(nextStroke(bg_and_stroke));
    }
Exemple #12
0
    void Start()
    {
        //string svg =
        //    @"<svg width=""283.9"" height=""283.9"" xmlns=""http://www.w3.org/2000/svg"">
        //        <line x1=""170.3"" y1=""226.99"" x2=""177.38"" y2=""198.64"" fill=""none"" stroke=""#888"" stroke-width=""1""/>
        //        <line x1=""205.73"" y1=""198.64"" x2=""212.81"" y2=""226.99"" fill=""none"" stroke=""#888"" stroke-width=""1""/>
        //        <line x1=""212.81"" y1=""226.99"" x2=""219.9"" y2=""255.33"" fill=""none"" stroke=""#888"" stroke-width=""1""/>
        //        <line x1=""248.25"" y1=""255.33"" x2=""255.33"" y2=""226.99"" fill=""none"" stroke=""#888"" stroke-width=""1""/>
        //        <path d=""M170.08,226.77c7.09-28.34,35.43-28.34,42.52,0s35.43,28.35,42.52,0"" transform=""translate(0.22 0.22)"" fill=""none"" stroke=""red"" stroke-width=""1.2""/>
        //        <circle cx=""170.3"" cy=""226.99"" r=""1.2"" fill=""blue"" stroke-width=""0.6""/>
        //        <circle cx=""212.81"" cy=""226.99"" r=""1.2"" fill=""blue"" stroke-width=""0.6""/>
        //        <circle cx=""255.33"" cy=""226.99"" r=""1.2"" fill=""blue"" stroke-width=""0.6""/>
        //        <circle cx=""177.38"" cy=""198.64"" r=""1"" fill=""black"" />
        //        <circle cx=""205.73"" cy=""198.64"" r=""1"" fill=""black"" />
        //        <circle cx=""248.25"" cy=""255.33"" r=""1"" fill=""black"" />
        //        <circle cx=""219.9"" cy=""255.33"" r=""1"" fill=""black"" />
        //    </svg>";



        var tessOptions = new VectorUtils.TessellationOptions()
        {
            StepDistance         = 100.0f,
            MaxCordDeviation     = 0.5f,
            MaxTanAngleDeviation = 0.1f,
            SamplingStepSize     = 0.01f
        };

        //Pfad zur Datei
        string svgFilePath = Application.dataPath + "/Resources/testObject_layerTest-10-10.svg";

        StreamReader sr      = new StreamReader(svgFilePath);
        string       svgText = sr.ReadToEnd();

        print(svgText);
        sr.Close();
        sr.Dispose();

        var sceneInfo = SVGParser.ImportSVG(new StringReader(svgText));

        int NrOfLayers = sceneInfo.Scene.Root.Children.Count;

        m_Sprites = new Sprite[NrOfLayers];
        SVGParser.SceneInfo[]         m_SIArray = new SVGParser.SceneInfo[NrOfLayers];
        List <VectorUtils.Geometry>[] m_Geoms   = new List <VectorUtils.Geometry> [NrOfLayers];

        for (int i = 0; i < NrOfLayers; i++)
        {
            m_SIArray[i] = SVGParser.ImportSVG(new StringReader(svgText));
            int removed = 0;
            for (int c = 0; c < NrOfLayers; c++)
            {
                if (c != i)
                {
                    //print("at " + i + " removing index " + c);
                    m_SIArray[i].Scene.Root.Children.Remove(m_SIArray[i].Scene.Root.Children[c - removed]);
                    removed++;
                }
            }

            var fullBounds  = VectorUtils.SceneNodeBounds(sceneInfo.Scene.Root);
            var localBounds = VectorUtils.SceneNodeBounds(sceneInfo.Scene.Root.Children[i]);
            var pivot       = localBounds.position - fullBounds.position;

            var localSceneBounds = VectorUtils.SceneNodeBounds(m_SIArray[i].Scene.Root);

            Vector2 position = new Vector2(fullBounds.position.x, fullBounds.position.y);
            // position = new Vector2(fullBounds.center.x / fullBounds.width - (localBounds.position.x) / fullBounds.width, fullBounds.center.y / fullBounds.height - localBounds.position.y / fullBounds.height);
            //position = new Vector2((fullBounds.center.x - localBounds.position.x )/ fullBounds.width, 0);
            //position = new Vector2((fullBounds.position.x-localBounds.position.x-pivot.x) / fullBounds.width , 0);
            position = new Vector2(0, 0);

            print("FullBounds: " + fullBounds + " localBounds:" + localBounds);// + " localSceneBounds:"+ localSceneBounds);
            //print(i + ": " + position+" / pivot: "+pivot);

            //print(position.x * fullBounds.width + " , " + position.y * fullBounds.height);

            m_Geoms[i]   = VectorUtils.TessellateScene(m_SIArray[i].Scene, tessOptions);
            m_Sprites[i] = VectorUtils.BuildSprite(m_Geoms[i], 1000.0f, VectorUtils.Alignment.TopLeft, position, 128, true);

            GameObject     go = new GameObject();
            SpriteRenderer s  = go.AddComponent <SpriteRenderer>();
            go.transform.parent = transform;
            // go.transform.position = new Vector3((localSceneBounds.x - fullBounds.width/2f)/1000f, (fullBounds.y + fullBounds.height/2f - localSceneBounds.y) /1000f , 0);
            go.transform.position = new Vector3((localBounds.x) / 1000f, (fullBounds.y - localBounds.y) / 1000f, 0);
            s.sprite = m_Sprites[i];

            //var test = typeof(VectorUtils.TessellateScene);
            //var methods = test.GetMethods();

            //// test code: generate better shape
            //bool m_BetterGeneratePhysicsShape = true;
            //if (m_BetterGeneratePhysicsShape)
            //{
            //    var test = typeof(VectorUtils);
            //    var methods = test.GetMethods();
            //    foreach (MethodInfo mf in methods)
            //    {
            //        Debug.Log(mf.Name);
            //    }

            //    var physicsShapes = VectorUtils.TraceNodeHierarchyShapes(sceneInfo.Scene.Root, tessOptions);

            //    var rect = sceneInfo.SceneViewport;

            //    foreach (var vertices in physicsShapes)
            //    {
            //        if (rect == Rect.zero)
            //        {
            //            rect = VectorUtils.Bounds(vertices);
            //            VectorUtils.RealignVerticesInBounds(vertices, rect, flip: true);
            //        }
            //        else
            //        {
            //            VectorUtils.FlipVerticesInBounds(vertices, rect);
            //            VectorUtils.ClampVerticesInBounds(vertices, rect);
            //        }
            //    }

            //    m_Sprites[i].OverridePhysicsShape(physicsShapes);
            //}
            //// test code end

            go.AddComponent <PolygonCollider2D>();

            //PrefabUtility.SaveAsPrefabAsset(go, svgFilePath.Replace(".svg", "_2" + i.ToString() + ".prefab"));
        }



        //AssetImportContext ctx;

        //ctx.AddObjectToAsset();

        //var geoms = VectorUtils.TessellateScene(sceneInfo.Scene, tessOptions);

        //// Build a sprite with the tessellated geometry.
        //var sprite = VectorUtils.BuildSprite(geoms, 1000.0f, VectorUtils.Alignment.TopLeft, Vector2.zero, 128, true);
        //GetComponent<SpriteRenderer>().sprite = sprite;

        //GenerateSpriteAsset(ctx, sprite, name);
    }
    /// <summary>
    /// Create a Texture2D icon of a SVG image (editor only version).
    /// </summary>
    /// <param name="svg">String containing svg content.</param>
    /// <param name="renderUtil">PreviewRenderUtility to use for drawing</param>
    /// <remarks>
    /// Standard header and footer will be included if not found in svgContent
    /// </remarks>
    public static Texture2D GetIcon(string svgContent, PreviewRenderUtility renderUtil)
    {
        string svg;

        if (svgContent.StartsWith("<?xml version = \"1.0\" encoding=\"UTF - 8\"?>"))
        {
            svg = svgContent;
        }
        else
        {
            svg = svgIconHeader + svgContent;
        }

        if (!svg.EndsWith(svgIconFooter))
        {
            svg = svg + svgIconFooter;
        }

        // Parse the SVG
        SVGParser.SceneInfo sceneInfo = SVGParser.ImportSVG(new System.IO.StringReader(svg));
        int width  = Mathf.CeilToInt(sceneInfo.SceneViewport.width);
        int height = Mathf.CeilToInt(sceneInfo.SceneViewport.height);

        if ((width > 64) || (height > 64))
        {
            Debug.LogWarning("SVG icon of unusual size!");
        }

        // Save the render state and get a temporary render texture
        RenderTexture activeTexture = RenderTexture.active;

        renderUtil.camera.targetTexture   = RenderTexture.GetTemporary(width * 2, height * 2, 8, RenderTextureFormat.ARGB32);
        renderUtil.camera.backgroundColor = Color.clear;

        // Generate the mesh
        Mesh iconMesh = new Mesh();
        List <VectorUtils.Geometry> iconGeometry = VectorUtils.TessellateScene(sceneInfo.Scene, tessellationOptions);

        VectorUtils.FillMesh(iconMesh, iconGeometry, 1f);

        // Activate the render texture and draw the mesh into it
        RenderTexture.active = renderUtil.camera.targetTexture;
        float   cameraSize     = renderUtil.camera.orthographicSize;
        Vector3 cameraPosition = renderUtil.camera.transform.position;

        renderUtil.camera.orthographicSize   = sceneInfo.SceneViewport.height / 2;
        renderUtil.camera.transform.position = new Vector3(sceneInfo.SceneViewport.center.x, sceneInfo.SceneViewport.center.y, -1);
        // HACK until FillMesh() flpYAxis is fixed
        renderUtil.camera.transform.Rotate(0, 0, 180f);
        renderUtil.DrawMesh(iconMesh, Matrix4x4.identity, renderMaterial, 0);
        renderUtil.camera.Render();
        renderUtil.camera.transform.Rotate(0, 0, 180f);
        renderUtil.camera.orthographicSize   = cameraSize;
        renderUtil.camera.transform.position = cameraPosition;
        Texture2D iconTexture = new Texture2D(width * 2, height * 2);

        iconTexture.ReadPixels(new Rect(0, 0, width * 2, height * 2), 0, 0);
        iconTexture.Apply();

        // Restore the render state and release the temporary objects
        RenderTexture.active = activeTexture;
        RenderTexture.ReleaseTemporary(renderUtil.camera.targetTexture);
        UnityEngine.Object.DestroyImmediate(iconMesh);

        return(iconTexture);
    }
Exemple #14
0
    // Start is called before the first frame update
    void Start()
    {
        string path = string.Format(@"D:\WriteByHand\svgs\{0}.svg", 20986);
        string svg  = SVGHelper.readSVG(path);

        SVGParser.SceneInfo scene_info = SVGParser.ImportSVG(new StringReader(svg));
        scene = scene_info.Scene;

        // svg 本體
        SceneNode        node   = scene.Root;
        List <SceneNode> layer1 = node.Children;

        // node0:背景米字;node1:字的筆劃
        SceneNode node0 = layer1[0], node1 = layer1[1];

        // 背景米字
        //List<SceneNode> layer2 = node0.Children;
        //print("layer2:" + layer2.Count);

        // 字的筆劃
        List <SceneNode> layer3 = node1.Children;

        //print("layer3:" + layer3.Count);
        //int n = 0;
        //foreach (SceneNode scene_node in layer3)
        //{
        //    print(string.Format("=== Node {0} ===", ++n));
        //    List<Shape> shapes = scene_node.Shapes; // length = 1
        //    Shape shape = shapes[0]; // length = 1
        //    BezierContour[] contours = shape.Contours; // length = 1
        //    BezierPathSegment[] segments = contours[0].Segments; // 每一筆劃的區段數量不同
        //    int num = 0;
        //    foreach(BezierPathSegment bezierPathSegment in segments)
        //    {
        //        print(string.Format("= segment {0} =", ++num));
        //        print(bezierPathSegment.P0);
        //        print(bezierPathSegment.P1);
        //        print(bezierPathSegment.P2);
        //        break;
        //    }

        //    SceneNode clipper = (scene_node.Clipper == null) ? null : scene_node.Clipper;
        //    if(clipper != null)
        //    {
        //        List<SceneNode> clippers = clipper.Children; // length = 1
        //        SceneNode mask = clippers[0];
        //        List<Shape> m_shapes = mask.Shapes; // length = 1
        //        Shape m_shape = m_shapes[0];
        //        BezierContour[] m_contours = m_shape.Contours; // length = 1
        //        //print("m_contours len:" + m_contours.Length);
        //        BezierPathSegment[] m_segments = m_contours[0].Segments; // 每一筆劃的區段數量不同
        //        //print("m_segments len:" + m_segments.Length);
        //        int number = 0;
        //        foreach (BezierPathSegment m_bezierPathSegment in m_segments)
        //        {
        //            print(string.Format("= clipper segment {0} =", ++number));
        //            print(m_bezierPathSegment.P0);
        //            print(m_bezierPathSegment.P1);
        //            print(m_bezierPathSegment.P2);
        //            break;
        //        }
        //    }
        //    else
        //    {
        //        print("clipper is null");
        //    }
        //}

        n_scene = new Scene()
        {
            Root = new SceneNode()
            {
                // node.Children  正常的字
                // node1.Children  上下相反的字
                //Children = node.Children
                Children = new List <SceneNode>()
                {
                    new SceneNode()
                    {
                        Children = node1.Children
                    }
                }
            }
        };


        //foreach (SceneNode sceneNode in layer3)
        //{
        //    n_scene.Root.Children.Add(sceneNode);
        //}

        sceneDisplay(n_scene, render);

        //StartCoroutine(nextStroke(layer3));
    }
Exemple #15
0
        /// <summary>
        /// Imports a vector texture
        /// </summary>
        /// <param name="file">The file to import from</param>
        /// <param name="size">The size of the texture</param>
        /// <param name="type"></param>
        /// <returns>The vector texture imported as a Sprite</returns>
        public static Sprite ImportVector(FileInfo file, int size, SpriteImportType type)
        {
            StreamReader reader = null;
            StringReader sr     = null;

            try
            {
                reader = new StreamReader(file.OpenRead());
                sr     = new StringReader(reader.ReadToEnd());
                SVGParser.SceneInfo scene = SVGParser.ImportSVG(sr);

                VectorUtils.TessellationOptions tessOptions = new VectorUtils.TessellationOptions()
                {
                    StepDistance         = 100.0f,
                    MaxCordDeviation     = 0.5f,
                    MaxTanAngleDeviation = 0.1f,
                    SamplingStepSize     = 0.01f
                };

                List <VectorUtils.Geometry> geoms = VectorUtils.TessellateScene(scene.Scene, tessOptions);
                Sprite tempSprite = VectorUtils.BuildSprite(geoms, size, VectorUtils.Alignment.Center, Vector2.zero, 64, false);

                Shader shader = null;
                switch (type)
                {
                case SpriteImportType.svggradient:
                    shader = Shader.Find("Unlit/VectorGradient");
                    break;

                case SpriteImportType.svg:
                default:
                    shader = Shader.Find("Unlit/Vector");
                    break;
                }

                Texture2D tex = VectorUtils.RenderSpriteToTexture2D(tempSprite, size, size, new Material(shader));
                //tex.alphaIsTransparency = true;
                Sprite sprite = Sprite.Create(tex, new Rect(Vector2.zero, new Vector2(tex.width, tex.height)), new Vector2(0.5f, 0.5f), size * 2);

                return(sprite);
            }

            catch (Exception e)
            {
                MonoBehaviour.print(e.Message + "\nFile: " + file.Name + "\n" + e.StackTrace);
            }

            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
                if (sr != null)
                {
                    sr.Close();
                }
            }

            return(null);
        }