/// <summary> /// Calculates a tangent. /// </summary> /// <param name="vertex1">Vertex one.</param> /// <param name="vertex2">Vertex two.</param> /// <param name="vertex3">Vertex three.</param> /// <param name="normal">The normal of the face.</param> /// <returns>The calculate tangent.</returns> public static Vector3 CalculateTangent(ref TangentNormalTexture vertex1, ref TangentNormalTexture vertex2, ref TangentNormalTexture vertex3, ref Vector3 normal) { Vector3 tangent = Vector3.Zero; Vector3 edge1 = vertex3.Position - vertex1.Position; Vector3 edge2 = vertex2.Position - vertex1.Position; Vector2 texEdge1 = vertex3.TextureCoord - vertex1.TextureCoord; Vector2 texEdge2 = vertex2.TextureCoord - vertex1.TextureCoord; edge1.Normalize(); edge2.Normalize(); texEdge1.Normalize(); texEdge2.Normalize(); float det = (texEdge1.X * texEdge2.Y) - (texEdge1.Y * texEdge2.X); Vector3 t; if ((float)Math.Abs(det) < 1e-6f) { t = Vector3.UnitX; } else { det = 1.0f / det; t.X = (texEdge2.Y * edge1.X - texEdge1.Y * edge2.X) * det; t.Y = (texEdge2.Y * edge1.Y - texEdge1.Y * edge2.Y) * det; t.Z = (texEdge2.Y * edge1.Z - texEdge1.Y * edge2.Z) * det; t.Normalize(); } tangent.X = t.X; tangent.Y = t.Y; tangent.Z = t.Z; return(tangent); }
/// <summary> /// Used to set both the noprm and the tangent of the face. /// </summary> /// <param name="vertices">The vertices that make up the face.</param> public void SetNormalTangent(List <TangentNormalTexture> vertices) { TangentNormalTexture[] vert = new TangentNormalTexture[] { vertices[indices[0]], vertices[indices[1]], vertices[indices[2]] }; Vector3 normal = VertexHelper.CalculateNormal( ref vert[0].Position, ref vert[1].Position, ref vert[2].Position); Vector3 tangent = VertexHelper.CalculateTangent( ref vert[0], ref vert[1], ref vert[2], ref normal); for (int i = 0; i < vert.Length; i++) { vert[i].Normal += normal; vert[i].Normal.Normalize(); vert[i].Tangent += tangent; vert[i].EvaluateTangent(); vertices[indices[i]] = vert[i]; } }