示例#1
0
        public void AddFace(OBJFace face)
        {
            List <OBJFace> faces;

            if (!Faces.TryGetValue(face.Material, out faces))
            {
                Faces[face.Material] = faces = new List <OBJFace>();
            }
            faces.Add(face);
        }
示例#2
0
        public static void ParseLineStandard(OBJParserStatus s, string line)
        {
            OBJObject o;

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

            switch (data[0])
            {
            case "mtllib":
                // Currently ignore material libraries.
                return;

            case "o":
                o = new OBJObject(line.Substring(2), s.Current);
                s.Data.Objects.Add(o);
                s.Current         = o.Groups[0];
                s.CurrentMaterial = "";
                return;

            case "g":
                if (s.Data.Objects.Count == 0)
                {
                    o = new OBJObject("", s.Current);
                    s.Data.Objects.Add(o);
                    s.Current      = o.Groups[0];
                    s.Current.Name = line.Substring(2);
                }
                else
                {
                    s.Current = new OBJGroup(line.Substring(2), s.Current);
                    if (s.Current.PrevObj.Groups.Count == 2 &&
                        s.Current.PrevObj.Groups[0].Name == "")
                    {
                        s.Current.PrevObj.Groups.RemoveAt(0);
                    }
                }
                s.CurrentMaterial = "";
                return;

            case "v":
                s.Current.Vertices.Add(_ParseV3(data, 1));
                return;

            case "vt":
                s.Current.UVs.Add(_ParseV2(data, 1));
                return;

            case "vn":
                s.Current.Normals.Add(_ParseV3(data, 1));
                return;

            case "usemtl":
                // Currently ignore material usages.
                s.Current.Materials.Add(line.Substring(7));
                return;

            case "s":
                if (data[1] == "off")
                {
                    // Currently ignore smoothing group disabling.
                }
                else
                {
                    // Currently ignore smoothing group 1 - 32.
                }
                return;

            case "f":
                OBJGroup current = s.Current;
                if (4 <= data.Length && data.Length < 6)
                {
                    int[] indices = new int[data.Length - 1];
                    for (int i = 0; i < indices.Length; i++)
                    {
                        string elem = data[i + 1];

                        int iV  = 0;
                        int iN  = 0;
                        int iUV = 0;

                        if (elem.Contains("//"))
                        {
                            string[] parts = elem.Split('/');
                            iV = int.Parse(parts[0]);
                            iN = int.Parse(parts[2]);
                        }
                        else if (_Count(elem, '/', 2))
                        {
                            string[] parts = elem.Split('/');
                            iV  = int.Parse(parts[0]);
                            iUV = int.Parse(parts[1]);
                            iN  = int.Parse(parts[2]);
                        }
                        else if (!elem.Contains("/"))
                        {
                            iV = int.Parse(elem);
                        }
                        else
                        {
                            string[] parts = elem.Split('/');
                            iV  = int.Parse(parts[0]);
                            iUV = int.Parse(parts[1]);
                        }


                        string cacheKey = $"{iV}; {iN}; {iUV}";
                        int    cacheValue;
                        if (current.IndexCache.TryGetValue(cacheKey, out cacheValue))
                        {
                            indices[i] = cacheValue;
                        }
                        else
                        {
                            cacheValue = current.IndexCache.Count;
                            indices[i] = cacheValue;
                            current.IndexCache[cacheKey] = cacheValue;

                            if ((1 <= iV && iV <= current.Vertices.Count) ||
                                (iV < 0 && 1 <= (iV = iV + current.Vertices.Count + 1) && iV <= current.Vertices.Count))
                            {
                                current.UVertices.Add(current.Vertices[iV - 1]);
                            }
                            else
                            {
                                current.UVertices.Add(Vector3.zero);
                            }

                            if ((1 <= iN && iN <= current.Normals.Count) ||
                                (iN < 0 && 1 <= (iN = iN + current.Normals.Count + 1) && iN <= current.Normals.Count))
                            {
                                current.ContainsNormals = true;
                                current.UNormals.Add(current.Normals[iN - 1]);
                            }
                            else
                            {
                                current.UNormals.Add(Vector3.zero);
                            }

                            if ((1 <= iUV && iUV <= current.UVs.Count) ||
                                (iUV < 0 && 1 <= (iUV = iUV + current.UVs.Count + 1) && iUV <= current.UVs.Count))
                            {
                                current.UUVs.Add(current.UVs[iUV - 1]);
                            }
                            else
                            {
                                current.UUVs.Add(Vector2.zero);
                            }
                        }
                    }

                    OBJFace face = new OBJFace();
                    face.IndexMap   = OBJFace.DefaultIndexMap;
                    face.RawIndices = indices;
                    face.Material   = s.CurrentMaterial;
                    s.Current.AddFace(face);
                    if (indices.Length > 3)
                    {
                        face            = new OBJFace();
                        face.IndexMap   = OBJFace.SecondaryIndexMap;
                        face.RawIndices = indices;
                        face.Material   = s.CurrentMaterial;
                        s.Current.AddFace(face);
                    }
                }
                return;
            }
        }
示例#3
0
        public virtual Mesh ToMesh()
        {
            Mesh mesh = new Mesh();

            mesh.name = Name;

            List <Vector3>         pVertices = new List <Vector3>();
            List <Vector3>         pNormals  = new List <Vector3>();
            List <Vector2>         pUVs      = new List <Vector2>();
            List <List <int> >     pIndices  = new List <List <int> >();
            IDictionary <int, int> map       = new IntDictionary <int>();

            HashSet <string> materials = new HashSet <string>();

            foreach (KeyValuePair <string, List <OBJFace> > facesPerMat in Faces)
            {
                string         mat   = facesPerMat.Key;
                List <OBJFace> faces = facesPerMat.Value;
                if (faces.Count == 0)
                {
                    continue;
                }

                List <int> indices = new List <int>();
                for (int fi = 0; fi < faces.Count; fi++)
                {
                    OBJFace face = faces[fi];
                    indices.Add(face[0]);
                    indices.Add(face[1]);
                    indices.Add(face[2]);
                }

                if (!materials.Contains(mat))
                {
                    materials.Add(mat);
                    mesh.subMeshCount++;
                }

                for (int ii = 0; ii < indices.Count; ii++)
                {
                    int index = indices[ii];
                    if (map.ContainsKey(index))
                    {
                        indices[ii] = map[index];
                    }
                    else
                    {
                        indices[ii] = map[index] = pVertices.Count;
                        pVertices.Add(UVertices[index]);
                        pNormals.Add(UNormals[index]);
                        pUVs.Add(UUVs[index]);
                    }
                }

                pIndices.Add(indices);
            }

            mesh.SetVertices(pVertices);
            mesh.SetNormals(pNormals);
            mesh.SetUVs(0, pUVs);

            for (int i = 0; i < pIndices.Count; i++)
            {
                mesh.SetTriangles(pIndices[i], i);
            }

            if (!ContainsNormals)
            {
                mesh.RecalculateNormals();
            }
            mesh.RecalculateBounds();
            mesh.Optimize();

            return(mesh);
        }