private void LoadMeshFromObj(string filename)
        {
            // Force garbage collection to ensure that unmanaged resources are released.
            // Temporary workaround until unmanaged resource leak is identified
            GC.Collect();

            bool objectFound = false;
            //Dictionary<string, ObjectNode> objectTable = new Dictionary<string, ObjectNode>();
            List<ObjectNode> objects = new List<ObjectNode>();
            ObjectNode currentObject = new ObjectNode();
            currentObject.Name = "Default";

            int triangleCount = 0;
            int vertexCount = 0;

             //           List<Mesh.Group> matGroups = new List<Mesh.Group>();

            List<PositionNormalTextured> vertexList = new List<PositionNormalTextured>();
            List<Vector3> vertList = new List<Vector3>();
            List<Vector3> normList = new List<Vector3>();
            List<Vector2> uvList = new List<Vector2>();

            vertList.Add(new Vector3());
            normList.Add(new Vector3());
            uvList.Add(new Vector2());

            List<int> indexList = new List<int>();
            List<int> attribList = new List<int>();
            List<int[]> applyLists = new List<int[]>();
            List<int> applyListsIndex = new List<int>();
            List<string> materialNames = new List<string>();
            int currentMaterialIndex = -1;
            Material currentMaterial = new Material();
            Mesh.Group currentGroup = new Mesh.Group();

            int currentIndex = 0;

            //initialize the default material

            currentMaterial = new Material();
            currentMaterial.Diffuse = Color;
            currentMaterial.Ambient = Color;
            currentMaterial.Specular = System.Drawing.Color.White;
            currentMaterial.SpecularSharpness = 30.0f;
            currentMaterial.Opacity = 1.0f;
            currentMaterial.Default = true;

            //initialize the group
            currentGroup.startIndex = 0;
            currentGroup.indexCount = 0;
            currentGroup.materialIndex = 0;

            using (Stream fs = new FileStream(filename, FileMode.Open,FileAccess.Read))
            {
                StreamReader sr = new StreamReader(fs);

                while (!sr.EndOfStream)
                {
                    string line = sr.ReadLine().Replace("  ", " ");

                    string[] parts = line.Trim().Split(new char[] { ' ' });

                    if (parts.Length > 0)
                    {
                        switch (parts[0])
                        {
                            case "mtllib":
                                {
                                    string path = filename.Substring(0, filename.LastIndexOf('\\') + 1);
                                    string matFile = path + "\\" + parts[1];
                                    LoadMatLib(matFile);
                                }
                                break;
                            case "usemtl":
                                string materialName = parts[1];
                                if (matLib.ContainsKey(materialName))
                                {
                                    if (currentMaterialIndex == -1 && currentIndex > 0)
                                    {
                                        addMaterial(currentMaterial);
                                        currentMaterialIndex++;
                                    }

                                    if (currentMaterialIndex > -1)
                                    {
                                        currentGroup.indexCount = currentIndex - currentGroup.startIndex;
                                  //      matGroups.Add(currentGroup);
                                        currentObject.DrawGroup.Add(currentGroup);
                                    }

                                    currentMaterialIndex++;

                                    if (matLib.ContainsKey(materialName))
                                    {
                                        currentMaterial = matLib[materialName];

                                        if (textureLib.ContainsKey(materialName))
                                        {
                                            try
                                            {
                                                if (!TextureCache.ContainsKey(textureLib[materialName]))
                                                {
                                                    string path = filename.Substring(0, filename.LastIndexOf('\\') + 1);

                                                    Texture11 tex = LoadTexture(path + textureLib[materialName]);
                                                    if (tex != null)
                                                    {
                                                        meshFilenames.Add(textureLib[materialName]);
                                                        TextureCache.Add(textureLib[materialName], tex);
                                                    }
                                                }
                                                meshTextures.Add(TextureCache[textureLib[materialName]]);
                                            }
                                            catch
                                            {
                                            }
                                        }

                                        addMaterial(currentMaterial);

                                        currentGroup = new Mesh.Group();
                                        currentGroup.startIndex = currentIndex;
                                        currentGroup.indexCount = 0;
                                        currentGroup.materialIndex = currentMaterialIndex;
                                    }
                                }

                                break;
                            case "v":
                                vertexCount++;
                                if (FlipHandedness)
                                {
                                    vertList.Add(new Vector3(-float.Parse(parts[1]), float.Parse(parts[2]), float.Parse(parts[3])));
                                }
                                else
                                {
                                    vertList.Add(new Vector3(float.Parse(parts[1]), float.Parse(parts[2]), float.Parse(parts[3])));
                                }
                                break;
                            case "vn":
                                if (FlipHandedness)
                                {
                                    normList.Add(new Vector3(-float.Parse(parts[1]), float.Parse(parts[2]), float.Parse(parts[3])));
                                }
                                else
                                {
                                    normList.Add(new Vector3(float.Parse(parts[1]), float.Parse(parts[2]), float.Parse(parts[3])));
                                }
                                break;
                            case "vt":
                                uvList.Add(new Vector2(float.Parse(parts[1]), FlipV ? (1 - float.Parse(parts[2])) : float.Parse(parts[2])));
                                break;
                            case "g":
                            case "o":
                                if (objectFound)
                                {
                                    if (currentMaterialIndex > -1)
                                    {
                                        currentGroup.indexCount = currentIndex - currentGroup.startIndex;
                       //                 matGroups.Add(currentGroup);
                                        currentObject.DrawGroup.Add(currentGroup);
                                        currentGroup = new Mesh.Group();
                                        currentGroup.startIndex = currentIndex;
                                        currentGroup.indexCount = 0;
                                        currentGroup.materialIndex = currentMaterialIndex;
                                    }
                                    currentObject = new ObjectNode();
                                }

                                objectFound = true;
                                if (parts.Length > 1)
                                {
                                    currentObject.Name = parts[1];
                                }
                                else
                                {
                                    currentObject.Name = "Unnamed";
                                }
                                objects.Add(currentObject);
                                //if (!objectTable.ContainsKey(currentObject.Name))
                                //{
                                //    objectTable.Add(currentObject.Name, currentObject);
                                //}
                                break;
                            case "f":
                                int[] indexiesA = GetIndexies(parts[1]);
                                int[] indexiesB = GetIndexies(parts[2]);
                                int[] indexiesC = GetIndexies(parts[3]);

                                vertexList.Add(new PositionNormalTextured(vertList[indexiesA[0]], normList[indexiesA[2]], uvList[indexiesA[1]]));
                                vertexList.Add(new PositionNormalTextured(vertList[indexiesB[0]], normList[indexiesB[2]], uvList[indexiesB[1]]));
                                vertexList.Add(new PositionNormalTextured(vertList[indexiesC[0]], normList[indexiesC[2]], uvList[indexiesC[1]]));

                                if (FlipHandedness)
                                {
                                    indexList.Add(currentIndex);
                                    indexList.Add(currentIndex + 2);
                                    indexList.Add(currentIndex + 1);
                                }
                                else
                                {
                                    indexList.Add(currentIndex);
                                    indexList.Add(currentIndex + 1);
                                    indexList.Add(currentIndex + 2);

                                }

                                triangleCount++;
                                currentIndex += 3;
                                //bool flip = true;
                                if (parts.Length > 4)
                                {
                                    int partIndex = 4;

                                    while (partIndex < (parts.Length))
                                    {
                                        if (FlipHandedness)
                                        {
                                            indexiesA = GetIndexies(parts[1]);
                                            indexiesC = GetIndexies(parts[partIndex]);
                                            indexiesB = GetIndexies(parts[partIndex - 1]);
                                        }
                                        else
                                        {
                                            indexiesA = GetIndexies(parts[1]);
                                            indexiesB = GetIndexies(parts[partIndex - 1]);
                                            indexiesC = GetIndexies(parts[partIndex]);
                                        }
                                        vertexList.Add(new PositionNormalTextured(vertList[indexiesA[0]], normList[indexiesA[2]], uvList[indexiesA[1]]));
                                        vertexList.Add(new PositionNormalTextured(vertList[indexiesB[0]], normList[indexiesB[2]], uvList[indexiesB[1]]));
                                        vertexList.Add(new PositionNormalTextured(vertList[indexiesC[0]], normList[indexiesC[2]], uvList[indexiesC[1]]));

                                        indexList.Add(currentIndex);
                                        indexList.Add(currentIndex + 1);
                                        indexList.Add(currentIndex + 2);
                                        triangleCount++;

                                        currentIndex += 3;
                                        partIndex++;
                                    }
                                }
                                break;
                        }
                    }
                }
            }

            if (!objectFound)
            {
                // add the default object
                objects.Add(currentObject);
            }

            if (currentMaterialIndex == -1 && currentIndex > 0)
            {
                addMaterial(currentMaterial);
                currentMaterialIndex++;
            }

            if (currentMaterialIndex > -1)
            {
                currentGroup.indexCount = currentIndex - currentGroup.startIndex;
                currentObject.DrawGroup.Add(currentGroup);
            }

            if (normList.Count < 2)
            {

                float creaseAngleRad = MathUtil.DegreesToRadians(Smooth ? 170.0f : 45.0f);

                Vector3[] vertexNormals = CalculateVertexNormalsMerged(vertexList, indexList, creaseAngleRad);
                List<PositionNormalTextured> newVertexList = new List<PositionNormalTextured>();
                int newVertexCount = indexList.Count;

                for (int vertexIndex = 0; vertexIndex < newVertexCount; ++vertexIndex)
                {
                    PositionNormalTextured v = vertexList[indexList[vertexIndex]];
                    v.Normal = vertexNormals[vertexIndex];
                    newVertexList.Add(v);
                }

                vertexList = newVertexList;
            }

            mesh = new Mesh(vertexList.ToArray(), indexList.ToArray());
            ObjectNode rootDummy = new ObjectNode();
            rootDummy.Name = "Root";
            rootDummy.Parent = null;
            rootDummy.Level = -1;
            rootDummy.DrawGroup = null;
            rootDummy.Children = objects;

            Objects = new List<ObjectNode>();
            Objects.Add(rootDummy);

            mesh.setObjects(Objects);

            //List<ObjectNode> objects = new List<ObjectNode>();

            //ObjectNode node = new ObjectNode();
            //node.Name = "Default";
            //node.DrawGroup = matGroups;
            //objects.Add(node);
            //mesh.setObjects(objects);
            //Objects = objects;

            mesh.commitToDevice(RenderContext11.PrepDevice);

            dirty = false;

            GC.Collect();
        }