Пример #1
0
    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);
    }
    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);
    }
Пример #3
0
    private void CopyScaledAndTiledToAtlas(MB3_TextureCombiner.MB_TexSet texSet, MB3_TextureCombiner.MeshBakerMaterialTexture source, Vector2 obUVoffset, Vector2 obUVscale, Rect rec, ShaderTextureProperty texturePropertyName, TextureBlender resultMatTexBlender)
    {
        Rect r = rec;

        if (resultMatTexBlender != null)
        {
            myCamera.backgroundColor = resultMatTexBlender.GetColorIfNoTexture(texSet.mats[0].mat, texturePropertyName);
        }
        else
        {
            myCamera.backgroundColor = MB3_TextureCombiner.GetColorIfNoTexture(texturePropertyName);
        }

        if (source.t == null)
        {
            source.t = combiner._createTemporaryTexture(16, 16, TextureFormat.ARGB32, true);
        }

        r.y       = 1f - (r.y + r.height);   // DrawTexture uses topLeft 0,0, Texture2D uses bottomLeft 0,0
        r.x      *= _destinationTexture.width;
        r.y      *= _destinationTexture.height;
        r.width  *= _destinationTexture.width;
        r.height *= _destinationTexture.height;

        Rect rPadded = r;

        rPadded.x      -= _padding;
        rPadded.y      -= _padding;
        rPadded.width  += _padding * 2;
        rPadded.height += _padding * 2;

        Rect srcPrTex = source.matTilingRect.GetRect();
        Rect targPr   = new Rect();

        if (_fixOutOfBoundsUVs)
        {
            Rect ruv = new Rect(obUVoffset.x, obUVoffset.y, obUVscale.x, obUVscale.y);
            srcPrTex = MB3_UVTransformUtility.CombineTransforms(ref srcPrTex, ref ruv);
            if (LOG_LEVEL >= MB2_LogLevel.trace)
            {
                Debug.Log("Fixing out of bounds UVs for tex " + source.t);
            }
        }


        Texture2D tex = source.t;

        /*
         * if (_considerNonTextureProperties && resultMatTexBlender != null)
         * {
         *      if (LOG_LEVEL >= MB2_LogLevel.trace) Debug.Log(string.Format("Blending texture {0} mat {1} with non-texture properties using TextureBlender {2}", tex.name, texSet.mats[0].mat, resultMatTexBlender));
         *
         *      resultMatTexBlender.OnBeforeTintTexture(texSet.mats[0].mat, texturePropertyName.name);
         *      //combine the tintColor with the texture
         *      tex = combiner._createTextureCopy(tex);
         *      for (int i = 0; i < tex.height; i++)
         *      {
         *              Color[] cs = tex.GetPixels(0, i, tex.width, 1);
         *              for (int j = 0; j < cs.Length; j++)
         *              {
         *                      cs[j] = resultMatTexBlender.OnBlendTexturePixel(texturePropertyName.name, cs[j]);
         *              }
         *              tex.SetPixels(0, i, tex.width, 1, cs);
         *      }
         *      tex.Apply();
         * }
         */


        //main texture
        TextureWrapMode oldTexWrapMode = tex.wrapMode;

        if (srcPrTex.width == 1f && srcPrTex.height == 1f && srcPrTex.x == 0f && srcPrTex.y == 0f)
        {
            //fixes bug where there is a dark line at the edge of the texture
            tex.wrapMode = TextureWrapMode.Clamp;
        }
        else
        {
            tex.wrapMode = TextureWrapMode.Repeat;
        }


        if (LOG_LEVEL >= MB2_LogLevel.trace)
        {
            Debug.Log("DrawTexture tex=" + tex.name + " destRect=" + r + " srcRect=" + srcPrTex + " Mat=" + mat);
        }


        //fill the padding first
        Rect srcPr = new Rect();

        //top margin
        srcPr.x       = srcPrTex.x;
        srcPr.y       = srcPrTex.y + 1 - 1f / tex.height;
        srcPr.width   = srcPrTex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = r.x;
        targPr.y      = rPadded.y;
        targPr.width  = r.width;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //bot margin
        srcPr.x       = srcPrTex.x;
        srcPr.y       = srcPrTex.y;
        srcPr.width   = srcPrTex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = r.x;
        targPr.y      = r.y + r.height;
        targPr.width  = r.width;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);


        //left margin
        srcPr.x       = srcPrTex.x;
        srcPr.y       = srcPrTex.y;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = srcPrTex.height;
        targPr.x      = rPadded.x;
        targPr.y      = r.y;
        targPr.width  = _padding;
        targPr.height = r.height;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //right margin
        srcPr.x       = srcPrTex.x + 1f - 1f / tex.width;
        srcPr.y       = srcPrTex.y;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = srcPrTex.height;
        targPr.x      = r.x + r.width;
        targPr.y      = r.y;
        targPr.width  = _padding;
        targPr.height = r.height;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);


        //top left corner
        srcPr.x       = srcPrTex.x;
        srcPr.y       = srcPrTex.y + 1 - 1f / tex.height;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = rPadded.x;
        targPr.y      = rPadded.y;
        targPr.width  = _padding;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //top right corner
        srcPr.x       = srcPrTex.x + 1f - 1f / tex.width;
        srcPr.y       = srcPrTex.y + 1 - 1f / tex.height;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = r.x + r.width;
        targPr.y      = rPadded.y;
        targPr.width  = _padding;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //bot left corner
        srcPr.x       = srcPrTex.x;
        srcPr.y       = srcPrTex.y;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = rPadded.x;
        targPr.y      = r.y + r.height;
        targPr.width  = _padding;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //bot right corner
        srcPr.x       = srcPrTex.x + 1f - 1f / tex.width;
        srcPr.y       = srcPrTex.y;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = r.x + r.width;
        targPr.y      = r.y + r.height;
        targPr.width  = _padding;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //now the texture
        Graphics.DrawTexture(r, tex, srcPrTex, 0, 0, 0, 0, mat);

        tex.wrapMode = oldTexWrapMode;
    }
