Matrix vs. Tranform / Local vs. Global

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By raould
:warning: Old Version Published before Godot 3 was released.

I am easily confused.

var t is some Transform.

When I use t=t.scaled(s3) type stuff, it ends up scaling the entire coordinate space from then on. So if I want to make my space ship smaller or bigger and then move it into position, I next do t=t.translate(t3) but the end position isn’t t3 in global coordinates, it ends up being s3*t3 or something like that.

I guess I thought with 3d matrix math type stuff the initial scale would be a local thing like just scaling the mesh?

Is it the case that I am dumb/ignorant/wrong and I have to do t=t.translate(t3*(-s3)) or something? Or does it matter that I am using a Transform rather than manually doing matrix stuff?

thank you.

:bust_in_silhouette: Reply From: Gokudomatic2

I never used translate, so I don’t know for sure how it works. But setting the origin of the transform manually let you set its location exactly as you want. The origin field is only relative to the parent transform, unless you use the global transform.

:bust_in_silhouette: Reply From: avencherus

I’m not too clear about the pseudo code, maybe I’m missing it, but t isn’t given.

In general local matrices act as a reference for global transformations. When you want to move or rotate things in the world, you would do a global transformation and keep track of it in a matrix for each object. If you manipulate the local space matrix, the world space transformations will be acting on those new offsets.

As an example, changing the translation value of a local matrix will offset the origin point. If the origin is used for rotation, the pivot point of your object will now be offset whenever the game does global rotations of that object. It will begin orbiting the origin of the local space, rather than spinning on top of it. Something like this second image: http://www.glprogramming.com/red/images/Image52.gif

There is a get and set for global transforms as well, which I think that may be what you’re looking for: Node2D — Godot Engine (latest) documentation in English

set_global_transform(matrix)

The Matrix type for 3D is: http://docs.godotengine.org/en/latest/classes/class_matrix3.html

thanks for your note. do global transformations ignore parent hierarchy? whereas locals respect it?

raould | 2016-09-30 00:50

I’m not sure what you’re asking, because each parent becomes the origin point for what is considered local to it’s children.

You might be using the wrong terminology. So I don’t want to make assumptions and give you the wrong answer.

I’ve only tested in 2D with translations, so what I can say is that when you do a global transformation to translate a node, it is going to move it to that exact coordinate in world space, by offsetting it’s local coordinates. In most cases with 2D, the world space is going to be the coordinates you see as the canvas that the camera will pan across. In 3D it’s more like an abstract cube that holds all your objects. It’s hard to say what it will look like, because it will be transformed into a desired camera perspective, then another transformation to cast it into a screen space.

Returning to the point, If a node exists inside a hierarchy, it will be locally transformed, relative to it’s parent node, in order to achieve a position given by a global transform. If you want to preserve it’s local space, so it may remain centered on it’s 0,0 origin for example, then you will want to transform the root node instead. This is why I’m unclear by what you mean by ignoring it’s parent relationship.

As an example that might help clarify this. Think of a node named B. It is a child of a node named A. If node A rests at 200x and 200y, and it’s child node B is at 0x,0y, node B will also be at 200x, 200y in world space.

If you perform a local transformation that translates 50x, 50y to B, this will move it locally, adding the parents position and then it’s own. So you will find node B at 250x, 250y in the world.

However, if you do the same transformation to translate globally to 50x, 50y. You’re insisting that B move to the world space position of 50x, 50y. In order to do this, it must be translated locally by a negative amount. In this case it’s -150x, -150y. It’s local transformation will show it’s translation now as -150x, -150y. Since it’s parent rests at 200x, 200y, it must be offset locally to put it in that desired global coordinate.

I hope that was relevant. X)

avencherus | 2016-10-01 00:38

thank you for the thoughts.

my main problems are 2 fold i think:

[edit: adding concrete questions at the bottom of this comment]

  1. i don’t understand the Godot naming of things and the docs aren’t clear enough for me (e.g. in the api docs) so i never understand when i am doing something ‘locally’ or ‘globally’ or at least am probably wrong half the time.

  2. i probably have mistakes in my understanding about the matrix stuff. the way i think of it, the matrix changes the coordinate space, not just the item. which means if i want to scale and then translate, it seems i have to scale(v3(s,s,s)) but then translate(v3(x/s,y/s,z/s)) or something like that. i seem to be doing rotation and translation ok but things go wrong when i try to scale.

(also it is weird to me that 0 radians in godot is apaprently up/north/+y instead of being east/right/+x like in trigonometry?)

Questions:

  1. i am confused about the functions on the Spatial vs. the functions on the Transform. When I call Spatial.set_scale(v3) how is that different than making a Transform that is scaled(v3) and then set_transform(t) on the Spatial?

  2. how do i scale something locally and then move it? do i have to change how much i translate it since it got scaled?

  3. if i set_transform(v3) what do i get when i then call get_translation()? is it the end result of the transform? or is it only the translated() part of the transform?

  4. i think it is killing me that a Transform is different than a 3d 4x4 Matrix that is used in most other engines?! that might be a big root of my bugs/confusion. Unity - Scripting API: Matrix4x4

:slight_smile:

raould | 2016-10-01 21:16

I hear you on that, especially the unit circle’s orientation.

avencherus | 2016-10-02 11:55

:bust_in_silhouette: Reply From: raould

In the end I used a Transform for the global translation & rotation, and then after setting that on the Spatial I then used spatial.set_scale( v3 ) which did a local scale as I wanted. Confusing to me but it works anyway!?

:bust_in_silhouette: Reply From: LeeJiwon

For Matrix and Tranform, the following links will help you.

:bust_in_silhouette: Reply From: pioenisgreat

hi!

you already found a solution but i wanted to chime in anyway as i came across the same problem as you.

for scaling transforms along their local coordinates, the solution i found is to multiply the seperate basis vectors by a scaling factor

so to stretch a transform alongs its local y axis by a factor 10

transform.basis.y *= 10