Parenting object while keeping same worldspace

Hello, hopefully this question is appropriate for this forum.

I’m making an openGL (ES) based application. I need my user to be able to parent an object while keeping its current worldspace loc/rot/scl

I can do it by inversing the parent mat and multiplying it by the child mat, but this only seems to works when scale = 1. When scale is applied to my objects the result doesn’t work (i.e my child moves or skews after parenting)?

Any help would be great, thanks.

Either disable scale when computing the parent and child matrices to be inversed and multiplied together; or maybe orthonormalization of the 3x3 rotational part of the result will be necessary.

Thanks for your help! This works fine for all cases except when the parent is scaled. When the parent is scaled I need to factor this into the child’s final matrix.

I figure the child’s scale should become:
child.scl = child.scl * 1/parent.scl.

And the location of the child also shifts since the parent’s coord space is scaled. I thought the logical solution would be:
child.loc = child.loc * 1/parent.scl.

But both of these ways of factoring the scale back in skew my child object.

What is the proper way of applying the parent’s inverse scale to the child?

Thanks for any help,

Whatever your transform representation is, all you need to keep the world transform constant is a proper implementation of:

  1. Inversion operator: inv(loc,rot,scale) = (inv(rot)*loc/scale, inv(rot), 1/scale):
  2. Multiplication operator: (loc,rot,scale) * pos = rot * (pos*scale) + loc;

I’m sorry Dmitry, I’m not sure I understand you.

For example, parent: (loc, rot, scl) = (.25,.5,.75),(25,-45,90),(2,4,8)

Inverse = (-25*.25/2, 45*.5/4 ,-90*.75/8 )(-25,45,-90)(1/2,1/4,1/8)

As for multiplication, I don’t know what “pos” stands for? Shouldn’t I be multiplying the inverse with the child mat?

Sorry, my answer was really too short and incorrect.

While I mean multiplication of the transformations, instead I put the transform of a point. Also, I assume you have operations on your rotation structure defined (inversion,multiplication,rotation).

Hence, by writing “rot * some_vector” I mean the operation of rotation that your structure delivers, not a per-component multiplication.

Suppose you have the following functions defined for a rotation object:
“Rotate(rot,loc)” - to rotate a vector (or a point)
“Inverse(rot)” - to inverse the rotation
“Multiply(r1,r2)” - to combine rotations.

The corresponding routines for the whole transformation object (whatever name you give to it) can be written as follows:

Transform((loc,rot,scale),pos) = Rotate(rot,pos)*scale+loc;
Inverse((loc,rot,scale)) = ( Rotate(Inverse(rot), loc/scale), Inverse(rot), 1/scale );
Multiply((l1,r1,s1),(l2,r2,s2)) = (Rotate(r1,l2)*s1+l1, Multiply(r1,r2), s1*s2 );

If you have that implemented, the change of parenting is trivial:

New_local(object) = Multiply( Inverse(Wolrd(new_parent)), World(object) );