// List of BVHPrimitive infos including each triangle of the object // Start/end/total nodes for recursive split of the list private BVHBuildNode BuildRecursiveBVH(ref List <BVHPrimitiveInfo> primitiveInfos, int start, int end, ref int totalNodes) { BVHBuildNode node = new BVHBuildNode(); totalNodes++; Bounds3 bounds = new Bounds3(); bounds.pMin = Vector3.positiveInfinity; bounds.pMax = Vector3.negativeInfinity; // Calculate bounds of the parent BVH node from its children for (int i = start; i < end; i++) { bounds = bounds.Union(primitiveInfos[i].bounds); } int nPrimitives = end - start; // Create leaf if (nPrimitives == 1) { node.InitLeaf(primitiveInfos[start].triangleNo, bounds); return(node); } else { Bounds3 centroidBounds = new Bounds3(); centroidBounds.pMin = Vector3.positiveInfinity; centroidBounds.pMax = Vector3.negativeInfinity; for (int i = start; i < end; i++) { centroidBounds = centroidBounds.Union(primitiveInfos[i].center); } int dim = centroidBounds.MaximumExtend(); int mid = (start + end) / 2; // Order Primitives in axis 'dim' and split the list into 2 equal sized lists EqualCounts(ref primitiveInfos, dim, start, end); node.InitInterior(dim, BuildRecursiveBVH(ref primitiveInfos, start, mid, ref totalNodes), BuildRecursiveBVH(ref primitiveInfos, mid, end, ref totalNodes) ); return(node); } }
public PrimitiveList(IEnumerable <Primitive> primitives) { Primitives = new List <Primitive>(primitives); // Cache the world space bounds if (Primitives.Any()) { worldBounds = Primitives.First().WorldBounds; foreach (var p in Primitives.Skip(1)) { worldBounds = worldBounds.Union(p.WorldBounds); } } }
public void SetTrigles(TrigleFace[] trigles) { this.trigles = trigles; if (trigles != null && trigles.Length > 0) { Bounds3 bounds = trigles[0].BoundBox; foreach (var item in trigles) { bounds = Bounds3.Union(bounds, item.BoundBox); //item.material = _material; } this.BoundBox = bounds; } else { this.BoundBox = new Bounds3(); } CenterPoint = (BoundBox.pMin + BoundBox.pMax) * 0.5f; BVH = BVH.Build(trigles.AsSpan()); }
private BVHBuildNode RecursiveBuild(List <PrimitiveInfo> primitiveInfos, int start, int end, ref int nodeCount, ref List <Primitive> orderedPrimitives) { var node = new BVHBuildNode(); ++nodeCount; // Compute the bounds of all the primitives below this node Bounds3 <float> bounds = new Bounds3 <float>(); for (var i = start; i < end; ++i) { bounds = bounds.Union(primitiveInfos[i].Bounds); } var primitiveCount = end - start; // Create leaf node if (primitiveCount == 1) { var firstPrimitiveOffset = orderedPrimitives.Count(); for (var i = start; i < end; ++i) { orderedPrimitives.Add(allPrimitives[primitiveInfos[i].Index]); } node.InitLeaf(firstPrimitiveOffset, primitiveCount, bounds); } // Create interior node else { // Choose the axis to split (with the longest extent) var centroidBounds = new Bounds3 <float>(); for (var i = start; i < end; ++i) { centroidBounds = centroidBounds.Union(primitiveInfos[i].Centroid); } var dim = centroidBounds.MaximumExtent(); var mid = (start + end) / 2; // Juste create a leaf node if the bounds have zero volume // (all centroids are at the same position) if (centroidBounds.Max[dim] == centroidBounds.Min[dim]) { var firstPrimitiveOffset = orderedPrimitives.Count(); for (var i = start; i < end; ++i) { orderedPrimitives.Add(allPrimitives[primitiveInfos[i].Index]); } node.InitLeaf(firstPrimitiveOffset, primitiveCount, bounds); } else { // Sort primitives in the current range along the split dimension var orderedRange = primitiveInfos .GetRange(start, end - start) .OrderBy(p => p.Centroid[dim]); primitiveInfos = primitiveInfos.GetRange(0, start) .Concat(orderedRange) .Concat(primitiveInfos.GetRange(end, primitiveInfos.Count - end)) .ToList(); // Recursively split the rest of the tree node.InitInterior( dim, RecursiveBuild(primitiveInfos, start, mid, ref nodeCount, ref orderedPrimitives), RecursiveBuild(primitiveInfos, mid, end, ref nodeCount, ref orderedPrimitives)); } } return(node); }