#Confused about what it means when a child translation is relative to a parent translation?

58 messages · Page 1 of 1 (latest)

errant warren
#

For example, I have this simple piece of code which spawns a rectangle relative to its parent which is a circle:

    commands
        .spawn((MaterialMesh2dBundle {
            mesh: meshes.add(shape::Circle::default().into()).into(),
            material: materials.add(ColorMaterial::from(BALL_COLOR)),
            transform: Transform::from_translation(Vec3::new(10., 10., 0.)).with_scale(Vec3::new(50., 50., 1.)),
            ..default()
        },
        Ball)).with_children( |parent| {
                parent.spawn((
                    SpriteBundle{
                        transform: Transform {
                            translation: Vec3::new(2., 0., 1.),
                            scale: Vec3::new(0.2, 0.2, 1.),
                            ..default()
                        },
                        sprite: Sprite {
                            color: RECT_COLOR,
                            ..default()
                        },
                        ..default()
                    },
                    Rect
                ));
            });

I have a system which prints out both translations for both the Transform and the GlobalTransform of each of these shapes. For the ball entity the system prints: ball transform xy: [10, 10], ball global xy: [10, 10]. This is expected because the ball has no parent. However, for the rectangle the system prints: rect transform xy: [2, 0], rect global xy: [110, 10]. I would expect the child transform to be a simple addition onto the parent transform and print: rect transform xy: [2, 0], rect global xy: [12, 10] but that is not the case. So what is the relationship between the two? The extra 100 in the x value of the GlobalTransform of the child, the 2 in the Transform and the 50 as the width of the circle make me think its relative to the size of circle somehow. Is that the case?

fiery zenith
#

basically children's transforms are just matrix multiplications of it's parents and worlds

#

so for example, an objects transform in the world would be: world matrix * object matrix
If you have a child,
then it's calculated as such:
world matrix * object matrix * child matrix
or if we sum it up,
first_child = object * child

#

so it's not just an addition, it takes all the properties the parent has in the matrix, that is, translation, size, rotation

#

then it applies those to the child

#

you can have mutiple children, and they multiply it's parents matrix

#

hope that made some more sense

errant warren
#

@fiery zenith Ok this is starting to make sense. I don't have too much experience with matrix operations, is there any programmatic way to determine how to place the child transform so that it's global transform is at [12, 10]? Since setting the child transform to being [2, 0] does not work as I expected.

fiery zenith
#

there's a way to get global transfrom handle i believe

#

it's a different query

#

you can get it from there

quick token
#

GlobalTransform

#

it's called

#

I'm not sure if changing GlobalTransform gets propagated to Transform, @fiery zenith any idea?

#

I thought it was only the other way around

fiery zenith
#

you need to dereference it, it should work both ways

#

i never tried seeing if it actually changes local transform esau_thinking

quick token
#

it has to be synced up at some specific point too

limpid cape
#

I thought it only goes local -> global automatically. You shouldn't really be setting global transforms

fiery zenith
#

you can use it to see how to set it up

#

you can do math with parent to see how it works

limpid cape
#

You have .with_scale(Vec3::new(50., 50., 1.)), on your parent though, so that means all the transformes of the children will be scaled that much

fiery zenith
#

or reverse it

quick token
#

Parent's scale modifies the child local transform's translation?

limpid cape
#

the local transform is the same, but when it gets converted to global, the parent transform is used in the conversion

#

you can think of the parent transform as defining a new "space" for its children

#

if a parent has a scale of (5, 5) and a rotation of 90 degrees counterclockwise, then a child with a transform of (0, 2) (two units up) would become (-10, 0) 10 units left.

quick token
#

what if child was rotated, would the angle also get scaled? or would it shear

#

it's probably consequences of the mat multiplication, i don't remember the exact way it interacted

#

i usually worked with one transformation at a time

limpid cape
#

it wouldn't shear

#

you can think of doing all the children first, then doing the parent and all its children together

#

Say you were trying to draw this scene

#

with the ball at 3,3 with a scale of 1 and the plane at 0,0 with a scale of 10

#

if the ball was set to 3,3 and the plane has a default scale of 1 instead of 10, that would look like this, right?

#

point B is 3,3, point A is 5,5

quick token
#

yup

limpid cape
#

so now if you modify the parent scale, nothing moves relative to each other, we just have to update our labels now. C is 5,5 B is 30,30 (3from its translation*10 from the parent scale)

quick token
#

which one is the parent? the plane?

limpid cape
#

yes, sorry

quick token
#

so parent's scale only scales child's position

#

angle offsets angle

#

and position offsets scaled position

#

and child's scale is unaffected?

limpid cape
#

scale will also make the ball bigger

#

rotation will also move the ball around the parent;s origin

quick token
#

so parent scale is multiplied with child scale

#

hmm

#

alright

#

ty for explanation

limpid cape
#

so the two options to fix this are

  1. to compensate when setting the ball transform and use numbers that are relevant to the parnet before it is transformed
#
  1. move the parent's mesh to a second child so you can move it independently, and then only use the parent's transform when you are trying to move everything together
quick token
#

the 2nd solution seems much cleaner

#

that or just scaling mesh directly

#

but yeah, i ran into that with autodesk and it was very annoying

#

tis just how math works 🙁

errant warren
#

Ah this is much clearer now, thank you everyone for the explanations. I also think option 2 is the ideal solution.