Ejemplo n.º 1
0
        public static ObjFile FromFile(string fileName)
        {
            ObjFile obj = new ObjFile();

            obj.FileName = fileName;

            using (StreamReader file = new StreamReader(fileName))
            {
                string line;

                string materialName = null;

                ObjMesh mesh = new ObjMesh("unnamed");
                obj.Meshes.Add(mesh);

                ObjFaceGroup faceGroup = new ObjFaceGroup();
                mesh.FaceGroups.Add(faceGroup);

                while ((line = file.ReadLine()) != null)
                {
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }

                    line = line.Trim();

                    if (line.StartsWith("#", StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    string[] values = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);

                    switch (values[0].ToUpperInvariant())
                    {
                    case "MTLLIB":
                        if (values.Length != 2)
                        {
                            throw new InvalidDataException("missing mtllib name");
                        }

                        if (obj.Materials.Count > 0)
                        {
                            throw new InvalidDataException("multiple mtllib");
                        }

                        obj.Materials = ObjMaterialDictionary.FromFile(Path.Combine(Path.GetDirectoryName(fileName), values[1]));
                        break;

                    case "V":
                        if (values.Length < 4)
                        {
                            throw new InvalidDataException("v must be x y z");
                        }

                        obj.Vertices.Add(new ObjVector3(
                                             float.Parse(values[1], CultureInfo.InvariantCulture),
                                             float.Parse(values[2], CultureInfo.InvariantCulture),
                                             float.Parse(values[3], CultureInfo.InvariantCulture)));
                        break;

                    case "VT":
                        if (values.Length < 3)
                        {
                            throw new InvalidDataException("vt must be u v");
                        }

                        obj.VertexTexCoords.Add(new ObjVector2(
                                                    float.Parse(values[1], CultureInfo.InvariantCulture),
                                                    float.Parse(values[2], CultureInfo.InvariantCulture)));
                        break;

                    case "VN":
                        if (values.Length < 4)
                        {
                            throw new InvalidDataException("vn must be x y z");
                        }

                        obj.VertexNormals.Add(new ObjVector3(
                                                  float.Parse(values[1], CultureInfo.InvariantCulture),
                                                  float.Parse(values[2], CultureInfo.InvariantCulture),
                                                  float.Parse(values[3], CultureInfo.InvariantCulture)));
                        break;

                    case "O":
                    case "G":
                        if (values.Length < 2)
                        {
                            throw new InvalidDataException("missing object name");
                        }

                        if (faceGroup.Faces.Count == 0)
                        {
                            mesh.Name = values[1];
                        }
                        else
                        {
                            mesh = new ObjMesh(values[1]);
                            obj.Meshes.Add(mesh);

                            faceGroup = new ObjFaceGroup();
                            faceGroup.MaterialName = materialName;
                            mesh.FaceGroups.Add(faceGroup);
                        }
                        break;

                    case "USEMTL":
                        if (values.Length != 2)
                        {
                            throw new InvalidDataException("missing material name");
                        }

                        materialName = values[1];

                        if (faceGroup.Faces.Count == 0)
                        {
                            faceGroup.MaterialName = materialName;
                        }
                        else
                        {
                            faceGroup = new ObjFaceGroup();
                            faceGroup.MaterialName = materialName;
                            mesh.FaceGroups.Add(faceGroup);
                        }
                        break;

                    case "F":
                        if (values.Length == 4)
                        {
                            var v1 = ParseFaceVertex(values[1]);
                            var v2 = ParseFaceVertex(values[2]);
                            var v3 = ParseFaceVertex(values[3]);

                            var face = new ObjFace();
                            face.VerticesIndex        = new ObjIndex(v1.Item1, v2.Item1, v3.Item1);
                            face.VertexTexCoordsIndex = new ObjIndex(v1.Item2, v2.Item2, v3.Item2);
                            face.VertexNormalsIndex   = new ObjIndex(v1.Item3, v2.Item3, v3.Item3);

                            faceGroup.Faces.Add(face);
                        }
                        else if (values.Length == 5)
                        {
                            var v1 = ParseFaceVertex(values[1]);
                            var v2 = ParseFaceVertex(values[2]);
                            var v3 = ParseFaceVertex(values[3]);
                            var v4 = ParseFaceVertex(values[4]);

                            var face = new ObjFace();
                            face.VerticesIndex        = new ObjIndex(v1.Item1, v2.Item1, v3.Item1, v4.Item1);
                            face.VertexTexCoordsIndex = new ObjIndex(v1.Item2, v2.Item2, v3.Item2, v4.Item2);
                            face.VertexNormalsIndex   = new ObjIndex(v1.Item3, v2.Item3, v3.Item3, v4.Item3);

                            faceGroup.Faces.Add(face);
                        }
                        else
                        {
                            throw new InvalidDataException("invalid face");
                        }
                        break;
                    }
                }
            }

            return(obj);
        }
Ejemplo n.º 2
0
        public static ObjMaterialDictionary FromFile(string fileName)
        {
            ObjMaterialDictionary materials = new ObjMaterialDictionary();

            using (StreamReader file = new StreamReader(fileName))
            {
                string      line;
                ObjMaterial material = null;

                while ((line = file.ReadLine()) != null)
                {
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }

                    line = line.Trim();

                    if (line.StartsWith("#", StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    string[] values = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);

                    switch (values[0].ToUpperInvariant())
                    {
                    case "NEWMTL":
                        if (values.Length != 2)
                        {
                            throw new InvalidDataException("missing material name");
                        }

                        material      = new ObjMaterial();
                        material.Name = values[1];
                        materials.Add(material.Name, material);
                        break;

                    case "KD":
                        if (material == null || values.Length != 4)
                        {
                            break;
                        }

                        material.DiffuseColor = new ObjVector3(
                            float.Parse(values[1], CultureInfo.InvariantCulture),
                            float.Parse(values[2], CultureInfo.InvariantCulture),
                            float.Parse(values[3], CultureInfo.InvariantCulture));
                        break;

                    case "D":
                        if (material == null || values.Length != 2)
                        {
                            break;
                        }

                        material.DissolveFactor = float.Parse(values[1], CultureInfo.InvariantCulture);
                        break;

                    case "MAP_KD":
                        if (material == null || values.Length != 2)
                        {
                            break;
                        }

                        material.DiffuseMapFileName = values[1];
                        break;

                    case "MAP_D":
                        if (material == null || values.Length != 2)
                        {
                            break;
                        }

                        material.AlphaMapFileName = values[1];
                        break;
                    }
                }
            }

            return(materials);
        }