示例#1
0
 public void OnEnable()
 {
     m_Mesh          = new Mesh();
     m_VertexHelper  = new UIVertexHelper();
     m_PropertyBlock = new MaterialPropertyBlock();
     m_TextGenerator = new TextGenerator();
     m_Font.SetDefaultValue(Resources.GetBuiltinResource <Font>("Arial.ttf"));
 }
示例#2
0
        private void GenerateSlicedSprite(UIVertexHelper vertexHelper, SpriteData sprite, Rect rect, Color color)
        {
            Vector4 outer   = sprite.outerUv;
            Vector4 inner   = sprite.innerUv;
            Vector4 padding = sprite.padding;
            Vector4 border  = sprite.border;

            Vector4 adjustedBorders = border;

            s_VertScratch[0] = new Vector2(padding.x, padding.y);
            s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w);

            s_VertScratch[1].x = adjustedBorders.x;
            s_VertScratch[1].y = adjustedBorders.y;

            s_VertScratch[2].x = rect.width - adjustedBorders.z;
            s_VertScratch[2].y = rect.height - adjustedBorders.w;

            for (int i = 0; i < 4; ++i)
            {
                s_VertScratch[i].x += rect.x;
                s_VertScratch[i].y += rect.y;
            }

            s_UVScratch[0] = new Vector2(outer.x, outer.y);
            s_UVScratch[1] = new Vector2(inner.x, inner.y);
            s_UVScratch[2] = new Vector2(inner.z, inner.w);
            s_UVScratch[3] = new Vector2(outer.z, outer.w);

            vertexHelper.Clear();

            for (int x = 0; x < 3; ++x)
            {
                int x2 = x + 1;

                for (int y = 0; y < 3; ++y)
                {
                    if (!m_FillCenter && x == 1 && y == 1)
                    {
                        continue;
                    }

                    int y2 = y + 1;


                    AddQuad(vertexHelper,
                            new Vector2(s_VertScratch[x].x, s_VertScratch[y].y),
                            new Vector2(s_VertScratch[x2].x, s_VertScratch[y2].y),
                            color,
                            new Vector2(s_UVScratch[x].x, s_UVScratch[y].y),
                            new Vector2(s_UVScratch[x2].x, s_UVScratch[y2].y));
                }
            }
        }
示例#3
0
    protected static void AddQuad(UIVertexHelper vertexHelper, Vector3[] quadPositions, Color32 color, Vector3[] quadUVs)
    {
        int startIndex = vertexHelper.currentVertCount;

        for (int i = 0; i < 4; ++i)
        {
            vertexHelper.AddVert(quadPositions[i], color, quadUVs[i]);
        }

        vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);
        vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);
    }
示例#4
0
    protected static void AddQuad(UIVertexHelper vertexHelper, Vector2 posMin, Vector2 posMax, Color32 color, Vector2 uvMin, Vector2 uvMax)
    {
        int startIndex = vertexHelper.currentVertCount;

        vertexHelper.AddVert(new Vector3(posMin.x, posMin.y, 0), color, new Vector2(uvMin.x, uvMin.y));
        vertexHelper.AddVert(new Vector3(posMin.x, posMax.y, 0), color, new Vector2(uvMin.x, uvMax.y));
        vertexHelper.AddVert(new Vector3(posMax.x, posMax.y, 0), color, new Vector2(uvMax.x, uvMax.y));
        vertexHelper.AddVert(new Vector3(posMax.x, posMin.y, 0), color, new Vector2(uvMax.x, uvMin.y));

        vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);
        vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);
    }
示例#5
0
        private void GenerateSimpleSprite(UIVertexHelper vh, SpriteData sprite, Rect rect, Vector2 pivot, Color color)
        {
            Vector4 v  = GetDrawingDimensions(sprite.padding, sprite.rect.size, pivot, rect, preserveAspect);
            var     uv = sprite.outerUv;

            var color32 = color;

            vh.Clear();
            vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(uv.x, uv.y));
            vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(uv.x, uv.w));
            vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(uv.z, uv.w));
            vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(uv.z, uv.y));

            vh.AddTriangle(0, 1, 2);
            vh.AddTriangle(2, 3, 0);
        }
