Esempio n. 1
0
 public static Vector2 [][] Trace(Sprite sprite, Rect pixelRect)
 {
     return(Trace(
                sprite.texture,
                pixelRect,
                RasterHelper.GetPivot(sprite),
                RasterHelper.GetPixelsPerUnit(sprite)
                ));
 }
Esempio n. 2
0
    public static Vector2 [][] Trace(Sprite sprite)
    {
        var texture   = sprite.texture;
        var pixelRect = new Rect(0, 0, texture.width, texture.height);

        return(Trace(
                   sprite.texture,
                   pixelRect,
                   RasterHelper.GetPivot(sprite),
                   RasterHelper.GetPixelsPerUnit(sprite)
                   ));
    }
Esempio n. 3
0
    public static void CloneTextureAndSprite(SpriteRenderer spriteRenderer)
    {
        var sprite   = spriteRenderer.sprite;
        var texClone = Object.Instantiate(sprite.texture) as Texture2D;

        spriteRenderer.sprite = Sprite.Create(
            texClone,
            sprite.rect,
            RasterHelper.GetPivot(sprite),
            RasterHelper.GetPixelsPerUnit(sprite)
            );
        spriteRenderer.sprite.name = sprite.name + "(Clone)";
    }
    private void PerformTrace()
    {
        var spriteRenderer = GetComponent <SpriteRenderer> ();
        var sprite         = spriteRenderer.sprite;

        var ms = new MarchingSquares(
            sprite.texture,
            alphaThreshold: AlphaThreshold,
            clockWise: ClockWise,
            mipLevel: MipLevel
            );

        polyPath = ms.TraceContours();
        float pixelsPerUnit = RasterHelper.GetPixelsPerUnit(sprite);
        float scale         = (1 << MipLevel) / pixelsPerUnit;
        var   pivot         = RasterHelper.GetPivot(sprite);
        var   offset        = -Vector2.Scale(sprite.bounds.size, pivot);

        polyPath.Scale(scale);
        polyPath.Translate(offset);

        int   pointCountBeforeOpt = polyPath.TotalPointCount;
        float worldScale          = Common.WorldScale(spriteRenderer.transform);

        if (ReduceByMinDistance)
        {
            polyPath.ReduceByMinDistance(MinDistance, MinVertexCount);
        }

        if (ReduceByMinTriangleArea)
        {
            float globalScaleSq = worldScale * worldScale;

            polyPath.ReduceByMinTriangleArea(MinTriangleArea / globalScaleSq, MinVertexCount);
        }

        if (ReduceCodirected)
        {
            polyPath.ReduceCodirected(MinAngle * Mathf.Deg2Rad, MinVertexCount);
        }

        int pointCountAfterOpt = polyPath.TotalPointCount;

        print(string.Format(
                  "Reduction: {0}/{1} ({2:P})",
                  pointCountAfterOpt, pointCountBeforeOpt, 1.0f - ( float )pointCountAfterOpt / pointCountBeforeOpt
                  ));
    }
Esempio n. 5
0
    // TODO: make it FillCircle ()
    public static bool CutCircle(SpriteRenderer spriteRenderer, Vector2 center, float radius)
    {
        var tf = spriteRenderer.transform;

        center = tf.InverseTransformPoint(center);
        var localScaleVector  = tf.InverseTransformPoint(tf.position + Vector3.right);
        var worldToLocalScale = localScaleVector.magnitude;

        radius *= worldToLocalScale;

        var sprite = spriteRenderer.sprite;
        int pixelX, pixelY;

        RasterHelper.SpriteCoordsToPixelCoords(sprite, center, out pixelX, out pixelY);
        float pixelsPerUnit = RasterHelper.GetPixelsPerUnit(sprite);
        int   pixelRadius   = Mathf.RoundToInt(radius * pixelsPerUnit);

        return(RasterHelper.CutCircle(sprite.texture, pixelX, pixelY, pixelRadius));
    }
