Пример #1
0
        internal static Model LoadFromFile(string path)
        {
            Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
            ObjModel result = ObjModel.Load(@"models\sponza.obj");

            List<MeshVertex> meshVertices = new List<MeshVertex>();

            Dictionary<string, Texture> textures = LoadMTLTextures(result.Materials.Values.ToList());

            List<Mesh> meshes = new List<Mesh>();

            foreach (var group in result.Groups)
            {
                List<uint> meshIndices = new List<uint>();

                foreach (var face in group.Faces)
                {
                    Vector3 Q1 = new Vector3(
                        result.Vertices[face.Vertices[1].VertexIndex - 1].X - result.Vertices[face.Vertices[0].VertexIndex - 1].X,
                        result.Vertices[face.Vertices[1].VertexIndex - 1].Y - result.Vertices[face.Vertices[0].VertexIndex - 1].Y,
                        result.Vertices[face.Vertices[1].VertexIndex - 1].Z - result.Vertices[face.Vertices[0].VertexIndex - 1].Z);

                    Vector3 Q2 = new Vector3(
                        result.Vertices[face.Vertices[2].VertexIndex - 1].X - result.Vertices[face.Vertices[0].VertexIndex - 1].X,
                        result.Vertices[face.Vertices[2].VertexIndex - 1].Y - result.Vertices[face.Vertices[0].VertexIndex - 1].Y,
                        result.Vertices[face.Vertices[2].VertexIndex - 1].Z - result.Vertices[face.Vertices[0].VertexIndex - 1].Z);

                    double s1 = result.Textures[face.Vertices[1].TextureIndex - 1].X - result.Textures[face.Vertices[0].TextureIndex - 1].X;
                    double t1 = result.Textures[face.Vertices[1].TextureIndex - 1].Y - result.Textures[face.Vertices[0].TextureIndex - 1].Y;
                    double s2 = result.Textures[face.Vertices[2].TextureIndex - 1].X - result.Textures[face.Vertices[0].TextureIndex - 1].X;
                    double t2 = result.Textures[face.Vertices[2].TextureIndex - 1].Y - result.Textures[face.Vertices[0].TextureIndex - 1].Y;

                    double coefficient = 1.0 / (s1 * t2 - s2 * t1);
                    Vector3 sDir = new Vector3(t2 * Q1.X - t1 * Q2.X, t2 * Q1.Y - t1 * Q2.Y, t2 * Q1.Z - t1 * Q2.Z) * coefficient;
                    Vector3 tDir = new Vector3(s1 * Q2.X - s2 * Q1.X, s1 * Q2.Y - s2 * Q1.Y, s1 * Q2.Z - s2 * Q1.Z) * coefficient;

                    for (int i = 0; i < face.Vertices.Count; i++)
                    {
                        MeshPosition vertex = result.Vertices[face.Vertices[i].VertexIndex - 1];
                        MeshNormal normal = result.Normals[face.Vertices[i].NormalIndex - 1];
                        MeshTexCoord texture = result.Textures[face.Vertices[i].TextureIndex - 1];

                        Vector3 tempNormal = new Vector3(normal.X, normal.Y, normal.Z);
                        Vector3 tempTangent = (sDir - tempNormal * Vector3.Dot(tempNormal, sDir)).Normalized;

                        double handedness = (Vector3.Dot(Vector3.Cross(tempNormal, sDir), tDir) < 0.0) ? -1.0 : 1.0;
                        MeshTangent tangent = new MeshTangent((float)tempTangent.X, (float)tempTangent.Y, (float)tempTangent.Z, (float)handedness);

                        meshIndices.Add((uint)meshVertices.Count);
                        meshVertices.Add(new MeshVertex(
                            vertex,
                            normal,
                            texture,
                            tangent));
                    }

                    if (face.Vertices.Count == 3)
                    {
                    }
                    else if (face.Vertices.Count == 4)
                    {
                        uint vertexPointer1 = meshIndices[meshIndices.Count - 4];
                        uint vertexPointer2 = meshIndices[meshIndices.Count - 2];

                        meshIndices.Insert(meshIndices.Count - 1, vertexPointer1);
                        meshIndices.Insert(meshIndices.Count - 1, vertexPointer2);
                    }
                    else
                    {
                        throw new Exception("Only supports triangles or quads");
                    }
                }
                Mesh currentMesh = new Mesh(meshIndices.ToArray());

                ApplyMaterial(currentMesh, group.Material, textures);

                meshes.Add(currentMesh);
            }

            return new Model(meshVertices.ToArray(), meshes.ToArray(), textures.Values.ToArray());
        }
Пример #2
0
 public MeshVertex(MeshPosition pos, MeshNormal norm, MeshTexCoord texcoord, MeshTangent tangent)
 {
     Position = pos;
     Normal = norm;
     TexCoord = texcoord;
     Tangent = tangent;
 }