private Dictionary <string, List <DicedUnit> > DiceSourceTextures(List <FolderAsset <Texture2D> > textureAssets) { // Texture name -> units diced off the texture. var nameToUnitsMap = new Dictionary <string, List <DicedUnit> >(); var unitSize = diceUnitSizeProperty.intValue; foreach (var textureAsset in textureAssets) { var sourceTexture = textureAsset.Object; var key = nameToUnitsMap.ContainsKey(textureAsset.Name) ? textureAsset.Name + Guid.NewGuid().ToString() : textureAsset.Name; var value = new List <DicedUnit>(); var nameToUnits = new KeyValuePair <string, List <DicedUnit> >(key, value); // Make sure texture is readable and not crunched (can't get pixels otherwise). var textureImporter = textureAsset.Importer as TextureImporter; if (!textureImporter.isReadable || textureImporter.crunchedCompression) { textureImporter.isReadable = true; textureImporter.crunchedCompression = false; AssetDatabase.ImportAsset(textureAsset.Path); } var unitCountX = Mathf.CeilToInt((float)sourceTexture.width / unitSize); var unitCountY = Mathf.CeilToInt((float)sourceTexture.height / unitSize); for (int unitX = 0; unitX < unitCountX; unitX++) { var textureProgress = .5f * textureAssets.ProgressOf(textureAsset); var unitProgress = (.5f / textureAssets.Count) * ((float)unitX / unitCountX); var textureNumber = textureAssets.IndexOf(textureAsset) + 1; var message = $"Dicing texture '{textureAsset.Name}' ({textureNumber}/{textureAssets.Count})..."; DisplayProgressBar(message, textureProgress + unitProgress); var x = unitX * unitSize; for (int unitY = 0; unitY < unitCountY; unitY++) { var y = unitY * unitSize; var pixelsRect = new Rect(x, y, unitSize, unitSize); var paddedRect = pixelsRect.Crop(paddingProperty.intValue); var colors = sourceTexture.GetPixels(pixelsRect); // TODO: Get only padded pixels and evaluate original pixels from them. // Skip transparent units (no need to render them). if (colors.All(color => color.a == 0)) { continue; } var paddedColors = sourceTexture.GetPixels(paddedRect); var quadVerts = pixelsRect.Scale(1f / pixelsPerUnitProperty.floatValue); var dicedUnit = new DicedUnit() { QuadVerts = quadVerts, Colors = colors, PaddedColors = paddedColors }; nameToUnits.Value.Add(dicedUnit); } } nameToUnitsMap.Add(nameToUnits.Key, nameToUnits.Value); } return(nameToUnitsMap); }
public DicedTexture Dice(SourceTexture source) { var texture = source.Texture; var units = new List <DicedUnit>(); var unitCountX = Mathf.CeilToInt((float)texture.width / unitSize); var unitCountY = Mathf.CeilToInt((float)texture.height / unitSize); for (int unitX = 0; unitX < unitCountX; unitX++) { for (int unitY = 0; unitY < unitCountY; unitY++) { var x = unitX * unitSize; var y = unitY * unitSize; var pixelsRect = new RectInt(x, y, unitSize, unitSize); var pixels = GetPixels(texture, pixelsRect); if (pixels.All(p => p.a == 0)) { continue; } var paddedRect = PadRect(pixelsRect, padding); var paddedPixels = GetPixels(texture, paddedRect); var quadVerts = CropOverBorders(pixelsRect, x, y, texture); var hash = GetHash(unitSize, pixels); var dicedUnit = new DicedUnit(quadVerts, paddedPixels, hash); units.Add(dicedUnit); } } return(new DicedTexture(source, units)); }
private static Dictionary <string, List <DicedUnit> > DiceSourceTextures(List <FolderAsset <Texture2D> > textureAssets, int unitSize, int padding, float ppu) { // Texture name -> units diced off the texture. var nameToUnitsMap = new Dictionary <string, List <DicedUnit> >(); foreach (var textureAsset in textureAssets) { var sourceTexture = textureAsset.Object; var key = nameToUnitsMap.ContainsKey(textureAsset.Name) ? textureAsset.Name + Guid.NewGuid().ToString() : textureAsset.Name; var value = new List <DicedUnit>(); var nameToUnits = new KeyValuePair <string, List <DicedUnit> >(key, value); // Make sure texture is readable and not crunched (can't get pixels otherwise). var textureImporter = textureAsset.Importer as TextureImporter; if (textureImporter is null) { throw new Exception($"Failed to get texture importer for `{textureAsset.Name}`."); } if (!textureImporter.isReadable || textureImporter.crunchedCompression) { textureImporter.isReadable = true; textureImporter.crunchedCompression = false; AssetDatabase.ImportAsset(textureAsset.Path); } var unitCountX = Mathf.CeilToInt((float)sourceTexture.width / unitSize); var unitCountY = Mathf.CeilToInt((float)sourceTexture.height / unitSize); for (int unitX = 0; unitX < unitCountX; unitX++) { var textureProgress = .5f * textureAssets.ProgressOf(textureAsset); var unitProgress = (.5f / textureAssets.Count) * ((float)unitX / unitCountX); var textureNumber = textureAssets.IndexOf(textureAsset) + 1; var message = $"Dicing texture '{textureAsset.Name}' ({textureNumber}/{textureAssets.Count})..."; DisplayProgressBar(message, textureProgress + unitProgress); var x = unitX * unitSize; for (int unitY = 0; unitY < unitCountY; unitY++) { var y = unitY * unitSize; var pixelsRect = new Rect(x, y, unitSize, unitSize); var colors = sourceTexture.GetPixels(pixelsRect); // TODO: Get only padded pixels and evaluate original pixels from them. // Skip transparent units (no need to render them). if (colors.All(color => color.a == 0)) { continue; } var paddedRect = pixelsRect.Crop(padding); var paddedColors = sourceTexture.GetPixels(paddedRect); var quadVerts = pixelsRect.Scale(1f / ppu); // TODO: Find out how Unity builds that hash and replicate. Comparing each element in color arrays has issues with flat color textures and small dice units. var hash = Utilities.CreateTexture(unitSize, colors).imageContentsHash; var dicedUnit = new DicedUnit { QuadVerts = quadVerts, ContentHash = hash, PaddedColors = paddedColors }; nameToUnits.Value.Add(dicedUnit); } } nameToUnitsMap.Add(nameToUnits.Key, nameToUnits.Value); } return(nameToUnitsMap); }
private void AddDicedUnit(DicedUnit dicedUnit) { AddQuad(dicedUnit.QuadVerts.min, dicedUnit.QuadVerts.max, dicedUnit.QuadUVs.min, dicedUnit.QuadUVs.max); }
private void AddDicedUnit(DicedUnit unit, Rect uv) { var rect = ScaleRect(unit.QuadVerts); AddQuad(rect.min, rect.max, uv.min, uv.max); }