public void optimizeVertexCount()
        {
            return;

            if (areVerticesOptimized)
            {
                return;
            }
            List <Vector3> tmpList = new List <Vector3>();

            for (int j = 0; j < Faces.Count; j++)
            {
                OBJFace c     = Faces[j];
                int     count = c.VertexIndieces.Count;
                for (int i = 0; i < count; i++)
                {
                    int index = tmpList.FindIndex(v => v == Vertices[c.VertexIndieces[i]]);
                    if (index == -1)
                    {
                        tmpList.Add(Vertices[c.VertexIndieces[i]]);
                        c.VertexIndieces[i] = tmpList.Count - 1;
                    }
                    else
                    {
                        c.VertexIndieces[i] = index;
                    }
                }
            }
            Vertices             = tmpList;
            areVerticesOptimized = true;
        }
Beispiel #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);
        }
Beispiel #3
0
    //------------------------------------------------------------------------------------------------------------
    private static void PushOBJFace(string lFaceLine)
    {
        PushOBJGroupIfNeeded();

        var vertices = lFaceLine.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

        var face = new OBJFace();

        foreach (var vertexString in vertices)
        {
            face.ParseVertex(vertexString);
        }

        m_CurrentGroup.AddFace(face);
    }
Beispiel #4
0
        public static OBJFace readFace(string faceLine)
        {
            char[]   split       = { '/' };
            string[] faceStrings = faceLine.Split(split);

            OBJFace face = new OBJFace();

            if (faceStrings.Length == 3)              // #/#/#
            {
                face.positionIndex = Convert.ToUInt32(faceStrings[0].Trim());
                face.texCoordIndex = Convert.ToUInt32(faceStrings[1].Trim());
                face.normalIndex   = Convert.ToUInt32(faceStrings[2].Trim());
            }

            return(face);
        }
Beispiel #5
0
        public void Triangulate()
        {
            List< OBJFace > triangulatedFaces = new List< OBJFace >( faces.Count );

            foreach( OBJFace face in faces )
            {
                int nVertices = face.NumVertices;

                int v0 = face.PositionIndices[ 0 ];
                for( int v = 1; v < nVertices - 1; ++v )
                {
                    int v1 = face.PositionIndices[ v ];
                    int v2 = face.PositionIndices[ v + 1 ];

                    OBJFace triangle = new OBJFace( face.HasTextureCoordinates, face.HasNormals );
                    triangle.PositionIndices.Add( v0 );
                    triangle.PositionIndices.Add( v1 );
                    triangle.PositionIndices.Add( v2 );

                    if( face.HasTextureCoordinates )
                    {
                        triangle.TextureCoordinateIndices.Add( face.TextureCoordinateIndices[ 0 ] );
                        triangle.TextureCoordinateIndices.Add( face.TextureCoordinateIndices[ v ] );
                        triangle.TextureCoordinateIndices.Add( face.TextureCoordinateIndices[ v + 1 ] );
                    }

                    if( face.HasNormals )
                    {
                        triangle.NormalIndices.Add( face.NormalIndices[ 0 ] );
                        triangle.NormalIndices.Add( face.NormalIndices[ v ] );
                        triangle.NormalIndices.Add( face.NormalIndices[ v + 1 ] );
                    }

                    triangulatedFaces.Add( triangle );
                }
            }

            faces = triangulatedFaces;
        }
        //------------------------------------------------------------------------------------------------------------
        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);
            }
        }
Beispiel #7
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;
        }
Beispiel #8
0
 public OBJFinder(OBJFace target)
 {
     targetFace = target;
 }
Beispiel #9
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;
                }
                }
            }
        }
Beispiel #10
0
    public static GameObject LoadOBJFile(string filePath, bool inputIsRawOBJ = false)
    {
        string meshName = !inputIsRawOBJ?Path.GetFileNameWithoutExtension(filePath) : "LoadedOBJMesh";

        bool hasNormals = false;
        //OBJ LISTS
        List <Vector3> vertices = new List <Vector3>();
        List <Vector3> normals  = new List <Vector3>();
        List <Vector2> uvs      = new List <Vector2>();
        //UMESH LISTS
        List <Vector3> uvertices = new List <Vector3>();
        List <Vector3> unormals  = new List <Vector3>();
        List <Vector2> uuvs      = new List <Vector2>();
        //MESH CONSTRUCTION
        List <string>            materialNames = new List <string>();
        List <string>            objectNames   = new List <string>();
        Dictionary <string, int> hashtable     = new Dictionary <string, int>();
        List <OBJFace>           faceList      = new List <OBJFace>();
        string cmaterial = "";
        string cmesh     = "default";

        //CACHE
        Material[] materialCache = null;

        //save this info for later
        FileInfo OBJFileInfo = null;

        string[] OBJLines;

        if (!inputIsRawOBJ)
        {
            OBJFileInfo = new FileInfo(filePath);

            OBJLines = File.ReadAllLines(filePath);
        }
        else
        {
            OBJLines = filePath.Split(new[] { "\r", "\n" }, StringSplitOptions.None);
        }

        foreach (string ln in OBJLines)
        {
            if (ln.Length > 0 && ln[0] != '#')
            {
                string   l    = ln.Trim().Replace("  ", " ");
                string[] cmps = l.Split(' ');
                string   data = l.Remove(0, l.IndexOf(' ') + 1);

                if (cmps[0] == "mtllib" && !inputIsRawOBJ && OBJFileInfo != null)
                {
                    //load cache
                    string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName);
                    if (pth != null)
                    {
                        materialCache = LoadMTLFile(pth);
                    }
                }
                else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false)
                {
                    cmesh = data;
                    if (!objectNames.Contains(cmesh))
                    {
                        objectNames.Add(cmesh);
                    }
                }
                else if (cmps[0] == "usemtl")
                {
                    cmaterial = data;
                    if (!materialNames.Contains(cmaterial))
                    {
                        materialNames.Add(cmaterial);
                    }

                    if (splitByMaterial)
                    {
                        if (!objectNames.Contains(cmaterial))
                        {
                            objectNames.Add(cmaterial);
                        }
                    }
                }
                else if (cmps[0] == "v")
                {
                    //VERTEX
                    vertices.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "vn")
                {
                    //VERTEX NORMAL
                    normals.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "vt")
                {
                    //VERTEX UV
                    uvs.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "f")
                {
                    int[] indexes = new int[cmps.Length - 1];
                    for (int i = 1; i < cmps.Length; i++)
                    {
                        string felement    = cmps[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);
                        }
                    }
                }
            }
        }

        if (objectNames.Count == 0)
        {
            objectNames.Add("default");
        }

        //build objects
        GameObject parentObject = new GameObject(meshName);


        for (int objectNamesIndex = 0; objectNamesIndex < objectNames.Count; objectNamesIndex++)
        {
            string     obj             = objectNames[objectNamesIndex];
            GameObject subObjectParent = new GameObject(obj);
            subObjectParent.transform.parent = parentObject.transform;

            GameObject subObject = new GameObject("ChildMesh");
            subObject.transform.parent     = subObjectParent.transform;
            subObject.transform.localScale = new Vector3(-1, 1, 1);
            //Create mesh
            Mesh m = new Mesh();
            m.name = obj;
            //LISTS FOR REORDERING
            List <Vector3>        processedVertices = new List <Vector3>();
            List <Vector3>        processedNormals  = new List <Vector3>();
            List <Vector2>        processedUVs      = new List <Vector2>();
            List <int[]>          processedIndexes  = new List <int[]>();
            Dictionary <int, int> remapTable        = new Dictionary <int, int>();
            //POPULATE MESH
            List <string> meshMaterialNames = new List <string>();

            OBJFace[] ofaces = faceList.Where(x => x.meshName == obj).ToArray();

            foreach (string mn in materialNames)
            {
                OBJFace[] faces = ofaces.Where(x => x.materialName == mn).ToArray();

                if (faces.Length > 0)
                {
                    int[] indexes = new int[0];

                    foreach (OBJFace f in faces)
                    {
                        int l = indexes.Length;
                        System.Array.Resize(ref indexes, l + f.indexes.Length);
                        System.Array.Copy(f.indexes, 0, indexes, l, f.indexes.Length);
                    }

                    meshMaterialNames.Add(mn);

                    if (m.subMeshCount != meshMaterialNames.Count)
                    {
                        m.subMeshCount = meshMaterialNames.Count;
                    }

                    for (int i = 0; i < indexes.Length; i++)
                    {
                        int idx = indexes[i];
                        //build remap table
                        if (remapTable.ContainsKey(idx))
                        {
                            //ezpz
                            indexes[i] = remapTable[idx];
                        }
                        else
                        {
                            processedVertices.Add(uvertices[idx]);
                            processedNormals.Add(unormals[idx]);
                            processedUVs.Add(uuvs[idx]);
                            remapTable[idx] = processedVertices.Count - 1;
                            indexes[i]      = remapTable[idx];
                        }
                    }

                    processedIndexes.Add(indexes);
                }
            }

            //apply stuff
            m.vertices = processedVertices.ToArray();
            m.normals  = processedNormals.ToArray();
            m.uv       = processedUVs.ToArray();

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

            if (!hasNormals)
            {
                m.RecalculateNormals();
            }

            m.RecalculateBounds();

            MeshFilter   mf = subObject.AddComponent <MeshFilter>();
            MeshRenderer mr = subObject.AddComponent <MeshRenderer>();

            Material[] processedMaterials = new Material[meshMaterialNames.Count];

            for (int i = 0; i < meshMaterialNames.Count; i++)
            {
                if (materialCache == null)
                {
                    processedMaterials[i] = new Material(Shader.Find("Universal Render Pipeline/Simple Lit"));
                }
                else
                {
                    Material mfn = Array.Find(materialCache, x => x.name == meshMaterialNames[i]);

                    if (mfn == null)
                    {
                        processedMaterials[i] = new Material(Shader.Find("Universal Render Pipeline/Simple Lit"));
                    }
                    else
                    {
                        processedMaterials[i] = mfn;
                    }
                }

                processedMaterials[i].name = meshMaterialNames[i];
            }

            mr.materials = processedMaterials;
            mf.mesh      = m;
        }

        return(parentObject);
    }
