static void swap(TexturePosition[] textures, int i, int j) { TexturePosition temp = textures[i]; textures[i] = textures[j]; textures[j] = temp; }
static void textureQuickSort(TexturePosition[] textures, int low, int high) { if (low < high) { int pivot = partition(textures, low, high); textureQuickSort(textures, low, pivot - 1); textureQuickSort(textures, pivot + 1, high); } }
static void swap(TexturePosition[] textures, int i, int j) { TexturePosition temp = textures [i]; textures [i] = textures [j]; textures [j] = temp; }
/** * This function returns two variables: -> The tecture atlas -> An array of the old textures and their new positions. (Used for UV modification) */ public static Material combine(Material[] combines, out TexturePosition[] texturePositions, TextureAtlasInfo atlasInfo) { if (atlasInfo == null) { Debug.LogError("atlasInfo is null. Try removing and reattaching combine children component"); texturePositions = null; return null; } if (atlasInfo.shaderPropertiesToLookFor.Length <= 0) { Debug.LogError("You need to enter some shader properties to look for into Atlas Info. Cannot combine with 0 properties"); texturePositions = null; return null; } List<ShaderProperties> properties = new List<ShaderProperties>(); for (int i = 0; i < atlasInfo.shaderPropertiesToLookFor.Length; i++) { if (combines [0].HasProperty(atlasInfo.shaderPropertiesToLookFor [i].propertyName)) { properties.Add(atlasInfo.shaderPropertiesToLookFor [i]); } } texturePositions = new TexturePosition[combines.Length]; for (int i = 0; i < combines.Length; i++) { TexturePosition tempTexturePosition = new TexturePosition(); tempTexturePosition.textures = new Texture2D[properties.Count]; for (int j = 0; j < properties.Count; j++) { //Debug.Log((combines[i].GetTexture(properties[j].propertyName) == null) + ", " + properties[j].propertyName + ", " + combines[i].name); if (combines [i].GetTexture(properties [j].propertyName) == null) { Debug.LogError("Cannot combine textures when using Unity's default material texture"); texturePositions = null; return null; } tempTexturePosition.textures [j] = Object.Instantiate(combines [i].GetTexture(properties [j].propertyName)) as Texture2D; tempTexturePosition.textures [j].name = tempTexturePosition.textures [j].name.Remove(tempTexturePosition.textures [j].name.IndexOf("(Clone)", System.StringComparison.Ordinal)); } texturePositions [i] = tempTexturePosition; } textureQuickSort(texturePositions, 0, texturePositions.Length - 1); for (int i = 0; i < texturePositions.Length; i++) { for (int j = 1; j < texturePositions[i].textures.Length; j++) { texturePositions [i].textures [j] = scaleTexture(texturePositions [i].textures [j], texturePositions [i].textures [0].width, texturePositions [i].textures [0].height); } } texturePositions [0].position.x = texturePositions [0].position.y = 0; texturePositions [0].position.width = texturePositions [0].textures [0].width; texturePositions [0].position.height = texturePositions [0].textures [0].height; int height = texturePositions [0].textures [0].height; int width = texturePositions [0].textures [0].width; int widthIndex = width; int heightIndex = 0; bool useHeightAsReference = true; for (int i = 1; i < texturePositions.Length; i++) { texturePositions [i].position.x = widthIndex; texturePositions [i].position.y = heightIndex; texturePositions [i].position.width = texturePositions [i].textures [0].width; texturePositions [i].position.height = texturePositions [i].textures [0].height; if (useHeightAsReference) { if (widthIndex + texturePositions [i].textures [0].width > width) { width = widthIndex + texturePositions [i].textures [0].width; } heightIndex += texturePositions [i].textures [0].height; if (heightIndex >= height) { useHeightAsReference = false; height = heightIndex; heightIndex = height; widthIndex = 0; } } else { if (heightIndex + texturePositions [i].textures [0].height > height) { height = heightIndex + texturePositions [i].textures [0].height; } widthIndex += texturePositions [i].textures [0].width; if (widthIndex >= width) { useHeightAsReference = true; width = widthIndex; widthIndex = width; heightIndex = 0; } } } if (height > width) { width = height; } else { height = width; } float textureSizeFactor = 1.0f / height; Material newMaterial = new Material(combines [0]); for (int i = 0; i < properties.Count; i++) { Texture2D combinesTextures = new Texture2D(width, height, (atlasInfo.ignoreAlpha && !properties [i].markAsNormal) ? TextureFormat.RGB24 : TextureFormat.ARGB32, true); combinesTextures.anisoLevel = atlasInfo.anisoLevel; combinesTextures.filterMode = atlasInfo.filterMode; combinesTextures.wrapMode = atlasInfo.wrapMode; for (int j = 0; j < texturePositions.Length; j++) { combinesTextures.SetPixels((int)texturePositions [j].position.x, (int)texturePositions [j].position.y, texturePositions [j].textures [i].width, texturePositions [j].textures [i].height, texturePositions [j].textures [i].GetPixels()); } combinesTextures.Apply(); if (atlasInfo.compressTexturesInMemory) { combinesTextures.Compress(true); } newMaterial.SetTexture(properties [i].propertyName, combinesTextures); } for (int i = 0; i < texturePositions.Length; i++) { texturePositions [i].position.x = texturePositions [i].position.x * textureSizeFactor; texturePositions [i].position.y = texturePositions [i].position.y * textureSizeFactor; texturePositions [i].position.width = texturePositions [i].position.width * textureSizeFactor; texturePositions [i].position.height = texturePositions [i].position.height * textureSizeFactor; } return newMaterial; }
static int partition(TexturePosition[] texturePositions, int low, int high) { TexturePosition pivot_item; int pivotPosition = low; pivot_item = texturePositions [pivotPosition]; for (int i = low + 1; i <= high; i++) { if (texturePositions [i].textures [0].height > pivot_item.textures [0].height) { pivotPosition++; swap(texturePositions, pivotPosition, i); } } swap(texturePositions, low, pivotPosition); return pivotPosition; }
/** * This function returns two variables: * -> The tecture atlas * -> An array of the old textures and their new positions. (Used for UV modification) */ public static Material combine(Material[] combines, out TexturePosition[] texturePositions, TextureAtlasInfo atlasInfo) { if (atlasInfo == null) { Debug.LogError("atlasInfo is null. Try removing and reattaching combine children component"); texturePositions = null; return(null); } if (atlasInfo.shaderPropertiesToLookFor.Length <= 0) { Debug.LogError("You need to enter some shader properties to look for into Atlas Info. Cannot combine with 0 properties"); texturePositions = null; return(null); } List <ShaderProperties> properties = new List <ShaderProperties>(); for (int i = 0; i < atlasInfo.shaderPropertiesToLookFor.Length; i++) { if (combines[0].HasProperty(atlasInfo.shaderPropertiesToLookFor[i].propertyName) == true) { properties.Add(atlasInfo.shaderPropertiesToLookFor[i]); } } texturePositions = new TexturePosition[combines.Length]; for (int i = 0; i < combines.Length; i++) { TexturePosition tempTexturePosition = new TexturePosition(); tempTexturePosition.textures = new Texture2D[properties.Count]; for (int j = 0; j < properties.Count; j++) { //Debug.Log((combines[i].GetTexture(properties[j].propertyName) == null) + ", " + properties[j].propertyName + ", " + combines[i].name); if (combines[i].GetTexture(properties[j].propertyName) == null) { Debug.LogError("Cannot combine textures when using Unity's default material texture"); texturePositions = null; return(null); } tempTexturePosition.textures[j] = GameObject.Instantiate(combines[i].GetTexture(properties[j].propertyName)) as Texture2D; tempTexturePosition.textures[j].name = tempTexturePosition.textures[j].name.Remove(tempTexturePosition.textures[j].name.IndexOf("(Clone)")); } texturePositions[i] = tempTexturePosition; } textureQuickSort(texturePositions, 0, texturePositions.Length - 1); for (int i = 0; i < texturePositions.Length; i++) { for (int j = 1; j < texturePositions[i].textures.Length; j++) { texturePositions[i].textures[j] = scaleTexture(texturePositions[i].textures[j], texturePositions[i].textures[0].width, texturePositions[i].textures[0].height); } } texturePositions[0].position.x = texturePositions[0].position.y = 0; texturePositions[0].position.width = texturePositions[0].textures[0].width; texturePositions[0].position.height = texturePositions[0].textures[0].height; int height = texturePositions[0].textures[0].height; int width = texturePositions[0].textures[0].width; int widthIndex = width; int heightIndex = 0; bool useHeightAsReference = true; for (int i = 1; i < texturePositions.Length; i++) { texturePositions[i].position.x = widthIndex; texturePositions[i].position.y = heightIndex; texturePositions[i].position.width = texturePositions[i].textures[0].width; texturePositions[i].position.height = texturePositions[i].textures[0].height; if (useHeightAsReference) { if (widthIndex + texturePositions[i].textures[0].width > width) { width = widthIndex + texturePositions[i].textures[0].width; } heightIndex += texturePositions[i].textures[0].height; if (heightIndex >= height) { useHeightAsReference = false; height = heightIndex; heightIndex = height; widthIndex = 0; } } else { if (heightIndex + texturePositions[i].textures[0].height > height) { height = heightIndex + texturePositions[i].textures[0].height; } widthIndex += texturePositions[i].textures[0].width; if (widthIndex >= width) { useHeightAsReference = true; width = widthIndex; widthIndex = width; heightIndex = 0; } } } if (height > width) { width = height; } else { height = width; } float textureSizeFactor = 1.0f / height; Material newMaterial = new Material(combines[0]); for (int i = 0; i < properties.Count; i++) { Texture2D combinesTextures = new Texture2D(width, height, (atlasInfo.ignoreAlpha && !properties[i].markAsNormal) ? TextureFormat.RGB24 : TextureFormat.ARGB32, true); combinesTextures.anisoLevel = atlasInfo.anisoLevel; combinesTextures.filterMode = atlasInfo.filterMode; combinesTextures.wrapMode = atlasInfo.wrapMode; for (int j = 0; j < texturePositions.Length; j++) { combinesTextures.SetPixels((int)texturePositions[j].position.x, (int)texturePositions[j].position.y, texturePositions[j].textures[i].width, texturePositions[j].textures[i].height, texturePositions[j].textures[i].GetPixels()); } combinesTextures.Apply(); if (atlasInfo.compressTexturesInMemory == true) { combinesTextures.Compress(true); } newMaterial.SetTexture(properties[i].propertyName, combinesTextures); } for (int i = 0; i < texturePositions.Length; i++) { texturePositions[i].position.x = texturePositions[i].position.x * textureSizeFactor; texturePositions[i].position.y = texturePositions[i].position.y * textureSizeFactor; texturePositions[i].position.width = texturePositions[i].position.width * textureSizeFactor; texturePositions[i].position.height = texturePositions[i].position.height * textureSizeFactor; } // Debug.Log("TexCU : " + newMaterial.GetTexture(properties[0].propertyName).name + " combines[0] :"+combines[0].name); return(newMaterial); }