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 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 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;
        }