示例#6
0
        private void RebuildMesh(UIVertexHelper toFill, float pixelsPerUnit)
        {
            float            unitsPerPixel = 1 / pixelsPerUnit;
            IList <UIVertex> verts         = m_TextVerts;
            //Last 4 verts are always a new line... (\n)
            int vertCount = verts.Count - 4;

            for (int i = 0; i < vertCount; ++i)
            {
                int tempVertsIndex = i & 3;
                var vert           = verts[i];
                m_TempVerts[tempVertsIndex]           = vert;
                m_TempVerts[tempVertsIndex].position *= unitsPerPixel;
                if (tempVertsIndex == 3)
                {
                    toFill.AddUIVertexQuad(m_TempVerts);
                }
            }
        }
 public void OnEnable()
 {
     m_Mesh          = new Mesh();
     m_VertexHelper  = new UIVertexHelper();
     m_PropertyBlock = new MaterialPropertyBlock();
     m_MainTexProp   = Shader.PropertyToID("_MainTex");
     if (m_DefaultMaterial == null)
     {
         m_DefaultMaterial = new Material(Shader.Find("Sprites/Default"))
         {
             hideFlags = HideFlags.DontSave
         }
     }
     ;
     if (m_Material.value == null)
     {
         m_Material.SetDefaultValue(m_DefaultMaterial);
     }
 }
