示例#1
0
        public OBJGroup Build(List <OBJMaterial> materials)
        {
            Mesh mesh = new Mesh();

            mesh.name     = this.meshName;
            mesh.vertices = vertices.ToArray();
            mesh.uv       = uv.ToArray();
            if (this.normals.Count > 0)
            {
                mesh.normals = normals.ToArray();
            }
            mesh.triangles = triangles.ToArray();
            if (this.normals.Count <= 0)
            {
                mesh.RecalculateNormals();
            }
            mesh.RecalculateBounds();

            var group = new OBJGroup(this.meshName, mesh);

            if (materials != null)
            {
                group.material = materials.Find((mat) => mat.name == this.mtlName);
            }

            return(group);
        }
示例#2
0
        //------------------------------------------------------------------------------------------------------------
        public static OBJData EncodeOBJ(this Mesh lMesh)
        {
            OBJData lData = new OBJData
            {
                m_Vertices = new List <Vector3>(lMesh.vertices),
                m_UVs      = new List <Vector2>(lMesh.uv),
                m_Normals  = new List <Vector3>(lMesh.normals),
                m_UV2s     = new List <Vector2>(lMesh.uv2),
                m_Colors   = new List <Color>(lMesh.colors)
            };

            int[]         lIndices    = null;
            OBJGroup      lGroup      = null;
            OBJFace       lFace       = null;
            OBJFaceVertex lFaceVertex = null;

            for (int lMCount = 0; lMCount < lMesh.subMeshCount; ++lMCount)
            {
                lIndices = lMesh.GetTriangles(lMCount);
                lGroup   = new OBJGroup(lMesh.name + "_" + lMCount.ToString());

                for (int lCount = 0; lCount < lIndices.Length; lCount += 3)
                {
                    lFace = new OBJFace();

                    lFaceVertex = new OBJFaceVertex();
                    lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount] : -1;
                    lFaceVertex.m_UVIndex     = lData.m_UVs.Count > 0 ? lIndices[lCount] : -1;
                    lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount] : -1;
                    lFaceVertex.m_UV2Index    = lData.m_UV2s.Count > 0 ? lIndices[lCount] : -1;
                    lFaceVertex.m_ColorIndex  = lData.m_Colors.Count > 0 ? lIndices[lCount] : -1;
                    lFace.AddVertex(lFaceVertex);

                    lFaceVertex = new OBJFaceVertex();
                    lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount + 1] : -1;
                    lFaceVertex.m_UVIndex     = lData.m_UVs.Count > 0 ? lIndices[lCount + 1] : -1;
                    lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount + 1] : -1;
                    lFaceVertex.m_UV2Index    = lData.m_UV2s.Count > 0 ? lIndices[lCount + 1] : -1;
                    lFaceVertex.m_ColorIndex  = lData.m_Colors.Count > 0 ? lIndices[lCount + 1] : -1;
                    lFace.AddVertex(lFaceVertex);

                    lFaceVertex = new OBJFaceVertex();
                    lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount + 2] : -1;
                    lFaceVertex.m_UVIndex     = lData.m_UVs.Count > 0 ? lIndices[lCount + 2] : -1;
                    lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount + 2] : -1;
                    lFaceVertex.m_UV2Index    = lData.m_UV2s.Count > 0 ? lIndices[lCount + 2] : -1;
                    lFaceVertex.m_ColorIndex  = lData.m_Colors.Count > 0 ? lIndices[lCount + 2] : -1;
                    lFace.AddVertex(lFaceVertex);

                    lGroup.AddFace(lFace);
                }

                lData.m_Groups.Add(lGroup);
            }

            return(lData);
        }
