LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
Cleanup();
PostQuitMessage( 0 );
return 0;
case WM_CHAR:
switch (wParam)
{
case 'w':
m_zPos+=1;
break;
case 's':
m_zPos-=1;
break;
case 'a':
m_xPos-=1;
break;
case 'd':
m_xPos+=1;
case 'e':
m_fYaw+=1;
break;
case 'q':
m_fYaw-=1;
break;
};
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
БагЪ с матрицами в директе
взял дефолтовый пример из DirectX SDK, решил его немного подправить, чтобы вращающаяся модель тигра вращалась и ПЕРЕМЕЩАЛАСЬ не в зависимости от системного времени, а в зависимости от нажатых клавиш, то есть реализовать WASD-управление. Функцию MsgProc изменил следующим образом:
Код:
Функцию SetupMatrices:
Код:
VOID SetupMatrices()
{
D3DXMATRIX MatTemp; // Temp matrix for rotations.
D3DXMATRIX MatRot; // Final rotation matrix, applied to
// pMatWorld.
// Using the left-to-right order of matrix concatenation,
// apply the translation to the object's world position
// before applying the rotations.
D3DXMatrixTranslation(&pMatWorld, m_xPos, m_yPos, m_zPos);
D3DXMatrixIdentity(&MatRot);
// Now, apply the orientation variables to the world matrix
if(m_fPitch || m_fYaw || m_fRoll)
{
// Produce and combine the rotation matrices.
D3DXMatrixRotationX(&MatTemp, m_fPitch); // Pitch
D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp);
D3DXMatrixRotationY(&MatTemp, m_fYaw); // Yaw
D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp);
D3DXMatrixRotationZ(&MatTemp, m_fRoll); // Roll
D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp);
// Apply the rotation matrices to complete the world matrix.
D3DXMatrixMultiply(&pMatWorld, &MatRot, &pMatWorld);
g_pd3dDevice->SetTransform( D3DTS_WORLD, &pMatWorld );
}
}
{
D3DXMATRIX MatTemp; // Temp matrix for rotations.
D3DXMATRIX MatRot; // Final rotation matrix, applied to
// pMatWorld.
// Using the left-to-right order of matrix concatenation,
// apply the translation to the object's world position
// before applying the rotations.
D3DXMatrixTranslation(&pMatWorld, m_xPos, m_yPos, m_zPos);
D3DXMatrixIdentity(&MatRot);
// Now, apply the orientation variables to the world matrix
if(m_fPitch || m_fYaw || m_fRoll)
{
// Produce and combine the rotation matrices.
D3DXMatrixRotationX(&MatTemp, m_fPitch); // Pitch
D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp);
D3DXMatrixRotationY(&MatTemp, m_fYaw); // Yaw
D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp);
D3DXMatrixRotationZ(&MatTemp, m_fRoll); // Roll
D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp);
// Apply the rotation matrices to complete the world matrix.
D3DXMatrixMultiply(&pMatWorld, &MatRot, &pMatWorld);
g_pd3dDevice->SetTransform( D3DTS_WORLD, &pMatWorld );
}
}
Наблюдаю стабильно следующий БагЪ: при нажатии любых кнопок кроме “D” ничего не происходит, модель остается стоять на месте, а при нажатии “D” модель сдвигается-таки вправо и ЕЩЁ ПОВОРАЧИВАЕТСЯ!!! Не знаю уже что с этим делать! Ни у кого нет примера нормальной реализации перемещения в директе, но чтобы было в то же время просто? И как мне переделать свой пример? Может кто с таким уже сталкивался??
Всё объяснимо. Так как ты забыл написать break после проверки на совпадение нажатой клавиши клавише 'd', то весь код, расположенный до следующего break (а это case 'e':m_fYaw+=1) выполняется каждый раз, когда нажимается 'd'. Именно поэтому происходит сдвиг и поворот одновременно. Далее. Видовая матрица у тебя обновляется только в том случае, если был осуществлен какой-либо поворот: if(m_fPitch || m_fYaw || m_fRoll), поэтому при нажатии клавиш, отвечающих за сдвиг, изображение не меняется. Для исправления этой ошибки вызов g_pd3dDevice->SetTransform( D3DTS_WORLD, &pMatWorld ) следует вынести из блока проверки условия.
C ума сойти! Всё из-за моей невнимательности! Как я только не насиловал этот бежный пример: даже в отладчике воевал с ним, а всё оказалось так просто... Спасибо огромное, Akela!