sábado, 30 de julho de 2011

XNA 4.0 - Criando Tangente e Binormal

A principio ia falar sobre efeitos em XNA bem superficialmente, mas decidi que seria legal colocar uma série separada, onde até eu mesmo irei aprender mais sobre isso.

Nós estamos usando efeitos básicos, que já vem com o XNA, e são muito simples, não permitem usar luzes pelo mapa e nada mais avançado, então se queremos usar efeitos avançado em nosso terreno teremos de calcular algumas coisas a mais. Efeitos em sua maioria requerem Tangente, BiNormal, Normal, Coordenada da Textura e Posição. Nós já fizemos e achamos a posição, a coordenada das texturas e a normal e para isso nós usamos o vertex: VertexPositiomNormal mas agora precisamos usar um outro tipo de vértice que junte tudo isso pra gente. Mas o XNA não fornece isso para gente, então vamos criar o VertexPositionNormalTangentBinormal. Na raiz do projeto crie uma pasta e nomeie-a como "Helpers", adicione um novo arquivo nessa parata, chamado de : "VertexPositionNormalTangentBinormal". O código é a estrutura interna do vértice, pelo nome e pelo o que contem é possível saber qual a estrutura dos outros tipos de Vertexs. O código do arquivo completo:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace Tutorial1.Helpers
{
public struct VertexPositionNormalTangentBinormal
{

#region Variaveis
public Vector3 Position;
public Vector3 Normal;
public Vector2 TextureCoordinate;
public Vector3 Tanget;
public Vector3 Binormal;
#endregion

#region Propriedades
public static int SizeInBytes
{
get
{
return (3 + 3 + 2 + 3 + 3 ) * sizeof(float);
}
}
#endregion

#region Construtor
public VertexPositionNormalTangentBinormal(Vector3 position, Vector3 normal, Vector2 textureCoordinate, Vector3 tanget, Vector3 binormal)
{
Position = position;
Normal = normal;
TextureCoordinate = textureCoordinate;
Tanget = tanget;
Binormal = binormal;
}
#endregion

#region Elementos do Vertex
public static VertexElement[] VertexElements = new VertexElement[] {
new VertexElement(0, VertexElementFormat.Vector3,
VertexElementUsage.Position, 0),
new VertexElement(12, VertexElementFormat.Vector3,
VertexElementUsage.Normal, 0),
new VertexElement(24, VertexElementFormat.Vector2,
VertexElementUsage.TextureCoordinate, 0),
new VertexElement(32, VertexElementFormat.Vector3,
VertexElementUsage.Tangent, 0),
new VertexElement(44, VertexElementFormat.Vector3,
VertexElementUsage.Binormal, 0),

};
#endregion
}
}

Volte no arquivo "Terrain.cs" aprete CTRL+H e substitua todas as ocorrências de VertexPositiomNormal para VertexPositionNormalTangentBinormal

No método GenerateTerrainMesh() substitua a declaração do vértice para essa

VertexDeclaration decl = new VertexDeclaration(VertexPositionNormalTangentBinormal.VertexElements);

No método GenerateTerrainVértices adicione a linha, a linha fica depois de "GenerateTerrainNormals(vertices, terrainIndices);"

GenerateTerrainTangentBinormal(vertices, terrainIndices);

Agora vamos criar o método GenerateTerrainTangentBinormal, a tangent é um vetor que aponta do atual vértice para o próximo. e a BiNormal é um vetor que é obtido atrávez do produto vetorial da Normal com a tangente, o código fica assim:
public void GenerateTerrainTangentBinormal(VertexPositionNormalTangentBinormal[] vertices, int[] indices)
{
for (int i = 0; i < vertexCountZ; i++) { for (int j = 0; j < vertexCountX; j++) { int vertexIndex = j + i * vertexCountX; Vector3 v1 = vertices[vertexIndex].Position; if (j < vertexCountX - 1) { Vector3 v2 = vertices[vertexIndex + 1].Position; vertices[vertexIndex].Tanget = (v2 - v1); } else { Vector3 v2 = vertices[vertexIndex - 1].Position; vertices[vertexIndex].Tanget = (v1 - v2); } vertices[vertexIndex].Tanget.Normalize(); vertices[vertexIndex].Binormal = Vector3.Cross(vertices[vertexIndex].Tanget, vertices[vertexIndex].Normal); } } }


Isso em nada vai mudar a nossa cena mas como usaremos efeitos avançados mais a frente é bom terminar a classe Terrain logo de uma vez;

Nenhum comentário:

Postar um comentário