예제 #1
0
        public void ImportModel()
        {
            OpenFileDialog dlg = new OpenFileDialog()
            {
                DefaultExt = "sa1mdl", Filter = "Model Files|*.sa1mdl;*.obj;*.objf", RestoreDirectory = true
            };

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                switch (Path.GetExtension(dlg.FileName).ToLowerInvariant())
                {
                case ".obj":
                case ".fbx":
                case ".dae":
                case ".objf":
                    Assimp.AssimpContext context = new Assimp.AssimpContext();
                    context.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
                    Assimp.Scene scene    = context.ImportFile(dlg.FileName, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.FlipUVs);
                    NJS_OBJECT   newmodel = SAEditorCommon.Import.AssimpStuff.AssimpImport(scene, scene.RootNode, ModelFormat.BasicDX, LevelData.TextureBitmaps[LevelData.leveltexs].Select(a => a.Name).ToArray(), true);
                    Model.Attach = newmodel.Attach;
                    Model.ProcessVertexData();
                    Mesh = Model.Attach.CreateD3DMesh();
                    break;

                case ".sa1mdl":
                    ModelFile mf = new ModelFile(dlg.FileName);
                    Model.Attach = mf.Model.Attach;
                    Model.ProcessVertexData();
                    Mesh = Model.Attach.CreateD3DMesh();
                    break;
                }
            }
        }
예제 #2
0
        private bool loadFile(string path)
        {
            Assimp.AssimpContext importer = new Assimp.AssimpContext();
            importer.SetConfig(new NormalSmoothingAngleConfig(66f));
            //TODO check which other post processes we need
            m_scene = importer.ImportFile(path,
                                          Assimp.PostProcessSteps.CalculateTangentSpace
                                          | Assimp.PostProcessSteps.GenerateNormals
                                          | Assimp.PostProcessSteps.Triangulate
                                          | Assimp.PostProcessSteps.JoinIdenticalVertices
                                          | Assimp.PostProcessSteps.OptimizeMeshes);

            //failed loading :(
            if (!m_scene.HasMeshes)
            {
                textBoxInfo.Text = "No Valid Meshes found.";
                return(false);
            }

            //display some info
            string msg = "Mesh Count: " + m_scene.MeshCount.ToString()
                         + Environment.NewLine + "Material count: " + m_scene.MaterialCount.ToString()
                         + " (Maximum material count is 32)";

            textBoxInfo.Text = msg;

            buttonSave.Enabled = (m_scene.MeshCount > 0 && m_scene.MaterialCount <= maxMaterials);

            return(true);
        }
