Matrix Transformation

Well it’s been sometime since I posted. But I thought for those that are interested, I will post a random topic I have been working with. That would be as the title suggests transformation of object via matrix and vector math. So in general there are 3 basic transformations those include: translation, Rotation, and scaling. These are the three that move object through out 3D space. In addition to those, projection transformation is used to go from view space to projection space. The D3DX library contains APIs that can conveniently construct a matrix for many purposes such as translation, rotation, scaling, world-to-view transformation, view-to-projection transformation, etc. An application can then use these matrices to transform vertices in its scene. Conveniently for some an understanding of the math isn’t really required to do some basic stuff. The transformations I am doing will be as such.

So!

Translation

Translation refers to moving or displacing for a certain distance in space. In 3D, the matrix used for translation has the form

    1  0  0  0
    0  1  0  0
    0  0  1  0
    a  b  c  1

Rotation

Rotation refers to rotating vertices about an axis going through the origin. Three such axes are the X, Y, and Z axes in the space. An example in 2D would be rotating the vector [1 0] 90 degrees counter-clockwise. The result from the rotation is the vector [0 1]. The matrix used for rotating ΐ degrees clockwise about the Y axis looks like this:

    cosΐ  0  -sinΐ   0
     0    1     0    0
    sinΐ  0   cosΐ  0
     0    0     0    1

Scaling

Scaling refers to enlarging or shrinking the size of vector components along axis directions. For example, a vector can be scaled up along all directions or scaled down along the X axis only. To scale, we usually apply the scaling matrix below:

    p  0  0  0
    0  q  0  0
    0  0  r  0
    0  0  0  1

where p, q, and r are the scaling factor along the X, Y, and Z direction, respectively. The figure below shows the effect of scaling by 2 along the X axis and scaling by 0.5 along the Y axis.

These three I stated above can be multiplied with each other to combine their effect. This is where you can start to get certain effects and movements  that can get the idea you are trying to get across. I created three cubes in the directx sample I will show. The sample you’ll see will include 1 cube in the middle as a type of planet. and two smaller “moon” cubes orbiting in differing axis and speeds. I will show the main transformation source code below.

void Render()
{
// Update our time
static float t = 0.0f;
if( g_driverType == D3D10_DRIVER_TYPE_REFERENCE )
{
t += ( float )D3DX_PI * 0.0125f;
}
else
{
static DWORD dwTimeStart = 0;
DWORD dwTimeCur = GetTickCount();
if( dwTimeStart == 0 )
dwTimeStart = dwTimeCur;
t = ( dwTimeCur – dwTimeStart ) / 1000.0f;
}

// 1st Cube: Rotate around the origin
D3DXMatrixRotationY( &g_World1, t );

// 2nd Cube: Rotate around origin
D3DXMATRIX mTranslate;
D3DXMATRIX mXTranslate;
D3DXMATRIX mYOrbit;
D3DXMATRIX mXOrbit;
D3DXMATRIX mSpin;
D3DXMATRIX mScale;
D3DXMATRIX m3Scale;
D3DXMatrixRotationZ( &mSpin, -t );
D3DXMatrixRotationY( &mYOrbit, -t * 2 );
D3DXMatrixRotationX( &mXOrbit, -t * 4 );
D3DXMatrixTranslation( &mTranslate, -4.0f, 0.0f, 0.0f );
D3DXMatrixTranslation( &mXTranslate, 0.0f, 3.0f, 0.0f );
D3DXMatrixScaling( &mScale, 0.3f, 0.3f, 0.3f );
D3DXMatrixScaling( &m3Scale, 0.2f, 0.2f, 0.2f );

D3DXMatrixMultiply( &g_World2, &mScale, &mSpin );
D3DXMatrixMultiply( &g_World2, &g_World2, &mTranslate );
D3DXMatrixMultiply( &g_World2, &g_World2, &mYOrbit );

//3rd cube
D3DXMatrixMultiply( &g_World3, &mSpin, &m3Scale );
D3DXMatrixMultiply( &g_World3, &g_World3, &mXTranslate );
D3DXMatrixMultiply( &g_World3, &g_World3, &mXOrbit );
// D3DXMatrixMultiply( &g_World3, &g_World3, &mYOrbit );

//
// Clear the back buffer
//
float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; //red, green, blue, alpha
g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );

//
// Clear the depth buffer to 1.0 (max depth)
//
g_pd3dDevice->ClearDepthStencilView( g_pDepthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0 );

//
// Update variables for the first cube
//
g_pWorldVariable->SetMatrix( ( float* )&g_World1 );
g_pViewVariable->SetMatrix( ( float* )&g_View );
g_pProjectionVariable->SetMatrix( ( float* )&g_Projection );

//
// Render the first cube
//
D3D10_TECHNIQUE_DESC techDesc;
g_pTechnique->GetDesc( &techDesc );
for( UINT p = 0; p < techDesc.Passes; ++p )
{
g_pTechnique->GetPassByIndex( p )->Apply( 0 );
g_pd3dDevice->DrawIndexed( 36, 0, 0 );
}

//
// Update variables for the second cube
//
g_pWorldVariable->SetMatrix( ( float* )&g_World2 );
g_pViewVariable->SetMatrix( ( float* )&g_View );
g_pProjectionVariable->SetMatrix( ( float* )&g_Projection );

//
// Render the second cube
//
for( UINT p = 0; p < techDesc.Passes; ++p )
{
g_pTechnique->GetPassByIndex( p )->Apply( 0 );
g_pd3dDevice->DrawIndexed( 36, 0, 0 );
}

//
// Update variables for the third cube
//
g_pWorldVariable->SetMatrix( ( float* )&g_World3 );
g_pViewVariable->SetMatrix( ( float* )&g_View );
g_pProjectionVariable->SetMatrix( ( float* )&g_Projection );

//
// Render the third cube
//
for( UINT p = 0; p < techDesc.Passes; ++p )
{
g_pTechnique->GetPassByIndex( p )->Apply( 0 );
g_pd3dDevice->DrawIndexed( 36, 0, 0 );
}

//
// Present our back buffer to our front buffer
//
g_pSwapChain->Present( 0, 0 );
}

Any comments would be appreciated.

Thanks for reading.

Doug.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s