Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Box2d raycast vs AABB query performance

I'm currently trying to improve performance of a game that makes use of box2d physics (actually box2dlights).

I have a method that makes several (let's say about 16 to 64) raycasts within an known area. I wonder if it would be a good idea to make an AABB query of that area in a first step to check if there is something the raycasts could report. If not, I can skip the raycasts. But if the AABB query finds something I have to make the raycasts and the query was redundant. How fast is an AABB query comparing to a raycast (especially in box2d)? Is it a good idea to make an often superfluous AABB query if I can skip some raycasts in turn?

like image 909
Sebastian Avatar asked Oct 31 '22 18:10

Sebastian


1 Answers

You really should determine at least in a back-of-the-envelope way whether you're really in need of adding an AABB test phase.

It sounds like you're actually using raycasts for lighting purposes. It really does stand to reason that if this is the case, most of the time your raycasts will actually intersect. You will probably have an outer boundary on your environment. This means that most likely an AABB test that you implement in such an environment will intersect most of the time if not all the time.

Furthermore, also working off of the assumption that the raycasts are performed in a radial fashion for 2D lighting purposes, an AABB of a rays starting from a central location is somewhat degenerate in the sense that each ray (the ray being infinite in length) will result in one of 4 possible AABB's:

x=0, y=0, x -> infinity  y -> infinity
x=0, y=0, x -> infinity  y -> -infinity
x=0, y=0, x -> -infinity y -> infinity
x=0, y=0, x -> -infinity y -> -infinity

It would be rather a waste of time if you raycast e.g. 64 radially equidistant rays and naively perform 64 AABB checks (one for each raycast), as for example all of the 16 rays with positive x and positive y direction will resolve into the same AABB check (the first one listed above).

You could do something like always perform those 4 AABB checks and if one of them does not intersect anything, then you can skip 16 raycasts. But this will only happen if you go all the way to the edge of an environment.

An AABB isn't terrifically suited for speeding up raycasts because only the rays that are close to being aligned with an axis would be well-modeled by an AABB (axis aligned bounding box).


An alternative thought process also exists that can show you that an AABB test isn't likely to be helpful.

The purpose of using Box2D to perform raycasts is because that library provides sophisticated mechanisms to accelerate the raycasts for you. See from iforce2d's World Querying:

Box2D provides two tools for [world querying] - ray casting and AABB testing. Ray casting... didn't we just do that? Yes, we did it the manual way, by looping through every fixture in the world and checking the ray against them all to find out which one was the closest. This can be very inefficient when you have a large number of fixtures in the scene. A better way is to use the RayCast function of the world itself. This allows the engine to focus on fixtures which it knows are near the ray's path.

This library will use its built-in spatial representation of the world with its built-in acceleration structures to figure out for you which bodies a particular ray will intersect with. This is actually box2dlights' own raison d'etre.

Because of this, there is no purpose to using AABB's (the other type of world query that Box2D offers) to try to augment it. If indeed that was a sensible thing to do, then Box2D would already do that for you under the hood in the raycast function.

like image 169
Steven Lu Avatar answered Nov 29 '22 12:11

Steven Lu