Beispiel #1
0
 public void SetTilingTreatmentAndAdjustEncapsulatingSamplingRect(MB_TextureTilingTreatment newTilingTreatment)
 {
     Debug.Assert(texSet.allTexturesUseSameMatTiling == false);
     if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeX)
     {
         foreach (MeshBakerMaterialTexture t in texSet.ts)
         {
             DRect r = t.GetEncapsulatingSamplingRect();
             r.width = 1;
             t.SetEncapsulatingSamplingRect(texSet, r);
         }
     }
     else if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeY)
     {
         foreach (MeshBakerMaterialTexture t in texSet.ts)
         {
             DRect r = t.GetEncapsulatingSamplingRect();
             r.height = 1;
             t.SetEncapsulatingSamplingRect(texSet, r);
         }
     }
     else if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeXY)
     {
         foreach (MeshBakerMaterialTexture t in texSet.ts)
         {
             DRect r = t.GetEncapsulatingSamplingRect();
             r.height = 1;
             r.width = 1;
             t.SetEncapsulatingSamplingRect(texSet, r);
         }
     }
 }
    /// <param name="mat">The Material</param>
    /// <param name="destRect">The rect in the atlas this material maps to</param>
    /// <param name="allPropsUseSameTiling">If true then use sourceMaterialTiling and samplingEncapsulatingRect.
    /// if false then use srcUVsamplingRect. None used values should be 0,0,0,0.</param>
    /// <param name="sourceMaterialTiling">allPropsUseSameTiling_sourceMaterialTiling</param>
    /// <param name="samplingEncapsulatingRect">allPropsUseSameTiling_samplingEncapsulatinRect</param>
    /// <param name="srcUVsamplingRect">propsUseDifferntTiling_srcUVsamplingRect</param>
    public MB_MaterialAndUVRect(Material mat,
                                Rect destRect,
                                bool allPropsUseSameTiling,
                                Rect sourceMaterialTiling,
                                Rect samplingEncapsulatingRect,
                                Rect srcUVsamplingRect,
                                MB_TextureTilingTreatment treatment,
                                string objName)
    {
        if (allPropsUseSameTiling)
        {
            Debug.Assert(srcUVsamplingRect == new Rect(0, 0, 0, 0));
        }

        if (!allPropsUseSameTiling)
        {
            Debug.Assert(samplingEncapsulatingRect == new Rect(0, 0, 0, 0));
            Debug.Assert(sourceMaterialTiling == new Rect(0, 0, 0, 0));
        }

        material                   = mat;
        atlasRect                  = destRect;
        tilingTreatment            = treatment;
        this.allPropsUseSameTiling = allPropsUseSameTiling;
        allPropsUseSameTiling_sourceMaterialTiling     = sourceMaterialTiling;
        allPropsUseSameTiling_samplingEncapsulatinRect = samplingEncapsulatingRect;
        propsUseDifferntTiling_srcUVsamplingRect       = srcUVsamplingRect;
        srcObjName = objName;
    }
    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);
    }
Beispiel #4
0
 public MB_TexSet(MeshBakerMaterialTexture[] tss, Vector2 uvOffset, Vector2 uvScale, MB_TextureTilingTreatment treatment)
 {
     ts = tss;
     tilingTreatment = treatment;
     obUVoffset = uvOffset;
     obUVscale = uvScale;
     allTexturesUseSameMatTiling = false;
     thisIsOnlyTexSetInAtlas = false;
     matsAndGOs = new MatsAndGOs();
     matsAndGOs.mats = new List<MatAndTransformToMerged>();
     matsAndGOs.gos = new List<GameObject>();
     pipelineVariation = new PipelineVariationSomeTexturesUseDifferentMatTiling(this);
 }
        /// <summary>
        /// A material can appear more than once in an atlas if using fixOutOfBoundsUVs.
        /// in this case you need to use the UV rect of the mesh to find the correct rectangle.
        /// If the all properties on the mat use the same tiling then
        /// encapsulatingRect can be larger and will include baked UV and material tiling
        /// If mat uses different tiling for different maps then encapsulatingRect is the uvs of
        /// source mesh used to bake atlas and sourceMaterialTilingOut is 0,0,1,1. This works because
        /// material tiling was baked into the atlas.
        /// </summary>
        public bool TryMapMaterialToUVRect(Material mat, Mesh m, int submeshIdx, int idxInResultMats, MB3_MeshCombinerSingle.MeshChannelsCache meshChannelCache, Dictionary <int, MB_Utility.MeshAnalysisResult[]> meshAnalysisCache,
                                           out MB_TextureTilingTreatment tilingTreatment,
                                           out Rect rectInAtlas,
                                           out Rect encapsulatingRectOut,
                                           out Rect sourceMaterialTilingOut,
                                           ref String errorMsg,
                                           MB2_LogLevel logLevel)
        {
            if (tbr.version < VERSION)
            {
                UpgradeToCurrentVersion(tbr);
            }
            tilingTreatment = MB_TextureTilingTreatment.unknown;
            if (tbr.materialsAndUVRects.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();
                encapsulatingRectOut    = new Rect();
                sourceMaterialTilingOut = new Rect();
                return(false);
            }
            if (mat == null)
            {
                rectInAtlas             = new Rect();
                encapsulatingRectOut    = 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();
                encapsulatingRectOut    = 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();
                encapsulatingRectOut    = 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.");
                }
                MB_MaterialAndUVRect mr = matsAndSrcUVRect[idx];
                rectInAtlas             = mr.atlasRect;
                tilingTreatment         = mr.tilingTreatment;
                encapsulatingRectOut    = mr.GetEncapsulatingRect();
                sourceMaterialTilingOut = mr.GetMaterialTilingRect();
                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;
                Rect encapsulatingRect    = new Rect(0, 0, 0, 0);
                Rect sourceMaterialTiling = new Rect(0, 0, 0, 0);
                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++)
                {
                    MB_MaterialAndUVRect matAndUVrect = matsAndSrcUVRect[i];
                    if (matAndUVrect.material == mat)
                    {
                        if (matAndUVrect.allPropsUseSameTiling)
                        {
                            encapsulatingRect    = matAndUVrect.allPropsUseSameTiling_samplingEncapsulatinRect;
                            sourceMaterialTiling = matAndUVrect.allPropsUseSameTiling_sourceMaterialTiling;
                        }
                        else
                        {
                            encapsulatingRect    = matAndUVrect.propsUseDifferntTiling_srcUVsamplingRect;
                            sourceMaterialTiling = new Rect(0, 0, 1, 1);
                        }

                        if (IsMeshAndMaterialRectEnclosedByAtlasRect(
                                matAndUVrect.tilingTreatment,
                                mar[submeshIdx].uvRect,
                                sourceMaterialTiling,
                                encapsulatingRect,
                                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)
                {
                    MB_MaterialAndUVRect mr = matsAndSrcUVRect[idx];
                    rectInAtlas             = mr.atlasRect;
                    tilingTreatment         = mr.tilingTreatment;
                    encapsulatingRectOut    = mr.GetEncapsulatingRect();
                    sourceMaterialTilingOut = mr.GetMaterialTilingRect();
                    return(true);
                }
                else
                {
                    rectInAtlas             = new Rect();
                    encapsulatingRectOut    = 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);
                }
            }
        }