Beispiel #11
0
 //------------------------------------------------------------------------------------------------------------
 public void AddFace(OBJFace lFace)
 {
     m_Faces.Add(lFace);
 }
Beispiel #12
0
        public static PreparedMesh prepare(string fn)
        {
            PreparedMesh prepMesh = new PreparedMesh();

            List <string>  objectNames = prepMesh.objectNames;
            List <OBJFace> faceList    = prepMesh.faceList;

            string meshName = Path.GetFileNameWithoutExtension(fn);

            //OBJ LISTS
            List <Vector3> vertices = new List <Vector3>(1000);
            List <Vector3> normals  = new List <Vector3>(1000);
            List <Vector2> uvs      = new List <Vector2>(1000);
            //UMESH LISTS

            //MESH CONSTRUCTION
            List <string> materialNames = prepMesh.materialNames;

            Dictionary <string, int> hashtable = new Dictionary <string, int>();

            string cmaterial = "";
            string cmesh     = "default";
            //CACHE
            //save this info for later
            FileInfo OBJFileInfo = new FileInfo(fn);

            Debug.Log("cmesh:" + cmesh);
            Debug.Log("cmaterial:" + cmaterial);



            String       ln     = "";
            StreamReader reader = new StreamReader(fn);

            while ((ln = reader.ReadLine()) != null)
            {
                if (ln.Length > 0 && ln[0] != '#')
                {
                    string   l    = ln.Trim().Replace("  ", " ");
                    string[] cmps = l.Split(' ');
                    string   data = l.Remove(0, l.IndexOf(' ') + 1);
                    //Debug.Log("parse: " + l);

                    if (cmps[0] == "mtllib")
                    {
                        //load cache
                        string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName);
                        if (pth != null)
                        {
                            prepMesh.materialCache = LoadMTLFile(pth);
                        }
                    }
                    else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false)
                    {
                        cmesh = data;
                        if (!objectNames.Contains(cmesh))
                        {
                            objectNames.Add(cmesh);
                        }
                    }
                    else if (cmps[0] == "usemtl")
                    {
                        cmaterial = data;
                        if (!materialNames.Contains(cmaterial))
                        {
                            materialNames.Add(cmaterial);
                        }

                        if (splitByMaterial)
                        {
                            if (!objectNames.Contains(cmaterial))
                            {
                                objectNames.Add(cmaterial);
                            }
                        }
                    }
                    else if (cmps[0] == "v")
                    {
                        //VERTEX
                        vertices.Add(ParseVectorFromCMPS(cmps));
                    }
                    else if (cmps[0] == "vn")
                    {
                        //VERTEX NORMAL
                        normals.Add(ParseVectorFromCMPS(cmps));
                    }
                    else if (cmps[0] == "vt")
                    {
                        //VERTEX UV
                        uvs.Add(ParseVectorFromCMPS(cmps));
                    }
                    else if (cmps[0] == "f")
                    {
                        int[] indexes = new int[cmps.Length - 1];
                        for (int i = 1; i < cmps.Length; i++)
                        {
                            string felement    = cmps[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;
                                prepMesh.uvertices.Add(vertices[vertexIndex]);
                                if (normalIndex < 0 || (normalIndex > (normals.Count - 1)))
                                {
                                    prepMesh.unormals.Add(Vector3.zero);
                                }
                                else
                                {
                                    prepMesh.hasNormals = true;
                                    prepMesh.unormals.Add(normals[normalIndex]);
                                }
                                if (uvIndex < 0 || (uvIndex > (uvs.Count - 1)))
                                {
                                    prepMesh.uuvs.Add(Vector2.zero);
                                }
                                else
                                {
                                    prepMesh.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);
                            }
                        }
                    }
                }
            }

            reader.Close();
            if (objectNames.Count == 0)
            {
                objectNames.Add("default");
            }

            prepMesh.pMesh2 = prepMesh2(prepMesh, fn);

            return(prepMesh);
        }
    public static OBJMesh LoadOBJMesh(string fn)
    {
        string meshName = Path.GetFileNameWithoutExtension(fn);

        bool hasNormals = false;
        //OBJ LISTS
        List <Vector3> vertices = new List <Vector3>();
        List <Vector3> normals  = new List <Vector3>();
        List <Vector2> uvs      = new List <Vector2>();
        //MESH CONSTRUCTION
        List <string>            materialNames = new List <string>();
        List <string>            objectNames   = new List <string>();
        Dictionary <string, int> hashtable     = new Dictionary <string, int>();
        List <OBJFace>           faceList      = new List <OBJFace>();
        string cmaterial = "";
        string cmesh     = "default";

        //CACHE
        Material[] materialCache = null;
        //save this info for later
        FileInfo OBJFileInfo = new FileInfo(fn);

        foreach (string ln in File.ReadAllLines(fn))
        {
            if (ln.Length > 0 && ln[0] != '#')
            {
                string   l    = ln.Trim().Replace("  ", " ");
                string[] cmps = l.Split(' ');
                string   data = l.Remove(0, l.IndexOf(' ') + 1);

                if (cmps[0] == "mtllib")
                {
                    //load cache
                    string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName);
                    if (pth != null)
                    {
                        materialCache = LoadMTLFile(pth);
                    }
                }
                else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false)
                {
                    cmesh = data;
                    if (!objectNames.Contains(cmesh))
                    {
                        objectNames.Add(cmesh);
                    }
                }
                else if (cmps[0] == "usemtl")
                {
                    cmaterial = data;
                    if (!materialNames.Contains(cmaterial))
                    {
                        materialNames.Add(cmaterial);
                    }

                    if (splitByMaterial)
                    {
                        if (!objectNames.Contains(cmaterial))
                        {
                            objectNames.Add(cmaterial);
                        }
                    }
                }
                else if (cmps[0] == "v")
                {
                    //VERTEX
                    vertices.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "vn")
                {
                    //VERTEX NORMAL
                    normals.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "vt")
                {
                    //VERTEX UV
                    uvs.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "f")
                {
                    int[] indexes = new int[cmps.Length - 1];
                    for (int i = 1; i < cmps.Length; i++)
                    {
                        string felement    = cmps[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;
                        }

                        indexes[i - 1] = vertexIndex;
                    }
                    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);
                        }
                    }
                }
            }
        }

        // return object with verts and faces
        OBJMesh finalMesh = new OBJMesh();

        finalMesh.vertices = vertices;
        finalMesh.faces    = faceList;
        return(finalMesh);
    }
