示例#1
0
文件: Model.cs 项目: pez2k/gt2tools
        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();
        }
示例#2
0
        public void ReadFromCAR(Stream stream)
        {
            ushort vertexCount   = stream.ReadUShort(); // at 0x80
            ushort normalCount   = stream.ReadUShort();
            ushort triangleCount = stream.ReadUShort();
            ushort quadCount     = stream.ReadUShort();

            stream.Position += sizeof(ushort) * 2;
            ushort uvTriangleCount = stream.ReadUShort();
            ushort uvQuadCount     = stream.ReadUShort();

            stream.Position += sizeof(ushort) * 10; // at 0x90
            Scale            = stream.ReadUShort();
            stream.Position += 2;

            Vertices    = new List <Vertex>(vertexCount); // at 0xA8
            Normals     = new List <Normal>(normalCount);
            Triangles   = new List <Polygon>(triangleCount);
            Quads       = new List <Polygon>(quadCount);
            UVTriangles = new List <UVPolygon>(uvTriangleCount);
            UVQuads     = new List <UVPolygon>(uvQuadCount);

            for (int i = 0; i < vertexCount; i++)
            {
                var vertex = new Vertex();
                vertex.ReadFromCAR(stream);
                Vertices.Add(vertex);
            }

            for (int i = 0; i < normalCount; i++)
            {
                var normal = new Normal();
                normal.ReadFromCAR(stream);
                Normals.Add(normal);
            }

            for (int i = 0; i < triangleCount; i++)
            {
                var triangle = new Polygon();
                triangle.ReadFromCAR(stream, false, Vertices, Normals);
                Triangles.Add(triangle);
            }

            for (int i = 0; i < quadCount; i++)
            {
                var quad = new Polygon();
                quad.ReadFromCAR(stream, true, Vertices, Normals);
                Quads.Add(quad);
            }

            for (int i = 0; i < uvTriangleCount; i++)
            {
                var uvTriangle = new UVPolygon();
                uvTriangle.ReadFromCAR(stream, false, Vertices, Normals);
                UVTriangles.Add(uvTriangle);
            }

            for (int i = 0; i < uvQuadCount; i++)
            {
                var uvQuad = new UVPolygon();
                uvQuad.ReadFromCAR(stream, true, Vertices, Normals);
                UVQuads.Add(uvQuad);
            }

            // calculate model bounds - can't spot this sort of data in CAR
            GenerateBoundingBox();
        }
示例#3
0
        public void ReadFromCDO(Stream stream)
        {
            ushort vertexCount   = stream.ReadUShort();
            ushort normalCount   = stream.ReadUShort();
            ushort triangleCount = stream.ReadUShort();
            ushort quadCount     = stream.ReadUShort();

            stream.Position += sizeof(ushort) * 2;
            ushort uvTriangleCount = stream.ReadUShort();
            ushort uvQuadCount     = stream.ReadUShort();

            stream.Read(unknown);
            lowBoundX  = stream.ReadShort(); // at 8C0
            lowBoundY  = stream.ReadShort();
            lowBoundZ  = stream.ReadShort();
            lowBoundW  = stream.ReadShort();
            highBoundX = stream.ReadShort();
            highBoundY = stream.ReadShort();
            highBoundZ = stream.ReadShort();
            highBoundW = stream.ReadShort();
            Scale      = stream.ReadUShort(); // at 8D0
            unknown2   = stream.ReadSingleByte();
            unknown3   = stream.ReadSingleByte();

            Vertices    = new List <Vertex>(vertexCount);
            Normals     = new List <Normal>(normalCount);
            Triangles   = new List <Polygon>(triangleCount);
            Quads       = new List <Polygon>(quadCount);
            UVTriangles = new List <UVPolygon>(uvTriangleCount);
            UVQuads     = new List <UVPolygon>(uvQuadCount);

            for (int i = 0; i < vertexCount; i++)
            {
                var vertex = new Vertex();
                vertex.ReadFromCDO(stream);
                Vertices.Add(vertex);
            }

            for (int i = 0; i < normalCount; i++)
            {
                var normal = new Normal();
                normal.ReadFromCDO(stream);
                Normals.Add(normal);
            }

            for (int i = 0; i < triangleCount; i++)
            {
                var triangle = new Polygon();
                triangle.ReadFromCDO(stream, false, Vertices, Normals);
                Triangles.Add(triangle);
            }

            for (int i = 0; i < quadCount; i++)
            {
                var quad = new Polygon();
                quad.ReadFromCDO(stream, true, Vertices, Normals);
                Quads.Add(quad);
            }

            for (int i = 0; i < uvTriangleCount; i++)
            {
                var uvTriangle = new UVPolygon();
                uvTriangle.ReadFromCDO(stream, false, Vertices, Normals);
                UVTriangles.Add(uvTriangle);
            }

            for (int i = 0; i < uvQuadCount; i++)
            {
                var uvQuad = new UVPolygon();
                uvQuad.ReadFromCDO(stream, true, Vertices, Normals);
                UVQuads.Add(uvQuad);
            }
        }
示例#4
0
        public void ReadFromCAR(Stream stream)
        {
            ushort vertexCount   = stream.ReadUShort();
            ushort normalCount   = stream.ReadUShort();
            ushort triangleCount = stream.ReadUShort();
            ushort quadCount     = stream.ReadUShort();

            stream.Position += sizeof(ushort) * 2;
            ushort uvTriangleCount = stream.ReadUShort();
            ushort uvQuadCount     = stream.ReadUShort();

            stream.Position += sizeof(ushort) * 12;

            Vertices    = new List <Vertex>(vertexCount);
            Normals     = new List <Normal>(normalCount);
            Triangles   = new List <Polygon>(triangleCount);
            Quads       = new List <Polygon>(quadCount);
            UVTriangles = new List <UVPolygon>(uvTriangleCount);
            UVQuads     = new List <UVPolygon>(uvQuadCount);

            for (int i = 0; i < vertexCount; i++)
            {
                var vertex = new Vertex();
                vertex.ReadFromCAR(stream);
                Vertices.Add(vertex);
            }

            for (int i = 0; i < normalCount; i++)
            {
                var normal = new Normal();
                normal.ReadFromCAR(stream);
                Normals.Add(normal);
            }

            for (int i = 0; i < triangleCount; i++)
            {
                var triangle = new Polygon();
                triangle.ReadFromCAR(stream, false, Vertices, Normals);
                Triangles.Add(triangle);
            }

            for (int i = 0; i < quadCount; i++)
            {
                var quad = new Polygon();
                quad.ReadFromCAR(stream, true, Vertices, Normals);
                Quads.Add(quad);
            }

            for (int i = 0; i < uvTriangleCount; i++)
            {
                var uvTriangle = new UVPolygon();
                uvTriangle.ReadFromCAR(stream, false, Vertices, Normals);
                UVTriangles.Add(uvTriangle);
            }

            for (int i = 0; i < uvQuadCount; i++)
            {
                var uvQuad = new UVPolygon();
                uvQuad.ReadFromCAR(stream, true, Vertices, Normals);
                UVQuads.Add(uvQuad);
            }
        }