/** * Initialization. */ public override void SetupScenegraph() { Random random = new Random(); int numberOfPoints = 10; List <Vector3> points = new List <Vector3>(); List <int> pointIndices = new List <int>(); for (int i = 0; i < numberOfPoints; i++) { points.Add(new Vector3((float)(2 * random.NextDouble() - 1), (float)(2 * random.NextDouble() - 1), 0)); pointIndices.Add(i); } BspTreeToolsDummy tools = new BspTreeToolsDummy(); BspTreeNode rootNode = tools.CreateBspTree(null, points, pointIndices); if (rootNode != null) { Vector3 observer = new Vector3(1, 1, 0); List <int> sortedPoints = tools.GetBackToFront(rootNode, points, observer); node = new BspNode(rootNode, points, sortedPoints, observer); GetRoot().AddChild(node); } GetRoot().LightPosition = new Vector3(0, 0, 1); GetRoot().BackgroundColor = Color4.DarkGray; GL.PointSize(5); GL.LineWidth(5); }
/** * Recursively create a BSP tree for a given set of points * */ public static BspTreeNode CreateBspTree(BspTreeNode parentNode, List <Vector3> allPoints, List <int> pointIndices) { if (pointIndices.Count == 1) { InsertNode(parentNode, allPoints, pointIndices[0]); } else if (pointIndices.Count == 2) { // Two nodes - create separating plane BspTreeNode node = new BspTreeNode(); Vector3 p0 = allPoints[pointIndices[0]]; Vector3 p1 = allPoints[pointIndices[1]]; node.P = Vector3.Multiply(Vector3.Add(p0, p1), 0.5f); node.N = Vector3.Subtract(p0, p1).Normalized(); InsertNode(node, allPoints, pointIndices[0]); InsertNode(node, allPoints, pointIndices[1]); return(node); } else { // PCA-based separation BspTreeNode node = new BspTreeNode(); PrincipalComponentAnalysis pca = new PrincipalComponentAnalysis(); foreach (int index in pointIndices) { pca.Add(allPoints[index]); } pca.applyPCA(); node.P = pca.getCentroid(); node.N = pca.getEigenVector(2); // Handle children List <int> pos = new List <int>(); List <int> neg = new List <int>(); foreach (int index in pointIndices) { if (node.IsPositive(allPoints[index])) { pos.Add(index); } else { neg.Add(index); } } node.SetChild(BspTreeNode.Orientation.POSITIVE, CreateBspTree(node, allPoints, pos)); node.SetChild(BspTreeNode.Orientation.NEGATIVE, CreateBspTree(node, allPoints, neg)); return(node); } return(null); }
public BspNode(BspTreeNode rootNode, List <Vector3> points) { this.rootNode = rootNode; this.points = points; vboPoints.Setup(CreateVBOPoints(), PrimitiveType.Points); vboBack2FrontPath.Setup(CreateVBOBack2Front(), PrimitiveType.LineStrip); vboPlanes.Setup(CreateVBOPlanes(rootNode, 0.7f), PrimitiveType.Lines); vboElements.Setup(CreateVBOElements(rootNode), PrimitiveType.Lines); }
private static void InsertNode(BspTreeNode node, List <Vector3> allPoints, int pointIndex) { if (node.IsPositive(allPoints[pointIndex])) { node.AddElement(BspTreeNode.Orientation.POSITIVE, pointIndex); } else { node.AddElement(BspTreeNode.Orientation.NEGATIVE, pointIndex); } }
private static List <int> GetBackToFrontElements(BspTreeNode node, BspTreeNode.Orientation orientation, List <Vector3> allPoints, Vector3 eye) { List <int> list = new List <int>(); for (int i = 0; i < node.getNumberOfElements(orientation); i++) { list.Add(node.getElement(orientation, i)); } list.AddRange(GetBackToFront(node.GetChild(orientation), allPoints, eye)); return(list); }
public BspScene() : base(100, Shader.ShaderMode.NO_LIGHTING, RenderMode.REGULAR) { Random random = new Random(); int numberOfPoints = 10; List <Vector3> points = new List <Vector3>(); List <int> pointIndices = new List <int>(); for (int i = 0; i < numberOfPoints; i++) { points.Add(new Vector3((float)(2 * random.NextDouble() - 1), (float)(2 * random.NextDouble() - 1), 0)); pointIndices.Add(i); } BspTreeNode rootNode = BspTreeTools.CreateBspTree(null, points, pointIndices); node = new BspNode(rootNode, points); GetRoot().AddChild(node); GetRoot().LightPosition = new Vector3(0, 0, 1); }
/** * Create VBO render vertices for the BSP tree planes. * */ private List <RenderVertex> CreateVBOPlanes(BspTreeNode node, float scale) { List <RenderVertex> renderVertices = new List <RenderVertex>(); if (node == null) { return(renderVertices); } Vector3 tangent = Vector3.Multiply(new Vector3(node.N.Y, -node.N.X, 0), scale); renderVertices.Add(new RenderVertex(Vector3.Add(node.P, tangent), normal, Color4.White)); renderVertices.Add(new RenderVertex(Vector3.Subtract(node.P, tangent), normal, Color4.White)); renderVertices.Add(new RenderVertex(node.P, normal, Color4.White)); renderVertices.Add(new RenderVertex(Vector3.Add(node.P, Vector3.Multiply(node.N, scale * 0.3f)), normal, Color4.White)); renderVertices.AddRange(CreateVBOPlanes(node.GetChild(BspTreeNode.Orientation.POSITIVE), scale * 0.5f)); renderVertices.AddRange(CreateVBOPlanes(node.GetChild(BspTreeNode.Orientation.NEGATIVE), scale * 0.5f)); return(renderVertices); }
public static List <int> GetBackToFront(BspTreeNode node, List <Vector3> points, Vector3 eye) { if (node == null) { return(new List <int>()); } if (node.IsPositive(eye)) { List <int> l1 = GetBackToFrontElements(node, BspTreeNode.Orientation.NEGATIVE, points, eye); List <int> l2 = GetBackToFrontElements(node, BspTreeNode.Orientation.POSITIVE, points, eye); l1.AddRange(l2); return(l1); } else { List <int> l1 = GetBackToFrontElements(node, BspTreeNode.Orientation.POSITIVE, points, eye); List <int> l2 = GetBackToFrontElements(node, BspTreeNode.Orientation.NEGATIVE, points, eye); l1.AddRange(l2); return(l1); } }
/** * Create VBO render vertices for the elements in a node (front and back). */ private List <RenderVertex> CreateVBOElements(BspTreeNode node) { List <RenderVertex> renderVertices = new List <RenderVertex>(); if (node == null) { return(renderVertices); } for (int orientation = 0; orientation < 2; orientation++) { Color4 color = (orientation == 0) ? Color4.Magenta : Color4.Orange; for (int i = 0; i < node.getNumberOfElements((BspTreeNode.Orientation)orientation); i++) { int index = node.getElement((BspTreeNode.Orientation)orientation, i); renderVertices.Add(new RenderVertex(node.P, normal, color)); renderVertices.Add(new RenderVertex(points[index], normal, color)); } } renderVertices.AddRange(CreateVBOElements(node.GetChild(BspTreeNode.Orientation.POSITIVE))); renderVertices.AddRange(CreateVBOElements(node.GetChild(BspTreeNode.Orientation.NEGATIVE))); return(renderVertices); }
public void SetChild(Orientation orientation, BspTreeNode childNode) { children[(int)orientation] = childNode; }
/** * Compute the back-to-front ordering for all points in 'points' based on the * tree in 'node' and the given eye position * * @param node * Root node of the BSP tree * @param points * List of points to be considered * @param eye * Observer position * @return Sorted (back-to-front) list of points */ public virtual List <int> GetBackToFront(BspTreeNode node, List <Vector3> points, Vector3 eye) { // YOUR CODE GOES HERE! return(null); }
/** * Recursively create a BSP tree for a given set of points. * * @param parentNode * Parent scene graph node * @param allPoints * List with all point positions in the dataset * @param Set * if indices used in the current recursive call */ public virtual BspTreeNode CreateBspTree(BspTreeNode parentNode, List <Vector3> allPoints, List <int> pointIndices) { // YOUR CODE GOES HERE! return(null); }