SvinSimpe
SvinSimpe

Reputation: 870

How to rotate an object around one of its local axis in DirectX11

I want to rotate an object around one of its local axis. In my case the Y-axis. The object has its own world matrix that is initialized like this:

XMFLOAT4X4 newInstance;

// Construct matrix
XMStoreFloat4x4( &newInstance.worldMatrix, XMMatrixScaling( scale.x, scale.y, scale.z ) *
                 XMMatrixRotationRollPitchYaw( XMConvertToRadians( rotation.x ),
                                               XMConvertToRadians( rotation.y ),
                                               XMConvertToRadians( rotation.z ) ) *
                    XMMatrixTranslation( translation.x, translation.y, translation.z ) ) ;

// Add new instance to collection
mInstanceData.push_back( newInstance );

My end goal is to rotate my object based on input from a gamepad.

I don't have a "math-heavy" background so please bear with me on this one. I'm familiar with the importance of order when multiplying matrices (Scale * Rotation * Translation). I've tried several approaches and all fail on me.

1st approach

// Create rotation matrix
XMMATRIX rotationMatrix = XMMatrixRotationY( XMConvertToRadians( angle ) );

// Multiply with old matrix AND store back to the old matrix
XMStoreFloat4x4( &newInstance.worldMatrix, XMLoadFloat4X4( &newInstance.worldMatrix ) * rotationMatrix );

This results in the object rotating around the world Y-axis and not its local axis.

2nd approach

I figured that I need to find my local Y-axis. Perhaps extracting it out of my existing world matrix? I found this post where someone explains that you can indeed extract all the local axis of an object from its world matrix.

A | 1 0 0 0 |
B | 0 1 0 0 |
C | 0 0 1 0 |
D | 0 0 0 1 |
----x y z w

Here, the first three values in row A are your local X-axis = (1,0,0)
first three values in row B are your local Y-axis = (0,1,0)
and first three values in row C are your local z-axis = (0,0,1).

So I went about extracting the Y-axis from the object world matrix.

// Construct axis
XMVECTOR axis =  XMVectorSet( mInstanceData[0].worldMatrix._21, mInstanceData[0].worldMatrix._22, mInstanceData[0].worldMatrix._23, 0 );

// Create rotation matrix based on axis
XMMATRIX rotationMatrix = XMMatrixRotationAxis( axis ,XMConvertToRadians( angle) );

// Multiply with old matrix AND store back to the old matrix
XMStoreFloat4x4( &mInstanceData[0].worldMatrix, XMLoadFloat4x4( &mInstanceData[0].worldMatrix ) * rotationMatrix );

This approach also failed. The result of using XMMatrixRotationAxis is the object rotating around and axis from the world origin to the specified vector.

3rd approach

Then I thought that I could perhaps perform the rotation using the same technique I initialized the matrix with! This meant that I still needed to extract some current data from the objects world matrix. I found this: enter image description here

So I tried to extract any relevant data from the current world matrix and construct new Scale, Rotation and Translation matrices, multiply them and store into the object world matrix.

// Extract scale and translation and construct new matrix
XMStoreFloat4x4( &mInstanceData[0].worldMatrix,  XMMatrixScaling( mInstanceData[0].worldMatrix._11, mInstanceData[0].worldMatrix._22, mInstanceData[0].worldMatrix._33 ) *
        XMMatrixRotationRollPitchYaw( 0.0f, XMConvertToRadians( angle ), 0.0f ) *
        XMMatrixTranslation( mInstanceData[0].worldMatrix._41, mInstanceData[0].worldMatrix._42, mInstanceData[0].worldMatrix._43 ) );

This resulted in the object just morphing itself into something unspeakable.

When all things fail you turn to stackoverlow.. Anyone out there with some insight to share? Thank you!

Upvotes: 2

Views: 4404

Answers (1)

Bartosz Boczula
Bartosz Boczula

Reputation: 349

AFAIU, the 1st approach is correct, however, it seems that first you create a world matrix (hence each of your vertex is in world-space now) and then you apply the 'around-local-y-axis' transformation. IMO, you should first apply XMMatrixRotationY( XMConvertToRadians( angle ) ); to vertexes in model-space and then construct World Matrix.

Upvotes: 2

Related Questions