示例#3
0
    //------------------------------------------------------------------------------------------------------------
    public static OBJData LoadOBJ(Stream lStream)
    {
        m_OBJData = new OBJData();

        m_CurrentMaterial = null;
        m_CurrentGroup    = null;

        StreamReader lLineStreamReader = new StreamReader(lStream);

        Action <string> lAction      = null;
        string          lCurrentLine = null;

        string[] lFields  = null;
        string   lKeyword = null;
        string   lData    = null;


        while (!lLineStreamReader.EndOfStream)
        {
            lCurrentLine = lLineStreamReader.ReadLine();

            if (StringExt.IsNullOrWhiteSpace(lCurrentLine) ||
                lCurrentLine[0] == '#')
            {
                continue;
            }

            lFields = lCurrentLine.Trim().Split(null, 2);
            if (lFields.Length < 2)
            {
                continue;
            }

            lKeyword = lFields[0].Trim();
            lData    = lFields[1].Trim();

            lAction = null;
            m_ParseOBJActionDictionary.TryGetValue(lKeyword.ToLowerInvariant(), out lAction);

            if (lAction != null)
            {
                lAction(lData);
            }
        }

        Debug.Log("reached");
        var lOBJData = m_OBJData;

        m_OBJData = null;

        return(lOBJData);
    }
示例#4
0
        //------------------------------------------------------------------------------------------------------------
        public static void LoadOBJ(this Mesh lMesh, OBJData lData)
        {
            List <Vector3> lVertices = new List <Vector3>();
            List <Vector3> lNormals  = new List <Vector3>();
            List <Vector2> lUVs      = new List <Vector2>();

            List <int>[] lIndices = new List <int> [lData.m_Groups.Count];
            OBJGroup     lGroup   = null;

            lMesh.subMeshCount = lData.m_Groups.Count;


            for (int lGCount = 0; lGCount < lData.m_Groups.Count; ++lGCount)
            {
                lGroup            = lData.m_Groups[lGCount];
                lIndices[lGCount] = new List <int>();

                for (int lFCount = 0; lFCount < lGroup.Faces.Count; ++lFCount)
                {
                    for (int lVCount = 0; lVCount < lGroup.Faces[lFCount].Count; ++lVCount)
                    {
                        if (lGroup.Faces[lFCount][lVCount].m_VertexIndex < lData.m_Vertices.Count)
                        {
                            lIndices[lGCount].Add(lVertices.Count);

                            lVertices.Add(lData.m_Vertices[lGroup.Faces[lFCount][lVCount].m_VertexIndex]);
                            if (lGroup.Faces[lFCount][lVCount].m_UVIndex >= 0)
                            {
                                lUVs.Add(lData.m_UVs[lGroup.Faces[lFCount][lVCount].m_UVIndex]);
                            }
                            if (lGroup.Faces[lFCount][lVCount].m_NormalIndex >= 0)
                            {
                                lNormals.Add(lData.m_Normals[lGroup.Faces[lFCount][lVCount].m_NormalIndex]);
                            }
                        }
                    }
                }
            }

            lMesh.vertices = lVertices.ToArray();
            lMesh.uv       = lUVs.ToArray();
            lMesh.normals  = lNormals.ToArray();
            lMesh.RecalculateTangents();

            for (int lGCount = 0; lGCount < lData.m_Groups.Count; ++lGCount)
            {
                lMesh.SetTriangles(lIndices[lGCount].ToArray(), lGCount);
            }
        }
示例#5
0
    //------------------------------------------------------------------------------------------------------------
    public static OBJData LoadOBJ(Stream lStream)
    {
        m_OBJData = new OBJData();

        m_CurrentMaterial = null;
        m_CurrentGroup = null;

        StreamReader lLineStreamReader = new StreamReader(lStream);

        Action<string> lAction = null;
        string lCurrentLine = null;
        string[] lFields = null;
        string lKeyword = null;
        string lData = null;

        while (!lLineStreamReader.EndOfStream)
        {
            lCurrentLine = lLineStreamReader.ReadLine();

            if (StringExt.IsNullOrWhiteSpace(lCurrentLine) 
                || lCurrentLine[0] == '#')
            {
                continue;
            }

            lFields = lCurrentLine.Trim().Split(null, 2);
            if (lFields.Length < 2)
            {
                continue;
            }

            lKeyword = lFields[0].Trim();
            lData = lFields[1].Trim();

            lAction = null;
            m_ParseOBJActionDictionary.TryGetValue(lKeyword.ToLowerInvariant(), out lAction);

            if (lAction != null)
            {
                lAction(lData);
            }
        }

        var lOBJData = m_OBJData;
        m_OBJData = null;

        return lOBJData; 
    }
