Exemplo n.º 1
0
        private (Vertex v, Normal n, UVCoordinate u) ParseVertex(string value, List <Vertex> vertices, List <Normal> normals, List <UVCoordinate> uvCoords,
                                                                 List <int> usedVertexIDs, List <int> usedNormalIDs)
        {
            string[] vertexData = value.Split('/');
            int      vertexID   = int.Parse(vertexData[0]) - 1;
            Vertex   vertex     = vertices[vertexID];

            usedVertexIDs.Add(vertexID);
            UVCoordinate uvCoord = null;

            if (vertexData.Length > 1 && vertexData[1] != "")
            {
                uvCoord = uvCoords[int.Parse(vertexData[1]) - 1];
            }
            Normal normal = null;

            if (vertexData.Length > 2 && vertexData[2] != "")
            {
                int normalID = int.Parse(vertexData[2]) - 1;
                normal = normals[normalID];
                usedNormalIDs.Add(normalID);
            }
            return(vertex, normal, uvCoord);
        }
Exemplo n.º 2
0
        public void ReadFromOBJ(TextReader reader, Stream unknownData)
        {
            if (unknownData != null)
            {
                Unknown1 = unknownData.ReadUShort();
                Unknown2 = unknownData.ReadUShort();
                Unknown3 = unknownData.ReadUShort();
                Unknown4 = unknownData.ReadUShort();
                unknownData.Read(Unknown5);
            }

            var    lods           = new LOD[3];
            var    wheelPositions = new WheelPosition[4];
            string line;
            int    currentWheelPosition       = -1;
            short  currentWheelPositionWValue = 0;
            int    currentLODNumber           = -1;
            bool   shadow                 = false;
            string currentMaterial        = "untextured";
            Vertex wheelPositionCandidate = null;
            LOD    currentLOD             = null;
            var    vertices               = new List <Vertex>();
            var    normals                = new List <Normal>();
            var    uvCoords               = new List <UVCoordinate>();
            var    usedVertexIDs          = new List <int>();
            var    usedNormalIDs          = new List <int>();
            int    shadowVertexStartID    = 0;
            double currentScale           = 1;

            do
            {
                line = reader.ReadLine();
                if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#"))
                {
                    continue;
                }

                try
                {
                    if (line.StartsWith("o ") || line.StartsWith("g "))
                    {
                        string[] objectNameParts = line.Split(' ')[1].Split('/');
                        if (objectNameParts[0].StartsWith("wheelpos"))
                        {
                            currentWheelPosition = int.Parse(objectNameParts[0].Replace("wheelpos", ""));
                            foreach (string namePart in objectNameParts)
                            {
                                string[] keyAndValue = namePart.Split('=');
                                if (keyAndValue.Length == 2 && keyAndValue[0] == "w")
                                {
                                    currentWheelPositionWValue = short.Parse(keyAndValue[1]);
                                }
                            }
                        }
                        else if (objectNameParts[0].StartsWith("lod"))
                        {
                            if (wheelPositions.Any(position => position == null))
                            {
                                //throw new Exception("Expected four wheel position objects before any LOD objects."); // TODO: is this safe to remove?
                            }
                            if (currentLOD != null)
                            {
                                currentLOD.Vertices = usedVertexIDs.OrderBy(id => id).Distinct().Select(id => vertices[id]).ToList();
                                usedVertexIDs       = new List <int>();
                                currentLOD.Normals  = usedNormalIDs.OrderBy(id => id).Distinct().Select(id => normals[id]).ToList();
                                usedNormalIDs       = new List <int>();
                                currentLOD.GenerateBoundingBox();
                            }
                            currentLODNumber = int.Parse(objectNameParts[0].Replace("lod", ""));
                            currentLOD       = new LOD();
                            currentLOD.PrepareForOBJRead(unknownData);
                            lods[currentLODNumber] = currentLOD;
                            currentScale           = GetScale(objectNameParts);
                            currentLOD.Scale       = LOD.ConvertScale(currentScale);
                        }
                        else if (objectNameParts[0].StartsWith("shadow"))
                        {
                            if (lods.Any(lod => lod == null))
                            {
                                throw new Exception("Expected three LOD objects before shadow object.");
                            }
                            currentLOD.Vertices = usedVertexIDs.OrderBy(id => id).Distinct().Select(id => vertices[id]).ToList();
                            currentLOD.Normals  = usedNormalIDs.OrderBy(id => id).Distinct().Select(id => normals[id]).ToList();
                            currentLOD.GenerateBoundingBox();
                            shadow = true;
                            Shadow = new Shadow();
                            Shadow.PrepareForOBJRead(unknownData);
                            shadowVertexStartID = vertices.Count;
                            currentScale        = GetScale(objectNameParts);
                            Shadow.Scale        = LOD.ConvertScale(currentScale);
                        }
                    }
                    else if (line.StartsWith("v "))
                    {
                        if (shadow)
                        {
                            var vertex = new ShadowVertex();
                            vertex.ReadFromOBJ(line, currentScale);
                            Shadow.Vertices.Add(vertex);
                        }
                        else
                        {
                            var vertex = new Vertex();
                            vertex.ReadFromOBJ(line, currentScale);
                            vertices.Add(vertex);
                            if (currentLODNumber == -1)
                            {
                                wheelPositionCandidate = vertex;
                            }
                        }
                    }
                    else if (line.StartsWith("vt "))
                    {
                        var uvCoord = new UVCoordinate();
                        uvCoord.ReadFromOBJ(line);
                        uvCoords.Add(uvCoord);
                    }
                    else if (line.StartsWith("vn "))
                    {
                        var normal = new Normal();
                        normal.ReadFromOBJ(line);
                        normals.Add(normal);
                    }
                    else if (line.StartsWith("usemtl "))
                    {
                        currentMaterial = line.Split(' ')[1];
                    }
                    else if (line.StartsWith("f "))
                    {
                        if (shadow)
                        {
                            var polygon = new ShadowPolygon();
                            polygon.ReadFromOBJ(line, Shadow.Vertices, shadowVertexStartID, currentMaterial);
                            if (polygon.IsQuad)
                            {
                                Shadow.Quads.Add(polygon);
                            }
                            else
                            {
                                Shadow.Triangles.Add(polygon);
                            }
                        }
                        else if (currentLODNumber == -1)
                        {
                            continue;
                            //throw new Exception("Face found outside of a LOD or shadow.");
                        }
                        else if (currentMaterial.StartsWith("untextured"))
                        {
                            var polygon = new Polygon();
                            polygon.ReadFromOBJ(line, vertices, normals, currentMaterial, usedVertexIDs, usedNormalIDs);
                            if (polygon.IsQuad)
                            {
                                currentLOD.Quads.Add(polygon);
                            }
                            else
                            {
                                currentLOD.Triangles.Add(polygon);
                            }
                        }
                        else
                        {
                            var polygon = new UVPolygon();
                            polygon.ReadFromOBJ(line, vertices, normals, uvCoords, currentMaterial, usedVertexIDs, usedNormalIDs);
                            if (polygon.IsQuad)
                            {
                                currentLOD.UVQuads.Add(polygon);
                            }
                            else
                            {
                                currentLOD.UVTriangles.Add(polygon);
                            }
                        }
                    }

                    if (currentWheelPosition != -1 && wheelPositionCandidate != null)
                    {
                        var position = new WheelPosition();
                        position.ReadFromOBJ(wheelPositionCandidate, currentWheelPositionWValue);
                        wheelPositions[currentWheelPosition] = position;
                        wheelPositionCandidate = null;
                        currentWheelPosition   = -1;
                    }
                }
                catch (Exception exception)
                {
                    throw new Exception($"Line:{line}\r\n{exception.Message}", exception);
                }
            }while (line != null);

            Shadow.GenerateBoundingBox();
            LODs           = lods.ToList();
            WheelPositions = wheelPositions.ToList();
        }
Exemplo n.º 3
0
 private string WriteVertexToOBJ(Vertex vertex, Normal normal, List <Vertex> vertices, List <Normal> normals, int firstVertexNumber,
                                 int firstNormalNumber, UVCoordinate coord, List <UVCoordinate> coords, int firstCoordNumber) =>
 $"{vertices.IndexOf(vertex) + firstVertexNumber}/{coords.IndexOf(coord) + firstCoordNumber}/{normals.IndexOf(normal) + firstNormalNumber}";