Partilhar via


Pilhas de matriz (Direct3D 9)

Observação

A biblioteca de utilitários D3DX foi preterida. Recomendamos que você use DirectXMath em vez disso, juntamente com este cabeçalho do GitHub.

A biblioteca de utilitários D3DX fornece a interfaceID3DXMATRIXStack. Ele fornece um mecanismo para permitir que as matrizes sejam empurradas e retiradas de uma pilha de matrizes. A implementação de uma pilha de matrizes é uma maneira eficiente de rastrear matrizes enquanto percorre uma hierarquia de transformação.

A biblioteca de utilitários D3DX usa uma pilha de matrizes para armazenar transformações como matrizes. Os vários métodos do interface ID3DXMATRIXStack lidam com a matriz atual, ou a matriz localizada no topo da pilha. Você pode limpar a matriz atual com o ID3DXMATRIXStack::LoadIdentity método. Para especificar explicitamente uma determinada matriz a ser carregada como a matriz de transformação atual, use o método ID3DXMATRIXStack::LoadMatrix. Em seguida, você pode chamar o método ID3DXMATRIXStack::MultMatrix ou o método ID3DXMATRIXStack::MultMatrixLocal para multiplicar a matriz atual pela matriz especificada.

O método ID3DXMATRIXStack::P op permite que você retorne à matriz de transformação anterior e o método ID3DXMATRIXStack::P ush adiciona uma matriz de transformação à pilha.

As matrizes individuais na pilha de matrizes são representadas como matrizes homogêneas 4x4, definidas pela biblioteca de utilitários D3DX D3DXMATRIX estrutura.

A biblioteca de utilitários D3DX fornece uma pilha de matriz por meio de um objeto COM (component object model).

Implementando uma hierarquia de cena

Uma pilha matricial simplifica a construção de modelos hierárquicos, nos quais objetos complicados são construídos a partir de uma série de objetos mais simples.

Uma hierarquia de cena, ou transformação, geralmente é representada por uma estrutura de dados em árvore. Cada nó na estrutura de dados da árvore contém uma matriz. Uma matriz específica representa a mudança nos sistemas de coordenadas do pai do nó para o nó. Por exemplo, se você estiver modelando um braço humano, poderá implementar a hierarquia mostrada no diagrama a seguir.

diagrama da hierarquia de um braço humano

Nesta hierarquia, a matriz corporal coloca o corpo no mundo. A matriz UpperArm contém a rotação do ombro, a matriz LowerArm contém a rotação do cotovelo e a matriz Hand contém a rotação do pulso. Para determinar onde a mão está em relação ao mundo, você multiplica todas as matrizes do Corpo para baixo através da Mão juntas.

A hierarquia anterior é excessivamente simplista, porque cada nó tem apenas um filho. Se você começar a modelar a mão com mais detalhes, provavelmente adicionará dedos e um polegar. Cada dígito pode ser adicionado à hierarquia como filhos de Hand, como mostrado no diagrama a seguir.

diagrama da hierarquia de uma mão humana

Se você percorrer o gráfico completo do braço em profundidade - percorrendo o mais longe possível por um caminho antes de passar para o próximo caminho - para desenhar a cena, você executa uma sequência de renderização segmentada. Por exemplo, para renderizar a mão e os dedos, implemente o seguinte padrão.

  1. Empurre a matriz Hand para a pilha de matrizes.
  2. Desenhe a mão.
  3. Empurre a matriz Thumb para a pilha de matrizes.
  4. Desenhe o polegar.
  5. Coloque a matriz do polegar fora da pilha.
  6. Empurre a matriz Finger 1 para a pilha de matrizes.
  7. Desenhe o primeiro dedo.
  8. Retire a matriz Finger 1 da pilha.
  9. Empurre a matriz Finger 2 para a pilha de matrizes. Você continua desta maneira até que todos os dedos e polegar sejam renderizados.

Depois de concluir a renderização dos dedos, você colocaria a matriz Hand fora da pilha.

Você pode seguir esse processo básico em código com os exemplos a seguir. Quando você encontrar um nó durante a primeira pesquisa profunda da estrutura de dados da árvore, empurre a matriz para a parte superior da pilha de matrizes.

MatrixStack->Push();

MatrixStack->MultMatrix(pNode->matrix);

Quando terminar de usar um nó, coloque a matriz na parte superior da pilha de matrizes.

MatrixStack->Pop();

Desta forma, a matriz no topo da pilha representa sempre a transformação do mundo do nó atual. Portanto, antes de desenhar cada nó, você deve definir a matriz Direct3D.

pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(0), *MatrixStack->GetTop());

Para obter mais informações sobre os métodos específicos que você pode executar em uma pilha de matriz D3DX, consulte o ID3DXMATRIXStack tópico de referência.

Vertex Pipeline