public 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()); if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("Only one image per atlas. Will re-use original texture"); } for (int i = 0; i < data.numAtlases; i++) { MeshBakerMaterialTexture dmt = data.distinctMaterialTextures[0].ts[i]; atlases[i] = dmt.GetTexture2D(); if (data.resultType == MB2_TextureBakeResults.ResultType.atlas) { data.resultMaterial.SetTexture(data.texPropertyNames[i].name, atlases[i]); data.resultMaterial.SetTextureScale(data.texPropertyNames[i].name, Vector2.one); data.resultMaterial.SetTextureOffset(data.texPropertyNames[i].name, Vector2.zero); } } yield break; }
public static void Log(MB2_LogLevel l, String msg, MB2_LogLevel currentThreshold) { if (l <= currentThreshold) { if (l == MB2_LogLevel.error) { Debug.LogError(msg); } if (l == MB2_LogLevel.warn) { Debug.LogWarning(String.Format("frm={0} WARN {1}", Time.frameCount, msg)); } if (l == MB2_LogLevel.info) { Debug.Log(String.Format("frm={0} INFO {1}", Time.frameCount, msg)); } if (l == MB2_LogLevel.debug) { Debug.Log(String.Format("frm={0} DEBUG {1}", Time.frameCount, msg)); } if (l == MB2_LogLevel.trace) { Debug.Log(String.Format("frm={0} TRACE {1}", Time.frameCount, msg)); } } }
public Vector2[] GetMeshUV1s(Mesh m, MB2_LogLevel LOG_LEVEL) { if (LOG_LEVEL >= MB2_LogLevel.warn) { MB2_Log.LogDebug("UV1 does not exist in Unity 5+", new object[0]); } Vector2[] array = m.uv; if (array.Length == 0) { if (LOG_LEVEL >= MB2_LogLevel.debug) { MB2_Log.LogDebug("Mesh " + m + " has no uv1s. Generating", new object[0]); } if (LOG_LEVEL >= MB2_LogLevel.warn) { Debug.LogWarning("Mesh " + m + " didn't have uv1s. Generating uv1s."); } array = new Vector2[m.vertexCount]; for (int i = 0; i < array.Length; i++) { array[i] = this._HALF_UV; } } return(array); }
public Vector2[] GetMeshUV3orUV4(Mesh m, bool get3, MB2_LogLevel LOG_LEVEL) { Vector2[] array; if (get3) { array = m.uv3; } else { array = m.uv4; } if (array.Length == 0) { if (LOG_LEVEL >= MB2_LogLevel.debug) { MB2_Log.LogDebug(string.Concat(new object[] { "Mesh ", m, " has no uv", (!get3) ? "4" : "3", ". Generating" }), new object[0]); } array = new Vector2[m.vertexCount]; for (int i = 0; i < array.Length; i++) { array[i] = this._HALF_UV; } } return(array); }
public Vector2[] GetMeshUV3orUV4(Mesh m, bool get3, MB2_LogLevel LOG_LEVEL) { Vector2[] uvs; #if (UNITY_4_6 || UNITY_4_7 || UNITY_4_5 || UNITY_4_3 || UNITY_4_2 || UNITY_4_1 || UNITY_4_0_1 || UNITY_4_0 || UNITY_3_5) if (LOG_LEVEL >= MB2_LogLevel.warn) { MB2_Log.LogDebug("UV3 and UV4 do not exist in Unity 4"); } uvs = m.uv; #else if (get3) { uvs = m.uv3; } else { uvs = m.uv4; } #endif if (uvs.Length == 0) { if (LOG_LEVEL >= MB2_LogLevel.debug) { MB2_Log.LogDebug("Mesh " + m + " has no uv" + (get3 ? "3" : "4") + ". Generating"); } uvs = new Vector2[m.vertexCount]; for (int i = 0; i < uvs.Length; i++) { uvs[i] = _HALF_UV; } } return(uvs); }
public Vector2[] GetMeshUV1s(Mesh m, MB2_LogLevel LOG_LEVEL) { Vector2[] uv; #if (UNITY_4_6 || UNITY_4_7 || UNITY_4_5 || UNITY_4_3 || UNITY_4_2 || UNITY_4_1 || UNITY_4_0_1 || UNITY_4_0 || UNITY_3_5) uv = m.uv1; #else if (LOG_LEVEL >= MB2_LogLevel.warn) { MB2_Log.LogDebug("UV1 does not exist in Unity 5+"); } uv = m.uv; #endif if (uv.Length == 0) { if (LOG_LEVEL >= MB2_LogLevel.debug) { MB2_Log.LogDebug("Mesh " + m + " has no uv1s. Generating"); } if (LOG_LEVEL >= MB2_LogLevel.warn) { Debug.LogWarning("Mesh " + m + " didn't have uv1s. Generating uv1s."); } uv = new Vector2[m.vertexCount]; for (int i = 0; i < uv.Length; i++) { uv[i] = _HALF_UV; } } return(uv); }
public static void Log(MB2_LogLevel l, string msg, MB2_LogLevel currentThreshold) { if (l <= currentThreshold) { if (l == MB2_LogLevel.error) { Debug.LogError(msg); } if (l == MB2_LogLevel.warn) { Debug.LogWarning(string.Format("frm={0} WARN {1}", Time.frameCount, msg)); } if (l == MB2_LogLevel.info) { Debug.Log(string.Format("frm={0} INFO {1}", Time.frameCount, msg)); } if (l == MB2_LogLevel.debug) { Debug.Log(string.Format("frm={0} DEBUG {1}", Time.frameCount, msg)); } if (l == MB2_LogLevel.trace) { Debug.Log(string.Format("frm={0} TRACE {1}", Time.frameCount, msg)); } } }
public void RunTestHarness() { int numTex = 32; int min = 126; int max = 2046; //txs[0] = new Image(0,5,800); //txs[1] = new Image(1,5,5000); List <Vector2> imgsToAdd = new List <Vector2>(); for (int i = 0; i < numTex; i++) { imgsToAdd.Add(new Vector2(UnityEngine.Random.Range(min, max), UnityEngine.Random.Range(min, max) * 5)); } doPowerOfTwoTextures = true; LOG_LEVEL = MB2_LogLevel.trace; // imgsToAdd.Add(new Vector2(2046,900)); // imgsToAdd.Add(new Vector2(2046,900)); // imgsToAdd.Add(new Vector2(2,2)); // imgsToAdd.Add(new Vector2(2,2)); int padding = 1; int w; int h; GetRects(imgsToAdd, 4096, padding, out w, out h); }
public MB3_TextureCombinerMerging(bool considerNonTextureProps, MB3_TextureCombinerNonTextureProperties resultMaterialTexBlender, bool fixObUVs, MB2_LogLevel logLevel) { LOG_LEVEL = logLevel; _considerNonTextureProperties = considerNonTextureProps; resultMaterialTextureBlender = resultMaterialTexBlender; fixOutOfBoundsUVs = fixObUVs; }
public virtual IEnumerator ConvertTexturesToReadableFormats(ProgressUpdateDelegate progressInfo, MB3_TextureCombiner.CombineTexturesIntoAtlasesCoroutineResult result, MB3_TextureCombinerPipeline.TexturePipelineData data, MB3_TextureCombiner combiner, MB2_EditorMethodsInterface textureEditorMethods, MB2_LogLevel LOG_LEVEL) { Debug.Assert(!data.OnlyOneTextureInAtlasReuseTextures()); //MakeProceduralTexturesReadable(progressInfo, result, data, combiner, textureEditorMethods, LOG_LEVEL); for (int i = 0; i < data.distinctMaterialTextures.Count; i++) { for (int j = 0; j < data.texPropertyNames.Count; j++) { MeshBakerMaterialTexture ts = data.distinctMaterialTextures[i].ts[j]; if (!ts.isNull) { if (textureEditorMethods != null) { Texture tx = ts.GetTexture2D(); TextureFormat format = TextureFormat.ARGB32; if (progressInfo != null) { progressInfo(String.Format("Convert texture {0} to readable format ", tx), .5f); } textureEditorMethods.AddTextureFormat((Texture2D)tx, format, data.texPropertyNames[j].isNormalMap); } } } } yield break; }
public Vector2[] GetMeshUVChannel(int channel, Mesh m, MB2_LogLevel LOG_LEVEL) { Vector2[] uvs = new Vector2[0]; switch (channel) { case 0: uvs = m.uv; break; case 2: uvs = m.uv2; break; case 3: uvs = m.uv3; break; case 4: uvs = m.uv4; break; #if UNITY_2018_2_OR_NEWER case 5: uvs = m.uv5; break; case 6: uvs = m.uv6; break; case 7: uvs = m.uv7; break; case 8: uvs = m.uv8; break; #endif default: Debug.LogError("Mesh does not have UV channel " + channel); break; } if (uvs.Length == 0) { if (LOG_LEVEL >= MB2_LogLevel.debug) { MB2_Log.LogDebug("Mesh " + m + " has no uv" + channel + ". Generating"); } uvs = new Vector2[m.vertexCount]; for (int i = 0; i < uvs.Length; i++) { uvs[i] = _HALF_UV; } } return(uvs); }
public static Vector2[] GetMeshChannel(int channel, Mesh m, MB2_LogLevel LOG_LEVEL) { if (_MBVersion == null) { _MBVersion = _CreateMBVersionConcrete(); } return(_MBVersion.GetMeshUVChannel(channel, m, LOG_LEVEL)); }
public static Vector2[] GetMeshUV1s(Mesh m, MB2_LogLevel LOG_LEVEL) { if (_MBVersion == null) { _MBVersion = _CreateMBVersionConcrete(); } return(_MBVersion.GetMeshUV1s(m, LOG_LEVEL)); }
public static Vector2[] GetMeshUV1s(Mesh m, MB2_LogLevel LOG_LEVEL) { if (_MBVersion == null) { _MBVersion = (MBVersionInterface)Activator.CreateInstance(Type.GetType("DigitalOpus.MB.Core.MBVersionConcrete,Assembly-CSharp")); } return(_MBVersion.GetMeshUV1s(m, LOG_LEVEL)); }
public static Vector2[] GetMeshUV3orUV4(Mesh m, bool get3, MB2_LogLevel LOG_LEVEL) { if (_MBVersion == null) { _MBVersion = _CreateMBVersionConcrete(); } return(_MBVersion.GetMeshUV3orUV4(m, get3, LOG_LEVEL)); }
public Texture2D DoRenderAtlas(GameObject gameObject, int width, int height, int padding, Rect[] rss, List <MB3_TextureCombiner.MB_TexSet> textureSetss, int indexOfTexSetToRenders, bool isNormalMap, bool fixOutOfBoundsUVs, MB3_TextureCombiner texCombiner, MB2_LogLevel LOG_LEV) { this.LOG_LEVEL = LOG_LEV; this.textureSets = textureSetss; this.indexOfTexSetToRender = indexOfTexSetToRenders; this._padding = padding; this._isNormalMap = isNormalMap; this._fixOutOfBoundsUVs = fixOutOfBoundsUVs; this.combiner = texCombiner; this.rs = rss; Shader shader; if (this._isNormalMap) { shader = Shader.Find("MeshBaker/NormalMapShader"); } else { shader = Shader.Find("MeshBaker/AlbedoShader"); } if (shader == null) { UnityEngine.Debug.LogError("Could not find shader for RenderTexture. Try reimporting mesh baker"); return(null); } this.mat = new Material(shader); this._destinationTexture = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32); this._destinationTexture.filterMode = FilterMode.Point; this.myCamera = gameObject.GetComponent <Camera>(); this.myCamera.orthographic = true; this.myCamera.orthographicSize = (float)(height >> 1); this.myCamera.aspect = (float)(width / height); this.myCamera.targetTexture = this._destinationTexture; this.myCamera.clearFlags = CameraClearFlags.Color; Transform component = this.myCamera.GetComponent <Transform>(); component.localPosition = new Vector3((float)width / 2f, (float)height / 2f, 3f); component.localRotation = Quaternion.Euler(0f, 180f, 180f); this._doRenderAtlas = true; if (this.LOG_LEVEL >= MB2_LogLevel.debug) { UnityEngine.Debug.Log(string.Format("Begin Camera.Render destTex w={0} h={1} camPos={2}", width, height, component.localPosition)); } this.myCamera.Render(); this._doRenderAtlas = false; MB_Utility.Destroy(this.mat); MB_Utility.Destroy(this._destinationTexture); if (this.LOG_LEVEL >= MB2_LogLevel.debug) { UnityEngine.Debug.Log("Finished Camera.Render "); } Texture2D result = this.targTex; this.targTex = null; return(result); }
public IEnumerator ConvertTexturesToReadableFormats(ProgressUpdateDelegate progressInfo, MB3_TextureCombiner.CombineTexturesIntoAtlasesCoroutineResult result, MB3_TextureCombinerPipeline.TexturePipelineData data, MB3_TextureCombiner combiner, MB2_EditorMethodsInterface textureEditorMethods, MB2_LogLevel LOG_LEVEL) { Debug.Assert(data.OnlyOneTextureInAtlasReuseTextures()); yield break; }
public bool isDirty = false; //needs apply public CombinedMesh(int maxNumVertsInMesh, GameObject resultSceneObject, MB2_LogLevel ll){ combinedMesh = new MB3_MeshCombinerSingle(); combinedMesh.resultSceneObject = resultSceneObject; combinedMesh.LOG_LEVEL = ll; extraSpace = maxNumVertsInMesh; numVertsInListToDelete = 0; numVertsInListToAdd = 0; gosToAdd = new List<GameObject>(); gosToDelete = new List<int>(); gosToUpdate = new List<GameObject>(); }
public MB3_TextureCombinerNonTextureProperties(MB2_LogLevel ll, bool considerNonTextureProps) { _considerNonTextureProperties = considerNonTextureProps; textureProperty2DefaultColorMap = new Dictionary <string, Color>(); for (int i = 0; i < defaultTextureProperty2DefaultColorMap.Length; i++) { textureProperty2DefaultColorMap.Add(defaultTextureProperty2DefaultColorMap[i].name, defaultTextureProperty2DefaultColorMap[i].color); _nonTexturePropertiesBlender = new NonTexturePropertiesDontBlendProps(this); } }
public Texture2D DoRenderAtlas(GameObject gameObject, int width, int height, int padding, Rect[] rss, List<MB3_TextureCombiner.MB_TexSet> textureSetss, int indexOfTexSetToRenders, bool isNormalMap, bool fixOutOfBoundsUVs, MB3_TextureCombiner texCombiner, MB2_LogLevel LOG_LEV) { this.LOG_LEVEL = LOG_LEV; this.textureSets = textureSetss; this.indexOfTexSetToRender = indexOfTexSetToRenders; this._padding = padding; this._isNormalMap = isNormalMap; this._fixOutOfBoundsUVs = fixOutOfBoundsUVs; this.combiner = texCombiner; this.rs = rss; Shader shader; if (this._isNormalMap) { shader = Shader.Find("MeshBaker/NormalMapShader"); } else { shader = Shader.Find("MeshBaker/AlbedoShader"); } if (shader == null) { UnityEngine.Debug.LogError("Could not find shader for RenderTexture. Try reimporting mesh baker"); return null; } this.mat = new Material(shader); this._destinationTexture = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32); this._destinationTexture.filterMode = FilterMode.Point; this.myCamera = gameObject.GetComponent<Camera>(); this.myCamera.orthographic = true; this.myCamera.orthographicSize = (float)(height >> 1); this.myCamera.aspect = (float)(width / height); this.myCamera.targetTexture = this._destinationTexture; this.myCamera.clearFlags = CameraClearFlags.Color; Transform component = this.myCamera.GetComponent<Transform>(); component.localPosition = new Vector3((float)width / 2f, (float)height / 2f, 3f); component.localRotation = Quaternion.Euler(0f, 180f, 180f); this._doRenderAtlas = true; if (this.LOG_LEVEL >= MB2_LogLevel.debug) { UnityEngine.Debug.Log(string.Format("Begin Camera.Render destTex w={0} h={1} camPos={2}", width, height, component.localPosition)); } this.myCamera.Render(); this._doRenderAtlas = false; MB_Utility.Destroy(this.mat); MB_Utility.Destroy(this._destinationTexture); if (this.LOG_LEVEL >= MB2_LogLevel.debug) { UnityEngine.Debug.Log("Finished Camera.Render "); } Texture2D result = this.targTex; this.targTex = null; return result; }
public bool isDirty = false; //needs apply public CombinedMesh(int maxNumVertsInMesh, GameObject resultSceneObject, MB2_LogLevel ll) { combinedMesh = new MB3_MeshCombinerSingle(); combinedMesh.resultSceneObject = resultSceneObject; combinedMesh.LOG_LEVEL = ll; extraSpace = maxNumVertsInMesh; numVertsInListToDelete = 0; numVertsInListToAdd = 0; gosToAdd = new List <GameObject>(); gosToDelete = new List <int>(); gosToUpdate = new List <GameObject>(); }
public Texture2D DoRenderAtlas(GameObject gameObject, int width, int height, int padding, Rect[] rss, List<MB3_TextureCombiner.MB_TexSet> textureSetss, int indexOfTexSetToRenders, bool isNormalMap, bool fixOutOfBoundsUVs, MB3_TextureCombiner texCombiner, MB2_LogLevel LOG_LEV){ LOG_LEVEL = LOG_LEV; textureSets = textureSetss; indexOfTexSetToRender = indexOfTexSetToRenders; _padding = padding; _isNormalMap = isNormalMap; _fixOutOfBoundsUVs = fixOutOfBoundsUVs; combiner = texCombiner; rs = rss; Shader s; if (_isNormalMap){ s = Shader.Find ("MeshBaker/NormalMapShader"); } else { s = Shader.Find ("MeshBaker/AlbedoShader"); } if (s == null){ Debug.LogError ("Could not find shader for RenderTexture. Try reimporting mesh baker"); return null; } mat = new Material(s); _destinationTexture = new RenderTexture(width,height,24,RenderTextureFormat.ARGB32); _destinationTexture.filterMode = FilterMode.Point; myCamera = gameObject.GetComponent<Camera>(); myCamera.orthographic = true; myCamera.orthographicSize = height >> 1; myCamera.aspect = width / height; myCamera.targetTexture = _destinationTexture; myCamera.clearFlags = CameraClearFlags.Color; Transform camTransform = myCamera.GetComponent<Transform>(); camTransform.localPosition = new Vector3(width/2.0f, height/2f, 3); camTransform.localRotation = Quaternion.Euler(0, 180, 180); _doRenderAtlas = true; if (LOG_LEVEL >= MB2_LogLevel.debug) Debug.Log(string.Format ("Begin Camera.Render destTex w={0} h={1} camPos={2}", width, height, camTransform.localPosition)); //This triggers the OnRenderObject callback myCamera.Render(); _doRenderAtlas = false; MB_Utility.Destroy(mat); MB_Utility.Destroy(_destinationTexture); if (LOG_LEVEL >= MB2_LogLevel.debug) Debug.Log ("Finished Camera.Render "); Texture2D tempTex = targTex; targTex = null; return tempTex; }
public void Initialize( int camMaskLayer, int width, int height, int padding, MB2_LogLevel LOG_LEVEL = MB2_LogLevel.info ) { this.camMaskLayer = camMaskLayer; this.width = width; this.height = height; this.padding = padding; this.LOG_LEVEL = LOG_LEVEL; _initialized = true; }
public Vector2[] GetMeshUV1s(Mesh m, MB2_LogLevel LOG_LEVEL) { Vector2[] uv; #if (UNITY_4_6 || UNITY_4_5 || UNITY_4_3 || UNITY_4_2 || UNITY_4_1 || UNITY_4_0_1 || UNITY_4_0 || UNITY_3_5) uv = m.uv1; #else if (LOG_LEVEL >= MB2_LogLevel.warn) MB2_Log.LogDebug("UV1 does not exist in Unity 5+"); uv = m.uv; #endif if (uv.Length == 0){ if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("Mesh " + m + " has no uv1s. Generating"); if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Mesh " + m + " didn't have uv1s. Generating uv1s."); uv = new Vector2[m.vertexCount]; for (int i = 0; i < uv.Length; i++){uv[i] = _HALF_UV;} } return uv; }
public void RunTestHarness() { int num = 32; int min = 126; int max = 2046; List <Vector2> list = new List <Vector2>(); for (int i = 0; i < num; i++) { list.Add(new Vector2((float)UnityEngine.Random.Range(min, max), (float)(UnityEngine.Random.Range(min, max) * 5))); } this.doPowerOfTwoTextures = true; this.LOG_LEVEL = MB2_LogLevel.trace; int padding = 1; int num2; int num3; this.GetRects(list, 4096, padding, out num2, out num3); }
public static bool YisFlipped(MB2_LogLevel LOG_LEVEL) { string graphicsDeviceVersion = SystemInfo.graphicsDeviceVersion.ToLower(); bool flipY; if (!MBVersion.GraphicsUVStartsAtTop()) { flipY = false; } else { // "opengl es, direct3d" flipY = true; } if (LOG_LEVEL == MB2_LogLevel.debug) { Debug.Log("Graphics device version is: " + graphicsDeviceVersion + " flipY:" + flipY); } return(flipY); }
public static void MakeProceduralTexturesReadable(ProgressUpdateDelegate progressInfo, MB3_TextureCombiner.CombineTexturesIntoAtlasesCoroutineResult result, MB3_TextureCombinerPipeline.TexturePipelineData data, MB3_TextureCombiner combiner, MB2_EditorMethodsInterface textureEditorMethods, MB2_LogLevel LOG_LEVEL) { Debug.LogError("TODO this should be done as close to textures being used as possible due to memory issues."); //make procedural materials readable /* * for (int i = 0; i < combiner._proceduralMaterials.Count; i++) * { * if (!combiner._proceduralMaterials[i].proceduralMat.isReadable) * { * combiner._proceduralMaterials[i].originalIsReadableVal = combiner._proceduralMaterials[i].proceduralMat.isReadable; * combiner._proceduralMaterials[i].proceduralMat.isReadable = true; * //textureEditorMethods.AddProceduralMaterialFormat(_proceduralMaterials[i].proceduralMat); * combiner._proceduralMaterials[i].proceduralMat.RebuildTexturesImmediately(); * } * } * //convert procedural textures to RAW format * * for (int i = 0; i < distinctMaterialTextures.Count; i++) * { * for (int j = 0; j < texPropertyNames.Count; j++) * { * if (distinctMaterialTextures[i].ts[j].IsProceduralTexture()) * { * if (LOG_LEVEL >= MB2_LogLevel.debug) Debug.Log("Converting procedural texture to Textur2D:" + distinctMaterialTextures[i].ts[j].GetTexName() + " property:" + texPropertyNames[i]); * Texture2D txx = distinctMaterialTextures[i].ts[j].ConvertProceduralToTexture2D(_temporaryTextures); * distinctMaterialTextures[i].ts[j].t = txx; * } * } * } */ }
public UVAdjuster_Atlas(MB2_TextureBakeResults tbr, MB2_LogLevel ll) { textureBakeResults = tbr; LOG_LEVEL = ll; matsAndSrcUVRect = tbr.materialsAndUVRects; //count the number of times a material appears in the atlas. used for fast lookup numTimesMatAppearsInAtlas = new int[matsAndSrcUVRect.Length]; for (int i = 0; i < matsAndSrcUVRect.Length; i++) { if (numTimesMatAppearsInAtlas[i] > 1) { continue; } int count = 1; for (int j = i + 1; j < matsAndSrcUVRect.Length; j++) { if (matsAndSrcUVRect[i].material == matsAndSrcUVRect[j].material) { count++; } } numTimesMatAppearsInAtlas[i] = count; if (count > 1) { //allMatsAreUnique = false; for (int j = i + 1; j < matsAndSrcUVRect.Length; j++) { if (matsAndSrcUVRect[i].material == matsAndSrcUVRect[j].material) { numTimesMatAppearsInAtlas[j] = count; } } } } }
public static bool IsMeshAndMaterialRectEnclosedByAtlasRect(Rect uvR, Rect sourceMaterialTiling, Rect samplingEncapsulatinRect, MB2_LogLevel logLevel) { Rect potentialRect = new Rect(); Rect matR = sourceMaterialTiling; // test to see if this would fit in what was baked in the atlas Rect rr = samplingEncapsulatinRect; potentialRect = MB3_UVTransformUtility.CombineTransforms(ref uvR, ref matR); if (logLevel >= MB2_LogLevel.trace) { if (logLevel >= MB2_LogLevel.trace) { Debug.Log("uvR=" + uvR.ToString("f5") + " matR=" + matR.ToString("f5") + "Potential Rect " + potentialRect.ToString("f5") + " encapsulating=" + rr.ToString("f5")); } } if (logLevel >= MB2_LogLevel.trace) { if (logLevel >= MB2_LogLevel.trace) { Debug.Log("Potential Rect Cannonical " + potentialRect.ToString("f5") + " encapsulating=" + rr.ToString("f5")); } } if (MB3_UVTransformUtility.RectContainsShifted(ref rr, ref potentialRect)) { return(true); } return(false); }
//a material can appear more than once in an atlas if using fixOutOfBoundsUVs. //in this case need to use the UV rect of the mesh to find the correct rectangle. public bool TryMapMaterialToUVRect(Material mat, Mesh m, int submeshIdx, int idxInResultMats, MB3_MeshCombinerSingle.MeshChannelsCache meshChannelCache, Dictionary <int, MB_Utility.MeshAnalysisResult[]> meshAnalysisCache, out Rect rectInAtlas, //out Rect subrectInAtlasMatTiling, out Rect encapsulatingRect, out Rect sourceMaterialTilingOut, ref String errorMsg, MB2_LogLevel logLevel) { if (tbr.materialsAndUVRects.Length == 0 && tbr.materials.Length > 0) { errorMsg = "The 'Texture Bake Result' needs to be re-baked to be compatible with this version of Mesh Baker. Please re-bake using the MB3_TextureBaker."; rectInAtlas = new Rect(); //subrectInAtlasMatTiling = new Rect(); encapsulatingRect = new Rect(); sourceMaterialTilingOut = new Rect(); return(false); } if (mat == null) { rectInAtlas = new Rect(); //subrectInAtlasMatTiling = new Rect(); encapsulatingRect = new Rect(); sourceMaterialTilingOut = new Rect(); errorMsg = String.Format("Mesh {0} Had no material on submesh {1} cannot map to a material in the atlas", m.name, submeshIdx); return(false); } if (submeshIdx >= m.subMeshCount) { errorMsg = "Submesh index is greater than the number of submeshes"; rectInAtlas = new Rect(); //subrectInAtlasMatTiling = new Rect(); encapsulatingRect = new Rect(); sourceMaterialTilingOut = new Rect(); return(false); } //find the first index of this material int idx = -1; for (int i = 0; i < matsAndSrcUVRect.Length; i++) { if (mat == matsAndSrcUVRect[i].material) { idx = i; break; } } // if couldn't find material if (idx == -1) { rectInAtlas = new Rect(); //subrectInAtlasMatTiling = new Rect(); encapsulatingRect = new Rect(); sourceMaterialTilingOut = new Rect(); errorMsg = String.Format("Material {0} could not be found in the Texture Bake Result", mat.name); return(false); } if (!tbr.resultMaterials[idxInResultMats].considerMeshUVs) { if (numTimesMatAppearsInAtlas[idx] != 1) { Debug.LogError("There is a problem with this TextureBakeResults. FixOutOfBoundsUVs is false and a material appears more than once."); } rectInAtlas = matsAndSrcUVRect[idx].atlasRect; //subrectInAtlasMatTiling = matsAndSrcUVRect[idx].atlasSubrectMaterialOnly; encapsulatingRect = matsAndSrcUVRect[idx].samplingEncapsulatinRect; sourceMaterialTilingOut = matsAndSrcUVRect[idx].sourceMaterialTiling; return(true); } else { //todo what if no UVs //Find UV rect in source mesh MB_Utility.MeshAnalysisResult[] mar; if (!meshAnalysisCache.TryGetValue(m.GetInstanceID(), out mar)) { mar = new MB_Utility.MeshAnalysisResult[m.subMeshCount]; for (int j = 0; j < m.subMeshCount; j++) { Vector2[] uvss = meshChannelCache.GetUv0Raw(m); MB_Utility.hasOutOfBoundsUVs(uvss, m, ref mar[j], j); } meshAnalysisCache.Add(m.GetInstanceID(), mar); } //this could be a mesh that was not used in the texture baking that has huge UV tiling too big for the rect that was baked //find a record that has an atlas uvRect capable of containing this bool found = false; if (logLevel >= MB2_LogLevel.trace) { Debug.Log(String.Format("Trying to find a rectangle in atlas capable of holding tiled sampling rect for mesh {0} using material {1} meshUVrect={2}", m, mat, mar[submeshIdx].uvRect.ToString("f5"))); } for (int i = idx; i < matsAndSrcUVRect.Length; i++) { if (matsAndSrcUVRect[i].material == mat) { if (IsMeshAndMaterialRectEnclosedByAtlasRect(mar[submeshIdx].uvRect, matsAndSrcUVRect[i].sourceMaterialTiling, matsAndSrcUVRect[i].samplingEncapsulatinRect, logLevel)) { if (logLevel >= MB2_LogLevel.trace) { Debug.Log("Found rect in atlas capable of containing tiled sampling rect for mesh " + m + " at idx=" + i); } idx = i; found = true; break; } } } if (found) { rectInAtlas = matsAndSrcUVRect[idx].atlasRect; //subrectInAtlasMatTiling = matsAndSrcUVRect[idx].atlasSubrectMaterialOnly; encapsulatingRect = matsAndSrcUVRect[idx].samplingEncapsulatinRect; sourceMaterialTilingOut = matsAndSrcUVRect[idx].sourceMaterialTiling; return(true); } else { rectInAtlas = new Rect(); //subrectInAtlasMatTiling = new Rect(); encapsulatingRect = new Rect(); sourceMaterialTilingOut = new Rect(); errorMsg = String.Format("Could not find a tiled rectangle in the atlas capable of containing the uv and material tiling on mesh {0} for material {1}", m.name, mat); return(false); } } }
public Vector2[] GetMeshUV3orUV4(Mesh m, bool get3, MB2_LogLevel LOG_LEVEL) { Vector2[] uvs; #if (UNITY_4_6 || UNITY_4_5 || UNITY_4_3 || UNITY_4_2 || UNITY_4_1 || UNITY_4_0_1 || UNITY_4_0 || UNITY_3_5) if (LOG_LEVEL >= MB2_LogLevel.warn) MB2_Log.LogDebug("UV3 and UV4 do not exist in Unity 4"); uvs = m.uv; #else if (get3) uvs = m.uv3; else uvs = m.uv4; #endif if (uvs.Length == 0) { if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("Mesh " + m + " has no uv" + (get3 ? "3" : "4") + ". Generating"); uvs = new Vector2[m.vertexCount]; for (int i = 0; i < uvs.Length; i++) { uvs[i] = _HALF_UV; } } return uvs; }
public static bool IsMeshAndMaterialRectEnclosedByAtlasRect(MB_TextureTilingTreatment tilingTreatment, Rect uvR, Rect sourceMaterialTiling, Rect samplingEncapsulatinRect, MB2_LogLevel logLevel) { Rect potentialRect = new Rect(); Rect matR = sourceMaterialTiling; // test to see if this would fit in what was baked in the atlas Rect rr = samplingEncapsulatinRect; potentialRect = MB3_UVTransformUtility.CombineTransforms(ref uvR, ref matR); if (logLevel >= MB2_LogLevel.trace) { if (logLevel >= MB2_LogLevel.trace) { Debug.Log("uvR=" + uvR.ToString("f5") + " matR=" + matR.ToString("f5") + "Potential Rect " + potentialRect.ToString("f5") + " encapsulating=" + rr.ToString("f5")); } } if (logLevel >= MB2_LogLevel.trace) { if (logLevel >= MB2_LogLevel.trace) { Debug.Log("Potential Rect Cannonical " + potentialRect.ToString("f5") + " encapsulating=" + rr.ToString("f5")); } } if (tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeX) { if (MB3_UVTransformUtility.LineSegmentContainsShifted(rr.y, rr.height, potentialRect.y, potentialRect.height)) { return(true); } } else if (tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeY) { if (MB3_UVTransformUtility.LineSegmentContainsShifted(rr.x, rr.width, potentialRect.x, potentialRect.width)) { return(true); } } else if (tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeXY) { //only one rect in atlas and is edge to edge in both X and Y directions. return(true); } else { if (MB3_UVTransformUtility.RectContainsShifted(ref rr, ref potentialRect)) { return(true); } } return(false); }
public void Log(MB2_LogLevel l, string msg, MB2_LogLevel currentThreshold) { MB2_Log.Log(l, msg, currentThreshold); this._CacheLogMessage(msg); }
public override AtlasPackingResult[] CalculateAtlasRectangles(MB3_TextureCombinerPipeline.TexturePipelineData data, bool doMultiAtlas, MB2_LogLevel LOG_LEVEL) { Debug.Assert(!data.OnlyOneTextureInAtlasReuseTextures()); //with Unity texture packer we don't find the rectangles, Unity does. When packer is run return(new AtlasPackingResult[] { new AtlasPackingResult(new AtlasPadding[0]) }); }
// used by Unity texture packer to handle tiled textures. // may create a new texture that has the correct tiling to handle fix out of bounds UVs internal static Texture2D GetAdjustedForScaleAndOffset2(string propertyName, MeshBakerMaterialTexture source, Vector2 obUVoffset, Vector2 obUVscale, MB3_TextureCombinerPipeline.TexturePipelineData data, MB3_TextureCombiner combiner, MB2_LogLevel LOG_LEVEL) { Texture2D sourceTex = source.GetTexture2D(); if (source.matTilingRect.x == 0f && source.matTilingRect.y == 0f && source.matTilingRect.width == 1f && source.matTilingRect.height == 1f) { if (data._fixOutOfBoundsUVs) { if (obUVoffset.x == 0f && obUVoffset.y == 0f && obUVscale.x == 1f && obUVscale.y == 1f) { return(sourceTex); //no adjustment necessary } } else { return(sourceTex); //no adjustment necessary } } Vector2 dim = MB3_TextureCombinerPipeline.GetAdjustedForScaleAndOffset2Dimensions(source, obUVoffset, obUVscale, data, LOG_LEVEL); if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.LogWarning("GetAdjustedForScaleAndOffset2: " + sourceTex + " " + obUVoffset + " " + obUVscale); } float newWidth = dim.x; float newHeight = dim.y; float scx = (float)source.matTilingRect.width; float scy = (float)source.matTilingRect.height; float ox = (float)source.matTilingRect.x; float oy = (float)source.matTilingRect.y; if (data._fixOutOfBoundsUVs) { scx *= obUVscale.x; scy *= obUVscale.y; ox = (float)(source.matTilingRect.x * obUVscale.x + obUVoffset.x); oy = (float)(source.matTilingRect.y * obUVscale.y + obUVoffset.y); } Texture2D newTex = combiner._createTemporaryTexture(propertyName, (int)newWidth, (int)newHeight, TextureFormat.ARGB32, true); for (int i = 0; i < newTex.width; i++) { for (int j = 0; j < newTex.height; j++) { float u = i / newWidth * scx + ox; float v = j / newHeight * scy + oy; newTex.SetPixel(i, j, sourceTex.GetPixelBilinear(u, v)); } } newTex.Apply(); return(newTex); }
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; }
public static Vector2[] GetMeshUV1s(Mesh m, MB2_LogLevel LOG_LEVEL) { if (_MBVersion == null) _MBVersion = _CreateMBVersionConcrete(); return _MBVersion.GetMeshUV1s(m,LOG_LEVEL); }
/* public static Vector2[] GetMeshUV1s(Mesh m, MB2_LogLevel LOG_LEVEL){ if (_MBVersion == null) _MBVersion = _CreateMBVersionConcrete(); return _MBVersion.GetMeshUV1s(m,LOG_LEVEL); } */ public static Vector2[] GetMeshUV3orUV4(Mesh m, bool get3, MB2_LogLevel LOG_LEVEL) { if (_MBVersion == null) _MBVersion = _CreateMBVersionConcrete(); return _MBVersion.GetMeshUV3orUV4(m,get3,LOG_LEVEL); }
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 (uvRects.Length == 1) { if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("Only one image per atlas. Will re-use original texture"); } 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 { int atlasSizeX = packedAtlasRects.atlasX; int atlasSizeY = packedAtlasRects.atlasY; if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("Generated atlas will be " + atlasSizeX + "x" + atlasSizeY); } for (int propIdx = 0; propIdx < data.numAtlases; propIdx++) { Texture2D atlas = null; if (!MB3_TextureCombinerPipeline._ShouldWeCreateAtlasForThisProperty(propIdx, data._considerNonTextureProperties, data.allTexturesAreNullAndSameColor)) { atlas = null; if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("=== Not creating atlas for " + data.texPropertyNames[propIdx].name + " because textures are null and default value parameters are the same."); } } else { if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("=== Creating atlas for " + data.texPropertyNames[propIdx].name); } GC.Collect(); //use a jagged array because it is much more efficient in memory Color[][] atlasPixels = new Color[atlasSizeY][]; for (int j = 0; j < atlasPixels.Length; j++) { atlasPixels[j] = new Color[atlasSizeX]; } bool isNormalMap = false; if (data.texPropertyNames[propIdx].isNormalMap) { isNormalMap = true; } for (int texSetIdx = 0; texSetIdx < data.distinctMaterialTextures.Count; texSetIdx++) { string s = "Creating Atlas '" + data.texPropertyNames[propIdx].name + "' texture " + data.distinctMaterialTextures[texSetIdx]; if (progressInfo != null) { progressInfo(s, .01f); } MB_TexSet texSet = data.distinctMaterialTextures[texSetIdx]; if (LOG_LEVEL >= MB2_LogLevel.trace) { Debug.Log(string.Format("Adding texture {0} to atlas {1}", texSet.ts[propIdx].GetTexture2D() == null ? "null" : texSet.ts[propIdx].GetTexName(), data.texPropertyNames[propIdx])); } Rect r = uvRects[texSetIdx]; Texture2D t = texSet.ts[propIdx].GetTexture2D(); int x = Mathf.RoundToInt(r.x * atlasSizeX); int y = Mathf.RoundToInt(r.y * atlasSizeY); int ww = Mathf.RoundToInt(r.width * atlasSizeX); int hh = Mathf.RoundToInt(r.height * atlasSizeY); if (ww == 0 || hh == 0) { Debug.LogError("Image in atlas has no height or width " + r); } if (progressInfo != null) { progressInfo(s + " set ReadWrite flag", .01f); } if (textureEditorMethods != null) { textureEditorMethods.SetReadWriteFlag(t, true, true); } if (progressInfo != null) { progressInfo(s + "Copying to atlas: '" + texSet.ts[propIdx].GetTexName() + "'", .02f); } DRect samplingRect = texSet.ts[propIdx].encapsulatingSamplingRect; yield return(CopyScaledAndTiledToAtlas(texSet.ts[propIdx], texSet, data.texPropertyNames[propIdx], samplingRect, x, y, ww, hh, packedAtlasRects.padding[texSetIdx], atlasPixels, isNormalMap, data, combiner, progressInfo, LOG_LEVEL)); // Debug.Log("after copyScaledAndTiledAtlas"); } yield return(data.numAtlases); if (progressInfo != null) { progressInfo("Applying changes to atlas: '" + data.texPropertyNames[propIdx].name + "'", .03f); } atlas = new Texture2D(atlasSizeX, atlasSizeY, TextureFormat.ARGB32, true); for (int j = 0; j < atlasPixels.Length; j++) { atlas.SetPixels(0, j, atlasSizeX, 1, atlasPixels[j]); } atlas.Apply(); if (LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("Saving atlas " + data.texPropertyNames[propIdx].name + " w=" + atlas.width + " h=" + atlas.height); } } atlases[propIdx] = atlas; if (progressInfo != null) { progressInfo("Saving atlas: '" + data.texPropertyNames[propIdx].name + "'", .04f); } System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); if (data._saveAtlasesAsAssets && textureEditorMethods != null) { textureEditorMethods.SaveAtlasToAssetDatabase(atlases[propIdx], data.texPropertyNames[propIdx], propIdx, data.resultMaterial); } else { data.resultMaterial.SetTexture(data.texPropertyNames[propIdx].name, atlases[propIdx]); } data.resultMaterial.SetTextureOffset(data.texPropertyNames[propIdx].name, Vector2.zero); data.resultMaterial.SetTextureScale(data.texPropertyNames[propIdx].name, Vector2.one); combiner._destroyTemporaryTextures(); // need to save atlases before doing this } } //data.rectsInAtlas = uvRects; // Debug.Log("finished!"); yield break; }