2

enter image description here

I have a RigidBody Node (3D), and I want to get, in global coordinates, the position of "target", given:

  • an angle "rot" (up is Y)
  • a Vector = 5 * Vector.FORWARD

It looks very easy.... first translate, then rotate, or if it's not working, first rotate, then rotate.

A to B -> If I only apply the translation, it works, no problem:

target = global_transform.translated(5 * Vector3.FORWARD).origin

But if I want B to C, it fails: it looks like it rotate around world origin

I tried many things during last few hours and read so many articles on Transform and now, I'm giving up. So... How would you do it?

enter image description here

Cyrille
  • 13,905
  • 2
  • 22
  • 41

2 Answers2

2

We will define a position relative to your RigidBody(3D) by polar coordinates (namely a "rot" angle and a distance, I'll call it "d") on the XZ plane.

To be clear, we are going to define it in local space of the RigidBody(3D), and then move it to global coordinates.

We can do it using transforms. Which you would do if you need to preserve the rotation. Although it requires a little more work. Or, you can do it Using vectors only. Which is easier.

Below are the different approaches to do this.


Using Transforms

Local transform

We define combine the rotation and translation transformation like this:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)

By the way, the order does not matter when using these methods. The result is this either way:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot) * Transform.IDENTITY.translated(d * Vector3.FORWARD)

Which gives a rotation around the origin at a given distance. However, if you do this:

var t = Transform.IDENTITY.translated(d * Vector3.FORWARD) * Transform.IDENTITY.rotated(Vector3.UP, rot)

You get a transform that is displaced forward, and then rotates in position.


Global transform

For the global transform, we can use the fact that this should be relative to the RidigBody(3D), and we have the global transform of it:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var global_t = global_transform * t

Be aware that this will apply rotation, scaling, and so on. If you only wanted the global translation, you can do it like this:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var global_t = Transform.IDENTITY.translated(global_transform.origin) * t

And no, t.translated(global_transform.origin) is not the same thing. When you use translated it is in the local coordinates of the transform on which you are calling it.


Local position

As you know, we can use the origin of the transform:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var v = t.origin

Global position

Either you can use to_global:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var v = t.origin
var global_v = to_global(v)

Or we can take origin from the global transform:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var global_t = global_transform * t
var global_v = global_t.origin

If you only want the global translation, you can add global_transform.origin:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var v = t.origin
var global_v = global_transform.origin + v

Using Vectors Only

Local position

If you only care about the position, we can do this without the transforms altogether:

var v = (d * Vector3.FORWARD).rotated(Vector3.UP, rot)

Global position

And, of course, you can use to_global:

var v = (d * Vector3.FORWARD).rotated(Vector3.UP, rot)
var global_v = to_global(v)

And again, if you only want the global translation, you can add global_transform.origin:

var v = (d * Vector3.FORWARD).rotated(Vector3.UP, rot)
var global_v = global_transform.origing + v
Theraot
  • 31,890
  • 5
  • 57
  • 86
1

After 1 more hour, I finally found something, but it's kind of ugly:

target = to_global(to_local(transform.translated(3 * Vector3.FORWARD).origin).rotated(Vector3.UP, rot))

If you have something better, please add your answer!

Cyrille
  • 13,905
  • 2
  • 22
  • 41
  • 1
    In your answer, only the global translation affects the resulting vector. Which is different from what I had answered. For example, there is an scaling transformation, the vector would be stretched accordingly. So I up vote for that. Also, I added other ways to only keep the global translation in my answer. – Theraot Jul 30 '21 at 02:19