rigs-of-rods
rigs-of-rods copied to clipboard
Interconnecting actor woes
#2973 opens up the nasty topic of connecting actors together at all.
Interconnecting beams
Under the hood, every actor has it's own pool of nodes and beams, and the beam which interconnects actors always belongs to one of them. Until 2014-2015 this was handled by a lot of if()
-s in calcBeams()
which somehow worked but broke with multithreading. Ulteq invested a lot of energy to find a solution and finally added calcBeamsInterActor()
(modified copypaste of calcBeams()
) which processes just the interconnecting beams, and a good deal of code to determine and track which beams are interconnecting. But there are still edge cases IIRC.
Transferring forces
In a physics simulation, position of nodes is calculated (integrated) based on forces and time. Setting the forces directly is prone to break numeric stability. We have multiple means of interconnecting actors (ropes, ties, locks...) and IIRC each works slightly differently and I've definitely seen position being copied from one node to another. This is a hazzard which we must eliminate. The only acceptable way of applying any external force to a node (be it from other actor, or user interface, or script, or anything else) is... well, to apply force.
Multithreading
Presently we do simulation in 2 phases: 1. each actor n/b and intra-collisions are simulated on it's own thread (using thread pool) 2. interconnecting beams and inter-actor collisions are simulated on shared physics thread. This means that if you have just 1 local actor (the common case!), you're using just single CPU core.
I have a solution in mind
Under the hood, merge all actors into one huge, permanently active n/b pool, and keep one extra dummy pool permanently sleeping. Keep the existing N/B logic around for spawning and repair/reset, just do simulation on this common pool. To sleep or wake up, swap the N/B between those. This would ellegantly solve the interconnecting problem as any beam would be technically on the same actor. This would also allow us to replace the threadpool by "symmetric multiprocessing" where the workload is equally split in all available CPU cores.
Related: https://github.com/RigsOfRods/rigs-of-rods/pull/3057 - adding MSG_SIM_ACTOR_LINKING_REQUESTED
fixes a threading hazard, but the performance concerns still apply