public void RebuildBounding(QuadTreeNode node)
        {
            Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
            Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);

            Type type = node.GetType();

            if (type == typeof(QuadTree))
            {
                QuadTree tree = (QuadTree)node;

                if (tree.UpperLeft != null)
                {
                    RebuildBounding(tree.UpperLeft);
                    min = Vector3.Min(min, tree.UpperLeft.BoundingBox.Min);
                    max = Vector3.Max(max, tree.UpperLeft.BoundingBox.Max);
                }

                if (tree.UpperRight != null)
                {
                    RebuildBounding(tree.UpperRight);
                    min = Vector3.Min(min, tree.UpperRight.BoundingBox.Min);
                    max = Vector3.Max(max, tree.UpperRight.BoundingBox.Max);
                }

                if (tree.LowerLeft != null)
                {
                    RebuildBounding(tree.LowerLeft);
                    min = Vector3.Min(min, tree.LowerLeft.BoundingBox.Min);
                    max = Vector3.Max(max, tree.LowerLeft.BoundingBox.Max);
                }

                if (tree.LowerRight != null)
                {
                    RebuildBounding(tree.LowerRight);
                    min = Vector3.Min(min, tree.LowerRight.BoundingBox.Min);
                    max = Vector3.Max(max, tree.LowerRight.BoundingBox.Max);
                }
            }
            else if (type == typeof(LandscapeBlock))
            {
                LandscapeBlock block = (LandscapeBlock)node;
                min = Vector3.Min(min, block.BoundingBox.Min);
                max = Vector3.Max(max, block.BoundingBox.Max);
            }

            node.BoundingBox = new BoundingBox(min, max);
        }
        public void BuildLandscapeBlocks(Texture2D heightmap)
        {
            // Calculate how many blocks we should make based off total Width / desired size of each block
            numBlocksX = Width / BlockSize;
            numBlocksZ = Height / BlockSize;

            Blocks = new LandscapeBlock[numBlocksX][];

            // create blocks
            for (int x = 0; x < numBlocksX; x++)
            {
                Blocks[x] = new LandscapeBlock[numBlocksZ];

                for (int z = 0; z < numBlocksZ; z++)
                {
                    LandscapeBlock block = new LandscapeBlock(Game, Width, Height, x * BlockSize, z * BlockSize);
                    block.Position        = new Vector2(x * BlockSize, z * BlockSize);
                    block.Width           = BlockSize;
                    block.Height          = BlockSize;
                    block.HeightColorData = new Color[(BlockSize + 1) * (BlockSize + 1)];
                    block.MaxHeight       = MaxHeight;
                    block.Smoothness      = Smoothness;
                    block.Camera          = Camera;

                    // Height map data provided
                    if (heightmap != null)
                    {
                        heightmap.GetData(0,
                                          new Rectangle((int)block.Position.X, (int)block.Position.Y, (BlockSize + 1), (BlockSize + 1)),
                                          block.HeightColorData, 0, (BlockSize + 1) * (BlockSize + 1));
                    }

                    block.Initialize();

                    Blocks[x][z] = block;
                }
            }

            FindNeighborBlocks();

            Trunk = BuildTreeNode(0, 0, numBlocksX, numBlocksZ) as QuadTree;
        }
        public int DrawTreeNode(BoundingFrustum frustum, QuadTreeNode node, GameTime gameTime)
        {
            int totalTriangles = 0;

            if (node != null && node.Visible != true)
            {
                return(totalTriangles);
            }

            if (node is QuadTree)
            {
                QuadTree tree = (QuadTree)node;

                if (!tree.BoundingBox.Intersects(frustum))
                {
                    return(0);
                }

                if (tree.UpperLeft != null)
                {
                    if (tree.UpperLeft.BoundingBox.Intersects(frustum))
                    {
                        totalTriangles += DrawTreeNode(frustum, tree.UpperLeft, gameTime);
                    }
                }

                if (tree.UpperRight != null)
                {
                    if (tree.UpperRight.BoundingBox.Intersects(frustum))
                    {
                        totalTriangles += DrawTreeNode(frustum, tree.UpperRight, gameTime);
                    }
                }

                if (tree.LowerLeft != null)
                {
                    if (tree.LowerLeft.BoundingBox.Intersects(frustum))
                    {
                        totalTriangles += DrawTreeNode(frustum, tree.LowerLeft, gameTime);
                    }
                }

                if (tree.LowerRight != null)
                {
                    if (tree.LowerRight.BoundingBox.Intersects(frustum))
                    {
                        totalTriangles += DrawTreeNode(frustum, tree.LowerRight, gameTime);
                    }
                }
            }
            else if (node is LandscapeBlock)
            {
                LandscapeBlock block = (LandscapeBlock)node;
                {
                    if (block.Visible)
                    {
                        if (block.BoundingBox.Intersects(frustum))
                        {
                            totalTriangles += block.DrawBlock(gameTime);
                        }
                    }
                }
            }

            return(totalTriangles);
        }
        public void UpdateTreeNode(BoundingFrustum frustum, QuadTreeNode node, bool skipFrustumCheck, GameTime gameTime)
        {
            node.Visible = false;

            if (skipFrustumCheck != true)
            {
                ContainmentType containment = frustum.Contains(node.BoundingBox);

                if (containment == ContainmentType.Disjoint)
                {
                    return;
                }

                // if the entire node is contained within, then assume all children are as well
                if (containment == ContainmentType.Contains)
                {
                    skipFrustumCheck = true;
                }
            }

            node.Visible = true;

            Type type = node.GetType();

            if (type == typeof(QuadTree))
            {
                QuadTree tree = (QuadTree)node;

                if (tree.UpperLeft != null)
                {
                    UpdateTreeNode(frustum, tree.UpperLeft, skipFrustumCheck, gameTime);
                }

                if (tree.UpperRight != null)
                {
                    UpdateTreeNode(frustum, tree.UpperRight, skipFrustumCheck, gameTime);
                }

                if (tree.LowerLeft != null)
                {
                    UpdateTreeNode(frustum, tree.LowerLeft, skipFrustumCheck, gameTime);
                }

                if (tree.LowerRight != null)
                {
                    UpdateTreeNode(frustum, tree.LowerRight, skipFrustumCheck, gameTime);
                }
            }
            else if (type == typeof(LandscapeBlock))
            {
                LandscapeBlock block = (LandscapeBlock)node;
                {
                    if (block.BoundingBox.Intersects(frustum))
                    {
                        block.Visible = true;
                        block.Update(gameTime);
                    }
                    else
                    {
                        block.Visible = false;
                    }
                }
            }
        }