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 Face[][] ToGroupFaceArray(MeshInformationData[] meshdata) { Face[][] GroupFaceArray = new Face[meshdata.Length][]; for (int SubMesh = 0; SubMesh < meshdata.Length; SubMesh++) { List<Face> FaceArray = new List<Face>(meshdata[0].IndiceLength); int Start = meshdata[SubMesh].IndiceStart; int End = meshdata[SubMesh].IndiceStart + meshdata[SubMesh].IndiceLength - 2; bool Winding = true; int Index = 0; for (int x = Start; x < End; x++) { Face Temp = new Face(IndiceArray[x], IndiceArray[x + 1], IndiceArray[x + 2]); if (!Temp.IsDegenerate) { FaceArray.Add(Temp); if (Winding == false) { short y = Temp.VertexIndices[1]; short z = Temp.VertexIndices[2]; Temp.VertexIndices[1] = z; Temp.VertexIndices[2] = y; Winding = true; } else { Winding = false; } } else { if (Winding == false) { Winding = true; } else { Winding = false; } } Index++; } FaceArray.TrimExcess(); GroupFaceArray[SubMesh] = FaceArray.ToArray(); } return GroupFaceArray; }
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(); }
public Face[] ToFaceArray(MeshInformationData[] meshdata) { List<Face> FaceArray = new List<Face>(IndiceArray.Length); for (int SubMesh = 0; SubMesh < meshdata.Length; SubMesh++) { int Start = meshdata[SubMesh].IndiceStart; int End = meshdata[SubMesh].IndiceStart + meshdata[SubMesh].IndiceLength - 2; bool Winding = true; for (int x = Start; x < End; x++) { Face Temp = new Face(IndiceArray[x], IndiceArray[x + 1], IndiceArray[x + 2], IndiceArray[x], IndiceArray[x + 1], IndiceArray[x + 2], IndiceArray[x], IndiceArray[x + 1], IndiceArray[x + 2]); Temp.MaterialID = meshdata[SubMesh].ShaderIndex; Temp.GroupID = SubMesh; if (!Temp.IsDegenerate) { FaceArray.Add(Temp); if (Winding == false) { short y = Temp.VertexIndices[1]; short z = Temp.VertexIndices[2]; Temp.VertexIndices[1] = z; Temp.VertexIndices[2] = y; y = Temp.TexcoordIndices[1]; z = Temp.TexcoordIndices[2]; Temp.TexcoordIndices[1] = z; Temp.TexcoordIndices[2] = y; y = Temp.NormalIndices[1]; z = Temp.NormalIndices[2]; Temp.NormalIndices[1] = z; Temp.NormalIndices[2] = y; Winding = true; } else { Winding = false; } } else { if (Winding == false) { Winding = true; } else { Winding = false; } } } } FaceArray.TrimExcess(); return FaceArray.ToArray(); }