里记录一下矩阵的基本操作和矩阵乘法的顺序问题。
1: while( msg.message!=WM_QUIT )
2: {
3: // check for messages
4: if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
5: {
6: TranslateMessage( &msg );
7: DispatchMessage( &msg );
8: }
9: // this is called when no messages are pending
10: else
11: {
12: // Clear the backbuffer to a black color
13: pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,255), 1.0f, 0 );
14:
15: pd3dDevice->BeginScene();
16:
17: pd3dDevice->SetStreamSource( 0, vertexBuffer, 0, sizeof(CUSTOMVERTEX) );
18: pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
19:
20: // translate the object away from the origin
21: D3DXMatrixTranslation(&matTranslate, 64.0f, 0.0f, 0.0f);
22:
23: // set the rotation
24: D3DXMatrixRotationY(&matRotate, timeGetTime()/1000.0f);
25:
26: // multiple the translation and rotation matrices to create the objMat matrix
27: D3DXMatrixMultiply(&objMat, &matRotate, &matTranslate);
28: D3DXMatrixMultiply(&objMat, &matTranslate, &matRotate);
29:
30: // transform the object in world space
31: pd3dDevice->SetTransform(D3DTS_WORLD, &objMat);
32:
33: pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
34: pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 4, 2 );
35: pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 8, 2 );
36: pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 12, 2 );
37: pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 16, 2 );
38: pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 20, 2 );
39:
40: pd3dDevice->EndScene();
41:
42: // Present the backbuffer contents to the display
43: pd3dDevice->Present( NULL, NULL, NULL, NULL );
44: }
45: }
第21行和第23行的顺序其实是没有关系的。关键是第27行和第28行的区别。这里先插一句timeGetTime函数的用法。MSND上是这样说的:
The timeGetTime function retrieves the system time, in milliseconds. The system time is the time elapsed since Windows was started.
DWORD timeGetTime(VOID);
The only difference between this function and the timeGetSystemTime function is that timeGetSystemTime uses the MMTIME structure to return the system time. The timeGetTime function has less overhead than timeGetSystemTime.
所以timeGetTime得到的是一个递增的毫秒值。
第27行:matRotate * matTranslate,表示先平移后旋转(顺序与表达式刚好相反),效果就是绕着一根轴旋转,而该轴是Y轴向右(X轴正方向)平移6个单位。
第28行: matTranslate * matRotate,表示先旋转和平移。效果就是绕着Y轴旋转,旋转半径是64。可以在脑海中想一下,是这样叠加而成的:先在源点转一个角度,此时X轴也跟着旋转了,然后再向X轴平移64个单位。
怎样理解这种变换:前一个矩阵变换会影响后一个矩阵变换。据我所知,世界坐标是一个客观存在,那么可以推测以上的矩阵变换中的坐标都是围绕着物体模型本身的坐标。
比如第27行,物体先向X轴平移64个单位,此时物体模型的坐标系也向X轴平移了64个单位,然后再绕Y轴旋转,此时的Y轴不是世界坐标中的Y轴,而是物体模型坐标中经过平移之后的Y轴。这是可以解释的。
同样第28行,物体先绕着物体模型坐标系的Y轴旋转一个角度(此时,物体模型坐标系和世界坐标系是重合的),这时物体模型坐标系像前面一样,也旋转了同样的角度。此时物体模型坐标系的X轴与世界坐标系的X轴已经不再重合,此时再平移,是沿着物体坐标系的X轴向“右”平移64个单位。这也解释得通。
以上的推测,就是基于一点,世界坐标是客观存在的,它不会为其中一个物体的变换而变换。
分享到:
相关推荐
`o3djs` 包含了 O3D 的辅助库,提供了许多实用的工具函数和类,如加载管理器、动画系统、矩阵和向量操作等,它们简化了 O3D 开发过程,帮助开发者更高效地构建应用。 总的来说,这个 O3D 实例是一个典型的入门项目...
O3D库使用这些数学概念来表示位置、旋转和缩放,以及进行投影和平移等操作。开发者需要熟悉线性代数和几何学的基本知识。 5. **场景图**:O3D使用场景图来组织3D对象。场景图是一种层次结构,其中每个节点代表一个...
【标题】"o3d-webgl-pool" 是一个基于废弃的 o3d 引擎开发者构建的3D台球游戏演示项目。这个项目利用了WebGL技术来呈现逼真的3D图形,让玩家能够在浏览器中体验台球游戏的乐趣。 【JavaScript】作为主要的编程语言...
首先,`dgemm`是BLAS(基础线性代数子程序库)的一部分,这是一个广泛使用的库,提供了一系列用于处理线性代数问题的基本操作。`d`代表双精度,`gemm`则代表Generalized Matrix Multiply,即通用矩阵乘法。它能高效...
总的来说,这个资源对于理解OBB和OpenGL碰撞检测的实现非常有帮助,不仅可以学习到如何构建和操作OBB,还能了解到如何在实际场景中应用这些概念。对于希望提升游戏开发或3D应用技术的人来说,这是一个宝贵的参考资料...
速度雅可比矩阵是从关节速度向末端操作速度的线性变换。 2. 速度雅可比矩阵的推导 上面的运动学方程两边对时间求导,得到下面的速度表达式: (17) 把上式写成如下的矩阵形式: (18) 令上式中的末端位置...
- **结构**:由微型Al2O3陶瓷管、SnO2敏感层、测量电极和加热器等组成。 - **工作原理**:通过加热回路和信号输出回路工作,输出电压范围为0-5V。 2. **A/D转换电路** - **ADC0809**:8位逐次逼近型A/D转换器,...
- **数据输入(D0–D3):** 在写入操作期间,将数据输入到存储器中。 - **倒相数据输出(O0–O3):** 在读取模式下,输出存储器中存储的4位数据的倒相值。 - **芯片选择输入(CS):** 当CS为低电平时,选中该...