public static Vector2 [][] Trace(Sprite sprite, Rect pixelRect) { return(Trace( sprite.texture, pixelRect, RasterHelper.GetPivot(sprite), RasterHelper.GetPixelsPerUnit(sprite) )); }
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) )); }
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 )); }
// 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)); }
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); }
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; }