Esempio n. 6
0
    private PolygonPath BuildPolyPath(SpriteRenderer spriteRenderer)
    {
        var sprite = spriteRenderer.sprite;

        float buildPathStartTime = Time.realtimeSinceStartup;
        float msStartTime        = Time.realtimeSinceStartup;
        var   ms = new MarchingSquares(
            sprite.texture,
            alphaThreshold: AlphaThreshold,
            clockWise: ClockWise,
            mipLevel: MipLevel
            );
        float msTimeElapsed = Time.realtimeSinceStartup - msStartTime;

        float traceStartTime   = Time.realtimeSinceStartup;
        var   polyPath         = ms.TraceContours();
        float traceTimeElapsed = Time.realtimeSinceStartup - traceStartTime;

        float pixelsPerUnit = RasterHelper.GetPixelsPerUnit(sprite);
        float scale         = (1 << MipLevel) / pixelsPerUnit;
        var   pivot         = RasterHelper.GetPivot(sprite);
        var   offset        = -Vector2.Scale(sprite.bounds.size, pivot);

        float transformStartTime = Time.realtimeSinceStartup;

        polyPath.Scale(scale);
        polyPath.Translate(offset);
        float transformTimeElapsed = Time.realtimeSinceStartup - transformStartTime;

#if MUTABLE_COLLIDER_STATS
        float buildPathTimeElapsed = Time.realtimeSinceStartup - buildPathStartTime;

        print(string.Format(
                  "Build path timing -- Trace: {0}, Transform: {1}, Get pixels: {2}, Total: {3}",
                  traceTimeElapsed, transformTimeElapsed, msTimeElapsed, buildPathTimeElapsed
                  ));
#endif

        return(polyPath);
    }
Esempio n. 7
0
    void Start()
    {
        var spriteRenderer = GetComponent <SpriteRenderer> ();

        spriteRenderer.enabled = false;

        var initialPolyCollider = GetComponent <PolygonCollider2D> ();

        if (initialPolyCollider != null)
        {
            Destroy(initialPolyCollider);
        }

        // TODO: i don't remember why we clone texture here. Is this really needed?
        if (CloneTexture)
        {
            RasterHelper.CloneTextureAndSprite(spriteRenderer);
        }

        var initialSprite = spriteRenderer.sprite;

        spriteRenderer.sprite = null;           // Prevent newly added polygon colliders from autotrace.
        var   initialTexture = initialSprite.texture;
        float pixelsPerUnit  = RasterHelper.GetPixelsPerUnit(initialSprite);

        /* TODO: unite small cells on the border with those which are inside.
         * UPD: no, don't unite. Make border cell and adjacent cell even sized,
         * thus guarantees that size of any cell is smaller than CellSize. */

        for (int y = 0; y < initialTexture.height; y += CellSize)
        {
            int cellHeight = Mathf.Min(initialTexture.height - y, CellSize);

            for (int x = 0; x < initialTexture.width; x += CellSize)
            {
                int cellWidth   = Mathf.Min(initialTexture.width - x, CellSize);
                var pixels      = initialTexture.GetPixels(x, y, cellWidth, cellHeight);
                var cellTexture = new Texture2D(cellWidth, cellHeight);
                cellTexture.name = string.Format(
                    "{0} [y: {1}, x: {2}]",
                    initialTexture.name, y, x
                    );
                cellTexture.filterMode = FilterMode.Trilinear;
                cellTexture.wrapMode   = TextureWrapMode.Clamp;
                cellTexture.SetPixels(pixels);
                cellTexture.Apply();

                var pixelRect = new Rect(x, y, cellWidth, cellHeight);
                var cellPivot = RasterHelper.CalculateRelativePivot(initialSprite, pixelRect);

                var cellSprite = Sprite.Create(
                    cellTexture,
                    new Rect(0, 0, cellWidth, cellHeight),
                    cellPivot,
                    pixelsPerUnit
                    );

                cellSprite.name = string.Format(
                    "{0} [y: {1}, x: {2}]",
                    initialSprite.name, y, x
                    );

                var cellGameObject = new GameObject(
                    string.Format(
                        "{0} [y: {1}, x: {2}]",
                        name, y, x
                        )
                    );
                var cellSpriteRenderer = cellGameObject.AddComponent <SpriteRenderer> ();
                cellSpriteRenderer.sprite         = cellSprite;
                cellSpriteRenderer.sortingLayerID = spriteRenderer.sortingLayerID;
                cellSpriteRenderer.sortingOrder   = spriteRenderer.sortingOrder;

                var cellTf = cellGameObject.transform;
                cellTf.parent        = this.transform;
                cellTf.localPosition = Vector3.zero;
                cellTf.localRotation = Quaternion.identity;
                cellTf.localScale    = Vector3.one;

                if (UsePolyCollider)
                {
                    var cellPolyCollider = gameObject.AddComponent <PolygonCollider2D> ();
                    cellPolyCollider.pathCount           = 0;
                    colliderSpriteMap [cellPolyCollider] = cellSpriteRenderer;
                }

                UpdateSpriteColliders(cellSpriteRenderer);
            }
        }

        spriteRenderer.sprite = initialSprite;
    }