private void CalculateTangentArray(int vertexCount, Vertex[] vertex, Vector[] normal, Texcoord[] texcoord, int triangleCount, Face[] triangles, out Vector[] Bitangent, out Vector[] Normals, out Vector[] Tangent) { Vector3[] tan1 = new Vector3[vertexCount]; Vector3[] tan2 = new Vector3[vertexCount]; Normals = new Vector[vertexCount]; for (int a = 0; a < triangleCount; a++) { //Store Vertex Index's int i1 = triangles[a].VertexIndices[0]; int i2 = triangles[a].VertexIndices[1]; int i3 = triangles[a].VertexIndices[2]; int n1 = triangles[a].NormalIndices[0]; int n2 = triangles[a].NormalIndices[1]; int n3 = triangles[a].NormalIndices[2]; int vt1 = triangles[a].TexcoordIndices[0]; int vt2 = triangles[a].TexcoordIndices[1]; int vt3 = triangles[a].TexcoordIndices[2]; //From Vertex Array Copy Coordinates of Vertex's Vertex v1 = vertex[i1]; Vertex v2 = vertex[i2]; Vertex v3 = vertex[i3]; //From Texture Array Copy Coordinates of Vertex's Texcoord w1 = texcoord[vt1]; Texcoord w2 = texcoord[vt2]; Texcoord w3 = texcoord[vt3]; //Make Relative to Vertex 1 //Vertex Coordinates float x1 = v2.Position.X - v1.Position.X; float x2 = v3.Position.X - v1.Position.X; float y1 = v2.Position.Y - v1.Position.Y; float y2 = v3.Position.Y - v1.Position.Y; float z1 = v2.Position.Z - v1.Position.Z; float z2 = v3.Position.Z - v1.Position.Z; //Texture Coordinates float s1 = w2.Coordinates.X - w1.Coordinates.X; float s2 = w3.Coordinates.X - w1.Coordinates.X; float t1 = w2.Coordinates.Y - w1.Coordinates.Y; float t2 = w3.Coordinates.Y - w1.Coordinates.Y; float r = 1.0F / (s1 * t2 - s2 * t1); Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); AngleFucker AF = new AngleFucker(v1.Position, v2.Position, v3.Position); tan1[i1] += Vector3.Multiply(sdir, AF.Get_v1_Angle()); tan1[i2] += Vector3.Multiply(sdir, AF.Get_v2_Angle()); tan1[i3] += Vector3.Multiply(sdir, AF.Get_v3_Angle()); tan2[i1] += Vector3.Multiply(tdir, AF.Get_v1_Angle()); tan2[i2] += Vector3.Multiply(tdir, AF.Get_v2_Angle()); tan2[i3] += Vector3.Multiply(tdir, AF.Get_v3_Angle()); } Tangent = new Vector[vertexCount]; Bitangent = new Vector[vertexCount]; for (int a = 0; a < vertexCount; a++) { Vector3 n = normal[a].Components; Normals[a] = Round(normal[a]); Vector3 b = tan2[a]; Vector3 t = tan1[a]; // Gram-Schmidt orthogonalize Vector3 temp = Vector3.Subtract(t, Vector3.Multiply(n, Vector3.Dot(n, t))); temp.Normalize(); Tangent[a] = new Vector(Vector3.Empty, Vector.VectorUsage.Tangent); Tangent[a].Components = temp; Tangent[a] = Round(Tangent[a]); // Calculate handedness float W = (Vector3.Dot(Vector3.Cross(n, t), b) < 0.0F) ? -1.0F : 1.0F; //Calculate Bitangent Bitangent[a] = new Vector(Vector3.Empty, Vector.VectorUsage.Bitangent); Bitangent[a].Components = Vector3.Multiply((Vector3.Cross(n, temp)), W); Bitangent[a] = Round(Bitangent[a]); } }
public VectorData(int vertexcount, Vertex[] vertices, Vector[] normals, Texcoord[] texcoords, int trianglecount, Face[] triangles) { Vector[] Tangents, Bitangents; CalculateTangentArray(vertexcount, vertices, normals, texcoords, trianglecount, triangles, out Bitangents, out normals, out Tangents); Size = (uint)(normals.Length * 3 * 4); List<int> RawData = new List<int>((int)Size); for (int Index = 0; Index < normals.Length; Index++) { RawData.Add(Compress(ref normals[Index])); RawData.Add(Compress(ref Bitangents[Index])); RawData.Add(Compress(ref Tangents[Index])); } RawVectorData = RawData.ToArray(); }