So I cannot figure it out… How should I set the rotation of gltf asset to have an exact rotation in my 3d software? I’ve been trying to use quaternions, flipping axes, converting to radians… And after few hours of testing I just can’t figure it out.
There’s also additional diffuculty, because babylon and the 3d software I use have different coordinate (one is left-handed the other right-handed). For the position it’s super easy:
root.position = new Vector3(
-data.position[0],
data.position[1],
data.position[2],
)
This makes sure the positions are correct. But with rotations… I have no idea anymore.
So how can I set the rotations in babylon to exactly what I have in the 3d software? Assuming that:
x: data.rotation[0] // rotation of X in degrees
y: data.rotation[1] // rotation of Y in degrees
z: data.rotation[2] // rotation of Z in degrees
And in the 3d software the rotation order is Rx Ry Rz.
On your 3D software you must have an option when you export you GLTF asset, such as “Y up”. For example I use Blender, which is Z up. I check “Y up” at export, so that final export is Y up, just like BabylonJS is.
By default, the BabylonJS GLTF import sets the rotation to quaternion, which means mesh.rotation[0], or mesh.rotation.x which are euler angles, won’t work. To switch back to euler, you can do this in your GLTF import callback :
I’m using Houdini, and it’s GLTF exporter for some reason is quite bad, it doesn’t even have nice options like in Blender. Anyways this Y axis should be easily flipped in Babylon as well, right?
Ok, I fixed it! But not on Babylon side, but in Houdini. My scene is too complex to share, it’s using custom HDAs, external assets, so it won’t work on your side.
So what I did…
Before I used each asset rotation (x, y, z) - that all was exported to JSON, from that I can instantiate containters to proper place, rotation, scale.
Instead doing that I just converted the rotation to quaternion in a wrangle:
So once I have that, on Babylon side I have to invert the incomming values:
root.rotationQuaternion = new Quaternion(
-data.orient[0],
data.orient[1],
data.orient[2],
-data.orient[3],
)
Now it even matches the rotation conversion I use when sending/receiving data to the Go server (which by default is using whatever the rotation and position I use in Houdini).
Phew… I can’t believe I’ve spend so many hours on this…