Example #1
0
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------

    public override void OnInspectorGUI()
    {
        // ========================================================
        // Base GUI
        // ========================================================

        base.OnInspectorGUI();
        GUILayout.Space(20);

        // ========================================================
        // init values
        // ========================================================

        //
        bool needRebuild = false;

        editSprite.spanim = editSprite.GetComponent <exSpriteAnimation>();

        // get ElementInfo first
        Texture2D editTexture = exEditorHelper.LoadAssetFromGUID <Texture2D>(editSprite.textureGUID);

        // ========================================================
        // Texture preview (input)
        // ========================================================

        bool textureChanged = false;

        GUI.enabled = !inAnimMode;
        GUILayout.BeginHorizontal();
        GUILayout.Space(20);
        EditorGUIUtility.LookLikeControls();
        Texture2D newTexture = (Texture2D)EditorGUILayout.ObjectField(editTexture
                                                                      , typeof(Texture2D)
                                                                      , false
                                                                      , GUILayout.Width(100)
                                                                      , GUILayout.Height(100)
                                                                      );

        EditorGUIUtility.LookLikeInspector();
        if (newTexture != editTexture)
        {
            editTexture            = newTexture;
            editSprite.textureGUID = exEditorHelper.AssetToGUID(editTexture);
            textureChanged         = true;
            GUI.changed            = true;
        }
        GUILayout.Space(10);
        GUILayout.BeginVertical();
        GUILayout.Space(90);
        GUILayout.Label(editTexture ? editTexture.name : "None");
        GUILayout.EndVertical();
        GUILayout.EndHorizontal();
        GUI.enabled = true;

        // ========================================================
        // get atlas element info from atlas database
        // ========================================================

        exAtlas editAtlas = null;
        int     editIndex = -1;

        exAtlasDB.ElementInfo elInfo = exAtlasDB.GetElementInfo(editSprite.textureGUID);
        if (elInfo != null)
        {
            editAtlas = exEditorHelper.LoadAssetFromGUID <exAtlas>(elInfo.guidAtlas);
            editIndex = elInfo.indexInAtlas;
        }
        bool useAtlas = editAtlas != null && editIndex != -1;

        // get atlas and index from textureGUID
        if (!EditorApplication.isPlaying)
        {
            // if we don't use atlas and current edit target use atlas, clear it.
            if (editSprite.useAtlas != useAtlas)
            {
                editSprite.Clear();
            }

            // if we use atlas, check if the atlas,index changes
            if (useAtlas)
            {
                if (editAtlas != editSprite.atlas ||
                    editIndex != editSprite.index)
                {
                    editSprite.SetSprite(editAtlas, editIndex);
                    GUI.changed = true;
                }
            }

            // check if we are first time assignment
            if (useAtlas || editTexture != null)
            {
                if (isPrefab == false && editSprite.meshFilter.sharedMesh == null)
                {
                    needRebuild = true;
                }
            }
        }

        // ========================================================
        // get trimTexture
        // ========================================================

        GUI.enabled = !inAnimMode && !useAtlas;
        bool newTrimTexture = EditorGUILayout.Toggle("Trim Texture", editSprite.trimTexture);

        if (!useAtlas &&
            (textureChanged || newTrimTexture != editSprite.trimTexture))
        {
            editSprite.GetComponent <Renderer>().sharedMaterial = exEditorHelper.GetDefaultMaterial(editTexture, editTexture.name);
            editSprite.trimTexture = newTrimTexture;

            // get trimUV
            Rect trimUV = new Rect(0, 0, 1, 1);
            if (editTexture != null)
            {
                if (editSprite.trimTexture)
                {
                    if (exTextureHelper.IsValidForAtlas(editTexture) == false)
                    {
                        exTextureHelper.ImportTextureForAtlas(editTexture);
                    }
                    trimUV = exTextureHelper.GetTrimTextureRect(editTexture);
                    trimUV = new Rect(trimUV.x / editTexture.width,
                                      (editTexture.height - trimUV.height - trimUV.y) / editTexture.height,
                                      trimUV.width / editTexture.width,
                                      trimUV.height / editTexture.height);
                }

                if (editSprite.customSize == false)
                {
                    editSprite.width  = trimUV.width * editTexture.width;
                    editSprite.height = trimUV.height * editTexture.height;
                }
            }
            editSprite.trimUV       = trimUV;
            editSprite.updateFlags |= exPlane.UpdateFlags.UV;
            editSprite.updateFlags |= exPlane.UpdateFlags.Vertex;
        }
        GUI.enabled = true;

        // ========================================================
        // color
        // ========================================================

        editSprite.color = EditorGUILayout.ColorField("Color", editSprite.color);

        // ========================================================
        // atlas & index
        // ========================================================

        GUILayout.BeginHorizontal();
        GUI.enabled = false;
        EditorGUILayout.ObjectField("Atlas"
                                    , editSprite.atlas
                                    , typeof(exAtlas)
                                    , false
                                    );
        GUI.enabled = true;

        GUI.enabled = !inAnimMode;
        if (GUILayout.Button("Edit...", GUILayout.Width(40), GUILayout.Height(15)))
        {
            exAtlasEditor editor = exAtlasEditor.NewWindow();
            editor.Edit(editSprite.atlas);
        }
        GUI.enabled = true;
        GUILayout.EndHorizontal();

        GUI.enabled = false;
        EditorGUILayout.IntField("Index", editSprite.index);
        GUI.enabled = true;

        // ========================================================
        // custom size
        // ========================================================

        GUI.enabled           = !inAnimMode;
        editSprite.customSize = EditorGUILayout.Toggle("Custom Size", editSprite.customSize);
        GUI.enabled           = true;

        // ========================================================
        // width & height
        // ========================================================

        ++EditorGUI.indentLevel;
        GUI.enabled = !inAnimMode && editSprite.customSize;
        // width
        float newWidth = EditorGUILayout.FloatField("Width", editSprite.width);

        if (newWidth != editSprite.width)
        {
            if (newWidth < 1.0f)
            {
                newWidth = 1.0f;
            }
            editSprite.width = newWidth;
        }

        // height
        float newHeight = EditorGUILayout.FloatField("Height", editSprite.height);

        if (newHeight != editSprite.height)
        {
            if (newHeight < 1.0f)
            {
                newHeight = 1.0f;
            }
            editSprite.height = newHeight;
        }
        --EditorGUI.indentLevel;

        // ========================================================
        // Reset to original
        // ========================================================

        GUILayout.BeginHorizontal();
        GUILayout.Space(30);
        if (GUILayout.Button("Reset", GUILayout.Width(50)))
        {
            if (useAtlas)
            {
                exAtlas.Element el = editAtlas.elements[editIndex];
                editSprite.width  = el.trimRect.width;
                editSprite.height = el.trimRect.height;
            }
            else if (editTexture)
            {
                editSprite.width  = editSprite.trimUV.width * editTexture.width;
                editSprite.height = editSprite.trimUV.height * editTexture.height;
            }
            GUI.changed = true;
        }
        GUILayout.EndHorizontal();
        GUI.enabled = true;

        // ========================================================
        // Rebuild button
        // ========================================================

        GUI.enabled = !inAnimMode;
        GUILayout.BeginHorizontal();
        GUILayout.FlexibleSpace();
        if (GUILayout.Button("Rebuild...", GUILayout.Height(20)))
        {
            needRebuild = true;
        }
        GUILayout.EndHorizontal();
        GUI.enabled = true;
        GUILayout.Space(5);

        // if dirty, build it.
        if (!EditorApplication.isPlaying && !AnimationUtility.InAnimationMode())
        {
            if (needRebuild)
            {
                EditorUtility.ClearProgressBar();
                editSprite.Build(editTexture);
            }
            else if (GUI.changed)
            {
                if (editSprite.meshFilter.sharedMesh != null)
                {
                    editSprite.UpdateMesh(editSprite.meshFilter.sharedMesh);
                }
                EditorUtility.SetDirty(editSprite);
            }
        }
    }
