Best way to load and apply transform on GLTF files

Hi “Jedi council” :smiley:

So I am creating a configurator, in which user can move rotate scale the 3D items which we have made editable via some logic.

Now since we have to use GLTF file format, while exporting them to glb the exporter creates a root node on each mesh. So should I load them into scene by changing the position of root or the first child of root. And when I apply the rotation gizmo ideally where should I place it on the root or the child?

Am I following the correct pipeline of loading assets in my scene i.e. All roots are at origin and the meshes under them are at different coordinates for example if there are two chairs in my scene both have their root at the origin but their actual position is at somewhere else.

Phew! I hope I am making sense :stuck_out_tongue:

Regards,
Nipun David

1 Like

hey @nipundavid, there is no real good answer. Both work. Just take the one you prefer (root or first child).

I’m more on the “use the root” as it seems to be easier to do for me

Hi @Deltakosh, thanks for the insights.

So how to design scene then in this case, as root always goes on origin and my object is some other coordinate.

What I understood from you is that while exporting to glb the model and the root should be on the origin but then how should I design the level. as earlier I was embedding the object transform in the blender and the exporting but in this case all my objects will be at the origin with root

Also the rotation which I see in sandbox for a particular mesh when I applied it in the scene there is a an offset (Screenshot)


regards,
Nipun David

Maybe in Blender you should export your customisable meshes placed on [0,0,0] instead of their “real” place in the final scene. Then once in BJS you could apply their spawn position.
Little tips when importing a gltf: in the onSuccess callback you can rename the __root__ object, so as to get it more easily later (like here lines 30 & 85).

Approach 1

  newMeshes[1].rotate(Axis.X, 0, Space.WORLD);
  newMeshes[1].rotate(Axis.Y, -90, Space.WORLD);
  newMeshes[1].rotate(Axis.Z, 0, Space.WORLD);

Approach 2

newMeshes[1].rotation = new Vector3( 0, -90,0 );

I tried the above approaches - but my rotation everytime is off (approach 2 crashed my code)

regards,
Nipun David

The rotation applied is due to different axys convention between Blender <> glTF <> BJS. You can even spot the Z scale of your root which is equal to -1.

Shouldn’t it be new BABYLON.Vector3 instead of new Vector3?

I am using React project, so I am imported babylon Core in my file already

The values of rotation and quaternioRotations seems very weird to me when I am loading the scene for the first time

Capture

Why I cannot see the -90 degrees on the y-axis :frowning_face:

How is this even possible?

And I want to apply rotations

Approach 1

Copy to clipboard

  newMeshes[1].rotate(Axis.X, 0, Space.WORLD);
  newMeshes[1].rotate(Axis.Y, -90, Space.WORLD);
  newMeshes[1].rotate(Axis.Z, 0, Space.WORLD);

Approach 2

newMeshes[1].rotation = new Vector3( 0, -90,0 );

What should be the correct approach

If you use mesh.rotation, make sure mesh.rotationQuaternion is undefined or you will continue relying on the quaternion.

The inspector converts everything in the UI so it might confuse you but usually speaking when loading from GLTF only quaternions are used.

1 Like

:sweat_smile: I think I figured it out…Damn! you radians :smiley:

Lesson Learned : Never under estimate the power of trigonometry in computer graphics :sweat_smile:

When Loading in OnSceneMount -

if (newMeshes[1].rotationQuaternion) {
              newMeshes[1].rotation = new Vector3(
                (Math.PI / 180) * modelData.rotation.x,
                (Math.PI / 180) * modelData.rotation.y,
                (Math.PI / 180) * modelData.rotation.z
              );
            }

when Saving after rotation applied through gizmo -

rotateGizmo.onDragEndObservable.add(() => {
      let _rotation = rotateGizmo.attachedMesh.rotationQuaternion;
      let modelRotation = {
        x: (_rotation.toEulerAngles().x / (Math.PI / 180)),
        y: (_rotation.toEulerAngles().y / (Math.PI / 180)),
        z: (_rotation.toEulerAngles().z / (Math.PI / 180))
      };
      RuleEngine.rotateModel(modelRotation);
    });

Thanks @sebavan @Vinc3r for looking into it’

I will get that Jedi Council Badge some day :sunglasses:

2 Likes

also you could have call firstChild.setParent(null) to get rid of the root node :wink:

1 Like