示例#6
0
        public void Read(string fname)
        {
            string input = File.ReadAllText(fname);

            RegexOptions options = RegexOptions.None;
            Regex        regex   = new Regex("[ ]{2,}", options);

            input = regex.Replace(input, " ");

            string[] lines = input.Split('\n');

            Vector3   v;
            OBJObject o = null;
            OBJGroup  g = null;

            for (int i = 0; i < lines.Length; i++)
            {
                string[] args = lines[i].Split(' ');
                switch (args[0])
                {
                case "v":
                    if (o == null)
                    {
                        o = new OBJObject();
                        g = new OBJGroup();
                        o.groups.Add(g);
                        objects.Add(o);
                    }
                    v = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3]));
                    this.v.Add(v);
                    break;

                case "vn":
                    v = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3]));
                    vn.Add(v);
                    break;

                case "vt":
                    vt.Add(new Vector2(float.Parse(args[1]), float.Parse(args[2])));
                    break;

                case "f":
                    g.v.Add(int.Parse(args[1].Split('/')[0]) - 1);
                    g.v.Add(int.Parse(args[2].Split('/')[0]) - 1);
                    g.v.Add(int.Parse(args[3].Split('/')[0]) - 1);
                    if (args[1].Split('/').Length > 1)
                    {
                        g.vt.Add(int.Parse(args[1].Split('/')[1]) - 1);
                        g.vt.Add(int.Parse(args[2].Split('/')[1]) - 1);
                        g.vt.Add(int.Parse(args[3].Split('/')[1]) - 1);
                    }
                    if (args[1].Split('/').Length > 2)
                    {
                        g.vn.Add(int.Parse(args[1].Split('/')[2]) - 1);
                        g.vn.Add(int.Parse(args[2].Split('/')[2]) - 1);
                        g.vn.Add(int.Parse(args[3].Split('/')[2]) - 1);
                    }
                    break;

                case "o":
                    o      = new OBJObject();
                    o.name = args[1];
                    objects.Add(o);
                    g = new OBJGroup();
                    o.groups.Add(g);
                    break;

                case "g":
                    g = new OBJGroup();
                    if (o == null || args.Length > 1)
                    {
                        o = new OBJObject();
                        if (args.Length > 1)
                        {
                            o.name = args[1];
                        }
                        objects.Add(o);
                    }
                    o.groups.Add(g);
                    break;
                }
            }
        }