Example #2
0
    ///////////////////////////////////////////////////////////////////////////////
    // mesh building functions
    ///////////////////////////////////////////////////////////////////////////////

    // ------------------------------------------------------------------
    /// \param _mesh the mesh to update
    ///
    /// Update the _mesh depends on the exPlane.updateFlags
    // ------------------------------------------------------------------

    public void UpdateMesh(Mesh _mesh)
    {
        if (guiBorder_ == null)
        {
            updateFlags = UpdateFlags.None;
            return;
        }

        exAtlas.Element el = null;
        if (useAtlas)
        {
            el = atlas_.elements[index_];
        }

        // ========================================================
        // Update Vertex
        // ========================================================

        if ((updateFlags & UpdateFlags.Vertex) != 0)
        {
            // init
            float widthScaled      = width_ * scale_.x;
            float heightScaled     = height_ * scale_.y;
            float halfWidthScaled  = widthScaled * 0.5f;
            float halfHeightScaled = heightScaled * 0.5f;
            float offsetX          = 0.0f;
            float offsetY          = 0.0f;

            Vector3[] vertices = new Vector3[16];

            switch (anchor_)
            {
            case Anchor.TopLeft: offsetX = -halfWidthScaled;   offsetY = -halfHeightScaled;  break;

            case Anchor.TopCenter: offsetX = 0.0f;               offsetY = -halfHeightScaled;  break;

            case Anchor.TopRight: offsetX = halfWidthScaled;    offsetY = -halfHeightScaled;  break;

            case Anchor.MidLeft: offsetX = -halfWidthScaled;   offsetY = 0.0f;               break;

            case Anchor.MidCenter: offsetX = 0.0f;               offsetY = 0.0f;               break;

            case Anchor.MidRight: offsetX = halfWidthScaled;    offsetY = 0.0f;               break;

            case Anchor.BotLeft: offsetX = -halfWidthScaled;   offsetY = halfHeightScaled;   break;

            case Anchor.BotCenter: offsetX = 0.0f;               offsetY = halfHeightScaled;   break;

            case Anchor.BotRight: offsetX = halfWidthScaled;    offsetY = halfHeightScaled;   break;

            default: offsetX = 0.0f;               offsetY = 0.0f;               break;
            }
            offsetX -= offset_.x;
            offsetY += offset_.y;

            float centerWidth  = width_ - guiBorder_.border.horizontal;
            float centerHeight = height_ - guiBorder_.border.vertical;

            // calculate the base pos
            float x = -halfWidthScaled;
            float y = halfHeightScaled;

            float x0 = x;
            float x1 = x0 + guiBorder_.border.left * scale_.x;
            float x2 = x1 + centerWidth * scale_.x;
            float x3 = x2 + guiBorder_.border.right * scale_.x;

            float y0 = y;
            float y1 = y0 - guiBorder_.border.top * scale_.y;
            float y2 = y1 - centerHeight * scale_.y;
            float y3 = y2 - guiBorder_.border.bottom * scale_.y;

            // calculate the pos affect by anchor
            x0 -= offsetX; x1 -= offsetX; x2 -= offsetX; x3 -= offsetX;
            y0 += offsetY; y1 += offsetY; y2 += offsetY; y3 += offsetY;

            // build vertices
            vertices[0] = new Vector3(x0 + y0 * shear_.x, y0 + x0 * shear_.y, 0.0f);
            vertices[1] = new Vector3(x1 + y0 * shear_.x, y0 + x1 * shear_.y, 0.0f);
            vertices[2] = new Vector3(x2 + y0 * shear_.x, y0 + x2 * shear_.y, 0.0f);
            vertices[3] = new Vector3(x3 + y0 * shear_.x, y0 + x3 * shear_.y, 0.0f);

            vertices[4] = new Vector3(x0 + y1 * shear_.x, y1 + x0 * shear_.y, 0.0f);
            vertices[5] = new Vector3(x1 + y1 * shear_.x, y1 + x1 * shear_.y, 0.0f);
            vertices[6] = new Vector3(x2 + y1 * shear_.x, y1 + x2 * shear_.y, 0.0f);
            vertices[7] = new Vector3(x3 + y1 * shear_.x, y1 + x3 * shear_.y, 0.0f);

            vertices[8]  = new Vector3(x0 + y2 * shear_.x, y2 + x0 * shear_.y, 0.0f);
            vertices[9]  = new Vector3(x1 + y2 * shear_.x, y2 + x1 * shear_.y, 0.0f);
            vertices[10] = new Vector3(x2 + y2 * shear_.x, y2 + x2 * shear_.y, 0.0f);
            vertices[11] = new Vector3(x3 + y2 * shear_.x, y2 + x3 * shear_.y, 0.0f);

            vertices[12] = new Vector3(x0 + y3 * shear_.x, y3 + x0 * shear_.y, 0.0f);
            vertices[13] = new Vector3(x1 + y3 * shear_.x, y3 + x1 * shear_.y, 0.0f);
            vertices[14] = new Vector3(x2 + y3 * shear_.x, y3 + x2 * shear_.y, 0.0f);
            vertices[15] = new Vector3(x3 + y3 * shear_.x, y3 + x3 * shear_.y, 0.0f);

            // DELME {
            // // build vertices
            // switch ( plane ) {
            // case Plane.XY:
            //     vertices[0]  = new Vector3( x0 + y0 * shear_.x, y0 + x0 * shear_.y, 0.0f );
            //     vertices[1]  = new Vector3( x1 + y0 * shear_.x, y0 + x1 * shear_.y, 0.0f );
            //     vertices[2]  = new Vector3( x2 + y0 * shear_.x, y0 + x2 * shear_.y, 0.0f );
            //     vertices[3]  = new Vector3( x3 + y0 * shear_.x, y0 + x3 * shear_.y, 0.0f );

            //     vertices[4]  = new Vector3( x0 + y1 * shear_.x, y1 + x0 * shear_.y, 0.0f );
            //     vertices[5]  = new Vector3( x1 + y1 * shear_.x, y1 + x1 * shear_.y, 0.0f );
            //     vertices[6]  = new Vector3( x2 + y1 * shear_.x, y1 + x2 * shear_.y, 0.0f );
            //     vertices[7]  = new Vector3( x3 + y1 * shear_.x, y1 + x3 * shear_.y, 0.0f );

            //     vertices[8]  = new Vector3( x0 + y2 * shear_.x, y2 + x0 * shear_.y, 0.0f );
            //     vertices[9]  = new Vector3( x1 + y2 * shear_.x, y2 + x1 * shear_.y, 0.0f );
            //     vertices[10] = new Vector3( x2 + y2 * shear_.x, y2 + x2 * shear_.y, 0.0f );
            //     vertices[11] = new Vector3( x3 + y2 * shear_.x, y2 + x3 * shear_.y, 0.0f );

            //     vertices[12] = new Vector3( x0 + y3 * shear_.x, y3 + x0 * shear_.y, 0.0f );
            //     vertices[13] = new Vector3( x1 + y3 * shear_.x, y3 + x1 * shear_.y, 0.0f );
            //     vertices[14] = new Vector3( x2 + y3 * shear_.x, y3 + x2 * shear_.y, 0.0f );
            //     vertices[15] = new Vector3( x3 + y3 * shear_.x, y3 + x3 * shear_.y, 0.0f );
            //     break;

            // case Plane.XZ:
            //     vertices[0]  = new Vector3( x0 + y0 * shear_.x, 0.0f, y0 + x0 * shear_.y );
            //     vertices[1]  = new Vector3( x1 + y0 * shear_.x, 0.0f, y0 + x1 * shear_.y );
            //     vertices[2]  = new Vector3( x2 + y0 * shear_.x, 0.0f, y0 + x2 * shear_.y );
            //     vertices[3]  = new Vector3( x3 + y0 * shear_.x, 0.0f, y0 + x3 * shear_.y );

            //     vertices[4]  = new Vector3( x0 + y1 * shear_.x, 0.0f, y1 + x0 * shear_.y );
            //     vertices[5]  = new Vector3( x1 + y1 * shear_.x, 0.0f, y1 + x1 * shear_.y );
            //     vertices[6]  = new Vector3( x2 + y1 * shear_.x, 0.0f, y1 + x2 * shear_.y );
            //     vertices[7]  = new Vector3( x3 + y1 * shear_.x, 0.0f, y1 + x3 * shear_.y );

            //     vertices[8]  = new Vector3( x0 + y2 * shear_.x, 0.0f, y2 + x0 * shear_.y );
            //     vertices[9]  = new Vector3( x1 + y2 * shear_.x, 0.0f, y2 + x1 * shear_.y );
            //     vertices[10] = new Vector3( x2 + y2 * shear_.x, 0.0f, y2 + x2 * shear_.y );
            //     vertices[11] = new Vector3( x3 + y2 * shear_.x, 0.0f, y2 + x3 * shear_.y );

            //     vertices[12] = new Vector3( x0 + y3 * shear_.x, 0.0f, y3 + x0 * shear_.y );
            //     vertices[13] = new Vector3( x1 + y3 * shear_.x, 0.0f, y3 + x1 * shear_.y );
            //     vertices[14] = new Vector3( x2 + y3 * shear_.x, 0.0f, y3 + x2 * shear_.y );
            //     vertices[15] = new Vector3( x3 + y3 * shear_.x, 0.0f, y3 + x3 * shear_.y );
            //     break;

            // case Plane.ZY:
            //     vertices[0]  = new Vector3( 0.0f, y0 + x0 * shear_.y, x0 + y0 * shear_.x );
            //     vertices[1]  = new Vector3( 0.0f, y0 + x1 * shear_.y, x1 + y0 * shear_.x );
            //     vertices[2]  = new Vector3( 0.0f, y0 + x2 * shear_.y, x2 + y0 * shear_.x );
            //     vertices[3]  = new Vector3( 0.0f, y0 + x3 * shear_.y, x3 + y0 * shear_.x );
            //
            //     vertices[4]  = new Vector3( 0.0f, y1 + x0 * shear_.y, x0 + y1 * shear_.x );
            //     vertices[5]  = new Vector3( 0.0f, y1 + x1 * shear_.y, x1 + y1 * shear_.x );
            //     vertices[6]  = new Vector3( 0.0f, y1 + x2 * shear_.y, x2 + y1 * shear_.x );
            //     vertices[7]  = new Vector3( 0.0f, y1 + x3 * shear_.y, x3 + y1 * shear_.x );
            //
            //     vertices[8]  = new Vector3( 0.0f, y2 + x0 * shear_.y, x0 + y2 * shear_.x );
            //     vertices[9]  = new Vector3( 0.0f, y2 + x1 * shear_.y, x1 + y2 * shear_.x );
            //     vertices[10] = new Vector3( 0.0f, y2 + x2 * shear_.y, x2 + y2 * shear_.x );
            //     vertices[11] = new Vector3( 0.0f, y2 + x3 * shear_.y, x3 + y2 * shear_.x );
            //
            //     vertices[12] = new Vector3( 0.0f, y3 + x0 * shear_.y, x0 + y3 * shear_.x );
            //     vertices[13] = new Vector3( 0.0f, y3 + x1 * shear_.y, x1 + y3 * shear_.x );
            //     vertices[14] = new Vector3( 0.0f, y3 + x2 * shear_.y, x2 + y3 * shear_.x );
            //     vertices[15] = new Vector3( 0.0f, y3 + x3 * shear_.y, x3 + y3 * shear_.x );
            //     break;
            // }
            // } DELME end

            _mesh.vertices = vertices;
            _mesh.bounds   = GetMeshBounds(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f);

            // update collider if we have
            UpdateBoundRect(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f);
            if (collisionHelper)
            {
                collisionHelper.UpdateCollider();
            }
        }

        // ========================================================
        // Update UV
        // ========================================================

        if ((updateFlags & UpdateFlags.UV) != 0)
        {
            Vector2[] uvs = new Vector2[16];

            // if the sprite is in an atlas
            if (el != null)
            {
                float xStart = el.coords.x;
                float yStart = el.coords.y;
                float xEnd   = el.coords.xMax;
                float yEnd   = el.coords.yMax;

                float leftRatio   = (float)guiBorder_.border.left / (float)atlas_.texture.width;
                float rightRatio  = (float)guiBorder_.border.right / (float)atlas_.texture.width;
                float topRatio    = (float)guiBorder_.border.top / (float)atlas_.texture.height;
                float bottomRatio = (float)guiBorder_.border.bottom / (float)atlas_.texture.height;

                float u0 = xStart;
                float u1 = xStart + leftRatio;
                float u2 = xEnd - rightRatio;
                float u3 = xEnd;

                float v0 = yEnd;
                float v1 = yEnd - topRatio;
                float v2 = yStart + bottomRatio;
                float v3 = yStart;

                uvs[0] = new Vector2(u0, v0);
                uvs[1] = new Vector2(u1, v0);
                uvs[2] = new Vector2(u2, v0);
                uvs[3] = new Vector2(u3, v0);

                uvs[4] = new Vector2(u0, v1);
                uvs[5] = new Vector2(u1, v1);
                uvs[6] = new Vector2(u2, v1);
                uvs[7] = new Vector2(u3, v1);

                uvs[8]  = new Vector2(u0, v2);
                uvs[9]  = new Vector2(u1, v2);
                uvs[10] = new Vector2(u2, v2);
                uvs[11] = new Vector2(u3, v2);

                uvs[12] = new Vector2(u0, v3);
                uvs[13] = new Vector2(u1, v3);
                uvs[14] = new Vector2(u2, v3);
                uvs[15] = new Vector2(u3, v3);
            }
            else
            {
                float xStart = 0.0f;
                float yStart = 0.0f;
                float xEnd   = 1.0f;
                float yEnd   = 1.0f;

                Texture texture     = GetComponent <Renderer>().sharedMaterial.mainTexture;
                float   leftRatio   = (float)guiBorder_.border.left / (float)texture.width;
                float   rightRatio  = (float)guiBorder_.border.right / (float)texture.width;
                float   topRatio    = (float)guiBorder_.border.top / (float)texture.height;
                float   bottomRatio = (float)guiBorder_.border.bottom / (float)texture.height;

                float u0 = xStart;
                float u1 = xStart + leftRatio;
                float u2 = xEnd - rightRatio;
                float u3 = xEnd;

                float v0 = yEnd;
                float v1 = yEnd - topRatio;
                float v2 = yStart + bottomRatio;
                float v3 = yStart;

                uvs[0] = new Vector2(u0, v0);
                uvs[1] = new Vector2(u1, v0);
                uvs[2] = new Vector2(u2, v0);
                uvs[3] = new Vector2(u3, v0);

                uvs[4] = new Vector2(u0, v1);
                uvs[5] = new Vector2(u1, v1);
                uvs[6] = new Vector2(u2, v1);
                uvs[7] = new Vector2(u3, v1);

                uvs[8]  = new Vector2(u0, v2);
                uvs[9]  = new Vector2(u1, v2);
                uvs[10] = new Vector2(u2, v2);
                uvs[11] = new Vector2(u3, v2);

                uvs[12] = new Vector2(u0, v3);
                uvs[13] = new Vector2(u1, v3);
                uvs[14] = new Vector2(u2, v3);
                uvs[15] = new Vector2(u3, v3);
            }
            _mesh.uv = uvs;
        }

        // ========================================================
        // Update Color
        // ========================================================

        if ((updateFlags & UpdateFlags.Color) != 0)
        {
            Color[] colors = new Color[16];
            for (int i = 0; i < 16; ++i)
            {
                colors[i] = color_;
            }
            _mesh.colors = colors;
        }

        // ========================================================
        // Update Index
        // ========================================================

        if ((updateFlags & UpdateFlags.Index) != 0)
        {
            int[] indices = new int[6 * 9];
            for (int i = 0; i < 3; ++i)
            {
                int vid = 4 * i;
                for (int j = 0; j < 3; ++j)
                {
                    int vert_id = vid + j;
                    int idx_id  = 6 * (i * 3 + j);

                    indices[idx_id + 0] = vert_id + 0;
                    indices[idx_id + 1] = vert_id + 1;
                    indices[idx_id + 2] = vert_id + 4;
                    indices[idx_id + 3] = vert_id + 4;
                    indices[idx_id + 4] = vert_id + 1;
                    indices[idx_id + 5] = vert_id + 5;
                }
            }
            _mesh.triangles = indices;
        }

        // NOTE: though we set updateFlags to None at exPlane::LateUpdate,
        //       the Editor still need this or it will caused editor keep dirty
        updateFlags = UpdateFlags.None;
    }
