public void Transform(DestroyableRect newRect, int width, int height, byte[] data)
        {
            Clear();
            Prepare(newRect, false);

            for (var y = newRect.MinY; y < newRect.MaxY; y++)
            {
                for (var x = newRect.MinX; x < newRect.MaxX; x++)
                {
                    var alpha = data[x + y * width];
                    var index = x - newRect.MinX + (y - newRect.MinY) * newRect.SizeX;

                    if (alpha > 127)
                    {
                        Cells[index] = new Cell(0, 0, 0);
                    }
                    else
                    {
                        Cells[index] = new Cell(10000, 10000, 10000 * 10000);
                    }
                }
            }

            Transform();
        }
Пример #2
0
        public static DestroyableRect CalculateCombined(DestroyableRect a, DestroyableRect b)
        {
            a.MinX = Mathf.Min(a.MinX, b.MinX);
            a.MaxX = Mathf.Max(a.MaxX, b.MaxX);
            a.MinY = Mathf.Min(a.MinY, b.MinY);
            a.MaxY = Mathf.Max(a.MaxY, b.MaxY);

            return(a);
        }
Пример #3
0
        public static DestroyableRect CalculateOverlap(DestroyableRect a, DestroyableRect b)
        {
            a.MinX = Mathf.Clamp(a.MinX, b.MinX, b.MaxX);
            a.MaxX = Mathf.Clamp(a.MaxX, b.MinX, b.MaxX);
            a.MinY = Mathf.Clamp(a.MinY, b.MinY, b.MaxY);
            a.MaxY = Mathf.Clamp(a.MaxY, b.MinY, b.MaxY);

            return(a);
        }
        protected override void OnAlphaDataModified(DestroyableRect rect)
        {
            base.OnAlphaDataModified(rect);

            if (CellSize <= 0)
            {
                Mark(); Sweep(); return;
            }

            if (destructible.AlphaWidth != expectedWidth || destructible.AlphaHeight != expectedHeight || cells == null || cells.Length != cellWidth * cellHeight || CellSize != expectedCellSize)
            {
                Rebuild(); return;
            }

            var cellXMin = rect.MinX / CellSize;
            var cellYMin = rect.MinY / CellSize;
            var cellXMax = (rect.MaxX + 1) / CellSize;
            var cellYMax = (rect.MaxY + 1) / CellSize;

            cellXMin = Mathf.Clamp(cellXMin, 0, cellWidth - 1);
            cellXMax = Mathf.Clamp(cellXMax, 0, cellWidth - 1);
            cellYMin = Mathf.Clamp(cellYMin, 0, cellHeight - 1);
            cellYMax = Mathf.Clamp(cellYMax, 0, cellHeight - 1);

            for (var cellY = cellYMin; cellY <= cellYMax; cellY++)
            {
                var offset = cellY * cellWidth;

                for (var cellX = cellXMin; cellX <= cellXMax; cellX++)
                {
                    var index = cellX + offset;
                    var cell  = cells[index];

                    if (cell != null)
                    {
                        cell.Clear(tempColliders);

                        cells[index] = DestroyablePolygonColliderCell.Add(cell);
                    }

                    RebuildCell(ref cells[index], cellX, cellY);
                }
            }

            Sweep();
        }
        public void Transform(DestroyableRect newRect, DestroyableLogFloodfill.Island island)
        {
            Clear();
            Prepare(newRect, true);

            for (var i = island.Lines.Count - 1; i >= 0; i--)
            {
                var line = island.Lines[i];

                for (var x = line.MinX; x < line.MaxX; x++)
                {
                    Cells[x - newRect.MinX + (line.Y - newRect.MinY) * newRect.SizeX] = new Cell(0, 0, 0);
                }
            }

            Transform();
        }
        public void Prepare(DestroyableRect newRect, bool fill)
        {
            var s = newRect.Area;

            Rect = newRect;

            if (Cells == null || Cells.Length < s)
            {
                Cells = new Cell[s];
            }

            if (fill == true)
            {
                for (var i = 0; i < s; i++)
                {
                    Cells[i] = new Cell(10000, 10000, 10000 * 10000);
                }
            }
        }
