3D Forces on RigidBody objects

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

I’m trying to simulate a ship in 3D space using a RigidBody, but I’m having a hard time figuring it out. My goal is to have all movement come as the result of physics calculations involving forces that have their source in the ship itself in the form of various thrusters. I need movement and rotation in all three axes as the result of player input, calculated as physics, so pure translations don’t cut it.

The code below seems to work for applying thrust forces to the RigidBody right up until it rotates, at which point the forces applied no longer correspond to the orientation of the object in 3D space:

func _physics_process(delta):
    var thrust_total = Vector3(0, 0, 0)
    if Input.is_action_pressed("ui_up"):
	    thrust_total += thrust_forward
    if Input.is_action_pressed("ui_down"):
	    thrust_total += thrust_backward
    if Input.is_action_pressed("ui_left"):
	    thrust_total += thrust_left
    if Input.is_action_pressed("ui_right"):
	    thrust_total += thrust_right
    if Input.is_action_pressed("ui_page_up"):
	    thrust_total += thrust_up
    if Input.is_action_pressed("ui_page_down"):
	    thrust_total += thrust_down
    apply_impulse(Vector3(0, 0, 0), thrust_total * delta)

How do I translate between local forces (for example, the player applies the ship’s main rear thrusters in an attempt to get the ship moving forward relative to it’s own orientation in space) and global forces (the way Godot seems to currently handle 3D forces)?

:bust_in_silhouette: Reply From: SIsilicon
#Get your basis from your transform..
var basis = global_transform.basis
#Then transform your thrust total..
thrust_total = basis.xform(thrust_total)
#And finally use your thrust total as usual.
apply_impulse(Vector3(), thrust_total * delta)