世界转型 (Direct3D 9)

世界转型的讨论介绍了基本概念,并提供了有关如何设置世界转型的详细信息。

什么是世界转型?

世界变换将坐标从模型空间(其中顶点相对于模型的本地原点定义)更改为世界空间,其中顶点相对于场景中所有对象通用的原点进行定义。 本质上,世界转换将模型放入世界空间中;然后是它的名称。 下图显示世界坐标系和模型的本地坐标系之间的关系。

世界坐标和本地坐标的相关方式的图示

世界转换可包含转换、旋转和缩放的任意组合。

设置世界矩阵

与任何其他转换一样,通过将一系列矩阵连接到一个包含其效果总计的矩阵来创建世界转换。 在最简单的情况下,当模型位于世界原点且其本地坐标轴的方向与世界空间的相同时,世界矩阵为标识矩阵。 更常见的情况是,世界矩阵是世界空间中的转换与根据需要对模型进行的一次或多次旋转的组合。

以下示例从用 C++ 编写的虚构 3D 模型类中,使用 D3DX 实用工具库中包含的帮助程序函数创建一个包含三个旋转的世界矩阵,用于定位模型,以及一个转换以相对于其在世界空间中的位置进行重定位。

/*
 * For the purposes of this example, the following variables
 * are assumed to be valid and initialized.
 *
 * The m_xPos, m_yPos, m_zPos variables contain the model's
 * location in world coordinates.
 *
 * The m_fPitch, m_fYaw, and m_fRoll variables are floats that 
 * contain the model's orientation in terms of pitch, yaw, and roll
 * angles, in radians.
 */
 
void C3DModel::MakeWorldMatrix( D3DXMATRIX* 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);
    }
}

准备世界矩阵后,调用 IDirect3DDevice9::SetTransform 方法进行设置,为第一个参数指定 D3DTS_WORLD 宏。

注意

Direct3D 使用你设置的世界矩阵和视图矩阵来配置多个内部数据结构。 每当你设置新的世界矩阵或视图矩阵时,系统将重新计算关联的内部结构。 从计算方面来看,频繁设置这些矩阵(例如,每帧数千次)是非常耗时的。 你可以通过将世界矩阵和视图矩阵连接到设为世界矩阵的世界-视图矩阵,并将视图矩阵设置为标识来最大程度地减少所需的计算次数。 保留单个世界矩阵和视图矩阵的缓存副本,以便能根据需要修改、连接和重置世界矩阵。 为清楚起见,本文档中的 Direct3D 示例很少采用这种优化。

 

转换