Пример #7
0
        private static void CalculateLayout(DestroyableRect rect, int alphaWidth, int alphaHeight)
        {
            if (rect.MinX == 0 && rect.MaxX == alphaWidth && rect.MinY == 0 && rect.MaxY == alphaHeight)
            {
                IslandLayout = Layout.Whole; return;
            }

            if (rect.MinX == 0 && rect.MaxX == alphaWidth && rect.MinY > 0 && rect.MaxY < alphaHeight)
            {
                IslandLayout = Layout.Vertical; return;
            }

            if (rect.MinY == 0 && rect.MaxY == alphaHeight && rect.MinX > 0 && rect.MaxX < alphaWidth)
            {
                IslandLayout = Layout.Horizontal; return;
            }

            IslandLayout = Layout.Island;
        }
Пример #8
0
 public void ClampTo(DestroyableRect other)
 {
     if (MinX < other.MinX)
     {
         MinX = other.MinX;
     }
     if (MaxX > other.MaxX)
     {
         MaxX = other.MaxX;
     }
     if (MinY < other.MinY)
     {
         MinY = other.MinY;
     }
     if (MaxY > other.MaxY)
     {
         MaxY = other.MaxY;
     }
 }
Пример #9
0
        public static bool CalculateRect(Matrix4x4 matrix, ref DestroyableRect rect, int sizeX, int sizeY)
        {
            var a = matrix.MultiplyPoint(new Vector3(0.0f, 0.0f, 0.0f));
            var b = matrix.MultiplyPoint(new Vector3(1.0f, 0.0f, 0.0f));
            var c = matrix.MultiplyPoint(new Vector3(0.0f, 1.0f, 0.0f));
            var d = matrix.MultiplyPoint(new Vector3(1.0f, 1.0f, 0.0f));

            var minX = Mathf.Min(Mathf.Min(a.x, b.x), Mathf.Min(c.x, d.x));
            var maxX = Mathf.Max(Mathf.Max(a.x, b.x), Mathf.Max(c.x, d.x));
            var minY = Mathf.Min(Mathf.Min(a.y, b.y), Mathf.Min(c.y, d.y));
            var maxY = Mathf.Max(Mathf.Max(a.y, b.y), Mathf.Max(c.y, d.y));

            if (minX < maxX && minY < maxY)
            {
                rect.MinX = Mathf.FloorToInt(minX * sizeX);
                rect.MaxX = Mathf.CeilToInt(maxX * sizeX);
                rect.MinY = Mathf.FloorToInt(minY * sizeY);
                rect.MaxY = Mathf.CeilToInt(maxY * sizeY);

                return(true);
            }

            return(false);
        }
Пример #10
0
 public static bool AlphaIsValid(byte[] data, DestroyableRect rect)
 {
     return(data != null && rect.IsSet == true && data.Length >= rect.Area);
 }
        protected override void OnAlphaDataSubset(DestroyableRect rect)
        {
            base.OnAlphaDataSubset(rect);

            Rebuild();
        }
Пример #12
0
 public void Add(DestroyableRect rect)
 {
     Add(rect.MinX, rect.MaxX, rect.MinY, rect.MaxY);
 }
Пример #13
0
        private static void SortIslands(DestroyableRect rect, float alphaWidth, float alphaHeight)
        {
            switch (IslandLayout)
            {
            case Layout.Whole:
            {
                IslandsA.AddRange(tempIslands);
            }
            break;

            case Layout.Island:
            {
                if (rect.MinX == 0)
                {
                    rect.MinX -= 1;
                }
                if (rect.MinY == 0)
                {
                    rect.MinY -= 1;
                }
                if (rect.MaxX == alphaWidth)
                {
                    rect.MaxX += 1;
                }
                if (rect.MaxY == alphaHeight)
                {
                    rect.MaxY += 1;
                }

                for (var i = tempIslands.Count - 1; i >= 0; i--)
                {
                    var island = tempIslands[i];

                    if (island.MinX > rect.MinX && island.MinY > rect.MinY && island.MaxX < rect.MaxX && island.MaxY < rect.MaxY)
                    {
                        IslandsA.Add(island);
                    }
                    else
                    {
                        IslandsB.Add(island);
                    }
                }
            }
            break;

            case Layout.Horizontal:
            {
                for (var i = tempIslands.Count - 1; i >= 0; i--)
                {
                    var island = tempIslands[i];

                    if (island.MinX <= rect.MinX)
                    {
                        IslandsB.Add(island);
                    }
                    else if (island.MinX <= rect.MinX)
                    {
                        IslandsC.Add(island);
                    }
                    else
                    {
                        IslandsA.Add(island);
                    }
                }
            }
            break;

            case Layout.Vertical:
            {
                for (var i = tempIslands.Count - 1; i >= 0; i--)
                {
                    var island = tempIslands[i];

                    if (island.MinY <= rect.MinY)
                    {
                        IslandsB.Add(island);
                    }
                    else if (island.MinY <= rect.MinY)
                    {
                        IslandsC.Add(island);
                    }
                    else
                    {
                        IslandsA.Add(island);
                    }
                }
            }
            break;
            }

            tempIslands.Clear();
        }
