Jump to content

Quaternion and Euler Angle conversion issue


Recommended Posts

Hey all,

I've been playing a bit with quaternions to rotate meshes but I also need to use Euler angles. The quaternions are great for my internal cooking because (imo) they are easier to use and more versatile than Euler angles, but Euler angles are good for UI, it speaks to people (especially if we convert everything into degrees (the audience of the app is neuroscience researchers, so they would probably think quaternions are black magic).

The BJS doc says "once you have used a quaternion, the rotation property of a mesh become null and basically no longer usable". Fortunately, we can have user think they set the rotation with a Euler angle but internally convert in into a quaternion. Unfortunately, I think I went into a bug. Here is what I have:

// this._planeSystem is a mesh composed of 3 orthogonal planes

let currentQuaternion = BABYLON.Quaternion.FromRotationMatrix( this._planeSystem.computeWorldMatrix(true) )
let eulerAngle = currentQuaternion.toEulerAngles()
let someQuaternion = eulerAngle.toQuaternion()

I expected currentQuaternion to be the same as someQuaternion (with possibly some epsylon)
but instead, here is what I have:


  w: 0.9987502633525326,
  x: 0.04997916777685541,
  y: 0,
  z: -1.1097604563493715e-17

  x: 0.09999999729822372,
  y: -1.1148677691588498e-18,
  z: -2.2278771887960178e-17

  w: 0.9987502604624825,
  x: -5.56737237414314e-19,
  y: -2.786008172251712e-20,
  z: 0.04997916792147843

I am not sure if it's toEulerAngles() or toEulerAngles() which is in fault but it looks like someQuaternion.z should have been someQuaternion.x

I'm not sure, but looking at the source, it looks like you plan on giving the choice of the order.

Do you confirm it's a bug?





Link to comment
Share on other sites

I now know that it's the method 'Vector3.toQuaternion()' that is guilty!

In my project, I just replaced it by a piece of code I borrowed from glMatrix that made more Babylony:

  function eulerAngleToQuaternion( eulerAngle={x:0, y:0, z:0}) {
    let toHalf = 0.5;
    let x = eulerAngle.x * toHalf;
    let y = eulerAngle.y * toHalf;
    let z = eulerAngle.z * toHalf;
    let sx = Math.sin(x);
    let cx = Math.cos(x);
    let sy = Math.sin(y);
    let cy = Math.cos(y);
    let sz = Math.sin(z);
    let cz = Math.cos(z);
    let quat = {
      x: sx * cy * cz - cx * sy * sz,
      y: cx * sy * cz + sx * cy * sz,
      z: cx * cy * sz - sx * sy * cz,
      w: cx * cy * cz + sx * sy * sz
    return quat;

It now gives the same quaternion back, which is good enough for now. It also seems simpler than the one implemented in babylon.math.ts


Link to comment
Share on other sites

Hey @Sebavan , thanks for the fix! You're right, using BABYLON.Quaternion.RotationYawPitchRoll(y, x, z) is a solid alternative!

I've just updated to v3.2.0-rc.2 and now I can get my user to think in Euler angles (read/write) but have all my internal logic in quaternions!! Thanks for your reactivity on the updates and on providing playground examples, highly appreciated!


Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...