// 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(ShaderTextureProperty 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.name, (int)newWidth, (int)newHeight, TextureFormat.ARGB32, true, MB3_TextureCombiner.ShouldTextureBeLinear(propertyName));

            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);
        }
 internal static void CreateTemporaryTexturesForAtlas(List <MB_TexSet> distinctMaterialTextures, MB3_TextureCombiner combiner, int propIdx, MB3_TextureCombinerPipeline.TexturePipelineData data)
 {
     for (int texSetIdx = 0; texSetIdx < data.distinctMaterialTextures.Count; texSetIdx++)
     {
         MB_TexSet txs = data.distinctMaterialTextures[texSetIdx];
         MeshBakerMaterialTexture matTex = txs.ts[propIdx];
         if (matTex.isNull)
         {
             //create a small 16 x 16 texture to use in the atlas
             Color col = data.nonTexturePropertyBlender.GetColorForTemporaryTexture(txs.matsAndGOs.mats[0].mat, data.texPropertyNames[propIdx]);
             txs.CreateColoredTexToReplaceNull(data.texPropertyNames[propIdx].name, propIdx, data._fixOutOfBoundsUVs, combiner, col, MB3_TextureCombiner.ShouldTextureBeLinear(data.texPropertyNames[propIdx]));
         }
     }
 }