/// <summary> /// Find the optimal split for a polygon /// </summary> /// <param name="poly"></param> /// <returns></returns> private (Vector3 point, Vector3 normal, List <BSPPoly <T> > left, List <BSPPoly <T> > right) FindOptimalSplit(BSPPoly <T>[] poly) { //init Vector3 point = Vector3.zero, normal = Vector3.zero; List <BSPPoly <T> > left = null, right = null; //optimal diff int diff = int.MaxValue; //get the working polygon IPoly working = poly[0].working; for (int i = 0; i < working.Resolution; i++) { //get the current point and normal Vector3 localPoint = working.GetPoint(i), localNormal = working.GetSurfaceNormal(i); //get output (List <BSPPoly <T> > localInside, List <BSPPoly <T> > localOutput) = GetSplit(poly, localPoint, localNormal); //calc the diff, and compare int localDiff = Math.Abs(localInside.Count - localOutput.Count); if (localDiff < diff) { left = localInside; right = localOutput; point = localPoint; normal = localNormal; diff = localDiff; } } return(point, normal, left, right); }
public BSPNode(BSPPoly <T> poly, BSPNode <T> inside, BSPNode <T> outside, Vector3 planePoint, Vector3 planeNormal) { this.poly = poly; this.inside = inside; this.outside = outside; this.planePoint = planePoint; this.planeNormal = planeNormal; }
/// <summary> /// Get the split for polys[0], for the specified point and normal /// </summary> /// <param name="polys"></param> /// <param name="point"></param> /// <param name="normal"></param> /// <param name="startPoly"></param> /// <returns></returns> private (List <BSPPoly <T> > left, List <BSPPoly <T> > right) GetSplit(BSPPoly <T>[] polys, Vector3 point, Vector3 normal, int startPoly = 1) { List <BSPPoly <T> > inside = new List <BSPPoly <T> >(), outside = new List <BSPPoly <T> >(); for (int i = startPoly; i < polys.Length; i++) { BSPPoly <T> poly = polys[i]; IPoly working = poly.working; object[] split = CSG.Geometry.CSGGeometry.Divide(working, point, normal); if (split[0] != null) { inside.Add(new BSPPoly <T>(poly.original, (IPoly)split[0])); } if (split[1] != null) { outside.Add(new BSPPoly <T>(poly.original, (IPoly)split[1])); } } return(inside, outside); }