I unfortunately don’t have anything to add as far as a real suggestion or solution, but I thought I’d chime in since I’ve been working on a prototype to demo pretty much the same thing (but failing miserably). My approach has been a bit different, in that I’ve been trying to model multiple frames of reference as a hierarchy of PhysX scenes. I’m trying to do it this way primarily since I want to ensure PhysX dynamics go to sleep if they are stable within their local frame of reference. It would also allow me to do some really cool stuff with scene-wide forces.
I have an example world in my head that fleshes out similar to your diagram. Consider the following initial physics scene/frame of reference hierarchy:
Space
+-Planet
| +-Space ship
+-Space station
The space scene is by definition (since it’s the root scene) static, covers the entire global coordinate extent and in this case would have no scene-wide forces. For simplicity, the planet scene is stationary within space and centered on a sphere, with a scene-wide radial gravity that applies an acceleration toward’s it’s local origin to all child actors and scenes within its bounds. The space ship scene includes the interior of a space ship and, while not moving locally, on its own has no scene-wide force. Finally, the space station scene is a rotating ring with artificial gravity created by centripetal force (think the movie Elysium). Again for simplicity, the center of the space station scene can be considered stationary within space.
The way I envision this working in real time is that initially everything in the world is sleeping physics-wise. The space ship scene is stationary on the surface of the planet. There is a character sitting in the space ship experiencing that scene’s forces, which is the accumulation of forces inherited down from the root, including those related to the forces each scene experiences within it’s parent frame of reference. At this point, that means the character experiences only gravity. The space ship takes off and begins to fly away, which changes the scene-wide force experienced by the character, since now it includes gravity plus the opposite of the acceleration vector of the space ship within the planet scene.
Eventually, the space ship passes out of the bounds of the planet scene, at which point it transitions into the root space scene. As it flies through space toward the space station, the scene-wide force experienced within the space ship scene is only that related to the space ship’s acceleration within the root frame of reference. When the space ship approaches the space station, it transitions into the space station scene. Since the space station scene is rotating, the space ship’s local velocity and acceleration change to offset the new scene-wide forces that apply to it. As the space ship flies in a way to match the rotation of the “surface” (inner side facing the center) of the space station, the local velocity and acceleration of the space ship approach zero. Eventually it is stationary within the space station scene, as it lands on the surface. The character in the space ship is now experiencing the centripetal force inherited by the space ship scene. The character leaves the space ship, transitioning into the space station scene. Since the space ship scene was stationary/asleep within the space station scene, the character’s local velocity and acceleration are unchanged. The character then throws a ball up in the air, which rises and falls based on the scene-wide centripetal force applying to the space station scene. The ball comes to rest and goes to sleep, despite it’s constantly changing global velocity and acceleration.
I know this sounds extremely ambitious, but I think the hard part is really modifying the existing physics “middleware” in the engine, as opposed to the from-scratch coding that’s needed to implement this on top of PhysX. With some simplifying assumptions regarding how to deal with actors and movable child scenes that cross over scene boundaries, each scene within the hierarchy could really be considered independently. Since this would allow the greatest opportunity for dynamics to fall to sleep, hypothetically this means it could be more efficient (not to mention the actor partitioning should reduce the number of overlap tests needed).
All that said, my problem has been that the use of a single PhysX scene (setting aside the async and cloth scenes) is highly embedded in the core of the engine code. So far it’s been a frustrating/confusing attempt. All I’ve managed to do is stick with a single scene with a sphere that applies radial gravity to a handful of cubes that start off floating above it’s surface. They all fall to the surface and eventually fall to sleep (I had to bypass FPhysScene::AddForce and directly call physx::PxRigidDynamic::addForce to do that). Then I can “hit” the sphere in a direction, which causes the cubes to dislocate but follow the sphere, with it all eventually falling to sleep again.
I’m pretty stuck trying to introduce the PhysX scene hierarchy I need. And at this point I think I’m going to step back and implement a prototype directly on top of PhysX. Then, once I have that working, I’ll reattempt reworking the core engine code to handle a hierarchy of scenes.
I also welcome any comments (even if telling me to stop wasting my time on this) and/or references to any similar prior notes or work. I’ll let you know if I make any progress on the above or with one of the methods you mention.
Sorry for the long post. (I cut myself off from going into details on the cool stuff that this would hypothetically allow me to do, like having a meteor hit the space station, with it’s resulting motion applied down into it’s interior scene…)