コード例 #1
0
ファイル: Mesh.cs プロジェクト: kholdfuzion/halo2x-sunfish
        public byte[] Serialize(Section section, CompressionBounds boundingBox, out Resource[] resources)
        {
            MemoryStream stream = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(stream);

            List<Resource> resourceList = new List<Resource>();
            
            byte[] fourCC = Encoding.UTF8.GetBytes("crsr");

            bw.Write(Encoding.UTF8.GetBytes("hklb"), 0, 4);
            stream.Seek(4, SeekOrigin.Current);
            bw.Write(Groups.Length);
            //stream.Seek(4, SeekOrigin.Current);
            //bw.Write(1);
            stream.Seek(8, SeekOrigin.Current);
            stream.Seek(20, SeekOrigin.Current);
            bw.Write(Indices.Length);
            stream.Seek(20, SeekOrigin.Current);
            bw.Write(3);
            stream.Seek(40, SeekOrigin.Current);
            bw.Write(1);
            stream.Seek(8, SeekOrigin.Current);
            bw.Write(fourCC, 0, 4);
            resourceList.Add(new Resource(ResourceType.MeshInformation, ResourceSubType.MeshInformationData, (int)(stream.Position - 120), 72));
            for (int i = 0; i < Groups.Length; i++)
            {
                Groups[i].Serialize(stream, boundingBox);
            }

            //bw.Write(fourCC, 0, 4);
            //resourceList.Add(new Resource(ResourceType.UnknownStruct8, ResourceSubType.UnknownStruct8, (int)(stream.Position - 120), 8));
            //bw.Write(0x00000000); bw.Write((ushort)0xFFFF); bw.Write((short)0x0000);

            bw.Write(fourCC, 0, 4);
            resourceList.Add(new Resource(ResourceType.TriangleStrip, ResourceSubType.IndiceStripData, (int)(stream.Position - 120), Indices.Length * 2));
            foreach (short i in Indices)
                bw.Write(i);
            stream.Pad(4);

            bw.Write(fourCC, 0, 4);
            resourceList.Add(new Resource(ResourceType.Unknown, ResourceSubType.UnknownData, (int)(stream.Position - 120), 96));
            bw.Write((byte)0x02); bw.Write((byte)0x06); bw.Write((byte)0x00); bw.Write((byte)0x00);
            bw.Write(new byte[28]);
            bw.Write((byte)0x19); bw.Write((byte)0x04); bw.Write((byte)0x00); bw.Write((byte)0x00);
            bw.Write(new byte[28]);
            bw.Write((byte)0x1B); bw.Write((byte)0x0C); bw.Write((byte)0x00); bw.Write((byte)0x00);
            bw.Write(new byte[28]);

            bw.Write(fourCC, 0, 4);
            resourceList.Add(new Resource(ResourceType.Vertex, ResourceSubType.VertexData, (int)(stream.Position - 120), _Vertices.Length * 6));
            foreach (Vector3 v in _Vertices)
            {
                bw.Write(CompressionBounds.Compress(v.X, boundingBox.X));
                bw.Write(CompressionBounds.Compress(v.Y, boundingBox.Y));
                bw.Write(CompressionBounds.Compress(v.Z, boundingBox.Z));
            }
            bw.Write(Padding.GetBytes(stream.Position, 4));

            bw.Write(fourCC, 0, 4);
            resourceList.Add(new Resource(ResourceType.Vertex, ResourceSubType.UVData, (int)(stream.Position - 120), _Vertices.Length * 4));
            foreach (Vector2 t in Texcoords)
            {
                bw.Write(CompressionBounds.Compress(t.X, boundingBox.X));
                bw.Write(CompressionBounds.Compress(t.Y, boundingBox.Y));
            }
            bw.Write(Padding.GetBytes(stream.Position, 4));

            bw.Write(fourCC, 0, 4);
            resourceList.Add(new Resource(ResourceType.Vertex, ResourceSubType.VectorData, (int)(stream.Position - 120), Normals.Length * 4 * 3));
            for (int i = 0; i < Normals.Length; i++)
            {
                bw.Write(CompressVector(Normals[i]));
                bw.Write(CompressVector(Tangents[i]));
                bw.Write(CompressVector(Bitangents[i]));
            }
            bw.Write(Padding.GetBytes(stream.Position, 4));

            bw.Write(fourCC, 0, 4);
            resourceList.Add(new Resource(ResourceType.BoneMap, ResourceSubType.BoneData, (int)(stream.Position - 120), BoneMap.Length));
            if (BoneMap.Length == 0)
            {
                foreach (byte b in BoneMap)
                    bw.Write(b);
                bw.Write(Padding.GetBytes(stream.Position, 4));
            }
            else
            {
                bw.Write(0);
            }
            bw.Write(Encoding.UTF8.GetBytes("fklb"), 0, 4);
            int rawLength = (int)stream.Position;
            stream.Seek(4, SeekOrigin.Begin);
            bw.Write(rawLength - 116);

            resources = resourceList.ToArray();
            return stream.ToArray();
        }
