예제 #1
0
 public void Serialize(Stream stream, CompressionBounds boundingbox)
 {
     BinaryWriter bw = new BinaryWriter(stream);
     bw.Write((short)2);
     bw.Write((short)3);
     bw.Write(ShaderIndex);
     bw.Write(IndiceStart);
     bw.Write(IndiceCount);
     stream.Seek(4, SeekOrigin.Current);
     bw.Write((short)1);
     stream.Seek(16, SeekOrigin.Current);
     bw.Write(1.0F);
     bw.Write(0.0F);
     bw.Write(0.0F);
     bw.Write(1.0F);
     bw.Write(boundingbox.X.Min);
     bw.Write(boundingbox.X.Max);
     bw.Write(boundingbox.Y.Min);
     bw.Write(boundingbox.Y.Max);
     bw.Write(boundingbox.Z.Min);
     bw.Write(boundingbox.Z.Max);
 }
예제 #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] */
                };
            }
        }
예제 #3
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();
        }
예제 #4
0
        public void ImportWavefrontObject(WavefrontObject Wavefront, CompressionBounds boundingBox)
        {
            List<D3DVertex> temp = new List<D3DVertex>(Wavefront.FaceCount * 3);
            for (int Material = 0; Material < Wavefront.MaterialCount; Material++)
            {
                int[] FaceIndices = Wavefront.GetFaceIndicesUsingMaterialID(Material);
                for (int Face = 0; Face < FaceIndices.Length; Face++)
                {
                    for (int Component = 0; Component < 3; Component++)
                    {
                        D3DVertex d3DVertex = new D3DVertex();
                        d3DVertex.Position = Wavefront.Vertices[Wavefront.Faces[FaceIndices[Face]].VertexIndices[Component]];
                        d3DVertex.Texture = Wavefront.Texcoords[Wavefront.Faces[FaceIndices[Face]].TexcoordIndices[Component]];
                        d3DVertex.Normal = Wavefront.Normals[Wavefront.Faces[FaceIndices[Face]].NormalIndices[Component]];
                        temp.Add(d3DVertex);
                    }
                }
            }
            //Hashtable D3DVertexHashtable = new Hashtable(Wavefront.FaceCount * 3);
            List<short> tempIndices = new List<short>(Wavefront.FaceCount * 3);
            List<D3DVertex> D3DVertexList = new List<D3DVertex>(Wavefront.FaceCount * 3);
            short IndiceIndex = 0;
            for (int Index = 0; Index < temp.Count; Index++)
            {
                D3DVertex d3DVertex = temp[Index];
                if (!D3DVertexList.Contains(d3DVertex))
                {
                    //D3DVertexHashtable.Add(d3DVertex, d3DVertex);
                    D3DVertexList.Add(d3DVertex);
                    tempIndices.Add(IndiceIndex);
                    IndiceIndex++;
                }
                else
                {
                    tempIndices.Add((short)D3DVertexList.IndexOf(d3DVertex));
                }
            }
            this.Indices = tempIndices.ToArray();
            D3DVertex[] D3DVertices = D3DVertexList.ToArray();

            RenderDevice Device = new RenderDevice();
            Device.InitializeDevice();

            Microsoft.DirectX.Direct3D.Mesh mesh = new Microsoft.DirectX.Direct3D.Mesh(Wavefront.FaceCount, D3DVertices.Length, MeshFlags.SystemMemory, D3DVertex.Format, Device.Device);

            List<int> newAttributes = new List<int>(Wavefront.FaceCount);
            foreach (Face f in Wavefront.Faces)
            {
                newAttributes.Add(f.MaterialID);
            }
            mesh.LockAttributeBuffer(LockFlags.None);
            mesh.UnlockAttributeBuffer(newAttributes.ToArray());
            mesh.SetIndexBufferData(Indices.ToArray(), LockFlags.None);
            mesh.SetVertexBufferData(D3DVertices.ToArray(), LockFlags.None);

            int[] adj = new int[Wavefront.FaceCount * 3];
            mesh.GenerateAdjacency(0.005F, adj);
            mesh.OptimizeInPlace(MeshFlags.OptimizeAttributeSort, adj);
            IndexBuffer iBuffer = mesh.IndexBuffer;

            short[] D3DIndices;
            int IndiceCount;

            short[][] MaterialFaceIndices = new short[Wavefront.MaterialCount][];

            for (int Material = 0; Material < Wavefront.MaterialCount; Material++)
            {
                iBuffer = Microsoft.DirectX.Direct3D.Mesh.ConvertMeshSubsetToSingleStrip(mesh, Material, MeshFlags.SystemMemory, out IndiceCount);
                GraphicsStream graphics = iBuffer.Lock(0, 0, LockFlags.None);
                unsafe
                {
                    short* IndiceArray = (short*)graphics.InternalData.ToPointer();
                    D3DIndices = new short[IndiceCount];
                    for (int Index = 0; Index < IndiceCount; Index++)
                    {
                        D3DIndices[Index] = IndiceArray[Index];
                    }
                }
                MaterialFaceIndices[Material] = D3DIndices;
            }

            List<short> newIndices = new List<short>();
            Groups = new Group[MaterialFaceIndices.Length];
            for (int i = 0; i < MaterialFaceIndices.Length; i++)
            {
                Groups[i] = new Group();
                Groups[i].IndiceStart = (short)newIndices.Count;
                Groups[i].IndiceCount = (short)MaterialFaceIndices[i].Length;
                Groups[i].ShaderIndex = (short)i;
                newIndices.AddRange(MaterialFaceIndices[i]);
            }
            this.Indices = newIndices.ToArray();

            this._Vertices = new Vector3[D3DVertices.Length];
            this.Texcoords = new Vector2[D3DVertices.Length];
            this.Normals = new Vector3[D3DVertices.Length];
            for (int i = 0; i < D3DVertices.Length; i++)
            {
                _Vertices[i] = D3DVertices[i].Position;
                Texcoords[i] = D3DVertices[i].Texture;
                Normals[i] = D3DVertices[i].Normal;
            }

            CalculateTangentArray(_Vertices.Length, _Vertices, Normals, Texcoords, mesh.NumberFaces, Wavefront.Faces.ToArray(), out Bitangents, out Tangents);
            mesh.Dispose();
        }
예제 #5
0
 public CompressionBounds GenerateBoundingBox()
 {
     CompressionBounds bounds = new CompressionBounds();
     foreach (Vector3 v in Vertices)
     {
         bounds.X.Expand(v.X);
         bounds.Y.Expand(v.Y);
         bounds.Z.Expand(v.Z);
     }
     foreach (Vector2 vt in Texcoords)
     {
         bounds.U.Expand(vt.X);
         bounds.V.Expand(vt.Y);
     }
     return bounds;
 }