void GenMeshWithBound(HEX _hex)
    {
        if (tri_ver == null)
        {
            tri_ver = new Vector3[] { new Vector3(_bound.min.x, _bound.min.y, 0), new Vector3(_bound.max.x, _bound.min.y, 0), new Vector3(_bound.min.x, _bound.max.y, 0), new Vector3(_bound.max.x, _bound.max.y, 0) };
        }
        mPlan           = new Mesh();
        mPlan.vertices  = tri_ver;
        mPlan.triangles = tri_idx;
        mPlan.colors    = null;
        mPlan.tangents  = null;
        mPlan.uv        = null;
        mPlan.bounds    = _bound;
        //计算法线
        mPlan.RecalculateNormals();

        MeshFilter mf = gameObject.AddComponent <MeshFilter>();

        mf.sharedMesh = mPlan;

        MeshRenderer mr = gameObject.AddComponent <MeshRenderer>();

        mr.sharedMaterials = _hex.GetWaterMats();
        //UpdateBlock();
        //mr.SetPropertyBlock(_block);

        //_weak_mat = new WeakReference(mr.material);
        //_weak_mesh = new WeakReference(mf.mesh);

        //BoxCollider pb = gameObject.AddComponent<BoxCollider>();
        //pb.center = _bound.center;
        //pb.size = _bound.size;
    }
    void GenHexMesh(HEX _hex)
    {
        MapProxy mapProxy = GameFacade.GetProxy <MapProxy>();

        Vector3[] hexgon =
        {
#if HEXGON0
            new Vector3(0,     0, 0),   // 0
#endif
            new Vector3(0,    +1, 0),   // 1
            new Vector3(+Tx, +Ty, 0),   // 2
            new Vector3(+Tx, -Ty, 0),   // 3
            new Vector3(0,    -1, 0),   // 4
            new Vector3(-Tx, -Ty, 0),   // 5
            new Vector3(-Tx, +Ty, 0),   // 6
        };

        Vector2[] water =
        {
            new Vector2(0, 0),
            new Vector2(1, 0),
        };

        Color[] sc =
        {
            new Color(0, 0, 0, 0),
            new Color(1, 0, 0, 0),
            new Color(0, 1, 0, 0),
            new Color(0, 0, 1, 0),
            new Color(0, 0, 0, 1),
        };

        Vector4[] vc =
        {
            new Vector4(0, 0, 0, 0),
            new Vector4(1, 0, 0, 0),
            new Vector4(0, 1, 0, 0),
            new Vector4(0, 0, 1, 0),
            new Vector4(0, 0, 0, 1),
        };

        int siz = (_hex.yTile + 1) * (_hex.yTile + 1) * 8;

        if (lst == null)
        {
            lst = new int[siz];
        }
        for (int i = 0; i < siz; i++)
        {
            lst[i] = -1;
        }


        welement e       = new welement();
        _reindex reindex = (ref welement _elm, int _ver, int _col, int _row) =>
        {
            MapTileVO tileVo = mapProxy.GetTile(_col + _hex.xTile * _x, _row + _hex.yTile * _y);
            int       loc    = ((_row + 1) * (_hex.xTile + 1) + (_col + 1)) * 8 + _ver;
            int       idx    = lst[loc];
            if (idx >= 0)
            {
                return(idx);
            }

            idx      = _elm.vHex.Count;
            lst[loc] = idx;

            Vector3 _v = Vector3.zero;
            Vector3 _n = Vector3.zero;
            Vector4 _t = Vector4.zero;
            Vector2 _u = Vector2.zero;
            Color   _c;
            Vector2 _waterColor;

            float _R = Tx * 2.0f + _hex.fvHex.x;

            int m = tileVo.mat;
            int n = isGenHeight ? tileVo.height : MapConst.MAP_HEIGHT_HORIZON;
            if (m == 8)
            {
                _waterColor = water[1];
                _c          = sc [0];
                _t          = vc [0];
            }
            else
            {
                _waterColor = water[0];
                _c          = sc [m < 4 ? m + 1 : 0];
                _t          = vc [m > 3 ? m - 3 : 0];
            }

            _v.x = _R * _col;
            _v.y = _R * Tx * _row;
            _v.z = n;
            _n.z = m;
            if (_row % 2 == 0)
            {
                _v.x += 0.0f;
            }
            else
            {
                _v.x += Tx + Ty * _hex.fvHex.x;
            }

            _elm.vHex.Add(hexgon [_ver] + _v);
            _elm.vNor.Add(_n);
            _elm.vClr.Add(_c);
            _elm.vTan.Add(_t);
            _elm.vTex.Add(_u);
            _elm.vWater.Add(_waterColor);
            _elm.hasFoam.Add(new Vector2(tileVo.blockType == MapBlockType.WaterWave ? 1 : 0, 0));
            return(idx);
        };

        _recheck recheck = (int _ver, int _col, int _row) =>
        {
            MapTileVO tileVo = mapProxy.GetTile(_col + _hex.xTile * _x, _row + _hex.yTile * _y);
            //if (tileVo.mat < 1)
            if (tileVo.IsWater())
            {
                return(false);
            }
            return(true);
        };
        int nHexIndices, nIndexOffset;

#if HEXGON0
        int[] tdx =
        {
            0, 1, 2, 0, 2, 3, 0, 3, 4,
            0, 4, 5, 0, 5, 6, 0, 6, 1,
        };
        nHexIndices  = 18;
        nIndexOffset = 0;
#else
        int[] tdx =
        {
            0, 1, 5, 5, 1, 4, 2, 4, 1, 3, 4, 2
        };
        nHexIndices  = 12;
        nIndexOffset = 1;
#endif

        int[][] edx =
        {
            new int[] { 6, 5, 2, 3, 2, 5 },
            new int[] { 5, 4, 1, 2, 1, 4 },
            new int[] { 1, 6, 3, 4, 3, 6 },
            new int[] { 6, 2, 4, 5, 1, 3 },
        };

        List <int> vIdx = new List <int>();
        List <int> vSub = new List <int>();
        bool       pass = true;
        for (int y = 0; y < _yTile; y++)
        {
            for (int x = 0; x < _xTile; x++)
            {
                for (int i = 0; i < nHexIndices; i++)
                {
                    if (recheck(tdx[i], x, y) == false)
                    {
                        vIdx.Add(reindex(ref e, tdx[i], x, y));
                    }
                }

                // west -> x-1
                // south west -> odd : x, y-1  even: x-1, y-1
                // south -> odd: x+1, y-1 even: x, y-1

                int t  = y % 2;
                int ww = x - 1;                 // y
                int sw = t > 0 ? x : x - 1;     // y-1
                int nw = t > 0 ? x : x - 1;     // y+1

                if (IsValid(ww, y))
                {
                    pass  = true;
                    pass &= recheck(edx[0][0] - nIndexOffset, x, y);
                    pass &= recheck(edx[0][1] - nIndexOffset, x, y);
                    pass &= recheck(edx[0][2] - nIndexOffset, ww, y);

                    if (pass == false)
                    {
                        vSub.Add(reindex(ref e, edx[0][0] - nIndexOffset, x, y));
                        vSub.Add(reindex(ref e, edx[0][1] - nIndexOffset, x, y));
                        vSub.Add(reindex(ref e, edx[0][2] - nIndexOffset, ww, y));
                    }

                    pass  = true;
                    pass &= recheck(edx[0][3] - nIndexOffset, ww, y);
                    pass &= recheck(edx[0][4] - nIndexOffset, ww, y);
                    pass &= recheck(edx[0][5] - nIndexOffset, x, y);

                    if (pass == false)
                    {
                        vSub.Add(reindex(ref e, edx[0][3] - nIndexOffset, ww, y));
                        vSub.Add(reindex(ref e, edx[0][4] - nIndexOffset, ww, y));
                        vSub.Add(reindex(ref e, edx[0][5] - nIndexOffset, x, y));
                    }

                    if (IsValid(nw, y + 1))
                    {
                        pass  = true;
                        pass &= recheck(edx[3][0] - nIndexOffset, x, y);
                        pass &= recheck(edx[3][1] - nIndexOffset, ww, y);
                        pass &= recheck(edx[3][2] - nIndexOffset, nw, y + 1);

                        if (pass == false)
                        {
                            vSub.Add(reindex(ref e, edx[3][0] - nIndexOffset, x, y));
                            vSub.Add(reindex(ref e, edx[3][1] - nIndexOffset, ww, y));
                            vSub.Add(reindex(ref e, edx[3][2] - nIndexOffset, nw, y + 1));
                        }
                    }

                    if (IsValid(sw, y - 1))
                    {
                        pass  = true;
                        pass &= recheck(edx[3][3] - nIndexOffset, x, y);
                        pass &= recheck(edx[3][4] - nIndexOffset, sw, y - 1);
                        pass &= recheck(edx[3][5] - nIndexOffset, ww, y);

                        if (pass == false)
                        {
                            vSub.Add(reindex(ref e, edx[3][3] - nIndexOffset, x, y));
                            vSub.Add(reindex(ref e, edx[3][4] - nIndexOffset, sw, y - 1));
                            vSub.Add(reindex(ref e, edx[3][5] - nIndexOffset, ww, y));
                        }
                    }
                }

                if (IsValid(sw, y - 1))
                {
                    pass  = true;
                    pass &= recheck(edx[1][0] - nIndexOffset, x, y);
                    pass &= recheck(edx[1][1] - nIndexOffset, x, y);
                    pass &= recheck(edx[1][2] - nIndexOffset, sw, y - 1);

                    if (pass == false)
                    {
                        vSub.Add(reindex(ref e, edx[1][0] - nIndexOffset, x, y));
                        vSub.Add(reindex(ref e, edx[1][1] - nIndexOffset, x, y));
                        vSub.Add(reindex(ref e, edx[1][2] - nIndexOffset, sw, y - 1));
                    }

                    pass  = true;
                    pass &= recheck(edx[1][3] - nIndexOffset, sw, y - 1);
                    pass &= recheck(edx[1][4] - nIndexOffset, sw, y - 1);
                    pass &= recheck(edx[1][5] - nIndexOffset, x, y);

                    if (pass == false)
                    {
                        vSub.Add(reindex(ref e, edx[1][3] - nIndexOffset, sw, y - 1));
                        vSub.Add(reindex(ref e, edx[1][4] - nIndexOffset, sw, y - 1));
                        vSub.Add(reindex(ref e, edx[1][5] - nIndexOffset, x, y));
                    }
                }

                if (IsValid(nw, y + 1))
                {
                    pass  = true;
                    pass &= recheck(edx[2][0] - nIndexOffset, x, y);
                    pass &= recheck(edx[2][1] - nIndexOffset, x, y);
                    pass &= recheck(edx[2][2] - nIndexOffset, nw, y + 1);

                    if (pass == false)
                    {
                        vSub.Add(reindex(ref e, edx[2][0] - nIndexOffset, x, y));
                        vSub.Add(reindex(ref e, edx[2][1] - nIndexOffset, x, y));
                        vSub.Add(reindex(ref e, edx[2][2] - nIndexOffset, nw, y + 1));
                    }

                    pass  = true;
                    pass &= recheck(edx[2][3] - nIndexOffset, nw, y + 1);
                    pass &= recheck(edx[2][4] - nIndexOffset, nw, y + 1);
                    pass &= recheck(edx[2][5] - nIndexOffset, x, y);

                    if (pass == false)
                    {
                        vSub.Add(reindex(ref e, edx[2][3] - nIndexOffset, nw, y + 1));
                        vSub.Add(reindex(ref e, edx[2][4] - nIndexOffset, nw, y + 1));
                        vSub.Add(reindex(ref e, edx[2][5] - nIndexOffset, x, y));
                    }
                }

                if (y == 0)
                {
                    // we only patch west, north west, south west, which leaves crack in zero line
                    if (IsValid(x, y - 1))
                    {
                        pass  = true;
                        pass &= recheck(edx[2][3] - nIndexOffset, x, y);
                        pass &= recheck(edx[2][4] - nIndexOffset, x, y);
                        pass &= recheck(edx[2][5] - nIndexOffset, x, y - 1);

                        if (pass == false)
                        {
                            vSub.Add(reindex(ref e, edx[2][3] - nIndexOffset, x, y));
                            vSub.Add(reindex(ref e, edx[2][4] - nIndexOffset, x, y));
                            vSub.Add(reindex(ref e, edx[2][5] - nIndexOffset, x, y - 1));
                        }

                        pass  = true;
                        pass &= recheck(edx[2][0] - nIndexOffset, x, y - 1);
                        pass &= recheck(edx[2][1] - nIndexOffset, x, y - 1);
                        pass &= recheck(edx[2][2] - nIndexOffset, x, y);

                        if (pass == false)
                        {
                            vSub.Add(reindex(ref e, edx[2][0] - nIndexOffset, x, y - 1));
                            vSub.Add(reindex(ref e, edx[2][1] - nIndexOffset, x, y - 1));
                            vSub.Add(reindex(ref e, edx[2][2] - nIndexOffset, x, y));
                        }

                        if (IsValid(x - 1, y - 1))
                        {
                            pass  = true;
                            pass &= recheck(edx[3][0] - nIndexOffset, x, y - 1);
                            pass &= recheck(edx[3][1] - nIndexOffset, x - 1, y - 1);
                            pass &= recheck(edx[3][2] - nIndexOffset, x, y);

                            if (pass == false)
                            {
                                vSub.Add(reindex(ref e, edx[3][0] - nIndexOffset, x, y - 1));
                                vSub.Add(reindex(ref e, edx[3][1] - nIndexOffset, x - 1, y - 1));
                                vSub.Add(reindex(ref e, edx[3][2] - nIndexOffset, x, y));
                            }
                        }
                    }
                }
            }
        }


        Mesh me = new Mesh();
        me.subMeshCount = 2;
        me.vertices     = e.vHex.ToArray();
        me.SetTriangles(vIdx.ToArray(), 0);
        me.SetTriangles(vSub.ToArray(), 1);
        me.normals  = e.vNor.ToArray();
        me.colors   = e.vClr.ToArray();
        me.tangents = e.vTan.ToArray();
        me.uv       = e.vTex.ToArray();
        me.uv2      = e.vWater.ToArray();
        me.uv3      = e.hasFoam.ToArray();
        me.bounds   = _bound;

        var mf = gameObject.GetComponent <MeshFilter>();
        if (mf == null)
        {
            mf = gameObject.AddComponent <MeshFilter>();
        }
        mf.sharedMesh = me;

        var mr = gameObject.GetComponent <MeshRenderer>();
        if (mr == null)
        {
            mr = gameObject.AddComponent <MeshRenderer>();
        }
        mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
        mr.sharedMaterials   = _hex.GetWaterMats();
        //mr.SetPropertyBlock(UpdateBlock());
    }