Example #3
0
    // ------------------------------------------------------------------
    /// \param _atlasInfo the atlas info
    /// \param _noImport if true, ex2D will not import the texture to fit for atlas
    /// build the atlas info to atlas
    // ------------------------------------------------------------------

    public static void Build(exAtlasInfo _atlasInfo, bool _noImport = false)
    {
        exAtlas   atlas    = _atlasInfo.atlas;
        Texture2D texture  = _atlasInfo.texture;
        Material  material = _atlasInfo.material;

        // check if the atlas info is valid for build
        if (atlas == null)
        {
            Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the atlas is missing!");
            return;
        }
        if (texture == null)
        {
            Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the texture is missing!");
            return;
        }
        if (material == null)
        {
            Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the material is missing!");
            return;
        }

        //
        if (_atlasInfo.needLayout)
        {
            _atlasInfo.LayoutElements();
            _atlasInfo.needLayout = false;
        }

        // create temp texture
        Color32 buildColor = new Color(0.0f, 0.0f, 0.0f, 0.0f);

        if (_atlasInfo.useBuildColor)
        {
            buildColor = new Color(_atlasInfo.buildColor.r,
                                   _atlasInfo.buildColor.g,
                                   _atlasInfo.buildColor.b,
                                   0.0f);
        }

        string path = AssetDatabase.GetAssetPath(texture);

        TextureImporter importer = TextureImporter.GetAtPath(path) as TextureImporter;

        // TextureImporterSettings textureImporterSettings = new TextureImporterSettings();
        // importer.ReadTextureSettings(textureImporterSettings);
        // textureImporterSettings.readable = true;
        // importer.SetTextureSettings(textureImporterSettings);
        importer.wrapMode   = TextureWrapMode.Clamp;
        importer.isReadable = true;
        AssetDatabase.ImportAsset(path);

        Color32[] colors = new Color32[_atlasInfo.width * _atlasInfo.height];
        for (int i = 0; i < _atlasInfo.width * _atlasInfo.height; ++i)
        {
            colors[i] = buildColor;
        }
        texture.SetPixels32(colors);

        try {
            EditorUtility.DisplayProgressBar("Building Atlas " + _atlasInfo.name, "Building Atlas...", 0.1f);

            // build atlas texture
            _atlasInfo.elements.Sort(exAtlasInfo.CompareByName);
            FillAtlasTexture(texture, _atlasInfo, _noImport);
            EditorUtility.DisplayProgressBar("Building Atlas " + _atlasInfo.name,
                                             "Import Atlas",
                                             0.9f);

            // write to disk
            byte[] pngData = texture.EncodeToPNG();
            if (pngData != null)
            {
                File.WriteAllBytes(path, pngData);
            }

            // now we finish atlas texture filling, we should turn off Read/Write settings, that will save memory a lot!
            TextureImporter importSettings = TextureImporter.GetAtPath(path) as TextureImporter;
            importSettings.wrapMode   = TextureWrapMode.Clamp;
            importSettings.isReadable = _atlasInfo.readable;
            AssetDatabase.ImportAsset(path);

            //
            atlas.elements = new exAtlas.Element[_atlasInfo.elements.Count];
            for (int i = 0; i < _atlasInfo.elements.Count; ++i)
            {
                exAtlasInfo.Element el  = _atlasInfo.elements[i];
                exAtlas.Element     el2 = new exAtlas.Element();

                int   coord_x = el.coord[0];
                int   coord_y = el.atlasInfo.height - el.coord[1] - (int)el.Height();
                float xStart  = (float)coord_x / (float)el.atlasInfo.width;
                float yStart  = (float)coord_y / (float)el.atlasInfo.height;
                float xEnd    = (float)(coord_x + el.Width()) / (float)el.atlasInfo.width;
                float yEnd    = (float)(coord_y + el.Height()) / (float)el.atlasInfo.height;
                el2.name           = el.texture.name;
                el2.coords         = new Rect(xStart, yStart, xEnd - xStart, yEnd - yStart);
                el2.rotated        = el.rotated;
                el2.originalWidth  = el.texture.width;
                el2.originalHeight = el.texture.height;
                el2.trimRect       = el.trimRect;
                atlas.elements[i]  = el2;

                // update the index in exAtlasDB
                if (el.isFontElement == false)
                {
                    exAtlasDB.UpdateElementInfo(el, i);
                }
            }
            atlas.texture  = texture;
            atlas.material = material;
            EditorUtility.SetDirty(atlas);
            EditorUtility.ClearProgressBar();
        }
        catch (System.Exception) {
            EditorUtility.ClearProgressBar();
            throw;
        }

        // save the needRebuild setting
        _atlasInfo.needRebuild = false;
        EditorUtility.SetDirty(_atlasInfo);
    }
