internal SdkMeshIndexBuffer(D3D11Device device, SdkMeshRawFile rawFile, SdkMeshRawMesh rawMesh)
        {
            int index = rawMesh.IndexBuffer;
            SdkMeshRawIndexBufferHeader header = rawFile.IndexBufferHeaders[index];

            byte[] bytes = rawFile.IndexBufferBytes[index];

            this.NumIndices = (int)header.NumIndices;
            this.SizeBytes  = (uint)header.SizeBytes;

            switch (header.IndexType)
            {
            case SdkMeshIndexType.IndexType16Bit:
                this.IndexFormat = DxgiFormat.R16UInt;
                break;

            case SdkMeshIndexType.IndexType32Bit:
                this.IndexFormat = DxgiFormat.R32UInt;
                break;

            default:
                this.IndexFormat = DxgiFormat.R16UInt;
                break;
            }

            var desc = new D3D11BufferDesc((uint)header.SizeBytes, D3D11BindOptions.IndexBuffer);
            var data = new D3D11SubResourceData(bytes, 0, 0);

            this.Buffer = device.CreateBuffer(desc, data);
        }
        internal SdkMeshMesh(D3D11Device device, SdkMeshRawFile rawFile, SdkMeshRawMesh rawMesh)
        {
            this.Name = rawMesh.Name;
            this.ComputeBoundingBox(rawFile, rawMesh);

            this.VertexBuffers = new SdkMeshVertexBuffer[rawMesh.NumVertexBuffers];

            for (int i = 0; i < rawMesh.NumVertexBuffers; i++)
            {
                this.VertexBuffers[i] = new SdkMeshVertexBuffer(device, rawFile, rawMesh, i);
            }

            this.IndexBuffer = new SdkMeshIndexBuffer(device, rawFile, rawMesh);

            foreach (int index in rawMesh.SubsetsIndices)
            {
                SdkMeshSubset subset = new SdkMeshSubset(rawFile.Subsets[index]);
                this.Subsets.Add(subset);
            }

            foreach (int index in rawMesh.FrameInfluencesIndices)
            {
                this.FrameInfluencesIndices.Add(index);
            }
        }
        internal SdkMeshVertexBuffer(D3D11Device device, SdkMeshRawFile rawFile, SdkMeshRawMesh rawMesh, int i)
        {
            int index = rawMesh.VertexBuffers[i];
            SdkMeshRawVertexBufferHeader header = rawFile.VertexBufferHeaders[index];

            byte[] bytes = rawFile.VertexBufferBytes[index];

            this.NumVertices = (int)header.NumVertices;
            this.SizeBytes   = (uint)header.SizeBytes;
            this.StrideBytes = (uint)header.StrideBytes;
            this.Decl        = header.Decl.ToArray();

            var desc = new D3D11BufferDesc((uint)header.SizeBytes, D3D11BindOptions.VertexBuffer);
            var data = new D3D11SubResourceData(bytes, 0, 0);

            this.Buffer = device.CreateBuffer(desc, data);
        }
