private void addPolygon(ref BSPNode root, BSPFaceRef face, Polygon transformed) { if(root == null) root = new BSPNode(); if(root.PolygonsFront.Count == 0) { // We though root.Front == null && root.Back == null root.Plane = transformed.Plane; root.PolygonsFront = new List<BSPFaceRef> { face }; return; } var positive = 0; var negative = 0; var inPlane = 0; foreach(var v in transformed.Vertices) { var dist = root.Plane.Distance(v.Position); if (dist > SPLIT_EPSILON) positive++; else if (dist < -SPLIT_EPSILON) negative++; else inPlane++; } if(positive > 0 && negative == 0) // SPLIT_FRONT { addPolygon(ref root.Front, face, transformed); } else if(positive == 0 && negative > 0) // SPLIT_BACK { addPolygon(ref root.Back, face, transformed); } else // SPLIT_IN_PLANE { if(transformed.Plane.Normal.Dot(root.Plane.Normal) > 0.9) { root.PolygonsFront.Add(face); } else { root.PolygonsBack.Add(face); } } }
public void RenderBSPBackToFront(BlendingMode currentTransparency, BSPNode root, UnlitTintedShaderDescription shader) { var d = root.Plane.Distance(EngineCamera.Position); if (d >= 0) { if (root.Back != null) { RenderBSPBackToFront(currentTransparency, root.Back, shader); } foreach (var p in root.PolygonsBack) { RenderPolygonTransparency(currentTransparency, p, shader); } foreach (var p in root.PolygonsFront) { RenderPolygonTransparency(currentTransparency, p, shader); } if (root.Front != null) { RenderBSPBackToFront(currentTransparency, root.Front, shader); } } else { if (root.Front != null) { RenderBSPBackToFront(currentTransparency, root.Front, shader); } foreach (var p in root.PolygonsFront) { RenderPolygonTransparency(currentTransparency, p, shader); } foreach (var p in root.PolygonsBack) { RenderPolygonTransparency(currentTransparency, p, shader); } if (root.Back != null) { RenderBSPBackToFront(currentTransparency, root.Back, shader); } } }
public void Reset() { Root = new BSPNode(); }