public BVHNode(Vector3 minBound, Vector3 maxBound, BVHNode leftChild, BVHNode rightChild, int start, int end) { bound = new BoundingBox(minBound, maxBound); lChild = leftChild; rChild = rightChild; surfaceIndexStart = start; surfaceIndexEnd = end; }
public BVHNode() { bound = new BoundingBox(); lChild = null; rChild = null; surfaceIndexStart = -1; surfaceIndexEnd = -1; }
public void Build(VertexPositionTexture[] verts, int[] inds) { tris = new List <Triangle>(inds.Length / 3); for (int i = 0; i < inds.Length;) { int i1 = inds[i++]; int i2 = inds[i++]; int i3 = inds[i++]; tris.Add(new Triangle( verts[i1].Position, verts[i2].Position, verts[i3].Position )); } root = CreateTree(0, tris.Count); }
private BVHNode CreateTree(int start, int end) { Vector3 minB = new Vector3(float.MaxValue); Vector3 maxB = new Vector3(-float.MaxValue); for (int i = start; i < end; i++) { minB = Vector3.Min(tris[i].MinBound, minB); maxB = Vector3.Max(tris[i].MaxBound, maxB); } // Check For Leaf Node Condition if (end - start <= 1) { return(new BVHNode(minB, maxB, null, null, start, end)); } // Sort On Widest Dimension Vector3 dim = maxB - minB; if (dim.X >= dim.Y && dim.X >= dim.Z) { tris.Sort(start, end - start, F_SORT_X); } else if (dim.Y >= dim.Z) { tris.Sort(start, end - start, F_SORT_Y); } else { tris.Sort(start, end - start, F_SORT_Z); } // Create Children int e = (start + end) / 2; BVHNode leftChild = CreateTree(start, e); BVHNode rightChild = CreateTree(e, end); return(new BVHNode(minB, maxB, leftChild, rightChild, start, end)); }
private bool IntersectHelper(BVHNode node, ref IntersectionRecord outRecord, Ray rayIn) { if (node.IsLeaf) { outRecord.T = float.PositiveInfinity; IntersectionRecord tempRec = new IntersectionRecord(); for (int i = node.surfaceIndexStart; i < node.surfaceIndexEnd; i++) { if (tris[i].Intersect(ref tempRec, rayIn)) { // check if current t value is smaller if (tempRec.T < outRecord.T) { outRecord = tempRec; } } } return(!float.IsPositiveInfinity(outRecord.T)); } else { float t1 = node.lChild.IntersectTime(rayIn); float t2 = node.rChild.IntersectTime(rayIn); if (float.IsNaN(t1)) { if (float.IsNaN(t2)) { return(false); } return(IntersectHelper(node.rChild, ref outRecord, rayIn)); } if (float.IsNaN(t2)) { return(IntersectHelper(node.lChild, ref outRecord, rayIn)); } // Need To Check Both IntersectionRecord lRec = new IntersectionRecord(); IntersectionRecord rRec = new IntersectionRecord(); bool lHit, rHit; lHit = IntersectHelper(node.lChild, ref lRec, rayIn); rHit = IntersectHelper(node.rChild, ref rRec, rayIn); if (lHit && rHit) { outRecord = lRec.T <= rRec.T ? lRec : rRec; } else if (lHit) { outRecord = lRec; } else if (rHit) { outRecord = rRec; } else { return(false); } return(true); } }