summaryrefslogtreecommitdiff
path: root/VRCSDK3Worlds/Assets/MeshBaker/scripts/MB3_TextureBaker.cs
diff options
context:
space:
mode:
authortylermurphy534 <tylermurphy534@gmail.com>2022-11-06 15:12:42 -0500
committertylermurphy534 <tylermurphy534@gmail.com>2022-11-06 15:12:42 -0500
commiteb84bb298d2b95aec7b2ae12cbf25ac64f25379a (patch)
treeefd616a157df06ab661c6d56651853431ac6b08b /VRCSDK3Worlds/Assets/MeshBaker/scripts/MB3_TextureBaker.cs
downloadunityprojects-eb84bb298d2b95aec7b2ae12cbf25ac64f25379a.tar.gz
unityprojects-eb84bb298d2b95aec7b2ae12cbf25ac64f25379a.tar.bz2
unityprojects-eb84bb298d2b95aec7b2ae12cbf25ac64f25379a.zip
move to self host
Diffstat (limited to 'VRCSDK3Worlds/Assets/MeshBaker/scripts/MB3_TextureBaker.cs')
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/MB3_TextureBaker.cs742
1 files changed, 742 insertions, 0 deletions
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/MB3_TextureBaker.cs b/VRCSDK3Worlds/Assets/MeshBaker/scripts/MB3_TextureBaker.cs
new file mode 100644
index 00000000..17c986c4
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/MB3_TextureBaker.cs
@@ -0,0 +1,742 @@
+//----------------------------------------------
+// MeshBaker
+// Copyright © 2011-2012 Ian Deane
+//----------------------------------------------
+using UnityEngine;
+using System.Collections;
+using System.Collections.Specialized;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using DigitalOpus.MB.Core;
+
+
+
+/// <summary>
+/// Component that handles baking materials into a combined material.
+///
+/// The result of the material baking process is a MB2_TextureBakeResults object, which
+/// becomes the input for the mesh baking.
+///
+/// This class uses the MB_TextureCombiner to do the combining.
+///
+/// This class is a Component (MonoBehavior) so it is serialized and found using GetComponent. If
+/// you want to access the texture baking functionality without creating a Component then use MB_TextureCombiner
+/// directly.
+/// </summary>
+public class MB3_TextureBaker : MB3_MeshBakerRoot
+{
+ public MB2_LogLevel LOG_LEVEL = MB2_LogLevel.info;
+
+ [SerializeField]
+ protected MB2_TextureBakeResults _textureBakeResults;
+ public override MB2_TextureBakeResults textureBakeResults
+ {
+ get { return _textureBakeResults; }
+ set { _textureBakeResults = value; }
+ }
+
+ [SerializeField]
+ protected int _atlasPadding = 1;
+ public virtual int atlasPadding
+ {
+ get { return _atlasPadding; }
+ set { _atlasPadding = value; }
+ }
+
+ [SerializeField]
+ protected int _maxAtlasSize = 4096;
+ public virtual int maxAtlasSize
+ {
+ get { return _maxAtlasSize; }
+ set { _maxAtlasSize = value; }
+ }
+
+ [SerializeField]
+ protected bool _useMaxAtlasWidthOverride = false;
+ public virtual bool useMaxAtlasWidthOverride
+ {
+ get { return _useMaxAtlasWidthOverride; }
+ set { _useMaxAtlasWidthOverride = value; }
+ }
+
+ [SerializeField]
+ protected int _maxAtlasWidthOverride = 4096;
+ public virtual int maxAtlasWidthOverride
+ {
+ get { return _maxAtlasWidthOverride; }
+ set { _maxAtlasWidthOverride = value; }
+ }
+
+ [SerializeField]
+ protected bool _useMaxAtlasHeightOverride = false;
+ public virtual bool useMaxAtlasHeightOverride
+ {
+ get { return _useMaxAtlasHeightOverride; }
+ set { _useMaxAtlasHeightOverride = value; }
+ }
+
+ [SerializeField]
+ protected int _maxAtlasHeightOverride = 4096;
+ public virtual int maxAtlasHeightOverride
+ {
+ get { return _maxAtlasHeightOverride; }
+ set { _maxAtlasHeightOverride = value; }
+ }
+
+ [SerializeField]
+ protected bool _resizePowerOfTwoTextures = false;
+ public virtual bool resizePowerOfTwoTextures
+ {
+ get { return _resizePowerOfTwoTextures; }
+ set { _resizePowerOfTwoTextures = value; }
+ }
+
+ [SerializeField]
+ protected bool _fixOutOfBoundsUVs = false; //is considerMeshUVs but can't change because it would break all existing bakers
+ public virtual bool fixOutOfBoundsUVs
+ {
+ get { return _fixOutOfBoundsUVs; }
+ set { _fixOutOfBoundsUVs = value; }
+ }
+
+ [SerializeField]
+ protected int _maxTilingBakeSize = 1024;
+ public virtual int maxTilingBakeSize
+ {
+ get { return _maxTilingBakeSize; }
+ set { _maxTilingBakeSize = value; }
+ }
+
+ [SerializeField]
+ protected MB2_PackingAlgorithmEnum _packingAlgorithm = MB2_PackingAlgorithmEnum.MeshBakerTexturePacker;
+ public virtual MB2_PackingAlgorithmEnum packingAlgorithm
+ {
+ get { return _packingAlgorithm; }
+ set { _packingAlgorithm = value; }
+ }
+
+ [SerializeField]
+ protected int _layerTexturePackerFastMesh = -1;
+ public virtual int layerForTexturePackerFastMesh
+ {
+ get { return _layerTexturePackerFastMesh; }
+ set { _layerTexturePackerFastMesh = value; }
+ }
+
+ [SerializeField]
+ protected bool _meshBakerTexturePackerForcePowerOfTwo = true;
+ public bool meshBakerTexturePackerForcePowerOfTwo
+ {
+ get { return _meshBakerTexturePackerForcePowerOfTwo; }
+ set { _meshBakerTexturePackerForcePowerOfTwo = value; }
+ }
+
+ [SerializeField]
+ protected List<ShaderTextureProperty> _customShaderProperties = new List<ShaderTextureProperty>();
+ public virtual List<ShaderTextureProperty> customShaderProperties
+ {
+ get { return _customShaderProperties; }
+ set { _customShaderProperties = value; }
+ }
+
+ //this is depricated
+ [SerializeField]
+ protected List<string> _customShaderPropNames_Depricated = new List<string>();
+ public virtual List<string> customShaderPropNames
+ {
+ get { return _customShaderPropNames_Depricated; }
+ set { _customShaderPropNames_Depricated = value; }
+ }
+
+ [SerializeField]
+ protected MB2_TextureBakeResults.ResultType _resultType;
+ public virtual MB2_TextureBakeResults.ResultType resultType
+ {
+ get { return _resultType; }
+ set { _resultType = value; }
+ }
+
+ [SerializeField]
+ protected bool _doMultiMaterial;
+ public virtual bool doMultiMaterial
+ {
+ get { return _doMultiMaterial; }
+ set { _doMultiMaterial = value; }
+ }
+
+ [SerializeField]
+ protected bool _doMultiMaterialSplitAtlasesIfTooBig = true;
+ public virtual bool doMultiMaterialSplitAtlasesIfTooBig
+ {
+ get { return _doMultiMaterialSplitAtlasesIfTooBig; }
+ set { _doMultiMaterialSplitAtlasesIfTooBig = value; }
+ }
+
+ [SerializeField]
+ protected bool _doMultiMaterialSplitAtlasesIfOBUVs = true;
+ public virtual bool doMultiMaterialSplitAtlasesIfOBUVs
+ {
+ get { return _doMultiMaterialSplitAtlasesIfOBUVs; }
+ set { _doMultiMaterialSplitAtlasesIfOBUVs = value; }
+ }
+
+ [SerializeField]
+ protected Material _resultMaterial;
+ public virtual Material resultMaterial
+ {
+ get { return _resultMaterial; }
+ set { _resultMaterial = value; }
+ }
+
+ [SerializeField]
+ protected bool _considerNonTextureProperties = false;
+ public bool considerNonTextureProperties
+ {
+ get { return _considerNonTextureProperties; }
+ set { _considerNonTextureProperties = value; }
+ }
+
+ [SerializeField]
+ protected bool _doSuggestTreatment = true;
+ public bool doSuggestTreatment
+ {
+ get { return _doSuggestTreatment; }
+ set { _doSuggestTreatment = value; }
+ }
+
+ private MB3_TextureCombiner.CreateAtlasesCoroutineResult _coroutineResult;
+ public MB3_TextureCombiner.CreateAtlasesCoroutineResult CoroutineResult
+ {
+ get
+ {
+ return _coroutineResult;
+ }
+ }
+
+ public MB_MultiMaterial[] resultMaterials = new MB_MultiMaterial[0];
+
+ public MB_MultiMaterialTexArray[] resultMaterialsTexArray = new MB_MultiMaterialTexArray[0];
+
+ public MB_TextureArrayFormatSet[] textureArrayOutputFormats;
+
+ public List<GameObject> objsToMesh; //todo make this Renderer
+
+ public override List<GameObject> GetObjectsToCombine()
+ {
+ if (objsToMesh == null) objsToMesh = new List<GameObject>();
+ return objsToMesh;
+ }
+
+ public MB_AtlasesAndRects[] CreateAtlases()
+ {
+ return CreateAtlases(null, false, null);
+ }
+
+ public delegate void OnCombinedTexturesCoroutineSuccess();
+ public delegate void OnCombinedTexturesCoroutineFail();
+ public OnCombinedTexturesCoroutineSuccess onBuiltAtlasesSuccess;
+ public OnCombinedTexturesCoroutineFail onBuiltAtlasesFail;
+ public MB_AtlasesAndRects[] OnCombinedTexturesCoroutineAtlasesAndRects;
+
+ public IEnumerator CreateAtlasesCoroutine(ProgressUpdateDelegate progressInfo, MB3_TextureCombiner.CreateAtlasesCoroutineResult coroutineResult, bool saveAtlasesAsAssets = false, MB2_EditorMethodsInterface editorMethods = null, float maxTimePerFrame = .01f)
+ {
+ yield return _CreateAtlasesCoroutine(progressInfo, coroutineResult, saveAtlasesAsAssets, editorMethods, maxTimePerFrame);
+
+ if (coroutineResult.success && onBuiltAtlasesSuccess != null)
+ {
+ onBuiltAtlasesSuccess();
+ }
+
+ if (!coroutineResult.success && onBuiltAtlasesFail != null)
+ {
+ onBuiltAtlasesFail();
+ }
+ }
+
+ private IEnumerator _CreateAtlasesCoroutineAtlases(MB3_TextureCombiner combiner, ProgressUpdateDelegate progressInfo, MB3_TextureCombiner.CreateAtlasesCoroutineResult coroutineResult, bool saveAtlasesAsAssets = false, MB2_EditorMethodsInterface editorMethods = null, float maxTimePerFrame = .01f)
+ {
+ int numResults = 1;
+ if (_doMultiMaterial)
+ {
+ numResults = resultMaterials.Length;
+ }
+
+ OnCombinedTexturesCoroutineAtlasesAndRects = new MB_AtlasesAndRects[numResults];
+ for (int i = 0; i < OnCombinedTexturesCoroutineAtlasesAndRects.Length; i++)
+ {
+ OnCombinedTexturesCoroutineAtlasesAndRects[i] = new MB_AtlasesAndRects();
+ }
+
+ //Do the material combining.
+ for (int i = 0; i < OnCombinedTexturesCoroutineAtlasesAndRects.Length; i++)
+ {
+ Material resMatToPass = null;
+ List<Material> sourceMats = null;
+ if (_doMultiMaterial)
+ {
+ sourceMats = resultMaterials[i].sourceMaterials;
+ resMatToPass = resultMaterials[i].combinedMaterial;
+ combiner.fixOutOfBoundsUVs = resultMaterials[i].considerMeshUVs;
+ }
+ else
+ {
+ resMatToPass = _resultMaterial;
+ }
+
+ MB3_TextureCombiner.CombineTexturesIntoAtlasesCoroutineResult coroutineResult2 = new MB3_TextureCombiner.CombineTexturesIntoAtlasesCoroutineResult();
+ yield return combiner.CombineTexturesIntoAtlasesCoroutine(progressInfo, OnCombinedTexturesCoroutineAtlasesAndRects[i], resMatToPass, objsToMesh, sourceMats, editorMethods, coroutineResult2, maxTimePerFrame,
+ onlyPackRects: false, splitAtlasWhenPackingIfTooBig: false);
+ coroutineResult.success = coroutineResult2.success;
+ if (!coroutineResult.success)
+ {
+ coroutineResult.isFinished = true;
+ yield break;
+ }
+ }
+
+ unpackMat2RectMap(OnCombinedTexturesCoroutineAtlasesAndRects);
+ //Save the results
+ textureBakeResults.resultType = MB2_TextureBakeResults.ResultType.atlas;
+ textureBakeResults.resultMaterialsTexArray = new MB_MultiMaterialTexArray[0];
+ textureBakeResults.doMultiMaterial = _doMultiMaterial;
+ if (_doMultiMaterial)
+ {
+ textureBakeResults.resultMaterials = resultMaterials;
+ }
+ else
+ {
+ MB_MultiMaterial[] resMats = new MB_MultiMaterial[1];
+ resMats[0] = new MB_MultiMaterial();
+ resMats[0].combinedMaterial = _resultMaterial;
+ resMats[0].considerMeshUVs = _fixOutOfBoundsUVs;
+ resMats[0].sourceMaterials = new List<Material>();
+ for (int i = 0; i < textureBakeResults.materialsAndUVRects.Length; i++)
+ {
+ resMats[0].sourceMaterials.Add(textureBakeResults.materialsAndUVRects[i].material);
+ }
+ textureBakeResults.resultMaterials = resMats;
+ }
+
+ if (LOG_LEVEL >= MB2_LogLevel.info) Debug.Log("Created Atlases");
+ }
+
+ internal IEnumerator _CreateAtlasesCoroutineTextureArray(MB3_TextureCombiner combiner, ProgressUpdateDelegate progressInfo, MB3_TextureCombiner.CreateAtlasesCoroutineResult coroutineResult, bool saveAtlasesAsAssets = false, MB2_EditorMethodsInterface editorMethods = null, float maxTimePerFrame = .01f)
+ {
+ MB_TextureArrayResultMaterial[] bakedMatsAndSlices = null;
+
+ // Validate the formats
+ if (textureArrayOutputFormats == null || textureArrayOutputFormats.Length == 0)
+ {
+ Debug.LogError("No Texture Array Output Formats. There must be at least one entry.");
+ coroutineResult.isFinished = true;
+ yield break;
+ }
+
+ for (int i = 0; i < textureArrayOutputFormats.Length; i++)
+ {
+ if (!textureArrayOutputFormats[i].ValidateTextureImporterFormatsExistsForTextureFormats(editorMethods, i))
+ {
+ Debug.LogError("Could not map the selected texture format to a Texture Importer Format. Safest options are ARGB32, or RGB24.");
+ coroutineResult.isFinished = true;
+ yield break;
+ }
+ }
+
+ for (int resMatIdx = 0; resMatIdx < resultMaterialsTexArray.Length; resMatIdx++)
+ {
+ MB_MultiMaterialTexArray textureArraySliceConfig = resultMaterialsTexArray[resMatIdx];
+ if (textureArraySliceConfig.combinedMaterial == null)
+ {
+ Debug.LogError("Material is null for Texture Array Slice Configuration: " + resMatIdx + ".");
+ coroutineResult.isFinished = true;
+ yield break;
+ }
+
+
+ List<MB_TexArraySlice> slices = textureArraySliceConfig.slices;
+ for (int sliceIdx = 0; sliceIdx < slices.Count; sliceIdx++)
+ {
+ for (int srcMatIdx = 0; srcMatIdx < slices[sliceIdx].sourceMaterials.Count; srcMatIdx++)
+ {
+ MB_TexArraySliceRendererMatPair sourceMat = slices[sliceIdx].sourceMaterials[srcMatIdx];
+ if (sourceMat.sourceMaterial == null)
+ {
+ Debug.LogError("Source material is null for Texture Array Slice Configuration: " + resMatIdx + " slice: " + sliceIdx);
+ coroutineResult.isFinished = true;
+ yield break;
+ }
+
+ if (slices[sliceIdx].considerMeshUVs)
+ {
+ if (sourceMat.renderer == null)
+ {
+ Debug.LogError("Renderer is null for Texture Array Slice Configuration: " + resMatIdx + " slice: " + sliceIdx + ". If considerUVs is enabled then a renderer must be supplied for each source material. The same source material can be used multiple times.");
+ coroutineResult.isFinished = true;
+ yield break;
+ }
+ }
+ else
+ {
+ // TODO check for duplicate source mats.
+ }
+ }
+ }
+ }
+
+ // initialize structure to store results. For texture arrays the structure is two layers deep.
+ // First layer is resultMaterial / submesh (each result material can use a different shader)
+ // Second layer is a set of TextureArrays for the TextureProperties on that result material.
+ int numResultMats = resultMaterialsTexArray.Length;
+ bakedMatsAndSlices = new MB_TextureArrayResultMaterial[numResultMats];
+ for (int resMatIdx = 0; resMatIdx < bakedMatsAndSlices.Length; resMatIdx++)
+ {
+ bakedMatsAndSlices[resMatIdx] = new MB_TextureArrayResultMaterial();
+ int numSlices = resultMaterialsTexArray[resMatIdx].slices.Count;
+ MB_AtlasesAndRects[] slices = bakedMatsAndSlices[resMatIdx].slices = new MB_AtlasesAndRects[numSlices];
+ for (int j = 0; j < numSlices; j++) slices[j] = new MB_AtlasesAndRects();
+ }
+
+ // Some of the slices will be atlases (more than one atlas per slice).
+ // Do the material combining for these. First loop over the result materials (1 per submeshes).
+ for (int resMatIdx = 0; resMatIdx < bakedMatsAndSlices.Length; resMatIdx++)
+ {
+ yield return MB_TextureArrays._CreateAtlasesCoroutineSingleResultMaterial(resMatIdx, bakedMatsAndSlices[resMatIdx], resultMaterialsTexArray[resMatIdx],
+ objsToMesh,
+ combiner,
+ textureArrayOutputFormats,
+ resultMaterialsTexArray,
+ customShaderProperties,
+ progressInfo, coroutineResult, saveAtlasesAsAssets, editorMethods, maxTimePerFrame);
+ if (!coroutineResult.success) yield break;
+ }
+
+ if (coroutineResult.success)
+ {
+ // Save the results into the TextureBakeResults.
+ unpackMat2RectMap(bakedMatsAndSlices);
+ textureBakeResults.resultType = MB2_TextureBakeResults.ResultType.textureArray;
+ textureBakeResults.resultMaterials = new MB_MultiMaterial[0];
+ textureBakeResults.resultMaterialsTexArray = resultMaterialsTexArray;
+ if (LOG_LEVEL >= MB2_LogLevel.info) Debug.Log("Created Texture2DArrays");
+ }
+ else
+ {
+ if (LOG_LEVEL >= MB2_LogLevel.info) Debug.Log("Failed to create Texture2DArrays");
+ }
+ }
+
+ private IEnumerator _CreateAtlasesCoroutine(ProgressUpdateDelegate progressInfo, MB3_TextureCombiner.CreateAtlasesCoroutineResult coroutineResult, bool saveAtlasesAsAssets = false, MB2_EditorMethodsInterface editorMethods = null, float maxTimePerFrame = .01f)
+ {
+ MBVersionConcrete mbv = new MBVersionConcrete();
+ if (!MB3_TextureCombiner._RunCorutineWithoutPauseIsRunning && (mbv.GetMajorVersion() < 5 || (mbv.GetMajorVersion() == 5 && mbv.GetMinorVersion() < 3)))
+ {
+ Debug.LogError("Running the texture combiner as a coroutine only works in Unity 5.3 and higher");
+ coroutineResult.success = false;
+ yield break;
+ }
+ this.OnCombinedTexturesCoroutineAtlasesAndRects = null;
+
+ if (maxTimePerFrame <= 0f)
+ {
+ Debug.LogError("maxTimePerFrame must be a value greater than zero");
+ coroutineResult.isFinished = true;
+ yield break;
+ }
+ MB2_ValidationLevel vl = Application.isPlaying ? MB2_ValidationLevel.quick : MB2_ValidationLevel.robust;
+ if (!DoCombinedValidate(this, MB_ObjsToCombineTypes.dontCare, null, vl))
+ {
+ coroutineResult.isFinished = true;
+ yield break;
+ }
+ if (_doMultiMaterial && !_ValidateResultMaterials())
+ {
+ coroutineResult.isFinished = true;
+ yield break;
+ }
+ else if (resultType == MB2_TextureBakeResults.ResultType.textureArray)
+ {
+ //TODO validate texture arrays.
+ }
+ else if (!_doMultiMaterial)
+ {
+ if (_resultMaterial == null)
+ {
+ Debug.LogError("Combined Material is null please create and assign a result material.");
+ coroutineResult.isFinished = true;
+ yield break;
+ }
+ Shader targShader = _resultMaterial.shader;
+ for (int i = 0; i < objsToMesh.Count; i++)
+ {
+ Material[] ms = MB_Utility.GetGOMaterials(objsToMesh[i]);
+ for (int j = 0; j < ms.Length; j++)
+ {
+ Material m = ms[j];
+ if (m != null && m.shader != targShader)
+ {
+ Debug.LogWarning("Game object " + objsToMesh[i] + " does not use shader " + targShader + " it may not have the required textures. If not small solid color textures will be generated.");
+ }
+
+ }
+ }
+ }
+
+ MB3_TextureCombiner combiner = CreateAndConfigureTextureCombiner();
+ combiner.saveAtlasesAsAssets = saveAtlasesAsAssets;
+
+ OnCombinedTexturesCoroutineAtlasesAndRects = null;
+ if (resultType == MB2_TextureBakeResults.ResultType.textureArray)
+ {
+ yield return _CreateAtlasesCoroutineTextureArray(combiner, progressInfo, coroutineResult, saveAtlasesAsAssets, editorMethods, maxTimePerFrame);
+ if (!coroutineResult.success) yield break;
+ }
+ else
+ {
+ yield return _CreateAtlasesCoroutineAtlases(combiner, progressInfo, coroutineResult, saveAtlasesAsAssets, editorMethods, maxTimePerFrame);
+ if (!coroutineResult.success) yield break;
+ }
+
+ //set the texture bake resultAtlasesAndRects on the Mesh Baker component if it exists
+ MB3_MeshBakerCommon[] mb = GetComponentsInChildren<MB3_MeshBakerCommon>();
+ for (int i = 0; i < mb.Length; i++)
+ {
+ mb[i].textureBakeResults = textureBakeResults;
+ }
+
+ coroutineResult.isFinished = true;
+ }
+
+ /// <summary>
+ /// Creates the atlases.
+ /// </summary>
+ /// <returns>
+ /// The atlases.
+ /// </returns>
+ /// <param name='progressInfo'>
+ /// Progress info is a delegate function that displays a progress dialog. Can be null
+ /// </param>
+ /// <param name='saveAtlasesAsAssets'>
+ /// if true atlases are saved as assets in the project folder. Othersise they are instances in memory
+ /// </param>
+ /// <param name='editorMethods'>
+ /// Texture format tracker. Contains editor functionality such as save assets. Can be null.
+ /// </param>
+ public MB_AtlasesAndRects[] CreateAtlases(ProgressUpdateDelegate progressInfo, bool saveAtlasesAsAssets = false, MB2_EditorMethodsInterface editorMethods = null)
+ {
+ MB_AtlasesAndRects[] mAndAs = null;
+
+ try
+ {
+ _coroutineResult = new MB3_TextureCombiner.CreateAtlasesCoroutineResult();
+ MB3_TextureCombiner.RunCorutineWithoutPause(CreateAtlasesCoroutine(progressInfo, _coroutineResult, saveAtlasesAsAssets, editorMethods, 1000f), 0);
+ if (_coroutineResult.success && textureBakeResults != null)
+ {
+ mAndAs = this.OnCombinedTexturesCoroutineAtlasesAndRects;
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.LogError(ex.Message + "\n" + ex.StackTrace.ToString());
+ }
+ finally
+ {
+ if (saveAtlasesAsAssets)
+ { //Atlases were saved to project so we don't need these ones
+ if (mAndAs != null)
+ {
+ for (int j = 0; j < mAndAs.Length; j++)
+ {
+ MB_AtlasesAndRects mAndA = mAndAs[j];
+ if (mAndA != null && mAndA.atlases != null)
+ {
+ for (int i = 0; i < mAndA.atlases.Length; i++)
+ {
+ if (mAndA.atlases[i] != null)
+ {
+ if (editorMethods != null) editorMethods.Destroy(mAndA.atlases[i]);
+ else MB_Utility.Destroy(mAndA.atlases[i]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return mAndAs;
+ }
+
+ void unpackMat2RectMap(MB_AtlasesAndRects[] rawResults)
+ {
+ List<MB_MaterialAndUVRect> mss = new List<MB_MaterialAndUVRect>();
+ for (int i = 0; i < rawResults.Length; i++)
+ {
+ List<MB_MaterialAndUVRect> map = rawResults[i].mat2rect_map;
+ if (map != null)
+ {
+ for (int j = 0; j < map.Count; j++)
+ {
+ map[j].textureArraySliceIdx = -1;
+ mss.Add(map[j]);
+ }
+ }
+ }
+
+ textureBakeResults.version = MB2_TextureBakeResults.VERSION;
+ textureBakeResults.materialsAndUVRects = mss.ToArray();
+ }
+
+ internal void unpackMat2RectMap(MB_TextureArrayResultMaterial[] rawResults)
+ {
+ List<MB_MaterialAndUVRect> mss = new List<MB_MaterialAndUVRect>();
+ for (int resMatIdx = 0; resMatIdx < rawResults.Length; resMatIdx++)
+ {
+ MB_AtlasesAndRects[] slices = rawResults[resMatIdx].slices;
+ for (int sliceIdx = 0; sliceIdx < slices.Length; sliceIdx++)
+ {
+ List<MB_MaterialAndUVRect> map = slices[sliceIdx].mat2rect_map;
+ if (map != null)
+ {
+ for (int rectIdx = 0; rectIdx < map.Count; rectIdx++)
+ {
+ map[rectIdx].textureArraySliceIdx = sliceIdx;
+ mss.Add(map[rectIdx]);
+ }
+ }
+ }
+ }
+
+ textureBakeResults.version = MB2_TextureBakeResults.VERSION;
+ textureBakeResults.materialsAndUVRects = mss.ToArray();
+ }
+
+ public MB3_TextureCombiner CreateAndConfigureTextureCombiner()
+ {
+ MB3_TextureCombiner combiner = new MB3_TextureCombiner();
+ combiner.LOG_LEVEL = LOG_LEVEL;
+ combiner.atlasPadding = _atlasPadding;
+ combiner.maxAtlasSize = _maxAtlasSize;
+ combiner.maxAtlasHeightOverride = _maxAtlasHeightOverride;
+ combiner.maxAtlasWidthOverride = _maxAtlasWidthOverride;
+ combiner.useMaxAtlasHeightOverride = _useMaxAtlasHeightOverride;
+ combiner.useMaxAtlasWidthOverride = _useMaxAtlasWidthOverride;
+ combiner.customShaderPropNames = _customShaderProperties;
+ combiner.fixOutOfBoundsUVs = _fixOutOfBoundsUVs;
+ combiner.maxTilingBakeSize = _maxTilingBakeSize;
+ combiner.packingAlgorithm = _packingAlgorithm;
+ combiner.layerTexturePackerFastMesh = _layerTexturePackerFastMesh;
+ combiner.resultType = _resultType;
+ combiner.meshBakerTexturePackerForcePowerOfTwo = _meshBakerTexturePackerForcePowerOfTwo;
+ combiner.resizePowerOfTwoTextures = _resizePowerOfTwoTextures;
+ combiner.considerNonTextureProperties = _considerNonTextureProperties;
+ return combiner;
+ }
+
+ public static void ConfigureNewMaterialToMatchOld(Material newMat, Material original)
+ {
+ if (original == null)
+ {
+ Debug.LogWarning("Original material is null, could not copy properties to " + newMat + ". Setting shader to " + newMat.shader);
+ return;
+ }
+ newMat.shader = original.shader;
+ newMat.CopyPropertiesFromMaterial(original);
+ ShaderTextureProperty[] texPropertyNames = MB3_TextureCombinerPipeline.shaderTexPropertyNames;
+ for (int j = 0; j < texPropertyNames.Length; j++)
+ {
+ Vector2 scale = Vector2.one;
+ Vector2 offset = Vector2.zero;
+ if (newMat.HasProperty(texPropertyNames[j].name))
+ {
+ newMat.SetTextureOffset(texPropertyNames[j].name, offset);
+ newMat.SetTextureScale(texPropertyNames[j].name, scale);
+ }
+ }
+ }
+
+ string PrintSet(HashSet<Material> s)
+ {
+ StringBuilder sb = new StringBuilder();
+ foreach (Material m in s)
+ {
+ sb.Append(m + ",");
+ }
+ return sb.ToString();
+ }
+
+ bool _ValidateResultMaterials()
+ {
+ HashSet<Material> allMatsOnObjs = new HashSet<Material>();
+ for (int i = 0; i < objsToMesh.Count; i++)
+ {
+ if (objsToMesh[i] != null)
+ {
+ Material[] ms = MB_Utility.GetGOMaterials(objsToMesh[i]);
+ for (int j = 0; j < ms.Length; j++)
+ {
+ if (ms[j] != null) allMatsOnObjs.Add(ms[j]);
+ }
+ }
+ }
+
+ if (resultMaterials.Length < 1)
+ {
+ Debug.LogError("Using multiple materials but there are no 'Source Material To Combined Mappings'. You need at least one.");
+ }
+
+ HashSet<Material> allMatsInMapping = new HashSet<Material>();
+ for (int i = 0; i < resultMaterials.Length; i++)
+ {
+ for (int j = i + 1; j < resultMaterials.Length; j++)
+ {
+ if (resultMaterials[i].combinedMaterial == resultMaterials[j].combinedMaterial)
+ {
+ Debug.LogError(String.Format("Source To Combined Mapping: Submesh {0} and Submesh {1} use the same combined material. These should be different", i, j));
+ return false;
+ }
+ }
+
+ MB_MultiMaterial mm = resultMaterials[i];
+ if (mm.combinedMaterial == null)
+ {
+ Debug.LogError("Combined Material is null please create and assign a result material.");
+ return false;
+ }
+ Shader targShader = mm.combinedMaterial.shader;
+ for (int j = 0; j < mm.sourceMaterials.Count; j++)
+ {
+ if (mm.sourceMaterials[j] == null)
+ {
+ Debug.LogError("There are null entries in the list of Source Materials");
+ return false;
+ }
+ if (targShader != mm.sourceMaterials[j].shader)
+ {
+ Debug.LogWarning("Source material " + mm.sourceMaterials[j] + " does not use shader " + targShader + " it may not have the required textures. If not empty textures will be generated.");
+ }
+ if (allMatsInMapping.Contains(mm.sourceMaterials[j]))
+ {
+ Debug.LogError("A Material " + mm.sourceMaterials[j] + " appears more than once in the list of source materials in the source material to combined mapping. Each source material must be unique.");
+ return false;
+ }
+ allMatsInMapping.Add(mm.sourceMaterials[j]);
+ }
+ }
+
+ if (allMatsOnObjs.IsProperSubsetOf(allMatsInMapping))
+ {
+ allMatsInMapping.ExceptWith(allMatsOnObjs);
+ Debug.LogWarning("There are materials in the mapping that are not used on your source objects: " + PrintSet(allMatsInMapping));
+ }
+ if (resultMaterials != null && resultMaterials.Length > 0 && allMatsInMapping.IsProperSubsetOf(allMatsOnObjs))
+ {
+ allMatsOnObjs.ExceptWith(allMatsInMapping);
+ Debug.LogError("There are materials on the objects to combine that are not in the mapping: " + PrintSet(allMatsOnObjs));
+ return false;
+ }
+ return true;
+ }
+}
+