Camera system, rotating an object regardless the camera
hey,
I know its a very basic question but I dont know how to figure out.
I have a Quaternion-based camera system. I created my 3D objects, and I can move in it, rotate freely etc (like a spectator mode in an FPS) so everything is OK yet.
Now I want to rotate a cube (not physically - no lock - rotate sin/cos - unlock).
I know I have to do this all with VIEW matrixes. When I save the current view matrix, doesnt do anything with it, apply it, draw cube, and apply the original view matrix, nothing happens - I meant thats the correct behaviour.
When I do this:
D3DXMatrixRotationY( aWorldMatX, 1 );
D3DXMatrixMultiply( aWorldMat, aWorldMat, aWorldMatY );
then it brilliantly gyros around me - not around its origo. Cube is put the origo (1.5, -1.5 coords), originally not translated!
Can anyone give me some formulas how to rotate this cube so that it remains where its set originall?
And if I do this:
D3DXMatrixRotationX( aWorldMatX, gyro );
D3DXMatrixRotationY( aWorldMatY, gyro );
D3DXMatrixRotationZ( aWorldMatZ, gyro );
D3DXMatrixMultiply( aWorldMat, aWorldMatX, aWorldMatY );
D3DXMatrixMultiply( aWorldMat, aWorldMat, aWorldMatY );
then it does gyro around me - but then it "follows" me, I cant go out of this box!
some1 very smart told me once that the order that u multiply the matrices are important.
The general way to do it is
worldMat=scaleMat*rotationMat*translationMat;
For this case the scaleMat should be an identity matrix so u can ignore it.
thus becomes
worldMat=rotationMat*translationMat;// this will rotate around its own axes
worldMat=translationMat*rotationMat;// this will rotate around the world origin
so lets say u want to move the cube to (2,5,-8) and let it rotate around its own axis then u would do the following:
// in your render call
D3DXMATRIX worldMat,translationMat,rotationMat;
D3DXMatrixTranslation(&translationMat,2,5,-8); // saves the translation
D3DXMatrixRotationY(&,timeGetTime()/100.0f);// rotate around Y-axis
worldMat=rotationMat*translationMat;
//worldMat=translationMat*rotationMat; //this will rotate around the map origin
dev->SetTransform(D3DTS_WORLD, &worldMat);
// now draw the cube
i hope this helps
The general way to do it is
worldMat=scaleMat*rotationMat*translationMat;
For this case the scaleMat should be an identity matrix so u can ignore it.
thus becomes
worldMat=rotationMat*translationMat;// this will rotate around its own axes
worldMat=translationMat*rotationMat;// this will rotate around the world origin
so lets say u want to move the cube to (2,5,-8) and let it rotate around its own axis then u would do the following:
// in your render call
D3DXMATRIX worldMat,translationMat,rotationMat;
D3DXMatrixTranslation(&translationMat,2,5,-8); // saves the translation
D3DXMatrixRotationY(&,timeGetTime()/100.0f);// rotate around Y-axis
worldMat=rotationMat*translationMat;
//worldMat=translationMat*rotationMat; //this will rotate around the map origin
dev->SetTransform(D3DTS_WORLD, &worldMat);
// now draw the cube
i hope this helps
D3DTS_WORLD tells your graphics device where to draw an object. U have to use D3DTS_VIEW and D3DTS_PROJECTION as well.
U need all 3 transforms to view an 3D scene. The view tells the device where u r looking from, the projection tells the device how to project objects in 3D space and lastly D3DTS_WORLD specifies where/how large and how the object is rotated that u r rendering.
I can give u an complete example that will rotate an object around its own axis if u like?
U need all 3 transforms to view an 3D scene. The view tells the device where u r looking from, the projection tells the device how to project objects in 3D space and lastly D3DTS_WORLD specifies where/how large and how the object is rotated that u r rendering.
I can give u an complete example that will rotate an object around its own axis if u like?
try this code, i assume u r using visual studio's C++
// the window class to use
// the title bar text
// the window style
CW_USEDEFAULT, // the starting x coordinate
CW_USEDEFAULT, // the starting y coordinate
1024, // the pixel width of the window
768, // the pixel height of the window
NULL, // the parent window; NULL for desktop
NULL, // the menu for the application; NULL for
// none
hInstance, // the handle to the application instance
NULL); // no values passed to the window
// Make sure that the window handle that is created is valid
if (!wndHandle)
return false;
// Display the window on the screen
ShowWindow(wndHandle, SW_SHOW);
UpdateWindow(wndHandle);
return true;
}
INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow )
{
// Initialize the window
if(!initWindow( hInstance ) )
return false;
if(!init3D())
return false;
MSG msg;
ZeroMemory( &msg, sizeof( msg ) );
while( msg.message!=WM_QUIT )
{
// Check the message queue
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage ( &msg );
DispatchMessage ( &msg );
}
if(pd3dDevice!=NULL)
{
render();
}
}
return (int) msg.wParam;
}
I tested this so i know it works
#include <Windows.h>#include <mmsystem.h>#include <d3d9.h>#pragma warning( disable : 4996 ) // disable deprecated warning #include <d3dx9.h>#pragma warning( disable : 4996 ) // disable deprecated warning #include <strsafe.h>#pragma warning( disable : 4996 ) // disable deprecated warning HINSTANCE hInst; // global handle to hold the application instanceHWND wndHandle; // global variable to hold the window handleLPDIRECT3D9 pD3D=NULL; //objectLPDIRECT3DDEVICE9 pd3dDevice=NULL; //deviceLPD3DXMESH cube=NULL;void cleanUp(){ if(pD3D!=NULL) pD3D->Release(); if(pd3dDevice!=NULL) { pd3dDevice->Release(); pd3dDevice=NULL; } if(cube!=NULL) cube->Release();}VOID cameraStuff(){ //////////////FOV+PROECTION/////////////////////////// D3DXMATRIX matProj,matView; float nearClip=0.01f,farClip=17500; D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/3.0, 4.0f/3.0f, nearClip, farClip); pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj); //////////////FOV+PROECTION/////////////////////////// /////////////CAMERA/////////////////////////////////// D3DXVECTOR3 cameraPosition(0.0f,5.0f,-5.0f),cameraLook(0.0f,0.0f,0.0f); D3DXMatrixLookAtLH (&matView, &cameraPosition, //camera position &cameraLook, //look at position &D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); //up direction pd3dDevice->SetTransform (D3DTS_VIEW, &matView); }void DrawCube1()//will rotate around its own axis (Y axis) at pos(1,1,1){ D3DXMATRIX world,rot,pos; D3DXMatrixTranslation(&pos,1,1,1); D3DXMatrixRotationY(&rot,timeGetTime()/1000.0f); world=rot*pos; pd3dDevice->SetTransform(D3DTS_WORLD,&world); cube->DrawSubset(0);}void DrawCube2()//will rotate (Y axis) around the world origin (0,0,0) at a distance 1{ D3DXMATRIX world,rot,pos; D3DXMatrixTranslation(&pos,1,1,1); D3DXMatrixRotationY(&rot,timeGetTime()/1000.0f); world=pos*rot; pd3dDevice->SetTransform(D3DTS_WORLD,&world); cube->DrawSubset(0);}void render(){ pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER ,D3DCOLOR_XRGB( 0,128,255 ), 1.0f, 0 );//clear to black /* * The camera u can now change to look at any point from any point using your code */ cameraStuff();//setup camera if( SUCCEEDED( pd3dDevice->BeginScene() ) ) { DrawCube1(); DrawCube2(); pd3dDevice->EndScene(); pd3dDevice->Present(NULL,NULL,NULL,NULL); }}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ // Check any available messages from the queue switch (message) { case WM_DESTROY:{ cleanUp(); PostQuitMessage(0); }break; } return DefWindowProc(hWnd, message, wParam, lParam);}HRESULT init3D(){ if(NULL==(pD3D=Direct3DCreate9( D3D_SDK_VERSION )) ) { return false; } D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof( d3dpp ) ); d3dpp.Windowed=TRUE; d3dpp.hDeviceWindow = wndHandle; d3dpp.BackBufferHeight = 768; d3dpp.BackBufferWidth = 1024; d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat=D3DFMT_X8R8G8B8;//D3DFMT_UNKNOWN; d3dpp.BackBufferCount=2; d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; //create main device if( FAILED( pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wndHandle, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice ) ) ) { return false; } pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE ); pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); pd3dDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE ); pd3dDevice->SetRenderState (D3DRS_SPECULARENABLE, FALSE); D3DXCreateBox(pd3dDevice,1.0f,1.0f,1.0f,&cube,NULL);//generate Cube return true;}bool initWindow( HINSTANCE hInstance ){ WNDCLASSEX wcex; // Fill in the WNDCLASSEX structure. This describes how the window // will look to the system wcex.cbSize = sizeof(WNDCLASSEX); // the size of the structure wcex.style = CS_HREDRAW | CS_VREDRAW; // the class style*/ wcex.lpfnWndProc = WndProc; // the window procedure callback wcex.cbClsExtra = 0; // extra bytes to allocate for this class wcex.cbWndExtra = 0; // extra bytes to allocate for this instance wcex.hInstance = hInstance; // handle to the application instance wcex.hIcon = 0; // icon to associate with the application wcex.hCursor = LoadCursor(NULL, IDC_ARROW);// the default cursor wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_PEN);//(HBRUSH)(COLOR_WINDOW+1); // the background color wcex.lpszMenuName = NULL; // the resource name for the menu wcex.lpszClassName = "Test"; // the class name being created wcex.hIconSm = 0; // the handle to the small icon RegisterClassEx(&wcex); // Create the window wndHandle = CreateWindow( "Test", "Test", WS_OVERLAPPEDWINDOW | WS_EX_TOPMOST | WS_VISIBLE, /*WS_OVERLAPPEDWINDOW, //WIndowed*/ //WS_POPUP only graph window
// the window class to use
// the title bar text
// the window style
CW_USEDEFAULT, // the starting x coordinate
CW_USEDEFAULT, // the starting y coordinate
1024, // the pixel width of the window
768, // the pixel height of the window
NULL, // the parent window; NULL for desktop
NULL, // the menu for the application; NULL for
// none
hInstance, // the handle to the application instance
NULL); // no values passed to the window
// Make sure that the window handle that is created is valid
if (!wndHandle)
return false;
// Display the window on the screen
ShowWindow(wndHandle, SW_SHOW);
UpdateWindow(wndHandle);
return true;
}
INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow )
{
// Initialize the window
if(!initWindow( hInstance ) )
return false;
if(!init3D())
return false;
MSG msg;
ZeroMemory( &msg, sizeof( msg ) );
while( msg.message!=WM_QUIT )
{
// Check the message queue
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage ( &msg );
DispatchMessage ( &msg );
}
if(pd3dDevice!=NULL)
{
render();
}
}
return (int) msg.wParam;
}
I tested this so i know it works
Quote:Original post by Kapoef
some1 very smart told me once that the order that u multiply the matrices are important.
It is. The multiplication order of a matrix is ISR(O)T
Matrix Identity * Scale * Rotation * (Origin Matrix) * Translation
D3DTS_WOLRD tells D3D to set the world transformation in (I assume) the vertex-shader. In XNA we have no default shader, I'm not sure about DirectX, but you must be using one in some form or way.
Just as D3DTS_VIEW sets the view transformation. This is the orientation of your "camera" view.
D3DTS_PROJECTION sets the projection matrix which describes how everything should be rendered. I.e aspect ratio, near-plane, far-plane, etc is held here.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement