124 const double bestDistSqr = best.distance * best.distance;
126 const Node* left = node + 1;
127 const Node* right = &m_nodes[node->child];
133 Vector<double, N> closestLeft = left->bound.Clamp(pt);
134 Vector<double, N> closestRight = right->bound.Clamp(pt);
139 const bool shouldVisitLeft = distMinLeftSqr < bestDistSqr;
140 const bool shouldVisitRight = distMinRightSqr < bestDistSqr;
142 if (shouldVisitLeft && shouldVisitRight)
144 const Node* secondChild;
145 const Node* firstChild;
147 if (distMinLeftSqr < distMinRightSqr)
159 todo[todoPos] = secondChild;
163 else if (shouldVisitLeft)
167 else if (shouldVisitRight)
177 node = todo[todoPos];
190template <
typename T,
size_t N>
194 if (!m_bound.Overlaps(
box))
207 while (
node !=
nullptr)
231 const Node* firstChild =
node + 1;
235 if (!firstChild->bound.Overlaps(
box))
256template <
typename T,
size_t N>
260 if (!m_bound.Intersects(
ray))
273 while (
node !=
nullptr)
297 const Node* firstChild;
300 if (
ray.direction[
node->flags] > 0.0)
302 firstChild =
node + 1;
307 firstChild =
const_cast<Node*
>(&m_nodes[
node->child]);
312 if (!firstChild->bound.Intersects(
ray))
333template <
typename T,
size_t N>
339 if (!m_bound.Overlaps(
box))
352 while (
node !=
nullptr)
376 const Node* firstChild =
node + 1;
380 if (!firstChild->bound.Overlaps(
box))
399template <
typename T,
size_t N>
404 if (!m_bound.Intersects(
ray))
417 while (
node !=
nullptr)
441 const Node* firstChild;
444 if (
ray.direction[
node->flags] > 0.0)
446 firstChild =
node + 1;
451 firstChild =
const_cast<Node*
>(&m_nodes[
node->child]);
456 if (!firstChild->bound.Intersects(
ray))
475template <
typename T,
size_t N>
481 best.distance = std::numeric_limits<double>::max();
484 if (!m_bound.Intersects(
ray))
497 while (
node !=
nullptr)
523 const Node* firstChild;
526 if (
ray.direction[
node->flags] > 0.0)
528 firstChild =
node + 1;
533 firstChild =
const_cast<Node*
>(&m_nodes[
node->child]);
538 if (!firstChild->bound.Intersects(
ray))
559template <
typename T,
size_t N>
565template <
typename T,
size_t N>
568 return m_items.
begin();
571template <
typename T,
size_t N>
574 return m_items.
end();
577template <
typename T,
size_t N>
580 return m_items.
begin();
583template <
typename T,
size_t N>
586 return m_items.
end();
589template <
typename T,
size_t N>
592 return m_items.Length();
595template <
typename T,
size_t N>
601template <
typename T,
size_t N>
604 return m_nodes.Length();
607template <
typename T,
size_t N>
612 return std::make_pair(std::numeric_limits<size_t>::max(),
613 std::numeric_limits<size_t>::max());
616 return std::make_pair(i + 1, m_nodes[i].child);
619template <
typename T,
size_t N>
622 return m_nodes[i].
IsLeaf();
625template <
typename T,
size_t N>
628 return m_nodes[i].bound;
631template <
typename T,
size_t N>
636 return m_nodes[i].item + begin();
642template <
typename T,
size_t N>
647 return m_nodes[i].item + begin();
653template <
typename T,
size_t N>
658 m_nodes.Append(Node{});
663 m_nodes[nodeIndex].InitLeaf(itemIndices[0],
664 m_itemBounds[itemIndices[0]]);
665 return currentDepth + 1;
669 BoundingBox<double, N> nodeBound;
670 for (
size_t i = 0; i < nItems; ++i)
672 nodeBound.Merge(m_itemBounds[itemIndices[i]]);
675 Vector<double, N> d = nodeBound.upperCorner - nodeBound.lowerCorner;
678 auto axis =
static_cast<uint8_t
>(d.DominantAxis());
681 0.5 * (nodeBound.upperCorner[axis] + nodeBound.lowerCorner[axis]);
684 const size_t midPoint = QSplit(itemIndices, nItems, pivot, axis);
688 Build(nodeIndex + 1, itemIndices, midPoint, currentDepth + 1);
689 m_nodes[nodeIndex].InitInternal(axis, m_nodes.Length(), nodeBound);
690 const size_t d1 = Build(m_nodes[nodeIndex].child, itemIndices + midPoint,
691 nItems - midPoint, currentDepth + 1);
693 return std::max(d0, d1);
696template <
typename T,
size_t N>
697size_t BVH<T, N>::QSplit(
size_t* itemIndices,
size_t numItems,
double pivot,
702 for (
size_t i = 0; i < numItems; ++i)
704 BoundingBox<double, N> b = m_itemBounds[itemIndices[i]];
706 if (
const double centroid =
707 0.5f * (b.lowerCorner[axis] + b.upperCorner[axis]);
710 std::swap(itemIndices[i], itemIndices[ret]);
715 if (ret == 0 || ret == numItems)