Example #4
0
    // ------------------------------------------------------------------
    /// \param _atlas the new atlas
    /// \param _index the index of the element in the new atlas
    /// Set a new picture in an atlas to this sprite
    // ------------------------------------------------------------------

    public void SetSprite(exAtlas _atlas, int _index)
    {
        bool checkVertex = false;
        bool createMesh  = false;

        // pre-check
        if (_atlas == null ||
            _atlas.elements == null ||
            _index < 0 ||
            _index >= _atlas.elements.Length)
        {
            Debug.LogWarning("Invalid input in SetSprite. atlas = " + (_atlas ? _atlas.name : "null") + ", index = " + _index);
            return;
        }

        // it is possible that the atlas is null and we don't have mesh
        if (atlas_ == null)
        {
            createMesh = true;
        }

        //
        if (atlas_ != _atlas)
        {
            atlas_ = _atlas;
            renderer.sharedMaterial = _atlas.material;
            updateFlags            |= UpdateFlags.UV;
            checkVertex             = true;
        }

        //
        if (index_ != _index)
        {
            index_       = _index;
            updateFlags |= UpdateFlags.UV;
            checkVertex  = true;
        }

        //
        if (checkVertex)
        {
            // NOTE: if we use texture offset, it always need to update vertex
            if (useTextureOffset_)
            {
                updateFlags |= UpdateFlags.Vertex;
            }

            if (!customSize_)
            {
                exAtlas.Element el = atlas_.elements[index_];

                float newWidth  = el.trimRect.width;
                float newHeight = el.trimRect.height;
                // float newWidth = el.coords.width * atlas_.texture.width;
                // float newHeight = el.coords.height * atlas_.texture.height;

                if (el.rotated)
                {
                    float tmp = newWidth;
                    newWidth  = newHeight;
                    newHeight = tmp;
                }

                if (newWidth != width_ || newHeight != height_)
                {
                    width_       = newWidth;
                    height_      = newHeight;
                    updateFlags |= UpdateFlags.Vertex;
                }
            }
        }

        //
        if (createMesh)
        {
            // create mesh ( in editor, this can duplicate mesh to prevent shared mesh for sprite)
            meshFilter_.mesh = new Mesh();
            updateFlags      = UpdateFlags.Vertex | UpdateFlags.UV | UpdateFlags.Color | UpdateFlags.Index;

            // check if update mesh collider
            MeshCollider meshCollider = collider as MeshCollider;
            if (meshCollider && meshCollider.sharedMesh == null)
            {
                this.UpdateColliderSize(0.2f);
            }
        }
    }
Example #5
0
    // ------------------------------------------------------------------
    /// \param _mesh the mesh to update
    ///
    /// Update the _mesh depends on the exPlane.updateFlags
    // ------------------------------------------------------------------

    public void UpdateMesh(Mesh _mesh)
    {
        exAtlas.Element el = null;
        if (useAtlas)
        {
            el = atlas_.elements[index_];
        }

        // ========================================================
        // get clip info first
        // ========================================================

        float clipLeft   = 0.0f;
        float clipRight  = 0.0f;
        float clipTop    = 0.0f;
        float clipBottom = 0.0f;

        if (clipInfo_.clipped)
        {
            if (scale_.x >= 0.0f)
            {
                clipLeft  = clipInfo_.left;
                clipRight = clipInfo_.right;
            }
            else
            {
                clipLeft  = clipInfo_.right;
                clipRight = clipInfo_.left;
            }

            if (scale_.y >= 0.0f)
            {
                clipTop    = clipInfo_.top;
                clipBottom = clipInfo_.bottom;
            }
            else
            {
                clipTop    = clipInfo_.bottom;
                clipBottom = clipInfo_.top;
            }
        }

        // ========================================================
        // Update Vertex
        // ========================================================

        if ((updateFlags & UpdateFlags.Vertex) != 0)
        {
            Vector2 finalScale = new Vector2(scale_.x * ppfScale_.x,
                                             scale_.y * ppfScale_.y);

            // init
            float halfWidthScaled  = width_ * finalScale.x * 0.5f;
            float halfHeightScaled = height_ * finalScale.y * 0.5f;
            float offsetX          = 0.0f;
            float offsetY          = 0.0f;

            Vector3[] vertices = new Vector3[4];
            Vector3[] normals  = new Vector3[4]; // TEMP

            // calculate anchor offset
            if (useTextureOffset_)
            {
                // get original width and height
                float originalWidth  = 0.0f;
                float originalHeight = 0.0f;
                Rect  trimRect       = new Rect(0, 0, 1, 1);

                if (el != null)
                {
                    originalWidth  = el.originalWidth * finalScale.x;
                    originalHeight = el.originalHeight * finalScale.y;
                    trimRect       = new Rect(el.trimRect.x * finalScale.x,
                                              el.trimRect.y * finalScale.y,
                                              el.trimRect.width * finalScale.x,
                                              el.trimRect.height * finalScale.y);
                }
                else
                {
                    if (renderer.sharedMaterial != null)
                    {
                        Texture texture = renderer.sharedMaterial.mainTexture;
                        originalWidth  = texture.width * finalScale.x;
                        originalHeight = texture.height * finalScale.y;
                        trimRect       = new Rect(trimUV.x * originalWidth,
                                                  (1.0f - trimUV.height - trimUV.y) * originalHeight,
                                                  trimUV.width * originalWidth,
                                                  trimUV.height * originalHeight);
                    }
                }

                switch (anchor_)
                {
                //
                case Anchor.TopLeft:
                    offsetX = -halfWidthScaled - trimRect.x;
                    offsetY = -halfHeightScaled - trimRect.y;
                    break;

                case Anchor.TopCenter:
                    offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x;
                    offsetY = -halfHeightScaled - trimRect.y;
                    break;

                case Anchor.TopRight:
                    offsetX = halfWidthScaled + originalWidth - trimRect.xMax;
                    offsetY = -halfHeightScaled - trimRect.y;
                    break;

                //
                case Anchor.MidLeft:
                    offsetX = -halfWidthScaled - trimRect.x;
                    offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y;
                    break;

                case Anchor.MidCenter:
                    offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x;
                    offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y;
                    break;

                case Anchor.MidRight:
                    offsetX = halfWidthScaled + originalWidth - trimRect.xMax;
                    offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y;
                    break;

                //
                case Anchor.BotLeft:
                    offsetX = -halfWidthScaled - trimRect.x;
                    offsetY = halfHeightScaled + originalHeight - trimRect.yMax;
                    break;

                case Anchor.BotCenter:
                    offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x;
                    offsetY = halfHeightScaled + originalHeight - trimRect.yMax;
                    break;

                case Anchor.BotRight:
                    offsetX = halfWidthScaled + originalWidth - trimRect.xMax;
                    offsetY = halfHeightScaled + originalHeight - trimRect.yMax;
                    break;

                default:
                    offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x;
                    offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y;
                    break;
                }
            }
            else
            {
                switch (anchor_)
                {
                case Anchor.TopLeft: offsetX = -halfWidthScaled;   offsetY = -halfHeightScaled;  break;

                case Anchor.TopCenter: offsetX = 0.0f;               offsetY = -halfHeightScaled;  break;

                case Anchor.TopRight: offsetX = halfWidthScaled;    offsetY = -halfHeightScaled;  break;

                case Anchor.MidLeft: offsetX = -halfWidthScaled;   offsetY = 0.0f;               break;

                case Anchor.MidCenter: offsetX = 0.0f;               offsetY = 0.0f;               break;

                case Anchor.MidRight: offsetX = halfWidthScaled;    offsetY = 0.0f;               break;

                case Anchor.BotLeft: offsetX = -halfWidthScaled;   offsetY = halfHeightScaled;   break;

                case Anchor.BotCenter: offsetX = 0.0f;               offsetY = halfHeightScaled;   break;

                case Anchor.BotRight: offsetX = halfWidthScaled;    offsetY = halfHeightScaled;   break;

                default: offsetX = 0.0f;               offsetY = 0.0f;               break;
                }
            }
            offsetX -= offset_.x;
            offsetY += offset_.y;

            //
            float xMinClip = finalScale.x * width_ * (-0.5f + clipLeft);
            float xMaxClip = finalScale.x * width_ * (0.5f - clipRight);
            float yMinClip = finalScale.y * height_ * (-0.5f + clipTop);
            float yMaxClip = finalScale.y * height_ * (0.5f - clipBottom);

            // build vertices & normals
            for (int r = 0; r < 2; ++r)
            {
                for (int c = 0; c < 2; ++c)
                {
                    int   i = r * 2 + c;
                    float x, y;
                    CalculateVertex(out x, out y,
                                    width_ * finalScale.x, height_ * finalScale.y,
                                    c, r,
                                    xMinClip, xMaxClip, yMinClip, yMaxClip,
                                    offsetX, offsetY);
                    vertices[i] = new Vector3(x, y, 0.0f);
                    normals[i]  = new Vector3(0.0f, 0.0f, -1.0f);  // TEMP
                }
            }

            _mesh.vertices = vertices;
            _mesh.normals  = normals; // TEMP
            _mesh.bounds   = GetMeshBounds(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f);

            // update collider if we have
            UpdateBoundRect(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f);
            if (collisionHelper)
            {
                collisionHelper.UpdateCollider();
            }

// #if UNITY_EDITOR
//             _mesh.RecalculateBounds();
// #endif
        }

        // ========================================================
        // Update UV
        // ========================================================

        if ((updateFlags & UpdateFlags.UV) != 0)
        {
            Vector2[] uvs = new Vector2[4];

            // if the sprite is in an atlas
            if (el != null)
            {
                float xStart = el.coords.x;
                float yStart = el.coords.y;
                float xEnd   = el.coords.xMax;
                float yEnd   = el.coords.yMax;

                // do uv clip
                if (clipInfo_.clipped)
                {
                    xStart += el.coords.width * clipLeft;
                    yStart += el.coords.height * clipTop;
                    xEnd   -= el.coords.width * clipRight;
                    yEnd   -= el.coords.height * clipBottom;
                }

                if (el.rotated)
                {
                    uvs[0] = new Vector2(xEnd, yEnd);
                    uvs[1] = new Vector2(xEnd, yStart);
                    uvs[2] = new Vector2(xStart, yEnd);
                    uvs[3] = new Vector2(xStart, yStart);
                }
                else
                {
                    uvs[0] = new Vector2(xStart, yEnd);
                    uvs[1] = new Vector2(xEnd, yEnd);
                    uvs[2] = new Vector2(xStart, yStart);
                    uvs[3] = new Vector2(xEnd, yStart);
                }
            }
            else
            {
                float xStart = trimUV.x;
                float yStart = trimUV.y;
                float xEnd   = trimUV.xMax;
                float yEnd   = trimUV.yMax;

                // do uv clip
                if (clipInfo_.clipped)
                {
                    xStart += trimUV.width * clipLeft;
                    yStart += trimUV.height * clipTop;
                    xEnd   -= trimUV.width * clipRight;
                    yEnd   -= trimUV.height * clipBottom;
                }

                uvs[0] = new Vector2(xStart, yEnd);
                uvs[1] = new Vector2(xEnd, yEnd);
                uvs[2] = new Vector2(xStart, yStart);
                uvs[3] = new Vector2(xEnd, yStart);
            }
            _mesh.uv = uvs;
        }

        // ========================================================
        // Update Color
        // ========================================================

        if ((updateFlags & UpdateFlags.Color) != 0)
        {
            Color[] colors = new Color[4];
            for (int i = 0; i < 4; ++i)
            {
                colors[i] = color_;
            }
            _mesh.colors = colors;
        }

        // ========================================================
        // Update Index
        // ========================================================

        if ((updateFlags & UpdateFlags.Index) != 0)
        {
            int[] indices = new int[6];
            indices[0]      = 0;
            indices[1]      = 1;
            indices[2]      = 2;
            indices[3]      = 2;
            indices[4]      = 1;
            indices[5]      = 3;
            _mesh.triangles = indices;
        }

        // NOTE: though we set updateFlags to None at exPlane::LateUpdate,
        //       the Editor still need this or it will caused editor keep dirty
        updateFlags = UpdateFlags.None;
    }