예제 #4
0
        public static SdkMeshFile FromFile(D3D11Device device, D3D11DeviceContext deviceContext, string fileName)
        {
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }

            if (deviceContext == null)
            {
                throw new ArgumentNullException(nameof(deviceContext));
            }

            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException(nameof(fileName));
            }

            var file = new SdkMeshFile
            {
                _d3dDevice        = device,
                _d3dDeviceContext = deviceContext,
                FilePath          = fileName,
                FileDirectory     = Path.GetDirectoryName(fileName)
            };

            SdkMeshRawFile rawFile = SdkMeshRawFile.FromFile(file.FilePath);

            foreach (SdkMeshRawMaterial rawMaterial in rawFile.Materials)
            {
                var material = new SdkMeshMaterial(file._d3dDevice, file._d3dDeviceContext, file.FileDirectory, rawMaterial);
                file.Materials.Add(material);
            }

            foreach (SdkMeshRawMesh rawMesh in rawFile.Meshes)
            {
                var mesh = new SdkMeshMesh(file._d3dDevice, rawFile, rawMesh);
                file.Meshes.Add(mesh);
            }

            foreach (SdkMeshRawFrame rawFrame in rawFile.Frames)
            {
                var frame = new SdkMeshFrame(rawFrame);
                file.Frames.Add(frame);
            }

            string animFilePath = file.FilePath + "_anim";

            if (File.Exists(animFilePath))
            {
                SdkMeshRawAnimFile rawAnimFile = SdkMeshRawAnimFile.FromFile(animFilePath);

                file.AnimationFrameTransformType = rawAnimFile.Header.FrameTransformType;
                file.AnimationKeysCount          = rawAnimFile.Header.NumAnimationKeys;
                file.AnimationFPS = rawAnimFile.Header.AnimationFPS;

                foreach (SdkMeshRawAnimFrameData rawFrame in rawAnimFile.AnimationFrames)
                {
                    var frame = new SdkMeshAnimationFrame(rawFrame);
                    file.AnimationFrames.Add(frame);
                }

                for (int index = 0; index < file.AnimationFrames.Count; index++)
                {
                    SdkMeshFrame frame = file.FindFrame(file.AnimationFrames[index].FrameName);

                    if (frame != null)
                    {
                        frame.UpdateAnimationFrameIndex(index);
                    }
                }
            }

            return(file);
        }
        private void ComputeBoundingBox(SdkMeshRawFile rawFile, SdkMeshRawMesh rawMesh)
        {
            //this.BoundingBoxCenter = rawMesh.BoundingBoxCenter;
            //this.BoundingBoxExtents = rawMesh.BoundingBoxExtents;

            XMVector lower = XMVector.Replicate(float.MaxValue);
            XMVector upper = XMVector.Replicate(float.MinValue);

            int indsize;

            if (rawFile.IndexBufferHeaders[rawMesh.IndexBuffer].IndexType == SdkMeshIndexType.IndexType32Bit)
            {
                indsize = 4;
            }
            else
            {
                indsize = 2;
            }

            for (int subset = 0; subset < rawMesh.NumSubsets; subset++)
            {
                SdkMeshRawSubset pSubset = rawFile.Subsets[rawMesh.SubsetsIndices[subset]];

                SdkMeshPrimitiveType primType = pSubset.PrimitiveType;
                Debug.Assert(primType == SdkMeshPrimitiveType.TriangleList, "Only triangle lists are handled.");

                if (primType != SdkMeshPrimitiveType.TriangleList)
                {
                    continue;
                }

                int    indexCount = (int)pSubset.IndexCount;
                int    indexStart = (int)pSubset.IndexStart;
                byte[] ind        = rawFile.IndexBufferBytes[rawMesh.IndexBuffer];
                byte[] verts      = rawFile.VertexBufferBytes[rawMesh.VertexBuffers[0]];
                int    stride     = (int)rawFile.VertexBufferHeaders[rawMesh.VertexBuffers[0]].StrideBytes;

                for (int vertind = indexStart; vertind < indexStart + indexCount; vertind++)
                {
                    int current_ind;

                    if (indsize == 2)
                    {
                        current_ind = BitConverter.ToInt16(ind, vertind * 2);
                    }
                    else
                    {
                        current_ind = BitConverter.ToInt32(ind, vertind * 4);
                    }

                    float x = BitConverter.ToSingle(verts, stride * current_ind);
                    float y = BitConverter.ToSingle(verts, stride * current_ind + 4);
                    float z = BitConverter.ToSingle(verts, stride * current_ind + 8);

                    lower = XMVector.Min(new XMVector(x, y, z, 1.0f), lower);
                    upper = XMVector.Max(new XMVector(x, y, z, 1.0f), upper);
                }
            }

            XMVector half = upper - lower;

            half *= 0.5f;

            this.BoundingBoxCenter  = lower + half;
            this.BoundingBoxExtents = half;
        }
        public static SdkMeshRawFile FromStream(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            var file = new SdkMeshRawFile();

            using (var reader = new BinaryReader(stream, Encoding.UTF8, true))
            {
                file.Header = SdkMeshRawHeader.Read(reader);

                if (file.Header.Version != FileVersion)
                {
                    throw new InvalidDataException();
                }

                if (stream.Position != file.Header.VertexStreamHeadersOffset)
                {
                    throw new InvalidDataException();
                }

                stream.Seek(file.Header.VertexStreamHeadersOffset, SeekOrigin.Begin);
                for (int i = 0; i < file.Header.NumVertexBuffers; i++)
                {
                    SdkMeshRawVertexBufferHeader header = SdkMeshRawVertexBufferHeader.Read(reader);
                    file.VertexBufferHeaders.Add(header);
                }

                if (stream.Position != file.Header.IndexStreamHeadersOffset)
                {
                    throw new InvalidDataException();
                }

                stream.Seek(file.Header.IndexStreamHeadersOffset, SeekOrigin.Begin);
                for (int i = 0; i < file.Header.NumIndexBuffers; i++)
                {
                    SdkMeshRawIndexBufferHeader header = SdkMeshRawIndexBufferHeader.Read(reader);
                    file.IndexBufferHeaders.Add(header);
                }

                if (stream.Position != file.Header.MeshDataOffset)
                {
                    throw new InvalidDataException();
                }

                stream.Seek(file.Header.MeshDataOffset, SeekOrigin.Begin);
                for (int i = 0; i < file.Header.NumMeshes; i++)
                {
                    SdkMeshRawMesh mesh = SdkMeshRawMesh.Read(reader);
                    file.Meshes.Add(mesh);
                }

                if (stream.Position != file.Header.SubsetDataOffset)
                {
                    throw new InvalidDataException();
                }

                stream.Seek(file.Header.SubsetDataOffset, SeekOrigin.Begin);
                for (int i = 0; i < file.Header.NumTotalSubsets; i++)
                {
                    SdkMeshRawSubset subset = SdkMeshRawSubset.Read(reader);
                    file.Subsets.Add(subset);
                }

                if (stream.Position != file.Header.FrameDataOffset)
                {
                    throw new InvalidDataException();
                }

                stream.Seek(file.Header.FrameDataOffset, SeekOrigin.Begin);
                for (int i = 0; i < file.Header.NumFrames; i++)
                {
                    SdkMeshRawFrame frame = SdkMeshRawFrame.Read(reader);
                    file.Frames.Add(frame);
                }

                if (stream.Position != file.Header.MaterialDataOffset)
                {
                    throw new InvalidDataException();
                }

                stream.Seek(file.Header.MaterialDataOffset, SeekOrigin.Begin);
                for (int i = 0; i < file.Header.NumMaterials; i++)
                {
                    SdkMeshRawMaterial material = SdkMeshRawMaterial.Read(reader);
                    file.Materials.Add(material);
                }

                foreach (SdkMeshRawMesh mesh in file.Meshes)
                {
                    if (stream.Position != mesh.SubsetOffset)
                    {
                        throw new InvalidDataException();
                    }

                    stream.Seek(mesh.SubsetOffset, SeekOrigin.Begin);
                    for (int i = 0; i < mesh.NumSubsets; i++)
                    {
                        int index = reader.ReadInt32();
                        mesh.SubsetsIndices.Add(index);
                    }

                    if (stream.Position != mesh.FrameInfluenceOffset)
                    {
                        throw new InvalidDataException();
                    }

                    stream.Seek(mesh.FrameInfluenceOffset, SeekOrigin.Begin);
                    for (int i = 0; i < mesh.NumFrameInfluences; i++)
                    {
                        int index = reader.ReadInt32();
                        mesh.FrameInfluencesIndices.Add(index);
                    }
                }

                if (stream.Position != file.Header.HeaderSize + file.Header.NonBufferDataSize)
                {
                    throw new InvalidDataException();
                }

                foreach (SdkMeshRawVertexBufferHeader buffer in file.VertexBufferHeaders)
                {
                    stream.Seek(buffer.DataOffset, SeekOrigin.Begin);

                    byte[] bytes = reader.ReadBytes((int)buffer.SizeBytes);
                    file.VertexBufferBytes.Add(bytes);
                }

                foreach (SdkMeshRawIndexBufferHeader buffer in file.IndexBufferHeaders)
                {
                    stream.Seek(buffer.DataOffset, SeekOrigin.Begin);

                    byte[] bytes = reader.ReadBytes((int)buffer.SizeBytes);
                    file.IndexBufferBytes.Add(bytes);
                }
            }

            return(file);
        }