Ejemplo n.º 1
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);
            }
        }
Ejemplo n.º 2
0
        public virtual void ReadFromCDO(Stream stream, bool isQuad, List <Vertex> vertices, List <Normal> normals)
        {
            byte vertex0Ref = stream.ReadSingleByte();

            Vertex0 = vertices[vertex0Ref];
            byte vertex1Ref = stream.ReadSingleByte();

            Vertex1 = vertices[vertex1Ref];
            byte vertex2Ref = stream.ReadSingleByte();

            Vertex2 = vertices[vertex2Ref];
            byte vertex3Ref = stream.ReadSingleByte();

            if (isQuad)
            {
                Vertex3 = vertices[vertex3Ref];
            }
            else if (vertex3Ref != 0x00)
            {
                throw new Exception("Vertex 3 in Triangle not zero");
            }

            ushort renderOrderAndFirstNormalData = stream.ReadUShort();
            ushort renderFlagsData = stream.ReadUShort();
            int    normalsData     = stream.ReadInt();
            int    faceTypeData    = stream.ReadInt();

            RenderOrder = renderOrderAndFirstNormalData & 0x1F;
            if (RenderOrder == 0b1000)
            {
                Debug.WriteLine($"Render order of 0b1000 found at {stream.Position}");
            }

            if (normals.Any())
            {
                int normal0Ref = (renderOrderAndFirstNormalData >> 5) & 0x1FF;
                Vertex0Normal = normals[normal0Ref];
            }

            RenderFlags = renderFlagsData >> 12;
            if (RenderFlags != 0b1100 && RenderFlags != 0b1000 && RenderFlags != 0)
            {
                Debug.WriteLine($"Render flags of {RenderFlags} found at {stream.Position}");
            }

            if (normals.Any())
            {
                int normal1Ref = (normalsData >> 1) & 0x1FF;
                Vertex1Normal = normals[normal1Ref];
                int normal2Ref = (normalsData >> 10) & 0x1FF;
                Vertex2Normal = normals[normal2Ref];
                int normal3Ref = (normalsData >> 19) & 0x1FF;
                Vertex3Normal = normals[normal3Ref];
            }

            FaceType = faceTypeData >> 24;
            // 100000 (32) for untextured tri
            // 100101 (37) for textured tri
            // 101000 (40) for untextured quad
            // 101101 (45) for textured quad
            if (FaceType != 32 && FaceType != 37 && FaceType != 40 && FaceType != 45)
            {
                throw new Exception($"Unrecognised face type {FaceType}");
            }
        }