Пример #4
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,
                                           out Rect encapsulatingRect,
                                           out Rect sourceMaterialTilingOut,
                                           ref String errorMsg,
                                           MB2_LogLevel logLevel)
        {
            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();
                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 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;
                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.LogWarning(String.Format("Trying to find a rectangle in atlas capable of holding tiled sampling rect for mesh {0} using material {1}", m, mat));
                }
                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].sourceMaterialTiling;
                        // test to see if this would fit in what was baked in the atlas
                        Rect rr = matsAndSrcUVRect[i].samplingEncapsulatinRect;
                        MB3_UVTransformUtility.Canonicalize(ref rr, 0, 0);

                        potentialRect = MB3_UVTransformUtility.CombineTransforms(ref uvR, ref matR);
                        if (logLevel >= MB2_LogLevel.trace)
                        {
                            Debug.Log("uvR=" + uvR.ToString("f5") + " matR=" + matR.ToString("f5") + "Potential Rect " + potentialRect.ToString("f5") + " encapsulating=" + rr.ToString("f5"));
                        }
                        MB3_UVTransformUtility.Canonicalize(ref potentialRect, rr.x, rr.y);
                        if (logLevel >= MB2_LogLevel.trace)
                        {
                            Debug.Log("Potential Rect Cannonical " + potentialRect.ToString("f5") + " encapsulating=" + rr.ToString("f5"));
                        }

                        if (MB3_UVTransformUtility.RectContains(ref rr, ref potentialRect))
                        {
                            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}", m.name);
                    return(false);
                }
            }
        }
    private void CopyScaledAndTiledToAtlas(MB3_TextureCombiner.MeshBakerMaterialTexture source, Vector2 obUVoffset, Vector2 obUVscale, Rect rec)
    {
        Rect r = rec;

        myCamera.backgroundColor = source.colorIfNoTexture;

        if (source.t == null)
        {
            source.t = combiner._createTemporaryTexture(16, 16, TextureFormat.ARGB32, true);
            Debug.Log("Creating texture with color " + source.colorIfNoTexture + " isNormal" + _isNormalMap);
            MB_Utility.setSolidColor(source.t, source.colorIfNoTexture);
        }

        r.y       = 1f - (r.y + r.height);   // DrawTexture uses topLeft 0,0, Texture2D uses bottomLeft 0,0
        r.x      *= _destinationTexture.width;
        r.y      *= _destinationTexture.height;
        r.width  *= _destinationTexture.width;
        r.height *= _destinationTexture.height;

        Rect rPadded = r;

        rPadded.x      -= _padding;
        rPadded.y      -= _padding;
        rPadded.width  += _padding * 2;
        rPadded.height += _padding * 2;

        Rect srcPrTex = source.matTilingRect.GetRect();
        Rect targPr   = new Rect();

        if (_fixOutOfBoundsUVs)
        {
            Rect ruv = new Rect(obUVoffset.x, obUVoffset.y, obUVscale.x, obUVscale.y);
            srcPrTex = MB3_UVTransformUtility.CombineTransforms(ref srcPrTex, ref ruv);
            if (LOG_LEVEL >= MB2_LogLevel.trace)
            {
                Debug.Log("Fixing out of bounds UVs for tex " + source.t);
            }
        }

        Texture tex = source.t;

        //main texture
        TextureWrapMode oldTexWrapMode = tex.wrapMode;

        if (srcPrTex.width == 1f && srcPrTex.height == 1f && srcPrTex.x == 0f && srcPrTex.y == 0f)
        {
            //fixes bug where there is a dark line at the edge of the texture
            tex.wrapMode = TextureWrapMode.Clamp;
        }
        else
        {
            tex.wrapMode = TextureWrapMode.Repeat;
        }


        if (LOG_LEVEL >= MB2_LogLevel.trace)
        {
            Debug.Log("DrawTexture tex=" + tex.name + " destRect=" + r + " srcRect=" + srcPrTex + " Mat=" + mat);
        }


        //fill the padding first
        Rect srcPr = new Rect();

        //top margin
        srcPr.x       = srcPrTex.x;
        srcPr.y       = srcPrTex.y + 1 - 1f / tex.height;
        srcPr.width   = srcPrTex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = r.x;
        targPr.y      = rPadded.y;
        targPr.width  = r.width;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //bot margin
        srcPr.x       = srcPrTex.x;
        srcPr.y       = srcPrTex.y;
        srcPr.width   = srcPrTex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = r.x;
        targPr.y      = r.y + r.height;
        targPr.width  = r.width;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);


        //left margin
        srcPr.x       = srcPrTex.x;
        srcPr.y       = srcPrTex.y;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = srcPrTex.height;
        targPr.x      = rPadded.x;
        targPr.y      = r.y;
        targPr.width  = _padding;
        targPr.height = r.height;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //right margin
        srcPr.x       = srcPrTex.x + 1f - 1f / tex.width;
        srcPr.y       = srcPrTex.y;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = srcPrTex.height;
        targPr.x      = r.x + r.width;
        targPr.y      = r.y;
        targPr.width  = _padding;
        targPr.height = r.height;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);


        //top left corner
        srcPr.x       = srcPrTex.x;
        srcPr.y       = srcPrTex.y + 1 - 1f / tex.height;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = rPadded.x;
        targPr.y      = rPadded.y;
        targPr.width  = _padding;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //top right corner
        srcPr.x       = srcPrTex.x + 1f - 1f / tex.width;
        srcPr.y       = srcPrTex.y + 1 - 1f / tex.height;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = r.x + r.width;
        targPr.y      = rPadded.y;
        targPr.width  = _padding;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //bot left corner
        srcPr.x       = srcPrTex.x;
        srcPr.y       = srcPrTex.y;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = rPadded.x;
        targPr.y      = r.y + r.height;
        targPr.width  = _padding;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //bot right corner
        srcPr.x       = srcPrTex.x + 1f - 1f / tex.width;
        srcPr.y       = srcPrTex.y;
        srcPr.width   = 1f / tex.width;
        srcPr.height  = 1f / tex.height;
        targPr.x      = r.x + r.width;
        targPr.y      = r.y + r.height;
        targPr.width  = _padding;
        targPr.height = _padding;
        Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

        //now the texture
        Graphics.DrawTexture(r, tex, srcPrTex, 0, 0, 0, 0, mat);

        tex.wrapMode = oldTexWrapMode;
    }