private Dictionary<Vector4, BlockRange[]> SetupModelData(Dictionary<Vector3, List<BlockRange>> data, Point3 position, float level)
        {
            Dictionary<Vector4, List<BlockRange>> rt = new Dictionary<Vector4, List<BlockRange>>();

            foreach (KeyValuePair<Vector3, List<BlockRange>> pair in data)
            {
                Vector4 key = new Vector4(pair.Key.X, pair.Key.Y, pair.Key.Z, level);

                PointF xy = GetXYByNormal(pair.Key, position);

                List<BlockRange> rg = pair.Value;

                for (int x = 0; x < rg.Count; x++)
                    rg[x].Shift(xy);

                if (rt.ContainsKey(key))
                {
                    rt[key].AddRange(pair.Value);
                }
                else
                {
                    rt.Add(key, rg);
                }
            }

            Dictionary<Vector4, BlockRange[]> e = new Dictionary<Vector4, BlockRange[]>();

            foreach (KeyValuePair<Vector4, List<BlockRange>> pair in rt)
            {
                e.Add(pair.Key, pair.Value.ToArray());
            }

            return e;
        }
        private BlockData GetBlockDataAt(Point3 pos)
        {
            if (pos.X >= 0 && pos.Y >= 0 && pos.Z >= 0 && pos.X < _in.BlockIDs.GetLength(0) && pos.Y < _in.BlockIDs.GetLength(1) && pos.Z < _in.BlockIDs.GetLength(2))
            {
                if (_in.BlockIDs[pos.X, pos.Y, pos.Z] == 0)
                    return new BlockData(0, 0);
                return new BlockData(_in.BlockIDs[pos.X, pos.Y, pos.Z], _in.BlockMetadatas[pos.X, pos.Y, pos.Z]);
            }

            return new BlockData(0, 0);
        }
        private PointF GetXYByNormal(Vector3 normal, Point3 position)
        {
            if (normal.X != 0 && normal.Y == 0 && normal.Z == 0)
            {
                return new PointF(position.Z, position.Y);
            }
            if (normal.X == 0 && normal.Y != 0 && normal.Z == 0)
            {
                return new PointF(position.X, position.Z);
            }
            if (normal.X == 0 && normal.Y == 0 && normal.Z != 0)
            {
                return new PointF(position.X, position.Y);
            }

            return new PointF(0, 0);
        }
        private Point3 ConvertLevelAndXYToPos(int a, int b, int level, Point3 xyzLength)
        {
            if (xyzLength.X == 2 && xyzLength.Y == 1 && xyzLength.Z == 0)
                return new Point3(level, b, a);
            if (xyzLength.X == 0 && xyzLength.Y == 2 && xyzLength.Z == 1)
                return new Point3(a, level, b);
            if (xyzLength.X == 0 && xyzLength.Y == 1 && xyzLength.Z == 2)
                return new Point3(a, b, level);

            return new Point3(0, 0, 0);
        }
        private bool CheckFaceInterior(Point3 block, Vector3 normal)
        {
            Point3 dir = normal.ToPoint3Normal();

            Point3 pos = block;

            pos += dir;

            if (!(pos.X >= 0 && pos.Y >= 0 && pos.Z >= 0 && pos.X < _in.BlockIDs.GetLength(0) && pos.Y < _in.BlockIDs.GetLength(1) && pos.Z < _in.BlockIDs.GetLength(2)))
                return false;

            while (pos.X >= 0 && pos.Y >= 0 && pos.Z >= 0 && pos.X < _in.BlockIDs.GetLength(0) && pos.Y < _in.BlockIDs.GetLength(1) && pos.Z < _in.BlockIDs.GetLength(2))
            {
                if (_in.BlockIDs[pos.X, pos.Y, pos.Z] != 0)
                {
                    return true;
                }

                pos += dir;
            }

            return false;
        }
        private bool CheckFace(Point3 block, Vector3 normal)
        {
            Point3 dir = normal.ToPoint3Normal();

            Point3 pos = block + dir;

            if (pos.X < 0 || pos.Y < 0 || pos.Z < 0 || pos.X >= _in.BlockIDs.GetLength(0) || pos.Y >= _in.BlockIDs.GetLength(1) || pos.Z >= _in.BlockIDs.GetLength(2))
                return false;

            return true;
        }
        private bool CanGenerateSide(Point3 pos, Vector3 norm)
        {
            BlockData me = GetBlockDataAt(pos);

            if (me == null)
                return false;

            Point3 p3normal = new Point3((int)norm.X, (int)norm.Y, (int)norm.Z);

            BlockData atSide = GetBlockDataAt(pos + p3normal);
            if (atSide == null)
                return true;

            if (atSide.EqualsFull(me))
                return false;

            uint i = BlockData.GetGlobalID(atSide.ID, 0);
            Block b = Block.Blocks[i];

            if (b != null)
            {
                Block bs = null;

                if (b.UseMetadata)
                {
                    bs = Block.Blocks[atSide.GetGlobalID()];
                }
                else
                {
                    bs = b;
                }

                return bs.IsTransparent();
            }

            return true;
        }
 public BlockData GetData(Point3 position)
 {
     return GetBlockDataAt(position);
 }