Example #6
0
    ///////////////////////////////////////////////////////////////////////////////
    // mesh building functions
    ///////////////////////////////////////////////////////////////////////////////

    // ------------------------------------------------------------------
    /// \param _mesh the mesh to update
    ///
    /// Update the _mesh depends on the exPlane.updateFlags
    // ------------------------------------------------------------------

    public void UpdateMesh(Mesh _mesh)
    {
        if (guiBorder_ == null)
        {
            updateFlags = UpdateFlags.None;
            return;
        }

        exAtlas.Element el = null;
        if (useAtlas)
        {
            el = atlas_.elements[index_];
        }

        // ========================================================
        // get clip info first
        // ========================================================

        float clipLeft   = 0.0f;
        float clipRight  = 0.0f;
        float clipTop    = 0.0f;
        float clipBottom = 0.0f;

        if (clipInfo_.clipped)
        {
            if (scale_.x >= 0.0f)
            {
                clipLeft  = clipInfo_.left;
                clipRight = clipInfo_.right;
            }
            else
            {
                clipLeft  = clipInfo_.right;
                clipRight = clipInfo_.left;
            }

            if (scale_.y >= 0.0f)
            {
                clipTop    = clipInfo_.top;
                clipBottom = clipInfo_.bottom;
            }
            else
            {
                clipTop    = clipInfo_.bottom;
                clipBottom = clipInfo_.top;
            }
        }

        // ========================================================
        // Update Vertex
        // ========================================================

        if ((updateFlags & UpdateFlags.Vertex) != 0)
        {
            // init
            float widthScaled      = width_ * scale_.x;
            float heightScaled     = height_ * scale_.y;
            float halfWidthScaled  = widthScaled * 0.5f;
            float halfHeightScaled = heightScaled * 0.5f;
            float offsetX          = 0.0f;
            float offsetY          = 0.0f;

            Vector3[] vertices = new Vector3[16];

            switch (anchor_)
            {
            case Anchor.TopLeft: offsetX = -halfWidthScaled;   offsetY = -halfHeightScaled;  break;

            case Anchor.TopCenter: offsetX = 0.0f;               offsetY = -halfHeightScaled;  break;

            case Anchor.TopRight: offsetX = halfWidthScaled;    offsetY = -halfHeightScaled;  break;

            case Anchor.MidLeft: offsetX = -halfWidthScaled;   offsetY = 0.0f;               break;

            case Anchor.MidCenter: offsetX = 0.0f;               offsetY = 0.0f;               break;

            case Anchor.MidRight: offsetX = halfWidthScaled;    offsetY = 0.0f;               break;

            case Anchor.BotLeft: offsetX = -halfWidthScaled;   offsetY = halfHeightScaled;   break;

            case Anchor.BotCenter: offsetX = 0.0f;               offsetY = halfHeightScaled;   break;

            case Anchor.BotRight: offsetX = halfWidthScaled;    offsetY = halfHeightScaled;   break;

            default: offsetX = 0.0f;               offsetY = 0.0f;               break;
            }
            offsetX -= offset_.x;
            offsetY += offset_.y;

            //
            float xMinClip = scale_.x * width_ * (-0.5f + clipLeft);
            float xMaxClip = scale_.x * width_ * (0.5f - clipRight);
            float yMinClip = scale_.y * height_ * (-0.5f + clipTop);
            float yMaxClip = scale_.y * height_ * (0.5f - clipBottom);

            float centerWidth  = width_ - guiBorder_.border.horizontal;
            float centerHeight = height_ - guiBorder_.border.vertical;

            // calculate the base pos
            float x = -halfWidthScaled;
            float y = halfHeightScaled;

            float x0 = x;
            float x1 = x0 + guiBorder_.border.left * scale_.x;
            float x2 = x1 + centerWidth * scale_.x;
            float x3 = x2 + guiBorder_.border.right * scale_.x;

            float y0 = y;
            float y1 = y0 - guiBorder_.border.top * scale_.y;
            float y2 = y1 - centerHeight * scale_.y;
            float y3 = y2 - guiBorder_.border.bottom * scale_.y;

            // do clip
            if (clipInfo_.clipped)
            {
                // xMinClip
                if (x2 <= xMinClip)
                {
                    clipLeft = (xMinClip - x3) / (guiBorder_.border.right * scale_.x);
                    x0       = xMinClip;
                    x1       = xMinClip;
                    x2       = xMinClip;
                }
                else if (x1 <= xMinClip)
                {
                    clipLeft = 0.0f; // FIXME
                    x0       = xMinClip;
                    x1       = xMinClip;
                }
                else if (x0 <= xMinClip)
                {
                    clipLeft = (xMinClip - x0) / (float)(guiBorder_.border.left * scale_.x);
                    x0       = xMinClip;
                }

                // xMaxClip
                if (x1 >= xMaxClip)
                {
                    clipRight = (x0 - xMaxClip) / (guiBorder_.border.left * scale_.x);
                    x1        = xMaxClip;
                    x2        = xMaxClip;
                    x3        = xMaxClip;
                }
                else if (x2 >= xMaxClip)
                {
                    clipRight = 0.0f; // FIXME
                    x2        = xMaxClip;
                    x3        = xMaxClip;
                }
                else if (x3 >= xMaxClip)
                {
                    clipRight = (x3 - xMaxClip) / (guiBorder_.border.right * scale_.x);
                    x3        = xMaxClip;
                }

                // yMinClip
                if (y1 <= yMinClip)
                {
                    clipTop = (yMinClip - y0) / (guiBorder_.border.bottom * scale_.y);
                    y1      = yMinClip;
                    y2      = yMinClip;
                    y3      = yMinClip;
                }
                else if (y2 <= yMinClip)
                {
                    clipTop = 0.0f; // FIXME
                    y2      = yMinClip;
                    y3      = yMinClip;
                }
                else if (y3 <= yMinClip)
                {
                    clipTop = (yMinClip - y3) / (guiBorder_.border.top * scale_.y);
                    y3      = yMinClip;
                }

                // yMaxClip
                if (y2 >= yMaxClip)
                {
                    clipBottom = (y3 - yMaxClip) / (guiBorder_.border.top * scale_.y);
                    y0         = yMaxClip;
                    y1         = yMaxClip;
                    y2         = yMaxClip;
                }
                else if (y1 >= yMaxClip)
                {
                    clipBottom = 0.0f; // FIXME
                    y0         = yMaxClip;
                    y1         = yMaxClip;
                }
                else if (y0 >= yMaxClip)
                {
                    clipBottom = (y0 - yMaxClip) / (guiBorder_.border.bottom * scale_.y);
                    y0         = yMaxClip;
                }
            }

            // calculate the pos affect by anchor
            x0 -= offsetX; x1 -= offsetX; x2 -= offsetX; x3 -= offsetX;
            y0 += offsetY; y1 += offsetY; y2 += offsetY; y3 += offsetY;

            // build vertices
            vertices[0] = new Vector3(x0 + y0 * shear_.x, y0 + x0 * shear_.y, 0.0f);
            vertices[1] = new Vector3(x1 + y0 * shear_.x, y0 + x1 * shear_.y, 0.0f);
            vertices[2] = new Vector3(x2 + y0 * shear_.x, y0 + x2 * shear_.y, 0.0f);
            vertices[3] = new Vector3(x3 + y0 * shear_.x, y0 + x3 * shear_.y, 0.0f);

            vertices[4] = new Vector3(x0 + y1 * shear_.x, y1 + x0 * shear_.y, 0.0f);
            vertices[5] = new Vector3(x1 + y1 * shear_.x, y1 + x1 * shear_.y, 0.0f);
            vertices[6] = new Vector3(x2 + y1 * shear_.x, y1 + x2 * shear_.y, 0.0f);
            vertices[7] = new Vector3(x3 + y1 * shear_.x, y1 + x3 * shear_.y, 0.0f);

            vertices[8]  = new Vector3(x0 + y2 * shear_.x, y2 + x0 * shear_.y, 0.0f);
            vertices[9]  = new Vector3(x1 + y2 * shear_.x, y2 + x1 * shear_.y, 0.0f);
            vertices[10] = new Vector3(x2 + y2 * shear_.x, y2 + x2 * shear_.y, 0.0f);
            vertices[11] = new Vector3(x3 + y2 * shear_.x, y2 + x3 * shear_.y, 0.0f);

            vertices[12] = new Vector3(x0 + y3 * shear_.x, y3 + x0 * shear_.y, 0.0f);
            vertices[13] = new Vector3(x1 + y3 * shear_.x, y3 + x1 * shear_.y, 0.0f);
            vertices[14] = new Vector3(x2 + y3 * shear_.x, y3 + x2 * shear_.y, 0.0f);
            vertices[15] = new Vector3(x3 + y3 * shear_.x, y3 + x3 * shear_.y, 0.0f);

            // DELME {
            // // build vertices
            // switch ( plane ) {
            // case Plane.XY:
            //     vertices[0]  = new Vector3( x0 + y0 * shear_.x, y0 + x0 * shear_.y, 0.0f );
            //     vertices[1]  = new Vector3( x1 + y0 * shear_.x, y0 + x1 * shear_.y, 0.0f );
            //     vertices[2]  = new Vector3( x2 + y0 * shear_.x, y0 + x2 * shear_.y, 0.0f );
            //     vertices[3]  = new Vector3( x3 + y0 * shear_.x, y0 + x3 * shear_.y, 0.0f );

            //     vertices[4]  = new Vector3( x0 + y1 * shear_.x, y1 + x0 * shear_.y, 0.0f );
            //     vertices[5]  = new Vector3( x1 + y1 * shear_.x, y1 + x1 * shear_.y, 0.0f );
            //     vertices[6]  = new Vector3( x2 + y1 * shear_.x, y1 + x2 * shear_.y, 0.0f );
            //     vertices[7]  = new Vector3( x3 + y1 * shear_.x, y1 + x3 * shear_.y, 0.0f );

            //     vertices[8]  = new Vector3( x0 + y2 * shear_.x, y2 + x0 * shear_.y, 0.0f );
            //     vertices[9]  = new Vector3( x1 + y2 * shear_.x, y2 + x1 * shear_.y, 0.0f );
            //     vertices[10] = new Vector3( x2 + y2 * shear_.x, y2 + x2 * shear_.y, 0.0f );
            //     vertices[11] = new Vector3( x3 + y2 * shear_.x, y2 + x3 * shear_.y, 0.0f );

            //     vertices[12] = new Vector3( x0 + y3 * shear_.x, y3 + x0 * shear_.y, 0.0f );
            //     vertices[13] = new Vector3( x1 + y3 * shear_.x, y3 + x1 * shear_.y, 0.0f );
            //     vertices[14] = new Vector3( x2 + y3 * shear_.x, y3 + x2 * shear_.y, 0.0f );
            //     vertices[15] = new Vector3( x3 + y3 * shear_.x, y3 + x3 * shear_.y, 0.0f );
            //     break;

            // case Plane.XZ:
            //     vertices[0]  = new Vector3( x0 + y0 * shear_.x, 0.0f, y0 + x0 * shear_.y );
            //     vertices[1]  = new Vector3( x1 + y0 * shear_.x, 0.0f, y0 + x1 * shear_.y );
            //     vertices[2]  = new Vector3( x2 + y0 * shear_.x, 0.0f, y0 + x2 * shear_.y );
            //     vertices[3]  = new Vector3( x3 + y0 * shear_.x, 0.0f, y0 + x3 * shear_.y );

            //     vertices[4]  = new Vector3( x0 + y1 * shear_.x, 0.0f, y1 + x0 * shear_.y );
            //     vertices[5]  = new Vector3( x1 + y1 * shear_.x, 0.0f, y1 + x1 * shear_.y );
            //     vertices[6]  = new Vector3( x2 + y1 * shear_.x, 0.0f, y1 + x2 * shear_.y );
            //     vertices[7]  = new Vector3( x3 + y1 * shear_.x, 0.0f, y1 + x3 * shear_.y );

            //     vertices[8]  = new Vector3( x0 + y2 * shear_.x, 0.0f, y2 + x0 * shear_.y );
            //     vertices[9]  = new Vector3( x1 + y2 * shear_.x, 0.0f, y2 + x1 * shear_.y );
            //     vertices[10] = new Vector3( x2 + y2 * shear_.x, 0.0f, y2 + x2 * shear_.y );
            //     vertices[11] = new Vector3( x3 + y2 * shear_.x, 0.0f, y2 + x3 * shear_.y );

            //     vertices[12] = new Vector3( x0 + y3 * shear_.x, 0.0f, y3 + x0 * shear_.y );
            //     vertices[13] = new Vector3( x1 + y3 * shear_.x, 0.0f, y3 + x1 * shear_.y );
            //     vertices[14] = new Vector3( x2 + y3 * shear_.x, 0.0f, y3 + x2 * shear_.y );
            //     vertices[15] = new Vector3( x3 + y3 * shear_.x, 0.0f, y3 + x3 * shear_.y );
            //     break;

            // case Plane.ZY:
            //     vertices[0]  = new Vector3( 0.0f, y0 + x0 * shear_.y, x0 + y0 * shear_.x );
            //     vertices[1]  = new Vector3( 0.0f, y0 + x1 * shear_.y, x1 + y0 * shear_.x );
            //     vertices[2]  = new Vector3( 0.0f, y0 + x2 * shear_.y, x2 + y0 * shear_.x );
            //     vertices[3]  = new Vector3( 0.0f, y0 + x3 * shear_.y, x3 + y0 * shear_.x );
            //
            //     vertices[4]  = new Vector3( 0.0f, y1 + x0 * shear_.y, x0 + y1 * shear_.x );
            //     vertices[5]  = new Vector3( 0.0f, y1 + x1 * shear_.y, x1 + y1 * shear_.x );
            //     vertices[6]  = new Vector3( 0.0f, y1 + x2 * shear_.y, x2 + y1 * shear_.x );
            //     vertices[7]  = new Vector3( 0.0f, y1 + x3 * shear_.y, x3 + y1 * shear_.x );
            //
            //     vertices[8]  = new Vector3( 0.0f, y2 + x0 * shear_.y, x0 + y2 * shear_.x );
            //     vertices[9]  = new Vector3( 0.0f, y2 + x1 * shear_.y, x1 + y2 * shear_.x );
            //     vertices[10] = new Vector3( 0.0f, y2 + x2 * shear_.y, x2 + y2 * shear_.x );
            //     vertices[11] = new Vector3( 0.0f, y2 + x3 * shear_.y, x3 + y2 * shear_.x );
            //
            //     vertices[12] = new Vector3( 0.0f, y3 + x0 * shear_.y, x0 + y3 * shear_.x );
            //     vertices[13] = new Vector3( 0.0f, y3 + x1 * shear_.y, x1 + y3 * shear_.x );
            //     vertices[14] = new Vector3( 0.0f, y3 + x2 * shear_.y, x2 + y3 * shear_.x );
            //     vertices[15] = new Vector3( 0.0f, y3 + x3 * shear_.y, x3 + y3 * shear_.x );
            //     break;
            // }
            // } DELME end

            _mesh.vertices = vertices;
            _mesh.bounds   = GetMeshBounds(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f);

            // update collider if we have
            UpdateBoundRect(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f);
            if (collisionHelper)
            {
                collisionHelper.UpdateCollider();
            }
        }

        // ========================================================
        // Update UV
        // ========================================================

        if ((updateFlags & UpdateFlags.UV) != 0)
        {
            Vector2[] uvs = new Vector2[16];

            // if the sprite is in an atlas
            if (el != null)
            {
                float xStart = el.coords.x;
                float yStart = el.coords.y;
                float xEnd   = el.coords.xMax;
                float yEnd   = el.coords.yMax;

                float leftRatio   = (float)guiBorder_.border.left / (float)atlas_.texture.width;
                float rightRatio  = (float)guiBorder_.border.right / (float)atlas_.texture.width;
                float topRatio    = (float)guiBorder_.border.top / (float)atlas_.texture.height;
                float bottomRatio = (float)guiBorder_.border.bottom / (float)atlas_.texture.height;

                float umin = xStart;
                float umax = xEnd;
                float vmin = yStart;
                float vmax = yEnd;

                float u0 = xStart;
                float u1 = xStart + leftRatio;
                float u2 = xEnd - rightRatio;
                float u3 = xEnd;

                float v0 = yEnd;
                float v1 = yEnd - topRatio;
                float v2 = yStart + bottomRatio;
                float v3 = yStart;

                // do uv clip
                if (clipInfo_.clipped)
                {
                    umin = clipLeft >= 0.0f ? xStart + clipLeft * leftRatio     : xEnd + clipLeft * rightRatio;
                    umax = clipRight >= 0.0f ? xEnd - clipRight * rightRatio   : xStart - clipRight * leftRatio;
                    vmin = clipTop >= 0.0f ? yStart + clipTop * topRatio       : yEnd + clipTop * bottomRatio;
                    vmax = clipBottom >= 0.0f ? yEnd - clipBottom * bottomRatio : yStart - clipBottom * topRatio;

                    u0 = Mathf.Clamp(u0, umin, umax);
                    u1 = Mathf.Clamp(u1, umin, umax);
                    u2 = Mathf.Clamp(u2, umin, umax);
                    u3 = Mathf.Clamp(u3, umin, umax);

                    v0 = Mathf.Clamp(v0, vmin, vmax);
                    v1 = Mathf.Clamp(v1, vmin, vmax);
                    v2 = Mathf.Clamp(v2, vmin, vmax);
                    v3 = Mathf.Clamp(v3, vmin, vmax);
                }

                uvs[0] = new Vector2(u0, v0);
                uvs[1] = new Vector2(u1, v0);
                uvs[2] = new Vector2(u2, v0);
                uvs[3] = new Vector2(u3, v0);

                uvs[4] = new Vector2(u0, v1);
                uvs[5] = new Vector2(u1, v1);
                uvs[6] = new Vector2(u2, v1);
                uvs[7] = new Vector2(u3, v1);

                uvs[8]  = new Vector2(u0, v2);
                uvs[9]  = new Vector2(u1, v2);
                uvs[10] = new Vector2(u2, v2);
                uvs[11] = new Vector2(u3, v2);

                uvs[12] = new Vector2(u0, v3);
                uvs[13] = new Vector2(u1, v3);
                uvs[14] = new Vector2(u2, v3);
                uvs[15] = new Vector2(u3, v3);
            }
            else
            {
                float xStart = 0.0f;
                float yStart = 0.0f;
                float xEnd   = 1.0f;
                float yEnd   = 1.0f;

                Texture texture     = renderer.sharedMaterial.mainTexture;
                float   leftRatio   = (float)guiBorder_.border.left / (float)texture.width;
                float   rightRatio  = (float)guiBorder_.border.right / (float)texture.width;
                float   topRatio    = (float)guiBorder_.border.top / (float)texture.height;
                float   bottomRatio = (float)guiBorder_.border.bottom / (float)texture.height;

                float umin = xStart;
                float umax = xEnd;
                float vmin = yStart;
                float vmax = yEnd;

                float u0 = xStart;
                float u1 = xStart + leftRatio;
                float u2 = xEnd - rightRatio;
                float u3 = xEnd;

                float v0 = yEnd;
                float v1 = yEnd - topRatio;
                float v2 = yStart + bottomRatio;
                float v3 = yStart;

                // do uv clip
                if (clipInfo_.clipped)
                {
                    umin = clipLeft >= 0.0f ? xStart + clipLeft * leftRatio     : xEnd + clipLeft * rightRatio;
                    umax = clipRight >= 0.0f ? xEnd - clipRight * rightRatio   : xStart - clipRight * leftRatio;
                    vmin = clipTop >= 0.0f ? yStart + clipTop * topRatio       : yEnd + clipTop * bottomRatio;
                    vmax = clipBottom >= 0.0f ? yEnd - clipBottom * bottomRatio : yStart - clipBottom * topRatio;

                    u0 = Mathf.Clamp(u0, umin, umax);
                    u1 = Mathf.Clamp(u1, umin, umax);
                    u2 = Mathf.Clamp(u2, umin, umax);
                    u3 = Mathf.Clamp(u3, umin, umax);

                    v0 = Mathf.Clamp(v0, vmin, vmax);
                    v1 = Mathf.Clamp(v1, vmin, vmax);
                    v2 = Mathf.Clamp(v2, vmin, vmax);
                    v3 = Mathf.Clamp(v3, vmin, vmax);
                }

                uvs[0] = new Vector2(u0, v0);
                uvs[1] = new Vector2(u1, v0);
                uvs[2] = new Vector2(u2, v0);
                uvs[3] = new Vector2(u3, v0);

                uvs[4] = new Vector2(u0, v1);
                uvs[5] = new Vector2(u1, v1);
                uvs[6] = new Vector2(u2, v1);
                uvs[7] = new Vector2(u3, v1);

                uvs[8]  = new Vector2(u0, v2);
                uvs[9]  = new Vector2(u1, v2);
                uvs[10] = new Vector2(u2, v2);
                uvs[11] = new Vector2(u3, v2);

                uvs[12] = new Vector2(u0, v3);
                uvs[13] = new Vector2(u1, v3);
                uvs[14] = new Vector2(u2, v3);
                uvs[15] = new Vector2(u3, v3);
            }
            _mesh.uv = uvs;
        }

        // ========================================================
        // Update Color
        // ========================================================

        if ((updateFlags & UpdateFlags.Color) != 0)
        {
            Color[] colors = new Color[16];
            for (int i = 0; i < 16; ++i)
            {
                colors[i] = color_;
            }
            _mesh.colors = colors;
        }

        // ========================================================
        // Update Index
        // ========================================================

        if ((updateFlags & UpdateFlags.Index) != 0)
        {
            int[] indices = new int[6 * 9];
            for (int i = 0; i < 3; ++i)
            {
                int vid = 4 * i;
                for (int j = 0; j < 3; ++j)
                {
                    int vert_id = vid + j;
                    int idx_id  = 6 * (i * 3 + j);

                    indices[idx_id + 0] = vert_id + 0;
                    indices[idx_id + 1] = vert_id + 1;
                    indices[idx_id + 2] = vert_id + 4;
                    indices[idx_id + 3] = vert_id + 4;
                    indices[idx_id + 4] = vert_id + 1;
                    indices[idx_id + 5] = vert_id + 5;
                }
            }
            _mesh.triangles = indices;
        }

        // NOTE: though we set updateFlags to None at exPlane::LateUpdate,
        //       the Editor still need this or it will caused editor keep dirty
        updateFlags = UpdateFlags.None;
    }
