Ejemplo n.º 1
0
    static float GetYAnchorForHeight(float textHeight, GeomData geomData)
    {
        tk2dTextMeshData data      = geomData.textMeshData;
        tk2dFontData     _fontInst = geomData.fontInst;

        int   heightAnchor = (int)data.anchor / 3;
        float lineHeight   = (_fontInst.lineHeight + data.lineSpacing) * data.scale.y;

        switch (heightAnchor)
        {
        case 0: return(-lineHeight);

        case 1:
        {
            float y = -textHeight / 2.0f - lineHeight;
            if (_fontInst.version >= 2)
            {
                float ty = _fontInst.texelSize.y * data.scale.y;
                return(Mathf.Floor(y / ty) * ty);
            }
            else
            {
                return(y);
            }
        }

        case 2: return(-textHeight - lineHeight);
        }
        return(-lineHeight);
    }
 public static GeomData Data(tk2dTextMeshData textMeshData, tk2dFontData fontData, string formattedText)
 {
     tmpData.textMeshData = textMeshData;
     tmpData.fontInst = fontData;
     tmpData.formattedText = formattedText;
     return tmpData;
 }
Ejemplo n.º 3
0
 // Use this to get a correctly set up textgeomdata object
 // This uses a static global tmpData object and is not thread safe
 // Fortunately for us, neither is the rest of Unity.
 public static GeomData Data(tk2dTextMeshData textMeshData, tk2dFontData fontData, string formattedText)
 {
     tmpData.textMeshData  = textMeshData;
     tmpData.fontInst      = fontData;
     tmpData.formattedText = formattedText;
     return(tmpData);
 }
Ejemplo n.º 4
0
    public static void GetTextMeshGeomDesc(out int numVertices, out int numIndices, GeomData geomData)
    {
        tk2dTextMeshData data = geomData.textMeshData;

        numVertices = data.maxChars * 4;
        numIndices  = data.maxChars * 6;
    }
Ejemplo n.º 5
0
    static float GetXAnchorForWidth(float lineWidth, GeomData geomData)
    {
        tk2dTextMeshData data      = geomData.textMeshData;
        tk2dFontData     _fontInst = geomData.fontInst;

        int widthAnchor = (int)data.anchor % 3;

        switch (widthAnchor)
        {
        case 0: return(0.0f); // left

        case 1:               // center
        {
            float x = -lineWidth / 2.0f;
            if (_fontInst.version >= 2)
            {
                float tx = _fontInst.texelSize.x * data.scale.x;
                return(Mathf.Floor(x / tx) * tx);
            }
            return(x);
        }

        case 2: return(-lineWidth);        // right
        }
        return(0.0f);
    }
    // this function is static to ensure that no fields are changed during this call
    private static tk2dColoredText FormatTextImpl(string txt, tk2dTextMeshData meshData)
    {
        string          localizedString = LocalisationManager.LocalizedStringOrSource(txt);
        tk2dColoredText result          = new tk2dColoredText(localizedString, meshData.colorS);

        ConvertString(result, meshData);

        return(result);
    }
Ejemplo n.º 7
0
    public static void SetTextMeshIndices(int[] indices, int offset, int vStart, GeomData geomData, int target)
    {
        tk2dTextMeshData data = geomData.textMeshData;

        for (int i = 0; i < data.maxChars; ++i)
        {
            indices[offset + i * 6 + 0] = vStart + i * 4 + 0;
            indices[offset + i * 6 + 1] = vStart + i * 4 + 1;
            indices[offset + i * 6 + 2] = vStart + i * 4 + 3;
            indices[offset + i * 6 + 3] = vStart + i * 4 + 2;
            indices[offset + i * 6 + 4] = vStart + i * 4 + 0;
            indices[offset + i * 6 + 5] = vStart + i * 4 + 3;
        }
    }
Ejemplo n.º 8
0
    /// <summary>
    /// Calculates the mesh dimensions for the given string
    /// and returns a width and height.
    /// </summary>
    public static Vector2 GetMeshDimensionsForString(this tk2dTextMeshData geomData, tk2dColoredText inputText, int startIdx, int count)
    {
        tk2dTextMeshData data      = geomData;
        tk2dFontData     _fontInst = data.FontInst;

        float maxWidth = 0.0f;

        float cursorX = 0.0f;
        float cursorY = 0.0f;

        for (int i = startIdx; (i < inputText.Length) && (i < (startIdx + count)); ++i)
        {
            int idx = inputText[i];
            if (idx == '\n')
            {
                maxWidth = Mathf.Max(cursorX, maxWidth);
                cursorX  = 0.0f;
                cursorY -= data.ActualLineSpaceHeight;
            }
            else
            {
                // Get the character from dictionary / array
                tk2dFontChar chr = _fontInst.GetCharForIndex(idx, 0);

                cursorX += (chr.advance + data.Spacing) * data.TotalScale.x;
                if (data.kerning && i < inputText.Length - 1)
                {
                    foreach (var k in _fontInst.kerning)
                    {
                        if (k.c0 == inputText[i] && k.c1 == inputText[i + 1])
                        {
                            cursorX += k.amount * data.TotalScale.x;
                            break;
                        }
                    }
                }
            }
        }

        maxWidth = Mathf.Max(cursorX, maxWidth);
        cursorY -= data.ActualLineHeight;

        return(new Vector2(maxWidth, cursorY));
    }
Ejemplo n.º 9
0
    public static float GetYAnchorForHeight(this tk2dTextMeshData geomData, float textHeight)
    {
        tk2dTextMeshData data      = geomData;
        tk2dFontData     _fontInst = data.FontInst;

        float lineHeight = data.ActualLineHeight;

        switch (data.anchor)
        {
        case TextAnchor.UpperCenter:
        case TextAnchor.UpperLeft:
        case TextAnchor.UpperRight:
            return(-lineHeight);

        case TextAnchor.MiddleCenter:
        case TextAnchor.MiddleLeft:
        case TextAnchor.MiddleRight:
        {
            float y = -textHeight / 2.0f - lineHeight;
            if (_fontInst.version >= 2)
            {
                float ty = _fontInst.texelSize.y * data.TotalScale.y;
                return(Mathf.Floor(y / ty) * ty);
            }
            else
            {
                return(y);
            }
        }

        case TextAnchor.LowerCenter:
        case TextAnchor.LowerLeft:
        case TextAnchor.LowerRight:
            return(-textHeight - lineHeight);
        }

        return(-lineHeight);
    }
