Gizmo rotation behavior after scaling mesh

Hi, I’m currently working on a 3D scene editor based on babylon.js.

Now I’ve encountered a problem that rotation gizmo got stuck after scaling mesh.
And the console print:

Unable to use a rotation gizmo matching mesh rotation with non uniform scaling. Use uniform scaling or set updateGizmoRotationToMatchAttachedMesh to false.

So I just set rotationGizmo.updateGizmoRotationToMatchAttachedMesh to false.
But the rotation gizmo just rotated badly (not sync with mouse behavior almost every time).

thanks a lot for any help.

Hello! As stated on the error message, it’s not possible to accurately determine the rotation of non-uniformly scaled meshes :slight_smile:

is there any way to achieve rotating non-unifromly scaled mesh correctly with gizmo?
I mean maybe some tricky way else (i.g. hard coding).
because I really need rotation gizmo work properly.
thank you.

cc @Cedric who runs the gizmos

Do you have a repro PG?

yeah this one

Press q, w can switch gizmoType.
Scale mesh first then rotate mesh any direction. (you should press ‘a’ after scaling)
a few trial you’ll find out the rotation direction was not correctly sync with axis.

thank you please.

I have a behavior where the scaling axis become all the same. the non uniform scaling becomes uniform is it the same repro you get?

I didn’t get that result. every single axis scaling should not become uniform.
try this code in your new PG

const createScene = async function () {
  const scene = new BABYLON.Scene(engine);

  //Adding an Arc Rotate Camera
  const camera = new BABYLON.ArcRotateCamera(
    'Camera',
    -Math.PI / 2,
    1.4,
    20,
    BABYLON.Vector3.Zero(),
    scene
  );
  camera.attachControl(canvas, false);
  camera.setTarget(new BABYLON.Vector3(0, 0, 0));

  // The first parameter can be used to specify which mesh to import. Here we import all meshes
  const result = await BABYLON.SceneLoader.ImportMeshAsync(
    '',
    '',
    'https://vsnova.app/static/models/asset-collections/Monitor-360.glb',
    scene
  );
  const newMeshes = result.meshes;
  const mesh = newMeshes[0];

  for (const mesh of newMeshes) {
    console.log(mesh.scaling);
    console.log(mesh.rotation);
  }

  mesh.position = BABYLON.Vector3.Zero();

  const oldPos = mesh.position.clone();
  const oldPivotTranslation = mesh.getPivotMatrix().getTranslation();
  mesh.position.set(
    -oldPivotTranslation.x,
    -oldPivotTranslation.y,
    -oldPivotTranslation.z
  );
  mesh.setPivotMatrix(BABYLON.Matrix.Translation(0, 0, 0), false);
  mesh.bakeCurrentTransformIntoVertices();
  mesh.position.copyFrom(oldPos);

  const gizmoManager = new BABYLON.GizmoManager(scene);
  gizmoManager.rotationGizmoEnabled = false;
  gizmoManager.scaleGizmoEnabled = true;
  gizmoManager.attachToMesh(mesh);

  document.onkeydown = (e) => {
    if (e.key === 'q' || e.key === 'w' || e.key === 'a') {
      gizmoManager.positionGizmoEnabled = false;
      gizmoManager.rotationGizmoEnabled = false;
      gizmoManager.scaleGizmoEnabled = false;
      if (e.key === 'q') {
        gizmoManager.rotationGizmoEnabled = true;
      }
      if (e.key === 'w') {
        gizmoManager.scaleGizmoEnabled = true;
      }
      if (e.key === 'a') {
        gizmoManager.gizmos.rotationGizmo.updateGizmoRotationToMatchAttachedMesh = false; 
      }
    }
  };

  return scene;
};

for detailed repro. here’s a video you can see:

I’ve scaled the y-axis(vertically) and switch to rotationGizmo.
In the beginning, rotation was stuck then I press ‘a’ to set rotationGizmo. updateGizmoRotationToMatchAttachedMesh to false.
the result is that rotation behavior not sync with gizmo axis.

Yes, that’s expected as updateGizmoRotationToMatchAttachedMesh is false. Gizmo stays in world space and is not in sync with mesh.

yeah as I see in the doc. (see image

my question is how can I make rotation gizmo support updating with attachedMesh?
maybe to overwrite gizmo prototype?

Making it so needs a quite big refactor in Gizmo regarding transformNodes and Nodes.
Until it gets more prioritized, I would suggest to not allow non uniform scaling or if it’s not possible then have a proxy TransformNode that you edit with the gizmo and apply back the rotation/scaling/translation to the mesh.

okay I got it.
proxy transformNode seems to be a nice solution.
really appreciate it.

1 Like