public CSGNode(List <CSGPolygon> _polygons, CSGPlane _plane, CSGNode _frontNode, CSGNode _backNode)
 {
     m_polygons  = _polygons;
     m_plane     = _plane;
     m_frontNode = _frontNode;
     m_backNode  = _backNode;
 }
        // Return a new CSG solid representing space both this solid and in the
        // solid `csg`. Neither this solid nor the solid `csg` are modified.
        public static List <Mesh> Intersect(CSGNode _nodeAIn, CSGNode _nodeBIn, CSGMeshingSettings _meshSettings)
        {
            List <Mesh> resultantMeshes = new List <Mesh>();

            CSGNode nodeA = _nodeAIn.Clone();
            CSGNode nodeB = _nodeBIn.Clone();

            nodeA.Invert();
            nodeB.ClipTo(nodeA);
            nodeB.Invert();
            nodeA.ClipTo(nodeB);
            nodeB.ClipTo(nodeA);
            nodeA.Build(nodeB.AllPolygons());
            nodeA.Invert();

            CSGModel resultModel = new CSGModel(nodeA.AllPolygons());

            if (resultModel.SubDivideMesh(_meshSettings))
            {
                for (int subMeshIter = 0; subMeshIter < resultModel.m_subModels.Count; subMeshIter++)
                {
                    resultantMeshes.Add(resultModel.m_subModels[subMeshIter].ToMesh());
                }
            }
            else
            {
                resultantMeshes.Add(resultModel.ToMesh());
            }

            return(resultantMeshes);
        }
        public static List <Mesh> Intersect(GameObject _objectA, GameObject _objectB, CSGMeshingSettings _meshSettings)
        {
            CSGModel modelA = new CSGModel(_objectA);
            CSGModel modelB = new CSGModel(_objectB);

            CSGNode nodeA = new CSGNode(modelA.ToPolygons());
            CSGNode nodeB = new CSGNode(modelB.ToPolygons());

            return(CSGNode.Intersect(nodeA, nodeB, _meshSettings));
        }
        // Build a BSP tree out of `polygons`. When called on an existing tree, the
        // new polygons are filtered down to the bottom of the tree and become new
        // nodes there. Each set of polygons is partitioned using the first polygon
        // (no heuristic is used to pick a good split).
        public void Build(List <CSGPolygon> _polygons, int _recursionCount = 0)
        {
            if (_recursionCount > C_MaxRecursions)
            {
                Debug.LogWarning("Hit RecursionCap");
                return;
            }

            if (_polygons.Count < 1)
            {
                return;
            }

            if (m_plane == null || !m_plane.Valid())
            {
                m_plane              = new CSGPlane();
                m_plane.m_normal     = _polygons[0].m_plane.m_normal;
                m_plane.m_planeWidth = _polygons[0].m_plane.m_planeWidth;
            }


            if (m_polygons == null)
            {
                m_polygons = new List <CSGPolygon>();
            }

            List <CSGPolygon> frontPolygons = new List <CSGPolygon>();
            List <CSGPolygon> backPolygons  = new List <CSGPolygon>();

            for (int i = 0; i < _polygons.Count; i++)
            {
                m_plane.SplitPolygon(_polygons[i], m_polygons, m_polygons, frontPolygons, backPolygons);
            }

            if (frontPolygons.Count > 0)
            {
                if (m_frontNode == null)
                {
                    m_frontNode = new CSGNode();
                }

                m_frontNode.Build(frontPolygons, _recursionCount + 1);
            }

            if (backPolygons.Count > 0)
            {
                if (m_backNode == null)
                {
                    m_backNode = new CSGNode();
                }

                m_backNode.Build(backPolygons, _recursionCount + 1);
            }
        }
        public CSGNode DeepClone()
        {
            List <CSGPolygon> polygons = new List <CSGPolygon>();

            for (int polygonIter = 0; polygonIter < m_polygons.Count; polygonIter++)
            {
                polygons.Add(m_polygons[polygonIter].DeepClone());
            }
            CSGNode clone = new CSGNode(m_polygons, m_plane.DeepClone(), m_frontNode, m_backNode);

            return(clone);
        }
        public static List <Mesh> NVSubtract(GameObject _objectA, GameObject _objectB, CSGMeshingSettings _meshSettings)
        {
            CSGModel modelA = new CSGModel(_objectA);
            CSGModel modelB = new CSGModel(_objectB);
            CSGModel modelC = new CSGModel(_objectA);
            CSGModel modelD = new CSGModel(_objectB);

            CSGNode nodeA = new CSGNode(modelA.ToPolygons());
            CSGNode nodeB = new CSGNode(modelB.ToPolygons());
            CSGNode nodeC = new CSGNode(modelC.ToPolygons());
            CSGNode nodeD = new CSGNode(modelD.ToPolygons());

            return(CSGNode.NVSubtract(nodeA, nodeB, nodeC, nodeD, _meshSettings));
        }
        // Return a new CSG solid representing space in this solid but not in the
        // solid `csg`. Neither this solid nor the solid `csg` are modified.
        public static List <Mesh> HVSubtract(CSGNode _nodeAIn, CSGNode _nodeBIn, CSGMeshingSettings _meshSettings)
        {
            List <Mesh> resultantMeshes = new List <Mesh>();

            CSGNode nodeA = _nodeAIn.Clone();
            CSGNode nodeB = _nodeBIn.Clone();

            nodeA.ClipTo(nodeB);

            CSGModel resultantModels = new CSGModel(nodeA.AllPolygons());

            resultantModels.SubDivideMesh(_meshSettings);
            resultantMeshes.Add(resultantModels.ToMesh());
            return(resultantMeshes);
        }
        // Return a new CSG solid representing space in either this solid or in the
        // solid `csg`. Neither this solid nor the solid `csg` are modified.
        public static List <Mesh> NVUnion(CSGNode _nodeAIn, CSGNode _nodeBIn, CSGMeshingSettings _meshSettings)
        {
            List <Mesh> resultantMeshes = new List <Mesh>();

            CSGNode nodeA = _nodeAIn.Clone();
            CSGNode nodeB = _nodeBIn.Clone();

            nodeA.Build(nodeB.AllPolygons());

            CSGModel resultantModel = new CSGModel(nodeA.AllPolygons());

            resultantModel.SubDivideMesh(_meshSettings);
            resultantMeshes.Add(resultantModel.ToMesh());

            return(resultantMeshes);
        }
        public static List <Mesh> NVIntersect(GameObject _objectA, GameObject _objectB, CSGMeshingSettings _meshSettings)
        {
            Mesh       mesh       = _objectB.GetComponent <MeshFilter>().mesh;
            GameObject planeRight = GameObject.Instantiate(_objectB);

            planeRight.AddComponent <DestroyOnLateUpdate>();
            GameObject planeLeft = GameObject.Instantiate(_objectB);

            planeLeft.AddComponent <DestroyOnLateUpdate>();
            GameObject planeUP = GameObject.Instantiate(_objectB);

            planeUP.AddComponent <DestroyOnLateUpdate>();
            GameObject planeBack = GameObject.Instantiate(_objectB);

            planeBack.AddComponent <DestroyOnLateUpdate>();
            GameObject planeFront = GameObject.Instantiate(_objectB);

            planeFront.AddComponent <DestroyOnLateUpdate>();

            planeRight.transform.position = _objectB.transform.position + new Vector3(mesh.bounds.max.x * planeRight.transform.localScale.x, 0.0f, 0.0f);
            planeRight.transform.Rotate(new Vector3(0.0f, 0.0f, 90.0f));
            planeLeft.transform.position = _objectB.transform.position + new Vector3(mesh.bounds.min.x * planeLeft.transform.localScale.x, 0.0f, 0.0f);
            planeLeft.transform.Rotate(new Vector3(0.0f, 0.0f, -90.0f));
            planeUP.transform.position = _objectB.transform.position;
            planeUP.transform.Rotate(new Vector3(180.0f, 0.0f, 0.0f));
            planeBack.transform.position = _objectB.transform.position + new Vector3(0.0f, 0.0f, mesh.bounds.max.z * planeRight.transform.localScale.z);
            planeBack.transform.Rotate(new Vector3(-90.0f, 0.0f, 0.0f));
            planeFront.transform.position = _objectB.transform.position + new Vector3(0.0f, 0.0f, mesh.bounds.min.z * planeRight.transform.localScale.z);
            planeFront.transform.Rotate(new Vector3(90.0f, 0.0f, 0.0f));

            CSGModel modelA = new CSGModel(_objectA);
            CSGModel modelB = new CSGModel(planeRight);
            CSGModel modelC = new CSGModel(planeLeft);
            CSGModel modelD = new CSGModel(planeUP);
            CSGModel modelE = new CSGModel(planeBack);
            CSGModel modelF = new CSGModel(planeFront);

            CSGNode nodeA = new CSGNode(modelA.ToPolygons());
            CSGNode nodeB = new CSGNode(modelB.ToPolygons());
            CSGNode nodeC = new CSGNode(modelC.ToPolygons());
            CSGNode nodeD = new CSGNode(modelD.ToPolygons());
            CSGNode nodeE = new CSGNode(modelE.ToPolygons());
            CSGNode nodeF = new CSGNode(modelF.ToPolygons());

            return(CSGNode.NVIntersect(nodeA, nodeB, nodeC, nodeD, nodeE, nodeF, _meshSettings));
        }
        // Remove all polygons in this BSP tree that are inside the other BSP tree
        // `bsp`.
        public void ClipTo(CSGNode _otherNode, int _recursionCount = 0)
        {
            if (_recursionCount > C_MaxRecursions)
            {
                Debug.LogWarning("Hit RecursionCap");
                return;
            }

            m_polygons = _otherNode.ClipPolygons(m_polygons, 0);

            if (m_frontNode != null)
            {
                m_frontNode.ClipTo(_otherNode, _recursionCount + 1);
            }

            if (m_backNode != null)
            {
                m_backNode.ClipTo(_otherNode, _recursionCount + 1);
            }
        }
        // Return a new CSG solid representing space in this solid but not in the
        // solid `csg`. Neither this solid nor the solid `csg` are modified.
        public static List <Mesh> NVSubtract(CSGNode _nodeAIn, CSGNode _nodeBIn, CSGNode _nodeCIn, CSGNode _nodeDIn, CSGMeshingSettings _meshSettings)
        {
            List <Mesh> resultantMeshes = new List <Mesh>();

            CSGNode nodeA = _nodeAIn.Clone();
            CSGNode nodeB = _nodeBIn.Clone();

            nodeA.ClipTo(nodeB);

            CSGNode nodeC = _nodeCIn.Clone();
            CSGNode nodeD = _nodeDIn.Clone();

            nodeD.Invert();
            nodeC.ClipTo(nodeD);

            CSGModel resultantModelA = new CSGModel(nodeA.AllPolygons());
            CSGModel resultantModelB = new CSGModel(nodeC.AllPolygons());

            resultantMeshes.Add(resultantModelA.ToMesh());
            resultantMeshes.Add(resultantModelB.ToMesh());
            return(resultantMeshes);
        }
        // Convert solid space to empty space and empty space to solid space.
        public void Invert()
        {
            for (int i = 0; i < m_polygons.Count; i++)
            {
                m_polygons[i].Flip();
            }

            m_plane.Flip();

            if (m_frontNode != null)
            {
                m_frontNode.Invert();
            }

            if (m_backNode != null)
            {
                m_backNode.Invert();
            }

            CSGNode tempNode = m_frontNode;

            m_frontNode = m_backNode;
            m_backNode  = tempNode;
        }
        // Return a new CSG solid representing space both this solid and in the
        // solid `csg`. Neither this solid nor the solid `csg` are modified.
        public static List <Mesh> NVIntersect(CSGNode _nodeAIn, CSGNode _nodeBIn, CSGNode _nodeCIn,
                                              CSGNode _nodeDIn, CSGNode _nodeEIn, CSGNode _nodeFIn, CSGMeshingSettings _meshSettings)
        {
            List <Mesh> resultantMeshes = new List <Mesh>();

            CSGNode nodeA = _nodeAIn.Clone();
            CSGNode nodeB = _nodeBIn.Clone();
            CSGNode nodeC = _nodeCIn.Clone();
            CSGNode nodeD = _nodeDIn.Clone();
            CSGNode nodeE = _nodeEIn.Clone();
            CSGNode nodeF = _nodeFIn.Clone();

            nodeA.ClipTo(nodeB);
            nodeA.ClipTo(nodeC);
            nodeA.ClipTo(nodeD);
            nodeA.ClipTo(nodeE);
            nodeA.ClipTo(nodeF);

            CSGModel resultantModels = new CSGModel(nodeA.AllPolygons());

            resultantModels.SubDivideMesh(_meshSettings);
            resultantMeshes.Add(resultantModels.ToMesh());
            return(resultantMeshes);
        }
        public CSGNode Clone()
        {
            CSGNode clone = new CSGNode(m_polygons, m_plane, m_frontNode, m_backNode);

            return(clone);
        }
 public CSGNode()
 {
     m_frontNode = null;
     m_backNode  = null;
 }