Hello Babylon community. I’d like to implement a force directed graph in Babylon similar to d3-force-graph. It needs to be super efficient as we’ll be displaying potentially thousands of nodes (each with image textures).
None of the physics engines in Babylon (Bullet/Oimo/Ammo/Energy?) seem to be geared to this sort of simulation (they are mostly rigid body, whereas d3-force-3d is a Verlet integration with all sorts of optimizations for large simulations) so I’d love to hear if anyone has any good advice:
Questions:
Am I missing something? (ie are Babylon’s physics engines perfectly capable/optimized for this sort of work?)
If yes, should I be looking at WebAssembly via Energy.js to speed things up? (I can’t tell if this is actually ready/useable/integrated or not), or the WASM version of Ammo?
If no, would it be worth trying to implement d3-force-3d (or ngraph, another similar library) as a Babylon physics plugin? (though I’m not sure if they map well to the interface/API that Babylon Exposes)
As an alternate approach, could soft body dynamics in Ammo be a relevant option to achieve something like this (ie. forces between particles)?
And a separate (but still related) question - should I be using SolidParticleSystem for drawing thousands of meshes with image textures once the physics part is figured out? (or is this unnecessary?)
Sorry I know that’s a lot of interconnected questions but any words of wisdom very much appreciated! Maybe someone out there has solved similar problems.
Thanks !
Babylon is just a visualization engine, if you have physic apis you want to use just spin up the physics system of your choice then have BJs handle the graphics.
You are totally right! We mostly deal with rigid body engines for physics simulations. Ammo does have soft-body support, but this is not exactly what you are looking for. I believe @Cedric will be able to provide a better answer about soft bodies though.
Yes and no. I can only assume the architecture of the physics engine (aimed towards “classical” physics engines with impostors/joints/impulses etc’) will not allow you to use the full potential of d3 or ngraph, and that most functions in the physics plugin will stay unimplemented. Link might be seen as a joint, but there is only one type (a sort of point-to-point), there is a way to provide force as well. You know d3 much better - if you think it fits this type of architecture, there is no reason why it wouldn’t work as a limited physics plugin.
If you don’t think it fits in - a physics engine runs alongside babylon.js bidirectional - Babylon creates the object to create an impostor for, notifies the physics engine, provides its position (on each frame) and get the new position from the physics simulation. In your specific case you could achieve this “manually” by running the update function of d3 before babylon’s render loop. It’s all a question of how you want to use babylon.
If you want to use it exclusively and have d3 integrated in the background (physics-plugin style), you will need to implement the needed functions on top of a babylon particle (the link function, for example). You will need to attach to Babylon’s observables (pre/post render) to keep the bodies aligned with the d3 simulation. This would be the cleanest solution, and would even allow you to offer that as a babylon plugin. It abstracts d3.
But if you want to use Babylon as a rendering engine only (the easier and quicker solution) you will need to run the simulation on your own using d3 code, get the information on each frame, and update the babylon scene accordingly. You can add that to a scene observable (pre-render) or simply run it prior to calling scene.render() when running the render loop.
Thanks for the detailed response @RaananW and others, this is super helpful.
It sounds like the right thing for me to do is first validate that d3 will give me what I need in terms of performance (ie. use it off the shelf, with Three integration for now) and then if that works I can come back to Babylon and explore one of the two integration options you suggested.
Really appreciate you all taking the time to help!
I realize that this is a really old thread, but it’s the top Google hit for “babylonjs 3d force graph”. Should anyone come across this in the future, here is a Gist that is a simple demo of how to create a 3D force-directed graph in babylon.js: