public void Split() { R3DBox pBox = CentralPointsBoundingBox; float middleX = (pBox.Min.X + pBox.Max.X) / 2; float middleZ = (pBox.Min.Z + pBox.Max.Z) / 2; // Node 1 (bottom-left) Vector3 node1Min = new Vector3(pBox.Min.X, pBox.Min.Y, pBox.Min.Z); Vector3 node1Max = new Vector3(middleX, pBox.Max.Y, middleZ); NVRNode node1 = new NVRNode(new R3DBox(node1Min, node1Max), this); // Node 2 (top-left) Vector3 node2Min = new Vector3(pBox.Min.X, pBox.Min.Y, middleZ); Vector3 node2Max = new Vector3(middleX, pBox.Max.Y, pBox.Max.Z); NVRNode node2 = new NVRNode(new R3DBox(node2Min, node2Max), this); // Node 3 (top-right) Vector3 node3Min = new Vector3(middleX, pBox.Min.Y, middleZ); Vector3 node3Max = new Vector3(pBox.Max.X, pBox.Max.Y, pBox.Max.Z); NVRNode node3 = new NVRNode(new R3DBox(node3Min, node3Max), this); // Node 4 (bottom-right) Vector3 node4Min = new Vector3(middleX, pBox.Min.Y, pBox.Min.Z); Vector3 node4Max = new Vector3(pBox.Max.X, pBox.Max.Y, middleZ); NVRNode node4 = new NVRNode(new R3DBox(node4Min, node4Max), this); foreach (NVRNode childNode in Children) { Vector3 proportions = childNode.CentralPointsBoundingBox.GetProportions(); if ((childNode.Meshes.Count > 1) && (proportions.X > 100 || proportions.Z > 100)) { childNode.Split(); } } }
public NVRNode(R3DBox centralPointsBox, NVRNode parentNode) { // Used if we create it from a parent node. this.CentralPointsBoundingBox = centralPointsBox; this.Meshes.AddRange(parentNode.Meshes.FindAll(x => this.CentralPointsBoundingBox.ContainsPoint(x.BoundingSphere.Position))); parentNode.Children.Add(this); this.BoundingBox = this.CalculateBoundingBox(); }
// Generate a node buffer public void GenerateNodeBuffer(NVRNode node) { node.ChildNodeCount = node.Children.Count; Nodes.InsertRange(0, node.Children); for (int i = node.Children.Count - 1; i >= 0; i--) { GenerateNodeBuffer(node.Children[i]); } }
private NVRNode CreateRootNode() { // Calculate the bounding box of the entire map + bounding box of the central points of the meshes (used to split nodes). NVRNode rootNode = new NVRNode(this.Meshes); // Create children for root node and all of its children and children and children if (this.Meshes.Count > 1) { rootNode.Split(); } return(rootNode); }
// Generate a mesh buffer public void GenerateMeshBuffer(NVRNode node) { node.FirstMesh = Meshes.Count; node.MeshCount = node.Meshes.Count; if (node.Children.Count == 0) { Meshes.AddRange(node.Meshes); } else { foreach (NVRNode child in node.Children) { GenerateMeshBuffer(child); } } }
// Generate buffers for writing private NVRBuffers GenerateBuffers() { NVRBuffers buffers = new NVRBuffers(); // Material buffer foreach (NVRMesh mesh in Meshes) { if (!buffers.Materials.Contains(mesh.Material)) { buffers.Materials.Add(mesh.Material); } } // Creating complex buffers first foreach (NVRMesh mesh in Meshes) { NVRDrawIndexedPrimitive complexMesh = mesh.IndexedPrimitives[0]; NVRVertexType type = complexMesh.Vertices[0].GetVertexType(); NVRVertexBuffer vertBuffer = buffers.GetVertexBuffer(complexMesh.Vertices.Count, type); int bufferIndex = buffers.VertexBuffers.IndexOf(vertBuffer); NVRIndexBuffer indBuffer = buffers.GetIndexBuffer(bufferIndex); complexMesh.IndexBuffer = bufferIndex; complexMesh.VertexBuffer = bufferIndex; complexMesh.FirstVertex = vertBuffer.Vertices.Count; complexMesh.FirstIndex = indBuffer.Indices.Count; complexMesh.IndexCount = complexMesh.Indices.Count; complexMesh.VertexCount = complexMesh.Vertices.Count; vertBuffer.Vertices.AddRange(complexMesh.Vertices); int indBufferMax = indBuffer.CurrentMax + 1; foreach (int index in complexMesh.Indices) { indBuffer.AddIndex(index + indBufferMax); } } // Then do simple ones foreach (NVRMesh mesh in Meshes) { NVRDrawIndexedPrimitive simpleMesh = mesh.IndexedPrimitives[1]; NVRVertexType type = simpleMesh.Vertices[0].GetVertexType(); NVRVertexBuffer vertBuffer = buffers.GetVertexBuffer(simpleMesh.Vertices.Count, type); int bufferIndex = buffers.VertexBuffers.IndexOf(vertBuffer); NVRIndexBuffer indBuffer = buffers.GetIndexBuffer(bufferIndex); simpleMesh.IndexBuffer = bufferIndex; simpleMesh.VertexBuffer = bufferIndex; simpleMesh.FirstVertex = vertBuffer.Vertices.Count; simpleMesh.FirstIndex = indBuffer.Indices.Count; simpleMesh.IndexCount = simpleMesh.Indices.Count; simpleMesh.VertexCount = simpleMesh.Vertices.Count; vertBuffer.Vertices.AddRange(simpleMesh.Vertices); int indBufferMax = indBuffer.CurrentMax + 1; foreach (int index in simpleMesh.Indices) { indBuffer.AddIndex(index + indBufferMax); } } NVRNode parentNode = this.CreateRootNode(); // Making mesh buffer buffers.GenerateMeshBuffer(parentNode); foreach (NVRMesh mesh in buffers.Meshes) { mesh.MaterialIndex = buffers.Materials.IndexOf(mesh.Material); } // Making node buffer buffers.Nodes.Add(parentNode); buffers.GenerateNodeBuffer(parentNode); foreach (NVRNode node in buffers.Nodes) { if (node.Children.Count > 0) { node.FirstChildNode = buffers.Nodes.IndexOf(node.Children[0]); } else { node.FirstChildNode = -1; } } return(buffers); }