Beispiel #14
0
            public bool isSame(OBJFace test)
            {
                FaceComparer f = new FaceComparer();

                return(f.Compare(targetFace, test) == 0);
            }
    public static GameObject LoadOBJFile(string fn)
    {

        string meshName = Path.GetFileNameWithoutExtension(fn);

        bool hasNormals = false;
        //OBJ LISTS
        List<Vector3> vertices = new List<Vector3>();
        List<Vector3> normals = new List<Vector3>();
        List<Vector2> uvs = new List<Vector2>();
        //UMESH LISTS
        List<Vector3> uvertices = new List<Vector3>();
        List<Vector3> unormals = new List<Vector3>();
        List<Vector2> uuvs = new List<Vector2>();
        //MESH CONSTRUCTION
        List<string> materialNames = new List<string>();
        List<string> objectNames = new List<string>();
        Dictionary<string,int> hashtable = new Dictionary<string, int>();
        List<OBJFace> faceList = new List<OBJFace>();
        string cmaterial = "";
        string cmesh = "default";
        //CACHE
        Material[] materialCache = null;
        //save this info for later
        FileInfo OBJFileInfo = new FileInfo(fn);
         
        foreach (string ln in File.ReadAllLines(fn))
        {
            if (ln.Length > 0 && ln[0] != '#')
            {
                string l = ln.Trim().Replace("  "," ");
                string[] cmps = l.Split(' ');
                string data = l.Remove(0, l.IndexOf(' ') + 1);

                if (cmps[0] == "mtllib")
                {
                    //load cache
                    string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName);
                    if (pth != null)
                        materialCache = LoadMTLFile(pth);

                }
                else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false)
                {
                    cmesh = data;
                    if (!objectNames.Contains(cmesh))
                    {
                        objectNames.Add(cmesh);
                    }
                }
                else if (cmps[0] == "usemtl")
                {
                    cmaterial = data;
                    if (!materialNames.Contains(cmaterial))
                    {
                        materialNames.Add(cmaterial);
                    }

                    if (splitByMaterial)
                    {
                        if (!objectNames.Contains(cmaterial))
                        {
                            objectNames.Add(cmaterial);
                        }
                    }
                }
                else if (cmps[0] == "v")
                {
                    //VERTEX
                    vertices.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "vn")
                {
                    //VERTEX NORMAL
                    normals.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "vt")
                {
                    //VERTEX UV
                    uvs.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "f")
                {
                    int[] indexes = new int[cmps.Length - 1];
                    for (int i = 1; i < cmps.Length ; i++)
                    {
                        string felement = cmps[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);
                        }
                    }
                }
            }
        }

        if (objectNames.Count == 0)
            objectNames.Add("default");
       
        //build objects
        GameObject parentObject = new GameObject(meshName);
        
        
        foreach (string obj in objectNames)
        {
            GameObject subObject = new GameObject(obj);
            subObject.transform.parent = parentObject.transform;
            subObject.transform.localScale = new Vector3(-1, 1, 1);
            //Create mesh
            Mesh m = new Mesh();
            m.name = obj;
            //LISTS FOR REORDERING
            List<Vector3> processedVertices = new List<Vector3>();
            List<Vector3> processedNormals = new List<Vector3>();
            List<Vector2> processedUVs = new List<Vector2>();
            List<int[]> processedIndexes = new List<int[]>();
            Dictionary<int,int> remapTable = new Dictionary<int, int>();
            //POPULATE MESH
            List<string> meshMaterialNames = new List<string>();

            OBJFace[] ofaces = faceList.Where(x =>  x.meshName == obj).ToArray();
            foreach (string mn in materialNames)
            {
                OBJFace[] faces = ofaces.Where(x => x.materialName == mn).ToArray();
                if (faces.Length > 0)
                {
                    int[] indexes = new int[0];
                    foreach (OBJFace f in faces)
                    {
                        int l = indexes.Length;
                        System.Array.Resize(ref indexes, l + f.indexes.Length);
                        System.Array.Copy(f.indexes, 0, indexes, l, f.indexes.Length);
                    }
                    meshMaterialNames.Add(mn);
                    if (m.subMeshCount != meshMaterialNames.Count)
                        m.subMeshCount = meshMaterialNames.Count;

                    for (int i = 0; i < indexes.Length; i++)
                    {
                        int idx = indexes[i];
                        //build remap table
                        if (remapTable.ContainsKey(idx))
                        {
                            //ezpz
                            indexes[i] = remapTable[idx];
                        }
                        else
                        {
                            processedVertices.Add(uvertices[idx]);
                            processedNormals.Add(unormals[idx]);
                            processedUVs.Add(uuvs[idx]);
                            remapTable[idx] = processedVertices.Count - 1;
                            indexes[i] = remapTable[idx];
                        }
                    }

                    processedIndexes.Add(indexes);
                }
                else
                {

                }
            }

            //apply stuff
            m.vertices = processedVertices.ToArray();
            m.normals = processedNormals.ToArray();
            m.uv = processedUVs.ToArray();

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

            if (!hasNormals)
            {
             m.RecalculateNormals();   
            }
            m.RecalculateBounds();
            m.Optimize();

            MeshFilter mf = subObject.AddComponent<MeshFilter>();
            MeshRenderer mr = subObject.AddComponent<MeshRenderer>();

            Material[] processedMaterials = new Material[meshMaterialNames.Count];
            for(int i=0 ; i < meshMaterialNames.Count; i++)
            {
                
                if (materialCache == null)
                {
                    processedMaterials[i] = new Material(Shader.Find("Standard (Specular setup)"));
                }
                else
                {
                    Material mfn = Array.Find(materialCache, x => x.name == meshMaterialNames[i]); ;
                    if (mfn == null)
                    {
                        processedMaterials[i] = new Material(Shader.Find("Standard (Specular setup)"));
                    }
                    else
                    {
                        processedMaterials[i] = mfn;
                    }
                    
                }
                processedMaterials[i].name = meshMaterialNames[i];
            }

            mr.materials = processedMaterials;
            mf.mesh = m;

        }

        return parentObject;
        }
