Exemple #1
0
        public static Mesh LoadObj(string file)
        {
            string filename = "E:\\dev\\c#\\Work\\Resources\\" + file;

            StreamReader stream = new StreamReader(filename);

            List <float>      Vertices     = new List <float>();
            List <float>      Normals      = new List <float>();
            List <float>      Textures     = new List <float>();
            List <MeshVertex> meshVertices = new List <MeshVertex>();



            List <FaceObj> ObjFaces = new List <FaceObj>();


            // On commence par lire l'intégrité du fichier. Dans le processus, on récupère les informations
            // sur les sommets et les faces
            while (!stream.EndOfStream)
            {
                string line = stream.ReadLine();

                if (line.Count() > 0)
                {
                    if (line[0] != ' ' && line[0] != '#')
                    {
                        char[] chars =
                        {
                            ' ',
                            '\t'
                        };

                        line = line.Trim();
                        RegexOptions options = RegexOptions.None;

                        // { 2,} signifie 2 fois au moins
                        // [] est un ensemble de caractère
                        Regex regex = new Regex(@"[ ]{2,}", options);
                        line = regex.Replace(line, @" ");

                        string[] splits = line.Split(' ');

                        // Si la ligne débute par v, on ajoute un sommet
                        if (splits[0] == "v")
                        {
                            for (int i = 1; i < splits.Count(); i++)
                            {
                                Vertices.Add(float.Parse(splits[i].Replace('.', ',')));
                            }
                        }
                        // Si la ligne débute par vn, on ajoute une normale
                        if (splits[0] == "vn")
                        {
                            for (int i = 1; i < splits.Count(); i++)
                            {
                                Normals.Add(float.Parse(splits[i].Replace('.', ',')));
                            }
                        }

                        // Si la ligne débute par vt, on ajoute une coordonnée de texture
                        if (splits[0] == "vt")
                        {
                            for (int i = 1; i < splits.Count(); i++)
                            {
                                Textures.Add(float.Parse(splits[i].Replace('.', ',')));
                            }
                        }

                        // Si la ligne débute par f, on ajoute une face
                        if (splits[0] == "f")
                        {
                            FaceObj fobj = new FaceObj();
                            ObjFaces.Add(fobj);

                            for (int i = 1; i < splits.Count(); i++)
                            {
                                string[] secondsplit = splits[i].Split('/');
                                int[]    vertex      = new int[secondsplit.Length];

                                for (int j = 0; j < secondsplit.Count(); j++)
                                {
                                    // Position
                                    if (j == 0)
                                    {
                                        int result;
                                        if (int.TryParse(secondsplit[j], out result))
                                        {
                                            fobj.IndexesVertice.Add(result);
                                        }
                                    }
                                    // Textures
                                    if (j == 1)
                                    {
                                        int result;
                                        if (int.TryParse(secondsplit[j], out result))
                                        {
                                            fobj.IndexesTexture.Add(result);
                                        }
                                        else
                                        {
                                            //fobj.IndexesNormal.Add( -1 );
                                        }
                                    }
                                    // Normals
                                    if (j == 2)
                                    {
                                        int result;
                                        if (int.TryParse(secondsplit[j], out result))
                                        {
                                            fobj.IndexesNormal.Add(result);
                                        }
                                        else
                                        {
                                            // fobj.IndexesTexture.Add( -1 );
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            StandardMesh mesh = new StandardMesh();

            for (int i = 0; i < ObjFaces.Count; i++)
            {
                // On va construire les sommets à partir des indices
                // Tout en essayant de ne pas dupliquer les sommets
                for (int j = 0; j < ObjFaces[i].IndexesVertice.Count; j++)
                {
                    Vector3 normal = new Vector3(0.0f, 0.0f, 0.0F);
                    Vector2 tex    = new Vector2(0.0f, 0.0f);

                    int vertexIndex  = ObjFaces[i].IndexesVertice[j] - 1;
                    int normalIndex  = -1;
                    int textureIndex = -1;

                    if (ObjFaces[i].IndexesNormal.Count > 0)
                    {
                        normalIndex = ObjFaces[i].IndexesNormal[j] - 1;
                        normal      = new Vector3(Normals[normalIndex * 3], Normals[normalIndex * 3 + 1], Normals[normalIndex * 3 + 2]);
                    }

                    if (ObjFaces[i].IndexesTexture.Count > 0)
                    {
                        textureIndex = ObjFaces[i].IndexesTexture[j] - 1;
                        tex          = new Vector2(Textures[textureIndex * 2], Textures[textureIndex * 2 + 1]);
                    }
                    MeshVertex mv    = new MeshVertex(vertexIndex, normalIndex, textureIndex);
                    int        index = MeshVertex.Exist(meshVertices, mv);
                    // Si on a pas déjà eu cette combinaison d'indice, on ajoute un nouveau sommet
                    if (index == -1)
                    {
                        meshVertices.Add(mv);
                        mesh.AddVertex
                        (
                            new StandardVertex
                            (
                                new Vector3(Vertices[vertexIndex * 3], Vertices[vertexIndex * 3 + 1], Vertices[vertexIndex * 3 + 2]),
                                normal,
                                tex
                            )
                        );
                        ObjFaces[i].RealIndex.Add(meshVertices.Count - 1);
                    }
                    else
                    {
                        ObjFaces[i].RealIndex.Add(index);
                    }
                }
            }

            // Pour le moment je ne gère que les obj contenant des triangles ou des carrés
            for (int i = 0; i < ObjFaces.Count; i++)
            {
                mesh.AddFace(ObjFaces[i].RealIndex[0], ObjFaces[i].RealIndex[1], ObjFaces[i].RealIndex[2]);

                if (ObjFaces[i].IndexesVertice.Count == 4)
                {
                    mesh.AddFace(ObjFaces[i].RealIndex[0], ObjFaces[i].RealIndex[2], ObjFaces[i].RealIndex[3]);
                }
            }

            if (Normals.Count == 0)
            {
                mesh.ComputeNormals();
            }

            return(mesh.ReturnMesh());
        }