godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Add an option for faster Area3D/Area2D enter/exit checks using AABBs only #2714

Open pouleyKetchoupp opened 3 years ago

pouleyKetchoupp commented 3 years ago

Describe the project you are working on

Godot Physics 3D/2D

Describe the problem or limitation you are having in your project

Area overlap tests can be expensive with many rigid bodies involved, especially with shapes like ConvexPolygonShape and ConcavePolygonShape.

The physics engine doesn't currently allow a less expensive alternative for detecting rigid bodies entering and exiting a large area.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Areas can have a new option to work with bounding boxes only, so the detailed collision phase is skipped entirely, which makes them much faster.

Area parameter in PhysicsServer3D/PhysicsServer2D:

AREA_PARAM_BROADPHASE_ONLY = 8

Constant to set/get whether the area uses broadphase-only collision detection.

This option allows much faster collision detection at the expense of accuracy,
since AABBs are used instead of the exact shapes for both the area and the other object.

Usage:
PhysicsServer.area_set_param(area_id, PhysicsServer.AREA_PARAM_BROADPHASE_ONLY, true)

Property in Area3D/Area2D:

bool broadphase_only [default: false]
set_broadphase_only(value) setter
is_broadphase_only() getter

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Feature branch on 3.x (no PR yet): https://github.com/nekomatata/godot/commit/46697942d48a1cdde2c806831834b9e6951b5a90

If this enhancement will not be used often, can it be worked around with a few lines of script?

This enhancement is trivial in the engine and can make things easier for users, while the alternative in the editor requires a lot of manual work.

Is there a reason why this should be core and not an add-on in the asset library?

It has to be part of the internal physics engine, where area collision detection takes place.

akien-mga commented 3 years ago

I think that's an interesting idea, provided that it fulfills valid use cases where rough collision enter/exit detection is sufficient. Do you have some examples in mind that could benefit from this performance-wise without compromising with gameplay? I imagine it could be useful for audio bus and gravity overrides at least.

nonunknown commented 3 years ago

yeah @akien-mga it will be useful for example for chunks detection for manually disable/enable huge areas of the game, like I'm doing in my current project!

pouleyKetchoupp commented 3 years ago

Yeah I think it can be generally useful for large areas that are used to detect many objects for gravity/damping/audio overrides or other custom behavior, like water surface or world limits.

TokisanGames commented 3 years ago

That mode should also check if the shape is a sphere, and do a distance check against the radius instead of AABB, which will be faster and more accurate.

And maybe use sdfs for capsules and cylinders. The current implementation of cylinder areas is dog slow and kills game performance for large areas. But the sdf is pretty simple. https://iquilezles.org/www/articles/distfunctions/distfunctions.htm

Janders1800 commented 3 years ago

As long as it is optional.

pouleyKetchoupp commented 3 years ago

@tinmanjuggernaut

That mode should also check if the shape is a sphere, and do a distance check against the radius instead of AABB, which will be faster and more accurate.

The idea is to keep things very simple, so I'd like to avoid specific cases for different shapes. Working just with AABB also allows extra optimizations in the future because it's tightly linked to the way the broadphase works. Doing too many different things now could block these optimizations because of compatibility breaking.

So for now, I prefer to propose a unique option based on AABB, and for more accuracy you can still use the default system.

And maybe use sdfs for capsules and cylinders. The current implementation of cylinder areas is dog slow and kills game performance for large areas. But the sdf is pretty simple. https://iquilezles.org/www/articles/distfunctions/distfunctions.htm

I agree some shapes could use specific optimizations, especially convex hulls and cylinders. That will be part of improving the general collision detection system, but it's not part of this proposal.

AndreaCatania commented 3 years ago

This is a great idea! I was thinking that not all people knows about Broad-phase and Narrow-phase in physics engines but also it's difficult to visualize the bounding box of a shape: so it may be difficult to really use it.

To fix this issue, instead to add this feature in the form on a parameter, what do you think about adding an AABB shape?

This shape is a box with the axis always relative to the global axis, exactly like the bouding box (AABB) used by the broadphase.

Under the hood, you can just skip the narrow-phase for this shape, and in editor for the user is obvious see how the shape will behave so will be much simpler use it in a level.

AABB shape, is probably a bad name though, I guess we can find a better one.

pouleyKetchoupp commented 3 years ago

To fix this issue, instead to add this feature in the form on a parameter, what do you think about adding an AABB shape?

That makes a lot of sense. I agree it would make things clearer and easier to setup in the editor.

Some thoughts around this idea:

pouleyKetchoupp commented 3 years ago

@AndreaCatania On second thought, I wonder if adding a new shape type is a bit overkill for this feature, and as an alternative, we could solve the problem of visualization by just making the area show the bounding box in both the editor and game when this option is checked, instead of the actual collision shape.

This way, it's still easy to setup for the user (just a checkbox), requires less changes in the engine and there can be no confusion with the fact a shape would influence a physics object behavior.

AndreaCatania commented 3 years ago

It may be a bit strange add a sphere, or another shape, and then use only an AABB. Apart that however, it should work, so if you feel like it's better ok to me, it will also solve the issue.