Beispiel #16
0
    public static GameObject LoadOBJ(string meshName, List <string> fileContents, Material baseMaterial)
    {
        bool hasNormals = false;
        //OBJ LISTS
        List <Vector3> vertices = new List <Vector3>();
        List <Vector3> normals  = new List <Vector3>();
        List <Vector2> uvs      = new List <Vector2>();
        //UMESH LISTS
        List <Vector3> uvertices = new List <Vector3>();
        List <Vector3> unormals  = new List <Vector3>();
        List <Vector2> uuvs      = new List <Vector2>();
        //MESH CONSTRUCTION
        List <string>            materialNames = new List <string>();
        List <string>            objectNames   = new List <string>();
        Dictionary <string, int> hashtable     = new Dictionary <string, int>();
        List <OBJFace>           faceList      = new List <OBJFace>();
        string cmaterial = "";
        string cmesh     = "default";

        foreach (string ln in fileContents)
        {
            if (ln.Length > 0 && ln[0] != '#')
            {
                string   l    = ln.Trim().Replace("  ", " ");
                string[] cmps = l.Split(' ');
                string   data = l.Remove(0, l.IndexOf(' ') + 1);

                if (cmps[0] == "mtllib")
                {
                }
                else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false)
                {
                    cmesh = data;
                    if (!objectNames.Contains(cmesh))
                    {
                        objectNames.Add(cmesh);
                    }
                }
                else if (cmps[0] == "usemtl")
                {
                    cmaterial = data;
                    if (!materialNames.Contains(cmaterial))
                    {
                        materialNames.Add(cmaterial);
                    }

                    if (splitByMaterial)
                    {
                        if (!objectNames.Contains(cmaterial))
                        {
                            objectNames.Add(cmaterial);
                        }
                    }
                }
                else if (cmps[0] == "v")
                {
                    //VERTEX
                    vertices.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "vn")
                {
                    //VERTEX NORMAL
                    normals.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "vt")
                {
                    //VERTEX UV
                    uvs.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "f")
                {
                    int[] indexes = new int[cmps.Length - 1];
                    for (int i = 1; i < cmps.Length; i++)
                    {
                        string felement    = cmps[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);
                        }
                    }
                }
            }
        }

        if (objectNames.Count == 0)
        {
            objectNames.Add("default");
        }
        if (materialNames.Count == 0)
        {
            materialNames.Add("");
        }

        //build objects
        GameObject parentObject = new GameObject(meshName);


        foreach (string obj in objectNames)
        {
            GameObject subObject = new GameObject(obj);
            subObject.transform.parent     = parentObject.transform;
            subObject.transform.localScale = new Vector3(-1, 1, 1);
            //Create mesh
            Mesh m = new Mesh();
            m.name = obj;
            //LISTS FOR REORDERING
            List <Vector3>        processedVertices = new List <Vector3>();
            List <Vector3>        processedNormals  = new List <Vector3>();
            List <Vector2>        processedUVs      = new List <Vector2>();
            List <int[]>          processedIndexes  = new List <int[]>();
            Dictionary <int, int> remapTable        = new Dictionary <int, int>();
            //POPULATE MESH
            List <string> meshMaterialNames = new List <string>();

            OBJFace[] ofaces = faceList.Where(x => x.meshName == obj).ToArray();
            foreach (string mn in materialNames)
            {
                OBJFace[] faces = ofaces.Where(x => x.materialName == mn).ToArray();
                if (faces.Length > 0)
                {
                    int[] indexes = new int[0];
                    foreach (OBJFace f in faces)
                    {
                        int l = indexes.Length;
                        System.Array.Resize(ref indexes, l + f.indexes.Length);
                        System.Array.Copy(f.indexes, 0, indexes, l, f.indexes.Length);
                    }
                    meshMaterialNames.Add(mn);
                    if (m.subMeshCount != meshMaterialNames.Count)
                    {
                        m.subMeshCount = meshMaterialNames.Count;
                    }

                    for (int i = 0; i < indexes.Length; i++)
                    {
                        int idx = indexes[i];
                        //build remap table
                        if (remapTable.ContainsKey(idx))
                        {
                            //ezpz
                            indexes[i] = remapTable[idx];
                        }
                        else
                        {
                            processedVertices.Add(uvertices[idx]);
                            processedNormals.Add(unormals[idx]);
                            processedUVs.Add(uuvs[idx]);
                            remapTable[idx] = processedVertices.Count - 1;
                            indexes[i]      = remapTable[idx];
                        }
                    }

                    processedIndexes.Add(indexes);
                }
                else
                {
                }
            }

            //apply stuff
            m.vertices = processedVertices.ToArray();
            m.normals  = processedNormals.ToArray();
            m.uv       = processedUVs.ToArray();

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

            if (!hasNormals)
            {
                m.RecalculateNormals();
            }
            m.RecalculateBounds();

            MeshFilter   mf = subObject.AddComponent <MeshFilter>();
            MeshRenderer mr = subObject.AddComponent <MeshRenderer>();

            Material[] processedMaterials = new Material[meshMaterialNames.Count];
            for (int i = 0; i < meshMaterialNames.Count; i++)
            {
                processedMaterials[i]      = new Material(baseMaterial);
                processedMaterials[i].name = meshMaterialNames[i];
            }

            mr.materials = processedMaterials;
            mf.mesh      = m;
        }

        return(parentObject);
    }
Beispiel #17
0
    //------------------------------------------------------------------------------------------------------------
    private static void PushOBJFace(string lFaceLine)
    {
		PushOBJGroupIfNeeded();

        var vertices = lFaceLine.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

        var face = new OBJFace();

        foreach (var vertexString in vertices)
        {
            face.ParseVertex(vertexString);
        }

        m_CurrentGroup.AddFace(face);
    }
Beispiel #18
0
 //------------------------------------------------------------------------------------------------------------
 public void AddFace(OBJFace lFace)
 {
     m_Faces.Add(lFace);
 }