示例#8
0
        private void GenerateSprite(UIVertexHelper vh, SpriteData sprite, Rect rect, Vector2 pivot, Color color)
        {
            var spriteSize = new Vector2(sprite.rect.width, sprite.rect.height);

            // Covert sprite pivot into normalized space.
            var  spritePivot = sprite.pivot / spriteSize;
            var  rectPivot   = pivot;
            Rect r           = rect;

            if (preserveAspect & spriteSize.sqrMagnitude > 0.0f)
            {
                PreserveSpriteAspectRatio(ref r, spriteSize, pivot);
            }

            var drawingSize     = new Vector2(r.width, r.height);
            var spriteBoundSize = sprite.bounds.size;

            // Calculate the drawing offset based on the difference between the two pivots.
            var drawOffset = (rectPivot - spritePivot) * drawingSize;

            var color32 = color;

            vh.Clear();

            Vector2[] vertices = sprite.vertices;
            Vector2[] uvs      = sprite.uvs;
            for (int i = 0; i < vertices.Length; ++i)
            {
                vh.AddVert(new Vector3((vertices[i].x / spriteBoundSize.x) * drawingSize.x - drawOffset.x, (vertices[i].y / spriteBoundSize.y) * drawingSize.y - drawOffset.y), color32, new Vector2(uvs[i].x, uvs[i].y));
            }

            UInt16[] triangles = sprite.triangles;
            for (int i = 0; i < triangles.Length; i += 3)
            {
                vh.AddTriangle(triangles[i + 0], triangles[i + 1], triangles[i + 2]);
            }
        }
        private void GenerateTiledSprite(UIVertexHelper toFill, SpriteData sprite, Rect rect, Color color)
        {
            bool    hasBorder  = sprite.hasBorder;
            Vector4 outer      = sprite.outerUv;
            Vector4 inner      = sprite.innerUv;
            Vector4 border     = sprite.border;
            Vector2 spriteSize = sprite.rect.size;

            float tileWidth  = (spriteSize.x - border.x - border.z);
            float tileHeight = (spriteSize.y - border.y - border.w);

            var uvMin = new Vector2(inner.x, inner.y);
            var uvMax = new Vector2(inner.z, inner.w);

            // Min to max max range for tiled region in coordinates relative to lower left corner.
            float xMin = border.x;
            float xMax = rect.width - border.z;
            float yMin = border.y;
            float yMax = rect.height - border.w;

            toFill.Clear();
            var clipped = uvMax;

            // if either width is zero we cant tile so just assume it was the full width.
            if (tileWidth <= 0)
            {
                tileWidth = xMax - xMin;
            }

            if (tileHeight <= 0)
            {
                tileHeight = yMax - yMin;
            }

            if (sprite.hasSprite && (hasBorder || sprite.packed || sprite.wrapMode != TextureWrapMode.Repeat))
            {
                // Sprite has border, or is not in repeat mode, or cannot be repeated because of packing.
                // We cannot use texture tiling so we will generate a mesh of quads to tile the texture.

                // Evaluate how many vertices we will generate. Limit this number to something sane,
                // especially since meshes can not have more than 65000 vertices.

                long nTilesW = 0;
                long nTilesH = 0;
                if (m_FillCenter)
                {
                    nTilesW = (long)System.Math.Ceiling((xMax - xMin) / tileWidth);
                    nTilesH = (long)System.Math.Ceiling((yMax - yMin) / tileHeight);

                    double nVertices = 0;
                    if (hasBorder)
                    {
                        nVertices = (nTilesW + 2.0) * (nTilesH + 2.0) * 4.0;                         // 4 vertices per tile
                    }
                    else
                    {
                        nVertices = nTilesW * nTilesH * 4.0;                         // 4 vertices per tile
                    }

                    if (nVertices > 65000.0)
                    {
                        Debug.LogError("Too many sprite tiles on Image \"" + name + "\". The tile size will be increased. To remove the limit on the number of tiles, convert the Sprite to an Advanced texture, remove the borders, clear the Packing tag and set the Wrap mode to Repeat.");

                        double maxTiles = 65000.0 / 4.0;                         // Max number of vertices is 65000; 4 vertices per tile.
                        double imageRatio;
                        if (hasBorder)
                        {
                            imageRatio = (nTilesW + 2.0) / (nTilesH + 2.0);
                        }
                        else
                        {
                            imageRatio = (double)nTilesW / nTilesH;
                        }

                        double targetTilesW = System.Math.Sqrt(maxTiles / imageRatio);
                        double targetTilesH = targetTilesW * imageRatio;
                        if (hasBorder)
                        {
                            targetTilesW -= 2;
                            targetTilesH -= 2;
                        }

                        nTilesW    = (long)System.Math.Floor(targetTilesW);
                        nTilesH    = (long)System.Math.Floor(targetTilesH);
                        tileWidth  = (xMax - xMin) / nTilesW;
                        tileHeight = (yMax - yMin) / nTilesH;
                    }
                }
                else
                {
                    if (hasBorder)
                    {
                        // Texture on the border is repeated only in one direction.
                        nTilesW = (long)System.Math.Ceiling((xMax - xMin) / tileWidth);
                        nTilesH = (long)System.Math.Ceiling((yMax - yMin) / tileHeight);
                        double nVertices = (nTilesH + nTilesW + 2.0 /*corners*/) * 2.0 /*sides*/ * 4.0 /*vertices per tile*/;
                        if (nVertices > 65000.0)
                        {
                            Debug.LogError("Too many sprite tiles on Image \"" + name + "\". The tile size will be increased. To remove the limit on the number of tiles, convert the Sprite to an Advanced texture, remove the borders, clear the Packing tag and set the Wrap mode to Repeat.");

                            double maxTiles     = 65000.0 / 4.0;                         // Max number of vertices is 65000; 4 vertices per tile.
                            double imageRatio   = (double)nTilesW / nTilesH;
                            double targetTilesW = (maxTiles - 4 /*corners*/) / (2 * (1.0 + imageRatio));
                            double targetTilesH = targetTilesW * imageRatio;

                            nTilesW    = (long)System.Math.Floor(targetTilesW);
                            nTilesH    = (long)System.Math.Floor(targetTilesH);
                            tileWidth  = (xMax - xMin) / nTilesW;
                            tileHeight = (yMax - yMin) / nTilesH;
                        }
                    }
                    else
                    {
                        nTilesH = nTilesW = 0;
                    }
                }

                if (m_FillCenter)
                {
                    // TODO: we could share vertices between quads. If vertex sharing is implemented. update the computation for the number of vertices accordingly.
                    for (long j = 0; j < nTilesH; j++)
                    {
                        float y1 = yMin + j * tileHeight;
                        float y2 = yMin + (j + 1) * tileHeight;
                        if (y2 > yMax)
                        {
                            clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1);
                            y2        = yMax;
                        }
                        clipped.x = uvMax.x;
                        for (long i = 0; i < nTilesW; i++)
                        {
                            float x1 = xMin + i * tileWidth;
                            float x2 = xMin + (i + 1) * tileWidth;
                            if (x2 > xMax)
                            {
                                clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1);
                                x2        = xMax;
                            }
                            AddQuad(toFill, new Vector2(x1, y1) + rect.position, new Vector2(x2, y2) + rect.position, color, uvMin, clipped);
                        }
                    }
                }
                if (hasBorder)
                {
                    clipped = uvMax;
                    for (long j = 0; j < nTilesH; j++)
                    {
                        float y1 = yMin + j * tileHeight;
                        float y2 = yMin + (j + 1) * tileHeight;
                        if (y2 > yMax)
                        {
                            clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1);
                            y2        = yMax;
                        }
                        AddQuad(toFill,
                                new Vector2(0, y1) + rect.position,
                                new Vector2(xMin, y2) + rect.position,
                                color,
                                new Vector2(outer.x, uvMin.y),
                                new Vector2(uvMin.x, clipped.y));
                        AddQuad(toFill,
                                new Vector2(xMax, y1) + rect.position,
                                new Vector2(rect.width, y2) + rect.position,
                                color,
                                new Vector2(uvMax.x, uvMin.y),
                                new Vector2(outer.z, clipped.y));
                    }

                    // Bottom and top tiled border
                    clipped = uvMax;
                    for (long i = 0; i < nTilesW; i++)
                    {
                        float x1 = xMin + i * tileWidth;
                        float x2 = xMin + (i + 1) * tileWidth;
                        if (x2 > xMax)
                        {
                            clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1);
                            x2        = xMax;
                        }
                        AddQuad(toFill,
                                new Vector2(x1, 0) + rect.position,
                                new Vector2(x2, yMin) + rect.position,
                                color,
                                new Vector2(uvMin.x, outer.y),
                                new Vector2(clipped.x, uvMin.y));
                        AddQuad(toFill,
                                new Vector2(x1, yMax) + rect.position,
                                new Vector2(x2, rect.height) + rect.position,
                                color,
                                new Vector2(uvMin.x, uvMax.y),
                                new Vector2(clipped.x, outer.w));
                    }

                    // Corners
                    AddQuad(toFill,
                            new Vector2(0, 0) + rect.position,
                            new Vector2(xMin, yMin) + rect.position,
                            color,
                            new Vector2(outer.x, outer.y),
                            new Vector2(uvMin.x, uvMin.y));
                    AddQuad(toFill,
                            new Vector2(xMax, 0) + rect.position,
                            new Vector2(rect.width, yMin) + rect.position,
                            color,
                            new Vector2(uvMax.x, outer.y),
                            new Vector2(outer.z, uvMin.y));
                    AddQuad(toFill,
                            new Vector2(0, yMax) + rect.position,
                            new Vector2(xMin, rect.height) + rect.position,
                            color,
                            new Vector2(outer.x, uvMax.y),
                            new Vector2(uvMin.x, outer.w));
                    AddQuad(toFill,
                            new Vector2(xMax, yMax) + rect.position,
                            new Vector2(rect.width, rect.height) + rect.position,
                            color,
                            new Vector2(uvMax.x, uvMax.y),
                            new Vector2(outer.z, outer.w));
                }
            }
            else
            {
                // Texture has no border, is in repeat mode and not packed. Use texture tiling.
                Vector2 uvScale = new Vector2((xMax - xMin) / tileWidth, (yMax - yMin) / tileHeight);

                if (m_FillCenter)
                {
                    AddQuad(toFill, new Vector2(xMin, yMin) + rect.position, new Vector2(xMax, yMax) + rect.position, color, Vector2.Scale(uvMin, uvScale), Vector2.Scale(uvMax, uvScale));
                }
            }
        }
        void GenerateFilledSprite(UIVertexHelper toFill, SpriteData sprite, Rect rect, Vector2 pivot, Color color, float fillAmount)
        {
            toFill.Clear();

            if (fillAmount < 0.001f)
            {
                return;
            }

            Vector4  v     = GetDrawingDimensions(sprite.padding, sprite.rect.size, pivot, rect, preserveAspect);
            Vector4  outer = sprite.outerUv;
            UIVertex uiv   = UIVertex.simpleVert;

            uiv.color = color;

            float tx0 = outer.x;
            float ty0 = outer.y;
            float tx1 = outer.z;
            float ty1 = outer.w;

            // Horizontal and vertical filled sprites are simple -- just end the Image prematurely
            if (m_FillMethod == Image.FillMethod.Horizontal || m_FillMethod == Image.FillMethod.Vertical)
            {
                if (m_FillMethod == Image.FillMethod.Horizontal)
                {
                    float fill = (tx1 - tx0) * fillAmount;

                    if (m_FillOrigin == 1)
                    {
                        v.x = v.z - (v.z - v.x) * fillAmount;
                        tx0 = tx1 - fill;
                    }
                    else
                    {
                        v.z = v.x + (v.z - v.x) * fillAmount;
                        tx1 = tx0 + fill;
                    }
                }
                else if (fillMethod == Image.FillMethod.Vertical)
                {
                    float fill = (ty1 - ty0) * fillAmount;

                    if (m_FillOrigin == 1)
                    {
                        v.y = v.w - (v.w - v.y) * fillAmount;
                        ty0 = ty1 - fill;
                    }
                    else
                    {
                        v.w = v.y + (v.w - v.y) * fillAmount;
                        ty1 = ty0 + fill;
                    }
                }
            }

            s_Xy[0] = new Vector2(v.x, v.y);
            s_Xy[1] = new Vector2(v.x, v.w);
            s_Xy[2] = new Vector2(v.z, v.w);
            s_Xy[3] = new Vector2(v.z, v.y);

            s_Uv[0] = new Vector2(tx0, ty0);
            s_Uv[1] = new Vector2(tx0, ty1);
            s_Uv[2] = new Vector2(tx1, ty1);
            s_Uv[3] = new Vector2(tx1, ty0);

            {
                if (fillAmount < 1f && m_FillMethod != Image.FillMethod.Horizontal && m_FillMethod != Image.FillMethod.Vertical)
                {
                    if (fillMethod == Image.FillMethod.Radial90)
                    {
                        if (RadialCut(s_Xy, s_Uv, fillAmount, m_FillClockwise, m_FillOrigin))
                        {
                            AddQuad(toFill, s_Xy, color, s_Uv);
                        }
                    }
                    else if (fillMethod == Image.FillMethod.Radial180)
                    {
                        for (int side = 0; side < 2; ++side)
                        {
                            float fx0, fx1, fy0, fy1;
                            int   even = m_FillOrigin > 1 ? 1 : 0;

                            if (m_FillOrigin == 0 || m_FillOrigin == 2)
                            {
                                fy0 = 0f;
                                fy1 = 1f;
                                if (side == even)
                                {
                                    fx0 = 0f;
                                    fx1 = 0.5f;
                                }
                                else
                                {
                                    fx0 = 0.5f;
                                    fx1 = 1f;
                                }
                            }
                            else
                            {
                                fx0 = 0f;
                                fx1 = 1f;
                                if (side == even)
                                {
                                    fy0 = 0.5f;
                                    fy1 = 1f;
                                }
                                else
                                {
                                    fy0 = 0f;
                                    fy1 = 0.5f;
                                }
                            }

                            s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0);
                            s_Xy[1].x = s_Xy[0].x;
                            s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1);
                            s_Xy[3].x = s_Xy[2].x;

                            s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0);
                            s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1);
                            s_Xy[2].y = s_Xy[1].y;
                            s_Xy[3].y = s_Xy[0].y;

                            s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0);
                            s_Uv[1].x = s_Uv[0].x;
                            s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1);
                            s_Uv[3].x = s_Uv[2].x;

                            s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0);
                            s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1);
                            s_Uv[2].y = s_Uv[1].y;
                            s_Uv[3].y = s_Uv[0].y;

                            float val = m_FillClockwise ? fillAmount * 2f - side : fillAmount * 2f - (1 - side);

                            if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((side + m_FillOrigin + 3) % 4)))
                            {
                                AddQuad(toFill, s_Xy, color, s_Uv);
                            }
                        }
                    }
                    else if (fillMethod == Image.FillMethod.Radial360)
                    {
                        for (int corner = 0; corner < 4; ++corner)
                        {
                            float fx0, fx1, fy0, fy1;

                            if (corner < 2)
                            {
                                fx0 = 0f;
                                fx1 = 0.5f;
                            }
                            else
                            {
                                fx0 = 0.5f;
                                fx1 = 1f;
                            }

                            if (corner == 0 || corner == 3)
                            {
                                fy0 = 0f;
                                fy1 = 0.5f;
                            }
                            else
                            {
                                fy0 = 0.5f;
                                fy1 = 1f;
                            }

                            s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0);
                            s_Xy[1].x = s_Xy[0].x;
                            s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1);
                            s_Xy[3].x = s_Xy[2].x;

                            s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0);
                            s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1);
                            s_Xy[2].y = s_Xy[1].y;
                            s_Xy[3].y = s_Xy[0].y;

                            s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0);
                            s_Uv[1].x = s_Uv[0].x;
                            s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1);
                            s_Uv[3].x = s_Uv[2].x;

                            s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0);
                            s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1);
                            s_Uv[2].y = s_Uv[1].y;
                            s_Uv[3].y = s_Uv[0].y;

                            float val = m_FillClockwise ?
                                        fillAmount * 4f - ((corner + m_FillOrigin) % 4) :
                                        fillAmount * 4f - (3 - ((corner + m_FillOrigin) % 4));

                            if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((corner + 2) % 4)))
                            {
                                AddQuad(toFill, s_Xy, color, s_Uv);
                            }
                        }
                    }
                }
                else
                {
                    AddQuad(toFill, s_Xy, color, s_Uv);
                }
            }
        }