Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have a simple realisation of entity/component game engine.
Transform component have methods to set local position, local rotation, global position and global rotation.

If transform is being set new global position, then local position also changes, to update local position in such case I'm just applying current transform local matrix to parent's transform world matrix.

Until then I have no problems, I can get updated local transform matrix.
But I'm struggling on how to update local position and rotation value in transform. Only solution I have in mind is to extract translation & rotation values from localMatrix of transform.

For translation it's quite easy - I just take 4th column values. but what's about rotation?
How to extract euler angles from transformation matrix?

Is such solution right?:
To find rotation around Z axis, we can find difference between X axis vector of localTransform and X axis vector of parent.localTransform and store result in Delta, then: localRotation.z = atan2(Delta.y, Delta.x);

Same for rotation around X & Y, just need to swap axis.

share|improve this question

1 Answer 1

up vote 3 down vote accepted

Normally I store all objects as 4x4 Matrices (you could do 3x3 but easier for me just to have 1 class) instead of translating back and forth between a 4x4 and 3 sets of vector3s (Translation, Rotation, Scale). Euler angles are notoriously difficult to deal with in certain scenarios so I would recommend using Quaternions if you really want to store the components instead of a matrix.

But here is some code I found a while back that works. I hope this helps, unfortunately I do not have the original source for where I found this. I have no idea what odd scenarios it may not work in. I am currently using this to get the rotation of YawPitchRoll rotated, left handed 4x4 matrices.

   union {
        struct 
        {
            float        _11, _12, _13, _14;
            float        _21, _22, _23, _24;
            float        _31, _32, _33, _34;
            float        _41, _42, _43, _44;
        };
        float m[4][4];
        float m2[16];
    };

    inline void GetRotation(float& Yaw, float& Pitch, float& Roll) const
    {
        if (_11 == 1.0f)
        {
            Yaw = atan2f(_13, _34);
            Pitch = 0;
            Roll = 0;

        }else if (_11 == -1.0f)
        {
            Yaw = atan2f(_13, _34);
            Pitch = 0;
            Roll = 0;
        }else 
        {

            Yaw = atan2(-_31,_11);
            Pitch = asin(_21);
            Roll = atan2(-_23,_22);
        }
    }

Here is another thread I found while trying to answer your question that looked like a similar result to mine.

http://stackoverflow.com/questions/1996957/conversion-euler-to-matrix-and-matrix-to-euler

share|improve this answer
    
It seems that my proposed solution is almost right, just don't know why isntead of atan2 asin is used for pitch. –  Denis Narushevich Mar 13 '13 at 16:57
    
Also, how it would help me, if I would store each component in separate mat4x4? How could I then get and e.g. output angle of rotation around some axis? –  Denis Narushevich Mar 13 '13 at 16:57
    
Your original question lead me to believe that you are storing your objects as 3 vector3s: Translation, Rotation, and Scale. Then when you creating a localTransform out of those doing some work and later attempting to convert (localTransform*globalTransform) back into 3 vector3s. I could be totally wrong I was just getting that impression. –  NtscCobalt Mar 13 '13 at 17:00
    
Yeah I don't know the math well enough for why pitch is done with ASIN but the linked question uses the same math so I believe it is correct. I've been using this function for a while to without any issue. –  NtscCobalt Mar 13 '13 at 17:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.