Ejemplo n.º 1
0
        public SUR(byte[] data)
        {
            HardpointSections = new List <HardpointSection>();
            int pos = 0;

            VersionString = Utilities.GetString(data, ref pos, 4);
            VersionNumber = Utilities.GetFloat(data, ref pos);

            if (VersionNumber != 2.0f || VersionString != "vers")
            {
                throw new FormatException();
            }

            MeshId      = Utilities.GetDWord(data, ref pos);
            SurfaceType = Utilities.GetDWord(data, ref pos);

            SurfaceSection ss = new SurfaceSection();

            while (pos < data.Length)
            {
                string nextType = Utilities.GetString(data, ref pos, 4);
                if (nextType == "hpid")
                {
                    HardpointSection hps = new HardpointSection();
                    hps.MeshIdCount = Utilities.GetDWord(data, ref pos);
                    hps.MeshIds     = new uint[hps.MeshIdCount];
                    for (int a = 0; a < hps.MeshIdCount; a++)
                    {
                        hps.MeshIds[a] = Utilities.GetDWord(data, ref pos);
                    }
                    HardpointSections.Add(hps);
                }
                else if (nextType == "!fxd")
                {
                    FixedFlag = nextType;
                }
                else if (nextType == "exts")
                {
                    ss.BoundingBox = new SharpDX.Vector3[2];
                    for (int a = 0; a < 2; a++)
                    {
                        ss.BoundingBox[a] = new SharpDX.Vector3(
                            Utilities.GetFloat(data, ref pos),
                            Utilities.GetFloat(data, ref pos),
                            Utilities.GetFloat(data, ref pos));
                    }
                }
                else if (nextType == "surf")
                {
                    uint unk = Utilities.GetDWord(data, ref pos);
                    ss.Center = new SharpDX.Vector3(
                        Utilities.GetFloat(data, ref pos),
                        Utilities.GetFloat(data, ref pos),
                        Utilities.GetFloat(data, ref pos));
                    ss.Inertia = new SharpDX.Vector3(
                        Utilities.GetFloat(data, ref pos),
                        Utilities.GetFloat(data, ref pos),
                        Utilities.GetFloat(data, ref pos));
                    ss.Radius            = Utilities.GetFloat(data, ref pos);
                    ss.Scale             = data[pos++];
                    ss.Size              = Utilities.GetDWord(data, ref pos) & 0x00FFFFFF; pos--;
                    ss.BitsSectionOffset = Utilities.GetDWord(data, ref pos);

                    // padding
                    pos += 3 * sizeof(uint);

                    int maxPos = data.Length;
                    while (pos < maxPos)
                    {
                        TriangleGroup tgh = new TriangleGroup();

                        tgh.VertexOffset   = Utilities.GetDWord(data, ref pos);
                        tgh.MeshId         = Utilities.GetDWord(data, ref pos);
                        tgh.Type           = data[pos++];
                        tgh.RefVertexCount = Utilities.GetDWord(data, ref pos) & 0x00FFFFFF; pos--;
                        tgh.TriangleCount  = Utilities.GetShort(data, ref pos);
                        tgh.Triangles      = new Triangle[tgh.TriangleCount];

                        maxPos = pos + (int)tgh.VertexOffset;

                        for (int a = 0; a < tgh.TriangleCount; a++)
                        {
                            Triangle t        = new Triangle();
                            byte[]   tempData = new byte[20];
                            Array.Copy(data, pos, tempData, 0, 20);
                            BitArray br     = new BitArray(tempData);
                            int      bitpos = 0;
                            bitpos          += 13;
                            t.TriangleNumber = (ushort)Advance(br, 12, ref bitpos);
                            t.TriangleOpp    = (ushort)Advance(br, 12, ref bitpos);
                            bitpos          += 7;
                            t.Flag           = (byte)Advance(br, 1, ref bitpos);
                            t.Indices        = new Index[3];
                            for (int b = 0; b < 3; b++)
                            {
                                Index i = new Index();
                                i.VertexId   = (ushort)Advance(br, sizeof(ushort) * 8, ref bitpos);
                                i.Offset     = (short)Advance(br, 15, ref bitpos);
                                i.Flag       = (byte)Advance(br, 1, ref bitpos);
                                t.Indices[b] = i;
                            }
                            tgh.Triangles[a] = t;

                            PrintBits(br);

                            pos += 20;
                        }
                    }
                }
                else
                {
                    throw new FormatException();
                }
            }
        }
        /// <summary>
        /// WARNING THIS IS NOT FINISHED AND IS DEFINITELY BROKEN
        /// </summary>
        /// <param name="filePath"></param>
        public SurFile(string filePath)
        {
            this.FilePath = filePath;
            byte[] data;

            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                data = new byte[fs.Length];
                fs.Read(data, 0, (int)fs.Length);
                fs.Close();
            }

            int pos = 0;

            VersionString = Utilities.GetString(data, ref pos, 4);
            VersionNumber = Utilities.GetFloat(data, ref pos);

            if (VersionNumber != 2.0f || VersionString != "vers")
            {
                throw new FormatException();
            }

            while (pos < data.Length)
            {
                Mesh m = new Mesh();
                m.HardpointSections = new List <HardpointSection>();
                m.SurfaceSections   = new List <SurfaceSection>();
                m.MeshId            = Utilities.GetDWord(data, ref pos);
                uint blockCount = Utilities.GetDWord(data, ref pos);

                while (blockCount-- > 0)
                {
                    string nextType = Utilities.GetString(data, ref pos, 4);
                    if (nextType == "hpid")
                    {
                        HardpointSection hps = new HardpointSection();
                        hps.MeshIdCount = Utilities.GetDWord(data, ref pos);
                        hps.MeshIds     = new uint[hps.MeshIdCount];
                        for (int a = 0; a < hps.MeshIdCount; a++)
                        {
                            hps.MeshIds[a] = Utilities.GetDWord(data, ref pos);
                        }
                        m.HardpointSections.Add(hps);
                    }
                    else if (nextType == "!fxd")
                    {
                        FixedFlag = nextType;
                    }
                    else if (nextType == "exts")
                    {
                        m.BoundingBox = new SharpDX.Vector3[2];
                        for (int a = 0; a < 2; a++)
                        {
                            m.BoundingBox[a] = new SharpDX.Vector3(
                                Utilities.GetFloat(data, ref pos),
                                Utilities.GetFloat(data, ref pos),
                                Utilities.GetFloat(data, ref pos));
                        }
                    }
                    else if (nextType == "surf")
                    {
                        SurfaceSection ss = new SurfaceSection();

                        uint size       = Utilities.GetDWord(data, ref pos);
                        uint header_pos = (uint)pos;
                        ss.Center = new SharpDX.Vector3(
                            Utilities.GetFloat(data, ref pos),
                            Utilities.GetFloat(data, ref pos),
                            Utilities.GetFloat(data, ref pos));
                        ss.Inertia = new SharpDX.Vector3(
                            Utilities.GetFloat(data, ref pos),
                            Utilities.GetFloat(data, ref pos),
                            Utilities.GetFloat(data, ref pos));
                        ss.Radius            = Utilities.GetFloat(data, ref pos);
                        ss.Scale             = data[pos] / 250.0f;
                        ss.Size              = Utilities.GetDWord(data, ref pos) >> 8;
                        ss.BitsSectionOffset = Utilities.GetDWord(data, ref pos);
                        ss.TriangleGroups    = new List <TriangleGroup>();
                        ss.Vertices          = new List <Vertex>();

                        uint bits_beg = header_pos + ss.BitsSectionOffset;
                        uint bits_end = header_pos + ss.Size;

                        // padding
                        pos += 3 * sizeof(uint);

                        int vertBufStart = data.Length;
                        while (pos < vertBufStart)
                        {
                            TriangleGroup tgh = new TriangleGroup();

                            int group_pos = pos;
                            tgh.VertexOffset   = Utilities.GetDWord(data, ref pos);
                            tgh.MeshId         = Utilities.GetDWord(data, ref pos);
                            tgh.Type           = data[pos];
                            tgh.RefVertexCount = Utilities.GetDWord(data, ref pos) >> 8;
                            tgh.TriangleCount  = Utilities.GetShort(data, ref pos); pos += 2;
                            tgh.Triangles      = new Triangle[tgh.TriangleCount];

                            vertBufStart = group_pos + (int)tgh.VertexOffset;

                            for (int a = 0; a < tgh.TriangleCount; a++)
                            {
                                Triangle t        = new Triangle();
                                byte[]   tempData = new byte[(12 + 12 + 7 + 1 + 3 * (16 + 15 + 1)) / 8];
                                Array.Copy(data, pos, tempData, 0, tempData.Length);
                                pos += tempData.Length;
                                BitArray br = new BitArray(tempData);

                                int bitpos = 0;
                                t.TriangleNumber = (ushort)Advance(br, 12, ref bitpos);
                                t.TriangleOpp    = (ushort)Advance(br, 12, ref bitpos);
                                bitpos          += 7;
                                t.Flag           = (byte)Advance(br, 1, ref bitpos);
                                t.Indices        = new Index[3];
                                for (int b = 0; b < 3; b++)
                                {
                                    Index i = new Index();
                                    i.VertexId   = (ushort)Advance(br, sizeof(ushort) * 8, ref bitpos);
                                    i.Offset     = (short)Advance(br, 15, ref bitpos);
                                    i.Flag       = (byte)Advance(br, 1, ref bitpos);
                                    t.Indices[b] = i;
                                }
                                tgh.Triangles[a] = t;
                            }

                            ss.TriangleGroups.Add(tgh);
                        }

                        // Vertices
                        while (pos < bits_beg)
                        {
                            Vertex vertex = new Vertex();
                            vertex.X      = Utilities.GetFloat(data, ref pos);
                            vertex.Y      = Utilities.GetFloat(data, ref pos);
                            vertex.Z      = Utilities.GetFloat(data, ref pos);
                            vertex.MeshId = Utilities.GetDWord(data, ref pos);
                            ss.Vertices.Add(vertex);
                        }

                        m.SurfaceSections.Add(ss);

                        pos = (int)bits_end;
                    }
                    else
                    {
                        throw new FormatException();
                    }
                }

                Meshes.Add(m);
            }
        }