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(); }
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); }
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); } } }
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; }
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; } }
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); }
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(); }
public void Add(DestroyableRect rect) { Add(rect.MinX, rect.MaxX, rect.MinY, rect.MaxY); }
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(); }
protected virtual void OnAlphaDataSubset(DestroyableRect rect) { UpdateBeforeBuild(); }
protected virtual void OnAlphaDataModified(DestroyableRect rect) { UpdateBeforeBuild(); }
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); } } } }
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); }