Beispiel #1
0
        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();
        }
Beispiel #2
0
        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] */
                };
            }
        }
Beispiel #3
0
        public Section(Tag tag, CompressionInfo boundingBox)
        {
            BinaryReader br = new BinaryReader(tag.TagStream);
            int StartOffset = (int)tag.TagStream.Position;

            buffer = br.ReadBytes(Size);
            tag.TagStream.Position = StartOffset;

            VertexType = (VertexType)br.ReadInt32();
            VertexCount = br.ReadInt16();
            TriangleCount = br.ReadInt16();

            tag.TagStream.Position = StartOffset + 26;
            CompressionFlags = (Compression)br.ReadInt32();

            tag.TagStream.Position = StartOffset + 56;
            RawOffset = br.ReadInt32();
            RawSize = br.ReadInt32();
            br.ReadInt32();
            RawDataSize = br.ReadInt32();

            tag.TagStream.Position = StartOffset + 72;
            int Count = br.ReadInt32();
            if (Count > 0)
            {
                int Offset = br.ReadInt32();
                Resources = new Resource[Count];
                for (int i = 0; i < Count; i++)
                {
                    tag.TagStream.Position = Offset + (i * Resource.Size);
                    Resources[i] = new Resource(tag.TagStream);
                }
            }
            if (Globals.IsExternalResource(RawOffset)) { return; }
            tag.ResourceStream.Position = tag.ResourceInformation[RawOffset].Address;
            mesh = new Mesh(tag.ResourceStream, Resources, this, boundingBox);

            Microsoft.Xna.Framework.Vector3[] points = new Microsoft.Xna.Framework.Vector3[mesh.Vertices.Length];
            for (int i = 0; i < points.Length; i++)
                points[i] = mesh.Vertices[i].Position;
            BoundingBox = Microsoft.Xna.Framework.BoundingBox.CreateFromPoints(points);
        }