Skip to content

Commit 2c2a32a

Browse files
committed
BVH updates
1 parent 81c47ed commit 2c2a32a

File tree

2 files changed

+49
-25
lines changed

2 files changed

+49
-25
lines changed

include/threepp/objects/BVH.hpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,25 @@ namespace threepp {
1717
class BVH {
1818

1919
public:
20+
struct IntersectionResult {
21+
int idxA;
22+
int idxB;
23+
Vector3 position;// Center of intersection region
24+
};
25+
2026
BVH(int maxTrianglesPerNode = 8, int maxSubdivisions = 10)
2127
: maxTrianglesPerNode(maxTrianglesPerNode), maxSubdivisions(maxSubdivisions) {}
2228

2329
void build(const BufferGeometry& geometry);
2430

25-
// Intersect this BVH with another BVH
26-
[[nodiscard]] std::vector<std::pair<int, int>> intersect(const BVH& other) const;
27-
2831
// Helper methods for single-shape intersections
2932
[[nodiscard]] std::vector<int> intersect(const Box3& box) const;
3033

3134
[[nodiscard]] std::vector<int> intersect(const Sphere& sphere) const;
3235

36+
// Intersect this BVH with another BVH
37+
[[nodiscard]] static std::vector<IntersectionResult> intersect(const BVH& b1, const Matrix4& m1, const BVH& b2, const Matrix4& m2);
38+
3339
// Simple true/false intersection test with another BVH
3440
[[nodiscard]] static bool intersects(const BVH& b1, const Matrix4& m1, const BVH& b2, const Matrix4& m2);
3541

@@ -58,7 +64,7 @@ namespace threepp {
5864
std::unique_ptr<BVHNode> buildNode(std::vector<int>& indices, int depth);
5965

6066
// Tests intersection between two BVH nodes
61-
void intersectBVHNodes(const BVHNode* nodeA, const BVHNode* nodeB, std::vector<std::pair<int, int>>& results) const;
67+
static void intersectBVHNodes(const BVH& b1, const BVHNode* nodeA, const Matrix4& m1, const BVH& b2, const BVHNode* nodeB, const Matrix4& m2, std::vector<IntersectionResult>& results);
6268

6369
static void collectBoxes(const BVHNode* node, std::vector<Box3>& boxes);
6470
};

src/threepp/objects/BVH.cpp

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,11 @@ void BVH::build(const BufferGeometry& geom) {
104104
root = buildNode(indices, 0);
105105
}
106106

107-
std::vector<std::pair<int, int>> BVH::intersect(const BVH& other) const {
108-
std::vector<std::pair<int, int>> results;
107+
std::vector<BVH::IntersectionResult> BVH::intersect(const BVH& b1, const Matrix4& m1, const BVH& b2, const Matrix4& m2) {
108+
std::vector<IntersectionResult> results;
109109

110110
// Test intersection between the two BVH trees
111-
intersectBVHNodes(root.get(), other.root.get(), results);
111+
intersectBVHNodes(b1, b1.root.get(), m1, b2, b2.root.get(), m2, results);
112112

113113
return results;
114114
}
@@ -269,11 +269,16 @@ void BVH::collectBoxes(std::vector<Box3>& boxes) const {
269269
collectBoxes(root.get(), boxes);
270270
}
271271

272-
void BVH::intersectBVHNodes(const BVHNode* nodeA, const BVHNode* nodeB, std::vector<std::pair<int, int>>& results) const {
273-
if (!nodeA || !nodeB) return;
272+
void BVH::intersectBVHNodes(const BVH& b1, const BVHNode* nodeA, const Matrix4& m1, const BVH& b2, const BVHNode* nodeB, const Matrix4& m2, std::vector<BVH::IntersectionResult>& results) {
273+
274+
Box3 bb1 = nodeA->boundingBox.clone();
275+
bb1.applyMatrix4(m1);
276+
277+
Box3 bb2 = nodeB->boundingBox.clone();
278+
bb2.applyMatrix4(m2);
274279

275280
// Quick rejection test using bounding boxes
276-
if (!nodeA->boundingBox.intersectsBox(nodeB->boundingBox)) {
281+
if (!bb1.intersectsBox(bb2)) {
277282
return;
278283
}
279284

@@ -287,16 +292,29 @@ void BVH::intersectBVHNodes(const BVHNode* nodeA, const BVHNode* nodeB, std::vec
287292
// For now, using bounding box test as an approximation
288293
Box3 boxA, boxB;
289294
boxA.setFromPoints(std::vector{
290-
triangles[idxA].a(),
291-
triangles[idxA].b(),
292-
triangles[idxA].c()});
295+
b1.triangles[idxA].a(),
296+
b1.triangles[idxA].b(),
297+
b1.triangles[idxA].c()});
293298
boxB.setFromPoints(std::vector{
294-
triangles[idxB].a(),
295-
triangles[idxB].b(),
296-
triangles[idxB].c()});
299+
b2.triangles[idxB].a(),
300+
b2.triangles[idxB].b(),
301+
b2.triangles[idxB].c()});
302+
303+
boxA.applyMatrix4(m1);
304+
boxB.applyMatrix4(m2);
297305

298306
if (boxA.intersectsBox(boxB)) {
299-
results.emplace_back(idxA, idxB);
307+
// Compute intersection box
308+
Box3 intersectionBox;
309+
intersectionBox.set({std::max(boxA.min().x, boxB.min().x),
310+
std::max(boxA.min().y, boxB.min().y),
311+
std::max(boxA.min().z, boxB.min().z)},
312+
{std::min(boxA.max().x, boxB.max().x),
313+
std::min(boxA.max().y, boxB.max().y),
314+
std::min(boxA.max().z, boxB.max().z)});
315+
316+
Vector3 center = (intersectionBox.min() + intersectionBox.max()) * 0.5f;
317+
results.emplace_back(idxA, idxB, center);
300318
}
301319
}
302320
}
@@ -313,22 +331,22 @@ void BVH::intersectBVHNodes(const BVHNode* nodeA, const BVHNode* nodeB, std::vec
313331
if (volumeA < volumeB) {
314332
// A is smaller, descend A
315333
if (nodeA->left && nodeA->right) {
316-
intersectBVHNodes(nodeA->left.get(), nodeB, results);
317-
intersectBVHNodes(nodeA->right.get(), nodeB, results);
334+
intersectBVHNodes(b1, nodeA->left.get(), m1, b2, nodeB, m2, results);
335+
intersectBVHNodes(b1, nodeA->right.get(), m1, b2, nodeB, m2, results);
318336
} else {
319337
// B must have children, descend B
320-
intersectBVHNodes(nodeA, nodeB->left.get(), results);
321-
intersectBVHNodes(nodeA, nodeB->right.get(), results);
338+
intersectBVHNodes(b1, nodeA, m1, b2, nodeB->left.get(), m2, results);
339+
intersectBVHNodes(b1, nodeA, m1, b2, nodeB->right.get(), m2, results);
322340
}
323341
} else {
324342
// B is smaller, descend B
325343
if (nodeB->left && nodeB->right) {
326-
intersectBVHNodes(nodeA, nodeB->left.get(), results);
327-
intersectBVHNodes(nodeA, nodeB->right.get(), results);
344+
intersectBVHNodes(b1, nodeA, m1, b2, nodeB->left.get(), m2, results);
345+
intersectBVHNodes(b1, nodeA, m1, b2, nodeB->right.get(), m2, results);
328346
} else {
329347
// A must have children, descend A
330-
intersectBVHNodes(nodeA->left.get(), nodeB, results);
331-
intersectBVHNodes(nodeA->right.get(), nodeB, results);
348+
intersectBVHNodes(b1, nodeA->left.get(), m1, b2, nodeB, m2, results);
349+
intersectBVHNodes(b1, nodeA->right.get(), m1, b2, nodeB, m2, results);
332350
}
333351
}
334352
}

0 commit comments

Comments
 (0)