private void WriteRange(BlockRange range, Vector3 normal, float level, Vector3 addNormal, ref Dictionary<string, DataSet> datas)
        {
            DataSet foundSet = null;

            BlockSide side = Block.GetSideFromNormal(normal);
            Block bl = Block.Blocks[range.Block.GetGlobalID()];
            string tex = bl.GetTextureForSide(side, range.Block.Metadata);

            if (datas.ContainsKey(tex))
                foundSet = datas[tex];
            else
            {
                foundSet = new DataSet();
                foundSet.BaseData = range.Block;
                foundSet.Texture = tex;

                datas.Add(tex, foundSet);
            }

            //BlockSide side = Block.GetSideFromNormal(normal);
            //Block bl = Block.Blocks[range.Block.GetGlobalID()];
            //byte sideByte = 6;
            //DataSet foundSet = null;
            //sideByte = (byte)Block.GetSideInt(side);
            //if (bl.UsesOneTexture)
            //{
            //    side = BlockSide.AllSame;
            //    sideByte = (byte)Block.GetSideInt(side);
            //}
            //else
            //{
            //    string tex = bl.GetTextureForSide(side, range.Block.Metadata);
            //    int[] ids = Find(bl.GetTextures(range.Block.Metadata), tex);

            //    DataSet[] ds = new DataSet[ids.Length];

            //    KeyStruct key = new KeyStruct(){
            //        ID = range.Block.ID,
            //        Metadata = range.Block.Metadata,
            //        SideByte = sideByte
            //    };

            //    for (int s = 0; s < ids.Length; s++)
            //    {
            //        KeyStruct k = new KeyStruct()
            //        {
            //            ID = range.Block.ID,
            //            Metadata = range.Block.Metadata,
            //            SideByte = (byte)ids[s]
            //        };

            //        if (datas.ContainsKey(k) && key != k)
            //        {
            //            ds[s] = datas[k];
            //        }
            //    }

            //    for (int e = 0; e < ds.Length; e++)
            //        if (ds[e] != null)
            //        {
            //            foundSet = ds[e];
            //            break;
            //        }
            //}

            PointF ch = new PointF((range.To.X - range.From.X) + 1, (range.To.Y - range.From.Y) + 1);

            PointF t1 = range.From;
            PointF t2 = new PointF(range.From.X + ch.X, range.From.Y);
            PointF t3 = new PointF(range.From.X + ch.X, range.From.Y + ch.Y);
            PointF t4 = new PointF(range.From.X, range.From.Y + ch.Y);

            Vector2 uv1 = new Vector2(0, 0);
            Vector2 uv2 = new Vector2(ch.X, 0);
            Vector2 uv3 = new Vector2(ch.X, ch.Y);
            Vector2 uv4 = new Vector2(0, ch.Y);

            Vector3 t3d1 = ConvertToPos(t1, normal, level) + addNormal;
            Vector3 t3d2 = ConvertToPos(t2, normal, level) + addNormal;
            Vector3 t3d3 = ConvertToPos(t3, normal, level) + addNormal;
            Vector3 t3d4 = ConvertToPos(t4, normal, level) + addNormal;

            if (foundSet == null)
            {
                //KeyStruct key = new KeyStruct()
                //{
                //    ID = range.Block.ID,
                //    Metadata = range.Block.Metadata,
                //    SideByte = sideByte
                //};

                //if (!datas.ContainsKey(key))
                //{
                //    datas.Add(key, new DataSet());
                //    datas[key].BaseData = range.Block;
                //    datas[key].SideByte = sideByte;
                //}

                //WriteTriangle(datas[key], t3d1, t3d2, t3d3, uv1, uv2, uv3, normal);
                //WriteTriangle(datas[key], t3d3, t3d4, t3d1, uv3, uv4, uv1, normal);
            }
            else
            {
                WriteTriangle(foundSet, t3d1, t3d2, t3d3, uv1, uv2, uv3, normal);
                WriteTriangle(foundSet, t3d3, t3d4, t3d1, uv3, uv4, uv1, normal);
            }
        }
        private void WriteTriangle(DataSet ds, Vector3 v1, Vector3 v2, Vector3 v3, Vector2 uv1, Vector2 uv2, Vector2 uv3, Vector3 normal)
        {
            ds.verts.Add(v1);
            ds.verts.Add(v2);
            ds.verts.Add(v3);
            _vertices += 3;

            ds.uvs.Add(uv1);
            ds.uvs.Add(uv2);
            ds.uvs.Add(uv3);

            ds.normals.Add(normal);
            ds.normals.Add(normal);
            ds.normals.Add(normal);
        }
        private void WriteCustomData(CustomBlockData range, ref Dictionary<string, DataSet> datas)
        {
            DataSet foundSet = null;

            if (datas.ContainsKey(range.Texture))
                foundSet = datas[range.Texture];
            else
            {
                foundSet = new DataSet();
                foundSet.BaseData = range.Source;
                foundSet.Texture = range.Texture;

                datas.Add(range.Texture, foundSet);
            }

            Vector3 normal = range.Normal;

            //BlockSide side = Block.GetSideFromNormal(normal);
            //Block bl = Block.Blocks[range.Source.GetGlobalID()];
            //byte sideByte = 6;
            //DataSet foundSet = null;
            //sideByte = (byte)Block.GetSideInt(side);
            //if (bl.UsesOneTexture)
            //{
            //    side = BlockSide.AllSame;
            //    sideByte = (byte)Block.GetSideInt(side);
            //}
            //else
            //{
            //    string tex = range.Texture;//bl.GetTextureForSide(side, range.Source.Metadata);
            //    int[] ids = Find(bl.GetTextures(range.Source.Metadata), tex);

            //    DataSet[] ds = new DataSet[ids.Length];

            //    KeyStruct key = new KeyStruct()
            //    {
            //        ID = range.Source.ID,
            //        Metadata = range.Source.Metadata,
            //        SideByte = sideByte,
            //    };

            //    for (int s = 0; s < ids.Length; s++)
            //    {
            //        KeyStruct k = new KeyStruct()
            //        {
            //            ID = range.Source.ID,
            //            Metadata = range.Source.Metadata,
            //            SideByte = (byte)ids[s]
            //        };

            //        if (datas.ContainsKey(k) && key != k)
            //        {
            //            ds[s] = datas[k];
            //        }
            //    }

            //    for (int e = 0; e < ds.Length; e++)
            //        if (ds[e] != null)
            //        {
            //            foundSet = ds[e];
            //            break;
            //        }
            //}

            //if (foundSet == null)
            //{
            //    KeyStruct key = new KeyStruct()
            //    {
            //        ID = range.Source.ID,
            //        Metadata = range.Source.Metadata,
            //        SideByte = sideByte
            //    };

            //    if (!datas.ContainsKey(key))
            //    {
            //        datas.Add(key, new DataSet());
            //        datas[key].BaseData = range.Source;
            //        datas[key].SideByte = sideByte;

            //        foundSet = datas[key];
            //    }
            //    else
            //    {
            //        foundSet = datas[key];
            //    }
            //}

            //tri1: 1,2,3
            //tri2: 3,4,1

            //Vector3 tri1Norm = Vector3.Cross((range.Vertex2 - range.Vertex1), (range.Vertex3 - range.Vertex1));
            //Vector3 tri2Norm = Vector3.Cross((range.Vertex3 - range.Vertex1), (range.Vertex4 - range.Vertex1));
            Vector3 tri1Norm = normal;
            Vector3 tri2Norm = normal;

            if (range.TriFlip)// || (!range.TriFlip && (normal.X < 0 || normal.Y < 0 || normal.Z < 0)))
            {
                WriteTriangle(foundSet, range.Vertex3, range.Vertex2, range.Vertex1, range.UV3, range.UV2, range.UV1, tri1Norm);
                if (!range.IsOneTriangle)
                {
                    WriteTriangle(foundSet, range.Vertex1, range.Vertex4, range.Vertex3, range.UV1, range.UV4, range.UV3, tri2Norm);
                }
            }
            else
            {
                WriteTriangle(foundSet, range.Vertex1, range.Vertex2, range.Vertex3, range.UV1, range.UV2, range.UV3, tri1Norm);
                if (!range.IsOneTriangle)
                {
                    WriteTriangle(foundSet, range.Vertex3, range.Vertex4, range.Vertex1, range.UV3, range.UV4, range.UV1, tri2Norm);
                }
            }

            if (range.DoubleSided)
            {
                range.DoubleSided = false;
                range.Normal = -range.Normal;
                WriteCustomData(range, ref datas);
            }
        }