I'm trying to apply_central_impulse() to RigidBody local axis.

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

My question is a little difficult to explain (which likely means I’m biting off more than I can chew)…

I have a 3ps vehicle combat game (I use a RigidBody on the vehicle for strafe controls). Which has been working very nicely so far. Then I get the stupid idea to introduce gravity rotation for wall riding…
My current code for testing wall ride:

func _physics_process(delta):

apply_central_impulse(Vector3(0, 0, -0.1))
apply_torque_impulse(Vector3(0, 0, rot_force))

vel = getWasdInput()

vel = vel.rotated(Vector3(1, 0, 0), deg2rad(90))

apply_central_impulse(vel)

I can play with controls to flip the logic around as needed depending on which direction the gravity will be in. For now I’m just trying to get 2 working directions of gravity, down and left. at the current point everything works fine, but “vel” does not get rotated with the vehicle. If I don’t rotate the vehicle then everything is wonderful. But if I rotate, then “vel” does not rotate as well.

I’ve tried many ways, but the transform matrix is confusing. I’m certain there is a much easier way to do this, but at this point I’d be happy with functional. Thanks in advance if anyone is able to assist.

:bust_in_silhouette: Reply From: wombatstampede

It’s all about transforms. :slight_smile:

I wrote down some links and info here:
https://godotforums.org/discussion/18480/godot-3d-vector-physics-cheat-sheet

Impulse and force are global vectors. Therefore, you’ll have to use “rotated” vectors.

global_transform.basis has three vectors .x, .y, .z which show the direction of each axis of that spatial in global space. So those are already rotated.

If you want the global down vector of your car. Then this is global_transform.basis.y * -1.
If you want “left” then this should be global_transform.basis.x * -1 (unsure about the * -1 here, but you can try this out).

If you’ve got an arbitrary vector3 in local space. Then you can use global_transform.basis.xform(vector3) to transform it into global space.

By the way: There’s also a way in the other direction (global to local).
I.e.: global_transform.basis.xform_inv(linear_velocity).z will transform the global velocity to a local vector. “.z” then takes the z-component which can serve as forward speed indicator (m/sec).

Just in case anyone finds this, years later, like I have, the cheat sheet can be found on the Wayback Machine: https://web.archive.org/web/20220122182120/https://godotforums.org/discussion/18480/godot-3d-vector-physics-cheat-sheet

Thanks for the good explanations!