Beispiel #19
0
    public static Mesh LoadOBJFileToMesh(string fn)
    {
        Mesh m = new Mesh();

        string meshName = Path.GetFileNameWithoutExtension(fn);

        bool hasNormals = false;
        //OBJ LISTS
        List <Vector3> vertices = new List <Vector3>();
        List <Vector3> normals  = new List <Vector3>();
        List <Vector2> uvs      = new List <Vector2>();
        //UMESH LISTS
        List <Vector3> uvertices = new List <Vector3>();
        List <Vector3> unormals  = new List <Vector3>();
        List <Vector2> uuvs      = new List <Vector2>();
        //MESH CONSTRUCTION
        List <string>            materialNames = new List <string>();
        List <string>            objectNames   = new List <string>();
        Dictionary <string, int> hashtable     = new Dictionary <string, int>();
        List <OBJFace>           faceList      = new List <OBJFace>();
        string cmaterial = "";
        string cmesh     = "default";

        //CACHE
        Material[] materialCache = null;
        //save this info for later
        FileInfo OBJFileInfo = new FileInfo(fn);

        foreach (string ln in File.ReadAllLines(fn))
        {
            if (ln.Length > 0 && ln[0] != '#')
            {
                string   l    = ln.Trim().Replace("  ", " ");
                string[] cmps = l.Split(' ');
                string   data = l.Remove(0, l.IndexOf(' ') + 1);

                if (cmps[0] == "mtllib")
                {
                    //load cache
                    string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName);
                    if (pth != null)
                    {
                        materialCache = LoadMTLFile(pth);
                    }
                }
                else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false)
                {
                    cmesh = data;
                    if (!objectNames.Contains(cmesh))
                    {
                        objectNames.Add(cmesh);
                    }
                }
                else if (cmps[0] == "usemtl")
                {
                    cmaterial = data;
                    if (!materialNames.Contains(cmaterial))
                    {
                        materialNames.Add(cmaterial);
                    }

                    if (splitByMaterial)
                    {
                        if (!objectNames.Contains(cmaterial))
                        {
                            objectNames.Add(cmaterial);
                        }
                    }
                }
                else if (cmps[0] == "v")
                {
                    //VERTEX
                    vertices.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "vn")
                {
                    //VERTEX NORMAL
                    normals.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "vt")
                {
                    //VERTEX UV
                    uvs.Add(ParseVectorFromCMPS(cmps));
                }
                else if (cmps[0] == "f")
                {
                    int[] indexes = new int[cmps.Length - 1];
                    for (int i = 1; i < cmps.Length; i++)
                    {
                        string felement    = cmps[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);
                        }
                    }
                }
            }
        }

        foreach (string obj in objectNames)
        {
            //LISTS FOR REORDERING
            List <Vector3>        processedVertices = new List <Vector3>();
            List <Vector3>        processedNormals  = new List <Vector3>();
            List <Vector2>        processedUVs      = new List <Vector2>();
            List <int[]>          processedIndexes  = new List <int[]>();
            Dictionary <int, int> remapTable        = new Dictionary <int, int>();
            //POPULATE MESH
            List <string> meshMaterialNames = new List <string>();

            OBJFace[] ofaces = faceList.Where(x => x.meshName == obj).ToArray();
            foreach (string mn in materialNames)
            {
                OBJFace[] faces = ofaces.Where(x => x.materialName == mn).ToArray();
                if (faces.Length > 0)
                {
                    int[] indexes = new int[0];
                    foreach (OBJFace f in faces)
                    {
                        int l = indexes.Length;
                        System.Array.Resize(ref indexes, l + f.indexes.Length);
                        System.Array.Copy(f.indexes, 0, indexes, l, f.indexes.Length);
                    }
                    meshMaterialNames.Add(mn);
                    if (m.subMeshCount != meshMaterialNames.Count)
                    {
                        m.subMeshCount = meshMaterialNames.Count;
                    }

                    for (int i = 0; i < indexes.Length; i++)
                    {
                        int idx = indexes[i];
                        //build remap table
                        if (remapTable.ContainsKey(idx))
                        {
                            //ezpz
                            indexes[i] = remapTable[idx];
                        }
                        else
                        {
                            processedVertices.Add(uvertices[idx]);
                            processedNormals.Add(unormals[idx]);
                            processedUVs.Add(uuvs[idx]);
                            remapTable[idx] = processedVertices.Count - 1;
                            indexes[i]      = remapTable[idx];
                        }
                    }

                    processedIndexes.Add(indexes);
                }
                else
                {
                }
            }

            //apply stuff
            m.vertices = processedVertices.ToArray();
            m.normals  = processedNormals.ToArray();
            m.uv       = processedUVs.ToArray();

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

            if (!hasNormals)
            {
                m.RecalculateNormals();
            }
            m.RecalculateNormals();
            m.RecalculateTangents();
            m.RecalculateBounds();
            ;
        }

        return(m);
    }
        public OBJ(byte[] Data)
        {
            var    enusculture = new CultureInfo("en-US");
            string curmat      = null;

            Vertices  = new List <Vector3>();
            Normals   = new List <Vector3>();
            TexCoords = new List <Vector2>();
            Faces     = new List <OBJFace>();
            TextReader tr = new StreamReader(new MemoryStream(Data));
            String     line;

            while ((line = tr.ReadLine()) != null)
            {
                line = line.Trim();
                if (line.Length < 1 || line.StartsWith("#"))
                {
                    continue;
                }

                string[] parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length < 1)
                {
                    continue;
                }
                switch (parts[0])
                {
                case "mtllib":
                    if (parts.Length < 2)
                    {
                        continue;
                    }
                    MTLPath = line.Substring(parts[0].Length + 1).Trim();
                    break;

                case "usemtl":
                    if (parts.Length < 2)
                    {
                        continue;
                    }
                    curmat = parts[1];
                    break;

                case "v":
                {
                    if (parts.Length < 4)
                    {
                        continue;
                    }
                    float x = float.Parse(parts[1], enusculture);
                    float y = float.Parse(parts[2], enusculture);
                    float z = float.Parse(parts[3], enusculture);
                    Vertices.Add(new Vector3(x, y, z));
                    break;
                }

                case "vn":
                {
                    if (parts.Length < 4)
                    {
                        continue;
                    }
                    float x = float.Parse(parts[1], enusculture);
                    float y = float.Parse(parts[2], enusculture);
                    float z = float.Parse(parts[3], enusculture);
                    Normals.Add(new Vector3(x, y, z));
                    break;
                }

                case "vt":
                {
                    if (parts.Length < 3)
                    {
                        continue;
                    }
                    float s = float.Parse(parts[1], enusculture);
                    float t = float.Parse(parts[2], enusculture);
                    TexCoords.Add(new Vector2(s, t));
                    break;
                }

                case "f":
                {
                    if (parts.Length < 4)
                    {
                        continue;
                    }
                    OBJFace f = new OBJFace();
                    f.Material = curmat;
                    for (int i = 0; i < parts.Length - 1; i++)
                    {
                        String[] Parts = parts[i + 1].Split('/');
                        f.VertexIndieces.Add(int.Parse(Parts[0]) - 1);
                        if (Parts.Length > 1)
                        {
                            if (Parts[1] != "")
                            {
                                f.TexCoordIndieces.Add(int.Parse(Parts[1]) - 1);
                            }
                            if (Parts.Length > 2 && Parts[2] != "")
                            {
                                f.NormalIndieces.Add(int.Parse(Parts[2]) - 1);
                            }
                        }
                    }
                    Faces.Add(f);
                    break;
                }
                }
            }
            tr.Close();
            //optimizeVertexCount();
        }
Beispiel #21
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);
                        }
                    }
                }
            }
        }
    }
