// This crops a polygon with a plane and keeps only a certain part of the polygon
        protected void CropPoly(ref WallPolygon poly, Plane p, bool keepfront)
        {
            const float NEAR_ZERO  = 0.01f;
            float       sideswitch = keepfront ? 1 : -1;
            WallPolygon newp       = new WallPolygon(poly.Count);

            poly.CopyProperties(newp);

            if (poly.Count > 0)
            {
                // First split lines that cross the plane so that we have vertices on the plane where the lines cross
                Vector3D v1    = poly[poly.Count - 1];
                float    side1 = p.Distance(v1) * sideswitch;
                for (int i = 0; i < poly.Count; i++)
                {
                    // Fetch vertex and determine side
                    Vector3D v2    = poly[i];
                    float    side2 = p.Distance(v2) * sideswitch;

                    // Front?
                    if (side2 > NEAR_ZERO)
                    {
                        if (side1 < -NEAR_ZERO)
                        {
                            // Split line with plane and insert the vertex
                            float u = 0.0f;
                            p.GetIntersection(v1, v2, ref u);
                            Vector3D v3 = v1 + (v2 - v1) * u;
                            newp.Add(v3);
                        }

                        newp.Add(v2);
                    }
                    // Back?
                    else if (side2 < -NEAR_ZERO)
                    {
                        if (side1 > NEAR_ZERO)
                        {
                            // Split line with plane and insert the vertex
                            float u = 0.0f;
                            p.GetIntersection(v1, v2, ref u);
                            Vector3D v3 = v1 + (v2 - v1) * u;
                            newp.Add(v3);
                        }
                    }
                    else
                    {
                        // On the plane
                        newp.Add(v2);
                    }

                    // Next
                    v1    = v2;
                    side1 = side2;
                }
            }

            poly = newp;
        }
        // This splits a polygon with a plane and returns the other part as a new polygon
        // The polygon is expected to be convex and clockwise
        protected WallPolygon SplitPoly(ref WallPolygon poly, Plane p, bool keepfront)
        {
            const float NEAR_ZERO = 0.01f;
            WallPolygon front     = new WallPolygon(poly.Count);
            WallPolygon back      = new WallPolygon(poly.Count);

            poly.CopyProperties(front);
            poly.CopyProperties(back);

            if (poly.Count > 0)
            {
                // Go for all vertices to see which side they have to be on
                Vector3D v1    = poly[poly.Count - 1];
                float    side1 = p.Distance(v1);
                for (int i = 0; i < poly.Count; i++)
                {
                    // Fetch vertex and determine side
                    Vector3D v2    = poly[i];
                    float    side2 = p.Distance(v2);

                    // Front?
                    if (side2 > NEAR_ZERO)
                    {
                        if (side1 < -NEAR_ZERO)
                        {
                            // Split line with plane and insert the vertex
                            float u = 0.0f;
                            p.GetIntersection(v1, v2, ref u);
                            Vector3D v3 = v1 + (v2 - v1) * u;
                            front.Add(v3);
                            back.Add(v3);
                        }

                        front.Add(v2);
                    }
                    // Back?
                    else if (side2 < -NEAR_ZERO)
                    {
                        if (side1 > NEAR_ZERO)
                        {
                            // Split line with plane and insert the vertex
                            float u = 0.0f;
                            p.GetIntersection(v1, v2, ref u);
                            Vector3D v3 = v1 + (v2 - v1) * u;
                            front.Add(v3);
                            back.Add(v3);
                        }

                        back.Add(v2);
                    }
                    else
                    {
                        // On the plane, add to both polygons
                        front.Add(v2);
                        back.Add(v2);
                    }

                    // Next
                    v1    = v2;
                    side1 = side2;
                }
            }

            if (keepfront)
            {
                poly = front;
                return(back);
            }
            else
            {
                poly = back;
                return(front);
            }
        }