Example #7
0
    // ------------------------------------------------------------------
    /// \param _mesh the mesh to update
    ///
    /// Update the _mesh depends on the exPlane.updateFlags
    // ------------------------------------------------------------------

    public void UpdateMesh(Mesh _mesh)
    {
        exAtlas.Element el = null;
        if (useAtlas)
        {
            el = atlas_.elements[index_];
        }

        // ========================================================
        // Update Vertex
        // ========================================================

        if ((updateFlags & UpdateFlags.Vertex) != 0)
        {
            Vector2 finalScale = new Vector2(scale_.x * ppfScale_.x,
                                             scale_.y * ppfScale_.y);

            // init
            float halfWidthScaled  = width_ * finalScale.x * 0.5f;
            float halfHeightScaled = height_ * finalScale.y * 0.5f;
            float offsetX          = 0.0f;
            float offsetY          = 0.0f;

            Vector3[] vertices = new Vector3[4];
            Vector3[] normals  = new Vector3[4];

            // calculate anchor offset
            if (useTextureOffset_)
            {
                // get original width and height
                float originalWidth  = 0.0f;
                float originalHeight = 0.0f;
                Rect  trimRect       = new Rect(0, 0, 1, 1);

                if (el != null)
                {
                    originalWidth  = el.originalWidth * finalScale.x;
                    originalHeight = el.originalHeight * finalScale.y;
                    trimRect       = new Rect(el.trimRect.x * finalScale.x,
                                              el.trimRect.y * finalScale.y,
                                              el.trimRect.width * finalScale.x,
                                              el.trimRect.height * finalScale.y);
                }
                else
                {
                    if (GetComponent <Renderer>().sharedMaterial != null)
                    {
                        Texture texture = GetComponent <Renderer>().sharedMaterial.mainTexture;
                        originalWidth  = texture.width * finalScale.x;
                        originalHeight = texture.height * finalScale.y;
                        trimRect       = new Rect(trimUV.x * originalWidth,
                                                  (1.0f - trimUV.height - trimUV.y) * originalHeight,
                                                  trimUV.width * originalWidth,
                                                  trimUV.height * originalHeight);
                    }
                }

                switch (anchor_)
                {
                //
                case Anchor.TopLeft:
                    offsetX = -halfWidthScaled - trimRect.x;
                    offsetY = -halfHeightScaled - trimRect.y;
                    break;

                case Anchor.TopCenter:
                    offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x;
                    offsetY = -halfHeightScaled - trimRect.y;
                    break;

                case Anchor.TopRight:
                    offsetX = halfWidthScaled + originalWidth - trimRect.xMax;
                    offsetY = -halfHeightScaled - trimRect.y;
                    break;

                //
                case Anchor.MidLeft:
                    offsetX = -halfWidthScaled - trimRect.x;
                    offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y;
                    break;

                case Anchor.MidCenter:
                    offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x;
                    offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y;
                    break;

                case Anchor.MidRight:
                    offsetX = halfWidthScaled + originalWidth - trimRect.xMax;
                    offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y;
                    break;

                //
                case Anchor.BotLeft:
                    offsetX = -halfWidthScaled - trimRect.x;
                    offsetY = halfHeightScaled + originalHeight - trimRect.yMax;
                    break;

                case Anchor.BotCenter:
                    offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x;
                    offsetY = halfHeightScaled + originalHeight - trimRect.yMax;
                    break;

                case Anchor.BotRight:
                    offsetX = halfWidthScaled + originalWidth - trimRect.xMax;
                    offsetY = halfHeightScaled + originalHeight - trimRect.yMax;
                    break;

                default:
                    offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x;
                    offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y;
                    break;
                }
            }
            else
            {
                switch (anchor_)
                {
                case Anchor.TopLeft: offsetX = -halfWidthScaled;   offsetY = -halfHeightScaled;  break;

                case Anchor.TopCenter: offsetX = 0.0f;               offsetY = -halfHeightScaled;  break;

                case Anchor.TopRight: offsetX = halfWidthScaled;    offsetY = -halfHeightScaled;  break;

                case Anchor.MidLeft: offsetX = -halfWidthScaled;   offsetY = 0.0f;               break;

                case Anchor.MidCenter: offsetX = 0.0f;               offsetY = 0.0f;               break;

                case Anchor.MidRight: offsetX = halfWidthScaled;    offsetY = 0.0f;               break;

                case Anchor.BotLeft: offsetX = -halfWidthScaled;   offsetY = halfHeightScaled;   break;

                case Anchor.BotCenter: offsetX = 0.0f;               offsetY = halfHeightScaled;   break;

                case Anchor.BotRight: offsetX = halfWidthScaled;    offsetY = halfHeightScaled;   break;

                default: offsetX = 0.0f;               offsetY = 0.0f;               break;
                }
            }
            offsetX -= offset_.x;
            offsetY += offset_.y;

            float minX = 9999.0f;
            float minY = 9999.0f;
            float maxX = -9999.0f;
            float maxY = -9999.0f;

            // build vertices & normals
            for (int r = 0; r < 2; ++r)
            {
                for (int c = 0; c < 2; ++c)
                {
                    int   i = r * 2 + c;
                    float x, y;
                    CalculateVertex(out x, out y,
                                    width_ * finalScale.x, height_ * finalScale.y,
                                    c, r,
                                    offsetX, offsetY);
                    vertices[i] = new Vector3(x, y, 0.0f);
                    normals[i]  = new Vector3(0.0f, 0.0f, -1.0f);

                    if (x < minX)
                    {
                        minX = x;
                    }
                    else if (x > maxX)
                    {
                        maxX = x;
                    }
                    if (y < minY)
                    {
                        minY = y;
                    }
                    else if (y > maxY)
                    {
                        maxY = y;
                    }
                }
            }

            float shearScaleWidth  = maxX - minX;
            float shearScaleHeight = maxY - minY;

            _mesh.vertices = vertices;
            _mesh.normals  = normals;
            _mesh.bounds   = GetMeshBounds(offsetX, offsetY, shearScaleWidth, shearScaleHeight);

            // update collider if we have
            UpdateBoundRect(offsetX, offsetY, shearScaleWidth, shearScaleHeight);
            if (collisionHelper)
            {
                collisionHelper.UpdateCollider();
            }

// #if UNITY_EDITOR
//             _mesh.RecalculateBounds();
// #endif
        }

        // ========================================================
        // Update UV
        // ========================================================

        if ((updateFlags & UpdateFlags.UV) != 0)
        {
            Vector2[] uvs = new Vector2[4];

            // if the sprite is in an atlas
            if (el != null)
            {
                float xStart = el.coords.x;
                float yStart = el.coords.y;
                float xEnd   = el.coords.xMax;
                float yEnd   = el.coords.yMax;

                if (el.rotated)
                {
                    uvs[0] = new Vector2(xEnd, yEnd);
                    uvs[1] = new Vector2(xEnd, yStart);
                    uvs[2] = new Vector2(xStart, yEnd);
                    uvs[3] = new Vector2(xStart, yStart);
                }
                else
                {
                    uvs[0] = new Vector2(xStart, yEnd);
                    uvs[1] = new Vector2(xEnd, yEnd);
                    uvs[2] = new Vector2(xStart, yStart);
                    uvs[3] = new Vector2(xEnd, yStart);
                }
            }
            else
            {
                float xStart = trimUV.x;
                float yStart = trimUV.y;
                float xEnd   = trimUV.xMax;
                float yEnd   = trimUV.yMax;

                uvs[0] = new Vector2(xStart, yEnd);
                uvs[1] = new Vector2(xEnd, yEnd);
                uvs[2] = new Vector2(xStart, yStart);
                uvs[3] = new Vector2(xEnd, yStart);
            }
            _mesh.uv = uvs;
        }

        // ========================================================
        // Update Color
        // ========================================================

        if ((updateFlags & UpdateFlags.Color) != 0)
        {
            Color[] colors = new Color[4];
            for (int i = 0; i < 4; ++i)
            {
                colors[i] = color_;
            }
            _mesh.colors = colors;
        }

        // ========================================================
        // Update Index
        // ========================================================

        if ((updateFlags & UpdateFlags.Index) != 0)
        {
            int[] indices = new int[6];
            indices[0]      = 0;
            indices[1]      = 1;
            indices[2]      = 2;
            indices[3]      = 2;
            indices[4]      = 1;
            indices[5]      = 3;
            _mesh.triangles = indices;
        }

        // NOTE: though we set updateFlags to None at exPlane::LateUpdate,
        //       the Editor still need this or it will caused editor keep dirty
        updateFlags = UpdateFlags.None;
    }