Beispiel #22
0
    IEnumerator LoadOBJFile(string fn)
    {
        string meshName = Path.GetFileNameWithoutExtension(fn);

        bool hasNormals = false;
        //OBJ LISTS
        List <Vector3> vertices = new List <Vector3>();
        List <Vector3> normals  = new List <Vector3>();
        List <Vector2> uvs      = new List <Vector2>();
        //UMESH LISTS
        List <Vector3> uvertices = new List <Vector3>();
        List <Vector3> unormals  = new List <Vector3>();
        List <Vector2> uuvs      = new List <Vector2>();
        //MESH CONSTRUCTION
        List <string>            materialNames = new List <string>();
        List <string>            objectNames   = new List <string>();
        Dictionary <string, int> hashtable     = new Dictionary <string, int>();
        List <OBJFace>           faceList      = new List <OBJFace>();
        string cmaterial = "";
        string cmesh     = "default";

        //CACHE
        Material[] materialCache = null;
        //save this info for later
        FileInfo OBJFileInfo = new FileInfo(fn);

        string[] lines = File.ReadAllLines(fn);
        string   ln;
        string   l;

        string[] cmps;
        string   data;

        int[] indexes1;



        string felement;
        int    vertexIndex = -1;
        int    normalIndex = -1;
        int    uvIndex     = -1;

        string[] elementComps;

        for (int xl = 0; xl < lines.Length; xl++)
        //foreach (string ln in File.ReadAllLines(fn))
        {
            ln = lines[xl];
            if (ln.Length > 0 && ln[0] != '#')
            {
                l    = ln.Trim().Replace("  ", " ");
                cmps = l.Split(' ');
                data = l.Remove(0, l.IndexOf(' ') + 1);
                if (cmps[0] == "mtllib")
                {
                    //load cache
                    string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName);
                    if (pth != null)
                    {
                        materialCache = LoadMTLFile(pth);
                    }
                }
                else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false)
                {
                    cmesh = data;
                    if (!objectNames.Contains(cmesh))
                    {
                        objectNames.Add(cmesh);
                    }
                }
                else if (cmps[0] == "usemtl")
                {
                    cmaterial = data;
                    if (!materialNames.Contains(cmaterial))
                    {
                        materialNames.Add(cmaterial);
                    }

                    if (splitByMaterial)
                    {
                        if (!objectNames.Contains(cmaterial))
                        {
                            objectNames.Add(cmaterial);
                        }
                    }
                }
                else if (cmps[0] == "v")
                {
                    //VERTEX
                    vertices.Add(ParseVectorFromCMPSY(cmps, true));
                }
                else if (cmps[0] == "vn")
                {
                    //VERTEX NORMAL
                    normals.Add(ParseVectorFromCMPSY(cmps, true));
                }
                else if (cmps[0] == "vt")
                {
                    //VERTEX UV
                    uvs.Add(ParseVectorFromCMPSY2(cmps, true));
                }
                else if (cmps[0] == "f")
                {
                    indexes1 = new int[cmps.Length - 1];
                    for (int i = 1; i < cmps.Length; i++)
                    {
                        felement    = cmps[i];
                        vertexIndex = -1;
                        normalIndex = -1;
                        uvIndex     = -1;
                        if (felement.Contains("//"))
                        {
                            //doubleslash, no UVS.
                            elementComps = felement.Split('/');
                            vertexIndex  = int.Parse(elementComps[0]) - 1;
                            normalIndex  = int.Parse(elementComps[2]) - 1;
                        }
                        else if (felement.Count(x => x == '/') == 2)
                        {
                            //contains everything
                            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
                            elementComps = felement.Split('/');
                            vertexIndex  = int.Parse(elementComps[0]) - 1;
                            uvIndex      = int.Parse(elementComps[1]) - 1;
                        }
                        string hashEntry = vertexIndex + "|" + normalIndex + "|" + uvIndex;
                        if (hashtable.ContainsKey(hashEntry))
                        {
                            indexes1[i - 1] = hashtable[hashEntry];
                        }
                        else
                        {
                            //create a new hash entry
                            indexes1[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 (indexes1.Length < 5 && indexes1.Length >= 3)
                    {
                        OBJFace f1 = new OBJFace();
                        f1.materialName = cmaterial;
                        f1.indexes      = new int[] { indexes1[0], indexes1[2], indexes1[1] };//modified by kfir for right2left
                        f1.meshName     = (splitByMaterial) ? cmaterial : cmesh;
                        faceList.Add(f1);
                        if (indexes1.Length > 3)
                        {
                            OBJFace f2 = new OBJFace();
                            f2.materialName = cmaterial;
                            f2.meshName     = (splitByMaterial) ? cmaterial : cmesh;
                            f2.indexes      = new int[] { indexes1[2], indexes1[0], indexes1[3] };//modified by kfir for right2left
                            faceList.Add(f2);
                        }
                    }
                }
            }
        }
        if (objectNames.Count == 0)
        {
            objectNames.Add("default");
        }
        //build objects
        GameObject parentObject = new GameObject(meshName);

        for (int obji = 0; obji < objectNames.Count; obji++)
        //foreach (string obj in objectNames)
        {
            string     obj       = objectNames[obji];
            GameObject subObject = new GameObject(obj);
            subObject.transform.parent     = parentObject.transform;
            subObject.transform.localScale = new Vector3(1, 1, 1);
            //Debug.LogWarning("subObject : " + subObject.name);
            //Create mesh
            Mesh m = new Mesh();
            m.name = obj;
            //LISTS FOR REORDERING
            List <Vector3>        processedVertices = new List <Vector3>();
            List <Vector3>        processedNormals  = new List <Vector3>();
            List <Vector2>        processedUVs      = new List <Vector2>();
            List <int[]>          processedIndexes  = new List <int[]>();
            Dictionary <int, int> remapTable        = new Dictionary <int, int>();
            //POPULATE MESH
            List <string> meshMaterialNames = new List <string>();
            OBJFace[]     ofaces            = faceList.Where(x => x.meshName == obj).ToArray();
            foreach (string mn in materialNames)
            {
                OBJFace[] faces = ofaces.Where(x => x.materialName == mn).ToArray();
                if (faces.Length > 0)
                {
                    //int[] indexes = new int[0];
                    List <int> indexes = new List <int>();;
                    for (int face_i = 0; face_i < faces.Length; face_i++)
                    //foreach (OBJFace f in faces)
                    {
                        OBJFace f = faces[face_i];
                        indexes.AddRange(f.indexes);
                        //int l = indexes.Length;
                        //System.Array.Resize(ref indexes, l + f.indexes.Length);
                        //System.Array.Copy(f.indexes, 0, indexes, l, f.indexes.Length);
                    }
                    meshMaterialNames.Add(mn);
                    if (m.subMeshCount != meshMaterialNames.Count)
                    {
                        m.subMeshCount = meshMaterialNames.Count;
                    }

                    for (int i = 0; i < indexes.Count; i++)
                    {
                        int idx = indexes[i];
                        //build remap table
                        if (remapTable.ContainsKey(idx))
                        {
                            //ezpz
                            indexes[i] = remapTable[idx];
                        }
                        else
                        {
                            processedVertices.Add(uvertices[idx]);
                            processedNormals.Add(unormals[idx]);
                            processedUVs.Add(uuvs[idx]);
                            remapTable[idx] = processedVertices.Count - 1;
                            indexes[i]      = remapTable[idx];
                        }
                    }
                    processedIndexes.Add(indexes.ToArray());
                }
                else
                {
                }
            }
            //apply stuff
            m.vertices = processedVertices.ToArray();
            m.normals  = processedNormals.ToArray();
            m.uv       = processedUVs.ToArray();

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

            if (!hasNormals)
            {
                m.RecalculateNormals();
            }
            m.RecalculateBounds();
            MeshFilter   mf = subObject.AddComponent <MeshFilter>();
            MeshRenderer mr = subObject.AddComponent <MeshRenderer>();
            Material[]   processedMaterials = new Material[meshMaterialNames.Count];
            for (int i = 0; i < meshMaterialNames.Count; i++)
            {
                if (materialCache == null)
                {
                    processedMaterials[i] = new Material(Shader.Find("Standard"));
                }
                else
                {
                    Material mfn = Array.Find(materialCache, x => x.name == meshMaterialNames[i]);;
                    if (mfn == null)
                    {
                        processedMaterials[i] = new Material(Shader.Find("Standard"));
                    }
                    else
                    {
                        processedMaterials[i] = mfn;
                    }
                }
                processedMaterials[i].name = meshMaterialNames[i];
            }
            mr.materials = processedMaterials;
            mf.mesh      = m;
        }
        //return parentObject;
        yield return(null);
    }
Beispiel #23
0
        public static GameObject LoadOBJFile(string fn)
        {
            Debug.Log("Loading map....");
            Debug.Log(fn);
            MaterialLoader.LoadAlphaMaterial();
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fn);

            if (fileNameWithoutExtension.Contains("alpha"))
            {
                alphaIsEnabledOld = true;
            }
            else
            {
                alphaIsEnabledOld = false;
            }
            bool                     flag2      = false;
            List <Vector3>           list       = new List <Vector3>();
            List <Vector3>           list2      = new List <Vector3>();
            List <Vector2>           list3      = new List <Vector2>();
            List <Vector3>           list4      = new List <Vector3>();
            List <Vector3>           list5      = new List <Vector3>();
            List <Vector2>           list6      = new List <Vector2>();
            List <string>            list7      = new List <string>();
            List <string>            list8      = new List <string>();
            Dictionary <string, int> dictionary = new Dictionary <string, int>();
            List <OBJFace>           list9      = new List <OBJFace>();
            string                   text       = "";
            string                   text2      = "default";

            Material[] array    = null;
            FileInfo   fileInfo = new FileInfo(fn);

            string[] text3 = File.ReadAllLines(fn);

            for (int e = 0; e < text3.Length; e++)
            {
                if (text3[e].Length > 0 && text3[e][0] != '#')
                {
                    string   text4  = text3[e].Trim().Replace("  ", " ");
                    string[] array2 = text4.Split(new char[]
                    {
                        ' '
                    });
                    string text5 = text4.Remove(0, text4.IndexOf(' ') + 1);
                    switch (array2[0])
                    {
                    case "o":
                        text2 = text5;
                        if (!list8.Contains(text2))
                        {
                            list8.Add(text2);
                        }
                        break;

                    case "mtllib":
                        string text6 = Search.OBJGetFilePath(text5, fileInfo.Directory.FullName + Path.DirectorySeparatorChar.ToString(), fileNameWithoutExtension);
                        if (text6 != null)
                        {
                            array = MaterialLoader.LoadMTLFile(text6, alphaIsEnabledOld);
                        }
                        break;

                    case "usemtl":
                        text = text5;
                        if (!list7.Contains(text))
                        {
                            list7.Add(text);
                        }
                        if (splitByMaterial && !list8.Contains(text))
                        {
                            list8.Add(text);
                        }
                        break;

                    case "v":
                        list.Add(ParseVectorFromCMPS(array2));
                        break;

                    case "vn":
                        list2.Add(ParseVectorFromCMPS(array2));
                        break;

                    case "vt":
                        list3.Add(ParseVectorFromCMPS(array2));
                        break;

                    case "f":
                        int[] array3 = new int[array2.Length - 1];
                        for (int i = 1; i < array2.Length; i++)
                        {
                            string text7 = array2[i];
                            int    num   = -1;
                            int    num2  = -1;
                            int    num3;
                            if (text7.Contains("//"))
                            {
                                string[] array8 = text7.Split(new char[]
                                {
                                    '/'
                                });
                                num3 = int.Parse(array8[0]) - 1;
                                num  = int.Parse(array8[2]) - 1;
                            }
                            else if (text7.Count(new Func <char, bool>(OBJLoader.Func1)) == 2)
                            {
                                string[] array9 = text7.Split(new char[]
                                {
                                    '/'
                                });
                                num3 = int.Parse(array9[0]) - 1;
                                num2 = int.Parse(array9[1]) - 1;
                                num  = int.Parse(array9[2]) - 1;
                            }
                            else if (!text7.Contains("/"))
                            {
                                num3 = int.Parse(text7) - 1;
                            }
                            else
                            {
                                string[] array10 = text7.Split(new char[]
                                {
                                    '/'
                                });
                                num3 = int.Parse(array10[0]) - 1;
                                num2 = int.Parse(array10[1]) - 1;
                            }
                            string key = string.Concat(new object[]
                            {
                                num3,
                                "|",
                                num,
                                "|",
                                num2
                            });
                            if (dictionary.ContainsKey(key))
                            {
                                array3[i - 1] = dictionary[key];
                            }
                            else
                            {
                                array3[i - 1]   = dictionary.Count;
                                dictionary[key] = dictionary.Count;
                                list4.Add(list[num3]);
                                if (num < 0 || num > list2.Count - 1)
                                {
                                    list5.Add(Vector3.zero);
                                }
                                else
                                {
                                    flag2 = true;
                                    list5.Add(list2[num]);
                                }
                                if (num2 < 0 || num2 > list3.Count - 1)
                                {
                                    list6.Add(Vector2.zero);
                                }
                                else
                                {
                                    list6.Add(list3[num2]);
                                }
                            }
                        }
                        if (array3.Length < 5 && array3.Length >= 3)
                        {
                            List <OBJFace> list10   = list9;
                            OBJFace        objface3 = new OBJFace
                            {
                                materialName = text,
                                indexes      = new int[]
                                {
                                    array3[0],
                                    array3[1],
                                    array3[2]
                                },
                                meshName = (splitByMaterial ? text : text2)
                            };
                            OBJFace item = objface3;
                            list10.Add(item);
                            if (array3.Length > 3)
                            {
                                List <OBJFace> list11 = list9;
                                objface3 = new OBJFace
                                {
                                    materialName = text,
                                    meshName     = (splitByMaterial ? text : text2),
                                    indexes      = new int[]
                                    {
                                        array3[2],
                                        array3[3],
                                        array3[0]
                                    }
                                };
                                item = objface3;
                                list11.Add(item);
                            }
                        }
                        break;
                    }
                }
            }
            if (list8.Count == 0)
            {
                list8.Add("default");
            }
            GameObject gameObject = new GameObject("ModdedMap");

            using (List <string> .Enumerator enumerator = list8.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    string     obj         = enumerator.Current;
                    GameObject gameObject2 = new GameObject(obj);
                    gameObject2.transform.parent     = gameObject.transform;
                    gameObject2.transform.localScale = new Vector3(-1f, 1f, 1f);
                    Mesh mesh = new Mesh();
                    mesh.name = obj;
                    List <Vector3>        list12      = new List <Vector3>();
                    List <Vector3>        list13      = new List <Vector3>();
                    List <Vector2>        list14      = new List <Vector2>();
                    List <int[]>          list15      = new List <int[]>();
                    Dictionary <int, int> dictionary2 = new Dictionary <int, int>();
                    OBJLoader.meshMaterialNames = new List <string>();
                    OBJFace[] source = list9.Where(x => x.meshName == obj).ToArray <OBJFace>();
                    using (List <string> .Enumerator enumerator2 = list7.GetEnumerator())
                    {
                        while (enumerator2.MoveNext())
                        {
                            mn = enumerator2.Current;
                            OBJFace[] array4 = source.Where(x => x.materialName == mn).ToArray <OBJFace>();
                            if (array4.Length != 0)
                            {
                                int[] array5 = new int[0];
                                foreach (OBJFace objface2 in array4)
                                {
                                    int num4 = array5.Length;
                                    Array.Resize <int>(ref array5, num4 + objface2.indexes.Length);
                                    Array.Copy(objface2.indexes, 0, array5, num4, objface2.indexes.Length);
                                }
                                meshMaterialNames.Add(mn);
                                if (mesh.subMeshCount != meshMaterialNames.Count)
                                {
                                    mesh.subMeshCount = meshMaterialNames.Count;
                                }
                                for (int j = 0; j < array5.Length; j++)
                                {
                                    int num5 = array5[j];
                                    if (dictionary2.ContainsKey(num5))
                                    {
                                        array5[j] = dictionary2[num5];
                                    }
                                    else
                                    {
                                        list12.Add(list4[num5]);
                                        list13.Add(list5[num5]);
                                        list14.Add(list6[num5]);
                                        dictionary2[num5] = list12.Count - 1;
                                        array5[j]         = dictionary2[num5];
                                    }
                                }
                                list15.Add(array5);
                            }
                        }
                    }
                    mesh.SetVertices(list12);
                    mesh.SetNormals(list13);
                    mesh.SetUVs(0, list14);
                    for (int k = 0; k < list15.Count; k++)
                    {
                        mesh.SetIndices(list15[k], MeshTopology.Triangles, k);
                    }
                    if (!flag2)
                    {
                        mesh.RecalculateNormals();
                    }
                    mesh.RecalculateBounds();
                    Material[] array6 = new Material[meshMaterialNames.Count];
                    counter = 0;
                    while (counter < meshMaterialNames.Count)
                    {
                        if (array == null)
                        {
                            Debug.Log("array null");
                            array6[counter] = new Material(Shader.Find("HDRP/Lit"));
                        }
                        else
                        {
                            Material[]           array12 = array;
                            Predicate <Material> match;
                            if ((match = haha3) == null)
                            {
                                match = haha3 = new Predicate <Material>(LoadOBJFile3);
                            }
                            Material material = Array.Find(array12, match);
                            Debug.Log(material);
                            if (material == null)
                            {
                                Debug.Log("material null");
                                array6[counter] = new Material(Shader.Find("HDRP/Lit"));
                            }
                            else
                            {
                                array6[counter] = material;
                            }
                        }
                        array6[counter].name = meshMaterialNames[counter];
                        int i2 = counter;
                        counter = i2 + 1;
                    }
                    meshFilter   = gameObject2.AddComponent <MeshFilter>();
                    meshRenderer = gameObject2.AddComponent <MeshRenderer>();
                    meshRenderer.receiveShadows = true;
                    meshFilter.mesh             = mesh;
                    meshRenderer.materials      = array6;
                    if (MaterialLoader.alphaIsEnabled || alphaIsEnabledOld)
                    {
                        Renderer[] newRenderer = new Renderer[1];
                        newRenderer[0] = meshRenderer;
                        LODGroup lods = gameObject2.AddComponent <LODGroup>();
                        LOD[]    lod  = new LOD[1];
                        lod[0].renderers = newRenderer;
                        lod[0].screenRelativeTransitionHeight = 0.8f;
                        lods.SetLODs(lod);
                        lods.RecalculateBounds();
                    }
                    if (!alphaIsEnabledOld)
                    {
                        meshCollider            = gameObject2.AddComponent <MeshCollider>();
                        meshCollider.convex     = false;
                        meshCollider.sharedMesh = mesh;
                        CarX.Material carXMaterial = gameObject2.AddComponent <CarX.Material>();
                        string        objectParams = gameObject2.name.Split('_')[0].ToLower();
                        switch (objectParams)
                        {
                        case "road":
                            Debug.Log("road set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 1, 0.01f, 0f, 0f, 100f, 0f, 0f, 100f);
                            gameObject2.isStatic = true;
                            break;

                        case "kerb":
                            Debug.Log("kerb set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 1, 0.015f, -0.007f, 0f, 12f, -0.007f, 0f, 12f);
                            gameObject2.isStatic = true;
                            break;

                        case "sand":
                            Debug.Log("sand set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Sand, 1, 0.13f, 0.06f, 0.05f, 25f, 0.06f, 0.05f, 25f);
                            gameObject2.isStatic = true;
                            break;

                        case "snow":
                            Debug.Log("snow set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Snow, 2, 0.1f, -0.01f, -0.01f, 30f, -0.01f, -0.01f, 30f);
                            gameObject2.isStatic = true;
                            break;

                        case "grass":
                            Debug.Log("grass set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Grass, 1, 0f, 0.05f, 0.04f, 25f, 0.05f, 0.04f, 25f);
                            gameObject2.isStatic = true;
                            break;

                        case "gravel":
                            Debug.Log("gravel set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Sand, 2, 0.1f, -0.01f, -0.01f, 30f, -0.01f, -0.01f, 30f);
                            gameObject2.isStatic = true;
                            break;

                        case "icyroad":
                            Debug.Log("icyroad set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 0.73f, 0.025f, 0f, 0f, 30f, 0f, 0f, 30f);
                            gameObject2.isStatic = true;
                            break;

                        case "dirt":
                            Debug.Log("dirt set");
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Earth, 1, 0.025f, -0.007f, 0f, 12f, -0.007f, 0f, 12f);
                            gameObject2.isStatic = true;
                            break;

                        case "nocol":
                            Debug.Log("nocol set");
                            meshCollider.enabled = false;
                            gameObject2.isStatic = true;
                            break;

                        case "rb":
                            Debug.Log("rb set");
                            gameObject2.transform.SetParent(null);
                            meshCollider.convex = true;
                            Rigidbody rb = gameObject2.AddComponent <Rigidbody>();
                            rbGos.Add(gameObject2);
                            gameObject2.isStatic = false;
                            break;

                        default:
                            gameObject2.AddComponent <CARXSurface>();
                            carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 1, 0.01f, 0f, 0f, 100f, 0f, 0f, 100f);
                            gameObject2.isStatic = true;
                            Debug.Log("Surface not set for this object");
                            break;
                        }
                    }
                    gameObject2.layer = 11;
                }
            }
            return(gameObject);
        }