Vamos aprender XNA? – Parte 6 – Loading 3D Models

Publicado em 29/04/2011

6


Olá pessoal, como estamos?

Se você está “chegando agora”, talvez queira dar uma olhada nos posts anteriores dessa série.

No post anterior, mostrei como desenhar um cubo 3D que pode ser rotacionado. Hoje, vou mostrar como fazer isso com um modelo 3D mais complexo, carregado de um arquivo.

Se desejar, você pode pegar o código-fonte do post de hoje em https://github.com/ElemarJR/VamosAprenderXNA.

Por que carregar modelos 3D de arquivos?

Nos posts anteriores, você viu que é possível desenhar qualquer coisa usando apenas triângulos. Embora isso seja verdade, isso será extremamente trabalhoso. Se o código para desenhar um cubo já foi extenso, imagine desenhar um objeto mais complexo, como um “humano”.

Quando desenhamos objetos mais complexos, usamos modelos 3D. Basicamente, um modelo 3D é uma coleção de informações necessárias para desenhar os triângulos que formam um modelo 3D mais complexo.

Modelos 3D são, geralmente, construídos em programas específicos para esse propósito. Entre os programas mais populares para esse fim estão 3D Studio, Blender, Rhinoceros, entre outros. O Blender é open-source e free.

Formatos de modelo 3D suportados pelo XNA

Modelos 3D podem ser salvos em diversos formatos. XNA suporta apenas arquivos .X e .FBX (criado pela AutoDesk).

Caso você possua um arquivo em um formato diferente, poderá converter facilmente para .X ou .FBX utilizando o Blender.

Adicionando modelos 3D em um projeto XNA

Para adicionar modelos 3D em um projeto com XNA, basta adicionar os arquivos correspondente no projeto da Content Pipeline. Após adicionar o arquivo, se o projeto compilar com êxito, sabemos que o arquivo foi interpretado e entendido.

Alguns arquivos 3D tem referências para arquivos com texturas. Nesse caso, será necessário manter esses arquivos nos caminhos especificados.

No post de hoje, estou utilizando um arquivo .X que era distribuído, originalmente, junto ao SDK do DirectX.

image

Código para carregar um modelo 3D

Carregar um modelo 3D é uma operação trivial. Mantendo o patter que já apresentei nos últimos posts, indico a carga desse dado no método LoadContent. Observe:


              
Model CurrentModel;
protected override void LoadContent()
{
    this.CurrentModel = Content.Load(@"models\spaceship");
}

            

Note que a única mudança em relação a carga de uma textura é a substituição do parâmetro de tipo. A classe Model é utilizada para representar os dados correspondentes a um modelo 3D na memória.

Desenhando um modelo 3D

Aqui, outra operação simples. Observe:


              
Matrix worldRotation = Matrix.Identity;
Matrix worldTranslation = Matrix.Identity;
Matrix worldScale = Matrix.Identity;

protected override void Draw(GameTime gameTime)
{
    foreach (ModelMesh mesh in CurrentModel.Meshes)
    {
        foreach (BasicEffect be in mesh.Effects)
        {
            be.EnableDefaultLighting();
            be.Projection = this.CurrentCamera.Projection;
            be.View = this.CurrentCamera.View;
            be.World = worldScale * worldRotation * worldTranslation
                * mesh.ParentBone.Transform;
        }
        mesh.Draw();
    }
}

            

Para começar, no exemplo de hoje, repeti o método Update do post anterior (para permitir rotação, translação e zoom). Vamos a informações quanto ao desenho. Perceba:

  • Ao construir um modelo 3D, um desenhista pode “separar” o desenho em diversas partes. Cada uma dessas partes é representada no objeto Model como um elemento da coleção Meshes;
  • Cada Mesh  pode especificiar um conjunto de efeitos (onde ocorre a aplicação de texturas, cores, sombreamentos). Para fazer o desenho, é necessário percorrer todos esses efeitos;
  • Mais uma vez, não estamos criando qualquer configuração de luz para nosso ambiente. Estamos utilizando uma configuração default que é suficiente para programas mais simples. Em posts futuros mostrarei técnicas avançadas de iluminação;
  • Continuo utilizando o objeto Camera (que construímos na parte 4) para calcular a matriz View.
  • A matriz “mundo” é computada pela combinação das matrizes de translação, rotação e escala que estamos atualizando no método Update (não apresentado aqui por ser idêntico ao que utilizamos no post anterior) e a matriz da Bone correspondente a Mesh.
  • Todo Mesh tem um Bone associado. Um Bone é fundamental para modelos que desejemos animar (considere um “robo”, por exemplo).
  • O desenho é efetivado pelo método Draw da mesh.

Segue alguns screenshots da execução do exemplo de hoje:

image

 

image

 

image

Lembre-se, o código-fonte dos exemplos todos os posts dessa série está disponível em  https://github.com/ElemarJR/VamosAprenderXNA.

Por hoje, era isso

Smiley piscando

Etiquetado:,
Publicado em: Sem categoria