Beispiel #6
0
 public void SetTilingTreatmentAndAdjustEncapsulatingSamplingRect(MB_TextureTilingTreatment newTilingTreatment)
 {
     tilingTreatment = newTilingTreatment;
     pipelineVariation.SetTilingTreatmentAndAdjustEncapsulatingSamplingRect(newTilingTreatment);
 }
            public bool MapSharedMaterialsToAtlasRects(Material[] sharedMaterials,
                                                       bool checkTargetSubmeshIdxsFromPreviousBake,
                                                       Mesh m, MeshChannelsCache meshChannelsCache,
                                                       Dictionary <int, MB_Utility.MeshAnalysisResult[]> meshAnalysisResultsCache,
                                                       OrderedDictionary sourceMats2submeshIdx_map, GameObject go, MB_DynamicGameObject dgoOut)
            {
                MB_TextureTilingTreatment[] tilingTreatment = new MB_TextureTilingTreatment[sharedMaterials.Length];
                Rect[] uvRectsInAtlas       = new Rect[sharedMaterials.Length];
                Rect[] encapsulatingRect    = new Rect[sharedMaterials.Length];
                Rect[] sourceMaterialTiling = new Rect[sharedMaterials.Length];
                int[]  sliceIdx             = new int[sharedMaterials.Length];
                String errorMsg             = "";

                for (int srcSubmeshIdx = 0; srcSubmeshIdx < sharedMaterials.Length; srcSubmeshIdx++)
                {
                    System.Object subIdx = sourceMats2submeshIdx_map[sharedMaterials[srcSubmeshIdx]];
                    int           resMatIdx;
                    if (subIdx == null)
                    {
                        Debug.LogError("Source object " + go.name + " used a material " + sharedMaterials[srcSubmeshIdx] + " that was not in the baked materials.");
                        return(false);
                    }
                    else
                    {
                        resMatIdx = (int)subIdx;
                        if (checkTargetSubmeshIdxsFromPreviousBake)
                        {
                            /*
                             *  Possibilities:
                             *  Consider a mesh with three submeshes with materials A, B, C that map to
                             *  different submeshes in the combined mesh, AA,BB,CC. The user is updating the UVs on a
                             *  MeshRenderer so that object 'one' now uses material C => CC instead of A => AA. This will mean that the
                             *  triangle buffers will need to be resized. This is not allowed in UpdateGameObjects.
                             *  Must map to the same submesh that the old one mapped to.
                             */

                            if (resMatIdx != dgoOut.targetSubmeshIdxs[srcSubmeshIdx])
                            {
                                Debug.LogError(String.Format("Update failed for object {0}. Material {1} is mapped to a different submesh in the combined mesh than the previous material. This is not supported. Try using AddDelete.", go.name, sharedMaterials[srcSubmeshIdx]));
                                return(false);
                            }
                        }
                    }

                    if (!TryMapMaterialToUVRect(sharedMaterials[srcSubmeshIdx], m, srcSubmeshIdx, resMatIdx, meshChannelsCache, meshAnalysisResultsCache,
                                                out tilingTreatment[srcSubmeshIdx],
                                                out uvRectsInAtlas[srcSubmeshIdx],
                                                out encapsulatingRect[srcSubmeshIdx],
                                                out sourceMaterialTiling[srcSubmeshIdx],
                                                out sliceIdx[srcSubmeshIdx],
                                                ref errorMsg, LOG_LEVEL))
                    {
                        Debug.LogError(errorMsg);
                        return(false);
                    }
                }

                dgoOut.uvRects              = uvRectsInAtlas;
                dgoOut.encapsulatingRect    = encapsulatingRect;
                dgoOut.sourceMaterialTiling = sourceMaterialTiling;
                dgoOut.textureArraySliceIdx = sliceIdx;
                return(true);
            }