예제 #3
0
        private void exportToAssimp(object sender, EventArgs e)
        {
            Debug.WriteLine("Exporting to assimp");

            if (RenderState.rootObject != null)
            {
                Assimp.AssimpContext ctx = new Assimp.AssimpContext();

                Dictionary <int, int> meshImportStatus = new Dictionary <int, int>();
                Assimp.Scene          aScene           = new Assimp.Scene();
                Assimp.Node           rootNode         = RenderState.rootObject.assimpExport(ref aScene, ref meshImportStatus);
                aScene.RootNode = rootNode;

                //add a single material for now
                Assimp.Material aMat = new Assimp.Material();
                aMat.Name = "testMaterial";
                aScene.Materials.Add(aMat);

                Assimp.ExportFormatDescription[] supported_formats = ctx.GetSupportedExportFormats();
                //Assimp.Scene blenderScene = ctx.ImportFile("SimpleSkin.gltf");
                //ctx.ExportFile(blenderScene, "SimpleSkin.glb", "glb2");
                try
                {
                    ctx.ExportFile(aScene, "test.glb", "glb2");
                    //ctx.ExportFile(aScene, "test.fbx", "fbx");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
예제 #4
0
        private LoadedModel LoadModelOfd()
        {
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (ofd.CheckFileExists)
                {
                    string dirName = Path.GetDirectoryName(ofd.FileName);
                    try
                    {
                        using (Assimp.AssimpContext importer = new Assimp.AssimpContext())
                        {
                            importer.SetConfig(new NormalSmoothingAngleConfig(66.0f));
                            Assimp.Scene model       = importer.ImportFile(ofd.FileName, Assimp.PostProcessPreset.TargetRealTimeMaximumQuality);
                            LoadedModel  loadedModel = new LoadedModel(model, dirName);
                            loadedModel.Name = Path.GetFileName(ofd.FileName);
                            return(loadedModel);
                        }
                    }
                    catch
                    {
                        System.Windows.MessageBox.Show("Unsupported file type.", "Error");
                    }
                }
            }
            return(null);
        }
예제 #5
0
        public void ImportModel(string filePath, bool legacyImport = false)
        {
            NJS_OBJECT newmodel;

            // Old OBJ import (with vcolor face) for NodeTable and legacy import
            if (legacyImport)
            {
                newmodel = new NJS_OBJECT
                {
                    Attach = SAModel.Direct3D.Extensions.obj2nj(filePath, LevelData.TextureBitmaps != null ? LevelData.TextureBitmaps[LevelData.leveltexs].Select(a => a.Name).ToArray() : null),
                };
                COL.Model.Attach = newmodel.Attach;
                COL.Model.ProcessVertexData();
                Visible = true;
                Solid   = true;
                mesh    = COL.Model.Attach.CreateD3DMesh();
                return;
            }
            Assimp.AssimpContext context = new Assimp.AssimpContext();
            context.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
            Assimp.Scene scene = context.ImportFile(filePath, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.FlipUVs);
            newmodel         = SAEditorCommon.Import.AssimpStuff.AssimpImport(scene, scene.RootNode, ModelFormat.BasicDX, LevelData.TextureBitmaps[LevelData.leveltexs].Select(a => a.Name).ToArray(), true);
            COL.Model.Attach = newmodel.Attach;
            COL.Model.ProcessVertexData();
            Visible = true;
            Solid   = true;
            mesh    = COL.Model.Attach.CreateD3DMesh();
        }
예제 #6
0
        private void OnSetFileAssociations(object sender, EventArgs e)
        {
            using (var imp = new Assimp.AssimpContext())
            {
                var list = imp.GetSupportedImportFormats();

                // do not associate .xml - it is too generic
                var filteredList = list.Where(s => s != ".xml").ToArray();

                var listString = string.Join(", ", filteredList);
                if (DialogResult.OK == MessageBox.Show(this, "The following file extensions will be associated with open3mod: " + listString,
                                                       "Set file associations",
                                                       MessageBoxButtons.OKCancel))
                {
                    if (!FileAssociations.SetAssociations(list))
                    {
                        MessageBox.Show(this, "Failed to set file extensions", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
                        MessageBox.Show(this, "File extensions have been successfully associated", "open3mod", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
        }
예제 #7
0
 protected override void OnLoad(EventArgs e)
 {
     base.OnLoad(e);
     AssimpContext = new Assimp.AssimpContext();
     RebuildSurfaceList();
     UpdateSurfaceComboBox();
     //FillModelsGridView();
     HasInitialized = true;
 }
예제 #8
0
        static Assimp.Scene LoadAssimpScene(string fileName)
        {
            Assimp.AssimpContext cont = new Assimp.AssimpContext();

            // AssImp adds dummy nodes for pivots from FBX, so we'll force them off
            cont.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
            cont.ZAxisRotation = -90.0f;
            return(cont.ImportFile(fileName, Assimp.PostProcessSteps.Triangulate));
        }
예제 #9
0
        public void Load()
        {
            BoneAnimations = new List <BoneAnimation>();

            var importer = new Assimp.AssimpContext();
            var aScene   = importer.ImportFile(FilePath, Assimp.PostProcessPreset.TargetRealTimeMaximumQuality);

            RootBoneAnimation = LoadBoneAnimation(aScene, aScene.RootNode, null);
        }
예제 #10
0
        public DeviceModelCollection LoadModel(string filePath)
        {
            var context = new Assimp.AssimpContext();

            var pp    = Assimp.PostProcessSteps.FindInvalidData | Assimp.PostProcessSteps.OptimizeGraph;
            var scene = context.ImportFile(filePath, pp);

            return(ReadModel(scene));
        }
예제 #11
0
        public static Assimp.Scene GetResourceModel(string resourceName, string format)
        {
            if (AssimpContext == null)
            {
                AssimpContext = new Assimp.AssimpContext();
            }
            var stream = GetResourceStream(resourceName);

            return(AssimpContext.ImportFileFromStream(stream, format));
        }
예제 #12
0
 public void SetUp()
 {
     var assimpNetimporter = new Assimp.AssimpContext();
     Assimp.LogStream.IsVerboseLoggingEnabled = true;
     var logger = new Assimp.ConsoleLogStream();
     logger.Attach();
     assimpNetScene = assimpNetimporter.ImportFile(filename);
     logger.Detach();
     var assimpSharpImporter = new AssimpSharp.FBX.FBXImporter();
     assimpSharpScene = new AssimpSharp.Scene();
     assimpSharpScene = assimpSharpImporter.ReadFile(filename);
 }
예제 #13
0
        public static void SaveToCollada(RwAnimationNode animation, RwFrameListNode frameList, string path)
        {
            var aiScene = ToAssimpScene(animation, frameList);

            using (var aiContext = new Assimp.AssimpContext())
            {
                if (!aiContext.ExportFile(aiScene, path, "collada"))
                {
                    throw new Exception("Failed to export");
                }
            }
        }
예제 #14
0
파일: Program.cs 프로젝트: thamstras/OpenKh
        public static MeshGroup FromFbx(string filePath)
        {
            const float Scale        = 1.0f;
            var         assimp       = new Assimp.AssimpContext();
            var         scene        = assimp.ImportFile(filePath, Assimp.PostProcessSteps.PreTransformVertices);
            var         baseFilePath = Path.GetDirectoryName(filePath);

            TexList     = new List <string>();
            TextureData = new List <Tm2>();

            foreach (Assimp.Material mat in scene.Materials)
            {
                TexList.Add(Path.GetFileName(mat.TextureDiffuse.FilePath));
                Stream str = File.OpenRead(TexList[TexList.Count - 1]);

                PngImage png     = new PngImage(str);
                Tm2      tmImage = Tm2.Create(png);
                TextureData.Add(tmImage);
            }

            int childCount = scene.RootNode.ChildCount;

            return(new MeshGroup()
            {
                MeshDescriptors = scene.Meshes
                                  .Select(x =>
                {
                    var vertices = new PositionColoredTextured[x.Vertices.Count];
                    for (var i = 0; i < vertices.Length; i++)
                    {
                        vertices[i].X = x.Vertices[i].X * Scale;
                        vertices[i].Y = x.Vertices[i].Y * Scale;
                        vertices[i].Z = x.Vertices[i].Z * Scale;
                        vertices[i].Tu = x.TextureCoordinateChannels[0][i].X;
                        vertices[i].Tv = 1.0f - x.TextureCoordinateChannels[0][i].Y;
                        vertices[i].R = 1.0f;
                        vertices[i].G = 1.0f;
                        vertices[i].B = 1.0f;
                        vertices[i].A = 1.0f;
                    }

                    return new MeshDescriptor
                    {
                        Vertices = vertices,
                        Indices = x.GetIndices(),
                        IsOpaque = true,
                        TextureIndex = x.MaterialIndex
                    };
                }).ToList()
            });
        }
예제 #15
0
        public static void AssimpPRMConvert(string initialFilePath, string finalFilePath)
        {
            Assimp.AssimpContext context = new Assimp.AssimpContext();
            context.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
            Assimp.Scene aiScene = context.ImportFile(initialFilePath, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.FlipUVs);

            PRMModel prm = new PRMModel();

            int totalVerts = 0;

            //Iterate through and combine meshes. PRMs can only have a single mesh
            IterateAiNodesPRM(prm, ref totalVerts, aiScene, aiScene.RootNode, Matrix4x4.Transpose(GetMat4FromAssimpMat4(aiScene.RootNode.Transform)));
            AquaUtil.WritePRMToFile(prm, finalFilePath, 4);
        }
예제 #16
0
 public static Assimp.Scene ImportScene(string path, bool allowWeights)
 {
     using (var aiContext = new Assimp.AssimpContext())
     {
         aiContext.SetConfig(new Assimp.Configs.VertexBoneWeightLimitConfig(allowWeights ? 3 : 1));
         aiContext.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
         return(aiContext.ImportFile(path,
                                     Assimp.PostProcessSteps.FindDegenerates | Assimp.PostProcessSteps.FindInvalidData |
                                     Assimp.PostProcessSteps.FlipUVs | Assimp.PostProcessSteps.ImproveCacheLocality |
                                     Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.LimitBoneWeights |
                                     Assimp.PostProcessSteps.SplitByBoneCount | Assimp.PostProcessSteps.Triangulate |
                                     Assimp.PostProcessSteps.ValidateDataStructure | Assimp.PostProcessSteps.GenerateUVCoords));
     }
 }
예제 #17
0
        public void ExportModel()
        {
            using (System.Windows.Forms.SaveFileDialog a = new System.Windows.Forms.SaveFileDialog
            {
                DefaultExt = "dae",
                Filter = "SAModel Files|*.sa1mdl|Collada|*.dae|Wavefront|*.obj"
            })
            {
                if (a.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    string ftype = "collada";
                    switch (System.IO.Path.GetExtension(a.FileName).ToLowerInvariant())
                    {
                    case ".sa1mdl":
                        ModelFile.CreateFile(a.FileName, COL.Model, null, null, null, null, COL.Model.GetModelFormat());
                        return;

                    case ".fbx":
                        ftype = "fbx";
                        break;

                    case ".obj":
                        ftype = "obj";
                        break;
                    }
                    Assimp.AssimpContext context = new Assimp.AssimpContext();
                    Assimp.Scene         scene   = new Assimp.Scene();
                    scene.Materials.Add(new Assimp.Material());
                    Assimp.Node n = new Assimp.Node();
                    n.Name         = "RootNode";
                    scene.RootNode = n;
                    string        rootPath     = System.IO.Path.GetDirectoryName(a.FileName);
                    List <string> texturePaths = new List <string>();
                    int           numSteps     = 0;
                    if (LevelData.TextureBitmaps != null && LevelData.TextureBitmaps.Count > 0)
                    {
                        numSteps = LevelData.TextureBitmaps[LevelData.leveltexs].Length;
                    }
                    for (int i = 0; i < numSteps; i++)
                    {
                        BMPInfo bmp = LevelData.TextureBitmaps[LevelData.leveltexs][i];
                        texturePaths.Add(System.IO.Path.Combine(rootPath, bmp.Name + ".png"));
                        bmp.Image.Save(System.IO.Path.Combine(rootPath, bmp.Name + ".png"));
                    }
                    SAEditorCommon.Import.AssimpStuff.AssimpExport(COL.Model, scene, Matrix.Identity, texturePaths.Count > 0 ? texturePaths.ToArray() : null, scene.RootNode);
                    context.ExportFile(scene, a.FileName, ftype, Assimp.PostProcessSteps.ValidateDataStructure | Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.FlipUVs);                    //
                }
            }
        }
예제 #18
0
 public override Assimp.Scene Import(string filename, ContentImporterContext context)
 {
     if (dllLoadExc != null)
     {
         context.RaiseBuildMessage("FBXIMPORT", dllLoadExc.Message, BuildMessageEventArgs.BuildMessageType.Error);
     }
     try
     {
         Assimp.AssimpContext c = new Assimp.AssimpContext();
         return(c.ImportFile(filename, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.OptimizeMeshes | Assimp.PostProcessSteps.OptimizeGraph));
     }
     catch (Exception ex)
     {
         context.RaiseBuildMessage(filename, ex.Message, BuildMessageEventArgs.BuildMessageType.Error);
     }
     return(null);
 }
        internal static Engine_MeshInfo LoadFilePro(string _fileName)
        {
            var a = new Assimp.AssimpContext();
            var s = a.ImportFile(_fileName);

            Engine_MeshInfo obj = new Engine_MeshInfo();

            obj.vertices = new List <Engine_Vertex>();
            obj.indices  = new List <ushort>();
            foreach (var mesh in s.Meshes)
            {
                for (int i = 0; i < mesh.VertexCount; i++)
                {
                    obj.vertices.Add(new Engine_Vertex(
                                         mesh.Vertices[i].X,
                                         mesh.Vertices[i].Y,
                                         mesh.Vertices[i].Z,
                                         mesh.TextureCoordinateChannels[0][i].X,
                                         mesh.TextureCoordinateChannels[0][i].Y,
                                         mesh.Normals[i].X,
                                         mesh.Normals[i].Y,
                                         mesh.Normals[i].Z));
                }

                foreach (var item in mesh.Faces)
                {
                    var rangeIndices = new ushort[] {
                        (ushort)(item.Indices[0]),
                        (ushort)(item.Indices[1]),
                        (ushort)(item.Indices[2])
                    };
                    obj.indices.AddRange(rangeIndices);
                    if (item.IndexCount == 4)
                    {
                        rangeIndices = new ushort[] {
                            (ushort)(item.Indices[0]),
                            (ushort)(item.Indices[2]),
                            (ushort)(item.Indices[3])
                        };
                        obj.indices.AddRange(rangeIndices);
                    }
                }
            }

            return(obj);
        }
예제 #20
0
        public static MeshGroup FromFbx(GraphicsDevice graphics, string filePath)
        {
            const float Scale        = 96.0f;
            var         assimp       = new Assimp.AssimpContext();
            var         scene        = assimp.ImportFile(filePath, Assimp.PostProcessSteps.PreTransformVertices);
            var         baseFilePath = Path.GetDirectoryName(filePath);

            return(new MeshGroup()
            {
                MeshDescriptors = scene.Meshes
                                  .Select(x =>
                {
                    var vertices = new PositionColoredTextured[x.Vertices.Count];
                    for (var i = 0; i < vertices.Length; i++)
                    {
                        vertices[i].X = x.Vertices[i].X * Scale;
                        vertices[i].Y = x.Vertices[i].Y * Scale;
                        vertices[i].Z = x.Vertices[i].Z * Scale;
                        vertices[i].Tu = x.TextureCoordinateChannels[0][i].X;
                        vertices[i].Tv = 1.0f - x.TextureCoordinateChannels[0][i].Y;
                        vertices[i].R = 0xFF;
                        vertices[i].G = 0xFF;
                        vertices[i].B = 0xFF;
                        vertices[i].A = 0xFF;
                    }

                    return new MeshDescriptor
                    {
                        Vertices = vertices,
                        Indices = x.Faces.SelectMany(f => f.Indices).ToArray(),
                        IsOpaque = true,
                        TextureIndex = x.MaterialIndex
                    };
                }).ToList(),
                Textures = scene.Materials.Select(x =>
                {
                    var path = Path.Join(baseFilePath, $"{x.Name}.png");
                    return new PngKingdomTexture(path, graphics);
                }).ToArray(),
            });
        }
예제 #21
0
        private void ASSIMPExportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog a = new SaveFileDialog
            {
                DefaultExt = "dae",
                Filter = "Model Files|*.obj;*.fbx;*.dae",
                FileName = "test"
            })
            {
                if (a.ShowDialog() == DialogResult.OK)
                {
                    Assimp.AssimpContext context = new Assimp.AssimpContext();
                    Assimp.Scene         scene   = new Assimp.Scene();
                    scene.Materials.Add(new Assimp.Material());
                    Assimp.Node n = new Assimp.Node();
                    n.Name         = "RootNode";
                    scene.RootNode = n;
                    string        rootPath     = Path.GetDirectoryName(a.FileName);
                    List <string> texturePaths = new List <string>();

                    if (LevelData.TextureBitmaps != null)
                    {
                        foreach (BMPInfo[] bmp_ in LevelData.TextureBitmaps.Values)                         //???????
                        {
                            foreach (BMPInfo bmp in bmp_)
                            {
                                texturePaths.Add(Path.Combine(rootPath, bmp.Name + ".png"));
                                bmp.Image.Save(Path.Combine(rootPath, bmp.Name + ".png"));
                            }
                        }
                    }

                    foreach (COL col in LevelData.geo.COL)
                    {
                        SAEditorCommon.Import.AssimpStuff.AssimpExport(col.Model, scene, Matrix.Identity, texturePaths.Count > 0 ? texturePaths.ToArray() : null, scene.RootNode);
                    }

                    context.ExportFile(scene, a.FileName, "collada", Assimp.PostProcessSteps.ValidateDataStructure | Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.FlipUVs);                    //
                }
            }
        }
예제 #22
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (!LDDEnvironment.HasInitialized)
            {
                LDDEnvironment.Initialize();
            }

            AssimpContext = new Assimp.AssimpContext();

            bool isProjectOpen = (CurrentProject != null);

            CurrentProjectRb.Enabled = isProjectOpen;
            (isProjectOpen ? CurrentProjectRb : SelectPartRb).Checked = true;
            PartBrowseTextBox.Enabled = SelectPartRb.Checked;

            if (SelectPartRb.Checked)
            {
                ValidateSelectedPartID();
            }
        }
예제 #23
0
        public static void WriteModelFile(IGeometryModel model, string fileName, string formatId)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

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

            formatId = (formatId ?? Settings.DefaultSaveFormat).ToLower();
            if (!ExportFormats.Any(f => f.FormatId == formatId))
            {
                throw new ArgumentException($"{formatId} is not a supported format.", nameof(formatId));
            }

            var ext = "." + GetFormatExtension(formatId);

            if (!fileName.EndsWith(ext, StringComparison.OrdinalIgnoreCase))
            {
                fileName += ext;
            }

            var format = ExportFormats.First(f => f.FormatId == formatId);

            if (format.ExportFunction != null)
            {
                format.ExportFunction(model, fileName);
            }
            else
            {
                using (var context = new Assimp.AssimpContext())
                {
                    var scene = model.CreateAssimpScene(context, formatId);
                    context.ExportFile(scene, fileName, formatId);
                }
            }
        }
예제 #24
0
파일: AssimpIO.cs 프로젝트: ubisoft/vrtist
        private async Task <Assimp.Scene> ImportAssimpFile(string fileName)
        {
            Assimp.Scene aScene = null;
            await Task <Assimp.Scene> .Run(() =>
            {
                try
                {
                    Assimp.AssimpContext ctx = new Assimp.AssimpContext();
                    aScene = ctx.ImportFile(fileName,
                                            Assimp.PostProcessSteps.Triangulate |
                                            Assimp.PostProcessSteps.GenerateNormals |
                                            Assimp.PostProcessSteps.GenerateUVCoords);
                }
                catch (Assimp.AssimpException e)
                {
                    Debug.LogError(e.Message);
                    aScene = null;
                }
            });

            return(aScene);
        }
예제 #25
0
파일: AssimpIO.cs 프로젝트: ubisoft/vrtist
 public void Import(string fileName, Transform root, bool synchronous = false)
 {
     blocking = synchronous;
     if (synchronous)
     {
         Assimp.AssimpContext ctx = new Assimp.AssimpContext();
         var aScene = ctx.ImportFile(fileName,
                                     Assimp.PostProcessSteps.Triangulate |
                                     Assimp.PostProcessSteps.GenerateNormals |
                                     Assimp.PostProcessSteps.GenerateUVCoords);
         CreateUnityDataFromAssimp(fileName, aScene, root).MoveNext();
         Clear();
         progress = 1.0f;
     }
     else
     {
         unityDataInCoroutineCreated = false;
         ImportTaskData d = new ImportTaskData();
         d.fileName = fileName;
         d.root     = root;
         taskData.Add(d);
     }
 }
예제 #26
0
        public void ExportModel()
        {
            using (System.Windows.Forms.SaveFileDialog a = new System.Windows.Forms.SaveFileDialog
            {
                DefaultExt = "dae",
                Filter = "SAModel Files|*.sa1mdl|Collada|*.dae|Wavefront|*.obj"
            })
            {
                if (a.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    string ftype = "collada";
                    switch (System.IO.Path.GetExtension(a.FileName).ToLowerInvariant())
                    {
                    case ".sa1mdl":
                        ModelFile.CreateFile(a.FileName, Model, null, null, null, null, Model.GetModelFormat());
                        return;

                    case ".fbx":
                        ftype = "fbx";
                        break;

                    case ".obj":
                        ftype = "obj";
                        break;
                    }
                    Assimp.AssimpContext context = new Assimp.AssimpContext();
                    Assimp.Scene         scene   = new Assimp.Scene();
                    scene.Materials.Add(new Assimp.Material());
                    Assimp.Node n = new Assimp.Node();
                    n.Name         = "RootNode";
                    scene.RootNode = n;
                    string rootPath = System.IO.Path.GetDirectoryName(a.FileName);
                    SAEditorCommon.Import.AssimpStuff.AssimpExport(Model, scene, Matrix.Identity, null, scene.RootNode);
                    context.ExportFile(scene, a.FileName, ftype, Assimp.PostProcessSteps.ValidateDataStructure | Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.FlipUVs);                    //
                }
            }
        }
예제 #27
0
        public static UnityEngine.Mesh ToUnityMesh(File file)
        {
            if (file.FileType != File.Type.Model)
            {
                return(null);
            }

            Assimp.AssimpContext ctx = new Assimp.AssimpContext();
            Assimp.Scene         s   = ctx.ImportFileFromStream(file.StreamData, Assimp.PostProcessSteps.Triangulate);
            if (!s.HasMeshes)
            {
                return(null);
            }
            var mesh = s.Meshes[0];

            var newMesh = new UnityEngine.Mesh();

            newMesh.vertices = mesh.Vertices.ConvertAll(v => v.ToV3()).ToArray();

            //int[] indicies = mesh.GetIndices();

            List <int> indicies = new List <int>();

            foreach (var face in mesh.Faces)
            {
                indicies.AddRange(face.Indices);
            }

            newMesh.triangles = indicies.ToArray();

            for (int i = 0; i < mesh.TextureCoordinateChannelCount; ++i)
            {
                newMesh.SetUVs(i, mesh.TextureCoordinateChannels[i].ConvertAll(v => v.ToV2()));
            }
            return(newMesh);
        }
예제 #28
0
        private void ConvertModelIntoMapModel(string modelFile, MapGenConfig config)
        {
            logger.Debug($"Loading 3D model file \"{modelFile}\" using Assimp.");

            var assimp = new Assimp.AssimpContext();
            var scene  = assimp.ImportFile(modelFile, Assimp.PostProcessSteps.PreTransformVertices);

            bigMeshContainer = new BigMeshContainer();

            var scale = config.scale;

            Matrix4x4 matrix = Matrix4x4.Identity;

            if (config.applyMatrix != null)
            {
                var m = config.applyMatrix;

                if (m.Length == 16)
                {
                    matrix = new Matrix4x4(
                        m[0], m[1], m[2], m[3],
                        m[4], m[5], m[6], m[7],
                        m[8], m[9], m[10], m[11],
                        m[12], m[13], m[14], m[15]
                        );

                    logger.Debug($"Apply matrix: {matrix}");
                }
            }
            else
            {
                matrix *= scale;
            }

            logger.Debug($"Starting triangle strip conversion for {scene.Meshes.Count} meshes.");

            foreach (var inputMesh in scene.Meshes)
            {
                logger.Debug($"Mesh: {inputMesh.Name} ({inputMesh.FaceCount:#,##0} faces, {inputMesh.VertexCount:#,##0} vertices)");

                var modelMat = scene.Materials[inputMesh.MaterialIndex];

                var matDef = config.FindMaterial(modelMat.Name ?? "default") ?? MaterialDef.CreateFallbackFor(modelMat.Name);
                if (matDef.ignore)
                {
                    logger.Info($"This mesh \"{inputMesh.Name}\" is not rendered due to ignore flag of material \"{modelMat.Name}\".");
                    continue;
                }

                var kh2Mesh = bigMeshContainer.AllocateBigMeshForMaterial(matDef);

                var diffuseTextureFile = modelMat.TextureDiffuse.FilePath;
                if (!string.IsNullOrEmpty(diffuseTextureFile))
                {
                    if (config.reuseImd)
                    {
                        logger.Debug($"The mesh \"{inputMesh.Name}\" material \"{matDef.name}\" has filepath \"{diffuseTextureFile}\" for diffuse texture. It will be associated with material's fromFile3. Setting preferable imd file to fromFile2 due to reuseImd flag.");

                        matDef.fromFile2 = Path.ChangeExtension(diffuseTextureFile, ".imd");
                        matDef.fromFile3 = diffuseTextureFile;
                    }
                    else
                    {
                        logger.Debug($"The mesh \"{inputMesh.Name}\" material \"{matDef.name}\" has filepath \"{diffuseTextureFile}\" for diffuse texture. It will be associated with material's fromFile2.");

                        matDef.fromFile3 = diffuseTextureFile;
                    }
                }

                var kh2BaseVert = kh2Mesh.vertexList.Count;

                List <int> vertexToLocal = new List <int>();

                foreach (var inputVertex in inputMesh.Vertices)
                {
                    var vertex = Vector3.Transform(
                        new Vector3(inputVertex.X, inputVertex.Y, inputVertex.Z),
                        matrix
                        );

                    var index = kh2Mesh.vertexList.IndexOf(vertex);
                    if (index < 0)
                    {
                        index = kh2Mesh.vertexList.Count;
                        kh2Mesh.vertexList.Add(vertex);
                    }

                    vertexToLocal.Add(index);
                }

                var localFaces = inputMesh.Faces
                                 .Select(
                    set => set.Indices
                    .Select(index => new VertPair {
                    uvColorIndex = index, vertexIndex = vertexToLocal[index]
                })
                    .ToArray()
                    )
                                 .ToArray();

                var inputTexCoords       = inputMesh.TextureCoordinateChannels.First();
                var inputVertexColorList = inputMesh.VertexColorChannels.First();

                var hasVertexColor = inputMesh.VertexColorChannelCount >= 1;

                var maxIntensity = matDef.maxColorIntensity
                                   ?? config.maxColorIntensity
                                   ?? 128;
                var maxAlpha = matDef.maxAlpha
                               ?? config.maxAlpha
                               ?? 128;

                var triConverter =
                    config.disableTriangleStripsOptimization
                    ? (TriangleFansToTriangleStripsConverter)TriangleFansToTriangleStripsNoOpts
                    : (TriangleFansToTriangleStripsConverter)TriangleFansToTriangleStripsOptimized;

                foreach (var triStripInput in triConverter(localFaces))
                {
                    var triStripOut = new BigMesh.TriangleStrip();

                    foreach (var vertPair in triStripInput)
                    {
                        triStripOut.vertexIndices.Add(kh2BaseVert + vertPair.vertexIndex);

                        triStripOut.uvList.Add(Get2DCoord(inputTexCoords[vertPair.uvColorIndex]));

                        if (hasVertexColor)
                        {
                            triStripOut.vertexColorList.Add(ConvertVertexColor(inputVertexColorList[vertPair.uvColorIndex], maxIntensity, maxAlpha));
                        }
                        else
                        {
                            triStripOut.vertexColorList.Add(new Color(maxIntensity, maxIntensity, maxIntensity, maxAlpha));
                        }
                    }

                    kh2Mesh.triangleStripList.Add(triStripOut);
                }

                logger.Debug($"Output: {kh2Mesh.vertexList.Count:#,##0} vertices, {kh2Mesh.triangleStripList.Count:#,##0} triangle strips.");
            }

            logger.Debug($"The conversion has done.");

            logger.Debug($"Starting mesh splitter and vif packets builder.");

            mapModel = new Mdlx.M4
            {
                VifPackets = new List <Mdlx.VifPacketDescriptor>(),
            };

            foreach (var bigMesh in bigMeshContainer.MeshList
                     .Where(it => it.textureIndex != -1)
                     )
            {
                foreach (var smallMesh in BigMeshSplitter.Split(bigMesh))
                {
                    var dmaPack = new MapVifPacketBuilder(smallMesh);

                    smallMeshList.Add(smallMesh);

                    bigMesh.vifPacketIndices.Add(Convert.ToUInt16(mapModel.VifPackets.Count));
                    smallMesh.vifPacketIndices.Add(Convert.ToUInt16(mapModel.VifPackets.Count));

                    mapModel.VifPackets.Add(
                        new Mdlx.VifPacketDescriptor
                    {
                        VifPacket = dmaPack.vifPacket.ToArray(),
                        TextureId = smallMesh.textureIndex,
                        DmaPerVif = new ushort[] {
                            dmaPack.firstVifPacketQwc,
                            0,
                        },
                        IsTransparentFlag = smallMesh.matDef.transparentFlag ?? 0,
                    }
                        );
                }
            }

            logger.Debug($"Output: {mapModel.VifPackets.Count:#,##0} vif packets.");

            logger.Debug($"The builder has done.");

            logger.Debug($"Starting vifPacketRenderingGroup builder.");

            // first group: render all

            mapModel.vifPacketRenderingGroup = new List <ushort[]>(
                new ushort[][] {
                Enumerable.Range(0, mapModel.VifPackets.Count)
                .Select(it => Convert.ToUInt16(it))
                .ToArray()
            }
                );

            logger.Debug($"Output: {mapModel.vifPacketRenderingGroup.Count:#,##0} groups.");

            mapModel.DmaChainIndexRemapTable = new List <ushort>(
                Enumerable.Range(0, mapModel.VifPackets.Count)
                .Select(it => Convert.ToUInt16(it))
                .ToArray()
                );
        }
예제 #29
0
 void LoadAssimpNetScene(string file)
 {
     var importer = new Assimp.AssimpContext();
     var assimpNetScene = importer.ImportFile(file);
 }
예제 #30
0
        public static Assimp.Scene CreateAssimpScene(this IGeometryModel model, Assimp.AssimpContext context, string formatId)
        {
            var scale = ModelViewerPlugin.Settings.GeometryScale;

            //either Assimp or collada has issues when there is a name conflict
            const string bonePrefix = "~";
            const string geomPrefix = "-";
            const string scenPrefix = "$";

            var scene = new Assimp.Scene();

            scene.RootNode = new Assimp.Node($"{scenPrefix}{model.Name}");

            //Assimp is Y-up in inches by default - this forces it to export as Z-up in meters
            scene.RootNode.Transform = (CoordinateSystem.HaloCEX * ModelViewerPlugin.Settings.AssimpScale).ToAssimp4x4();

            #region Nodes
            var allNodes = new List <Assimp.Node>();
            foreach (var node in model.Nodes)
            {
                var result = new Assimp.Node($"{bonePrefix}{node.Name}");

                var q   = new System.Numerics.Quaternion(node.Rotation.X, node.Rotation.Y, node.Rotation.Z, node.Rotation.W);
                var mat = System.Numerics.Matrix4x4.CreateFromQuaternion(q);
                mat.Translation  = new System.Numerics.Vector3(node.Position.X * scale, node.Position.Y * scale, node.Position.Z * scale);
                result.Transform = mat.ToAssimp4x4();

                allNodes.Add(result);
            }

            for (int i = 0; i < model.Nodes.Count; i++)
            {
                var node = model.Nodes[i];
                if (node.ParentIndex >= 0)
                {
                    allNodes[node.ParentIndex].Children.Add(allNodes[i]);
                }
                else
                {
                    scene.RootNode.Children.Add(allNodes[i]);
                }
            }
            #endregion

            var meshLookup = new List <int>();

            #region Meshes
            for (int i = 0; i < model.Meshes.Count; i++)
            {
                var geom = model.Meshes[i];
                if (geom.Submeshes.Count == 0)
                {
                    meshLookup.Add(-1);
                    continue;
                }

                meshLookup.Add(scene.MeshCount);

                foreach (var sub in geom.Submeshes)
                {
                    var m = new Assimp.Mesh($"mesh{i:D3}");

                    var indices = geom.Indicies.Skip(sub.IndexStart).Take(sub.IndexLength);

                    var minIndex  = indices.Min();
                    var maxIndex  = indices.Max();
                    var vertCount = maxIndex - minIndex + 1;

                    if (geom.IndexFormat == IndexFormat.TriangleStrip)
                    {
                        indices = indices.Unstrip();
                    }

                    indices = indices.Select(x => x - minIndex);
                    var vertices = geom.Vertices.Skip(minIndex).Take(vertCount);

                    if (geom.BoundsIndex >= 0)
                    {
                        vertices = vertices.Select(v => (IVertex) new CompressedVertex(v, model.Bounds[geom.BoundsIndex.Value]));
                    }

                    int vIndex     = -1;
                    var boneLookup = new Dictionary <int, Assimp.Bone>();
                    foreach (var v in vertices)
                    {
                        vIndex++;

                        if (v.Position.Count > 0)
                        {
                            m.Vertices.Add(v.Position[0].ToAssimp3D(scale));

                            //some Halo shaders use position W as the colour alpha - add it to a colour channel to preserve it
                            //also assimp appears to have issues exporting obj when a colour channel exists so only do this for collada
                            if (formatId == "collada" && v.Color.Count == 0 && !float.IsNaN(v.Position[0].W))
                            {
                                m.VertexColorChannels[0].Add(new Assimp.Color4D {
                                    R = v.Position[0].W
                                });
                            }
                        }

                        if (v.Normal.Count > 0)
                        {
                            m.Normals.Add(v.Normal[0].ToAssimp3D());
                        }

                        if (v.TexCoords.Count > 0)
                        {
                            m.TextureCoordinateChannels[0].Add(v.TexCoords[0].ToAssimpUV());
                        }

                        if (geom.VertexWeights == VertexWeights.None && !geom.NodeIndex.HasValue)
                        {
                            continue;
                        }

                        #region Vertex Weights
                        var weights = new List <Tuple <int, float> >(4);

                        if (geom.NodeIndex.HasValue)
                        {
                            weights.Add(Tuple.Create <int, float>(geom.NodeIndex.Value, 1));
                        }
                        else if (geom.VertexWeights == VertexWeights.Skinned)
                        {
                            var ind = v.BlendIndices[0];
                            var wt  = v.BlendWeight[0];

                            if (wt.X > 0)
                            {
                                weights.Add(Tuple.Create((int)ind.X, wt.X));
                            }
                            if (wt.Y > 0)
                            {
                                weights.Add(Tuple.Create((int)ind.Y, wt.Y));
                            }
                            if (wt.Z > 0)
                            {
                                weights.Add(Tuple.Create((int)ind.Z, wt.Z));
                            }
                            if (wt.W > 0)
                            {
                                weights.Add(Tuple.Create((int)ind.W, wt.W));
                            }
                        }

                        foreach (var val in weights)
                        {
                            Assimp.Bone b;
                            if (boneLookup.ContainsKey(val.Item1))
                            {
                                b = boneLookup[val.Item1];
                            }
                            else
                            {
                                var t = model.Nodes[val.Item1].OffsetTransform;
                                t.M41 *= scale;
                                t.M42 *= scale;
                                t.M43 *= scale;

                                b = new Assimp.Bone
                                {
                                    Name         = bonePrefix + model.Nodes[val.Item1].Name,
                                    OffsetMatrix = t.ToAssimp4x4()
                                };

                                m.Bones.Add(b);
                                boneLookup.Add(val.Item1, b);
                            }

                            b.VertexWeights.Add(new Assimp.VertexWeight(vIndex, val.Item2));
                        }
                        #endregion
                    }

                    m.SetIndices(indices.ToArray(), 3);
                    m.MaterialIndex = sub.MaterialIndex;

                    scene.Meshes.Add(m);
                }
            }
            #endregion

            #region Regions
            foreach (var reg in model.Regions)
            {
                var regNode = new Assimp.Node($"{geomPrefix}{reg.Name}");
                foreach (var perm in reg.Permutations)
                {
                    var meshStart = meshLookup[perm.MeshIndex];
                    if (meshStart < 0)
                    {
                        continue;
                    }

                    var permNode = new Assimp.Node($"{geomPrefix}{perm.Name}");
                    if (perm.TransformScale != 1 || !perm.Transform.IsIdentity)
                    {
                        permNode.Transform = Assimp.Matrix4x4.FromScaling(new Assimp.Vector3D(perm.TransformScale)) * perm.Transform.ToAssimp4x4(scale);
                    }

                    var meshCount = Enumerable.Range(perm.MeshIndex, perm.MeshCount).Sum(i => model.Meshes[i].Submeshes.Count);
                    permNode.MeshIndices.AddRange(Enumerable.Range(meshStart, meshCount));

                    regNode.Children.Add(permNode);
                }

                if (regNode.ChildCount > 0)
                {
                    scene.RootNode.Children.Add(regNode);
                }
            }
            #endregion

            #region Materials
            foreach (var mat in model.Materials)
            {
                var m = new Assimp.Material {
                    Name = mat?.Name ?? "unused"
                };

                //prevent max from making every material super shiny
                m.ColorEmissive = m.ColorReflective = m.ColorSpecular = new Assimp.Color4D(0, 0, 0, 1);
                m.ColorDiffuse  = m.ColorTransparent = new Assimp.Color4D(1);

                //max only seems to care about diffuse
                var dif = mat?.Submaterials.FirstOrDefault(s => s.Usage == MaterialUsage.Diffuse);
                if (dif != null)
                {
                    var suffix   = dif.Bitmap.SubmapCount > 1 ? "[0]" : string.Empty;
                    var filePath = $"{dif.Bitmap.Name}{suffix}.{ModelViewerPlugin.Settings.MaterialExtension}";

                    //collada spec says it requires URI formatting, and Assimp doesn't do it for us
                    //for some reason "new Uri(filePath, UriKind.Relative)" doesnt change the slashes, have to use absolute uri
                    if (formatId == FormatId.Collada)
                    {
                        filePath = new Uri("X:\\", UriKind.Absolute).MakeRelativeUri(new Uri(System.IO.Path.Combine("X:\\", filePath))).ToString();
                    }

                    m.TextureDiffuse = new Assimp.TextureSlot
                    {
                        BlendFactor = 1,
                        FilePath    = filePath,
                        TextureType = Assimp.TextureType.Diffuse
                    };
                }

                scene.Materials.Add(m);
            }
            #endregion

            return(scene);
        }
예제 #31
0
        public static List <Item> ImportFromFile(string filePath, EditorCamera camera, out bool errorFlag, out string errorMsg, EditorItemSelection selectionManager, OnScreenDisplay osd, bool multiple = false)
        {
            List <Item> createdItems = new List <Item>();

            if (!File.Exists(filePath))
            {
                errorFlag = true;
                errorMsg  = "File does not exist!";
                return(null);
            }

            DirectoryInfo filePathInfo = new DirectoryInfo(filePath);

            bool    importError    = false;
            string  importErrorMsg = "";
            Vector3 pos            = camera.Position + (-20 * camera.Look);

            switch (filePathInfo.Extension)
            {
            case ".sa1mdl":
                ModelFile  mf   = new ModelFile(filePath);
                NJS_OBJECT objm = mf.Model;
                osd.ClearMessageList();
                osd.AddMessage("Importing models, please wait...", 3000);
                osd.ClearMessageList();
                createdItems.AddRange(ImportFromHierarchy(objm, selectionManager, osd, multiple));
                osd.AddMessage("Stage import complete!", 100);
                break;

            case ".obj":
            case ".objf":
                LevelItem item = new LevelItem(filePath, new Vertex(pos.X, pos.Y, pos.Z), new Rotation(), levelItems.Count, selectionManager)
                {
                    Visible = true
                };

                createdItems.Add(item);
                break;

            case ".txt":
                NodeTable.ImportFromFile(filePath, out importError, out importErrorMsg, selectionManager);
                break;

            case ".dae":
            case ".fbx":
                Assimp.AssimpContext context = new Assimp.AssimpContext();
                Assimp.Configs.FBXPreservePivotsConfig conf = new Assimp.Configs.FBXPreservePivotsConfig(false);
                context.SetConfig(conf);
                Assimp.Scene scene = context.ImportFile(filePath, Assimp.PostProcessSteps.Triangulate);
                for (int i = 0; i < scene.RootNode.ChildCount; i++)
                {
                    osd.ClearMessageList();
                    osd.AddMessage("Importing model " + i.ToString() + " of " + scene.RootNode.ChildCount.ToString() + "...", 3000);
                    Assimp.Node        child  = scene.RootNode.Children[i];
                    List <Assimp.Mesh> meshes = new List <Assimp.Mesh>();
                    foreach (int j in child.MeshIndices)
                    {
                        meshes.Add(scene.Meshes[j]);
                    }
                    bool isVisible = true;
                    for (int j = 0; j < child.MeshCount; j++)
                    {
                        if (scene.Materials[meshes[j].MaterialIndex].Name.Contains("Collision"))
                        {
                            isVisible = false;
                            break;
                        }
                    }
                    ModelFormat mfmt = ModelFormat.Basic;
                    if (isVisible)
                    {
                        switch (geo.Format)
                        {
                        case LandTableFormat.SA2:
                            mfmt = ModelFormat.Chunk;
                            break;

                        case LandTableFormat.SA2B:
                            mfmt = ModelFormat.GC;
                            break;
                        }
                    }
                    NJS_OBJECT obj = AssimpStuff.AssimpImport(scene, child, mfmt, TextureBitmaps[leveltexs].Select(a => a.Name).ToArray(), !multiple);
                    {
                        //sa2 collision patch
                        if (obj.Attach.GetType() == typeof(BasicAttach))
                        {
                            BasicAttach ba = obj.Attach as BasicAttach;
                            foreach (NJS_MATERIAL mats in ba.Material)
                            {
                                mats.DoubleSided = true;
                            }
                        }
                        //cant check for transparent texture so i gotta force alpha for now, temporary
                        else if (obj.Attach.GetType() == typeof(ChunkAttach))
                        {
                            ChunkAttach ca = obj.Attach as ChunkAttach;
                            foreach (PolyChunk polys in ca.Poly)
                            {
                                if (polys.GetType() == typeof(PolyChunkMaterial))
                                {
                                    PolyChunkMaterial mat = polys as PolyChunkMaterial;
                                    mat.SourceAlpha      = AlphaInstruction.SourceAlpha;
                                    mat.DestinationAlpha = AlphaInstruction.InverseSourceAlpha;
                                }
                                else if (polys.GetType() == typeof(PolyChunkStrip))
                                {
                                    PolyChunkStrip str = polys as PolyChunkStrip;
                                    //str.UseAlpha = true;
                                }
                            }
                        }
                    }
                    obj.Attach.ProcessVertexData();
                    LevelItem newLevelItem = new LevelItem(obj.Attach, new Vertex(obj.Position.X + pos.X, obj.Position.Y + pos.Y, obj.Position.Z + pos.Z), obj.Rotation, levelItems.Count, selectionManager)
                    {
                        Visible = isVisible
                    };
                    createdItems.Add(newLevelItem);
                }
                osd.ClearMessageList();
                osd.AddMessage("Stage import complete!", 100);
                break;

            default:
                errorFlag = true;
                errorMsg  = "Invalid file format!";
                return(null);
            }

            StateChanged();

            errorFlag = importError;
            errorMsg  = importErrorMsg;

            return(createdItems);
        }
예제 #32
0
        protected unsafe override bool OnLoad(Model model, File stream)
        {
            var filePath = FileUtil.StandardlizeFile(stream.Name);

            filePath = FileUtil.GetPath(stream.Name);
            FileSystem.AddResourceDir(filePath);
            FileSystem.AddResourceDir(filePath + "textures");

            var    ctx = new Assimp.AssimpContext();
            string ext = FileUtil.GetExtension(loadingFile);

            if (!ctx.IsImportFormatSupported(ext))
            {
                ctx.Dispose();
                return(false);
            }

            //Assimp.Scene scene = ctx.ImportFileFromStream(stream, assimpFlags, ext);
            Assimp.Scene scene = ctx.ImportFile(stream.Name, assimpFlags);

            BoundingBox boundingBox = new BoundingBox();

            string path = FileUtil.GetPath(loadingFile);

            model.VertexBuffers = new List <Buffer>();
            model.IndexBuffers  = new List <Buffer>();

            vertexBuffer.Clear();
            indexBuffer.Clear();
            vertexOffset = 0;
            indexOffset  = 0;
            VertexLayout    vertexLayout = new VertexLayout(vertexComponents);
            List <Geometry> geoList      = new List <Geometry>();

            // Iterate through all meshes in the file and extract the vertex components
            for (int m = 0; m < scene.MeshCount; m++)
            {
                Assimp.Mesh mesh = scene.Meshes[m];
                if (mesh.MaterialIndex >= 0 && mesh.MaterialIndex < scene.MaterialCount)
                {
                    Material mat = ConvertMaterial(path, scene.Materials[mesh.MaterialIndex], mesh.HasTangentBasis);
                    if (mat == null)
                    {
                        continue;
                    }

                    model.Materials.Add(mat);
                }
                else
                {
                    Log.Error("No material : " + mesh.Name);
                }

                var geometry = ConvertGeometry(mesh, scale, vertexLayout, vertexComponents, combineVB, combineIB, out var meshBoundingBox);
                geoList.Add(geometry);

                if (geometry.VertexBuffer != null)
                {
                    model.VertexBuffers.Add(geometry.VertexBuffer);
                }

                if (geometry.IndexBuffer != null)
                {
                    model.IndexBuffers.Add(geometry.IndexBuffer);
                }

                model.Geometries.Add(new [] { geometry });
                model.GeometryCenters.Add(meshBoundingBox.Center);

                boundingBox.Merge(meshBoundingBox);
            }

            if (combineVB)
            {
                var vb = Buffer.Create(VkBufferUsageFlags.VertexBuffer, false, sizeof(float), vertexBuffer.Count, vertexBuffer.Data);
                model.VertexBuffers.Add(vb);

                foreach (var geo in geoList)
                {
                    geo.VertexBuffer = vb;
                }
            }

            if (combineIB)
            {
                var ib = Buffer.Create(VkBufferUsageFlags.IndexBuffer, false, sizeof(uint), indexBuffer.Count, indexBuffer.Data);
                model.IndexBuffers.Add(ib);
                foreach (var geo in geoList)
                {
                    geo.IndexBuffer = ib;
                }
            }

            model.BoundingBox = boundingBox;

            ctx.Dispose();

            FileSystem.RemoveResourceDir(filePath);
            FileSystem.RemoveResourceDir(filePath + "textures");
            return(true);
        }
예제 #33
0
        private void OnSetFileAssociations(object sender, EventArgs e)
        {
            using (var imp = new Assimp.AssimpContext())
            {
                var list = imp.GetSupportedImportFormats();

                // do not associate .xml - it is too generic 
                var filteredList = list.Where(s => s != ".xml").ToArray();           

                var listString = string.Join(", ", filteredList);
                if(DialogResult.OK == MessageBox.Show(this, "The following file extensions will be associated with open3mod: " + listString,
                    "Set file associations",
                    MessageBoxButtons.OKCancel))
                {
                    if (!FileAssociations.SetAssociations(list))
                    {
                        MessageBox.Show(this, "Failed to set file extensions","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
                    }
                    else
                    {
                        MessageBox.Show(this, "File extensions have been successfully associated", "open3mod", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
        }
예제 #34
0
        private void OnDrag(object sender, DragEventArgs e)
        {
            // code based on http://www.codeproject.com/Articles/3598/Drag-and-Drop
            try
            {
                var a = (Array)e.Data.GetData(DataFormats.FileDrop);

                if (a != null && a.GetLength(0) > 0)
                {
                    for (int i = 0, count = a.GetLength(0); i < count; ++i)
                    {
                        var s = a.GetValue(i).ToString();

                        // check if the dragged file is a folder. In this case,
                        // we load all applicable files in the folder.

                        // TODO this means, files with no proper file extension
                        // won't load this way.
                        try
                        {
                            FileAttributes attr = File.GetAttributes(s);
                            if (attr.HasFlag(FileAttributes.Directory))
                            {
                                string[] formats;
                                using (var tempImporter = new Assimp.AssimpContext())
                                {
                                    formats = tempImporter.GetSupportedImportFormats();
                                }

                                string[] files = Directory.GetFiles(s);
                                foreach (var file in files)
                                {
                                    var ext = Path.GetExtension(file);
                                    if (ext == null)
                                    {
                                        continue;
                                    }
                                    var lowerExt = ext.ToLower();
                                    if (formats.Any(format => lowerExt == format))
                                    {
                                        AddTab(file);
                                    }
                                }
                                continue;
                            }
                        }
                        // ReSharper disable EmptyGeneralCatchClause
                        catch (Exception)
                        // ReSharper restore EmptyGeneralCatchClause
                        {
                            // ignore this - AddTab() handles the failure
                        }

                        // Call OpenFile asynchronously.
                        // Explorer instance from which file is dropped is not responding
                        // all the time when DragDrop handler is active, so we need to return
                        // immediately (of particular importance if OpenFile shows MessageBox).
                        AddTab(s);
                    }

                    // in the case Explorer overlaps this form
                    Activate();
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Error in DragDrop function: " + ex.Message);
            }
        }
예제 #35
0
        public override IDisposable Load(Type resourceType, string identifier)
        {
            using (var assimpContext = new Assimp.AssimpContext())
            {
                var scene = assimpContext.ImportFile(identifier);
                var meshes = new List<Graphics.Mesh>();

                foreach (var mesh in scene.Meshes)
                {
                    var bytesPerVertex = 12;

                    if (mesh.HasNormals)
                    {
                        bytesPerVertex += 12;
                    }

                    if (mesh.HasTextureCoords(0))
                    {
                        bytesPerVertex += 8;
                    }

                    var vertexCount = mesh.VertexCount;
                    var meshSizeInBytes = vertexCount * bytesPerVertex;

                    using (var stream = new SlimDX.DataStream(meshSizeInBytes, true, true))
                    {
                        for (var i = 0; i < vertexCount; ++i)
                        {
                            stream.Write(mesh.Vertices[i]);

                            if (mesh.HasNormals)
                            {
                                stream.Write(mesh.Normals[i]);
                            }

                            if (mesh.HasTextureCoords(0))
                            {
                                stream.Write(mesh.TextureCoordinateChannels[0][i].X);
                                stream.Write(mesh.TextureCoordinateChannels[0][i].Y);
                            }
                        }

                        var vertexBuffer = new Graphics.VertexBuffer(device.Handle, stream, bytesPerVertex, vertexCount, SlimDX.Direct3D11.PrimitiveTopology.TriangleList);
                        var indices = mesh.GetIndices();

                        if (indices != null && indices.Count() > 0)
                        {
                            var indexBuffer = new Graphics.IndexBuffer(device.Handle, indices);

                            return new Graphics.Mesh(vertexBuffer, indexBuffer);
                        }

                        var result = new Graphics.Mesh(vertexBuffer);

                        if (resourceType.Equals(typeof(Graphics.Mesh)))
                        {
                            return result;
                        }
                        else
                        {
                            meshes.Add(result);
                        }
                    }
                }

                if (meshes.Count > 0)
                {
                    return new Graphics.MeshGroup(meshes);
                }
                else
                {
                    throw new KeyNotFoundException("Failed to load mesh: " + identifier);
                }
            }
        }
예제 #36
0
 private static void ImportDAEFile(ResourceWrapper res, string path)
 {
     var ctx = new Assimp.AssimpContext();
     res.WrappedObject = new RWScene(ctx.ImportFile(path));
 }
예제 #37
0
 private static void ExportOBJFile(ResourceWrapper res, string path)
 {
     var scene = (res as RWSceneWrapper).WrappedObject;
     var ctx = new Assimp.AssimpContext();
     ctx.ExportFile(RWScene.ToAssimpScene(scene), path, "obj");
 }