private void PerformNode(BspNode inNode, CSGFace inFace, int nodeSide, OperationInfo info) { while (inNode != null) { CSGFace.EPlaneSide side = inFace.Side(inNode.plane); switch (side) { case CSGFace.EPlaneSide.Side_Front: // nodeSide = nodeSide | (inNode.IsCsg() ? 1 : 0); // leaf node if (inNode.front == null) { // set operation infos info.leafNode = inNode; info.leafLocation = BspNode.EBspLocation.BspLocation_Front; // we are done, process face ProcessFace(inFace, SIDE_Outside, info); } // get to next front node (if any) inNode = inNode.front; break; case CSGFace.EPlaneSide.Side_Back: int backSide = inNode.IsCsg() ? 0 : 1; // nodeSide = nodeSide & backSide; // leaf node if (inNode.back == null) { // set leaf infos info.leafNode = inNode; info.leafLocation = BspNode.EBspLocation.BspLocation_Back; // we are done, process face ProcessFace(inFace, SIDE_Inside, info); } // get to next front node (if any) inNode = inNode.back; break; case CSGFace.EPlaneSide.Side_Split: // split face and process front and back CSGFace frontFace, backFace; // inFace.Split(inNode.plane, out frontFace, out backFace); // TODO: set polygon cutted flags frontFace.flags |= CSGFace.FaceFlags_WasCutted; backFace.flags |= CSGFace.FaceFlags_WasCutted; // front node is a leaf node if (inNode.front == null) { // info.leafNode = inNode; info.leafLocation = BspNode.EBspLocation.BspLocation_Front; ProcessFace(frontFace, SIDE_Outside, info); } else { PerformNode(inNode.front, frontFace, nodeSide, info); } // Prcess back node with back face if (inNode.back == null) { // info.leafNode = inNode; info.leafLocation = BspNode.EBspLocation.BspLocation_Back; ProcessFace(backFace, SIDE_Inside, info); } else { // process back node with new face PerformNode(inNode.back, backFace, nodeSide, info); } // stop loop inNode = null; break; case CSGFace.EPlaneSide.Side_Planar: BspNode front, back; if (info.wasPlanar == true) { Debug.Log("Reentering Planar Nodes!"); } // set operation infos info.wasPlanar = true; info.backNode = null; info.processingBack = false; if (Vector3.Dot(inFace.GetPlane().normal, inNode.plane.normal) >= 0.0f) { // same order as we face in the same order front = inNode.front; back = inNode.back; // we are for now outside (as we are looking outside) info.planarSide = SIDE_Outside; } else { // reverse order as we are facing in the opposite direction front = inNode.back; back = inNode.front; // we are now inside as we are looking to the inside info.planarSide = SIDE_Inside; } // we are leaf node (coplanar face) if (front == null && back == null) { // set leaf stuff info.leafNode = inNode; info.leafLocation = BspNode.EBspLocation.BspLocation_Planar; // process node info.processingBack = true; // process face ProcessFace(inFace, InverseSide(info.planarSide), info); // stop loop inNode = null; } else if (front == null && back != null) { // only back nodes info.processingBack = true; // process back inNode = back; } else { // tread like we were on front side (maybe we do have a back node) info.processingBack = false; // remember back node info.backNode = back; // process front inNode = front; } break; } } }
private void PerformNode( BspNode inNode, Face inFace, int nodeSide, OperationInfo info ) { while( inNode != null ) { Face.EPlaneSide side = inFace.Side( inNode.plane ); switch( side ) { case Face.EPlaneSide.Side_Front: // nodeSide = nodeSide | (inNode.IsCsg() ? 1 : 0); // leaf node if( inNode.front == null ) { // set operation infos info.leafNode = inNode; info.leafLocation = BspNode.EBspLocation.BspLocation_Front; // we are done, process face ProcessFace( inFace, SIDE_Outside, info ); } // get to next front node (if any) inNode = inNode.front; break; case Face.EPlaneSide.Side_Back: int backSide = inNode.IsCsg() ? 0 : 1; // nodeSide = nodeSide & backSide; // leaf node if( inNode.back == null ) { // set leaf infos info.leafNode = inNode; info.leafLocation = BspNode.EBspLocation.BspLocation_Back; // we are done, process face ProcessFace( inFace, SIDE_Inside, info ); } // get to next front node (if any) inNode = inNode.back; break; case Face.EPlaneSide.Side_Split: // split face and process front and back Face frontFace, backFace; // inFace.Split( inNode.plane, out frontFace, out backFace ); // TODO: set polygon cutted flags frontFace.flags |= Face.FaceFlags_WasCutted; backFace.flags |= Face.FaceFlags_WasCutted; // front node is a leaf node if( inNode.front == null ) { // info.leafNode = inNode; info.leafLocation = BspNode.EBspLocation.BspLocation_Front; ProcessFace( frontFace, SIDE_Outside, info ); } else { PerformNode( inNode.front, frontFace, nodeSide, info ); } // Prcess back node with back face if( inNode.back == null ) { // info.leafNode = inNode; info.leafLocation = BspNode.EBspLocation.BspLocation_Back; ProcessFace( backFace, SIDE_Inside, info ); } else { // process back node with new face PerformNode( inNode.back, backFace, nodeSide, info ); } // stop loop inNode = null; break; case Face.EPlaneSide.Side_Planar: BspNode front, back; if( info.wasPlanar == true ) { Debug.Log( "Reentering Planar Nodes!" ); } // set operation infos info.wasPlanar = true; info.backNode = null; info.processingBack = false; if( Vector3.Dot( inFace.GetPlane().normal, inNode.plane.normal ) >= 0.0f ) { // same order as we face in the same order front = inNode.front; back = inNode.back; // we are for now outside (as we are looking outside) info.planarSide = SIDE_Outside; } else { // reverse order as we are facing in the opposite direction front = inNode.back; back = inNode.front; // we are now inside as we are looking to the inside info.planarSide = SIDE_Inside; } // we are leaf node (coplanar face) if( front == null && back == null ) { // set leaf stuff info.leafNode = inNode; info.leafLocation = BspNode.EBspLocation.BspLocation_Planar; // process node info.processingBack = true; // process face ProcessFace( inFace, InverseSide(info.planarSide), info ); // stop loop inNode = null; } else if( front == null && back != null ) { // only back nodes info.processingBack = true; // process back inNode = back; } else { // tread like we were on front side (maybe we do have a back node) info.processingBack = false; // remember back node info.backNode = back; // process front inNode = front; } break; } } }