public static bool GetRectAndInvertMatrix(ref Matrix4x4 matrix, ref D2dRect rect, int sizeX, int sizeY) { // Grab transformed corners 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)); // Find min/max x/y 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)); // Has volume? if (minX < maxX && minY < maxY) { // Make sure rect doesn't go outside canvas rect.MinX = Mathf.Clamp(Mathf.FloorToInt(minX * sizeX), 0, sizeX); rect.MaxX = Mathf.Clamp(Mathf.CeilToInt(maxX * sizeX), 0, sizeX); rect.MinY = Mathf.Clamp(Mathf.FloorToInt(minY * sizeY), 0, sizeY); rect.MaxY = Mathf.Clamp(Mathf.CeilToInt(maxY * sizeY), 0, sizeY); matrix = matrix.inverse; return(true); } return(false); }
public void Transform(D2dRect 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 bool CalculateRect(Matrix4x4 matrix, ref D2dRect rect, int sizeX, int sizeY) { // Grab transformed corners 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)); // Find min/max x/y 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)); // Has volume? 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 D2dRect CalculateOverlap(D2dRect a, D2dRect b) { b.MinX = Mathf.Clamp(b.MinX, a.MinX, a.MaxX); b.MaxX = Mathf.Clamp(b.MaxX, a.MinX, a.MaxX); b.MinY = Mathf.Clamp(b.MinY, a.MinY, a.MaxY); b.MaxY = Mathf.Clamp(b.MaxY, a.MinY, a.MaxY); return(b); }
public static D2dRect CalculateCombined(D2dRect a, D2dRect 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); }
private void NotifyModified(D2dRect rect) { AlphaModified.Clear(); if (OnModified != null) { OnModified(rect); } }
public static D2dRect CalculateOverlap(D2dRect a, D2dRect 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); }
public static D2dRect CalculateCombined(D2dRect a, D2dRect b) { b.MinX = Mathf.Min(b.MinX, a.MinX, a.MaxX); b.MaxX = Mathf.Max(b.MaxX, a.MinX, a.MaxX); b.MinY = Mathf.Min(b.MinX, a.MinY, a.MaxY); b.MaxY = Mathf.Max(b.MaxX, a.MinY, a.MaxY); return(b); }
protected override void OnAlphaDataModified(D2dRect rect) { base.OnAlphaDataModified(rect); if (CellSize > 0) { var cellXMin = rect.MinX / CellSize; var cellYMin = rect.MinY / CellSize; var cellXMax = (rect.MaxX + 1) / CellSize; var cellYMax = (rect.MaxY + 1) / CellSize; // Mark for (var cellY = cellYMin; cellY <= cellYMax; cellY++) { var offset = cellY * width; for (var cellX = cellXMin; cellX <= cellXMax; cellX++) { var index = cellX + offset; if (index >= 0 && index < cells.Count) { Mark(cells[index]); } else { Regenerate(); } } } // Generate for (var cellY = cellYMin; cellY <= cellYMax; cellY++) { var offset = cellY * width; for (var cellX = cellXMin; cellX <= cellXMax; cellX++) { var index = cellX + offset; if (index >= 0 && index < cells.Count) { RebuildCell(cells[index], cellX, cellY); } } } Sweep(); } else { Rebuild(); } }
public static void TrySplit(D2dDestructible destructible, int feather) { if (destructible != null) { Search(destructible); if (islands.Count > 1) { var baseRect = new D2dRect(0, alphaWidth, 0, alphaHeight); if (feather > 0) { baseField.Transform(baseRect, alphaWidth, alphaHeight, alphaData); destructible.SplitBegin(); for (var i = islands.Count - 1; i >= 0; i--) { var island = islands[i]; var sprite = destructible.SplitNext(i == 0); var rect = new D2dRect(island.MinX, island.MaxX, island.MinY, island.MaxY); rect.Expand(feather); rect.ClampTo(baseRect); D2dHelper.ReserveTempAlphaDataClear(rect.SizeX, rect.SizeY); island.Fill(baseField, baseRect, rect); sprite.SubsetAlphaWith(D2dHelper.tempAlphaData, rect, island.Count); } } else { destructible.SplitBegin(); for (var i = islands.Count - 1; i >= 0; i--) { var island = islands[i]; var chunk = destructible.SplitNext(i == 0); var rect = new D2dRect(island.MinX, island.MaxX, island.MinY, island.MaxY); rect.ClampTo(baseRect); D2dHelper.ReserveTempAlphaDataClear(rect.SizeX, rect.SizeY); island.Fill(rect); chunk.SubsetAlphaWith(D2dHelper.tempAlphaData, rect); } } destructible.SplitEnd(); } } }
public void SubsetAlphaWith(Color32[] subData, D2dRect subRect, int newAlphaCount = -1) { var stepX = D2dHelper.Divide(alphaScale.x, alphaWidth); var stepY = D2dHelper.Divide(alphaScale.y, alphaHeight); alphaOffset.x += stepX * subRect.MinX; alphaOffset.y += stepY * subRect.MinY; alphaScale.x += stepX * (subRect.SizeX - alphaWidth); alphaScale.y += stepY * (subRect.SizeY - alphaHeight); FastCopyAlphaData(subData, subRect.SizeX, subRect.SizeY, newAlphaCount); NotifyRebuilt(); }
public void Fill(D2dRect rect) { for (var i = Lines.Count - 1; i >= 0; i--) { var line = Lines[i]; var o = (line.Y - rect.MinY) * rect.SizeX - rect.MinX; var z = line.Y * alphaWidth; for (var x = line.MinX; x < line.MaxX; x++) { D2dHelper.tempAlphaData[o + x] = alphaData[z + x]; } } }
public void Transform(D2dRect newRect, D2dFloodfill.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(); }
protected override void OnAlphaDataModified(D2dRect 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] = D2dPolygonColliderCell.Add(cell); } RebuildCell(ref cells[index], cellX, cellY); } } Sweep(); }
public void Submit(D2dDistanceField baseField, D2dSplitGroup splitGroup, D2dRect baseRect, D2dRect 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 void ClampTo(D2dRect 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; } }
private static void CalculateLayout(D2dRect 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 Prepare(D2dRect 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); } } }
public void Fill(D2dDistanceField baseField, D2dRect baseRect, D2dRect rect) { distanceField.Transform(rect, this); for (var y = rect.MinY; y < rect.MaxY; y++) { var o = (y - rect.MinY) * rect.SizeX - rect.MinX; var z = y * alphaWidth; 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) { D2dHelper.tempAlphaData[o + x] = alphaData[z + x]; } } } }
protected override void DoModified(D2dRect rect) { var cellXMin = rect.MinX / cellSiz; var cellYMin = rect.MinY / cellSiz; var cellXMax = (rect.MaxX + 1) / cellSiz; var cellYMax = (rect.MaxY + 1) / cellSiz; cellXMin = Mathf.Clamp(cellXMin, 0, cellCol - 1); cellXMax = Mathf.Clamp(cellXMax, 0, cellCol - 1); cellYMin = Mathf.Clamp(cellYMin, 0, cellRow - 1); cellYMax = Mathf.Clamp(cellYMax, 0, cellRow - 1); for (var cellY = cellYMin; cellY <= cellYMax; cellY++) { var offset = cellY * cellCol; for (var cellX = cellXMin; cellX <= cellXMax; cellX++) { ClearCell(cells[cellX + offset]); } } for (var cellY = cellYMin; cellY <= cellYMax; cellY++) { var offset = cellY * cellCol; for (var cellX = cellXMin; cellX <= cellXMax; cellX++) { var cell = cells[cellX + offset]; RebuildCell(cell, cellX, cellY); } } SweepColliders(); }
protected override void OnAlphaDataSubset(D2dRect rect) { base.OnAlphaDataSubset(rect); Rebuild(); }
private void Modified(D2dRect rect) { TrySplit(); }
public void Add(D2dRect rect) { Add(rect.MinX, rect.MaxX, rect.MinY, rect.MaxY); }
protected virtual void OnAlphaDataModified(D2dRect rect) { UpdateBeforeBuild(); }
private void HandleModified(D2dRect rect) { UpdateMass(); }
protected override void OnAlphaDataModified(D2dRect rect) { base.OnAlphaDataModified(rect); Rebuild(); }
public static bool AlphaIsValid(byte[] data, D2dRect rect) { return(data != null && rect.IsSet == true && data.Length >= rect.Area); }
private void HandleModified(D2dRect rect) { UpdateBeforeBuild(); DoModified(rect); }
protected virtual void OnAlphaDataSubset(D2dRect rect) { UpdateBeforeBuild(); }
protected abstract void DoModified(D2dRect rect);