private void PackItemsToAtlas(List <TextureTools.AtlasItem> items, Size atlasSize, out double packRate) { items.ForEach(i => i.Allocated = false); // Reserve space for default one-pixel padding. atlasSize.Width += 2; atlasSize.Height += 2; var rectAllocator = new RectAllocator(atlasSize); TextureTools.AtlasItem firstAllocatedItem = null; foreach (var item in items) { var padding = item.CookingRules.AtlasItemPadding; var paddedItemSize = new Size(item.BitmapInfo.Width + padding * 2, item.BitmapInfo.Height + padding * 2); if (firstAllocatedItem == null || AreAtlasItemsCompatible(items, firstAllocatedItem, item)) { if (rectAllocator.Allocate(paddedItemSize, out item.AtlasRect)) { item.Allocated = true; firstAllocatedItem = firstAllocatedItem ?? item; } } } packRate = rectAllocator.GetPackRate(); // Adjust item rects according to theirs paddings. foreach (var item in items) { if (!item.Allocated) { continue; } var atlasRect = item.AtlasRect; atlasRect.A += new IntVector2(item.CookingRules.AtlasItemPadding); atlasRect.B -= new IntVector2(item.CookingRules.AtlasItemPadding); // Don't leave space between item rectangle and texture boundaries for items with 1 pixel padding. if (item.CookingRules.AtlasItemPadding == 1) { atlasRect.A -= new IntVector2(1); atlasRect.B -= new IntVector2(1); } item.AtlasRect = atlasRect; } }
private static void PackItemsToAtlas(List <AtlasItem> items, Size size, out double packRate) { items.ForEach(i => i.Allocated = false); // Take in account 1 pixel border for each side. var a = new RectAllocator(new Size(size.Width + 2, size.Height + 2)); AtlasItem firstAllocatedItem = null; foreach (var item in items) { var sz = new Size(item.Bitmap.Width + 2, item.Bitmap.Height + 2); if (firstAllocatedItem == null || AreAtlasItemsCompatible(items, firstAllocatedItem, item)) { if (a.Allocate(sz, out item.AtlasRect)) { item.Allocated = true; firstAllocatedItem = firstAllocatedItem ?? item; } } } packRate = a.GetPackRate(); }