Пример #1
0
 public static void ExportModelToDirectory(Model model, string directory, ExportOptions exportOptions)
 {
     switch (exportOptions.ExportFormatInfo.ExportFormat)
     {
         case ExportFormats.Obj:
             exportModelAsOBJToDirectory(model, directory, exportOptions);
             break;
         //case ModelExportFormats.STL:
         //    exportModelAsSTLToDirectory(model, directory, formatOptions.Options);
         //    break;
     }
 }
Пример #2
0
        public static Mesh LoadFromStream(Model model, Stream stream)
        {
            BinaryReader binaryReader = new BinaryReader(stream);
            uint bytesPerVertex = 0;
            uint vertexStreamCount = 0;

            Mesh mesh = new Mesh(model);
            mesh.MaterialIndex = binaryReader.ReadUInt32();
            mesh.Unknown1 = binaryReader.ReadUInt32();
            mesh.Unknown2 = binaryReader.ReadUInt32();
            mesh.Unknown3 = binaryReader.ReadUInt32();
            vertexStreamCount = binaryReader.ReadUInt32();
            mesh.IndexSize = binaryReader.ReadUInt32();
            mesh.IndexCount = binaryReader.ReadUInt32();
            mesh.VertexCount = binaryReader.ReadUInt32();

            mesh.VertexStreams = new VertexStream[(int)vertexStreamCount];

            // read vertex streams
            for (int j = 0; j < vertexStreamCount; ++j)
            {
                bytesPerVertex = binaryReader.ReadUInt32();

                byte[] buffer = binaryReader.ReadBytes((int)mesh.VertexCount * (int)bytesPerVertex);
                VertexStream vertexStream = new VertexStream((int)bytesPerVertex, buffer);

                if (vertexStream != null)
                {
                    mesh.VertexStreams[j] = vertexStream;
                }
            }

            // read indices
            mesh.IndexData = binaryReader.ReadBytes((int)mesh.IndexCount * (int)mesh.IndexSize);

            uint materialDefinitionHash = model.Materials[(int)mesh.MaterialIndex].MaterialDefinitionHash;

            MaterialDefinition materialDefinition = null;

            MaterialDefinitionLibrary.Instance.MaterialDefinitions.TryGetValue(materialDefinitionHash, out materialDefinition);

            string effectName = materialDefinition.DrawStyles[0].Effect;

            return mesh;
        }
Пример #3
0
 private Mesh(Model model)
 {
     this.Model = model;
 }
