public WorldData(string filePath) { using (StreamReader sr = new StreamReader(filePath)) { int id = 0; string line; var vertices = new List <Vector4>(); while ((line = sr.ReadLine()) != null) { if (line.Length > 0) { string[] points = line.Split(' '); switch (line[0]) { case 'v': vertices.Add(new Vector4(float.Parse(points[1]), float.Parse(points[2]), float.Parse(points[3]), 1.0F)); break; case 'f': var poly = new Polygon { ID = id++, vertices = new Vector4[points.Length - 1] }; for (int i = 0; i < points.Length - 1; i++) { poly.vertices[i] = vertices[int.Parse(points[i + 1]) - 1]; } poly.normal = Transformations.CalculateSurfaceNormal(poly); Polygons.Add(poly); break; } } } } BSPTree = new BSPTree(Polygons); Polygons = BSPTree.Polygons; }
private Node GenerateTree(List <Polygon> polygons) { if (polygons.Count == 0) { return(null); } else { var polyRoot = new Node(polygons[0].ID); var frontPolygons = new List <Polygon>(); var backPolygons = new List <Polygon>(); var d = -Vector3.Dot(polygons[0].normal, Transformations.V4ToV3(polygons[0].vertices[0])); var plane = new Vector4(polygons[0].normal, d); for (int i = 1; i < polygons.Count; i++) { var polyPos = CheckPosition(polygons[i], plane); if (polyPos == Position.InFront) { frontPolygons.Add(polygons[i]); } else if (polyPos == Position.Behind) { backPolygons.Add(polygons[i]); } else { var d2 = -Vector3.Dot(polygons[i].normal, Transformations.V4ToV3(polygons[i].vertices[0])); var v = Vector3.Cross(polygons[0].normal, polygons[i].normal); var dot = Vector3.Dot(v, v); var u1 = d2 * polygons[0].normal; var u2 = -d * polygons[i].normal; var p = Vector3.Cross(u1 + u2, v / dot); int p1pos = -1, p2pos = -1; Vector3 point1 = new Vector3(), point2 = new Vector3(); for (int j = 0; j < polygons[i].vertices.Length; j++) { var current = polygons[i].vertices[j]; var next = polygons[i].vertices[(j + 1) % polygons[i].vertices.Length]; if (Vector4.Dot(current, plane) * Vector4.Dot(next, plane) <= 0) { var u = Transformations.V4ToV3(next - current); var a = Vector3.Cross(v, u); var b = Vector3.Cross(Transformations.V4ToV3(next) - p, u); var t = 0.0F; if (a.X != 0) { t = b.X / a.X; } else if (a.Y != 0) { t = b.Y / a.Y; } else if (a.Z != 0) { t = b.Z / a.Z; } if (p1pos == -1) { point1 = p + (t * v); p1pos = j + 1; } else { point2 = p + (t * v); p2pos = j + 1; } } } var poly1 = new Polygon { ID = Polygons.Count, vertices = new Vector4[p1pos + (polygons[i].vertices.Length - p2pos) + 2], normal = polygons[i].normal }; for (int j = 0, k = 0; k < p1pos; j++, k++) { poly1.vertices[j] = polygons[i].vertices[k]; } poly1.vertices[p1pos] = new Vector4(point1, 1.0F); poly1.vertices[p1pos + 1] = new Vector4(point2, 1.0F); for (int j = p1pos + 2, k = p2pos; k < polygons[i].vertices.Length; j++, k++) { poly1.vertices[j] = polygons[i].vertices[k]; } poly1.normal = Transformations.CalculateSurfaceNormal(poly1); Polygons.Add(poly1); var poly2 = new Polygon { ID = Polygons.Count, vertices = new Vector4[p2pos - p1pos + 2], normal = polygons[i].normal }; poly2.vertices[0] = new Vector4(point1, 1.0F); for (int j = 1, k = p1pos; k < p2pos; j++, k++) { poly2.vertices[j] = polygons[i].vertices[k]; } poly2.vertices[p2pos - p1pos + 1] = new Vector4(point2, 1.0F); Polygons.Add(poly2); if (CheckPosition(poly1, plane) == Position.InFront) { frontPolygons.Add(poly1); backPolygons.Add(poly2); } else { frontPolygons.Add(poly2); backPolygons.Add(poly1); } } } polyRoot.Front = GenerateTree(frontPolygons); polyRoot.Back = GenerateTree(backPolygons); return(polyRoot); } }