//Test for Box --> Sphere Collision
 public Contact Collides(Box box)
 {
     return base.Collides(this, box);
 }
        //Point-Of-View Ray Casting collision detection for Boxes
        public List<Contact> ProjectPOVRay(Box box, float RayLength)
        {
            List<Contact> Contacts = new List<Contact>();

            Vector3 sideOffset = Vector3.Normalize(Vector3.Cross(this.Velocity, new Vector3(0, 1, 0)));

            Vector3 side1 = this.Position - sideOffset;
            Vector3 side2 = this.Position + sideOffset;

            Vector3[] vertices = box.GetVertices();

            Vector3[] normals = box.GetNormals();

            float[] Distances = new float[6];
            for (int i = 0; i < normals.Length; i++)
            {
                Distances[i] = Vector3.Dot(((box.Position + (normals[i] * box.Size / 2) - side1)), normals[i]) / Vector3.Dot(this.velocity, normals[i]);
            }

            //The number of faces whose normals are not pointing away from the sphere.
            int PositiveCount = 0;

            List<int> indices = new List<int>();

            //Find shortest distance to Box Face
            int shortestIndex = -1;

            //Obtain list of faces whose normals are not pointing away from he sphere and the distance between the sphere and the closest box face
            for (int i = 0; i < Distances.Length; i++)
            {
                if (Distances[i] > 0)
                {
                    if (Distances[i] <= RayLength)
                    {
                        indices.Add(i);
                        PositiveCount++;

                        if (shortestIndex == -1)
                        {
                            shortestIndex = i;
                        }
                        else
                        {
                            if (Distances[shortestIndex] > Distances[i])
                            {
                                shortestIndex = i;
                            }
                        }
                    }
                    else
                    {
                        Distances[i] = -1;
                    }
                }
                else
                {
                    Distances[i] = -1;
                }
            }

            //Test For Left Ray
            //Don't collide if many positives are return, false positive
            if (PositiveCount > 0)
            {
                foreach (int index in indices)
                {
                    //Check for validity with point intersecting the box
                    Vector3 RayPoint = side1 + velocity / velocity.Length() * Distances[index];

                    Vector3 min = new Vector3(vertices[0].X, vertices[0].Y, vertices[0].Z);
                    Vector3 max = new Vector3(vertices[0].X, vertices[0].Y, vertices[0].Z);

                    for (int i = 0; i < vertices.Length; i++)
                    {
                        if (min.X > vertices[i].X)
                            min.X = vertices[i].X;

                        if (min.Y > vertices[i].Y)
                            min.Y = vertices[i].Y;

                        if (min.Z > vertices[i].Z)
                            min.Z = vertices[i].Z;

                        if (max.X < vertices[i].X)
                            max.X = vertices[i].X;

                        if (max.Y < vertices[i].Y)
                            max.Y = vertices[i].Y;

                        if (max.Z < vertices[i].Z)
                            max.Z = vertices[i].Z;
                    }

                    double dSquared = 0;

                    if (RayPoint.X < min.X)
                    {
                        dSquared += (float)Math.Pow((RayPoint.X - min.X), 2);
                    }
                    else if (RayPoint.X > max.X)
                    {
                        dSquared += (float)Math.Pow((RayPoint.X - max.X), 2);
                    }

                    if (RayPoint.Y < min.Y)
                    {
                        dSquared += (float)Math.Pow((RayPoint.Y - min.Y), 2);
                    }
                    else if (RayPoint.Y > max.Y)
                    {
                        dSquared += (float)Math.Pow((RayPoint.Y - max.Y), 2);
                    }

                    if (RayPoint.Z < min.Z)
                    {
                        dSquared += (float)Math.Pow((RayPoint.Z - min.Z), 2);
                    }
                    else if (RayPoint.Z > max.Z)
                    {
                        dSquared += (float)Math.Pow((RayPoint.Z - max.Z), 2);
                    }

                    if (dSquared <= 0.01)
                    {
                        Contact contact = new Contact();
                        contact.ContactType = CollisionType.POVRay;
                        contact.RayCollided = RayCollisionResult.Left;
                        contact.ContactNormal = -velocity / Velocity.Length();
                        contact.ContactPoint = RayPoint;
                        contact.DeepestPoint = side1 + velocity / Velocity.Length() * RayLength;
                        contact.PenetrationDepth = (contact.DeepestPoint - contact.ContactPoint).Length();

                        //Compute contact angle
                        if (PositiveCount == 1)
                        {
                            float scalar = Vector3.Dot(normals[shortestIndex], velocity / velocity.Length());
                            contact.ContactAngle = (float)Math.Acos(scalar);

                        }
                        else
                        {
                            float scalar = Vector3.Dot(normals[shortestIndex], velocity / velocity.Length());
                            contact.ContactAngle = (float)Math.Acos(scalar);

                        }

                        //Angle should never be higher than 90 degrees.
                        if (contact.ContactAngle > Math.PI / 2)
                        {
                            contact.ContactAngle = (float)Math.PI - contact.ContactAngle;
                        }

                        Contacts.Add(contact);
                        break;
                    }
                }
            }

            Distances = new float[6];
            for (int i = 0; i < normals.Length; i++)
            {
                Distances[i] = Vector3.Dot(((box.Position + (normals[i] * box.Size / 2) - side2)), normals[i]) / Vector3.Dot(this.velocity, normals[i]);
            }

            //The number of faces whose normals are not pointing away from the sphere.
            PositiveCount = 0;
            indices = new List<int>();

            //Obtain list of faces whose normals are not pointing away from he sphere and the distance between the sphere and the closest box face
            shortestIndex = 0;
            for (int i = 0; i < Distances.Length; i++)
            {
                if (Distances[i] > 0)
                {
                    if (Distances[i] <= RayLength)
                    {
                        indices.Add(i);
                        PositiveCount++;

                        if (shortestIndex == -1)
                        {
                            shortestIndex = i;
                        }
                        else
                        {
                            if (Distances[shortestIndex] > Distances[i])
                            {
                                shortestIndex = i;
                            }
                        }
                    }
                    else
                    {
                        Distances[i] = -1;
                    }
                }
                else
                {
                    Distances[i] = -1;
                }
            }

            //Test For Right Ray
            //Don't collide if many positives are return, false positive
            if (PositiveCount > 0)
            {
                foreach (int index in indices)
                {
                    //Check for validity with point intersecting the box
                    Vector3 RayPoint = side2 + velocity / velocity.Length() * Distances[index];

                    Vector3 min = new Vector3(vertices[0].X, vertices[0].Y, vertices[0].Z);
                    Vector3 max = new Vector3(vertices[0].X, vertices[0].Y, vertices[0].Z);

                    for (int i = 0; i < vertices.Length; i++)
                    {
                        if (min.X > vertices[i].X)
                            min.X = vertices[i].X;

                        if (min.Y > vertices[i].Y)
                            min.Y = vertices[i].Y;

                        if (min.Z > vertices[i].Z)
                            min.Z = vertices[i].Z;

                        if (max.X < vertices[i].X)
                            max.X = vertices[i].X;

                        if (max.Y < vertices[i].Y)
                            max.Y = vertices[i].Y;

                        if (max.Z < vertices[i].Z)
                            max.Z = vertices[i].Z;
                    }

                    double dSquared = 0;

                    if (RayPoint.X < min.X)
                    {
                        dSquared += (float)Math.Pow((RayPoint.X - min.X), 2);
                    }
                    else if (RayPoint.X > max.X)
                    {
                        dSquared += (float)Math.Pow((RayPoint.X - max.X), 2);
                    }

                    if (RayPoint.Y < min.Y)
                    {
                        dSquared += (float)Math.Pow((RayPoint.Y - min.Y), 2);
                    }
                    else if (RayPoint.Y > max.Y)
                    {
                        dSquared += (float)Math.Pow((RayPoint.Y - max.Y), 2);
                    }

                    if (RayPoint.Z < min.Z)
                    {
                        dSquared += (float)Math.Pow((RayPoint.Z - min.Z), 2);
                    }
                    else if (RayPoint.Z > max.Z)
                    {
                        dSquared += (float)Math.Pow((RayPoint.Z - max.Z), 2);
                    }

                    if (dSquared <= 0.01)
                    {
                        Contact contact = new Contact();
                        contact.ContactType = CollisionType.POVRay;
                        contact.RayCollided = RayCollisionResult.Right;
                        contact.ContactNormal = -velocity / Velocity.Length();
                        contact.ContactPoint = RayPoint;
                        contact.DeepestPoint = side2 + velocity / Velocity.Length() * RayLength;
                        contact.PenetrationDepth = (contact.DeepestPoint - contact.ContactPoint).Length();

                        //Compute contact angle
                        if (PositiveCount == 1)
                        {
                            float scalar = Vector3.Dot(normals[shortestIndex], velocity / velocity.Length());
                            contact.ContactAngle = (float)Math.Acos(scalar);

                        }
                        else
                        {
                            float scalar = Vector3.Dot(normals[shortestIndex], velocity / velocity.Length());
                            contact.ContactAngle = (float)Math.Acos(scalar);
                        }

                        //Angle should never be higher than 90 degrees.
                        if (contact.ContactAngle > Math.PI / 2)
                        {
                            contact.ContactAngle = (float)Math.PI - contact.ContactAngle;
                        }

                        Contacts.Add(contact);
                        break;
                    }
                }
            }

            //If contacts exist, collisions were found else return nothing
            if (Contacts.Count > 0)
            {
                return Contacts;
            }
            else
            {
                return null;
            }
        }
        //Box --> Plane Collision Detection and Contact Info generation
        //Returns null if no collision, a contact List object if a collision occurs
        protected List<Contact> Collides(Box box, Plane plane)
        {
            List<Contact> contacts = new List<Contact>();
            Vector3[] Vertices = box.GetVertices();

            foreach (Vector3 vertex in Vertices)
            {
                float Distance = Vector3.Dot(plane.Normal, vertex - plane.Position) / plane.Normal.Length();

                if (Distance <= 0)
                {
                    Contact contact = new Contact();

                    contact.ContactType = CollisionType.VertexFace;
                    contact.ContactNormal = plane.Normal;
                    contact.PenetrationDepth = -Distance;
                    contact.ContactPoint = vertex;
                    contact.DeepestPoint = vertex;

                    contacts.Add(contact);
                }
            }

            return contacts;
        }
        //Sphere --> Box Collision Detection and Contact Info generation
        //Returns null if no collision, a contact object if a collision occurs
        protected Contact Collides(Sphere sphere, Box box)
        {
            Contact contact = new Contact();
            Vector3[] vertices = box.GetVertices();

            //Implementation based on pages 644-645 of Geometric Tools for Computer Graphics [Philip J. Schneider & David H. Eberly, Morgan Kaufmann]
            //Make sure the sphere is touching the box before continuing

            //Distance from sphere to each of the box vertices
            float[] VertexDistances = new float[8];

            //Compute distance
            for (int i = 0; i < vertices.Length; i++)
            {
                VertexDistances[i] = (vertices[i] - sphere.Position).Length();
            }

            //Obtain Minimum and Maximum values for X,Y,Z
            Vector3 min = new Vector3(vertices[0].X, vertices[0].Y, vertices[0].Z);
            Vector3 max = new Vector3(vertices[0].X, vertices[0].Y, vertices[0].Z);

            for (int i = 0; i < vertices.Length; i++)
            {
                if (min.X > vertices[i].X)
                    min.X = vertices[i].X;

                if (min.Y > vertices[i].Y)
                    min.Y = vertices[i].Y;

                if (min.Z > vertices[i].Z)
                    min.Z = vertices[i].Z;

                if (max.X < vertices[i].X)
                    max.X = vertices[i].X;

                if (max.Y < vertices[i].Y)
                    max.Y = vertices[i].Y;

                if (max.Z < vertices[i].Z)
                    max.Z = vertices[i].Z;
            }

            //Test for collision
            double dSquared = 0;

            if (sphere.Position.X < min.X)
            {
                dSquared += (float)Math.Pow((sphere.Position.X - min.X), 2);
            }
            else if (sphere.Position.X > max.X)
            {
                dSquared += (float)Math.Pow((sphere.Position.X - max.X), 2);
            }

            if (sphere.Position.Y < min.Y)
            {
                dSquared += (float)Math.Pow((sphere.Position.Y - min.Y), 2);
            }
            else if (sphere.Position.Y > max.Y)
            {
                dSquared += (float)Math.Pow((sphere.Position.Y - max.Y), 2);
            }

            if (sphere.Position.Z < min.Z)
            {
                dSquared += (float)Math.Pow((sphere.Position.Z - min.Z), 2);
            }
            else if (sphere.Position.Z > max.Z)
            {
                float test = sphere.Position.Z - max.Z;
                dSquared += (float)Math.Pow((sphere.Position.Z - max.Z), 2);
            }

            if (dSquared <= Math.Pow(sphere.Radius, 2))
            {

                #region Vertex-Face

                foreach (Vector3 vertex in vertices)
                {
                    float Distance = (sphere.Position - vertex).Length();

                    if (Distance <= sphere.Radius)
                    {
                        Vector3 midline = vertex - sphere.Position;
                        contact.ContactType = CollisionType.VertexFace;
                        contact.ContactNormal = -midline / midline.Length();
                        contact.ContactPoint = vertex;// sphere.position + (midline * sphere.Radius) / midline.Length();
                        contact.DeepestPoint = sphere.Position + (midline * sphere.Radius) / midline.Length();
                        contact.PenetrationDepth = ((vertex - contact.DeepestPoint)).Length();

                        return contact;
                    }
                }
                #endregion

                #region Face-Face

                Vector3[] normals = box.GetNormals();
                float[] Distances = new float[6];
                for (int i = 0; i < normals.Length; i++)
                {
                    Distances[i] = Vector3.Dot(normals[i], sphere.Position - (box.Position + (normals[i] * box.Size / 2))) / normals[i].Length();
                }

                int index = 0;

                //The number of faces whose normals are not pointing away from the sphere.
                int PositiveCount = 0;

                for (int i = 0; i < Distances.Length; i++)
                {
                    if (Distances[i] > 0)
                    {
                        if (Distances[i] <= sphere.Radius)
                        {
                            PositiveCount++;
                        }

                        if (Distances[index] > Distances[i] || Distances[index] < 0)
                        {
                            index = i;
                        }
                    }
                }

                if (Distances[index] <= sphere.Radius && PositiveCount == 1)
                {
                    contact = new Contact();
                    contact.ContactType = CollisionType.FaceFace;
                    contact.ContactNormal = normals[index];
                    contact.PenetrationDepth = sphere.Radius - Distances[index]; //+

                    contact.ContactPoint = sphere.Position - contact.ContactNormal * VertexDistances[index];
                    contact.DeepestPoint = sphere.Position - contact.ContactNormal * (sphere.Radius);

                    return contact;

                }

                #endregion

                #region Edge-Face

                float[] PointDistances = new float[12];
                Vector3[,] VertexPair = new Vector3[12, 2];

                //Front Vertices
                Vector3 x0 = sphere.Position;
                Vector3 x1 = VertexPair[0, 0] = vertices[0];
                Vector3 x2 = VertexPair[0, 1] = vertices[1];

                PointDistances[0] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                x1 = VertexPair[1, 0] = vertices[1];
                x2 = VertexPair[1, 1] = vertices[3];

                PointDistances[1] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                x1 = VertexPair[2, 0] = vertices[3];
                x2 = VertexPair[2, 1] = vertices[2];

                PointDistances[2] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                x1 = VertexPair[3, 0] = vertices[2];
                x2 = VertexPair[3, 1] = vertices[0];

                PointDistances[3] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                //Back Vertices
                x1 = VertexPair[4, 0] = vertices[4];
                x2 = VertexPair[4, 1] = vertices[5];

                PointDistances[4] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                x1 = VertexPair[5, 0] = vertices[5];
                x2 = VertexPair[5, 1] = vertices[7];

                PointDistances[5] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                x1 = VertexPair[6, 0] = vertices[7];
                x2 = VertexPair[6, 1] = vertices[6];

                PointDistances[6] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                x1 = VertexPair[7, 0] = vertices[6];
                x2 = VertexPair[7, 1] = vertices[4];

                PointDistances[7] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                //Side Vertices
                x1 = VertexPair[8, 0] = vertices[0];
                x2 = VertexPair[8, 1] = vertices[4];

                PointDistances[8] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                x1 = VertexPair[9, 0] = vertices[1];
                x2 = VertexPair[9, 1] = vertices[5];

                PointDistances[9] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                x1 = VertexPair[10, 0] = vertices[2];
                x2 = VertexPair[10, 1] = vertices[6];

                PointDistances[10] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                x1 = VertexPair[11, 0] = vertices[3];
                x2 = VertexPair[11, 1] = vertices[7];

                PointDistances[11] = Vector3.Cross((x0 - x1), (x0 - x2)).Length() / (x2 - x1).Length();

                index = 0;

                for (int i = 0; i < PointDistances.Length; i++)
                {
                    if (PointDistances[index] > PointDistances[i])
                    {
                        index = i;
                    }
                }

                if (PointDistances[index] < sphere.Radius)
                {
                    x1 = VertexPair[index, 0];
                    x2 = VertexPair[index, 1];

                    //Required to compute point on the line
                    float t = -Vector3.Dot((x1 - x0), (x2 - x1)) / (x2 - x1).LengthSquared();

                    Vector3 LinePoint = new Vector3(x1.X + (x2.X - x1.X) * t, x1.Y + (x2.Y - x1.Y) * t, x1.Z + (x2.Z - x1.Z) * t);
                    contact.ContactType = CollisionType.EdgeFace;
                    contact.ContactNormal = Vector3.Normalize(x0 - LinePoint);
                    contact.ContactPoint = LinePoint;
                    contact.DeepestPoint = x0 - contact.ContactNormal / contact.ContactNormal.Length() * sphere.Radius;
                    contact.PenetrationDepth = (contact.DeepestPoint - contact.ContactPoint).Length();

                    return contact;
                }
                #endregion

            }
            //No Contact found...
            return null;
        }
 public List<Contact> Collides(Box box)
 {
     return base.Collides(box, this);
 }
        //Insert a box element in the tree
        public void Insert(Box box, QuadTreeNode node = null,int DepthLevel=0)
        {
            if (node == null)
                node = Head;

            Vector3 HeadOffset = new Vector3(Head.Position.X, 0, Head.Position.Y);
            //Verifies for all 4 corners of the box including based on the rotation offset of the box
            Vector3 offsetPos = Vector3.Transform(new Vector3(box.Size.X / 2, 0, box.Size.Z / 2), box.Offset);

            Vector3 corner1 = new Vector3(box.Position.X - offsetPos.X, 0, box.Position.Z + offsetPos.Z);
            Vector3 corner2 = new Vector3(box.Position.X + offsetPos.X, 0, box.Position.Z + offsetPos.Z);
            Vector3 corner3 = new Vector3(box.Position.X - offsetPos.X, 0, box.Position.Z - offsetPos.Z);
            Vector3 corner4 = new Vector3(box.Position.X + offsetPos.X, 0, box.Position.Z - offsetPos.Z);

            //Verifies for all 4 sides of the box including based on the rotation offset of the box
            offsetPos = Vector3.Transform(new Vector3(box.Size.X / 2, 0, box.Size.Z / 2), box.Offset);

            Vector3 Side1 = new Vector3(box.Position.X - offsetPos.X, 0, box.Position.Z + offsetPos.Z);
            Vector3 Side2 = new Vector3(box.Position.X + offsetPos.X, 0, box.Position.Z + offsetPos.Z);
            Vector3 Side3 = new Vector3(box.Position.X - offsetPos.X, 0, box.Position.Z - offsetPos.Z);
            Vector3 Side4 = new Vector3(box.Position.X + offsetPos.X, 0, box.Position.Z - offsetPos.Z);

            //Make sure Box is smaller than current quadrant. If yes, go deeper, otherwise add elements here
            if (DepthLevel < this.Depth && box.Size.X <= node.Size && box.Size.Z <= node.Size)
            {
                //Process North-West Part
                if (node.Children[0] != null)
                {
                    if (corner1.X <= node.Position.X && corner1.Z <= node.Position.Y ||
                        corner2.X <= node.Position.X && corner2.Z <= node.Position.Y ||
                        corner3.X <= node.Position.X && corner3.Z <= node.Position.Y ||
                        corner4.X <= node.Position.X && corner4.Z <= node.Position.Y ||
                        Side1.X <= node.Position.X && Side1.Z <= node.Position.Y ||
                        Side2.X <= node.Position.X && Side2.Z <= node.Position.Y ||
                        Side3.X <= node.Position.X && Side3.Z <= node.Position.Y ||
                        Side4.X <= node.Position.X && Side4.Z <= node.Position.Y)
                    {

                        Insert(box, node.Children[0],DepthLevel+1);
                    }
                }

                //Process North-East Part
                if (node.Children[1] != null)
                {
                    if (corner1.X >= node.Position.X && corner1.Z <= node.Position.Y ||
                        corner2.X >= node.Position.X && corner2.Z <= node.Position.Y ||
                        corner3.X >= node.Position.X && corner3.Z <= node.Position.Y ||
                        corner4.X >= node.Position.X && corner4.Z <= node.Position.Y ||
                        Side1.X >= node.Position.X && Side1.Z <= node.Position.Y ||
                        Side2.X >= node.Position.X && Side2.Z <= node.Position.Y ||
                        Side3.X >= node.Position.X && Side3.Z <= node.Position.Y ||
                        Side4.X >= node.Position.X && Side4.Z <= node.Position.Y)
                    {

                        Insert(box, node.Children[1], DepthLevel + 1);
                    }
                }

                //Process South-West Part
                if (node.Children[2] != null)
                {
                    if (corner1.X <= node.Position.X && corner1.Z >= node.Position.Y ||
                        corner2.X <= node.Position.X && corner2.Z >= node.Position.Y ||
                        corner3.X <= node.Position.X && corner3.Z >= node.Position.Y ||
                        corner4.X <= node.Position.X && corner4.Z >= node.Position.Y ||
                        Side1.X <= node.Position.X && Side1.Z >= node.Position.Y ||
                        Side2.X <= node.Position.X && Side2.Z >= node.Position.Y ||
                        Side3.X <= node.Position.X && Side3.Z >= node.Position.Y ||
                        Side4.X <= node.Position.X && Side4.Z >= node.Position.Y)
                    {

                        Insert(box, node.Children[2], DepthLevel + 1);
                    }
                }

                //Process South-East Part
                if (node.Children[3] != null)
                {
                    if (corner1.X >= node.Position.X && corner1.Z >= node.Position.Y ||
                        corner2.X >= node.Position.X && corner2.Z >= node.Position.Y ||
                        corner3.X >= node.Position.X && corner3.Z >= node.Position.Y ||
                        corner4.X >= node.Position.X && corner4.Z >= node.Position.Y ||
                        Side1.X >= node.Position.X && Side1.Z >= node.Position.Y ||
                        Side2.X >= node.Position.X && Side2.Z >= node.Position.Y ||
                        Side3.X >= node.Position.X && Side3.Z >= node.Position.Y ||
                        Side4.X >= node.Position.X && Side4.Z >= node.Position.Y)
                    {

                        Insert(box, node.Children[3], DepthLevel + 1);
                    }
                }
            }
            else
            {
                //Add box in current layer
                if (node.Primitives == null)
                    node.Primitives = new List<Primitive>();

                if (!node.Primitives.Contains(box))
                {
                    node.Primitives.Add(box);
                    ItemCount++;
                }
            }
        }
        //*UNUSED* *UNCOMMENTED*
        //Return boxes that generate Quad Tree Grid. It is possible to filter lower levels and display only higher ones by setting UpperLayerDepth to a value > 0
        public List<Box> RetrieveBoundariesFromPosition(Box box, ref List<Box> boxes, int UpperLayerDepth = 0, QuadTreeNode node = null)
        {
            if (node == null)
                node = Head;

            if (boxes == null)
                boxes = new List<Box>();

            //Verifies for all 4 sides of the box based on the rotation offset of the box
            Vector3 offsetPos = Vector3.Transform(new Vector3(box.Size.X / 2, 0, box.Size.Z / 2), box.Offset);

            Vector3 corner1 = new Vector3(box.Position.X - offsetPos.Z, 0, box.Position.Z + offsetPos.X);
            Vector3 corner2 = new Vector3(box.Position.X + offsetPos.X, 0, box.Position.Z + offsetPos.Z);
            Vector3 corner3 = new Vector3(box.Position.X - offsetPos.X, 0, box.Position.Z - offsetPos.Z);
            Vector3 corner4 = new Vector3(box.Position.X + offsetPos.Z, 0, box.Position.Z - offsetPos.X);

            //Verifies for all 4 sides of the box based on the rotation offset of the box
            offsetPos = Vector3.Transform(new Vector3(box.Size.X / 2, 0, 0), box.Offset);

            Vector3 Side1 = new Vector3(box.Position.X - offsetPos.Z, 0, box.Position.Z + offsetPos.X);
            Vector3 Side2 = new Vector3(box.Position.X + offsetPos.X, 0, box.Position.Z + offsetPos.Z);
            Vector3 Side3 = new Vector3(box.Position.X - offsetPos.X, 0, box.Position.Z - offsetPos.Z);
            Vector3 Side4 = new Vector3(box.Position.X + offsetPos.Z, 0, box.Position.Z - offsetPos.X);

            //Boxes are drawn twice as big as the node's size
            if (box.Size.X <= node.Size && box.Size.Z <= node.Size)
            {
                if (node.Children[0] != null)
                {
                    if (corner1.X <= node.Position.X && corner1.Z >= node.Position.Y ||
                        corner2.X <= node.Position.X && corner2.Z >= node.Position.Y ||
                        corner3.X <= node.Position.X && corner3.Z >= node.Position.Y ||
                        corner4.X <= node.Position.X && corner4.Z >= node.Position.Y ||
                        Side1.X <= node.Position.X && Side1.Z >= node.Position.Y ||
                        Side2.X <= node.Position.X && Side2.Z >= node.Position.Y ||
                        Side3.X <= node.Position.X && Side3.Z >= node.Position.Y ||
                        Side4.X <= node.Position.X && Side4.Z >= node.Position.Y)
                    {

                        RetrieveBoundariesFromPosition(box, ref boxes, UpperLayerDepth, node.Children[0]);
                    }
                }

                if (node.Children[1] != null)
                {
                    if (corner1.X >= node.Position.X && corner1.Z >= node.Position.Y ||
                        corner2.X >= node.Position.X && corner2.Z >= node.Position.Y ||
                        corner3.X >= node.Position.X && corner3.Z >= node.Position.Y ||
                        corner4.X >= node.Position.X && corner4.Z >= node.Position.Y ||
                        Side1.X >= node.Position.X && Side1.Z >= node.Position.Y ||
                        Side2.X >= node.Position.X && Side2.Z >= node.Position.Y ||
                        Side3.X >= node.Position.X && Side3.Z >= node.Position.Y ||
                        Side4.X >= node.Position.X && Side4.Z >= node.Position.Y)
                    {

                        RetrieveBoundariesFromPosition(box, ref boxes, UpperLayerDepth, node.Children[1]);
                    }
                }

                if (node.Children[2] != null)
                {
                    if (corner1.X <= node.Position.X && corner1.Z <= node.Position.Y ||
                        corner2.X <= node.Position.X && corner2.Z <= node.Position.Y ||
                        corner3.X <= node.Position.X && corner3.Z <= node.Position.Y ||
                        corner4.X <= node.Position.X && corner4.Z <= node.Position.Y ||
                        Side1.X <= node.Position.X && Side1.Z <= node.Position.Y ||
                        Side2.X <= node.Position.X && Side2.Z <= node.Position.Y ||
                        Side3.X <= node.Position.X && Side3.Z <= node.Position.Y ||
                        Side4.X <= node.Position.X && Side4.Z <= node.Position.Y)
                    {

                        RetrieveBoundariesFromPosition(box, ref boxes, UpperLayerDepth, node.Children[2]);
                    }
                }

                if (node.Children[3] != null)
                {
                    if (corner1.X >= node.Position.X && corner1.Z <= node.Position.Y ||
                        corner2.X >= node.Position.X && corner2.Z <= node.Position.Y ||
                        corner3.X >= node.Position.X && corner3.Z <= node.Position.Y ||
                        corner4.X >= node.Position.X && corner4.Z <= node.Position.Y ||
                        Side1.X >= node.Position.X && Side1.Z <= node.Position.Y ||
                        Side2.X >= node.Position.X && Side2.Z <= node.Position.Y ||
                        Side3.X >= node.Position.X && Side3.Z <= node.Position.Y ||
                        Side4.X >= node.Position.X && Side4.Z <= node.Position.Y)
                    {

                        RetrieveBoundariesFromPosition(box, ref boxes, UpperLayerDepth, node.Children[3]);
                    }
                }
            }

            boxes.Add(new Box(new Vector3(node.Position.X, 1.5f, node.Position.Y), new Vector3(0), new Vector3(node.Size * 2, 3, node.Size * 2)));

            return boxes;
        }