Ejemplo n.º 3
0
        public virtual void ReadFromCAR(Stream stream, bool isQuad, List <Vertex> vertices, List <Normal> normals)
        {
            byte vertexByte0 = stream.ReadSingleByte();
            byte vertexByte1 = stream.ReadSingleByte();
            byte vertexByte2 = stream.ReadSingleByte();
            byte vertexByte3 = stream.ReadSingleByte();
            byte vertexByte4 = stream.ReadSingleByte();
            byte vertexByte5 = stream.ReadSingleByte();

            // example bytes:
            //  0  1  2  3  4  5
            // 1E 3A 68 88 00 00 -> 30 29 26 0
            // 52 2E 60 88 00 00
            // 16 32 60 88 17 00
            // 1A 3A 70 80 1B 00
            // 22 AC 64 88 16 00
            // 41 DA BC 89 43 00

            /*
             *
             * 1E - 0001 1110
             * 3A - 0011 1010
             * 68 - 0110 1000
             * 88 - 1000 1000
             *
             * 0001 1110 0011 1010 0110 1000 1000 1000 0000 0000 0000 0000
             *
             * 0001 1110
             * 0001 1101
             * 0001 1010
             *
             * 0001 1110   - 30
             * (0)001 1101 - 29
             * (0)001 1010 - 26
             * (0)001 0001 - 17 dec??
             * (0)000 0000 - 0
             * 0000 0000 0000
             *
             * V      V      V      V
             * 0001111000111010011010001000100000000000 0000 0000
             *
             * 49 - 0100 1001
             * DA - 1101 1010
             * BC - 1011 1100
             * 89 - 1000 1001
             * 43 - 0100 0011
             *
             * 0100 1001 1101 1010 1011 1100 1000 1001 0100 0011 0000 0000
             *
             * 0 1001001 1101101 0101111 0010001 0010100 0011000 00000
             *
             * 0100 1001 - 73
             * 0110 1101 - 109
             * 0010 1111 - 47
             * 0001 0001 - 17 again
             * 0001 0100 - 20
             * 0001 1000 - 24
             *
             */

            int vertex0Ref = ((vertexByte1 & 1) * 256) + vertexByte0;

            Vertex0 = vertices[vertex0Ref];
            int vertex1Ref = ((vertexByte2 & 2) * 128) + ((vertexByte2 & 1) * 128) + (vertexByte1 >> 1);

            Vertex1 = vertices[vertex1Ref];
            int vertex2Ref = ((vertexByte3 & 4) * 64) + ((vertexByte3 & 2) * 64) + ((vertexByte3 & 1) * 64) + (vertexByte2 >> 2);

            Vertex2 = vertices[vertex2Ref];
            int vertex3Ref = ((vertexByte5 & 1) * 256) + vertexByte4;

            if (isQuad)
            {
                Vertex3 = vertices[vertex3Ref];
            }

            /*else if (vertex3Ref != 0x00)
             * {
             *  throw new System.Exception("Vertex 3 in Triangle not zero");
             * }*/

            byte normalsByte1 = stream.ReadSingleByte(); // many values - bottom bit tex only, top 5 tex only
            byte normalsByte2 = stream.ReadSingleByte(); // 0, 1, 2, 3, 4, 5, 6, 128, 133 - top bit set on both unt and tex, not on tex quads but two tex tris
            // bottom 3 bits set on tex only
            // 0000 0000 - 0
            // 0000 0001 - 1
            // 0000 0010 - 2
            // 0000 0011 - 3
            // 0000 0100 - 4
            // 0000 0101 - 5
            // 0000 0110 - 6
            // 1000 0000 - 128 + 0 - bottom bit of next normal index?
            // 1000 0101 - 128 + 5
            byte normalsByte3 = stream.ReadSingleByte(); // many values - very top bit set for any sort of tex poly, so normal 2 at most - all bits set at least once
            // all bits set for tex only

            byte normalsByte4 = stream.ReadSingleByte(); // many values - all 8 bits are only set for tex quads, so part of normal 3? - bit 2 never set?
            byte normalsByte5 = stream.ReadSingleByte(); // 0, 1, 2, 3 - top bit of final normal index? - only set for tex quads, so top of normal 3
            byte normalsByte6 = stream.ReadSingleByte(); // always 0

            //         8         7         6         5         4         3       vb5
            // 0000 0000 0000 0xxx xxxx xx0x xxxx xxxx x000 xxxx xxxx x0xx ---- ---v
            //                 ttt tttt tt t tttt tttt a    tttt tttt t tt tttt ttt
            //                 qqq qqqq qq q
            //                 333 3333 33 2 2222 2222 ?    1111 1111 1 00 0000 000v

            /*if ((vertexByte5 & 0b0000_0001) != 0)
             * {
             *  Debug.WriteLine($"{GetType()} -- {isQuad}");
             * }*/

            if ((normalsByte2 & 0b1000_0000) != 0)
            {
                // faces with this bit set seem to be side windows, wheelarch interiors, wing mounts
                RenderOrder = 0b10001;
            }

            int normal0Maybe = vertexByte5 + (normalsByte1 * 256);

            normal0Maybe >>= 1;
            normal0Maybe  &= 0x1FF;
            Vertex0Normal  = normals[normal0Maybe];

            int normal1Maybe = normalsByte1 + (normalsByte2 * 256);

            normal1Maybe >>= 3;
            normal1Maybe  &= 0x1FF;
            Vertex1Normal  = normals[normal1Maybe];

            int normal2Maybe = normalsByte3 + (normalsByte4 * 256);

            normal2Maybe &= 0x1FF;
            Vertex2Normal = normals[normal2Maybe];

            int normal3Maybe = normalsByte4 + (normalsByte5 * 256);

            normal3Maybe >>= 2;
            normal3Maybe  &= 0x1FF;
            Vertex3Normal  = normals[normal3Maybe];

            byte isTextured1 = stream.ReadSingleByte();  // 00 for untextured, FF for textured
            byte isTextured2 = stream.ReadSingleByte();  // 00 for untextured, FF for textured
            byte isTextured3 = stream.ReadSingleByte();  // 00 for untextured, FF for textured

            byte faceTypeData = stream.ReadSingleByte(); // 21 for unt tri, 29 unt quad, 25 tex tri, 2D tex quad

            // 100001 / 21 unt tri - GT2 + 1
            // 101001 / 29 unt quad - GT2 + 1
            // 100101 / 25 tex tri
            // 101101 / 2D tex quad
            if (faceTypeData == 33 || faceTypeData == 41)
            {
                FaceType = faceTypeData - 1;
            }
            else
            {
                FaceType = faceTypeData;
            }
        }
Ejemplo n.º 4
0
 private string WriteVertexToOBJ(Vertex vertex, Normal normal, List <Vertex> vertices, List <Normal> normals, int firstVertexNumber, int firstNormalNumber) =>
 $"{vertices.IndexOf(vertex) + firstVertexNumber}//{normals.IndexOf(normal) + firstNormalNumber}";
Ejemplo n.º 5
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}";