矩阵堆栈 (Direct3D 9)
注意
D3DX 实用工具库已弃用。 建议改用 DirectXMath 以及 gitHub 此标头。
D3DX 实用工具库提供 ID3DXMATRIXStack 接口。 它提供一种机制,使矩阵能够被推送到矩阵堆栈上并弹出。 实现矩阵堆栈是一种在遍历转换层次结构时跟踪矩阵的有效方法。
D3DX 实用工具库使用矩阵堆栈将转换存储为矩阵。 ID3DXMATRIXStack 接口的各种方法处理当前矩阵或位于堆栈顶部的矩阵。 可以使用 ID3DXMATRIXStack::LoadIdentity 方法清除当前矩阵。 若要显式指定要加载为当前转换矩阵的特定矩阵,请使用 ID3DXMATRIXStack::LoadMatrix 方法。 然后,可以调用 ID3DXMATRIXStack::MultMatrix 方法或 ID3DXMATRIXStack::MultMatrixLocal 方法将当前矩阵乘以指定的矩阵。
ID3DXMATRIXStack::P op 方法使你能够返回到以前的转换矩阵,ID3DXMATRIXStack::P ush 方法向堆栈中添加转换矩阵。
矩阵堆栈上的单个矩阵表示为 4x4 同质矩阵,由 D3DX 实用工具库 D3DXMATRIX 结构定义。
D3DX 实用工具库通过组件对象模型 (COM) 对象提供矩阵堆栈。
实现场景层次结构
矩阵堆栈简化了分层模型的构造,其中复杂对象是从一系列更简单的对象构造的。
场景或转换层次结构通常由树数据结构表示。 树数据结构中的每个节点都包含一个矩阵。 特定矩阵表示从节点的父级到节点的坐标系的变化。 例如,如果要对人臂进行建模,则可以实现下图所示的层次结构。
人臂层次结构的
在此层次结构中,Body 矩阵将正文置于世界。 UpperArm 矩阵包含肩部的旋转,LowerArm 矩阵包含肘部的旋转,手部矩阵包含手腕的旋转。 若要确定手相对于世界的位置,请将所有矩阵从身体向下乘以手。
上一个层次结构过于简单,因为每个节点只有一个子级。 如果开始更详细地对手进行建模,可能会添加手指和拇指。 每个数字都可以作为 Hand 的子级添加到层次结构中,如下图所示。
人工手图
如果按深度优先顺序遍历手臂的完整图-在转到下一个路径之前遍历一条路径-绘制场景,则执行分段呈现序列。 例如,若要呈现手和手指,请实现以下模式。
- 将手部矩阵推送到矩阵堆栈上。
- 绘制手。
- 将 Thumb 矩阵推送到矩阵堆栈。
- 绘制拇指。
- 从堆栈中弹出 Thumb 矩阵。
- 将手指 1 矩阵推到矩阵堆栈上。
- 绘制第一根手指。
- 从堆栈中弹出手指 1 矩阵。
- 将手指 2 矩阵推到矩阵堆栈上。 以这种方式继续,直到呈现所有手指和拇指。
完成手指呈现后,会从堆栈中弹出手部矩阵。
可以使用以下示例在代码中遵循此基本过程。 在深入搜索树数据结构期间遇到节点时,将矩阵推送到矩阵堆栈的顶部。
MatrixStack->Push();
MatrixStack->MultMatrix(pNode->matrix);
使用节点完成后,将矩阵从矩阵堆栈的顶部弹出。
MatrixStack->Pop();
这样,堆栈顶部的矩阵始终表示当前节点的世界转换。 因此,在绘制每个节点之前,应设置 Direct3D 矩阵。
pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(0), *MatrixStack->GetTop());
有关可以在 D3DX 矩阵堆栈上执行的特定方法的详细信息,请参阅 ID3DXMATRIXStack 参考主题。
相关主题