private void Subdivide(BVHNode[] leafs, int leafCount, int addNext) { if (leafCount == 1) { _nodes[addNext] = leafs.First(); return; } var bounds = leafs.Aggregate(Nothing, (cur, n) => BoundingBox.Merge(cur, n.Bounds)); var comparer = new AxisBVHNodeComparer(bounds.Maximum - bounds.Minimum); Array.Sort(leafs, comparer); _nodes[addNext++] = BVHNode.CreateBranch(ChildCountFor(leafCount), ref bounds); var leftCount = leafCount / 2; var rightCount = leafCount - leftCount; if (leafCount >= MinimumLeafCountForParallelism) { Parallel.Invoke(_parallelOptions, () => Subdivide(leafs.Take(leftCount).ToArray(), leftCount, addNext), () => Subdivide(leafs.Skip(leftCount).ToArray(), rightCount, addNext + ChildCountFor(leftCount))); } else { Subdivide(leafs.Take(leftCount).ToArray(), leftCount, addNext); Subdivide(leafs.Skip(leftCount).ToArray(), rightCount, addNext + ChildCountFor(leftCount)); } }
private static BVHNode[] ReduceToBVHNodes(IEnumerable <SceneObject> scene) { return(scene .SelectMany(s => s.Geometry.Triangles .Select((t, i) => { var bounds = t.BoundsIn(s.Geometry.Vertices); return BVHNode.CreateLeaf(s, i, ref bounds); })) .ToArray()); }