//-----------------------------------------------------------------------------
// 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;
}
}
}