ITADN

Ray-Bbox collision not working (too few collisions)

#109ClosedKatharsas 创建于 2026-01-13
question
K
Katharsascommented
I am currently using an Octree in my [Renderer](https://github.com/Katharsas/ZenRen) and wanted to evaluate using this BVH library instead to check if i can get better performance. So i have rewritten my ground face search. I want to only intersect the aabbs of my triangles, not the triangles themselves. So like suggested in https://github.com/madmann91/bvh/issues/90 I am using `traverse_top_down` and then using `DirectXMath` to do the ray-bbox intersections for me: ```cpp using BvhVec3 = bvh::v2::Vec<float, 3>; using BvhBBox = bvh::v2::BBox<float, 3>; using BvhNode = bvh::v2::Node<float, 3>; using Bvh = bvh::v2::Bvh<BvhNode>; struct VertLookupTree { Bvh bvh; std::vector<DirectX::BoundingBox> bboxes; std::vector<render::VertKey> treeIndexToVert; }; BvhBBox createBbox(const array<VertexPos, 3>& verts) { float minX = FLT_MAX, minY = FLT_MAX, minZ = FLT_MAX; float maxX = -FLT_MAX, maxY = -FLT_MAX, maxZ = -FLT_MAX; for (uint32_t i = 0; i < 3; i++) { auto& vert = verts[i]; minX = std::min(minX, vert.x); minY = std::min(minY, vert.y); minZ = std::min(minZ, vert.z); maxX = std::max(maxX, vert.x); maxY = std::max(maxY, vert.y); maxZ = std::max(maxZ, vert.z); } return BvhBBox { {minX, minY, minZ}, { maxX, maxY, maxZ } }; } DirectX::BoundingBox toBboxDx(BvhBBox bbox) { auto center = (bbox.max + bbox.min) * 0.5f; auto extents = (bbox.max - bbox.min) * 0.5f; return DirectX::BoundingBox({ center[0], center[1], center[2] }, { extents[0], extents[1], extents[2] }); } BvhVec3 createTriCenter(const array<VertexPos, 3>& verts) { Vec3 center = mul(add(add(verts[0], verts[1]), verts[2]), 1.f / 3.f); return BvhVec3 { center.x , center.y, center.z }; } bvh::v2::ThreadPool thread_pool; bvh::v2::ParallelExecutor executor(thread_pool); VertLookupTree createVertLookup(const MatToChunksToVertsBasic& meshData) { VertLookupTree result; std::vector<BvhBBox> bboxes; std::vector<BvhVec3> centers; forEachFace(meshData, [&](const VertKey& vertKey) -> void { auto tri = vertKey.getPos(meshData); centers.push_back(createTriCenter(tri)); // TODO should i use center of bbox or center of tri here?? auto bbox = createBbox(tri); bboxes.push_back(bbox); result.bboxes.push_back(toBboxDx(bbox)); result.treeIndexToVert.push_back(vertKey); }); typename bvh::v2::DefaultBuilder<BvhNode>::Config config; config.quality = bvh::v2::DefaultBuilder<BvhNode>::Quality::High; result.bvh = bvh::v2::DefaultBuilder<BvhNode>::build(thread_pool, bboxes, centers, config); return result; } vector<VertKey> rayIntersected(const VertLookupTree& lookup, BvhVec3 rayOrigin, BvhVec3 rayDir, float rayMaxLength) { const DirectX::XMVECTOR rayOriginXm = toXM4Pos(Vec3{ rayOrigin[0], rayOrigin[1], rayOrigin[2] }); const DirectX::XMVECTOR rayDirXm = toXM4Dir(Vec3{ rayDir[0], rayDir[1], rayDir[2] }); vector<VertKey> result; bvh::v2::SmallStack<Bvh::Index, 64> stack; lookup.bvh.traverse_top_down<false>(lookup.bvh.get_root().index, stack, [&](size_t begin, size_t end) { for (size_t i = begin; i < end; ++i) { DirectX::BoundingBox bbox = lookup.bboxes.at(i); float dist; bool intersect = bbox.Intersects(rayOriginXm, rayDirXm, dist) && dist < rayMaxLength; if (intersect) { result.push_back(lookup.treeIndexToVert.at(i)); } } return true; }, [&](const BvhNode& left, const BvhNode& right) { float dist; bool hit_left = toBboxDx(left.get_bbox()).Intersects(rayOriginXm, rayDirXm, dist) && dist < rayMaxLength; bool hit_right = toBboxDx(right.get_bbox()).Intersects(rayOriginXm, rayDirXm, dist) && dist < rayMaxLength; bool should_swap = false; return std::make_tuple(hit_left, hit_right, should_swap); } ); return result; } ``` I have checked to make sure i am generating bvh centers, bvh bboxes, and DirectXMath bboxes correctly. However i barely get any collisions. I have tried for several ours to find any problems but not found anything. But i must be using the library wrong somewhere. Total number of bbox collisions for all 9120 rays: - brute force (just looping over every triangle's bbox for every ray): 47164 - octree: 47656 - bvh: 6 Maybe i am completely misunderstanding what `(size_t begin, size_t end)` is. I assume they are indices corresponding to the bbox/center arrays that were passed to create the bvh.
关闭于 2026-01-13 1 条评论