以文本方式查看主题 - 计算机科学论坛 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- 使用.x文件模型(2) (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=75165) |
-- 作者:卷积内核 -- 发布时间:6/1/2009 2:07:00 PM -- 使用.x文件模型(2) 在三维图形程序中的一个模型对应空间中的一个物体,在现实世界中要完全定位一个物体需要6个参数,物体位置坐标的3个分量(x, y, z)和3个欧拉角(偏航角yaw,俯仰角pitch,侧倾角roll)。 3个欧拉角的定义为: (1)偏航角:物体绕自身y轴(即上向量up)旋转的角度。 (2)俯仰角:物体绕自身x轴(即右向量right)旋转的角度。 (3)侧倾角:物体绕自身z轴(即前向量look)旋转的角度。
通过矩阵实现模型旋转 在三维图形程序中模型在世界空间中的位置和姿态都是通过通过其世界矩阵来表示的,所以要在程序中确定一个模型的位置和姿态,就是将控制其状态的6个参数应用到其世界矩阵中。 通过物体的位置和物体的3个自身坐标轴朝向(3个向量)同样也可以完全定位模型,实际上在Direct3D程序中,模型的世界矩阵本身包含了模型的位置向量和3个方向向量,这些向量在世界矩阵中存储的顺序是:第一行是right向量,第二行是up向量,第三行是look向量,第四行是位置向量pos。通过函数D3DXMatrixIdentity()将矩阵设置为单位矩阵,同时也将4个向量都设置为默认值,因此right向量为(1.0f, 0.0f, 0.0f),up向量为(0.0, 1.0f, 0.0f),look向量为(0.0f, 0.0f, 1.0f),pos向量为(0.0f, 0.0f, 0.0f)。这时模型位于世界坐标系原点,并且朝向和世界坐标系的3个坐标轴方向相同。 要改变模型的状态,就是移动物体到指定位置,旋转物体改变其朝向。旋转一个物体实质上就是将look、up、right向量中的两个绕另一个作旋转。比如要横滚物体,就需要将up和right向量绕look向量旋转;要使物体产生俯仰,必须将up和look向量绕right向量旋转;要使物体产生偏航,必须将look和right向量绕up向量旋转。 向量的旋转需要分别借助偏航、俯仰和横滚矩阵来完成,这些矩阵可借助于D3DXMatrixRotationAxis()函数产生,该函数的声明如下: Builds a matrix that rotates around an arbitrary axis. D3DXMATRIX * D3DXMatrixRotationAxis( D3DXMATRIX * pOut, CONST D3DXVECTOR3 * pV, FLOAT Angle); Remarks 有了偏航、俯仰和横滚矩阵,就可以使用函数D3DXVec3TransformCoord()完成这种向量旋转的计算,该函数的声明如下: Transforms a 3D vector by a given matrix, projecting the result back into w = 1. D3DXVECTOR3 * D3DXVec3TransformCoord( D3DXVECTOR3 * pOut, CONST D3DXVECTOR3 * pV, CONST D3DXMATRIX * pM); Remarks The return value for this function is the same value returned in the pOut parameter. In this way, the D3DXVec3TransformCoord function can be used as a parameter for another function. 以下代码具体说明了实现这种旋转的核心内容: static D3DXMATRIX mat_around_right, mat_around_up, mat_around_look; D3DXVec3Normalize(&look, &look); D3DXVec3Cross(&right, &up, &look); D3DXVec3Normalize(&right, &right); D3DXVec3Cross(&up, &look, &right); D3DXVec3Normalize(&up, &up); 示例程序演示了使用矩阵旋转一个飞机模型,程序运行时按下"D"和"A"键,可使飞机模型绕look向量旋转;按下"S"和"W"键,可使飞机模型绕right向量旋转;按下"Q"和"E"键,可使飞机模型绕up向量旋转;按下"F"和"V"键,可使飞机模型向前和向后运动。
|
-- 作者:卷积内核 -- 发布时间:6/1/2009 2:07:00 PM -- 源程序: #pragma warning(disable : 4127) #define CLASS_NAME "GameApp" #define release_com(p) do { if(p) { (p)->Release(); (p) = NULL; } } while(0) IDirect3D9* g_d3d; ID3DXMesh* g_mesh; BYTE g_keys[256]; void setup_world_matrix() elapsed_time = (timeGetTime() - previous_time) / 1000.0f; float angle_around_right = 0.0f, angle_around_up = 0.0f, angle_around_look = 0.0f; if(g_keys['D']) angle_around_look -= 3 * elapsed_time; static D3DXVECTOR3 right, up, look, pos; // save old model pos right.x = g_mat_world._11; up.x = g_mat_world._21; look.x = g_mat_world._31; pos.x = g_mat_world._41; // now, calculate ratation matrix. static D3DXMATRIX mat_around_right, mat_around_up, mat_around_look; D3DXMatrixRotationAxis(&mat_around_up, &up, angle_around_up); D3DXMatrixRotationAxis(&mat_around_look, &look, angle_around_look); D3DXMatrixRotationAxis(&mat_around_right, &right, angle_around_right); // normalize look, right, up to avoid float calculation error D3DXVec3Normalize(&look, &look); // update model pos g_mat_world._11 = right.x; g_mat_world._21 = up.x; g_mat_world._31 = look.x; // move model forward or backward if(g_keys['F']) if(g_keys['V']) g_device->SetTransform(D3DTS_WORLD, &g_mat_world); void setup_view_proj_matrix() D3DXVECTOR3 eye(0.0f, 10.0f, -20.0f); D3DXMATRIX mat_view; // setup projection matrix D3DXMATRIX mat_proj; bool init_geometry() /* if(FAILED(D3DXLoadMeshFromX("airplane.x", D3DXMESH_MANAGED, g_device, NULL, &material_buffer, NULL, D3DXMATERIAL* xmaterials = (D3DXMATERIAL*) material_buffer->GetBufferPointer(); g_mesh_materials = new D3DMATERIAL9[g_num_materials]; for(DWORD i = 0; i < g_num_materials; i++) // set ambient reflected coefficient, because .x file do not set it. g_mesh_textures[i] = NULL; if(xmaterials[i].pTextureFilename != NULL && strlen(xmaterials[i].pTextureFilename) > 0) material_buffer->Release(); return true; bool init_d3d(HWND hwnd) if(g_d3d == NULL) D3DPRESENT_PARAMETERS d3dpp; d3dpp.Windowed = TRUE; if(FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, D3DXMatrixIdentity(&g_mat_world); g_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); void cleanup() if(g_mesh_textures) delete[] g_mesh_textures; void render() g_device->BeginScene(); setup_world_matrix(); for(DWORD i = 0; i < g_num_materials; i++) g_mesh->DrawSubset(i); g_device->Present(NULL, NULL, NULL, NULL); LRESULT WINAPI WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if(wParam == VK_ESCAPE) break; case WM_KEYUP: case WM_DESTROY: return DefWindowProc(hwnd, msg, wParam, lParam); int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR, INT) wc.cbSize = sizeof(WNDCLASSEX); if(! RegisterClassEx(&wc)) HWND hwnd = CreateWindow(CLASS_NAME, "Direct3D App", WS_OVERLAPPEDWINDOW, 200, 100, 640, 480, if(hwnd == NULL) if(init_d3d(hwnd)) MSG msg; while(msg.message != WM_QUIT) cleanup(); return 0;
[B][URL=http://www.cppblog.com/Files/changingnow/StateControlUseMatrix.rar]下载示例工程[/URL][/B]
|
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
93.750ms |