/// <summary> /// Builds the combined meshes using data from the atlased dictionary /// </summary> void BuildAtlasedMeshes() { _numOfExportedMeshes = 0; foreach (KeyValuePair <string, Dictionary <Material, List <MeshInstance> > > firstPass in _dataTreeWithAtlasing) { List <Material> allMaterialTextures = new List <Material> (firstPass.Value.Keys); ReimportNonReadonlyTextures(allMaterialTextures); TextureCombineOutput textureCombineOutput = TextureCombineUtility.Combine(allMaterialTextures, _textureAtlasProperties, true); if (textureCombineOutput != null && textureCombineOutput.texturePositions != null) { List <MeshInstance> meshIntermediates = new List <MeshInstance> (); foreach (KeyValuePair <Material, List <MeshInstance> > kv in firstPass.Value) { TexturePosition refTexture = GetReferenceTexturePosition(textureCombineOutput.texturePositions, kv.Key.mainTexture.name); for (int i = 0; i < kv.Value.Count; i++) { OffsetUvs(kv.Value [i].mesh, refTexture.position); meshIntermediates.Add(kv.Value [i]); } } IList <Mesh> combinedMeshes = MeshCombineUtility.Combine(meshIntermediates); string objectName = firstPass.Key.Remove(firstPass.Key.LastIndexOf(' ')); GameObject parent = new GameObject("Combined " + objectName + " Mesh Parent"); parent.transform.parent = _hiddenCombinedObject.transform; parent.transform.position = _hiddenCombinedObject.transform.position; parent.transform.rotation = _hiddenCombinedObject.transform.rotation; for (int i = 0; i < combinedMeshes.Count; i++) { GameObject go = new GameObject("Combined " + objectName + " Mesh"); go.transform.parent = parent.transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; MeshFilter filter = go.AddComponent <MeshFilter> (); go.AddComponent <MeshRenderer> ().sharedMaterial = textureCombineOutput.combinedMaterial; filter.mesh = combinedMeshes [i]; _numOfExportedMeshes++; } } } }
/// <summary> /// The main combining method. This calls combining methods and organizes game objects in the scene /// </summary> /// <param name="allMeshesAndMaterials">The dictionary containing all of the data</param> void CreateBatchedAtlasedObjects(IDictionary <string, Dictionary <Material, List <MeshInstance> > > allMeshesAndMaterials) { foreach (KeyValuePair <string, Dictionary <Material, List <MeshInstance> > > firstPass in allMeshesAndMaterials) { List <Material> allMaterialTextures = new List <Material>(firstPass.Value.Keys); TextureCombineOutput textureCombineOutput = TextureCombineUtility.Combine(allMaterialTextures, _textureAtlasProperties); if (textureCombineOutput != null && textureCombineOutput.texturePositions != null) { List <MeshInstance> meshIntermediates = new List <MeshInstance>(); foreach (KeyValuePair <Material, List <MeshInstance> > kv in firstPass.Value) { TexturePosition refTexture = GetReferenceTexturePosition(textureCombineOutput.texturePositions, kv.Key.mainTexture.name); for (int i = 0; i < kv.Value.Count; i++) { OffsetUvs(kv.Value[i].mesh, refTexture.position); meshIntermediates.Add(kv.Value[i]); } } IList <Mesh> combinedMeshes = MeshCombineUtility.Combine(meshIntermediates); GameObject parent = new GameObject("Combined " + gameObject.name + " " + firstPass.Key + " Mesh Parent"); parent.transform.position = transform.position; parent.transform.rotation = transform.rotation; for (int i = 0; i < combinedMeshes.Count; i++) { GameObject go = new GameObject("Combined " + gameObject.name + " Mesh"); go.transform.parent = parent.transform; go.tag = gameObject.tag; go.layer = gameObject.layer; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; MeshFilter filter = go.AddComponent <MeshFilter>(); go.AddComponent <MeshRenderer>().sharedMaterial = textureCombineOutput.combinedMaterial; filter.mesh = combinedMeshes[i]; } } } }
/// <summary> /// Combines the material's textures together using the atlas options /// </summary> /// <param name="combines">The materials that are being combined.</param> /// <param name="atlasInfo">Atlas options information.</param> public static TextureCombineOutput Combine(IList <Material> combines, DrawCallMinimizerInfo atlasInfo) { if (atlasInfo == null || atlasInfo.shaderPropertiesToLookFor == null || atlasInfo.shaderPropertiesToLookFor.Count <= 0) { Debug.LogError("You need to enter some shader properties to look for into Atlas Info. Cannot combine with 0 properties"); return(null); } TextureCombineOutput output = new TextureCombineOutput(); IList <ShaderProperties> properties = GetShaderProperties(combines, atlasInfo); for (int i = 0; i < combines.Count; i++) { FillInNullMainTexture(combines [i]); for (int j = 0; j < properties.Count; j++) { FillInNulls(combines [i], properties [j]); } } output.texturePositions = SetTexturePositions(combines, properties); Texture2D textureAtlas = new Texture2D(atlasInfo.maxTextureSize, atlasInfo.maxTextureSize, (atlasInfo.ignoreTransparency && !properties [0].markAsNormal) ? TextureFormat.RGB24 : TextureFormat.ARGB32, true); Rect[] UVs = PackOriginalTexture(output.texturePositions, textureAtlas, atlasInfo); if (UVs != null) { Material newMaterial = new Material(combines [0]); newMaterial.SetTexture(properties [0].propertyName, textureAtlas); for (int i = 1; i < properties.Count; i++) { Texture2D additionalAtlas = PackAdditionalTexture(GetTexturesAsArray(output.texturePositions, i), textureAtlas.width, textureAtlas.height, atlasInfo, UVs, properties [i].markAsNormal); newMaterial.SetTexture(properties [i].propertyName, additionalAtlas); } output.combinedMaterial = newMaterial; return(output); } Debug.LogError("There was some sort of issue while trying to pack the textures..."); return(null); }
/// <summary> /// Combines the material's textures together using the atlas options /// </summary> /// <param name="combines">The materials that are being combined.</param> /// <param name="atlasInfo">Atlas options information.</param> public static TextureCombineOutput Combine(IList<Material>combines, DrawCallMinimizerInfo atlasInfo) { if (atlasInfo == null || atlasInfo.shaderPropertiesToLookFor == null || atlasInfo.shaderPropertiesToLookFor.Count <= 0) { Debug.LogError("You need to enter some shader properties to look for into Atlas Info. Cannot combine with 0 properties"); return null; } TextureCombineOutput output = new TextureCombineOutput(); IList<ShaderProperties> properties = GetShaderProperties(combines, atlasInfo); for (int i = 0; i < combines.Count; i++) { FillInNullMainTexture(combines [i]); for (int j = 0; j < properties.Count; j++) { FillInNulls(combines [i], properties [j]); } } output.texturePositions = SetTexturePositions(combines, properties); Texture2D textureAtlas = new Texture2D(atlasInfo.maxTextureSize, atlasInfo.maxTextureSize, (atlasInfo.ignoreTransparency && !properties [0].markAsNormal) ? TextureFormat.RGB24 : TextureFormat.ARGB32, true); Rect[] UVs = PackOriginalTexture(output.texturePositions, textureAtlas, atlasInfo); if (UVs != null) { Material newMaterial = new Material(combines [0]); newMaterial.SetTexture(properties [0].propertyName, textureAtlas); for (int i = 1; i < properties.Count; i++) { Texture2D additionalAtlas = PackAdditionalTexture(GetTexturesAsArray(output.texturePositions, i), textureAtlas.width, textureAtlas.height, atlasInfo, UVs, properties [i].markAsNormal); newMaterial.SetTexture(properties [i].propertyName, additionalAtlas); } output.combinedMaterial = newMaterial; return output; } Debug.LogError("There was some sort of issue while trying to pack the textures..."); return null; }