Пример #14
0
 protected virtual void OnAlphaDataSubset(DestroyableRect rect)
 {
     UpdateBeforeBuild();
 }
Пример #15
0
 protected virtual void OnAlphaDataModified(DestroyableRect rect)
 {
     UpdateBeforeBuild();
 }
Пример #16
0
            public void Submit(DestroyableDistanceField baseField, DestroyableSplitGroup splitGroup, DestroyableRect baseRect, DestroyableRect rect)
            {
                distanceField.Transform(rect, this);

                for (var y = rect.MinY; y < rect.MaxY; y++)
                {
                    for (var x = rect.MinX; x < rect.MaxX; x++)
                    {
                        var cell     = distanceField.Cells[x - rect.MinX + (y - rect.MinY) * rect.SizeX];
                        var baseCell = baseField.Cells[x - baseRect.MinX + (y - baseRect.MinY) * baseRect.SizeX];

                        if (cell.D == baseCell.D)
                        {
                            splitGroup.AddPixel(x, y);
                        }
                    }
                }
            }
Пример #17
0
        public static void FastFind(byte[] alphaData, int alphaWidth, int alphaHeight, DestroyableRect rect)
        {
            Clear();

            if (rect.MinX < 0)
            {
                rect.MinX = 0;
            }
            if (rect.MinY < 0)
            {
                rect.MinY = 0;
            }
            if (rect.MaxX > alphaWidth)
            {
                rect.MaxX = alphaWidth;
            }
            if (rect.MaxY > alphaHeight)
            {
                rect.MaxY = alphaHeight;
            }

            lineCount = 0;

            CalculateLayout(rect, alphaWidth, alphaHeight);

            var oldCount = 0;

            for (var y = rect.MinY; y < rect.MaxY; y++)
            {
                var newCount = FastFindLines(alphaData, alphaWidth, y, rect.MinX, rect.MaxX);

                FastLinkLines(lineCount - newCount - oldCount, lineCount - newCount, lineCount);

                oldCount = newCount;
            }

            for (var i = 0; i < lineCount; i++)
            {
                var line = lines[i];

                if (line.Used == false)
                {
                    var island = DestroyablePool <Island> .Spawn() ?? new Island();

                    island.MinX  = line.MinX;
                    island.MaxX  = line.MaxX;
                    island.MinY  = line.Y;
                    island.MaxY  = line.Y + 1;
                    island.Count = 0;

                    // Scan though all connected lines and add to list
                    linkedLines.Clear(); linkedLines.Add(line); line.Used = true;

                    for (var j = 0; j < linkedLines.Count; j++)
                    {
                        var linkedLine = linkedLines[j];

                        island.MinX   = Mathf.Min(island.MinX, linkedLine.MinX);
                        island.MaxX   = Mathf.Max(island.MaxX, linkedLine.MaxX);
                        island.MinY   = Mathf.Min(island.MinY, linkedLine.Y);
                        island.MaxY   = Mathf.Max(island.MaxY, linkedLine.Y + 1);
                        island.Count += linkedLine.MaxX - linkedLine.MinX;

                        AddToScan(linkedLine.Ups);
                        AddToScan(linkedLine.Dns);

                        linkedLine.Island = island;

                        island.Lines.Add(linkedLine);
                    }

                    // Bridge layout?
                    switch (IslandLayout)
                    {
                    case Layout.Vertical:
                        if (island.MinY <= rect.MinY && island.MaxY >= rect.MaxY)
                        {
                            IslandLayout = Layout.Island;
                        }
                        break;

                    case Layout.Horizontal:
                        if (island.MinX <= rect.MinX && island.MaxX >= rect.MaxX)
                        {
                            IslandLayout = Layout.Island;
                        }
                        break;
                    }

                    tempIslands.Add(island);
                }
            }

            SortIslands(rect, alphaWidth, alphaHeight);
        }