public static CSGVertex Interpolate(CSGVertex _vertexA, CSGVertex _vertexB, float _step)
        {
            CSGVertex result = new CSGVertex();

            result.m_position = Vector3.Lerp(_vertexA.m_position, _vertexB.m_position, _step);
            result.m_normal   = Vector3.Lerp(_vertexA.m_normal, _vertexB.m_normal, _step);
            result.m_uv       = Vector2.Lerp(_vertexA.m_uv, _vertexB.m_uv, _step);
            result.m_color    = (_vertexA.m_color + _vertexB.m_color) / 2f;

            return(result);
        }
        // Split `polygon` by this plane if needed, then put the polygon or polygon
        // fragments in the appropriate lists. Coplanar polygons go into either
        // `coplanarFront` or `coplanarBack` depending on their orientation with
        // respect to this plane. Polygons in front or in back of this plane go into
        // either `front` or `back`.
        public void SplitPolygon(CSGPolygon _polygon, List <CSGPolygon> _coplanarFront,
                                 List <CSGPolygon> _coplanarBack, List <CSGPolygon> _front, List <CSGPolygon> _back)
        {
            // Classify each point as well as the entire polygon into one of the above
            // four classes.
            PolygonType        polygonType = 0;
            List <PolygonType> types       = new List <PolygonType>();

            for (int i = 0; i < _polygon.m_vertices.Count; i++)
            {
                float       t    = Vector3.Dot(m_normal, _polygon.m_vertices[i].m_position) - m_planeWidth;
                PolygonType type = (t < -CSG.EPSILON) ? PolygonType.Back : ((t > CSG.EPSILON) ?
                                                                            PolygonType.Front : PolygonType.Coplanar);
                polygonType |= type;
                types.Add(type);
            }

            // Put the polygon in the correct list, splitting it when necessary.
            switch (polygonType)
            {
            case PolygonType.Coplanar:
            {
                if (Vector3.Dot(m_normal, _polygon.m_plane.m_normal) > 0)
                {
                    _coplanarFront.Add(_polygon);
                }
                else
                {
                    _coplanarBack.Add(_polygon);
                }
            }
            break;

            case PolygonType.Front:
            {
                _front.Add(_polygon);
            }
            break;

            case PolygonType.Back:
            {
                _back.Add(_polygon);
            }
            break;

            case PolygonType.Spanning:
            {
                List <CSGVertex> front = new List <CSGVertex>();
                List <CSGVertex> back  = new List <CSGVertex>();

                for (int vertexIter = 0; vertexIter < _polygon.m_vertices.Count; vertexIter++)
                {
                    int nextVertexIndex = (vertexIter + 1) % _polygon.m_vertices.Count;

                    PolygonType currentType = types[vertexIter];
                    PolygonType nextType    = types[nextVertexIndex];

                    CSGVertex currentVertex = _polygon.m_vertices[vertexIter];
                    CSGVertex nextVertex    = _polygon.m_vertices[nextVertexIndex];

                    if (currentType != PolygonType.Back)
                    {
                        front.Add(currentVertex);
                    }

                    if (currentType != PolygonType.Front)
                    {
                        back.Add(currentVertex);
                    }

                    if ((currentType | nextType) == PolygonType.Spanning)
                    {
                        float step = (m_planeWidth - Vector3.Dot(m_normal, currentVertex.m_position)) / Vector3.Dot(m_normal, nextVertex.m_position - currentVertex.m_position);

                        CSGVertex vertex = CSGVertex.Interpolate(currentVertex, nextVertex, step);

                        front.Add(vertex);
                        back.Add(vertex);
                    }
                }

                if (front.Count >= 3)
                {
                    _front.Add(new CSGPolygon(front));
                }

                if (back.Count >= 3)
                {
                    _back.Add(new CSGPolygon(back));
                }
            }
            break;
            }
        }