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; }