示例#1
0
 private bool EnsureTokenizer()
 {
     if (tokenizer == null || !tokenizer.MoveNext())
     {
         String line = NextLine();
         if (line != null)
         {
             tokenizer = new LineTokenizer(line);
             return(tokenizer.MoveNext());
         }
         return(false);
     }
     return(true);
 }
示例#2
0
 public string NextLine()
 {
     tokenizer = null;
     return(reader.ReadLine());
 }
示例#3
0
 protected override IReadOnlyList <LineToken> GetTokens() => LineTokenizer.GetTokens(m_Input, m_Mode.HasFlag(ParserMode.TreatWhitespaceOnlyLinesAsBlankLines)).ToArray();
示例#4
0
    private void ParseFile()
    {
        StreamReader sr = new StreamReader(_path, Encoding.Default);
        string       ln;

        while (!sr.EndOfStream)
        {
            ln = sr.ReadLine();
            if (ln.Length > 0 && ln[0] != '#')
            {
                LineTokenizer lk = new LineTokenizer(ln);

                if (lk.Type == "mtllib")
                {
                    // Loads cache
                    string mtlPath = OBJLoader.OBJGetFilePath(lk.Data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, _meshName);

                    if (mtlPath != null)
                    {
                        materialCache = OBJLoader.LoadMTLFile(mtlPath);
                    }
                }

                else if ((lk.Type == "g" || lk.Type == "o") && _splitByMaterial == false)
                {
                    cmesh = lk.Data;
                    if (!objectNames.Contains(cmesh))
                    {
                        objectNames.Add(cmesh);
                    }
                }

                else if (lk.Type == "usemtl")
                {
                    cmaterial = lk.Data;
                    if (!materialNames.Contains(cmaterial))
                    {
                        materialNames.Add(cmaterial);
                    }

                    if (_splitByMaterial)
                    {
                        if (!objectNames.Contains(cmaterial))
                        {
                            objectNames.Add(cmaterial);
                        }
                    }
                }

                // Vertices
                else if (lk.Type == "v")
                {
                    vertices.Add(OBJLoader.ParseVectorFromCMPS(lk.Tokens));
                }

                // Vertex normals
                else if (lk.Type == "vn")
                {
                    normals.Add(OBJLoader.ParseVectorFromCMPS(lk.Tokens));
                }

                // Textures coordinates
                else if (lk.Type == "vt")
                {
                    uvs.Add(OBJLoader.ParseVectorFromCMPS(lk.Tokens));
                }

                // Polygonal face element
                else if (lk.Type == "f")
                {
                    int[] indexes = new int[lk.Tokens.Length - 1];
                    for (int i = 1; i < lk.Tokens.Length; i++)
                    {
                        string felement    = lk.Tokens[i];
                        int    vertexIndex = -1;
                        int    normalIndex = -1;
                        int    uvIndex     = -1;
                        if (felement.Contains("//"))
                        {
                            //doubleslash, no UVS.
                            string[] elementComps = felement.Split('/');
                            vertexIndex = int.Parse(elementComps[0]) - 1;
                            normalIndex = int.Parse(elementComps[2]) - 1;
                        }
                        else if (felement.Count(x => x == '/') == 2)
                        {
                            //contains everything
                            string[] elementComps = felement.Split('/');
                            vertexIndex = int.Parse(elementComps[0]) - 1;
                            uvIndex     = int.Parse(elementComps[1]) - 1;
                            normalIndex = int.Parse(elementComps[2]) - 1;
                        }
                        else if (!felement.Contains("/"))
                        {
                            //just vertex inedx
                            vertexIndex = int.Parse(felement) - 1;
                        }
                        else
                        {
                            //vertex and uv
                            string[] elementComps = felement.Split('/');
                            vertexIndex = int.Parse(elementComps[0]) - 1;
                            uvIndex     = int.Parse(elementComps[1]) - 1;
                        }
                        string hashEntry = vertexIndex + "|" + normalIndex + "|" + uvIndex;
                        if (hashtable.ContainsKey(hashEntry))
                        {
                            indexes[i - 1] = hashtable[hashEntry];
                        }
                        else
                        {
                            //create a new hash entry
                            indexes[i - 1]       = hashtable.Count;
                            hashtable[hashEntry] = hashtable.Count;
                            uvertices.Add(vertices[vertexIndex]);
                            if (normalIndex < 0 || (normalIndex > (normals.Count - 1)))
                            {
                                unormals.Add(Vector3.zero);
                            }
                            else
                            {
                                _hasNormals = true;
                                unormals.Add(normals[normalIndex]);
                            }
                            if (uvIndex < 0 || (uvIndex > (uvs.Count - 1)))
                            {
                                uuvs.Add(Vector2.zero);
                            }
                            else
                            {
                                uuvs.Add(uvs[uvIndex]);
                            }
                        }
                    }

                    if (indexes.Length < 5 && indexes.Length >= 3)
                    {
                        OBJFace f1 = new OBJFace();
                        f1.materialName = cmaterial;
                        f1.indexes      = new int[] { indexes[0], indexes[1], indexes[2] };
                        f1.meshName     = (_splitByMaterial) ? cmaterial : cmesh;
                        faceList.Add(f1);
                        if (indexes.Length > 3)
                        {
                            OBJFace f2 = new OBJFace();
                            f2.materialName = cmaterial;
                            f2.meshName     = (_splitByMaterial) ? cmaterial : cmesh;
                            f2.indexes      = new int[] { indexes[2], indexes[3], indexes[0] };
                            faceList.Add(f2);
                        }
                    }
                }
            }
        }
    }