void RecursivelyRenderDebug(KDNode<VoxelElement> node, RenderView view, int depth, bool isLeft) { if (node == null)// || view.GetFrustum().Contains(node.bounds) == ContainmentType.Disjoint) return; { Gaia.Rendering.DebugElementManager debugMgr = (Gaia.Rendering.DebugElementManager)view.GetRenderElementManager(Gaia.Rendering.RenderPass.Debug); Color currColor = (isLeft) ? nodeColorsLeft[depth % nodeColorsLeft.Length] : nodeColors[depth % nodeColors.Length]; if (depth == maxDepth) debugMgr.AddElements(DebugHelper.GetVerticesFromBounds(node.bounds, currColor)); if (node.element != null) { debugMgr.AddElements(DebugHelper.GetVerticesFromBounds(node.element.bounds, Color.White)); } } depth++; //if (depth < maxDepth) { RecursivelyRenderDebug(node.leftChild, view, depth, true); RecursivelyRenderDebug(node.rightChild, view, depth, false); } }
void RecursivelyRender(KDNode<VoxelElement> node, RenderView view) { if (node == null || (view.GetFrustum().Contains(node.bounds) == ContainmentType.Disjoint))// && node.bounds.Contains(view.GetPosition()) == ContainmentType.Disjoint)) return; if (node.element != null && (view.GetFrustum().Contains(node.element.bounds) != ContainmentType.Disjoint)) { view.AddElement(terrainMaterial, node.element.geometry.renderElement); } RecursivelyRender(node.leftChild, view); RecursivelyRender(node.rightChild, view); }
void RecursivelyBuildBounds(KDNode<VoxelElement> node) { if (node == null) return; RecursivelyBuildBounds(node.leftChild); RecursivelyBuildBounds(node.rightChild); if (node.element != null) { node.bounds = node.element.bounds; const float extra = 1.000001f; node.bounds.Min = node.bounds.Min * extra; node.bounds.Max = node.bounds.Max * extra; } else { if (node.leftChild != null) node.bounds = node.leftChild.bounds; else { if (node.rightChild != null) node.bounds = node.rightChild.bounds; else node.bounds = new BoundingBox(Vector3.One * float.PositiveInfinity, Vector3.One * float.NegativeInfinity); } } if (node.leftChild != null) { node.bounds.Min = Vector3.Min(node.leftChild.bounds.Min, node.bounds.Min); node.bounds.Max = Vector3.Max(node.leftChild.bounds.Max, node.bounds.Max); } if (node.rightChild != null) { node.bounds.Min = Vector3.Min(node.rightChild.bounds.Min, node.bounds.Min); node.bounds.Max = Vector3.Max(node.rightChild.bounds.Max, node.bounds.Max); } }
public KDTreeTriangles(List<TriangleVertexIndices> indices, List<Vector3> vertices) { this.rootNode = new KDNode(); ConvertToKD(indices, vertices); ConstructKDTree(rootNode, 0, this.indices.ToArray()); }
unsafe void GetTrianglesIntersectingAABox(KDNode node, int *triangles, ref int triCount, ref BoundingBox testBox) { if (node.boundingBox.Contains(testBox) != ContainmentType.Disjoint) { if (node.triangleBox.Contains(testBox) != ContainmentType.Disjoint) { ulong ID = GetID(ref node.element); triangles[triCount] = triMap[ID];//.Add(node.element); triCount++; } if (node.leftChild != null) GetTrianglesIntersectingAABox(node.leftChild, triangles, ref triCount, ref testBox); if (node.rightChild != null) GetTrianglesIntersectingAABox(node.rightChild, triangles, ref triCount, ref testBox); } }
void ConstructKDTree(KDNode currNode, int depth, TriangleVertexIndicesKD[] entities) { if (entities.Length == 0) return; int axis = depth % maxDimension; List<TriangleVertexIndicesKD> sortedList = new List<TriangleVertexIndicesKD>(); sortedList.AddRange(entities); switch (axis) { case 0: sortedList.Sort(CompareX); break; case 1: sortedList.Sort(CompareY); break; case 2: sortedList.Sort(CompareZ); break; } BoundingBox bounds = new BoundingBox(vertices[sortedList[0].I0], vertices[sortedList[0].I0]); Vector3[] vecs = new Vector3[3]; for (int i = 0; i < sortedList.Count; i++) { vecs[0] = vertices[sortedList[i].I0]; vecs[1] = vertices[sortedList[i].I1]; vecs[2] = vertices[sortedList[i].I2]; for (int j = 0; j < vecs.Length; j++) { bounds.Max = Vector3.Max(bounds.Max, vecs[j]); bounds.Min = Vector3.Min(bounds.Min, vecs[j]); } } int medianIndex = sortedList.Count / 2; vecs[0] = vertices[sortedList[medianIndex].I0]; vecs[1] = vertices[sortedList[medianIndex].I1]; vecs[2] = vertices[sortedList[medianIndex].I2]; BoundingBox triBounds = new BoundingBox(vecs[0], vecs[0]); for (int j = 0; j < vecs.Length; j++) { triBounds.Max = Vector3.Max(triBounds.Max, vecs[j]); triBounds.Min = Vector3.Min(triBounds.Min, vecs[j]); } float extra = 1.000001f; bounds.Min = bounds.Min * extra; bounds.Max = bounds.Max * extra; triBounds.Min = triBounds.Min * extra; triBounds.Max = triBounds.Max * extra; if (sortedList.Count > 1) { depth++; int leftCount = medianIndex; if (leftCount > 0) { TriangleVertexIndicesKD[] leftEntities = new TriangleVertexIndicesKD[leftCount]; sortedList.CopyTo(0, leftEntities, 0, leftCount); currNode.leftChild = new KDNode(); ConstructKDTree(currNode.leftChild, depth, leftEntities); } int rightCount = sortedList.Count - (medianIndex + 1); if (rightCount > 0) { TriangleVertexIndicesKD[] rightEntities = new TriangleVertexIndicesKD[rightCount]; sortedList.CopyTo(medianIndex + 1, rightEntities, 0, rightCount); currNode.rightChild = new KDNode(); ConstructKDTree(currNode.rightChild, depth, rightEntities); } } currNode.element = sortedList[medianIndex]; currNode.boundingBox = bounds; currNode.triangleBox = triBounds; }