bx icon indicating copy to clipboard operation
bx copied to clipboard

Mismatch between quatToEuler, mtxQuat, and mtxSRT

Open OswaldHurlem opened this issue 6 years ago • 7 comments

This code demonstrates a mismatch between the definition of "euler" angles used by quatToEuler and the definition (non-explicitly) used by mtxSRT. This created a bit of confusion for me when I was dipping my toes in BGFX.

void CheckBxEulerMath()
{
    float eulers[3] = { bx::kPiQuarter, bx::kPiQuarter, bx::kPiQuarter };
    float qX[4];
    float qY[4];
    float qZ[4];
    float qXqY[4];
    float qZqXqY[4];

    bx::quatRotateX(qX, eulers[0]);
    bx::quatRotateY(qY, eulers[1]);
    bx::quatRotateZ(qZ, eulers[2]);
    bx::quatMul(qXqY, qX, qY);
    bx::quatMul(qZqXqY, qZ, qXqY);

    float mtxFromQuat[16];
    bx::mtxQuat(mtxFromQuat, qZqXqY);
    float mtxFromSRT[16];
    bx::mtxSRT(
        mtxFromSRT,
        1.0f, 1.0f, 1.0f,
        eulers[0], eulers[1], eulers[2],
        0.0f, 0.0f, 0.0f);

    float eulersFromQuat[3];
    bx::quatToEuler(eulersFromQuat, qZqXqY);

    for (int idx = 0; idx < 16; idx++)
    {
        if (!bx::equal(mtxFromQuat[idx], mtxFromSRT[idx], 0.00001f)) {
            BX_TRACE("mtxFromQuat does not equal mtxFromSRT");
            abort();
        }
    }

    for (int idx = 0; idx < 3; idx++)
    {
        if (!bx::equal(eulers[idx], eulersFromQuat[idx], 0.1f))
        {
            BX_TRACE("eulers is way different from eulersFromQuat");
            abort();
        }
    }
}

I know that the historic correct definition for Euler angles is different from what mtxSRT gets passed but it would be nice for this discrepancy to fixed or made explicit. Perhaps you could add these functions

void quatPitchYawRoll(float* _result, float _pitch, float _yaw, float _roll);
void quatToPitchYawRoll(float* _result, const float* _quat);

and document how to compose the output of mtxSRT using individual transformations?

Thank you for your time and your open source projects.

OswaldHurlem avatar Jun 04 '18 03:06 OswaldHurlem

Additionally, mtxSRT appears to have the opposite rotation direction as Aerospace Eulers flight_dynamics_with_text https://gyazo.com/9e0d2019405543e5a63f4f5484b71c35

OswaldHurlem avatar Jul 01 '18 09:07 OswaldHurlem

cc @dariomanesku

bkaradzic avatar Jul 01 '18 16:07 bkaradzic

@OswaldHurlem: are you perhaps using left-handed coordinate system?

dariomanesku avatar Jul 02 '18 21:07 dariomanesku

I am, but is there any handedness inherit to my example from above? Also, bgfx/bx does not have any documented handedness.

OswaldHurlem avatar Jul 03 '18 02:07 OswaldHurlem

bx is not really part of bgfx... It's used there, but not everything.

bx vector math is going to get changed in the future, and ideally you should have your own math library.

bkaradzic avatar Jul 03 '18 02:07 bkaradzic

@OswaldHurlem: yes, try https://github.com/bkaradzic/bx/blob/7f4f5a282bd55eab36ba953c53311f6905e32dba/src/math.cpp#L320

dariomanesku avatar Jul 03 '18 08:07 dariomanesku

One particular thing that may have led me to believe BX's vector math was left-handed and integral to BGFX was the debug draw example: Debug Draw Example It has left-handed coordinates and +Y = Up

OswaldHurlem avatar Jul 07 '18 12:07 OswaldHurlem