コード例 #2
0
ファイル: Mesh.cs プロジェクト: kholdfuzion/halo2x-sunfish
        public Mesh(Stream stream, Resource[] resources, Section section, CompressionBounds boundingBox)
        {
            int StartOffset = (int)stream.Position;
            BinaryReader br = new BinaryReader(stream);
            stream.Position = 4;
            Size = br.ReadInt32();
            foreach (Resource r in resources)
            {
                stream.Position = StartOffset + 120 + r.RawDataOffset;
                int Count=0;
                switch (r.MainRawDataType)
                {
                    case ResourceType.BoneMap:
                        BoneMap = br.ReadBytes(r.RawDataSize);
                        break;
                    case ResourceType.MeshInformation:
                        Groups = new Group[r.RawDataSize / 72];
                        for (int i = 0; i < Groups.Length; i++)
                        {
                            stream.Position = StartOffset + 120 + r.RawDataOffset + (i * 72);
                            Groups[i] = new Group(br.ReadBytes(Group.Size));
                        }
                        break;


                    case ResourceType.Vertex:
                        switch (r.SubRawDataType)
                        {
                            #region Vertices

                            case ResourceSubType.VertexData:

                                byte[] Bytes = br.ReadBytes(r.RawDataSize);
                                int Index = 0;

                                int Stride;
                                switch (section.VertexType)
                                {
                                    case VertexType.Rigid: Stride = 0;//xyz
                                        break;
                                    case VertexType.RigidBoned: Stride = 2;//xyz
                                        break;
                                    case VertexType.Skinned: Stride = 6;//xyz
                                        break;
                                    default: throw new Exception();
                                }

                                if ((section.CompressionFlags & Compression.Position) != Compression.Position)
                                {
                                    int VertexSize = 12 + Stride;
                                    int VertexCount = Bytes.Length / VertexSize;
                                    Index = 0;
                                    _Vertices = new Vector3[VertexCount];

                                    for (int i = 0; i < VertexCount; i++)
                                    {
                                        float x = BitConverter.ToSingle(Bytes, Index + 0);
                                        float y = BitConverter.ToSingle(Bytes, Index + 4);
                                        float z = BitConverter.ToSingle(Bytes, Index + 8);
                                        _Vertices[i] = new Vector3(x, y, z);
                                        Index += VertexSize;
                                    }
                                }
                                else
                                {
                                    int VertexSize = 6 + Stride;
                                    int VertexCount = Bytes.Length / VertexSize;
                                    Index = 0;
                                    _Vertices = new Vector3[VertexCount];

                                    for (int i = 0; i < VertexCount; i++)
                                    {
                                        _Vertices[i] = new Vector3(CompressionBounds.Decompress(BitConverter.ToInt16(Bytes, Index + 0), boundingBox.X),
                                            CompressionBounds.Decompress(BitConverter.ToInt16(Bytes, Index + 2), boundingBox.Y),
                                            CompressionBounds.Decompress(BitConverter.ToInt16(Bytes, Index + 4), boundingBox.Z));
                                        Index += VertexSize;
                                    }
                                }
                                break;

                            #endregion

                            #region Texcoords

                            case ResourceSubType.UVData:
                                Index = 0;
                                Bytes = br.ReadBytes(r.RawDataSize);
                                if ((section.CompressionFlags & Compression.Texcoord) == Compression.Texcoord)
                                {
                                    int TexcoordSize = 4;
                                    Count = Bytes.Length / TexcoordSize;
                                    Texcoords = new Vector2[Count];
                                    for (int i = 0; i < Count; i++)
                                    {
                                        Texcoords[i] = new Vector2(CompressionBounds.Decompress(BitConverter.ToInt16(Bytes, Index + 0),
                                            boundingBox.U), CompressionBounds.Decompress(BitConverter.ToInt16(Bytes, Index + 2), boundingBox.V));
                                        Index += TexcoordSize;
                                    }
                                }
                                else
                                {
                                    int TexcoordSize = 8;
                                    Count = Bytes.Length / TexcoordSize;
                                    Texcoords = new Vector2[Count];
                                    for (int i = 0; i < Count; i++)
                                    {
                                        float u = BitConverter.ToSingle(Bytes, Index);
                                        float v = BitConverter.ToSingle(Bytes, Index + 4);
                                        Texcoords[i] = new Vector2(u, v);
                                        Index += TexcoordSize;
                                    }
                                }
                                break;

                            #endregion

                            #region Normals, Tangents, and Bitangents

                            case ResourceSubType.VectorData:

                                int[] Ints = new int[r.RawDataSize / 4];
                                for (int i = 0; i < Ints.Length; i++)
                                    Ints[i] = br.ReadInt32();

                                Normals = new Vector3[Ints.Length / 3];
                                Tangents = new Vector3[Ints.Length / 3];
                                Bitangents = new Vector3[Ints.Length / 3];

                                int[] normInts = new int[Ints.Length / 3];
                                for (int i = 0; i < normInts.Length; i++)
                                {
                                    normInts[i] = Ints[i * 3];
                                }

                                int normalsCount = 0;
                                int tangentsCount = 0;
                                int bitangentsCount = 0;
                                for (int i = 0; i < Ints.Length; i++)
                                {
                                    int CompressedData = Ints[i];
                                    int x10 = (CompressedData & 0x000007FF);
                                    if ((x10 & 0x00000400) == 0x00000400) { 
                                        x10 = -((~x10) & 0x000007FF);
                                        if (x10 == 0) x10 = -1;
                                    }
                                    int y11 = (CompressedData >> 11) & 0x000007FF;
                                    if ((y11 & 0x00000400) == 0x00000400)
                                    {
                                        y11 = -((~y11) & 0x000007FF);
                                        if (y11 == 0) y11 = -1;
                                    }
                                    int z11 = (CompressedData >> 22) & 0x000003FF;
                                    if ((z11 & 0x00000200) == 0x00000200)
                                    {
                                        z11 = -((~z11) & 0x000003FF);
                                        if (z11 == 0) z11 = -1;
                                    }
                                    float x, y, z;
                                    x = (x10 / (float)0x000003ff);
                                    y = (y11 / (float)0x000003FF);
                                    z = (z11 / (float)0x000001FF);
                                    int o = 0;

                                    switch (i % 3)
                                    {
                                        case 0:
                                            Normals[normalsCount] = new Vector3(x, y, z);
                                            normalsCount++;
                                            break;
                                        case 1:
                                            Tangents[tangentsCount] = new Vector3(x, y, z);
                                            tangentsCount++;
                                            break;
                                        case 2:
                                            Bitangents[bitangentsCount] = new Vector3(x, y, z);
                                            bitangentsCount++;
                                            break;
                                    }
                                }
                                //Normals = GenerateNormals(Vertices, Indices);
                                break;

                            #endregion
                        }
                        break;

                    #region Triangle Strip Indices

                    case ResourceType.TriangleStrip:
                        Count = r.RawDataSize / 2;
                        Indices = new short[Count];
                        for (int x = 0; x < Count; x++)
                        {
                            Indices[x] = br.ReadInt16();
                        }
                        break;

                    #endregion
                }
            }
            Vertices = new Vertex[_Vertices.Length];
            for (int i = 0; i < Vertices.Length; i++)
            {
                Vertices[i] = new Vertex(){
                    Position = _Vertices[i].ToXnaVector3(), 
                   Color = Microsoft.Xna.Framework.Graphics.Color.Gray,
                   Normal = Normals[i].ToXnaVector3(),
                   Tangent = Tangents[i].ToXnaVector3(),
                   Bitangent = Bitangents[i].ToXnaVector3(),
                    /*Texcoord = Texcoords[i] */
                };
            }
        }