Example #8
0
    // ------------------------------------------------------------------
    /// \param _atlasInfo the atlas info
    /// \param _noImport if true, ex2D will not import the texture to fit for atlas 
    /// build the atlas info to atlas 
    // ------------------------------------------------------------------
    public static void Build( exAtlasInfo _atlasInfo, bool _noImport = false )
    {
        exAtlas atlas = _atlasInfo.atlas;
        Texture2D texture = _atlasInfo.texture;
        Material material = _atlasInfo.material;

        // check if the atlas info is valid for build
        if ( atlas == null ) {
            Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the atlas is missing!");
            return;
        }
        if ( texture == null ) {
            Debug.LogError("Failed to build atlas info "  + _atlasInfo.name + ", the texture is missing!");
            return;
        }
        if ( material == null ) {
            Debug.LogError("Failed to build atlas info "  + _atlasInfo.name + ", the material is missing!");
            return;
        }

        //
        if ( _atlasInfo.needLayout ) {
            _atlasInfo.LayoutElements();
            _atlasInfo.needLayout = false;
        }

        // create temp texture
        Color32 buildColor = new Color ( 0.0f, 0.0f, 0.0f, 0.0f );
        if ( _atlasInfo.useBuildColor )
            buildColor = new Color ( _atlasInfo.buildColor.r,
                                     _atlasInfo.buildColor.g,
                                     _atlasInfo.buildColor.b,
                                     0.0f );

        string path = AssetDatabase.GetAssetPath(texture);

        TextureImporter importer = TextureImporter.GetAtPath(path) as TextureImporter;
        // TextureImporterSettings textureImporterSettings = new TextureImporterSettings();
        // importer.ReadTextureSettings(textureImporterSettings);
        // textureImporterSettings.readable = true;
        // importer.SetTextureSettings(textureImporterSettings);
        importer.wrapMode = TextureWrapMode.Clamp;
        importer.isReadable = true;
        AssetDatabase.ImportAsset( path );

        Color32[] colors = new Color32[_atlasInfo.width*_atlasInfo.height];
        for ( int i = 0; i < _atlasInfo.width * _atlasInfo.height; ++i )
            colors[i] = buildColor;
        texture.SetPixels32( colors );

        try {
            EditorUtility.DisplayProgressBar( "Building Atlas " + _atlasInfo.name, "Building Atlas...", 0.1f );

            // build atlas texture
            _atlasInfo.elements.Sort( exAtlasInfo.CompareByName );
            FillAtlasTexture ( texture, _atlasInfo, _noImport );
            EditorUtility.DisplayProgressBar( "Building Atlas " + _atlasInfo.name,
                                              "Import Atlas",
                                              0.9f );

            // write to disk
            byte[] pngData = texture.EncodeToPNG();
            if (pngData != null)
                File.WriteAllBytes(path, pngData);

            // now we finish atlas texture filling, we should turn off Read/Write settings, that will save memory a lot!
            TextureImporter importSettings = TextureImporter.GetAtPath(path) as TextureImporter;
            importSettings.wrapMode = TextureWrapMode.Clamp;
            importSettings.isReadable = _atlasInfo.readable;
            AssetDatabase.ImportAsset( path );

            //
            atlas.elements = new exAtlas.Element[_atlasInfo.elements.Count];
            for ( int i = 0; i < _atlasInfo.elements.Count; ++i ) {
                exAtlasInfo.Element el = _atlasInfo.elements[i];
                exAtlas.Element el2 = new exAtlas.Element ();

                int coord_x = el.coord[0];
                int coord_y = el.atlasInfo.height - el.coord[1] - (int)el.Height();
                float xStart  = (float)coord_x / (float)el.atlasInfo.width;
                float yStart  = (float)coord_y / (float)el.atlasInfo.height;
                float xEnd    = (float)(coord_x + el.Width()) / (float)el.atlasInfo.width;
                float yEnd    = (float)(coord_y + el.Height()) / (float)el.atlasInfo.height;
                el2.name = el.texture.name;
                el2.coords = new Rect ( xStart, yStart, xEnd - xStart, yEnd - yStart );
                el2.rotated = el.rotated;
                el2.originalWidth = el.texture.width;
                el2.originalHeight = el.texture.height;
                el2.trimRect = el.trimRect;
                atlas.elements[i] = el2;

                // update the index in exAtlasDB
                if ( el.isFontElement == false ) {
                    exAtlasDB.UpdateElementInfo( el, i );
                }
            }
            atlas.texture = texture;
            atlas.material = material;
            EditorUtility.SetDirty(atlas);
            EditorUtility.ClearProgressBar();
        }
        catch ( System.Exception ) {
            EditorUtility.ClearProgressBar();
            throw;
        }

        // save the needRebuild setting
        _atlasInfo.needRebuild = false;
        EditorUtility.SetDirty(_atlasInfo);
    }