Пример #1
0
        //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);
                }
            }
        }
Пример #2
0
        //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, MB3_MeshCombinerSingle.MeshChannelsCache meshChannelCache, Dictionary <int, MB_Utility.MeshAnalysisResult[]> meshAnalysisCache,
                                           out Rect rectInAtlas, out Rect subrectInAtlasMatTiling, ref String errorMsg)
        {
            if (tbr.materialsAndUVRects.Length == 0 && tbr.materials.Length > 0)
            {
                errorMsg                = "The 'Material 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();
                return(false);
            }
            if (mat == null)
            {
                rectInAtlas             = new Rect();
                subrectInAtlasMatTiling = 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();
                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();
                errorMsg = String.Format("Material {0} could not be found in the Material Bake Result", mat.name);
                return(false);
            }

            if (!tbr.fixOutOfBoundsUVs)
            {
                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;
                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;
                for (int i = idx; i < matsAndSrcUVRect.Length; i++)
                {
                    if (matsAndSrcUVRect[i].material == mat)
                    {
                        //calculate what the UV rect in the atlas would be if we combined the material tiling of this rect with the UV tiling of this submesh
                        Rect potentialRect = new Rect();
                        Rect uvR           = mar[submeshIdx].uvRect;
                        Rect matR          = matsAndSrcUVRect[i].atlasSubrectMaterialOnly;
                        potentialRect = MB3_UVTransformUtility.CombineTransforms(ref matR, ref uvR);
                        //MB3_UVTransformUtility.Canonicalize(ref potentialRect);
                        // test to see if this would fit in what was baked in the atlas
                        Rect rr = new Rect(0f, 0f, 1f, 1f);
                        if (MB3_UVTransformUtility.RectContains(ref rr, ref potentialRect))
                        {
                            idx   = i;
                            found = true;
                            break;
                        }
                    }
                }
                if (found)
                {
                    rectInAtlas             = matsAndSrcUVRect[idx].atlasRect;
                    subrectInAtlasMatTiling = matsAndSrcUVRect[idx].atlasSubrectMaterialOnly;
                    return(true);
                }
                else
                {
                    rectInAtlas             = new Rect();
                    subrectInAtlasMatTiling = 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}", m.name);
                    return(false);
                }
            }
        }