public TerrainBlock(Terrain terrain, int depth, GraphicsDevice GraphicsDevice, Effect effect, PlanetBlock planetBlock,
                            Planet.GetNeighbourDelegate method, Point location,TerrainBlock parent, Vector3 blockOffset = new Vector3())
        {
            this.GraphicsDevice = GraphicsDevice;
            this.effect = effect;
            this.depth = depth;
            this.planet = true;
            this.waterSphere = new BoundingSphere(Vector3.Zero, Terrain.PlanetRadius + Planet.HeightMag);
            this.GetNeighbour = method;
            this.location = location;
            this.parent = parent;
            if (blockOffset == Vector3.Zero)
                this.blockOffset = new Vector3(0, 0, Planet.PlanetRes);
            else
                this.blockOffset = new Vector3(blockOffset.X, blockOffset.Y, blockOffset.Z);
            this.planet = planet;
            this.pWidth = terrain.Size;
            this.busy = false;
            this.baseTexture = terrain.baseTexture;
            this.children = new TerrainBlock[BlockRes, BlockRes];
            this.terrain = new Terrain[BlockRes, BlockRes];
            if (planet)
                this.SplitMainTerrainPlanet(terrain);
            this.visible = true;

            //this.SplitChildren(Vector3.Zero);
        }
        public void SplitChildrenPlanet(object input)
        {
            Vector3 position = (Vector3)input;
            if (this.depth >= maxDepth)
                return;

            if (this.busy)
                return;

            this.busy = true;
            for (int x = 0; x < BlockRes; x++)
                for (int y = 0; y < BlockRes; y++)
                {
                    int t = this.terrain[x, y].Size - 1;
                    Vector3 a = this.terrain[x, y].Center + this.terrain[x, y].Position;//c
                    Vector3 b = this.terrain[x, y].GetAdjustedPos(this.terrain[x, y].vertices[0].Position) + this.terrain[x, y].Position;//NW
                    Vector3 c = this.terrain[x, y].GetAdjustedPos(this.terrain[x, y].vertices[t].Position) + this.terrain[x, y].Position;//NE
                    Vector3 d = this.terrain[x, y].GetAdjustedPos(this.terrain[x, y].vertices[this.terrain[x, y].vertices.Count() - 1].Position) + this.terrain[x, y].Position;//SE
                    Vector3 e = this.terrain[x, y].GetAdjustedPos(this.terrain[x, y].vertices[this.terrain[x, y].vertices.Count() - t - 1].Position) + this.terrain[x, y].Position;//SW
                    //float d = (Vector3.Cross((a - b), (b - position))).Length() / (a - b).Length();
                    if (((a - position).Length() > Terrain.PlanetRadius / (1.1f * (Math.Pow(2, this.depth))) &&
                        (b - position).Length() > Terrain.PlanetRadius / (1.1f * (Math.Pow(2, this.depth))) &&
                        (c - position).Length() > Terrain.PlanetRadius / (1.1f * (Math.Pow(2, this.depth))) &&
                        (d - position).Length() > Terrain.PlanetRadius / (1.1f * (Math.Pow(2, this.depth))) &&
                        (e - position).Length() > Terrain.PlanetRadius / (1.1f * (Math.Pow(2, this.depth)))) ||
                        waterSphere.Contains(new BoundingBox(b, d)) == ContainmentType.Contains)
                    {
                        if (this.children[x, y] != null)
                        {
                            this.children[x, y].nullChildren();
                            this.children[x, y] = null;
                        }
                        continue;
                    }

                    if (children[x, y] == null)
                    {
                        int size = Planet.PlanetRes;
                        Terrain tmp = new Terrain(terrain[x, y].CellSize / 4.0f, terrain[x, y].Height, terrain[x, y].TextureTiling, size,
                                                  new Vector3(terrain[x, y].Position.X, terrain[x, y].Position.Y, terrain[x, y].Position.Z),
                                                  effect, baseTexture, Terrain.Type.CubeFace, this.depth + 1);

                        float[,] heights = new float[size, size];
                        for (int x1 = 0; x1 < size; x1++)
                            for (int y1 = 0; y1 < size; y1++)
                                heights[x1, y1] = this.terrain[x, y].heightMaps[x1 / 2, y1 / 2];

                        Vector3 blcOff = new Vector3(blockOffset.X, blockOffset.Y, (blockOffset.Z - 1) * 2 + 1);
                        blcOff.X *= 2;
                        blcOff.Y *= 2;
                        blcOff.X += (size - 1) * x;
                        blcOff.Y += (size - 1) * y;

                        tmp.GenerateCustom(new Fractal(size, (this.depth + 1) * 8).stepFrac(heights, 1), blcOff);
                        tmp.GlobalRot = terrain[x, y].GlobalRot;

                        TerrainBlock tb = new TerrainBlock(tmp, this.depth + 1, GraphicsDevice, effect, this.planetBlock, this.GetNeighbour, new Point(x, y), this, blcOff);
                        children[x, y] = tb;
                    }

                    if (children[x, y] != null)
                        children[x, y].SplitChildrenPlanet(position);
                }

            this.busy = false;
        }
        public List<float>[] GetNeighbourTerrain(Point myLoc, TerrainBlock parent)
        {
            //ltrb
            List<float>[] result = new List<float>[4];

            if (parent == null)
                return result;

            if (myLoc.X == 0 && myLoc.Y == 0)
            {
                result[2] = parent.terrain[1, 0].MyRawHeightBorders[0];
                result[3] = parent.terrain[0, 1].MyRawHeightBorders[1];
            }
            else if (myLoc.X == 0 && myLoc.Y == 1)
            {
                result[1] = parent.terrain[0, 0].MyRawHeightBorders[3];
                result[2] = parent.terrain[1, 1].MyRawHeightBorders[0];
            }
            else if (myLoc.X == 1 && myLoc.Y == 0)
            {
                result[0] = parent.terrain[0, 0].MyRawHeightBorders[2];
                result[3] = parent.terrain[1, 1].MyRawHeightBorders[1];
            }
            else if (myLoc.X == 1 && myLoc.Y == 1)
            {
                result[0] = parent.terrain[0, 1].MyRawHeightBorders[2];
                result[1] = parent.terrain[1, 0].MyRawHeightBorders[3];
            }

            return result;
        }
        public Planet(GraphicsDevice GraphicsDevice, ContentManager Content)
        {
            this.isWater = false;
            Effect effect = Content.Load<Effect>(@"effects/PPModel");
            Texture2D texture = Content.Load<Texture2D>(@"textures/base");

            Vector3 pos = Vector3.Zero;
            top = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace);
            top.GenerateFractual();

            float[][] borders = new float[4][];
            borders[2] = top.MyHeightBorders[0].ToArray();

            left = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace);
            left.GenerateFractualSlice(new Vector3(0, 0, 90), borders, Fractal.BorderType.Right);

            borders = new float[4][];
            borders[0] = top.MyHeightBorders[2].ToArray();

            right = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace);
            right.GenerateFractualSlice(new Vector3(0, 0, -90), borders, Fractal.BorderType.Left);

            borders = new float[4][];
            borders[0] = left.MyHeightBorders[3].ToArray();
            borders[1] = top.MyHeightBorders[3].ToArray();
            borders[2] = right.MyHeightBorders[3].ToArray();

            Array.Reverse(borders[0]);

            front = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace);
            front.GenerateFractualSlice(new Vector3(90, 0, 0), borders, Fractal.BorderType.Left | Fractal.BorderType.Top | Fractal.BorderType.Right);

            borders = new float[4][];
            borders[0] = left.MyHeightBorders[1].ToArray();
            borders[2] = right.MyHeightBorders[1].ToArray();
            borders[3] = top.MyHeightBorders[1].ToArray();

            Array.Reverse(borders[2]);

            back = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace);
            back.GenerateFractualSlice(new Vector3(-90, 0, 0), borders, Fractal.BorderType.Left | Fractal.BorderType.Bottom | Fractal.BorderType.Right);

            borders = new float[4][];
            borders[0] = left.MyHeightBorders[0].ToArray();
            borders[1] = front.MyHeightBorders[3].ToArray();
            borders[2] = right.MyHeightBorders[2].ToArray();
            borders[3] = back.MyHeightBorders[1].ToArray();

            Array.Reverse(borders[0]);
            Array.Reverse(borders[2]);

            bottom = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace);
            bottom.GenerateFractualSlice(new Vector3(180, 0, 0), borders, Fractal.BorderType.All);

            ///////////////////
            top.loadPosBorders(left.MyRawHeightBorders[2], Fractal.BorderType.Left, false);
            top.loadPosBorders(right.MyRawHeightBorders[0], Fractal.BorderType.Right, false);
            top.loadPosBorders(front.MyRawHeightBorders[1], Fractal.BorderType.Bottom, false);
            top.loadPosBorders(back.MyRawHeightBorders[3], Fractal.BorderType.Top, false);
            top.PostNormalize();

            left.loadPosBorders(top.MyRawHeightBorders[0], Fractal.BorderType.Right, false);
            left.loadPosBorders(front.MyRawHeightBorders[0], Fractal.BorderType.Bottom, true);
            left.loadPosBorders(back.MyRawHeightBorders[0], Fractal.BorderType.Top, false);
            left.loadPosBorders(bottom.MyRawHeightBorders[0], Fractal.BorderType.Left, true);
            left.PostNormalize();

            right.loadPosBorders(top.MyRawHeightBorders[2], Fractal.BorderType.Left, false);
            right.loadPosBorders(front.MyRawHeightBorders[2], Fractal.BorderType.Bottom, false);
            right.loadPosBorders(back.MyRawHeightBorders[2], Fractal.BorderType.Top, true);
            right.loadPosBorders(bottom.MyRawHeightBorders[2], Fractal.BorderType.Right, true);
            right.PostNormalize();

            front.loadPosBorders(top.MyRawHeightBorders[3], Fractal.BorderType.Top, false);
            front.loadPosBorders(left.MyRawHeightBorders[3], Fractal.BorderType.Left, true);
            front.loadPosBorders(right.MyRawHeightBorders[3], Fractal.BorderType.Right, false);
            front.loadPosBorders(bottom.MyRawHeightBorders[1], Fractal.BorderType.Bottom, false);
            front.PostNormalize();

            back.loadPosBorders(top.MyRawHeightBorders[1], Fractal.BorderType.Bottom, false);
            back.loadPosBorders(right.MyRawHeightBorders[1], Fractal.BorderType.Right, true);
            back.loadPosBorders(left.MyRawHeightBorders[1], Fractal.BorderType.Left, false);
            back.loadPosBorders(bottom.MyRawHeightBorders[3], Fractal.BorderType.Top, false);
            back.PostNormalize();

            bottom.loadPosBorders(left.MyRawHeightBorders[0], Fractal.BorderType.Left, true);
            bottom.loadPosBorders(front.MyRawHeightBorders[3], Fractal.BorderType.Top, false);
            bottom.loadPosBorders(right.MyRawHeightBorders[2], Fractal.BorderType.Right, true);
            bottom.loadPosBorders(back.MyRawHeightBorders[1], Fractal.BorderType.Bottom, false);
            bottom.PostNormalize();

            topBlock = new TerrainBlock(top, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Top, this.GetNeighbourTerrain, new Point(), null);
            leftBlock = new TerrainBlock(left, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Left, this.GetNeighbourTerrain, new Point(), null);
            rightBlock = new TerrainBlock(right, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Right, this.GetNeighbourTerrain, new Point(), null);
            frontBlock = new TerrainBlock(front, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Front, this.GetNeighbourTerrain, new Point(), null);
            backBlock = new TerrainBlock(back, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Back, this.GetNeighbourTerrain, new Point(), null);
            bottomBlock = new TerrainBlock(bottom, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Bottom, this.GetNeighbourTerrain, new Point(), null);

            topBlock.GetNeighbour = this.GetNeighbourTerrain;
            leftBlock.GetNeighbour = this.GetNeighbourTerrain;
            rightBlock.GetNeighbour = this.GetNeighbourTerrain;
            frontBlock.GetNeighbour = this.GetNeighbourTerrain;
            backBlock.GetNeighbour = this.GetNeighbourTerrain;
            bottomBlock.GetNeighbour = this.GetNeighbourTerrain;

            water = new Planet(GraphicsDevice, Content, true);
        }
        public Planet(GraphicsDevice GraphicsDevice, ContentManager Content, Vector3 sunPosition)
        {
            this.isWater = false;

            Vector3 pos = Vector3.Zero;
            top = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace);
            top.GenerateFractual();
            top.LightPosition = sunPosition;

            topBlock = new TerrainBlock(top, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"));

            //l,t,r,b
            float[,] borders = new float[4, PlanetRes];
            for (int i = 0; i < 4; i++)
                for (int c = 0; c < PlanetRes; c++)
                    if (i == 2)
                        borders[i, c] = top.heightMaps[0, c];

            left = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace);
            left.GenerateFractualSlice(new Vector3(0, 0, 90), borders, Fractal.BorderType.Right);
            left.LightPosition = sunPosition;

            leftBlock = new TerrainBlock(left, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"));

            //l,t,r,b
            borders = new float[4, PlanetRes];
            for (int i = 0; i < 4; i++)
                for (int c = 0; c < PlanetRes; c++)
                    if (i == 0)
                        borders[i, c] = top.heightMaps[(PlanetRes - 1), c];

            right = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace);
            right.GenerateFractualSlice(new Vector3(0, 0, -90), borders, Fractal.BorderType.Left);
            right.LightPosition = sunPosition;

            rightBlock = new TerrainBlock(right, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"));

            //l,t,r,b
            borders = new float[4, PlanetRes];
            for (int i = 0; i < 4; i++)
                for (int c = 0; c < PlanetRes; c++)
                    if (i == 0)
                        borders[i, c] = left.heightMaps[(PlanetRes - 1) - c, (PlanetRes - 1)];
                    else if (i == 1)
                        borders[i, c] = top.heightMaps[c, (PlanetRes - 1)];
                    else if (i == 2)
                        borders[i, c] = right.heightMaps[c, (PlanetRes - 1)];

            front = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace);
            front.GenerateFractualSlice(new Vector3(90, 0, 0), borders, Fractal.BorderType.Left | Fractal.BorderType.Top | Fractal.BorderType.Right);
            front.LightPosition = sunPosition;

            frontBlock = new TerrainBlock(front, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"));

            //l,t,r,b
            borders = new float[4, PlanetRes];
            for (int i = 0; i < 4; i++)
                for (int c = 0; c < PlanetRes; c++)
                    if (i == 0)
                        borders[i, c] = left.heightMaps[c, 0];
                    else if (i == 2)
                        borders[i, c] = right.heightMaps[(PlanetRes - 1) - c, 0];
                    else if (i == 3)
                        borders[i, c] = top.heightMaps[c, 0];

            back = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace);
            back.GenerateFractualSlice(new Vector3(-90, 0, 0), borders, Fractal.BorderType.Left | Fractal.BorderType.Bottom | Fractal.BorderType.Right);
            back.LightPosition = sunPosition;

            backBlock = new TerrainBlock(back, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"));

            //l,t,r,b
            borders = new float[4, PlanetRes];
            for (int i = 0; i < 4; i++)
                for (int c = 0; c < PlanetRes; c++)
                    if (i == 0)
                        borders[i, c] = left.heightMaps[0, (PlanetRes - 1) - c];
                    else if (i == 1)
                        borders[i, c] = front.heightMaps[c, (PlanetRes - 1)];
                    else if (i == 2)
                        borders[i, c] = right.heightMaps[(PlanetRes - 1), (PlanetRes - 1) - c];
                    else if (i == 3)
                        borders[i, c] = back.heightMaps[c, 0];

            bottom = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace);
            bottom.GenerateFractualSlice(new Vector3(180, 0, 0), borders, Fractal.BorderType.All);
            bottom.LightPosition = sunPosition;

            bottomBlock = new TerrainBlock(bottom, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"));

            water = new Planet(GraphicsDevice, Content, true, sunPosition);
        }
        public void SplitChildrenPlanet(object input)
        {
            Vector3 position = (Vector3)input;
            if (this.depth >= maxDepth)
                return;

            if (this.busy)
                return;

            this.busy = true;
            for (int i = 0; i < 4; i++)
            {
                int t = this.terrain[i].width - 1;
                Vector3 a = this.terrain[i].Center + this.terrain[i].Position;//c
                Vector3 b = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[0].Position) + this.terrain[i].Position;//NW
                Vector3 c = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[t].Position) + this.terrain[i].Position;//NE
                Vector3 d = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[this.terrain[i].vertices.Count() - 1].Position) + this.terrain[i].Position;//SE
                Vector3 e = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[this.terrain[i].vertices.Count() - t - 1].Position) + this.terrain[i].Position;//SW
                //float d = (Vector3.Cross((a - b), (b - position))).Length() / (a - b).Length();
                if (((a - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (2.5f - (0 * depth)) &&
                    (b - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (2.5f - (0 * depth)) &&
                    (c - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (2.5f - (0 * depth)) &&
                    (d - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (2.5f - (0 * depth)) &&
                    (e - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (2.5f - (0 * depth))) ||
                    waterSphere.Contains(new BoundingBox(b, d)) == ContainmentType.Contains)
                {
                    if (this.children[i] != null)
                    {
                        this.children[i].nullChildren();
                        this.children[i] = null;
                    }
                    continue;
                }

                if (children[i] == null)
                {
                    Terrain tmp = new Terrain(terrain[i].cellSize / 2.0f, terrain[i].height, terrain[i].textureTiling, (int)(terrain[i].width * 2 - 1),
                                              new Vector3(terrain[i].Position.X, terrain[i].Position.Y, terrain[i].Position.Z),
                                              terrain[i].lightDirection, GraphicsDevice, effect, baseTexture, Terrain.Type.CubeFace);

                    int size = terrain[i].width * 2 - 1;
                    float[,] heights = new float[size, size];
                    for (int x = 0; x < size; x += 2)
                        for (int y = 0; y < size; y += 2)
                            heights[x, y] = terrain[i].heightMaps[x / 2, y / 2];

                    Vector3 blcOff = new Vector3(blockOffset.X, blockOffset.Y, -1);

                    switch (i)
                    {
                        case 0:
                            blcOff.X *= 2;
                            blcOff.Y *= 2;
                            break;
                        case 1:
                            blcOff.X *= 2;
                            blcOff.X += size - 1;
                            blcOff.Y *= 2;
                            break;
                        case 2:
                            blcOff.X *= 2;
                            blcOff.Y *= 2;
                            blcOff.Y += size - 1;
                            break;
                        case 3:
                            blcOff.X *= 2;
                            blcOff.X += size - 1;
                            blcOff.Y *= 2;
                            blcOff.Y += size - 1;
                            break;
                    }

                    tmp.GenerateCustom(new Fractal(size, this.depth + 8).singleStep(heights), terrain[i].LightPosition, blcOff);
                    tmp.GlobalRot = terrain[i].GlobalRot;

                    TerrainBlock tb = new TerrainBlock(tmp, this.depth + 1, this.planet, GraphicsDevice, effect, blcOff);
                    children[i] = tb;
                }

                if (children[i] != null)
                    children[i].SplitChildren(position);
            }

            this.busy = false;
        }
        public void SplitChildren(object input)
        {
            if (this.planet)
            {
                this.SplitChildrenPlanet(input);
                return;
            }

            Vector3 position = (Vector3)input;
            if (this.depth >= maxDepth)
                return;

            if (this.busy)
                return;

            this.busy = true;
            for (int i = 0; i < 4; i++)
            {
                int t = this.terrain[i].width - 1;
                Vector3 a = this.terrain[i].Center + this.terrain[i].Position;//c
                Vector3 b = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[0].Position) + this.terrain[i].Position;//NW
                Vector3 c = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[t].Position) + this.terrain[i].Position;//NE
                Vector3 d = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[this.terrain[i].vertices.Count() - 1].Position) + this.terrain[i].Position;//SE
                Vector3 e = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[this.terrain[i].vertices.Count() - t - 1].Position) + this.terrain[i].Position;//SW
                //float d = (Vector3.Cross((a - b), (b - position))).Length() / (a - b).Length();
                if ((a - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (1.75f + (0.075f * depth)) &&
                    (b - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (1.25f + (0.075f * depth)) &&
                    (c - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (1.25f + (0.075f * depth)) &&
                    (d - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (1.25f + (0.075f * depth)) &&
                    (e - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (1.25f + (0.075f * depth)))
                {
                    if (this.children[i] != null)
                    {
                        this.children[i].nullChildren();
                        this.children[i] = null;
                    }
                    continue;
                }

                float sizeOffset = (float)terrain[i].cellSize * ((float)terrain[i].width / 8.0f);
                Terrain tmp = new Terrain(terrain[i].cellSize / 2.0f, terrain[i].height, terrain[i].textureTiling, (int)(terrain[i].width * 2 - 1),
                                          new Vector3(terrain[i].Position.X - sizeOffset, terrain[i].Position.Y, terrain[i].Position.Z - sizeOffset),
                                          terrain[i].lightDirection,GraphicsDevice,effect, baseTexture);

                int size = terrain[i].width * 2 - 1;
                float[,] heights = new float[size, size];
                for (int x = 0; x < size; x += 2)
                    for (int y = 0; y < size; y += 2)
                        heights[x, y] = terrain[i].heightMaps[x / 2, y / 2];

                if (children[i] == null)
                {
                    tmp.GenerateCustom(new Fractal(size, this.depth + 8).singleStep(heights));

                    TerrainBlock tb = new TerrainBlock(tmp, this.depth + 1, this.planet, GraphicsDevice, effect);
                    children[i] = tb;
                }

                if (children[i] != null)
                    children[i].SplitChildren(position);
            }

            this.busy = false;
        }