//std::vector<Face> deadfaces; void FaceEmbed(BSPNode *node, Face && face) { assert(node); if(node->isleaf==OVER) { //deadfaces.push_back(std::move(face)); return; } if(node->isleaf==UNDER) { node->brep.push_back(std::move(face)); return; } int flag = FaceSplitTest(face, node->plane()); if(flag==UNDER) { FaceEmbed(node->under.get(),std::move(face)); return; } if(flag==OVER) { FaceEmbed(node->over.get(),std::move(face)); return; } if(flag==COPLANAR) { FaceEmbed(dot(node->xyz(), face.xyz()) > 0 ? node->under.get() : node->over.get(), std::move(face)); return; } assert(flag==SPLIT); // FIXME: add FaceSliceEdge calls here! FaceEmbed(node->over.get(), FaceClip(face, -node->plane())); FaceEmbed(node->under.get(), FaceClip(std::move(face), node->plane())); }
void FaceCutting(BSPNode *n,std::vector<Face*> &faces) { if(n->isleaf==OVER) { return; } if(n->isleaf==UNDER) { for(auto &f : faces) { delete f; } faces.clear(); return; } std::vector<Face*> faces_over; std::vector<Face*> faces_under; std::vector<Face*> faces_coplanar; while (faces.size()) { Face *f; f= Pop(faces); int s = FaceSplitTest(f, n->plane()); if(s==COPLANAR) faces_coplanar.push_back(f); else if(s==UNDER) faces_under.push_back(f); else if(s==OVER) faces_over.push_back(f); else { assert(s==SPLIT); Face *ovr = FaceDup(f); FaceClip(f,(*n)); FaceClip(ovr, float4(-n->xyz(), -n->w)); faces_under.push_back(f); faces_over.push_back(ovr); } } FaceCutting(n->under,faces_under); FaceCutting(n->over,faces_over); for(unsigned int i=0;i<faces_under.size();i++) faces.push_back(faces_under[i]); for (unsigned int i = 0; i<faces_over.size(); i++) faces.push_back(faces_over[i]); for (unsigned int i = 0; i<faces_coplanar.size(); i++) faces.push_back(faces_coplanar[i]); }
void FaceCutting(BSPNode *n, std::vector<Face> & faces) { if(n->isleaf==OVER) { return; } if(n->isleaf==UNDER) { faces.clear(); return; } std::vector<Face> faces_over; std::vector<Face> faces_under; std::vector<Face> faces_coplanar; while (faces.size()) { Face f = Pop(faces); int s = FaceSplitTest(f, n->plane()); if(s==COPLANAR) faces_coplanar.push_back(std::move(f)); else if(s==UNDER) faces_under.push_back(std::move(f)); else if(s==OVER) faces_over.push_back(std::move(f)); else { assert(s==SPLIT); faces_under.push_back(FaceClip(f, n->plane())); faces_over.push_back(FaceClip(std::move(f), -n->plane())); } } FaceCutting(n->under.get(),faces_under); FaceCutting(n->over.get(),faces_over); for(unsigned int i=0;i<faces_under.size();i++) faces.push_back(faces_under[i]); for (unsigned int i = 0; i<faces_over.size(); i++) faces.push_back(faces_over[i]); for (unsigned int i = 0; i<faces_coplanar.size(); i++) faces.push_back(faces_coplanar[i]); }
void DividePolys(const float4 &splitplane,std::vector<Face> && inputfaces, std::vector<Face> &under,std::vector<Face> &over,std::vector<Face> &coplanar){ int i=inputfaces.size(); while(i--) { int flag = FaceSplitTest(inputfaces[i],splitplane,FUZZYWIDTH); if(flag == OVER) { over.push_back(std::move(inputfaces[i])); } else if(flag == UNDER) { under.push_back(std::move(inputfaces[i])); } else if(flag == COPLANAR) { coplanar.push_back(std::move(inputfaces[i])); } else { assert(flag == SPLIT); over.push_back(FaceClip(inputfaces[i], -splitplane)); under.push_back(FaceClip(std::move(inputfaces[i]), splitplane)); } } }
Face FaceClip(const Face & face, const float4 & clip) { return FaceClip(Face(face), clip); }