public override IEnumerator CreateAtlases(ProgressUpdateDelegate progressInfo, MB3_TextureCombinerPipeline.TexturePipelineData data, MB3_TextureCombiner combiner, AtlasPackingResult packedAtlasRects, Texture2D[] atlases, MB2_EditorMethodsInterface textureEditorMethods, MB2_LogLevel LOG_LEVEL) { Debug.Assert(!data.OnlyOneTextureInAtlasReuseTextures()); Rect[] uvRects = packedAtlasRects.rects; long estArea = 0; int atlasSizeX = 1; int atlasSizeY = 1; uvRects = null; for (int propIdx = 0; propIdx < data.numAtlases; propIdx++) { //----------------------- ShaderTextureProperty prop = data.texPropertyNames[propIdx]; Texture2D atlas = null; if (!MB3_TextureCombinerPipeline._ShouldWeCreateAtlasForThisProperty(propIdx, data._considerNonTextureProperties, data.allTexturesAreNullAndSameColor)) { atlas = null; } else { if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.LogWarning("Beginning loop " + propIdx + " num temporary textures " + combiner._getNumTemporaryTextures()); } MB3_TextureCombinerPackerRoot.CreateTemporaryTexturesForAtlas(data.distinctMaterialTextures, combiner, propIdx, data); Texture2D[] texToPack = new Texture2D[data.distinctMaterialTextures.Count]; for (int texSetIdx = 0; texSetIdx < data.distinctMaterialTextures.Count; texSetIdx++) { MB_TexSet txs = data.distinctMaterialTextures[texSetIdx]; int tWidth = txs.idealWidth; int tHeight = txs.idealHeight; Texture2D tx = txs.ts[propIdx].GetTexture2D(); if (progressInfo != null) { progressInfo("Adjusting for scale and offset " + tx, .01f); } if (textureEditorMethods != null) { textureEditorMethods.SetReadWriteFlag(tx, true, true); } tx = GetAdjustedForScaleAndOffset2(prop.name, txs.ts[propIdx], txs.obUVoffset, txs.obUVscale, data, combiner, LOG_LEVEL); //create a resized copy if necessary if (tx.width != tWidth || tx.height != tHeight) { if (progressInfo != null) { progressInfo("Resizing texture '" + tx + "'", .01f); } if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.LogWarning("Copying and resizing texture " + prop.name + " from " + tx.width + "x" + tx.height + " to " + tWidth + "x" + tHeight); } tx = combiner._resizeTexture(prop.name, (Texture2D)tx, tWidth, tHeight); } estArea += tx.width * tx.height; if (data._considerNonTextureProperties) { //combine the tintColor with the texture tx = combiner._createTextureCopy(prop.name, tx); data.nonTexturePropertyBlender.TintTextureWithTextureCombiner(tx, data.distinctMaterialTextures[texSetIdx], prop); } texToPack[texSetIdx] = tx; } if (textureEditorMethods != null) { textureEditorMethods.CheckBuildSettings(estArea); } if (Math.Sqrt(estArea) > 3500f) { if (LOG_LEVEL >= MB2_LogLevel.warn) { Debug.LogWarning("The maximum possible atlas size is 4096. Textures may be shrunk"); } } atlas = new Texture2D(1, 1, TextureFormat.ARGB32, true); if (progressInfo != null) { progressInfo("Packing texture atlas " + prop.name, .25f); } if (propIdx == 0) { if (progressInfo != null) { progressInfo("Estimated min size of atlases: " + Math.Sqrt(estArea).ToString("F0"), .1f); } if (LOG_LEVEL >= MB2_LogLevel.info) { Debug.Log("Estimated atlas minimum size:" + Math.Sqrt(estArea).ToString("F0")); } int maxAtlasSize = 4096; uvRects = atlas.PackTextures(texToPack, data._atlasPadding, maxAtlasSize, false); if (LOG_LEVEL >= MB2_LogLevel.info) { Debug.Log("After pack textures atlas size " + atlas.width + " " + atlas.height); } atlasSizeX = atlas.width; atlasSizeY = atlas.height; atlas.Apply(); } else { if (progressInfo != null) { progressInfo("Copying Textures Into: " + prop.name, .1f); } atlas = _copyTexturesIntoAtlas(texToPack, data._atlasPadding, uvRects, atlasSizeX, atlasSizeY, combiner); } } atlases[propIdx] = atlas; //---------------------- if (data._saveAtlasesAsAssets && textureEditorMethods != null) { textureEditorMethods.SaveAtlasToAssetDatabase(atlases[propIdx], prop, propIdx, data.resultMaterial); } data.resultMaterial.SetTextureOffset(prop.name, Vector2.zero); data.resultMaterial.SetTextureScale(prop.name, Vector2.one); combiner._destroyTemporaryTextures(prop.name); GC.Collect(); } packedAtlasRects.rects = uvRects; yield break; }
Rect[] __CreateAtlasesUnityTexturePacker(ProgressUpdateDelegate progressInfo, int numAtlases, List<MB_TexSet> distinctMaterialTextures, List<string> texPropertyNames, Material resultMaterial, Texture2D[] atlases, MB2_EditorMethodsInterface textureEditorMethods, int _padding){ Rect[] uvRects; if (distinctMaterialTextures.Count == 1){ if (LOG_LEVEL >= MB2_LogLevel.debug) Debug.Log("Only one image per atlas. Will re-use original texture"); uvRects = new Rect[1]; uvRects[0] = new Rect(0f,0f,1f,1f); for (int i = 0; i < numAtlases; i++){ MeshBakerMaterialTexture dmt = distinctMaterialTextures[0].ts[i]; atlases[i] = dmt.t; resultMaterial.SetTexture(texPropertyNames[i],atlases[i]); resultMaterial.SetTextureScale(texPropertyNames[i],dmt.scale); resultMaterial.SetTextureOffset(texPropertyNames[i],dmt.offset); } } else { long estArea = 0; int atlasSizeX = 1; int atlasSizeY = 1; uvRects = null; for (int i = 0; i < numAtlases; i++){ //i is an atlas "MainTex", "BumpMap" etc... if (LOG_LEVEL >= MB2_LogLevel.debug) Debug.LogWarning("Beginning loop " + i + " num temporary textures " + _temporaryTextures.Count); for(int j = 0; j < distinctMaterialTextures.Count; j++){ //j is a distinct set of textures one for each of "MainTex", "BumpMap" etc... MB_TexSet txs = distinctMaterialTextures[j]; int tWidth = txs.idealWidth; int tHeight = txs.idealHeight; Texture2D tx = txs.ts[i].t; if (tx == null) tx = txs.ts[i].t = _createTemporaryTexture(tWidth,tHeight,TextureFormat.ARGB32, true); if (progressInfo != null) progressInfo("Adjusting for scale and offset " + tx, .01f); if (textureEditorMethods != null) textureEditorMethods.SetReadWriteFlag(tx, true, true); tx = getAdjustedForScaleAndOffset2(txs.ts[i]); //create a resized copy if necessary if (tx.width != tWidth || tx.height != tHeight) { if (progressInfo != null) progressInfo("Resizing texture '" + tx + "'", .01f); if (LOG_LEVEL >= MB2_LogLevel.debug) Debug.LogWarning("Copying and resizing texture " + texPropertyNames[i] + " from " + tx.width + "x" + tx.height + " to " + tWidth + "x" + tHeight); if (textureEditorMethods != null) textureEditorMethods.SetReadWriteFlag((Texture2D) tx, true, true); tx = _resizeTexture((Texture2D) tx,tWidth,tHeight); } txs.ts[i].t = tx; } Texture2D[] texToPack = new Texture2D[distinctMaterialTextures.Count]; for (int j = 0; j < distinctMaterialTextures.Count;j++){ Texture2D tx = distinctMaterialTextures[j].ts[i].t; estArea += tx.width * tx.height; texToPack[j] = tx; } if (textureEditorMethods != null) textureEditorMethods.CheckBuildSettings(estArea); if (Math.Sqrt(estArea) > 3500f){ if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("The maximum possible atlas size is 4096. Textures may be shrunk"); } atlases[i] = new Texture2D(1,1,TextureFormat.ARGB32,true); if (progressInfo != null) progressInfo("Packing texture atlas " + texPropertyNames[i], .25f); if (i == 0){ if (progressInfo != null) progressInfo("Estimated min size of atlases: " + Math.Sqrt(estArea).ToString("F0"), .1f); if (LOG_LEVEL >= MB2_LogLevel.info) Debug.Log("Estimated atlas minimum size:" + Math.Sqrt(estArea).ToString("F0")); _addWatermark(texToPack); if (distinctMaterialTextures.Count == 1){ //don't want to force power of 2 so tiling will still work uvRects = new Rect[1] {new Rect(0f,0f,1f,1f)}; atlases[i] = _copyTexturesIntoAtlas(texToPack,_padding,uvRects,texToPack[0].width,texToPack[0].height); } else { int maxAtlasSize = 4096; uvRects = atlases[i].PackTextures(texToPack,_padding,maxAtlasSize,false); } if (LOG_LEVEL >= MB2_LogLevel.info) Debug.Log("After pack textures atlas size " + atlases[i].width + " " + atlases[i].height); atlasSizeX = atlases[i].width; atlasSizeY = atlases[i].height; atlases[i].Apply(); } else { if (progressInfo != null) progressInfo("Copying Textures Into: " + texPropertyNames[i], .1f); atlases[i] = _copyTexturesIntoAtlas(texToPack,_padding,uvRects, atlasSizeX, atlasSizeY); } if (saveAtlasesAsAssets && textureEditorMethods != null){ textureEditorMethods.SaveAtlasToAssetDatabase(atlases[i], texPropertyNames[i], i, resultMaterial); } else { resultMaterial.SetTexture(texPropertyNames[i], atlases[i]); } resultMaterial.SetTextureOffset(texPropertyNames[i], Vector2.zero); resultMaterial.SetTextureScale(texPropertyNames[i],Vector2.one); _destroyTemporaryTextures(); // need to save atlases before doing this GC.Collect(); } } return uvRects; }
public IEnumerator CreateAtlases(ProgressUpdateDelegate progressInfo, MB3_TextureCombinerPipeline.TexturePipelineData data, MB3_TextureCombiner combiner, AtlasPackingResult packedAtlasRects, Texture2D[] atlases, MB2_EditorMethodsInterface textureEditorMethods, MB2_LogLevel LOG_LEVEL) { Rect[] uvRects = packedAtlasRects.rects; if (data.distinctMaterialTextures.Count == 1 && data._fixOutOfBoundsUVs == false) { if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("Only one image per atlas. Will re-use original texture"); } uvRects = new Rect[1]; uvRects[0] = new Rect(0f, 0f, 1f, 1f); for (int i = 0; i < data.numAtlases; i++) { MeshBakerMaterialTexture dmt = data.distinctMaterialTextures[0].ts[i]; atlases[i] = dmt.GetTexture2D(); data.resultMaterial.SetTexture(data.texPropertyNames[i].name, atlases[i]); data.resultMaterial.SetTextureScale(data.texPropertyNames[i].name, dmt.matTilingRect.size); data.resultMaterial.SetTextureOffset(data.texPropertyNames[i].name, dmt.matTilingRect.min); } } else { long estArea = 0; int atlasSizeX = 1; int atlasSizeY = 1; uvRects = null; for (int i = 0; i < data.numAtlases; i++) { //i is an atlas "MainTex", "BumpMap" etc... //----------------------- Texture2D atlas = null; if (!MB3_TextureCombinerPipeline._ShouldWeCreateAtlasForThisProperty(i, data._considerNonTextureProperties, data.allTexturesAreNullAndSameColor)) { atlas = null; } else { if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.LogWarning("Beginning loop " + i + " num temporary textures " + combiner._temporaryTextures.Count); } for (int j = 0; j < data.distinctMaterialTextures.Count; j++) { //j is a distinct set of textures one for each of "MainTex", "BumpMap" etc... MB_TexSet txs = data.distinctMaterialTextures[j]; int tWidth = txs.idealWidth; int tHeight = txs.idealHeight; Texture2D tx = txs.ts[i].GetTexture2D(); if (tx == null) { tx = txs.ts[i].t = combiner._createTemporaryTexture(tWidth, tHeight, TextureFormat.ARGB32, true); if (data._considerNonTextureProperties && data.nonTexturePropertyBlender != null) { Color col = data.nonTexturePropertyBlender.GetColorIfNoTexture(txs.matsAndGOs.mats[0].mat, data.texPropertyNames[i]); if (LOG_LEVEL >= MB2_LogLevel.trace) { Debug.Log("Setting texture to solid color " + col); } MB_Utility.setSolidColor(tx, col); } else { Color col = MB3_TextureCombinerNonTextureProperties.GetColorIfNoTexture(data.texPropertyNames[i]); MB_Utility.setSolidColor(tx, col); } } if (progressInfo != null) { progressInfo("Adjusting for scale and offset " + tx, .01f); } if (textureEditorMethods != null) { textureEditorMethods.SetReadWriteFlag(tx, true, true); } tx = GetAdjustedForScaleAndOffset2(txs.ts[i], txs.obUVoffset, txs.obUVscale, data, combiner, LOG_LEVEL); //create a resized copy if necessary if (tx.width != tWidth || tx.height != tHeight) { if (progressInfo != null) { progressInfo("Resizing texture '" + tx + "'", .01f); } if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.LogWarning("Copying and resizing texture " + data.texPropertyNames[i].name + " from " + tx.width + "x" + tx.height + " to " + tWidth + "x" + tHeight); } tx = combiner._resizeTexture((Texture2D)tx, tWidth, tHeight); } txs.ts[i].t = tx; } Texture2D[] texToPack = new Texture2D[data.distinctMaterialTextures.Count]; for (int j = 0; j < data.distinctMaterialTextures.Count; j++) { Texture2D tx = data.distinctMaterialTextures[j].ts[i].GetTexture2D(); estArea += tx.width * tx.height; if (data._considerNonTextureProperties) { //combine the tintColor with the texture tx = combiner._createTextureCopy(tx); data.nonTexturePropertyBlender.TintTextureWithTextureCombiner(tx, data.distinctMaterialTextures[j], data.texPropertyNames[i]); } texToPack[j] = tx; } if (textureEditorMethods != null) { textureEditorMethods.CheckBuildSettings(estArea); } if (Math.Sqrt(estArea) > 3500f) { if (LOG_LEVEL >= MB2_LogLevel.warn) { Debug.LogWarning("The maximum possible atlas size is 4096. Textures may be shrunk"); } } atlas = new Texture2D(1, 1, TextureFormat.ARGB32, true); if (progressInfo != null) { progressInfo("Packing texture atlas " + data.texPropertyNames[i].name, .25f); } if (i == 0) { if (progressInfo != null) { progressInfo("Estimated min size of atlases: " + Math.Sqrt(estArea).ToString("F0"), .1f); } if (LOG_LEVEL >= MB2_LogLevel.info) { Debug.Log("Estimated atlas minimum size:" + Math.Sqrt(estArea).ToString("F0")); } if (data.distinctMaterialTextures.Count == 1 && data._fixOutOfBoundsUVs == false) { //don't want to force power of 2 so tiling will still work uvRects = new Rect[1] { new Rect(0f, 0f, 1f, 1f) }; atlas = _copyTexturesIntoAtlas(texToPack, data._atlasPadding, uvRects, texToPack[0].width, texToPack[0].height, combiner); } else { int maxAtlasSize = 4096; uvRects = atlas.PackTextures(texToPack, data._atlasPadding, maxAtlasSize, false); } if (LOG_LEVEL >= MB2_LogLevel.info) { Debug.Log("After pack textures atlas size " + atlas.width + " " + atlas.height); } atlasSizeX = atlas.width; atlasSizeY = atlas.height; atlas.Apply(); } else { if (progressInfo != null) { progressInfo("Copying Textures Into: " + data.texPropertyNames[i].name, .1f); } atlas = _copyTexturesIntoAtlas(texToPack, data._atlasPadding, uvRects, atlasSizeX, atlasSizeY, combiner); } } atlases[i] = atlas; //---------------------- if (data._saveAtlasesAsAssets && textureEditorMethods != null) { textureEditorMethods.SaveAtlasToAssetDatabase(atlases[i], data.texPropertyNames[i], i, data.resultMaterial); } data.resultMaterial.SetTextureOffset(data.texPropertyNames[i].name, Vector2.zero); data.resultMaterial.SetTextureScale(data.texPropertyNames[i].name, Vector2.one); combiner._destroyTemporaryTextures(); // need to save atlases before doing this GC.Collect(); } } packedAtlasRects.rects = uvRects; yield break; }