Пример #4
0
        private static void exportModelAsOBJToDirectory(Model model, string directory, ExportOptions options)
        {
            //TODO: Figure out what to do with non-version 4 models.
            if (model != null && model.Version != 4)
            {
                return;
            }

            NumberFormatInfo format = new NumberFormatInfo();
            format.NumberDecimalSeparator = ".";

            if (options.Package)
            {
                try
                {
                    DirectoryInfo directoryInfo = Directory.CreateDirectory(directory + @"\" + Path.GetFileNameWithoutExtension(model.Name));
                    directory = directoryInfo.FullName;
                }
                catch (Exception) { }
            }

            if (options.Textures)
            {
                ImageImporter imageImporter = new ImageImporter();
                ImageExporter imageExporter = new ImageExporter();

                foreach(String textureString in model.TextureStrings)
                {
                    MemoryStream textureMemoryStream = AssetManager.Instance.CreateAssetMemoryStreamByName(textureString);

                    if(textureMemoryStream == null)
                        continue;

                    Image textureImage = imageImporter.LoadImageFromStream(textureMemoryStream);

                    if(textureImage == null)
                        continue;

                    imageExporter.SaveImage(textureImage, options.TextureFormat.ImageType, directory + @"\" + Path.GetFileNameWithoutExtension(textureString) + @"." + options.TextureFormat.Extension);
                }
            }

            String path = directory + @"\" + Path.GetFileNameWithoutExtension(model.Name) + ".obj";

            FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write);
            StreamWriter streamWriter = new StreamWriter(fileStream);

            for (Int32 i = 0; i < model.Meshes.Length; ++i)
            {
                Mesh mesh = model.Meshes[i];

                MaterialDefinition materialDefinition = MaterialDefinitionManager.Instance.MaterialDefinitions[model.Materials[(Int32)mesh.MaterialIndex].MaterialDefinitionHash];
                VertexLayout vertexLayout = MaterialDefinitionManager.Instance.VertexLayouts[materialDefinition.DrawStyles[0].VertexLayoutNameHash];

                //position
                VertexLayout.Entry.DataTypes positionDataType;
                Int32 positionOffset;
                Int32 positionStreamIndex;

                vertexLayout.GetEntryInfoFromDataUsageAndUsageIndex(VertexLayout.Entry.DataUsages.Position, 0, out positionDataType, out positionStreamIndex, out positionOffset);

                Mesh.VertexStream positionStream = mesh.VertexStreams[positionStreamIndex];

                for (Int32 j = 0; j < mesh.VertexCount; ++j)
                {
                    Vector3 position = readVector3(options, positionOffset, positionStream, j);

                    position.X *= options.Scale.X;
                    position.Y *= options.Scale.Y;
                    position.Z *= options.Scale.Z;

                    streamWriter.WriteLine("v " + position.X.ToString(format) + " " + position.Y.ToString(format) + " " + position.Z.ToString(format));
                }

                //texture coordinates
                if (options.TextureCoordinates)
                {
                    VertexLayout.Entry.DataTypes texCoord0DataType;
                    Int32 texCoord0Offset = 0;
                    Int32 texCoord0StreamIndex = 0;

                    Boolean texCoord0Present = vertexLayout.GetEntryInfoFromDataUsageAndUsageIndex(VertexLayout.Entry.DataUsages.Texcoord, 0, out texCoord0DataType, out texCoord0StreamIndex, out texCoord0Offset);

                    if (texCoord0Present)
                    {
                        Mesh.VertexStream texCoord0Stream = mesh.VertexStreams[texCoord0StreamIndex];

                        for (Int32 j = 0; j < mesh.VertexCount; ++j)
                        {
                            Vector2 texCoord;

                            switch (texCoord0DataType)
                            {
                                case VertexLayout.Entry.DataTypes.Float2:
                                    texCoord.X = BitConverter.ToSingle(texCoord0Stream.Data, (j * texCoord0Stream.BytesPerVertex) + 0);
                                    texCoord.Y = 1.0f - BitConverter.ToSingle(texCoord0Stream.Data, (j * texCoord0Stream.BytesPerVertex) + 4);
                                    break;
                                case VertexLayout.Entry.DataTypes.float16_2:
                                    texCoord.X = Half.FromBytes(texCoord0Stream.Data, (j * texCoord0Stream.BytesPerVertex) + texCoord0Offset + 0).ToSingle();
                                    texCoord.Y = 1.0f - Half.FromBytes(texCoord0Stream.Data, (j * texCoord0Stream.BytesPerVertex) + texCoord0Offset + 2).ToSingle();
                                    break;
                                default:
                                    texCoord.X = 0;
                                    texCoord.Y = 0;
                                    break;
                            }

                            streamWriter.WriteLine("vt " + texCoord.X.ToString(format) + " " + texCoord.Y.ToString(format));
                        }
                    }
                }
            }

            //faces
            UInt32 vertexCount = 0;

            for (Int32 i = 0; i < model.Meshes.Length; ++i)
            {
                Mesh mesh = model.Meshes[i];

                streamWriter.WriteLine("g Mesh" + i);

                for (Int32 j = 0; j < mesh.IndexCount; j += 3)
                {
                    UInt32 index0, index1, index2;

                    switch (mesh.IndexSize)
                    {
                        case 2:
                            index0 = vertexCount + BitConverter.ToUInt16(mesh.IndexData, (j * 2) + 0) + 1;
                            index1 = vertexCount + BitConverter.ToUInt16(mesh.IndexData, (j * 2) + 2) + 1;
                            index2 = vertexCount + BitConverter.ToUInt16(mesh.IndexData, (j * 2) + 4) + 1;
                            break;
                        case 4:
                            index0 = vertexCount + BitConverter.ToUInt32(mesh.IndexData, (j * 4) + 0) + 1;
                            index1 = vertexCount + BitConverter.ToUInt32(mesh.IndexData, (j * 4) + 4) + 1;
                            index2 = vertexCount + BitConverter.ToUInt32(mesh.IndexData, (j * 4) + 8) + 1;
                            break;
                        default:
                            index0 = 0;
                            index1 = 0;
                            index2 = 0;
                            break;
                    }

                    if (options.Normals && options.TextureCoordinates)
                    {
                        streamWriter.WriteLine("f " + index2 + "/" + index2 + "/" + index2 + " " + index1 + "/" + index1 + "/" + index1 + " " + index0 + "/" + index0 + "/" + index0);
                    }
                    else if (options.Normals)
                    {
                        streamWriter.WriteLine("f " + index2 + "//" + index2 + " " + index1 + "//" + index1 + " " + index0 + "//" + index0);
                    }
                    else if (options.TextureCoordinates)
                    {
                        streamWriter.WriteLine("f " + index2 + "/" + index2 + " " + index1 + "/" + index1 + " " + index0 + "/" + index0);
                    }
                    else
                    {
                        streamWriter.WriteLine("f " + index2 + " " + index1 + " " + index0);
                    }
                }

                vertexCount += (UInt32)mesh.VertexCount;
            }

            streamWriter.Close();
        }
Пример #5
0
        private static void exportModelAsSTLToDirectory(Model model, string directory, ExportOptions options)
        {
            //NumberFormatInfo format = new NumberFormatInfo();
            //format.NumberDecimalSeparator = ".";

            //String path = directory + @"\" + Path.GetFileNameWithoutExtension(model.Name) + ".stl";

            //FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write);
            //StreamWriter streamWriter = new StreamWriter(fileStream);

            //for (Int32 i = 0; i < model.Meshes.Length; ++i)
            //{
            //    Mesh mesh = model.Meshes[i];

            //    for (Int32 j = 0; j < mesh.Indices.Length; j += 3)
            //    {
            //        Vector3 normal = Vector3.Zero;
            //        normal += mesh.Vertices[mesh.Indices[j + 0]].Normal;
            //        normal += mesh.Vertices[mesh.Indices[j + 1]].Normal;
            //        normal += mesh.Vertices[mesh.Indices[j + 2]].Normal;
            //        normal.Normalize();

            //        streamWriter.WriteLine("facet normal " + normal.X.ToString("E", format) + " " + normal.Y.ToString("E", format) + " " + normal.Z.ToString("E", format));
            //        streamWriter.WriteLine("outer loop");

            //        for (Int32 k = 0; k < 3; ++k)
            //        {
            //            Vector3 vertex = mesh.Vertices[mesh.Indices[j + k]].Position;

            //            streamWriter.WriteLine("vertex " + vertex.X.ToString("E", format) + " " + vertex.Y.ToString("E", format) + " " + vertex.Z.ToString("E", format));
            //        }

            //        streamWriter.WriteLine("endloop");
            //        streamWriter.WriteLine("endfacet");
            //    }
            //}

            //streamWriter.Close();
        }
Пример #6
0
 public ModelInstance(Model model)
 {
     this.Model = model;
 }
Пример #7
0
        public static Model LoadFromStream(string name, Stream stream)
        {
            BinaryReader binaryReader = new BinaryReader(stream);

            //header
            byte[] magic = binaryReader.ReadBytes(4);

            if (magic[0] != 'D' ||
                magic[1] != 'M' ||
                magic[2] != 'O' ||
                magic[3] != 'D')
            {
                return null;
            }

            Model model = new Model();

            model.Version = binaryReader.ReadUInt32();

            if (model.Version != 4)
                return null;

            uint modelHeaderOffset = binaryReader.ReadUInt32();

            model.Name = name;

            //textures & materials
            model.TextureStrings = new List<string>();
            model.Materials = new List<Material>();

            Dma.Dma.LoadFromStream(binaryReader.BaseStream, model.TextureStrings, model.Materials);

            //bounding box
            Vector3 min = new Vector3();
            min.X = binaryReader.ReadSingle();
            min.Y = binaryReader.ReadSingle();
            min.Z = binaryReader.ReadSingle();
            model.Min = min;

            Vector3 max = new Vector3();
            max.X = binaryReader.ReadSingle();
            max.Y = binaryReader.ReadSingle();
            max.Z = binaryReader.ReadSingle();
            model.Max = max;

            //meshes
            uint meshCount = binaryReader.ReadUInt32();

            model.Meshes = new Mesh[meshCount];

            for (int i = 0; i < meshCount; ++i)
            {
                Mesh mesh = Mesh.LoadFromStream(model, binaryReader.BaseStream);

                if (mesh != null)
                    model.Meshes[i] = mesh;
            }

            //bone maps
            uint boneMapCount = binaryReader.ReadUInt32();

            model.BoneMaps = new BoneMap[boneMapCount];

            for (int i = 0; i < boneMapCount; ++i)
            {
                BoneMap boneMap = BoneMap.LoadFromStream(binaryReader.BaseStream);
                model.BoneMaps[i] = boneMap;
            }

            //bone map entries
            uint boneMapEntryCount = binaryReader.ReadUInt32();

            BoneMapEntry[] boneMapEntries = new BoneMapEntry[boneMapEntryCount];

            for (int i = 0; i < boneMapEntryCount; ++i)
            {
                BoneMapEntry boneMapEntry = BoneMapEntry.LoadFromStream(binaryReader.BaseStream);

                boneMapEntries[i] = boneMapEntry;
            }

            for (int i = 0; i < model.BoneMaps.Length; ++i)
            {
                uint end = 0;

                if (model.BoneMaps[i].BoneCount > 0)
                {
                    for (int j = 0; j < model.BoneMaps[i].BoneCount; ++j)
                    {
                        if (boneMapEntries[j].GlobalIndex + model.BoneMaps[i].Delta > end)
                        {
                            end = boneMapEntries[j].GlobalIndex + model.BoneMaps[i].Delta;
                        }
                    }
                }

                model.BoneMaps[i].BoneEnd = end;
            }

            uint boneCount = binaryReader.ReadUInt32();

            model.Bones = new Matrix4[boneCount];
            model.BonesMins = new Vector3[boneCount];
            model.BonesMaxs = new Vector3[boneCount];
            model.BoneHashes = new uint[boneCount];

            if (boneCount > 0)
            {
                for (int i = 0; i < boneCount; ++i)
                {
                    Matrix4 boneMatrix = Matrix4.Identity;

                    boneMatrix.M11 = binaryReader.ReadSingle();
                    boneMatrix.M12 = binaryReader.ReadSingle();
                    boneMatrix.M13 = binaryReader.ReadSingle();

                    boneMatrix.M21 = binaryReader.ReadSingle();
                    boneMatrix.M22 = binaryReader.ReadSingle();
                    boneMatrix.M23 = binaryReader.ReadSingle();

                    boneMatrix.M31 = binaryReader.ReadSingle();
                    boneMatrix.M32 = binaryReader.ReadSingle();
                    boneMatrix.M33 = binaryReader.ReadSingle();

                    boneMatrix.M41 = binaryReader.ReadSingle();
                    boneMatrix.M42 = binaryReader.ReadSingle();
                    boneMatrix.M43 = binaryReader.ReadSingle();

                    boneMatrix.Invert();

                    model.Bones[i] = boneMatrix;
                }

                //bones bounding box
                for(int i = 0; i < boneCount; ++i)
                {
                    Vector3 boneMin = new Vector3();
                    boneMin.X = binaryReader.ReadSingle();
                    boneMin.Y = binaryReader.ReadSingle();
                    boneMin.Z = binaryReader.ReadSingle();
                    model.BonesMins[i] = boneMin;

                    Vector3 boneMax = new Vector3();
                    boneMax.X = binaryReader.ReadSingle();
                    boneMax.Y = binaryReader.ReadSingle();
                    boneMax.Z = binaryReader.ReadSingle();
                    model.BonesMaxs[i] = boneMax;
                }

                //bone hashes
                for (int i = 0; i < boneCount; ++i)
                    model.BoneHashes[i] = binaryReader.ReadUInt32();
            }

            return model;
        }
Пример #8
0
        public static Model LoadFromStream(String name, Stream stream)
        {
            BinaryReader binaryReader = new BinaryReader(stream);

            //header
            byte[] magic = binaryReader.ReadBytes(4);

            if (magic[0] != 'D' ||
                magic[1] != 'M' ||
                magic[2] != 'O' ||
                magic[3] != 'D')
            {
                return null;
            }
            Model model = new Model();

            model.Version = binaryReader.ReadUInt32();

            if (model.Version != 4)
            {
                return null;
            }

            UInt32 modelHeaderOffset = binaryReader.ReadUInt32();

            model.Name = name;

            //materials
            model.TextureStrings = new List<String>();
            model.Materials = new List<Material>();
            Dma.Dma.LoadFromStream(binaryReader.BaseStream, model.TextureStrings, model.Materials);

            //bounding box
            model.min.X = binaryReader.ReadSingle();
            model.min.Y = binaryReader.ReadSingle();
            model.min.Z = binaryReader.ReadSingle();

            model.max.X = binaryReader.ReadSingle();
            model.max.Y = binaryReader.ReadSingle();
            model.max.Z = binaryReader.ReadSingle();

            //meshes
            UInt32 meshCount = binaryReader.ReadUInt32();

            model.Meshes = new Mesh[meshCount];

            for (Int32 i = 0; i < meshCount; ++i)
            {
                Mesh mesh = Mesh.LoadFromStream(binaryReader.BaseStream, model.Materials);

                if (mesh != null)
                {
                    model.Meshes[i] = mesh;

                }
            }

            //bone maps
            UInt32 boneMapCount = binaryReader.ReadUInt32();

            model.BoneMaps = new BoneMap[boneMapCount];

            for (Int32 i = 0; i < boneMapCount; ++i)
            {
                BoneMap boneMap = BoneMap.LoadFromStream(binaryReader.BaseStream);

                if (boneMap != null)
                {
                    model.BoneMaps[i] = boneMap;
                }
            }

            //bone map entries
            UInt32 boneMapEntryCount = binaryReader.ReadUInt32();

            BoneMapEntry[] boneMapEntries = new BoneMapEntry[boneMapEntryCount];

            for (Int32 i = 0; i < boneMapEntryCount; ++i)
            {
                BoneMapEntry boneMapEntry = BoneMapEntry.LoadFromStream(binaryReader.BaseStream);

                boneMapEntries[i] = boneMapEntry;
            }

            return model;
        }
Пример #9
0
 public ModelInstance(Model model)
 {
     Model = model;
 }
Пример #10
0
        public void ExportModelToDirectoryWithExportOptions(Model model, string directory, ModelExportOptions exportOptions)
        {
            if (model == null || directory == null || exportOptions == null )
                return;

            NumberFormatInfo numberFormatInfo = new NumberFormatInfo();
            numberFormatInfo.NumberDecimalSeparator = ".";

            if (exportOptions.Package)
            {
                try
                {
                    DirectoryInfo directoryInfo = Directory.CreateDirectory(directory + @"\" + Path.GetFileNameWithoutExtension(model.Name));
                    directory = directoryInfo.FullName;
                }
                catch (Exception) { }
            }

            if (exportOptions.Textures)
            {
                ImageImporter imageImporter = new ImageImporter();
                ImageExporter imageExporter = new ImageExporter();

                foreach(string textureString in model.TextureStrings)
                {
                    MemoryStream textureMemoryStream = AssetManager.Instance.CreateAssetMemoryStreamByName(textureString);
                    if(textureMemoryStream == null)
                        continue;

                    Image textureImage = imageImporter.LoadImageFromStream(textureMemoryStream);
                    if(textureImage == null)
                        continue;

                    imageExporter.SaveImage(textureImage, exportOptions.TextureFormat.ImageType, directory + @"\" + Path.GetFileNameWithoutExtension(textureString) + @"." + exportOptions.TextureFormat.Extension);
                }
            }

            string path = string.Format(@"{0}\{1}.{2}", directory, Path.GetFileNameWithoutExtension(model.Name), Extension);

            FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write);
            StreamWriter streamWriter = new StreamWriter(fileStream);

            for (int i = 0; i < model.Meshes.Length; ++i)
            {
                Mesh mesh = model.Meshes[i];

                //positions
                List<Vector3> positions;
                if (mesh.GetPositions(out positions, 0))
                {
                    foreach (Vector3 position in positions)
                    {
                        Vector3 scaledPosition = Vector3.Multiply(position, exportOptions.Scale);
                        streamWriter.WriteLine("v {0} {1} {2}", scaledPosition.X.ToString(numberFormatInfo), scaledPosition.Y.ToString(numberFormatInfo), scaledPosition.Z.ToString(numberFormatInfo));
                    }
                }

                //texture coordinates
                if (exportOptions.TextureCoordinates)
                {
                    Vector2[] texCoords;
                    if (mesh.GetTexCoords(out texCoords, 0))
                    {
                        foreach (Vector2 texcoord in texCoords)
                            streamWriter.WriteLine("vt {0} {1}", texcoord.X.ToString(numberFormatInfo), (-texcoord.Y).ToString(numberFormatInfo));
                    }
                }

                //normals
                if (exportOptions.Normals)
                {
                    Vector3[] normals;
                    if (mesh.GetNormals(out normals, 0))
                    {
                        foreach (Vector3 normal in normals)
                            streamWriter.WriteLine("vn {0} {1} {2}", normal.X.ToString(numberFormatInfo), normal.Y.ToString(numberFormatInfo), normal.Z.ToString(numberFormatInfo));
                    }
                }
            }

            //faces
            uint vertexCount = 0;

            for (int i = 0; i < model.Meshes.Length; ++i)
            {
                Mesh mesh = model.Meshes[i];

                streamWriter.WriteLine("g Mesh{0}", i);

                uint[] indices;
                mesh.GetIndices(out indices);

                for (int j = 0; j < mesh.IndexCount; j += 3)
                {
                    uint index0 = indices[j + 0];
                    uint index1 = indices[j + 1];
                    uint index2 = indices[j + 2];

                    if (exportOptions.TextureCoordinates && exportOptions.Normals)
                    {
                        streamWriter.WriteLine("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}", index2, index1, index0);
                    }
                    else if (exportOptions.Normals)
                    {
                        streamWriter.WriteLine("f {0}//{0} {1}//{1} {2}//{2}", index2, index1, index0);
                    }
                    else if (exportOptions.TextureCoordinates)
                    {
                        streamWriter.WriteLine("f {0}/{0} {1}/{1} {2}/{2}", index2, index1, index0);
                    }
                    else
                    {
                        streamWriter.WriteLine("f {0} {1} {2}", index2, index1, index0);
                    }
                }

                vertexCount += (uint)mesh.VertexCount;
            }

            streamWriter.Close();
        }