Ejemplo n.º 10
0
    public static int SetTextMeshGeom(Vector3[] pos, Vector2[] uv, Vector2[] uv2, Color32[] color, int offset, GeomData geomData)
    {
        tk2dTextMeshData data          = geomData.textMeshData;
        tk2dFontData     fontInst      = geomData.fontInst;
        string           formattedText = geomData.formattedText;

        meshTopColor     = new Color32(255, 255, 255, 255);
        meshBottomColor  = new Color32(255, 255, 255, 255);
        meshGradientTexU = (float)data.textureGradient / (float)((fontInst.gradientCount > 0) ? fontInst.gradientCount : 1);
        curGradientCount = fontInst.gradientCount;

        Vector2 dims    = GetMeshDimensionsForString(geomData.formattedText, geomData);
        float   offsetY = GetYAnchorForHeight(dims.y, geomData);

        float cursorX          = 0.0f;
        float cursorY          = 0.0f;
        int   target           = 0;
        int   alignStartTarget = 0;

        for (int i = 0; i < formattedText.Length && target < data.maxChars; ++i)
        {
            int          idx = formattedText[i];
            tk2dFontChar chr;

            bool inlineHatChar = (idx == '^');

            if (fontInst.useDictionary)
            {
                if (!fontInst.charDict.ContainsKey(idx))
                {
                    idx = 0;
                }
                chr = fontInst.charDict[idx];
            }
            else
            {
                if (idx >= fontInst.chars.Length)
                {
                    idx = 0;                                               // should be space
                }
                chr = fontInst.chars[idx];
            }

            if (inlineHatChar)
            {
                idx = '^';
            }

            if (idx == '\n')
            {
                float lineWidth      = cursorX;
                int   alignEndTarget = target;               // this is one after the last filled character
                if (alignStartTarget != target)
                {
                    float xOffset = GetXAnchorForWidth(lineWidth, geomData);
                    PostAlignTextData(pos, offset, alignStartTarget, alignEndTarget, xOffset);
                }


                alignStartTarget = target;
                cursorX          = 0.0f;
                cursorY         -= (fontInst.lineHeight + data.lineSpacing) * data.scale.y;
                continue;
            }
            else if (data.inlineStyling)
            {
                if (idx == '^')
                {
                    if (i + 1 < formattedText.Length && formattedText[i + 1] == '^')
                    {
                        ++i;
                    }
                    else
                    {
                        i += HandleStyleCommand(formattedText.Substring(i + 1));
                        continue;
                    }
                }
            }

            pos[offset + target * 4 + 0] = new Vector3(cursorX + chr.p0.x * data.scale.x, offsetY + cursorY + chr.p0.y * data.scale.y, 0);
            pos[offset + target * 4 + 1] = new Vector3(cursorX + chr.p1.x * data.scale.x, offsetY + cursorY + chr.p0.y * data.scale.y, 0);
            pos[offset + target * 4 + 2] = new Vector3(cursorX + chr.p0.x * data.scale.x, offsetY + cursorY + chr.p1.y * data.scale.y, 0);
            pos[offset + target * 4 + 3] = new Vector3(cursorX + chr.p1.x * data.scale.x, offsetY + cursorY + chr.p1.y * data.scale.y, 0);

            if (chr.flipped)
            {
                uv[offset + target * 4 + 0] = new Vector2(chr.uv1.x, chr.uv1.y);
                uv[offset + target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
                uv[offset + target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
                uv[offset + target * 4 + 3] = new Vector2(chr.uv0.x, chr.uv0.y);
            }
            else
            {
                uv[offset + target * 4 + 0] = new Vector2(chr.uv0.x, chr.uv0.y);
                uv[offset + target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
                uv[offset + target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
                uv[offset + target * 4 + 3] = new Vector2(chr.uv1.x, chr.uv1.y);
            }

            if (fontInst.textureGradients)
            {
                uv2[offset + target * 4 + 0] = chr.gradientUv[0] + new Vector2(meshGradientTexU, 0);
                uv2[offset + target * 4 + 1] = chr.gradientUv[1] + new Vector2(meshGradientTexU, 0);
                uv2[offset + target * 4 + 2] = chr.gradientUv[2] + new Vector2(meshGradientTexU, 0);
                uv2[offset + target * 4 + 3] = chr.gradientUv[3] + new Vector2(meshGradientTexU, 0);
            }

            if (fontInst.isPacked)
            {
                Color32 c = channelSelectColors[chr.channel];
                color[offset + target * 4 + 0] = c;
                color[offset + target * 4 + 1] = c;
                color[offset + target * 4 + 2] = c;
                color[offset + target * 4 + 3] = c;
            }
            else
            {
                color[offset + target * 4 + 0] = meshTopColor;
                color[offset + target * 4 + 1] = meshTopColor;
                color[offset + target * 4 + 2] = meshBottomColor;
                color[offset + target * 4 + 3] = meshBottomColor;
            }

            cursorX += (chr.advance + data.spacing) * data.scale.x;

            if (data.kerning && i < formattedText.Length - 1)
            {
                foreach (var k in fontInst.kerning)
                {
                    if (k.c0 == formattedText[i] && k.c1 == formattedText[i + 1])
                    {
                        cursorX += k.amount * data.scale.x;
                        break;
                    }
                }
            }

            ++target;
        }

        if (alignStartTarget != target)
        {
            float lineWidth      = cursorX;
            int   alignEndTarget = target;
            float xOffset        = GetXAnchorForWidth(lineWidth, geomData);
            PostAlignTextData(pos, offset, alignStartTarget, alignEndTarget, xOffset);
        }

        for (int i = target; i < data.maxChars; ++i)
        {
            pos[offset + i * 4 + 0] = pos[offset + i * 4 + 1] = pos[offset + i * 4 + 2] = pos[offset + i * 4 + 3] = Vector3.zero;
            uv[offset + i * 4 + 0]  = uv[offset + i * 4 + 1] = uv[offset + i * 4 + 2] = uv[offset + i * 4 + 3] = Vector2.zero;
            if (fontInst.textureGradients)
            {
                uv2[offset + i * 4 + 0] = uv2[offset + i * 4 + 1] = uv2[offset + i * 4 + 2] = uv2[offset + i * 4 + 3] = Vector2.zero;
            }

            if (!fontInst.isPacked)
            {
                color[offset + i * 4 + 0] = color[offset + i * 4 + 1] = meshTopColor;
                color[offset + i * 4 + 2] = color[offset + i * 4 + 3] = meshBottomColor;
            }
            else
            {
                color[offset + i * 4 + 0] = color[offset + i * 4 + 1] = color[offset + i * 4 + 2] = color[offset + i * 4 + 3] = Color.clear;
            }
        }

        return(target);
    }
Ejemplo n.º 11
0
    /// <summary>
    /// Calculates the mesh dimensions for the given string
    /// and returns a width and height.
    /// </summary>
    public static Vector2 GetMeshDimensionsForString(string str, GeomData geomData)
    {
        tk2dTextMeshData data      = geomData.textMeshData;
        tk2dFontData     _fontInst = geomData.fontInst;

        float maxWidth = 0.0f;

        float cursorX = 0.0f;
        float cursorY = 0.0f;

        bool ignoreNextCharacter = false;
        int  target = 0;

        for (int i = 0; i < str.Length && target < data.maxChars; ++i)
        {
            if (ignoreNextCharacter)
            {
                ignoreNextCharacter = false;
                continue;
            }

            int idx = str[i];
            if (idx == '\n')
            {
                maxWidth = Mathf.Max(cursorX, maxWidth);
                cursorX  = 0.0f;
                cursorY -= (_fontInst.lineHeight + data.lineSpacing) * data.scale.y;
                continue;
            }
            else if (data.inlineStyling)
            {
                if (idx == '^' && i + 1 < str.Length)
                {
                    if (str[i + 1] == '^')
                    {
                        ignoreNextCharacter = true;
                    }
                    else
                    {
                        int cmdLength = 0;
                        switch (str[i + 1])
                        {
                        case 'c': cmdLength = 5; break;

                        case 'C': cmdLength = 9; break;

                        case 'g': cmdLength = 9; break;

                        case 'G': cmdLength = 17; break;
                        }
                        i += cmdLength;
                        continue;
                    }
                }
            }

            bool inlineHatChar = (idx == '^');

            // Get the character from dictionary / array
            tk2dFontChar chr;
            if (_fontInst.useDictionary)
            {
                if (!_fontInst.charDict.ContainsKey(idx))
                {
                    idx = 0;
                }
                chr = _fontInst.charDict[idx];
            }
            else
            {
                if (idx >= _fontInst.chars.Length)
                {
                    idx = 0;                                                // should be space
                }
                chr = _fontInst.chars[idx];
            }

            if (inlineHatChar)
            {
                idx = '^';
            }

            cursorX += (chr.advance + data.spacing) * data.scale.x;
            if (data.kerning && i < str.Length - 1)
            {
                foreach (var k in _fontInst.kerning)
                {
                    if (k.c0 == str[i] && k.c1 == str[i + 1])
                    {
                        cursorX += k.amount * data.scale.x;
                        break;
                    }
                }
            }

            ++target;
        }

        maxWidth = Mathf.Max(cursorX, maxWidth);
        cursorY -= (_fontInst.lineHeight + data.lineSpacing) * data.scale.y;

        return(new Vector2(maxWidth, cursorY));
    }
Ejemplo n.º 12
0
    void DrawEditorGUI()
    {
        if (GUILayout.Button("Commit"))
        {
            // Select all children, EXCLUDING self
            Transform[] allTransforms = batcher.transform.GetComponentsInChildren <Transform>();
            allTransforms = (from t in allTransforms where t != batcher.transform select t).ToArray();

            // sort sprites, smaller to larger z
            if (batcher.CheckFlag(tk2dStaticSpriteBatcher.Flags.SortToCamera))
            {
                tk2dCamera tk2dCam = tk2dCamera.CameraForLayer(batcher.gameObject.layer);
                Camera     cam     = tk2dCam ? tk2dCam.GetComponent <Camera>() : Camera.main;
                allTransforms = (from t in allTransforms orderby cam.WorldToScreenPoint((t.GetComponent <Renderer>() != null) ? t.GetComponent <Renderer>().bounds.center : t.position).z descending select t).ToArray();
            }
            else
            {
                allTransforms = (from t in allTransforms orderby t.GetComponent <Renderer>().bounds.center.z descending select t).ToArray();
            }

            // and within the z sort by material
            if (allTransforms.Length == 0)
            {
                EditorUtility.DisplayDialog("StaticSpriteBatcher", "Error: No child objects found", "Ok");
                return;
            }

            Dictionary <Transform, int> batchedSpriteLookup = new Dictionary <Transform, int>();
            batchedSpriteLookup[batcher.transform] = -1;

            Matrix4x4 batcherWorldToLocal = batcher.transform.worldToLocalMatrix;

            batcher.spriteCollection = null;
            batcher.batchedSprites   = new tk2dBatchedSprite[allTransforms.Length];
            List <tk2dTextMeshData> allTextMeshData = new List <tk2dTextMeshData>();

            int currBatchedSprite = 0;
            foreach (var t in allTransforms)
            {
                tk2dBaseSprite baseSprite = t.GetComponent <tk2dBaseSprite>();
                tk2dTextMesh   textmesh   = t.GetComponent <tk2dTextMesh>();

                tk2dBatchedSprite bs = new tk2dBatchedSprite();
                bs.name           = t.gameObject.name;
                bs.position       = t.localPosition;
                bs.rotation       = t.localRotation;
                bs.relativeMatrix = batcherWorldToLocal * t.localToWorldMatrix;

                if (baseSprite)
                {
                    bs.baseScale  = Vector3.one;
                    bs.localScale = new Vector3(t.localScale.x * baseSprite.scale.x, t.localScale.y * baseSprite.scale.y, t.localScale.z * baseSprite.scale.z);
                    FillBatchedSprite(bs, t.gameObject);

                    // temp redundant - just incase batcher expects to point to a valid one, somewhere we've missed
                    batcher.spriteCollection = baseSprite.Collection;
                }
                else if (textmesh)
                {
                    bs.spriteCollection = null;

                    bs.type          = tk2dBatchedSprite.Type.TextMesh;
                    bs.color         = textmesh.color;
                    bs.baseScale     = textmesh.scale;
                    bs.renderLayer   = textmesh.SortingOrder;
                    bs.localScale    = new Vector3(t.localScale.x * textmesh.scale.x, t.localScale.y * textmesh.scale.y, t.localScale.z * textmesh.scale.z);
                    bs.FormattedText = textmesh.FormattedText;

                    tk2dTextMeshData tmd = new tk2dTextMeshData();
                    tmd.font            = textmesh.font;
                    tmd.text            = textmesh.text;
                    tmd.color           = textmesh.color;
                    tmd.color2          = textmesh.color2;
                    tmd.useGradient     = textmesh.useGradient;
                    tmd.textureGradient = textmesh.textureGradient;
                    tmd.anchor          = textmesh.anchor;
                    tmd.kerning         = textmesh.kerning;
                    tmd.maxChars        = textmesh.maxChars;
                    tmd.inlineStyling   = textmesh.inlineStyling;
                    tmd.formatting      = textmesh.formatting;
                    tmd.wordWrapWidth   = textmesh.wordWrapWidth;
                    tmd.spacing         = textmesh.Spacing;
                    tmd.lineSpacing     = textmesh.LineSpacing;

                    bs.xRefId = allTextMeshData.Count;
                    allTextMeshData.Add(tmd);
                }
                else
                {
                    // Empty GameObject
                    bs.spriteId   = -1;
                    bs.baseScale  = Vector3.one;
                    bs.localScale = t.localScale;
                    bs.type       = tk2dBatchedSprite.Type.EmptyGameObject;
                }


                batchedSpriteLookup[t] = currBatchedSprite;
                batcher.batchedSprites[currBatchedSprite++] = bs;
            }
            batcher.allTextMeshData = allTextMeshData.ToArray();

            int idx = 0;
            foreach (var t in allTransforms)
            {
                var bs = batcher.batchedSprites[idx];

                bs.parentId = batchedSpriteLookup[t.parent];
                t.parent    = batcher.transform;              // unparent
                ++idx;
            }

            Transform[] directChildren = (from t in allTransforms where t.parent == batcher.transform select t).ToArray();
            foreach (var t in directChildren)
            {
                GameObject.DestroyImmediate(t.gameObject);
            }

            Vector3 inverseScale = new Vector3(1.0f / batcher.scale.x, 1.0f / batcher.scale.y, 1.0f / batcher.scale.z);
            batcher.transform.localScale = Vector3.Scale(batcher.transform.localScale, inverseScale);
            batcher.Build();
            EditorUtility.SetDirty(target);
        }
    }
    void DrawEditorGUI()
    {
        if (GUILayout.Button("Commit"))
        {
            // Select all children, EXCLUDING self
            Transform[] allTransforms = batcher.transform.GetComponentsInChildren <Transform>();

            List <Transform> tempAllTransforms = new List <Transform>();
            foreach (Transform t in allTransforms)
            {
                if (t != batcher.transform)
                {
                    tempAllTransforms.Add(t);
                }
            }

            allTransforms = tempAllTransforms.ToArray();


#if !(UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_1 || UNITY_4_2)
            Renderer[] allRenderers = batcher.transform.GetComponentsInChildren <Renderer>();

            List <Renderer> tempAllRenderers = new List <Renderer>();
            foreach (Renderer r in allRenderers)
            {
                if (r != batcher.GetComponent <Renderer>())
                {
                    tempAllRenderers.Add(r);
                }
            }

            allRenderers = tempAllRenderers.ToArray();


            if (allRenderers.Length > 0)
            {
                string sortingLayerName = allRenderers[0].sortingLayerName;
                int    sortingOrder     = allRenderers[0].sortingOrder;
                foreach (Renderer r in allRenderers)
                {
                    if (sortingLayerName != r.sortingLayerName ||
                        sortingOrder != r.sortingOrder)
                    {
                        EditorUtility.DisplayDialog("StaticSpriteBatcher", "Error: Child objects use different sorting layer names and/or sorting orders.\n\nOnly one sorting layer and order is permitted in a static sprite batcher.", "Ok");
                        return;
                    }
                }
            }
#endif

            List <KeyValuePair <Transform, float> > tempList = new List <KeyValuePair <Transform, float> >();

            // sort sprites, smaller to larger z
            if (batcher.CheckFlag(tk2dStaticSpriteBatcher.Flags.SortToCamera))
            {
                tk2dCamera tk2dCam = tk2dCamera.CameraForLayer(batcher.gameObject.layer);
                Camera     cam     = tk2dCam ? tk2dCam.GetComponent <Camera>() : Camera.main;

                foreach (Transform t in allTransforms)
                {
                    tempList.Add(new KeyValuePair <Transform, float>(t, cam.WorldToScreenPoint((t.GetComponent <Renderer>() != null) ? t.GetComponent <Renderer>().bounds.center : t.position).z));
                }
            }
            else
            {
                foreach (Transform t in allTransforms)
                {
                    tempList.Add(new KeyValuePair <Transform, float>(t, ((t.GetComponent <Renderer>() != null) ? t.GetComponent <Renderer>().bounds.center : t.position).z));
                }
            }

            tempList.Sort((a, b) => a.Value.CompareTo(b.Value));

            List <Transform> tr = new List <Transform>();
            foreach (KeyValuePair <Transform, float> pair in tempList)
            {
                tr.Add(pair.Key);
            }

            allTransforms = tr.ToArray();

            // and within the z sort by material
            if (allTransforms.Length == 0)
            {
                EditorUtility.DisplayDialog("StaticSpriteBatcher", "Error: No child objects found", "Ok");
                return;
            }


#if !(UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_1 || UNITY_4_2)
            MeshCollider[]      childMeshColliders      = GetComponentsInChildrenExcludeSelf <MeshCollider>(batcher.transform);
            BoxCollider[]       childBoxColliders       = GetComponentsInChildrenExcludeSelf <BoxCollider>(batcher.transform);
            BoxCollider2D[]     childBoxCollider2Ds     = GetComponentsInChildrenExcludeSelf <BoxCollider2D>(batcher.transform);
            EdgeCollider2D[]    childEdgeCollider2Ds    = GetComponentsInChildrenExcludeSelf <EdgeCollider2D>(batcher.transform);
            PolygonCollider2D[] childPolygonCollider2Ds = GetComponentsInChildrenExcludeSelf <PolygonCollider2D>(batcher.transform);

            if ((childMeshColliders.Length > 0 || childBoxColliders.Length > 0) && (childBoxCollider2Ds.Length > 0 || childEdgeCollider2Ds.Length > 0 || childPolygonCollider2Ds.Length > 0))
            {
                EditorUtility.DisplayDialog("StaticSpriteBatcher", "Error: Can't mix 2D and 3D colliders", "Ok");
                return;
            }
#endif

            Dictionary <Transform, int> batchedSpriteLookup = new Dictionary <Transform, int>();
            batchedSpriteLookup[batcher.transform] = -1;

            Matrix4x4 batcherWorldToLocal = batcher.transform.worldToLocalMatrix;

            batcher.spriteCollection = null;
            batcher.batchedSprites   = new tk2dBatchedSprite[allTransforms.Length];
            List <tk2dTextMeshData> allTextMeshData = new List <tk2dTextMeshData>();

            int currBatchedSprite = 0;
            foreach (var t in allTransforms)
            {
                tk2dBaseSprite baseSprite = t.GetComponent <tk2dBaseSprite>();
                tk2dTextMesh   textmesh   = t.GetComponent <tk2dTextMesh>();

                tk2dBatchedSprite bs = new tk2dBatchedSprite();
                bs.name           = t.gameObject.name;
                bs.position       = t.localPosition;
                bs.rotation       = t.localRotation;
                bs.relativeMatrix = batcherWorldToLocal * t.localToWorldMatrix;

                if (baseSprite)
                {
                    bs.baseScale  = Vector3.one;
                    bs.localScale = new Vector3(t.localScale.x * baseSprite.scale.x, t.localScale.y * baseSprite.scale.y, t.localScale.z * baseSprite.scale.z);
                    FillBatchedSprite(bs, t.gameObject);

                    // temp redundant - just incase batcher expects to point to a valid one, somewhere we've missed
                    batcher.spriteCollection = baseSprite.Collection;
                }
                else if (textmesh)
                {
                    bs.spriteCollection = null;

                    bs.type          = tk2dBatchedSprite.Type.TextMesh;
                    bs.color         = textmesh.color;
                    bs.baseScale     = textmesh.scale;
                    bs.renderLayer   = textmesh.SortingOrder;
                    bs.localScale    = new Vector3(t.localScale.x * textmesh.scale.x, t.localScale.y * textmesh.scale.y, t.localScale.z * textmesh.scale.z);
                    bs.FormattedText = textmesh.FormattedText;

                    tk2dTextMeshData tmd = new tk2dTextMeshData();
                    tmd.Font            = textmesh.font;
                    tmd.Text            = textmesh.text;
                    tmd.color           = textmesh.color;
                    tmd.color2          = textmesh.color2;
                    tmd.useGradient     = textmesh.useGradient;
                    tmd.textureGradient = textmesh.textureGradient;
                    tmd.anchor          = textmesh.anchor;
                    tmd.kerning         = textmesh.kerning;
                    tmd.Spacing         = textmesh.Spacing;
                    tmd.LineSpacing     = textmesh.LineSpacing;

                    bs.xRefId = allTextMeshData.Count;
                    allTextMeshData.Add(tmd);
                }
                else
                {
                    // Empty GameObject
                    bs.spriteId   = -1;
                    bs.baseScale  = Vector3.one;
                    bs.localScale = t.localScale;
                    bs.type       = tk2dBatchedSprite.Type.EmptyGameObject;
                }


                batchedSpriteLookup[t] = currBatchedSprite;
                batcher.batchedSprites[currBatchedSprite++] = bs;
            }
            batcher.allTextMeshData = allTextMeshData.ToArray();

            int idx = 0;
            foreach (var t in allTransforms)
            {
                var bs = batcher.batchedSprites[idx];

                bs.parentId = batchedSpriteLookup[t.parent];
                t.parent    = batcher.transform;              // unparent
                ++idx;
            }

            //Transform[] directChildren = (from t in allTransforms where t.parent == batcher.transform select t).ToArray();

            List <Transform> tempdirectChildren = new List <Transform>();
            foreach (Transform t in allTransforms)
            {
                if (t.parent == batcher.transform)
                {
                    tempdirectChildren.Add(t);
                }
            }

            Transform[] directChildren = tempdirectChildren.ToArray();

            foreach (var t in directChildren)
            {
                GameObject.DestroyImmediate(t.gameObject);
            }

            Vector3 inverseScale = new Vector3(1.0f / batcher.scale.x, 1.0f / batcher.scale.y, 1.0f / batcher.scale.z);
            batcher.transform.localScale = Vector3.Scale(batcher.transform.localScale, inverseScale);
            batcher.Build();
            EditorUtility.SetDirty(target);
        }
    }
    // this function is static to ensure that no fields are changed during this call
    private static void ConvertString(tk2dColoredText formattedText,
                                      tk2dTextMeshData meshData)
    {
        const char NonBreakableSpace = (char)17;


        if (meshData.UseShortNumbers)
        {
            formattedText.ApplyShortNumber();
        }

        if (!meshData.DisableNumberGrouping)
        {
            int currentNumberCount = 0;

            for (int i = formattedText.Length - 1; i >= 0; i--)
            {
                var curChar = formattedText[i];
                if (curChar >= '0' && curChar <= '9')
                {
                    currentNumberCount += 1;
                }
                else
                {
                    currentNumberCount = 0;
                }

                if (currentNumberCount == 4)
                {
                    // add device control char -> if you add normal space ->
                    // code lower will make new lines
                    formattedText.Insert(i + 1, new string(NonBreakableSpace, 1));
                    currentNumberCount = 1;
                }
            }
        }


        // reset line break scale before calculate the dimentions
        meshData.lineBreakScale = Vector3.one;
        Vector2 dims = meshData.GetMeshDimensionsForString(formattedText);

        if (dims.x > meshData.maxTextLength)
        {
            if (meshData.maxTextLength > 0.0f)
            {
                switch (meshData.BreakMode)
                {
                case LineBreakMode.ScaleDown:
                {
                    float curScale = meshData.maxTextLength / dims.x;
                    meshData.lineBreakScale.Set(curScale,
                                                curScale,
                                                curScale);
                }
                break;


                case LineBreakMode.ThreeDots:
                {
                    formattedText.Append("...");
                    for (int i = formattedText.Length - 4; i >= 0 && meshData.GetMeshDimensionsForString(formattedText).x > meshData.MaxTextLength; i--)
                    {
                        formattedText.Remove(i);
                    }
                }
                break;


                case LineBreakMode.LineBreak:
                {
                    int curStartIndex  = 0;
                    int curFinishIndex = 0;
                    while (curFinishIndex < (formattedText.Length - 1))
                    {
                        int curNextSpace = formattedText.IndexOf(' ', curFinishIndex + 1);
                        int curLastIndex = (curNextSpace != -1) ? curNextSpace : (formattedText.Length - 1);
                        if (meshData.GetMeshDimensionsForString(formattedText, curStartIndex, (curLastIndex - curStartIndex + 1)).x > meshData.maxTextLength)
                        {
                            int actualFinishIndex = (curFinishIndex > curStartIndex) ? curFinishIndex : curLastIndex;

                            formattedText[actualFinishIndex] = '\n';

                            curFinishIndex = curStartIndex = actualFinishIndex + 1;
                        }
                        else
                        {
                            curFinishIndex = curLastIndex;
                        }
                    }
                }
                break;
                }
            }
        }

        float dimsY = Mathf.Abs(meshData.GetMeshDimensionsForString(formattedText).y);

        if (dimsY > meshData.maxTextHeight)
        {
            if (meshData.maxTextHeight > 0.0f)
            {
                float curScale = meshData.lineBreakScale.x;
                float newScale = meshData.maxTextHeight / dimsY;
                curScale = Math.Min(curScale, newScale);
                meshData.lineBreakScale.Set(curScale,
                                            curScale,
                                            curScale);
            }
        }

        if (meshData.ShouldScaleInCellSize)
        {
            float newScale = Mathf.Min(meshData.maxTextLength / dims.x, meshData.MaxTextHeight / Mathf.Abs(dims.y));
            meshData.lineBreakScale.Set(newScale, newScale, newScale);
        }

        formattedText.Replace(NonBreakableSpace, ' ');
    }
Ejemplo n.º 15
0
    public static void SetTextMeshGeom(this GeomData geomData, Vector3[] pos, Vector2[] uv, Vector2[] uv2, Color32[] color, int offset)
    {
        tk2dTextMeshData data          = geomData.TextMeshData;
        tk2dFontData     fontInst      = data.FontInst;
        tk2dColoredText  formattedText = data.FormattedText;

        InlineStyler curStyler = new InlineStyler();

        curStyler.meshTopColor     = new Color32(255, 255, 255, 255);
        curStyler.meshBottomColor  = new Color32(255, 255, 255, 255);
        curStyler.meshGradientTexU = (float)data.textureGradient / (float)((fontInst.gradientCount > 0) ? fontInst.gradientCount : 1);
        curStyler.curGradientCount = fontInst.gradientCount;

        Vector2 dims    = data.GetMeshDimensionsForString(formattedText);
        float   offsetY = data.GetYAnchorForHeight(dims.y);

        float cursorX = 0.0f;
        float cursorY = 0.0f;

        // target is required due to invisible '\n' character
        int target           = 0;
        int alignStartTarget = 0;

        for (int i = 0; i < formattedText.Length && target < geomData.CurrentAllocatedCharacters; ++i)
        {
            formattedText.ApplyColorCommand(curStyler, i);

            int          idx = formattedText[i];
            tk2dFontChar chr = fontInst.GetCharForIndex(idx, 0);

            if (idx == '\n')
            {
                float lineWidth      = cursorX;
                int   alignEndTarget = target;               // this is one after the last filled character
                if (alignStartTarget != target)
                {
                    float xOffset = data.GetXAnchorForWidth(lineWidth);
                    PostAlignTextData(pos, offset, alignStartTarget, alignEndTarget, xOffset);
                }


                alignStartTarget = target;
                cursorX          = 0.0f;
                cursorY         -= data.ActualLineSpaceHeight;
            }
            else
            {
                pos[offset + target * 4 + 0] = new Vector3(cursorX + chr.p0.x * data.TotalScale.x, offsetY + cursorY + chr.p0.y * data.TotalScale.y, 0);
                pos[offset + target * 4 + 1] = new Vector3(cursorX + chr.p1.x * data.TotalScale.x, offsetY + cursorY + chr.p0.y * data.TotalScale.y, 0);
                pos[offset + target * 4 + 2] = new Vector3(cursorX + chr.p0.x * data.TotalScale.x, offsetY + cursorY + chr.p1.y * data.TotalScale.y, 0);
                pos[offset + target * 4 + 3] = new Vector3(cursorX + chr.p1.x * data.TotalScale.x, offsetY + cursorY + chr.p1.y * data.TotalScale.y, 0);

                if (chr.flipped)
                {
                    uv[offset + target * 4 + 0] = new Vector2(chr.uv1.x, chr.uv1.y);
                    uv[offset + target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
                    uv[offset + target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
                    uv[offset + target * 4 + 3] = new Vector2(chr.uv0.x, chr.uv0.y);
                }
                else
                {
                    uv[offset + target * 4 + 0] = new Vector2(chr.uv0.x, chr.uv0.y);
                    uv[offset + target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
                    uv[offset + target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
                    uv[offset + target * 4 + 3] = new Vector2(chr.uv1.x, chr.uv1.y);
                }

                if (fontInst.textureGradients)
                {
                    uv2[offset + target * 4 + 0] = chr.gradientUv[0] + new Vector2(curStyler.meshGradientTexU, 0);
                    uv2[offset + target * 4 + 1] = chr.gradientUv[1] + new Vector2(curStyler.meshGradientTexU, 0);
                    uv2[offset + target * 4 + 2] = chr.gradientUv[2] + new Vector2(curStyler.meshGradientTexU, 0);
                    uv2[offset + target * 4 + 3] = chr.gradientUv[3] + new Vector2(curStyler.meshGradientTexU, 0);
                }

                if (fontInst.isPacked)
                {
                    Color32 c = channelSelectColors[chr.channel];
                    color[offset + target * 4 + 0] = c;
                    color[offset + target * 4 + 1] = c;
                    color[offset + target * 4 + 2] = c;
                    color[offset + target * 4 + 3] = c;
                }
                else
                {
                    color[offset + target * 4 + 0] = curStyler.meshTopColor;
                    color[offset + target * 4 + 1] = curStyler.meshTopColor;
                    color[offset + target * 4 + 2] = curStyler.meshBottomColor;
                    color[offset + target * 4 + 3] = curStyler.meshBottomColor;
                }

                cursorX += (chr.advance + data.Spacing) * data.TotalScale.x;

                if (data.kerning && i < formattedText.Length - 1)
                {
                    foreach (var k in fontInst.kerning)
                    {
                        if (k.c0 == formattedText[i] && k.c1 == formattedText[i + 1])
                        {
                            cursorX += k.amount * data.TotalScale.x;
                            break;
                        }
                    }
                }

                target++;
            }
        }

        if (alignStartTarget != target)
        {
            float lineWidth      = cursorX;
            int   alignEndTarget = target;
            float xOffset        = data.GetXAnchorForWidth(lineWidth);
            PostAlignTextData(pos, offset, alignStartTarget, alignEndTarget, xOffset);
        }

        for (int i = target; i < geomData.CurrentAllocatedCharacters; ++i)
        {
            pos[offset + i * 4 + 0] = pos[offset + i * 4 + 1] = pos[offset + i * 4 + 2] = pos[offset + i * 4 + 3] = Vector3.zero;
            uv[offset + i * 4 + 0]  = uv[offset + i * 4 + 1] = uv[offset + i * 4 + 2] = uv[offset + i * 4 + 3] = Vector2.zero;

            if (fontInst.textureGradients)
            {
                uv2[offset + i * 4 + 0] = uv2[offset + i * 4 + 1] = uv2[offset + i * 4 + 2] = uv2[offset + i * 4 + 3] = Vector2.zero;
            }

            color[offset + i * 4 + 0] = color[offset + i * 4 + 1] = color[offset + i * 4 + 2] = color[offset + i * 4 + 3] = Color.clear;
        }
    }
Ejemplo n.º 16
0
 // Use this to get a correctly set up textgeomdata object
 // This uses a static global tmpData object and is not thread safe
 // Fortunately for us, neither is the rest of Unity.
 public GeomData(tk2dTextMeshData _textMeshData, int _currentAllocatedCharacters)
 {
     textMeshData = _textMeshData;
     currentAllocatedCharacters = _currentAllocatedCharacters;
 }
	void DrawEditorGUI()
	{
		if (GUILayout.Button("Commit"))
		{
			// Select all children, EXCLUDING self
			Transform[] allTransforms = batcher.transform.GetComponentsInChildren<Transform>();
			allTransforms = (from t in allTransforms where t != batcher.transform select t).ToArray();
			
			// sort sprites, smaller to larger z
			if (batcher.CheckFlag(tk2dStaticSpriteBatcher.Flags.SortToCamera)) {
				tk2dCamera tk2dCam = tk2dCamera.CameraForLayer( batcher.gameObject.layer );
				Camera cam = tk2dCam ? tk2dCam.camera : Camera.main;
				allTransforms = (from t in allTransforms orderby cam.WorldToScreenPoint((t.renderer != null) ? t.renderer.bounds.center : t.position).z descending select t).ToArray();
			}
			else {
				allTransforms = (from t in allTransforms orderby t.position.z descending select t).ToArray();
			}
			
			// and within the z sort by material
			if (allTransforms.Length == 0)
			{
				EditorUtility.DisplayDialog("StaticSpriteBatcher", "Error: No child objects found", "Ok");
				return;
			}
		
			Dictionary<Transform, int> batchedSpriteLookup = new Dictionary<Transform, int>();
			batchedSpriteLookup[batcher.transform] = -1;

			Matrix4x4 batcherWorldToLocal = batcher.transform.worldToLocalMatrix;
			
			batcher.spriteCollection = null;
			batcher.batchedSprites = new tk2dBatchedSprite[allTransforms.Length];
			List<tk2dTextMeshData> allTextMeshData = new List<tk2dTextMeshData>();

			int currBatchedSprite = 0;
			foreach (var t in allTransforms)
			{
				tk2dBaseSprite baseSprite = t.GetComponent<tk2dBaseSprite>();
				tk2dTextMesh textmesh = t.GetComponent<tk2dTextMesh>();

				tk2dBatchedSprite bs = new tk2dBatchedSprite();
				bs.name = t.gameObject.name;
				bs.position = t.localPosition;
				bs.rotation = t.localRotation;
				bs.relativeMatrix = batcherWorldToLocal * t.localToWorldMatrix;

				if (baseSprite)
				{
					bs.baseScale = Vector3.one;
					bs.localScale = new Vector3(t.localScale.x * baseSprite.scale.x, t.localScale.y * baseSprite.scale.y, t.localScale.z * baseSprite.scale.z);
					FillBatchedSprite(bs, t.gameObject);

					// temp redundant - just incase batcher expects to point to a valid one, somewhere we've missed
					batcher.spriteCollection = baseSprite.Collection;
				}
				else if (textmesh)
				{
					bs.spriteCollection = null;

					bs.type = tk2dBatchedSprite.Type.TextMesh;
					bs.color = textmesh.color;
					bs.baseScale = textmesh.scale;
					bs.localScale = new Vector3(t.localScale.x * textmesh.scale.x, t.localScale.y * textmesh.scale.y, t.localScale.z * textmesh.scale.z);
					bs.FormattedText = textmesh.FormattedText;

					tk2dTextMeshData tmd = new tk2dTextMeshData();
					tmd.font = textmesh.font;
					tmd.text = textmesh.text;
					tmd.color = textmesh.color;
					tmd.color2 = textmesh.color2;
					tmd.useGradient = textmesh.useGradient;
					tmd.textureGradient = textmesh.textureGradient;
					tmd.anchor = textmesh.anchor;
					tmd.kerning = textmesh.kerning;
					tmd.maxChars = textmesh.maxChars;
					tmd.inlineStyling = textmesh.inlineStyling;
					tmd.formatting = textmesh.formatting;
					tmd.wordWrapWidth = textmesh.wordWrapWidth;
					tmd.spacing = textmesh.Spacing;
					tmd.lineSpacing = textmesh.LineSpacing;

					bs.xRefId = allTextMeshData.Count;
					allTextMeshData.Add(tmd);
				}
				else
				{
					// Empty GameObject
					bs.spriteId = -1;
					bs.baseScale = Vector3.one;
					bs.localScale = t.localScale;
					bs.type = tk2dBatchedSprite.Type.EmptyGameObject;
				}

				
				batchedSpriteLookup[t] = currBatchedSprite;
				batcher.batchedSprites[currBatchedSprite++] = bs;
			}
			batcher.allTextMeshData = allTextMeshData.ToArray();
			
			int idx = 0;
			foreach (var t in allTransforms)
			{
				var bs = batcher.batchedSprites[idx];

				bs.parentId = batchedSpriteLookup[t.parent];
				t.parent = batcher.transform; // unparent
				++idx;
			}
			
			Transform[] directChildren = (from t in allTransforms where t.parent == batcher.transform select t).ToArray();
			foreach (var t in directChildren)
			{
				GameObject.DestroyImmediate(t.gameObject);
			}
			
			Vector3 inverseScale = new Vector3(1.0f / batcher.scale.x, 1.0f / batcher.scale.y, 1.0f / batcher.scale.z);
			batcher.transform.localScale = Vector3.Scale( batcher.transform.localScale, inverseScale );
			batcher.Build();
			EditorUtility.SetDirty(target);
		}
	}
Ejemplo n.º 18
0
    void BuildRenderMesh()
    {
        List <Material>    materials = new List <Material>();
        List <List <int> > indices   = new List <List <int> >();

        bool needNormals  = false;
        bool needTangents = false;
        bool needUV2      = false;
        bool flattenDepth = CheckFlag(Flags.FlattenDepth);

        foreach (var bs in batchedSprites)
        {
            var spriteDef = bs.GetSpriteDefinition();
            if (spriteDef != null)
            {
                needNormals  |= (spriteDef.normals != null && spriteDef.normals.Length > 0);
                needTangents |= (spriteDef.tangents != null && spriteDef.tangents.Length > 0);
            }
            if (bs.type == tk2dBatchedSprite.Type.TextMesh)
            {
                tk2dTextMeshData textMeshData = allTextMeshData[bs.xRefId];
                if ((textMeshData.font != null) && textMeshData.font.inst.textureGradients)
                {
                    needUV2 = true;
                }
            }
        }

        // just helpful to have these here, stop code being more messy
        List <int> bsNVerts = new List <int>();
        List <int> bsNInds  = new List <int>();

        int numVertices = 0;

        foreach (var bs in batchedSprites)
        {
            if (!bs.IsDrawn)             // when the first non-drawn child is found, it signals the end of the drawn list
            {
                break;
            }

            var spriteDef = bs.GetSpriteDefinition();
            int nVerts    = 0;
            int nInds     = 0;
            switch (bs.type)
            {
            case tk2dBatchedSprite.Type.EmptyGameObject:
                break;

            case tk2dBatchedSprite.Type.Sprite:
                if (spriteDef != null)
                {
                    tk2dSpriteGeomGen.GetSpriteGeomDesc(out nVerts, out nInds, spriteDef);
                }
                break;

            case tk2dBatchedSprite.Type.TiledSprite:
                if (spriteDef != null)
                {
                    tk2dSpriteGeomGen.GetTiledSpriteGeomDesc(out nVerts, out nInds, spriteDef, bs.Dimensions);
                }
                break;

            case tk2dBatchedSprite.Type.SlicedSprite:
                if (spriteDef != null)
                {
                    tk2dSpriteGeomGen.GetSlicedSpriteGeomDesc(out nVerts, out nInds, spriteDef, bs.CheckFlag(tk2dBatchedSprite.Flags.SlicedSprite_BorderOnly));
                }
                break;

            case tk2dBatchedSprite.Type.ClippedSprite:
                if (spriteDef != null)
                {
                    tk2dSpriteGeomGen.GetClippedSpriteGeomDesc(out nVerts, out nInds, spriteDef);
                }
                break;

            case tk2dBatchedSprite.Type.TextMesh:
            {
                tk2dTextMeshData textMeshData = allTextMeshData[bs.xRefId];
                tk2dTextGeomGen.GetTextMeshGeomDesc(out nVerts, out nInds, tk2dTextGeomGen.Data(textMeshData, textMeshData.font.inst, bs.FormattedText));
                break;
            }
            }
            numVertices += nVerts;

            bsNVerts.Add(nVerts);
            bsNInds.Add(nInds);
        }

        Vector3[] meshNormals  = needNormals?new Vector3[numVertices]:null;
        Vector4[] meshTangents = needTangents?new Vector4[numVertices]:null;
        Vector3[] meshVertices = new Vector3[numVertices];
        Color32[] meshColors   = new Color32[numVertices];
        Vector2[] meshUvs      = new Vector2[numVertices];
        Vector2[] meshUv2s     = needUV2 ? new Vector2[numVertices] : null;

        int currVertex = 0;

        Material   currentMaterial = null;
        List <int> currentIndices  = null;

        Matrix4x4 scaleMatrix = Matrix4x4.identity;

        scaleMatrix.m00 = _scale.x;
        scaleMatrix.m11 = _scale.y;
        scaleMatrix.m22 = _scale.z;

        int bsIndex = 0;

        foreach (var bs in batchedSprites)
        {
            if (!bs.IsDrawn)             // when the first non-drawn child is found, it signals the end of the drawn list
            {
                break;
            }

            if (bs.type == tk2dBatchedSprite.Type.EmptyGameObject)
            {
                ++bsIndex;                 // watch out for this
                continue;
            }

            var spriteDef = bs.GetSpriteDefinition();
            int nVerts    = bsNVerts[bsIndex];
            int nInds     = bsNInds[bsIndex];

            Material material = GetMaterial(bs);

            // should have a material at this point
            if (material != currentMaterial)
            {
                if (currentMaterial != null)
                {
                    materials.Add(currentMaterial);
                    indices.Add(currentIndices);
                }

                currentMaterial = material;
                currentIndices  = new List <int>();
            }

            Vector3[] posData     = new Vector3[nVerts];
            Vector2[] uvData      = new Vector2[nVerts];
            Vector2[] uv2Data     = needUV2 ? new Vector2[nVerts] : null;
            Color32[] colorData   = new Color32[nVerts];
            Vector3[] normalData  = needNormals ? new Vector3[nVerts] : null;
            Vector4[] tangentData = needTangents ? new Vector4[nVerts] : null;
            int[]     indData     = new int[nInds];

            Vector3 boundsCenter  = Vector3.zero;
            Vector3 boundsExtents = Vector3.zero;

            switch (bs.type)
            {
            case tk2dBatchedSprite.Type.EmptyGameObject:
                break;

            case tk2dBatchedSprite.Type.Sprite:
                if (spriteDef != null)
                {
                    tk2dSpriteGeomGen.SetSpriteGeom(posData, uvData, normalData, tangentData, 0, spriteDef, Vector3.one);
                    tk2dSpriteGeomGen.SetSpriteIndices(indData, 0, currVertex, spriteDef);
                }
                break;

            case tk2dBatchedSprite.Type.TiledSprite:
                if (spriteDef != null)
                {
                    tk2dSpriteGeomGen.SetTiledSpriteGeom(posData, uvData, 0, out boundsCenter, out boundsExtents, spriteDef, Vector3.one, bs.Dimensions, bs.anchor, bs.BoxColliderOffsetZ, bs.BoxColliderExtentZ);
                    tk2dSpriteGeomGen.SetTiledSpriteIndices(indData, 0, currVertex, spriteDef, bs.Dimensions);
                }
                break;

            case tk2dBatchedSprite.Type.SlicedSprite:
                if (spriteDef != null)
                {
                    tk2dSpriteGeomGen.SetSlicedSpriteGeom(posData, uvData, 0, out boundsCenter, out boundsExtents, spriteDef, Vector3.one, bs.Dimensions, bs.SlicedSpriteBorderBottomLeft, bs.SlicedSpriteBorderTopRight, bs.anchor, bs.BoxColliderOffsetZ, bs.BoxColliderExtentZ);
                    tk2dSpriteGeomGen.SetSlicedSpriteIndices(indData, 0, currVertex, spriteDef, bs.CheckFlag(tk2dBatchedSprite.Flags.SlicedSprite_BorderOnly));
                }
                break;

            case tk2dBatchedSprite.Type.ClippedSprite:
                if (spriteDef != null)
                {
                    tk2dSpriteGeomGen.SetClippedSpriteGeom(posData, uvData, 0, out boundsCenter, out boundsExtents, spriteDef, Vector3.one, bs.ClippedSpriteRegionBottomLeft, bs.ClippedSpriteRegionTopRight, bs.BoxColliderOffsetZ, bs.BoxColliderExtentZ);
                    tk2dSpriteGeomGen.SetClippedSpriteIndices(indData, 0, currVertex, spriteDef);
                }
                break;

            case tk2dBatchedSprite.Type.TextMesh:
            {
                tk2dTextMeshData textMeshData = allTextMeshData[bs.xRefId];
                var geomData = tk2dTextGeomGen.Data(textMeshData, textMeshData.font.inst, bs.FormattedText);
                int target   = tk2dTextGeomGen.SetTextMeshGeom(posData, uvData, uv2Data, colorData, 0, geomData);
                if (!geomData.fontInst.isPacked)
                {
                    Color32 topColor    = textMeshData.color;
                    Color32 bottomColor = textMeshData.useGradient ? textMeshData.color2 : textMeshData.color;
                    for (int i = 0; i < colorData.Length; ++i)
                    {
                        Color32 c     = ((i % 4) < 2) ? topColor : bottomColor;
                        byte    red   = (byte)(((int)colorData[i].r * (int)c.r) / 255);
                        byte    green = (byte)(((int)colorData[i].g * (int)c.g) / 255);
                        byte    blue  = (byte)(((int)colorData[i].b * (int)c.b) / 255);
                        byte    alpha = (byte)(((int)colorData[i].a * (int)c.a) / 255);
                        if (geomData.fontInst.premultipliedAlpha)
                        {
                            red   = (byte)(((int)red * (int)alpha) / 255);
                            green = (byte)(((int)green * (int)alpha) / 255);
                            blue  = (byte)(((int)blue * (int)alpha) / 255);
                        }
                        colorData[i] = new Color32(red, green, blue, alpha);
                    }
                }
                tk2dTextGeomGen.SetTextMeshIndices(indData, 0, currVertex, geomData, target);
                break;
            }
            }

            bs.CachedBoundsCenter  = boundsCenter;
            bs.CachedBoundsExtents = boundsExtents;

            if (nVerts > 0 && bs.type != tk2dBatchedSprite.Type.TextMesh)
            {
                bool premulAlpha = (bs.spriteCollection != null) ? bs.spriteCollection.premultipliedAlpha : false;
                tk2dSpriteGeomGen.SetSpriteColors(colorData, 0, nVerts, bs.color, premulAlpha);
            }

            Matrix4x4 mat = scaleMatrix * bs.relativeMatrix;
            for (int i = 0; i < nVerts; ++i)
            {
                Vector3 pos = Vector3.Scale(posData[i], bs.baseScale);
                pos = mat.MultiplyPoint(pos);
                if (flattenDepth)
                {
                    pos.z = 0;
                }

                meshVertices[currVertex + i] = pos;

                meshUvs[currVertex + i] = uvData[i];
                if (needUV2)
                {
                    meshUv2s[currVertex + i] = uv2Data[i];
                }
                meshColors[currVertex + i] = colorData[i];

                if (needNormals)
                {
                    meshNormals[currVertex + i] = bs.rotation * normalData[i];
                }
                if (needTangents)
                {
                    Vector3 tang = new Vector3(tangentData[i].x, tangentData[i].y, tangentData[i].z);
                    tang = bs.rotation * tang;
                    meshTangents[currVertex + i] = new Vector4(tang.x, tang.y, tang.z, tangentData[i].w);
                }
            }

            currentIndices.AddRange(indData);

            currVertex += nVerts;

            ++bsIndex;
        }

        if (currentIndices != null)
        {
            materials.Add(currentMaterial);
            indices.Add(currentIndices);
        }

        if (mesh)
        {
            mesh.vertices = meshVertices;
            mesh.uv       = meshUvs;
            if (needUV2)
            {
                mesh.uv2 = meshUv2s;
            }
            mesh.colors32 = meshColors;
            if (needNormals)
            {
                mesh.normals = meshNormals;
            }
            if (needTangents)
            {
                mesh.tangents = meshTangents;
            }

            mesh.subMeshCount = indices.Count;
            for (int i = 0; i < indices.Count; ++i)
            {
                mesh.SetTriangles(indices[i].ToArray(), i);
            }

            mesh.RecalculateBounds();
        }

        GetComponent <Renderer>().sharedMaterials = materials.ToArray();
    }
Ejemplo n.º 19
0
 public static Vector2 GetMeshDimensionsForString(this tk2dTextMeshData geomData, tk2dColoredText inputText)
 {
     return(GetMeshDimensionsForString(geomData, inputText, 0, inputText.Length));
 }
Ejemplo n.º 20
0
    void DrawInstanceGUI()
    {
        if (GUILayout.Button("Edit"))
        {
            Vector3    batcherPos      = batcher.transform.position;
            Quaternion batcherRotation = batcher.transform.rotation;
            batcher.transform.position   = Vector3.zero;
            batcher.transform.rotation   = Quaternion.identity;
            batcher.transform.localScale = Vector3.Scale(batcher.transform.localScale, batcher.scale);

            Dictionary <int, Transform> parents  = new Dictionary <int, Transform>();
            List <Transform>            children = new List <Transform>();

            List <GameObject> gos = new List <GameObject>();

            int id;

            id = 0;
            foreach (var bs in batcher.batchedSprites)
            {
                GameObject go = new GameObject(bs.name);

                parents[id++] = go.transform;
                children.Add(go.transform);
                gos.Add(go);
            }

            id = 0;
            foreach (var bs in batcher.batchedSprites)
            {
                Transform parent = batcher.transform;
                if (bs.parentId != -1)
                {
                    parents.TryGetValue(bs.parentId, out parent);
                }

                children[id++].parent = parent;
            }

            id = 0;
            foreach (var bs in batcher.batchedSprites)
            {
                GameObject go = gos[id];

                go.transform.localPosition = bs.position;
                go.transform.localRotation = bs.rotation;
                {
                    float sx = bs.localScale.x / ((Mathf.Abs(bs.baseScale.x) > Mathf.Epsilon) ? bs.baseScale.x : 1.0f);
                    float sy = bs.localScale.y / ((Mathf.Abs(bs.baseScale.y) > Mathf.Epsilon) ? bs.baseScale.y : 1.0f);
                    float sz = bs.localScale.z / ((Mathf.Abs(bs.baseScale.z) > Mathf.Epsilon) ? bs.baseScale.z : 1.0f);
                    go.transform.localScale = new Vector3(sx, sy, sz);
                }

                if (bs.type == tk2dBatchedSprite.Type.TextMesh)
                {
                    tk2dTextMesh s = go.AddComponent <tk2dTextMesh>();
                    if (batcher.allTextMeshData == null || bs.xRefId == -1)
                    {
                        Debug.LogError("Unable to find text mesh ref");
                    }
                    else
                    {
                        tk2dTextMeshData tmd = batcher.allTextMeshData[bs.xRefId];
                        s.font            = tmd.font;
                        s.scale           = bs.baseScale;
                        s.SortingOrder    = bs.renderLayer;
                        s.text            = tmd.text;
                        s.color           = bs.color;
                        s.color2          = tmd.color2;
                        s.useGradient     = tmd.useGradient;
                        s.textureGradient = tmd.textureGradient;
                        s.anchor          = tmd.anchor;
                        s.scale           = bs.baseScale;
                        s.kerning         = tmd.kerning;
                        s.maxChars        = tmd.maxChars;
                        s.inlineStyling   = tmd.inlineStyling;
                        s.formatting      = tmd.formatting;
                        s.wordWrapWidth   = tmd.wordWrapWidth;
                        s.Spacing         = tmd.spacing;
                        s.LineSpacing     = tmd.lineSpacing;
                        s.Commit();
                    }
                }
                else
                {
                    RestoreBatchedSprite(go, bs);
                }

                ++id;
            }

            batcher.batchedSprites = null;
            batcher.Build();
            EditorUtility.SetDirty(target);

            batcher.transform.position = batcherPos;
            batcher.transform.rotation = batcherRotation;
        }

        batcher.scale = EditorGUILayout.Vector3Field("Scale", batcher.scale);

        batcher.SetFlag(tk2dStaticSpriteBatcher.Flags.GenerateCollider, EditorGUILayout.Toggle("Generate Collider", batcher.CheckFlag(tk2dStaticSpriteBatcher.Flags.GenerateCollider)));
        batcher.SetFlag(tk2dStaticSpriteBatcher.Flags.FlattenDepth, EditorGUILayout.Toggle("Flatten Depth", batcher.CheckFlag(tk2dStaticSpriteBatcher.Flags.FlattenDepth)));
        batcher.SetFlag(tk2dStaticSpriteBatcher.Flags.SortToCamera, EditorGUILayout.Toggle("Sort to Camera", batcher.CheckFlag(tk2dStaticSpriteBatcher.Flags.SortToCamera)));

        MeshFilter   meshFilter   = batcher.GetComponent <MeshFilter>();
        MeshRenderer meshRenderer = batcher.GetComponent <MeshRenderer>();

        if (meshFilter != null && meshFilter.sharedMesh != null && meshRenderer != null)
        {
            GUILayout.Label("Stats", EditorStyles.boldLabel);
            int  numIndices = 0;
            Mesh mesh       = meshFilter.sharedMesh;
            for (int i = 0; i < mesh.subMeshCount; ++i)
            {
                numIndices += mesh.GetTriangles(i).Length;
            }
            GUILayout.Label(string.Format("Triangles: {0}\nMaterials: {1}", numIndices / 3, meshRenderer.sharedMaterials.Length));
        }
    }
Ejemplo n.º 21
0
 public static Vector2 GetMeshDimensionsForString(this tk2dTextMeshData geomData, string inputString)
 {
     return(GetMeshDimensionsForString(geomData, new tk2dColoredText(inputString, Color.white)));
 }