Is it possible to completely override rigidbody physics while using multiple threads to apply new data?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Wrothmonk

I’m working on a game where one of the main mechanics is going to revolve around manipulating time, reversing it, manipulating multiple interacting timelines, etc. One of the main things that facilitates all this is a system of recording and playing back data on various types of nodes.

Now it seems that I can use multiple threads to record data on RigidBodies without issue, but if I try to multithread re-applying those states (while disabling physics as much as I can), things get a bit Weird.

I frankly don’t see any reason why I can’t achieve this somehow, given I want to completely ignore all physics while ‘rewinding’ these objects, and all the data interaction for each thread is entirely self contained as far as I’m aware.

I’ve tried having the rigidbodies sleep, set their modes to static or kinematic before moving them, and setting them to have custom integrators. None of it seems to stop something from attempting to take control of the rigidbody and messing things up.

You can find all my project code/data at this github page if you want to see exactly what I’m trying to do. It’s currently set up in a ‘working’ state with the multithreaded re-application of states commented out, and just replaced with a single-threaded version.

Have considered using the _integrate_forces method?

https://docs.godotengine.org/en/stable/classes/class_rigidbody.html#class-rigidbody-method-integrate-forces

klaas | 2020-07-20 19:44

I looked into that a bit, and it seems promising, but I can’t find a way to get the PhysicsDirectBodyState for the relevant RigidBody? I specifically need a way to get it for a script that’s on a child node.

Having to extend RigidBody just to be constantly storing it as a variable seems both inefficient and annoying to implement for every possible case.

Wrothmonk | 2020-07-20 23:43

At this point I’ve tried several different methods of messing with the physics engine, none of them have proved satisfactory, and several of them flat out do not work. I am now making the assumption that there simply is no way to decouple the physics engine from rigidbodies even temporarily that doesn’t present more of an overhead than is to be reclaimed by mutlithreading.

Wrothmonk | 2020-07-21 10:08

When you want to rewind time and want the switch physics processsing off while rewinding

isnt that …

PhysicsServer.set_active(false)

https://docs.godotengine.org/en/stable/classes/class_physicsserver.html#class-physicsserver-method-set-active

klaas | 2020-07-21 18:44

I don’t want to turn off the entire physics engine, just disconnect any interaction with a specific set of objects.

Wrothmonk | 2020-07-22 13:16

have you tried something like this

I have created a new space which then is inactive by default. Assigning object to this space removes them from the default space. Physics is then off only for them.

extends RigidBody

var org_space
var alt_space

func _ready():
	org_space = PhysicsServer.body_get_space(get_rid())
	alt_space = PhysicsServer.space_create()

func _input(event):
	if event.is_action_pressed("ui_left",true):
		PhysicsServer.body_set_space(get_rid(),alt_space)

	if event.is_action_pressed("ui_right",true):
		PhysicsServer.body_set_space(get_rid(),org_space)

klaas | 2020-07-22 23:45

I’m not quite sure I understand what these ‘spaces’ are, but what I do understand has me thinking this should work. However after implementing it and turning multi-threaded processing back on for physics objects, I still get the same weird physics abnormalities after reversing time.

In fact on a whim I tried turning off the physics engine entirely during time travel, and I still got those same abnormalities. So I’m now wondering if something else entirely is the root cause of the issue.

Wrothmonk | 2020-07-23 20:53