Weird behaviour with absolute scaling / Trying to get rid of negative Scaling

In my project i need to correct all the negative scalings that come after importing a mesh, because after i export everything as glb it sometimes get’s converted again to usdz which doesn’t allow it.

So i made a function that tries to achieve that. Here i come to some weird behaviour that i don’t get. Mesh2 works - Mesh1 doesn’t the only difference is a rotation in a child but shouldn’t the absolute rotation already adjust for that? if i transform my scaling Vector by the absoluterotation matrix mesh1 starts to work but mesh2 doesn’t.

I think this whole behaviour comes because those absolute transforms are all marked as _isDirty however they never update, only when moving with the position mode in the inspector.

Heres a repro:

Thanks for any help!

absoluteRotation and absoluteScaling are updated when the mesh world matrix is updated (so when you change position, rotation or scaling anywhere in the mesh hierarchy tree),

I’m not sure to follow what you try to achieve in your case :slight_smile:

We need to keep the negative scaling to move from right handed data (glb) to left handed (babylon by default),

But in your case, if you want to manipulate and exprot data to usdz, you can simply force the scene to be right handed:

scene.useRightHandedSystem = true;

That will remove all the negative scaling!

1 Like

yes that the absoluteRotation and absoluteScaling are updated after the mesh world matrix is updated is what i would’ve thought to, but check this link:

the vector always stays “dirty” and on the child the absoluteScaling shows -1 on y even though it should be -1 on z, no?

even after computing the world matrix of the whole hierarchy.
And then also try to move the parent node with the name “2” in the position mode and watch at the transformations, there is a sudden correction from

from | to
rotation (0, 180,0) | (0, 0 180)
scaling (1,1,-1) | (1 ,-1 ,1)

I will try with the useRightHandedSystem, thanks!

1 Like

The isDirty for the absolute properties is irrelevant as they are readonly properties for the user.

The isDirty is used internally for the nodes to know when to update the world matrix. For position, rotation, scaling their “dirtiness” is restored to false after the computation.

We do not do that for absolute**** as they are not used to trigger anything.

For the sudden change, I deeply apologize and I must be dense today but I do not see a sudden change in your PG. On the console there is only one print. Do you mind updating it to highlight the problem better maybe?

No problem, maybe im just bad at explaining myself here. I see ok then isDirty is not relevant.

Ok let’s see here:

the absolutescaling that i log shows -1 on the y axis.
However as seen on the second import of the same mesh:
setting z to -1 on the parent is the same as setting -1 to every children.
→ So i would expect the absoluteScaling of the children to be (1, 1, -1).

im not sure if the jump in transformations is all that relevant because it should come to the same result but here the video shows what i mean:

Oh I see!!!
This is because of the gizmo. It changes the mesh to be able to control it

cc @Cedric to add more details

1 Like

cc @alexchuber

Hey! You mentioned that USDZ doesn’t allow negative scalings-- could you elaborate a bit? As far as I was aware, the format supports them, although QuickLook appears to handle their facingness differently than other applications.

1 Like

Interesting i think you are right! I just thought so because the three.js exporter that is used in the model-viewer states so:

but this warning likely just comes because i opened this issue :grinning_face_with_smiling_eyes:

@Deltakosh the solution with the useRightHandedSystem works, thanks!

^^If someone still has the time to explain to me this i would be thankful:

1 Like

About your question with the absoluteScaling…

absoluteScaling and absoluteRotation are derived by decomposing the world matrix, which is a lossy operation.
Decomposing a transformation matrix that was created with negative scaling is mathematically ambiguous. We can detect that the matrix is flipping on an axis, but we can’t recover how. For example, flipping on the Z axis is the same as flipping the Y axis, then rotating by 180 on X.

We arbitrarily select the Y axis to be the negative scale factor in Matrix.decompose, which explains your case.

1 Like

And about your our USD scaling woes, what you pointed out in the Three.js thread about AR mode on iOS is very helpful! :slight_smile: I’ll check to see if Apple is aware.

2 Likes

Aha, i see!
thanks for the explanation, the help in general and glad that it was at least somewhat helpful! :slightly_smiling_face:

1 Like