HowTo : Scale + ThinInstances

Hello,

Up to this point, I hadn’t encountered any issues as I hadn’t been using thin instances. However, thin instances have now introduced a translation problem whenever I attempt to scale models. As someone relatively new to 3D development, despite scouring numerous forum posts, I’ve been unable to find a solution.

I use the assetsManager to load assets, and due to variations in the sizes of models, upon the successful completion of a task in the assetsManager, I apply a scale (as defined in a configuration file).

For instance, I apply a scale of 0.01 to task.loadedMeshes (which contains 3 meshes) simply by using: node.scaling = new Vector3(0.01, 0.01, 0.01); on each mesh (since the model is very large).

Upon rendering, I see my model scaled as expected. However, when I attempt to translate the model using a matrix, it barely moves; it’s as if it’s operating within its “local matrix” or something like that.

Initially, I had:

const matrix: Matrix = Matrix.Translation(x, y, z);
thinInstancesWorldMatrices.set(matrix.toArray(), id * 16);

I considered that perhaps I should multiply the matrix with a scaling matrix, but the outcome seemed even worse. I also tried to scale the root node (rootnodes[0]) of InstantiatedEntries from container.instantiateModelsToScene, the scaling is working but change nothing to the translation problem.

In reality, I’m facing a similar issue with rotation: I apply a rotation upon task load (also by configuration). However, when I endeavor to move the unit in a particular direction, at times, it moves in the opposite direction, seemingly influenced by the initial rotation.

Could you advise on how to correctly implement transformations on a loaded container/mesh, such as rotation or scaling please ?

This video illustrates the problem: https://youtu.be/uoFXEefp1Mo

I try to understand this post:thinking:

Other question: if we have a “character mesh” with children meshes, we can use the same thinInstance matrix for each child right ?

Thank you

Check this playground

As soon as we scale to 2, translations are also scaled.
Without the initial rotation, units move in opposite directions.

Bonus question : is there a better way than looping on child meshes ?

I also found this post (2021) with this playground as solution.

The solution say to use this code :

const scale = new Vector3(2, 2, 2);
const rot = new Quaternion.RotationYawPitchRoll(Math.PI/3, 0, 0);
const trans = new Vector3(-1, 2, 0);
var newMat = Matrix.Compose(scale, rot, trans);
sphere.thinInstanceSetMatrixAt(idx, newMat);

From what I understand we can also do something like this to avoid Quaternion (which cancel my initial rotation on container load) :

const matrix: Matrix = scaleMatrix
      .multiply(rotationMatrix)
      .multiply(translationMatrix);

UPDATE : this is indeed the solution . But it is not working in the given playground because the buffer is static, see later comments.

Notes :

  • my glb model have a scale of 1, 1, 1. But when I load it, I must set scale it at (1, 1, 1) explicitly otherwise the positioning is totally wrong. Strange behavior which does not help to debug. Updated playground

Hi.

Just to be sure about scaling behavior, did you export your model from Blender by yourself or find the glb directly ?

I cannot test right now but maybe these will help: Babylon.js docs

Since you ignore root node in your loading it may explain strange behavior.

Bye

1 Like

I found the model on Sketchfab, so I don’t know. But there is the same problem with the player.glb from babylon, here is a cleaned playground. Try to comment the scale 1,1,1.

Sorry I add infos in my original message

Indeed, importing objects is a nightmare for a beginner like me:

  • what we see in Blender is not always what we really have depending mysterious Blender config
  • we don’t really know what we export, depend on options (Z → Y, left/right handed)
  • Babylon also do changes automatically when importing (default conf of GLB loader when using assetManager)

So know I try to stop the headaches: my assets come with some initial transformations (scale & rotation) :sweat_smile:

Indeed, It explains why we (sometimes) have to (re)scale to 1 + rotate of 180 on Y, like my previous pg !

Most (all) of your orientation problems comes from the fact that Babylon uses a left handed coordinate system, while meshes are defined in a right handed system in a gltf/glb file. We have to set a special transformation (180° Y rotation and a -1 Z scale) on the root object to account for this difference. You will make your life much easier if you set the scene to be right handed by doing scene.useRightHandedSystem = true, because in that case the transformation is the identity.

Here’s how to fix your PG:

2 Likes

You right, at the beginning I also tried to switch to right handed, but my initial tests were incorrect.

Can someone please take a look at this playground, given as solution in another post ? The first sphere should scale, but it is not.

@Evgeni_Popov This is my last playground which works perfectly : https://playground.babylonjs.com/?#T8Y5DY#20

Now I just change the loaded .glb, look the result: https://playground.babylonjs.com/?#T8Y5DY#30

I understand that the model is probably exported with different parameters, but how the hell the result can be totally broken ? This is not a right handed problem, isn’t it ?

It does not scale because the default for staticBuffers has been changed to true for performance reasons. So, you have to pass false when calling thinInstanceSetBuffer:

No, it is a problem with the model itself. The meshes are children of a node with a 0.01 scale + a 90° rotation around X. The navmesh is not aware of it, so the matrices it returns can’t be used “as is”. I tried to fix it by multiplying the matrix with the inverse matrix of the parent node of the meshes:

Note that I reset the scale vector (line 4) to (1,1,1), and I also had to account for the 90° rotation around X line 138.

You’ll save yourself a lot of sweat if you ensure that all meshes are exported with an identity matrix from the DCC tool.

2 Likes

Thank you !! I see I still have a lot to learn :smile:

Hi @ylacaute, I’ve solved similar issues in the past by merging the imported model before doing anything with it. I’m not sure it’ll solve your issue, and (disclaimer) I did not go in depth on every aspect of the thread, but wanted to drop this here in case it helps. :v:

1 Like