Repository: godot
Issue: GodotPhysics performance when interacting with servers directly
Labels: discussion,topic:physics

I've been working on a prototype bullet-hell type game in Godot lately, and I've been trying to optimize as much as I can to get the most bullets on screen as possible.  To that end, I've taken some inspiration from this blog post which describes a method of interacting with the physics server directly to create many shapes in a single/minimal amount of areas, to avoid the overhead of nodes: https://worldeater-dev.itch.io/bittersweet-birthday/devlog/210789/howto-drawing-a-metric-ton-of-bullets-in-godot

I'm using this setup basically, except my prototype is in 3D  so I'm using a multimesh for the visual side of things, and I've made a few improvements along the way, such as not calling `free_rid()` multiple times per frame.

Anyway, I'm creating this issue mainly because it was requested by @pouleyKetchoupp I share my results here in hopes that there could be further optimizations for my use case.  I've tested using both Bullet and GodotPhysics engines, in 2D and 3D, and using the new BVH option in the latest beta.

My results below represent the highest number of bullets I was able to handle on my machine and still maintain a solid 60fps.  I'm also not running these on anything too powerful, it's a Lenovo T480s with an Intel i7-8650u with integrated graphics.

```
Godot version: 3.2.3-stable
Use 3d Server: true
Physics Engine: Bullet
Count: 10
Wave Time: 0.3
Active Shapes: 200

Top bottlenecks:
    BulletPhysicsManager._update_bullets()

Notes:
    Definitely the slowest of the bunch, and it drops off real hard when 
    just jumping from 10 to 11 for the count.


Godot version: 3.2.3-stable
Use 3d Server: true
Physics Engine: GodotPhysics (3D)
Count: 48
Wave Time: 0.1
Active Shapes: 2880

Top bottlenecks:
    BulletPhysicsManager._update_bullets()
    BulletPhysicsManager._destroy_bullet()

Notes:
    Removing shapes from an area (in _destroy_bullet()) seems to be slower 
    in GodotPhysics, but I believe this is just because it can handle so 
    many more shapes before this becomes an issue.


Godot version: 3.2.3-stable
Use 3d Server: false
Physics Engine: GodotPhysics (2D)
Count: 41
Wave Time: 0.1
Active Shapes: 2460

Top bottlenecks:
    BulletPhysicsManager._update_bullets()
    BulletPhysicsManager._destroy_bullet()
    Util.transform_to_2d_xz()

Notes:
    This is surprisingly slower than GodotPhysics 3D, and that appears to 
    be at least in small part due to my need to translate the transform 
    to 2D on the XZ plane.


Godot version: 3.2.4-beta6
Use 3d Server: true
Physics Engine: GodotPhysics (3D, Use BVH=true)
Count: 39
Wave Time: 0.1
Active Shapes: 2340

Top bottlenecks:
    BulletPhysicsManager._update_bullets()
    BulletPhysicsManager._destroy_bullet()

Notes:
    The other configurations on 3.2.4-beta6 are almost the same, but this 
    new option of using BVH is something I thought might improve things, 
    but it actually slows them down a bit, bringing it to be almost 
    tied with 2D.
```

The project I am using is available here: [bullet-physics-tests.zip](https://github.com/godotengine/godot/files/5854036/bullet-physics-tests.zip)

You can modify the "use 3d server" setting on the p_BulletPhysicsServer scene, "count" and "wave time" are both on the BulletCircleSpawner node in the Main scene, and if needed you can increase the number of visible instance for the multimesh in the BulletVisualManager scene's `init()` method.