示例#7
0
 //------------------------------------------------------------------------------------------------------------
 private static void PushOBJGroup(string lGroupName)
 {
     m_CurrentGroup = new OBJGroup(lGroupName);
     m_OBJData.m_Groups.Add(m_CurrentGroup);
 }
        //------------------------------------------------------------------------------------------------------------
        public static void LoadOBJ(this Mesh lMesh, OBJData lData)
        {
            List <Vector3> lVertices = new List <Vector3>();
            List <Vector3> lNormals  = new List <Vector3>();
            List <Vector2> lUVs      = new List <Vector2>();

            List <int>[] lIndices = new List <int> [lData.m_Groups.Count];
            Dictionary <OBJFaceVertex, int> lVertexIndexRemap = new Dictionary <OBJFaceVertex, int>();
            bool lHasNormals = lData.m_Normals.Count > 0;
            bool lHasUVs     = lData.m_UVs.Count > 0;

            lMesh.subMeshCount = lData.m_Groups.Count;
            for (int lGCount = 0; lGCount < lData.m_Groups.Count; ++lGCount)
            {
                OBJGroup lGroup = lData.m_Groups[lGCount];
                lIndices[lGCount] = new List <int>();

                for (int lFCount = 0; lFCount < lGroup.Faces.Count; ++lFCount)
                {
                    OBJFace lFace = lGroup.Faces[lFCount];

                    // Unity3d doesn't support non-triangle faces
                    // so we do simple fan triangulation
                    for (int lVCount = 1; lVCount < lFace.Count - 1; ++lVCount)
                    {
                        foreach (int i in new int[] { 0, lVCount, lVCount + 1 })
                        {
                            OBJFaceVertex lFaceVertex  = lFace[i];
                            int           lVertexIndex = -1;

                            if (!lVertexIndexRemap.TryGetValue(lFaceVertex, out lVertexIndex))
                            {
                                lVertexIndexRemap[lFaceVertex] = lVertices.Count;
                                lVertexIndex = lVertices.Count;

                                lVertices.Add(lData.m_Vertices[lFaceVertex.m_VertexIndex]);
                                if (lHasUVs)
                                {
                                    lUVs.Add(lData.m_UVs[lFaceVertex.m_UVIndex]);
                                }
                                if (lHasNormals)
                                {
                                    lNormals.Add(lData.m_Normals[lFaceVertex.m_NormalIndex]);
                                }
                            }

                            lIndices[lGCount].Add(lVertexIndex);
                        }
                    }
                }
            }

            lMesh.triangles = new int[] { };
            lMesh.vertices  = lVertices.ToArray();
            lMesh.uv        = lUVs.ToArray();
            lMesh.normals   = lNormals.ToArray();
            if (!lHasNormals)
            {
                lMesh.RecalculateNormals();
            }

            lMesh.RecalculateTangents();

            for (int lGCount = 0; lGCount < lData.m_Groups.Count; ++lGCount)
            {
                lMesh.SetTriangles(lIndices[lGCount].ToArray(), lGCount);
            }
        }
示例#9
0
        //------------------------------------------------------------------------------------------------------------
        public static OBJData EncodeOBJ(this Mesh lMesh)
        {
            OBJData lData = new OBJData
            {
                m_Vertices = new List<Vector3>(lMesh.vertices),
                m_UVs = new List<Vector2>(lMesh.uv),
                m_Normals = new List<Vector3>(lMesh.normals),
                m_UV2s = new List<Vector2>(lMesh.uv1),
                m_Colors = new List<Color>(lMesh.colors)
            };

            int[] lIndices = null;
            OBJGroup lGroup = null;
            OBJFace lFace = null;
            OBJFaceVertex lFaceVertex = null;

            for (int lMCount = 0; lMCount < lMesh.subMeshCount; ++lMCount)
            {
                lIndices = lMesh.GetTriangles(lMCount);
                lGroup = new OBJGroup(lMesh.name + "_" + lMCount.ToString());

                for (int lCount = 0; lCount < lIndices.Length; lCount += 3)
                {
                    lFace = new OBJFace();

                    lFaceVertex = new OBJFaceVertex();
                    lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount] : -1;
                    lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount] : -1;
                    lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount] : -1;
                    lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount] : -1;
                    lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount] : -1;
                    lFace.AddVertex(lFaceVertex);

                    lFaceVertex = new OBJFaceVertex();
                    lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount + 1] : -1;
                    lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount + 1] : -1;
                    lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount + 1] : -1;
                    lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount + 1] : -1;
                    lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount + 1] : -1;
                    lFace.AddVertex(lFaceVertex);

                    lFaceVertex = new OBJFaceVertex();
                    lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount + 2] : -1;
                    lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount + 2] : -1;
                    lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount + 2] : -1;
                    lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount + 2] : -1;
                    lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount + 2] : -1;
                    lFace.AddVertex(lFaceVertex);

                    lGroup.AddFace(lFace);
                }

                lData.m_Groups.Add(lGroup);
            }

            return lData;
        }
