1

I've recently started looking into BSPs for real-time collision detection, and I'm now looking into improving the performance of my solution.

The system that I've implemented is rather similar to the solution found on wikipedia (https://en.wikipedia.org/wiki/Binary_space_partitioning), where each node contains triangles found located on the node's hyperplane, and references to two nodes found on each side of the hyperplane.

BSP generation pseudocode:

Node generate_bsp(Trimesh mesh)
Trimesh back, front
Node node(mesh[0]) // Generates the plane position and normal of the node
loop (Triangle tri : mesh)
   if (onPlane(tri, node))
      node.triangles.add(tri)
   else if (inFront(tri, node))
      front.add(tri)
   else if (Behind(tri, node))
      back.add(tri)
   // Not fully in front or behind means that the triangle is found on both sides
   // and needs to be split
   else
      Triangle[] trisSplit = tri.split(node)
      loop (tri2 : trisSplit)
         if (inFront(tri2, node))
            front.add(tri)
         else if (Behind(tri2, node))
            back.add(tri)

node.nodeBack = generate_bsp(back)
node.nodeFront = generate_bsp(front)

return node

This means that for a raycast, I iterate over the hyperplanes sorted from front to back, and determine if my ray hits any of the triangles found on each hyperplane.

BSP raycast pseudocode:

Bool ray_intersect_bsp(Vector rayPos, Vector rayDir, Node* BSP)
if (BSP == null)
   return false

if (onPlane(rayPos, node))
   if (ray_intersect_triangles(rayPos, rayDir, BSP->triangles))
      return true
   if (ray_intersect_bsp(rayPos, rayDir, BSP->nodeFront))
      return true
   if (ray_intersect_bsp(rayPos, rayDir, BSP->nodeBack))
      return true
else if (inFront(rayPos, node))
   if (ray_intersect_bsp(rayPos, rayDir, BSP->nodeFront))
      return true
   if (ray_intersect_triangles(rayPos, rayDir, BSP->triangles))
      return true
   if (ray_intersect_bsp(rayPos, rayDir, BSP->nodeBack))
      return true
else
   if (ray_intersect_bsp(rayPos, rayDir, BSP->nodeBack))
      return true
   if (ray_intersect_triangles(rayPos, rayDir, BSP->triangles))
      return true
   if (ray_intersect_bsp(rayPos, rayDir, BSP->nodeFront))
      return true

return false

This system however demands using ray-triangle intersection determination, which is a costly procedure. What makes matters worse is that there's a high chance that the triangles you iterate on are missed by the ray, which results in a relatively large amount of costly raycasts that need to be performed before finding the closest hit on the trimesh.

What methods can I use to optimize my BSP structure and traversal?

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
Lolslayer
  • 63
  • 8
  • Hello Patrick, thanks for commenting on my question. I can't provide more information regarding my current implementation than I've already given, because doing so would require me to make the post bloated with information. But if you think that it's a wise decision, I can change my request of finding sources regarding the information I want to find, into a request on an explenation how such a BSP tree is generated. – Lolslayer Apr 28 '20 at 21:04
  • That might technically be on-topic, but what you're suggesting is a form of an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). By focusing on your attempted solution, you're arbitrarily restricting answers from suggesting alternate approaches you may have not considered for achieving your required performance goal. By providing your current implementation, you can help others avoid reinventing what you've already done, as well as open the question to accepting other valid approaches. – Patrick Roberts Apr 28 '20 at 21:07
  • 1
    I've rewritten my question according to the XY problem and provided pseucode that describes the overall idea behind the current implementation (there are some optimizations I've done that are not described here with choosing a more optimal triangle to form the base of each node, and discard intersections that are certain to be missed) – Lolslayer Apr 28 '20 at 21:45
  • I think your updated question looks good and I've retracted my close vote. Hopefully someone more knowledgable with this algorithm will be able to find your question now. If not, when your question becomes eligible for bounty in a few days and you still haven't received an answer, feel free to ping me in a comment here and I can add a bounty for you. – Patrick Roberts Apr 28 '20 at 21:58
  • Thank you very much, and thanks for offering the bounty, let's hope that that won't be necessary. – Lolslayer Apr 28 '20 at 22:45

0 Answers0