//----------------------------------------------------------------------------- // TangentVertex.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; using System.Collections; using System.Text; namespace RacingGame.Graphics { /// /// Tangent vertex format for shader vertex format used all over the place. /// It contains: Position, Normal vector, texture coords, tangent vector. /// public struct TangentVertex : IVertexType { /// /// Position /// public Vector3 pos; /// /// Texture coordinates /// public Vector2 uv; /// /// Normal /// public Vector3 normal; /// /// Tangent /// public Vector3 tangent; /*fixed number to prevent having us to use unsafe code /// /// Stride size, in XNA called SizeInBytes. I'm just conforming with that. /// Btw: How is this supposed to work without using unsafe AND /// without using System.Runtime.InteropServices.Marshal.SizeOf? /// public static unsafe int SizeInBytes { get { return (int)sizeof(TangentVertex); } } */ /// /// Stride size, in XNA called SizeInBytes. I'm just conforming with that. /// public static int SizeInBytes { get { // 4 bytes per float: // 3 floats pos, 2 floats uv, 3 floats normal and 3 float tangent. return 4 * (3 + 2 + 3 + 3); } } /// /// U texture coordinate /// /// Float public float U { get { return uv.X; } } /// /// V texture coordinate /// /// Float public float V { get { return uv.Y; } } /// /// Create tangent vertex /// /// Set position /// Set u texture coordinate /// Set v texture coordinate /// Set normal /// Set tangent public TangentVertex( Vector3 setPos, float setU, float setV, Vector3 setNormal, Vector3 setTangent) { pos = setPos; uv = new Vector2(setU, setV); normal = setNormal; tangent = setTangent; } /// /// Create tangent vertex /// /// Set position /// Set uv texture coordinates /// Set normal /// Set tangent public TangentVertex( Vector3 setPos, Vector2 setUv, Vector3 setNormal, Vector3 setTangent) { pos = setPos; uv = setUv; normal = setNormal; tangent = setTangent; } /// /// To string /// public override string ToString() { return "TangentVertex(pos=" + pos + ", " + "u=" + uv.X + ", " + "v=" + uv.Y + ", " + "normal=" + normal + ", " + "tangent=" + tangent + ")"; } /// /// Vertex elements for Mesh.Clone /// private static readonly VertexElement[] VertexElements = GenerateVertexElements(); /// /// Vertex declaration for vertex buffers. /// public static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration ( // Construct new vertex declaration with tangent info // First the normal stuff (we should already have that) new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), new VertexElement(12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0), new VertexElement(20, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0), // And now the tangent new VertexElement(32, VertexElementFormat.Vector3, VertexElementUsage.Tangent, 0) ); //Implement the IVertexType interface so that we can get the vertex //declaration straight from our custom vertex! VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration; } } /// /// Generate vertex declaration /// private static VertexElement[] GenerateVertexElements() { VertexElement[] decl = new VertexElement[] { // Construct new vertex declaration with tangent info // First the normal stuff (we should already have that) new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), new VertexElement(12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0), new VertexElement(20, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0), // And now the tangent new VertexElement(32, VertexElementFormat.Vector3, VertexElementUsage.Tangent, 0), }; return decl; } /// /// Returns true if declaration is tangent vertex declaration. /// public static bool IsTangentVertexDeclaration( VertexElement[] declaration) { if (declaration == null) throw new ArgumentNullException("declaration"); return declaration.Length == 4 && declaration[0].VertexElementUsage == VertexElementUsage.Position && declaration[1].VertexElementUsage == VertexElementUsage.TextureCoordinate && declaration[2].VertexElementUsage == VertexElementUsage.Normal && declaration[3].VertexElementUsage == VertexElementUsage.Tangent; } } }