コード例 #3
0
ファイル: Model.cs プロジェクト: kholdfuzion/halo2x-sunfish
        public Model(Tag tag)
        {
            BinaryReader br = new BinaryReader(tag.TagStream);
            tag.TagStream.Position = 0;
            buffer = br.ReadBytes(Size);
            tag.TagStream.Position = 0;
            Name = tag.Strings[br.ReadInt32()];

            #region Bounding Boxes

            tag.TagStream.Position = 20;
            int Count = br.ReadInt32();
            if (Count == 1)
            {
                int Offset = br.ReadInt32();
                tag.TagStream.Position = Offset;
                Space = new CompressionInfo(tag.TagStream);
            }
            else throw new Exception();

            #endregion

            #region Mesh Regions

            tag.TagStream.Position = 28;
            Count = br.ReadInt32();
            if (Count > 0)
            {
                int Offset = br.ReadInt32();
                Regions = new Region[Count];
                for (int i = 0; i < Count; i++)
                {
                    tag.TagStream.Position = Offset + (i * Region.Size);
                    Regions[i] = new Region(tag);
                }
            }

            #endregion

            #region Mesh Sections

            tag.TagStream.Position = 36;
            Count = br.ReadInt32();
            if (Count > 0)
            {
                int Offset = br.ReadInt32();
                Sections = new Section[Count];
                for (int i = 0; i < Count; i++)
                {
                    tag.TagStream.Position = Offset + (i * Section.Size);
                    Sections[i] = new Section(tag, Space);
                }
            }

            #endregion

            #region Section Groups

            tag.TagStream.Position = 52;
            Count = br.ReadInt32();
            if (Count > 0)
            {
                int Offset = br.ReadInt32();
                SectionGroups = new SectionGroup[Count];
                for (int i = 0; i < Count; i++)
                {
                    tag.TagStream.Position = Offset + (i * MarkerGroup.Size);
                    SectionGroups[i] = new SectionGroup(tag.TagStream);
                }
            }

            #endregion

            #region Nodes

            tag.TagStream.Position = 72;
            Count = br.ReadInt32();
            if (Count > 0)
            {
                int Offset = br.ReadInt32();
                Nodes = new Node[Count];
                for (int i = 0; i < Count; i++)
                {
                    tag.TagStream.Position = Offset + (i * Node.Size);
                    Nodes[i] = new Node(tag);
                }
            }

            #endregion            

            #region Marker Groups

            tag.TagStream.Position = 88;
            Count = br.ReadInt32();
            if (Count > 0)
            {
                int Offset = br.ReadInt32();
                MarkerGroups = new MarkerGroup[Count];
                for (int i = 0; i < Count; i++)
                {
                    tag.TagStream.Position = Offset + (i * MarkerGroup.Size);
                    MarkerGroups[i] = new MarkerGroup(tag);
                }
            }

            #endregion

            #region Shaders

            tag.TagStream.Position = 96;
            Count = br.ReadInt32();
            if (Count > 0)
            {
                int Offset = br.ReadInt32();
                Shaders = new Shader[Count];
                for (int i = 0; i < Count; i++)
                {
                    tag.TagStream.Position = Offset + (i * Shader.Size);
                    Shaders[i] = new Shader(tag);
                }
            }

            #endregion
        }