示例#10
0
 //------------------------------------------------------------------------------------------------------------
 private static void PushOBJGroup(string lGroupName)
 {
     m_CurrentGroup = new OBJGroup(lGroupName);
     m_OBJData.m_Groups.Add(m_CurrentGroup);
 }
示例#11
0
        public void Parse(TextReader reader)
        {
            // For each line:
            string   line;
            var      whitespace   = new char[] { ' ', '\t' };
            var      slash        = new char[] { '/' };
            OBJGroup currentGroup = null;

            while ((line = reader.ReadLine()) != null)
            {
                // Strip comment
                var commentIdx = line.IndexOf('#');
                if (commentIdx >= 0)
                {
                    line = line.Substring(0, commentIdx);
                }

                // Segment
                var parts = line.Split(whitespace, StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length == 0)
                {
                    continue;
                }

                // Parse
                var type = parts[0].ToLowerInvariant();
                switch (type)
                {
                case "mtllib":
                {
                    var path = parts[1];
                    MTLLib = path;
                    break;
                }

                case "o":
                case "g":
                {
                    var name = parts[1];
                    currentGroup = new OBJGroup(name);
                    Groups.Add(currentGroup);
                    break;
                }

                case "v":
                {
                    var x = float.Parse(parts[1], CultureInfo.InvariantCulture);
                    var y = float.Parse(parts[2], CultureInfo.InvariantCulture);
                    var z = float.Parse(parts[3], CultureInfo.InvariantCulture);
                    Positions.Add(new Vector3(x, y, z));
                    if (parts.Length > 4)
                    {
                        var r = float.Parse(parts[4], CultureInfo.InvariantCulture);
                        var g = float.Parse(parts[5], CultureInfo.InvariantCulture);
                        var b = float.Parse(parts[6], CultureInfo.InvariantCulture);
                        var a = (parts.Length > 7) ?
                                float.Parse(parts[7], CultureInfo.InvariantCulture) :
                                1.0f;
                        Colours.Add(new Vector4(r, g, b, a));
                    }
                    else
                    {
                        Colours.Add(Vector4.One);
                    }
                    break;
                }

                case "vt":
                {
                    var x = float.Parse(parts[1], CultureInfo.InvariantCulture);
                    var y = float.Parse(parts[2], CultureInfo.InvariantCulture);
                    TexCoords.Add(new Vector2(x, y));
                    break;
                }

                case "vn":
                {
                    var x = float.Parse(parts[1], CultureInfo.InvariantCulture);
                    var y = float.Parse(parts[2], CultureInfo.InvariantCulture);
                    var z = float.Parse(parts[3], CultureInfo.InvariantCulture);
                    Normals.Add(new Vector3(x, y, z));
                    break;
                }

                case "usemtl":
                {
                    var name = parts[1];
                    currentGroup.MaterialName = name;
                    break;
                }

                case "f":
                {
                    var face = new OBJFace();
                    face.FirstVertex = Verts.Count;
                    for (int i = 1; i < parts.Length; ++i)
                    {
                        var part     = parts[i];
                        var subParts = part.Split(slash, StringSplitOptions.None);
                        var vert     = new OBJVert();
                        if (subParts.Length > 0)
                        {
                            int posIndex;
                            if (int.TryParse(subParts[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out posIndex))
                            {
                                vert.PositionIndex = posIndex;
                            }
                        }
                        if (subParts.Length > 1)
                        {
                            int texCoordIndex;
                            if (int.TryParse(subParts[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out texCoordIndex))
                            {
                                vert.TexCoordIndex = texCoordIndex;
                            }
                        }
                        if (subParts.Length > 2)
                        {
                            int normalIndex;
                            if (int.TryParse(subParts[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out normalIndex))
                            {
                                vert.NormalIndex = normalIndex;
                            }
                        }
                        Verts.Add(vert);
                        face.VertexCount++;
                    }
                    currentGroup.Faces.Add(face);
                    break;
                }
                }
            }
        }