Exemple #1
0
    public void importmodel()
    {
        //string fileName = "F:/UNITY stuff/FlexHub/FlexHub_parts/FBX-Parts_FlexHub/Part_72.fbx";

        allnodes.Clear();
        //Create a new importer
        AssimpImporter importer = new AssimpImporter(); // create an importer instance
        //importer.SetConfig (new con)
        Scene model = importer.ImportFile(filetoImport, //import hte specified file
                                          PostProcessSteps.JoinIdenticalVertices |
                                          PostProcessSteps.FindInvalidData |
                                          PostProcessSteps.RemoveRedundantMaterials |
                                          PostProcessSteps.FixInFacingNormals
                                          );

        Debug.Log(model.RootNode.Name + "\n" + "-----------------------------"); // get the root node name

        MasterNode = model.RootNode;                                             // get the master node of the scene

        GameObject gobject = convertNodes(MasterNode);                           // call the function and pass the resulting GO to a new GO

        //int count = gobject.transform.childCount;
        //for(int i = 0; i < count; i++)
        //{
        //    Transform obj = gobject.transform.GetChild(i);
        //    Debug.Log(obj.name);
        //}


        importer.Dispose(); // diacard the importer when importing is done
    }
Exemple #2
0
    public void importmodel()
    {
        //string fileName = "F:/UNITY stuff/FlexHub/FlexHub_parts/FBX-Parts_FlexHub/Part_72.fbx";

        allnodes.Clear();
        //Create a new importer
        importer = new AssimpImporter();         // create an importer instance
        //importer.SetConfig (new con)
        model = importer.ImportFile(filetoImport //import the specified file
                                                 //PostProcessSteps.JoinIdenticalVertices |
                                                 //PostProcessSteps.FindInvalidData |
                                                 //PostProcessSteps.RemoveRedundantMaterials |
                                                 //PostProcessSteps.FixInFacingNormals
                                    );

        Debug.Log(model.RootNode.Name + "\n" + "-----------------------------"); // get the root node name

        MasterNode = model.RootNode;                                             // get the master node of the scene

        meshesinmodel = model.Meshes;

        GameObject gobject = convertNodes(MasterNode); // call the function and pass the resulting GO to a new GO


        importer.Dispose(); // diacard the importer when importing is done
    }
        public AssimpModelLoader(string modelFilePath, SkeletonPerVertexBoneInfluenceType skeletonType = SkeletonPerVertexBoneInfluenceType.ThreeBones)
        {
            m_skeletonType = skeletonType;
            var importer = new AssimpImporter();

            m_scene = importer.ImportFile(modelFilePath, PostProcessSteps.FlipUVs | PostProcessSteps.CalculateTangentSpace);
        }
Exemple #4
0
    public void importmodel()
    {
        //string fileName = "F:/UNITY stuff/FlexHub/FlexHub_parts/FBX-Parts_FlexHub/Part_72.fbx";

        allnodes.Clear();
        //Create a new importer
        importer = new AssimpImporter();                           // create an importer instance
        //importer.SetConfig (new con)
        model = importer.ImportFile(filetoImport,                  //import the specified file
                                                                   //PostProcessSteps.JoinIdenticalVertices |
                                    PostProcessSteps.Triangulate | //very important
                                    PostProcessSteps.FindInvalidData |
                                    PostProcessSteps.RemoveRedundantMaterials
                                    );

        Debug.Log(model.RootNode.Name + "\n" + "-----------------------------"); // get the root node name

        MasterNode = model.RootNode;                                             // get the master node of the scene

        //meshesinmodel = model.Meshes;

        Debug.Log("No.Of Meshes in the model : " + model.MeshCount + "\n" + "-----------------------------");

        //foreach (Assimp.Mesh m in meshesinmodel)
        //{
        //    Debug.Log("Polygon type: " +m.PrimitiveType);
        //    /*************************************************************************************/
        //    Debug.Log("No. Vertices in this mesh: " +m.VertexCount);

        //    verticesinmesh = m.Vertices;
        //    for (int y = 0; y < verticesinmesh.Length; ++y)
        //    {
        //        Debug.Log ("vertex " + (y+1) + " is " + verticesinmesh[y]);
        //    }
        //    Debug.Log("No.Vertices detected in this mesh: " +verticesinmesh.Length);

        //    /*************************************************************************************/
        //    Debug.Log("Faces in this mesh: " + m.FaceCount);
        //    facesinmesh = m.Faces;
        //    foreach (Assimp.Face f in facesinmesh)
        //    {
        //        faceindices = f.Indices;
        //        for (int x = 0; x < faceindices.Length; ++x)
        //        {
        //            Debug.Log(faceindices[x]);
        //        }
        //        Debug.Log("Length of the face indeces array: "+faceindices.Length);
        //    }

        //    Debug.Log("No.Faces detected in this mesh: " + facesinmesh.Length);

        //}
        GameObject gobject = convertNodes(MasterNode); // call the function and pass the resulting GO to a new GO


        importer.Dispose(); // diacard the importer when importing is done
    }
Exemple #5
0
        /// <summary>
        /// Loads a model file into the model.
        /// </summary>
        /// <param name="assetManager">AssetManager that provides texture assets</param>
        /// <param name="fileName">File name of the model.</param>
        public void Load(AssetManager assetManager, string fileName)
        {
            using (var importer = new AssimpImporter())
            {
                var scene = importer.ImportFile(fileName, postProcessing);

                this.Load(new AssetLoadContext(assetManager, Path.GetFileNameWithoutExtension(fileName), "."), scene);
            }
        }
Exemple #6
0
        public void Construct(string path, Action <Vector3, Vector3, Vector2> appendVertex, Action <Int3> appendIndex, int index)
        {
            Assimp.AssimpImporter importer = new AssimpImporter();
            Scene scene = importer.ImportFile(path, PostProcessPreset.ConvertToLeftHanded | PostProcessPreset.TargetRealTimeQuality);

            Assimp.Mesh mesh   = scene.Meshes[index % scene.MeshCount];
            int         offset = 0;

            Construct(mesh, appendVertex, appendIndex, ref offset);
        }
Exemple #7
0
		public SimpleOpenGLSample() : base() {
			Title = "Quack! - Assimp.NET Simple OpenGL Sample";

			String fileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "duck.dae");

			AssimpImporter importer = new AssimpImporter();
			importer.SetConfig(new NormalSmoothingAngleConfig(66.0f));
			m_model = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality);
			ComputeBoundingBox();
		}
        public void TestObjLoad()
        {
            String path = Path.Combine(TestHelper.RootPath, "TestFiles\\sphere.obj");

            AssimpImporter importer = new AssimpImporter();
            Scene scene = importer.ImportFile(path);

            Assert.IsNotNull(scene);
            Assert.IsNotNull(scene.RootNode);
            Assert.IsTrue(scene.RootNode.Name.Equals("sphere.obj"));
        }
Exemple #9
0
        public AssimpModel(RenderContext context, string fileName)
        {
            this.FileName = Path.GetFileName(fileName);
            this.context  = context;
            loader        = new BasicSubresourceLoader(Path.GetDirectoryName(fileName));
            AssimpImporter importer = new AssimpImporter();

            modelScene = importer.ImportFile(fileName, PostProcessSteps.Triangulate | PostProcessSteps.GenerateSmoothNormals);
            Visibility = true;
            Initialize();
        }
Exemple #10
0
        private Scene LoadDaeScene(String path)
        {
            Scene scene;

            using (var importer = new AssimpImporter())
            {
                importer.SetConfig(new NormalSmoothingAngleConfig(66.0f));
                scene = importer.ImportFile(path, PostProcessPreset.TargetRealTimeMaximumQuality);
            }

            return(scene);
        }
        public SimpleOpenGLSample() : base()
        {
            Title = "Quack! - Assimp.NET Simple OpenGL Sample";

            String fileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "duck.dae");

            AssimpImporter importer = new AssimpImporter();

            importer.SetConfig(new NormalSmoothingAngleConfig(66.0f));
            m_model = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality);
            ComputeBoundingBox();
        }
Exemple #12
0
        public void ConstructAll(string path, Action <Vector3, Vector3, Vector2> appendVertex, Action <Int3> appendIndex)
        {
            Assimp.AssimpImporter importer = new AssimpImporter();
            Scene scene = importer.ImportFile(path, PostProcessPreset.ConvertToLeftHanded | PostProcessPreset.TargetRealTimeQuality);

            int offset = 0;

            foreach (Assimp.Mesh m in scene.Meshes)
            {
                Construct(m, appendVertex, appendIndex, ref offset);
            }
        }
Exemple #13
0
        private ContentCompilerResult CompileFromFileInternal(string fileName, ModelCompilerOptions compilerOptions)
        {
            logger = new Logger();
            var result = new ContentCompilerResult()
            {
                Logger = logger
            };

            modelFilePath  = fileName;
            modelDirectory = Path.GetDirectoryName(modelFilePath);

            // Preload AssimpLibrary if not already loaded
            if (!AssimpLibrary.Instance.LibraryLoaded)
            {
                var rootPath = Path.GetDirectoryName(typeof(AssimpLibrary).Assembly.Location);
                AssimpLibrary.Instance.LoadLibrary(Path.Combine(rootPath, AssimpLibrary.Instance.DefaultLibraryPath32Bit), Path.Combine(rootPath, AssimpLibrary.Instance.DefaultLibraryPath64Bit));
            }

            var importer = new AssimpImporter();

            importer.SetConfig(new Assimp.Configs.MaxBoneCountConfig(72));
            //importer.SetConfig(new NormalSmoothingAngleConfig(66.0f));

            // Steps for Direct3D Right-Handed, should we make this configurable?
            var steps = PostProcessSteps.FlipUVs | PostProcessSteps.FlipWindingOrder | PostProcessSteps.LimitBoneWeights | PostProcessSteps.SplitByBoneCount;

            // Setup quality
            switch (compilerOptions.Quality)
            {
            case ModelRealTimeQuality.Low:
                steps |= PostProcessPreset.TargetRealTimeFast;
                break;

            case ModelRealTimeQuality.Maximum:
                steps |= PostProcessPreset.TargetRealTimeMaximumQuality;
                break;

            default:
                steps |= PostProcessPreset.TargetRealTimeQuality;
                break;
            }

            scene = importer.ImportFile(fileName, steps);
            model = new ModelData();
            ProcessScene();

            result.IsContentGenerated = true;
            result.ModelData          = model;

            return(result);
        }
Exemple #14
0
        public Model Load(string fileName)
        {
            Scene scene = _importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality);

            //use this directory path to load textures from
            _modelPath = Path.GetDirectoryName(fileName);

            var model    = new Model();
            var identity = Matrix.Identity;

            AddVertexData(model, scene, scene.RootNode, _device, ref identity);
            ComputeBoundingBox(model, scene);

            return(model);
        }
Exemple #15
0
        public void LoadScene()
        {
            AssimpImporter importer = new AssimpImporter();

            LogStream logstream = new LogStream(delegate(String msg, String userData)
            {
                Console.WriteLine(msg);
            });

            importer.AttachLogStream(logstream);

            m_scene = importer.ImportFile(Path.Combine(m_scenePath, m_sceneFileName));

            // Oslobadjanje resursa koriscenih za ucitavanje podataka o sceni.
            importer.Dispose();
        }
        /// <summary>
        ///  Ucitavanje podataka o sceni iz odgovarajuceg fajla.
        /// </summary>
        public void LoadScene()
        {
            // Instanciranje klase za ucitavanje podataka o sceni.
            AssimpImporter importer = new AssimpImporter();

            // Definisanje callback delegata za belezenje poruka u toku ucitavanja podataka o sceni.
            LogStream logstream = new LogStream(delegate(String msg, String userData) {
                Console.WriteLine(msg);
            });

            importer.AttachLogStream(logstream);

            // Ucitavanje podataka o sceni iz odgovarajuceg fajla.
            m_scene = importer.ImportFile(Path.Combine(m_scenePath, m_sceneFileName));

            // Oslobadjanje resursa koriscenih za ucitavanje podataka o sceni.
            importer.Dispose();
        }
Exemple #17
0
        public List <DX11IndexedGeometry> LoadModelsFromFile(string path, AssimpLoadInformation loadInfo)
        {
            Assimp.AssimpImporter importer = new AssimpImporter();
            Scene scene = importer.ImportFile(path, PostProcessPreset.ConvertToLeftHanded | PostProcessPreset.TargetRealTimeQuality);

            List <DX11IndexedGeometry> result = new List <DX11IndexedGeometry>();

            for (int j = 0; j < scene.MeshCount; j++)
            {
                Assimp.Mesh mesh = scene.Meshes[j];

                if (mesh.HasFaces && mesh.HasVertices)
                {
                    result.Add(this.LoadFromMesh(mesh, loadInfo));
                }
            }
            return(result);
        }
        public Model Load(string basePath, string fileName)
        {
            string absoluteFilePath = Path.Combine(basePath, fileName);

            Scene scene = m_importer.ImportFile(absoluteFilePath, PostProcessSteps.GenerateSmoothNormals);

            //use this directory path to load textures from
            m_modelPath = Path.GetDirectoryName(absoluteFilePath);

            Model model = new Model();

            model.basePath  = basePath;
            model.modelPath = fileName;
            Matrix identity = Matrix.Identity;

            AddVertexData(model, scene, scene.RootNode, m_device, ref identity);
            ComputeBoundingBox(model, scene);

            return(model);
        }
Exemple #19
0
        private static void BuildMesh(D3D10.Device d, string meshArgs)
        {
            string name = meshArgs.Split(',')[0];

            InputElement[] layout = (InputElement[])typeof(MeshInputElements10).GetField(meshArgs.Split(',')[1]).GetValue(typeof(MeshInputElements10));


            string fileName = ConfigurationSettings.AppSettings["ExportsFolder"] + name;

            AssimpImporter importer  = new AssimpImporter();
            LogStream      logstream = new LogStream(delegate(String msg, String userData) {
                Console.WriteLine(msg);
            });

            importer.AttachLogStream(logstream);

            importer.Scale                 = 0;
            importer.XAxisRotation         = 0;
            importer.YAxisRotation         = 0;
            importer.ZAxisRotation         = 0;
            importer.VerboseLoggingEnabled = true;
            importer.RemoveConfigs();

            Scene model = importer.ImportFile(fileName,
                                              PostProcessSteps.CalculateTangentSpace      // calculate tangents and bitangents if possible
                                              | PostProcessSteps.JoinIdenticalVertices    // join identical vertices/ optimize indexing CAUSES A PROBLEM
                                                                                          //| PostProcessSteps.ValidateDataStructure // perform a full validation of the loader's output
                                              | PostProcessSteps.ImproveCacheLocality     // improve the cache locality of the output vertices
                                              | PostProcessSteps.RemoveRedundantMaterials // remove redundant materials
                                                                                          //| PostProcessSteps.FindDegenerates // remove degenerated polygons from the import CAUSES A PROBLEM
                                                                                          //| PostProcessSteps.FindInvalidData // detect invalid model data, such as invalid normal vectors
                                              | PostProcessSteps.GenerateUVCoords         // convert spherical, cylindrical, box and planar mapping to proper UVs
                                              | PostProcessSteps.TransformUVCoords        // preprocess UV transformations (scaling, translation ...)
                                                                                          //| PostProcessSteps.FindInstances // search for instanced meshes and remove them by references to one master
                                                                                          //| PostProcessSteps.LimitBoneWeights // limit bone weights to 4 per vertex
                                              | PostProcessSteps.OptimizeMeshes           // join small meshes, if possible;
                                              | PostProcessSteps.GenerateSmoothNormals    // generate smooth normal vectors if not existing
                                              | PostProcessSteps.Triangulate              // triangulate polygons with more than 3 edges
                                              | PostProcessSteps.SortByPrimitiveType      // make 'clean' meshes which consist of a single typ of primitives
                                              | PostProcessSteps.FlipUVs                  // common DirectX issue (Xna also)
                                              | PostProcessSteps.FixInFacingNormals
                                              | PostProcessSteps.MakeLeftHanded
                                              | PostProcessSteps.FlipWindingOrder
                                              );


            MeshHelper.BuildMeshTextures(d, model);



            Mesh3D m = MeshHelper.LoadFromFile(d, model, layout);

            importer.Dispose();


            Stream          stream     = File.Open(ConfigurationSettings.AppSettings["ExportsFolder"] + name.Replace(".X", ".mesh"), FileMode.Create);
            BinaryFormatter bFormatter = new BinaryFormatter();

            if (m != null)
            {
                bFormatter.Serialize(stream, m);
            }
            stream.Close();
        }
Exemple #20
0
        public override NodeContent Import(string filename, ContentImporterContext context)
        {
            var identity = new ContentIdentity(filename, GetType().Name);
            var importer = new AssimpImporter();

            importer.AttachLogStream(new LogStream((msg, userData) => context.Logger.LogMessage(msg)));
            var scene = importer.ImportFile(filename,
                                            PostProcessSteps.FlipUVs | // So far appears necessary
                                            PostProcessSteps.JoinIdenticalVertices |
                                            PostProcessSteps.Triangulate |
                                            PostProcessSteps.SortByPrimitiveType |
                                            PostProcessSteps.FindInvalidData
                                            );

            var rootNode = new NodeContent
            {
                Name      = scene.RootNode.Name,
                Identity  = identity,
                Transform = ToXna(scene.RootNode.Transform)
            };

            // TODO: Materials
            var materials = new List <MaterialContent>();

            foreach (var sceneMaterial in scene.Materials)
            {
                var diffuse = sceneMaterial.GetTexture(TextureType.Diffuse, 0);

                materials.Add(new BasicMaterialContent()
                {
                    Name     = sceneMaterial.Name,
                    Identity = identity,
                    Texture  = new ExternalReference <TextureContent>(diffuse.FilePath, identity)
                });
            }

            // Meshes
            var meshes = new Dictionary <Mesh, MeshContent>();

            foreach (var sceneMesh in scene.Meshes)
            {
                if (!sceneMesh.HasVertices)
                {
                    continue;
                }

                var mesh = new MeshContent
                {
                    Name = sceneMesh.Name
                };

                // Position vertices are shared at the mesh level
                foreach (var vert in sceneMesh.Vertices)
                {
                    mesh.Positions.Add(new Vector3(vert.X, vert.Y, vert.Z));
                }

                var geom = new GeometryContent
                {
                    Name = string.Empty,
                    //Material = materials[sceneMesh.MaterialIndex]
                };

                // Geometry vertices reference 1:1 with the MeshContent parent,
                // no indirection is necessary.
                geom.Vertices.Positions.AddRange(mesh.Positions);
                geom.Vertices.AddRange(Enumerable.Range(0, sceneMesh.VertexCount));
                geom.Indices.AddRange(sceneMesh.GetIntIndices());

                // Individual channels go here
                if (sceneMesh.HasNormals)
                {
                    geom.Vertices.Channels.Add(VertexChannelNames.Normal(), ToXna(sceneMesh.Normals));
                }

                for (var i = 0; i < sceneMesh.TextureCoordsChannelCount; i++)
                {
                    geom.Vertices.Channels.Add(VertexChannelNames.TextureCoordinate(i),
                                               ToXnaVector2(sceneMesh.GetTextureCoords(i)));
                }

                mesh.Geometry.Add(geom);
                rootNode.Children.Add(mesh);
                meshes.Add(sceneMesh, mesh);
            }

            // Bones
            var bones          = new Dictionary <Node, BoneContent>();
            var hierarchyNodes = scene.RootNode.Children.SelectDeep(n => n.Children).ToList();

            foreach (var node in hierarchyNodes)
            {
                var bone = new BoneContent
                {
                    Name      = node.Name,
                    Transform = Matrix.Transpose(ToXna(node.Transform))
                };

                if (node.Parent == scene.RootNode)
                {
                    rootNode.Children.Add(bone);
                }
                else
                {
                    var parent = bones[node.Parent];
                    parent.Children.Add(bone);
                }

                // Copy the bone's name to the MeshContent - this appears to be
                // the way it comes out of XNA's FBXImporter.
                foreach (var meshIndex in node.MeshIndices)
                {
                    meshes[scene.Meshes[meshIndex]].Name = node.Name;
                }

                bones.Add(node, bone);
            }

            return(rootNode);
        }
Exemple #21
0
        public BasicModel(Device device, TextureManager texMgr, string filename, string texturePath, bool flipUV = false)
        {
            var importer = new AssimpImporter();

            if (!importer.IsImportFormatSupported(Path.GetExtension(filename)))
            {
                throw new ArgumentException("Model format " + Path.GetExtension(filename) + " is not supported!  Cannot load {1}", "filename");
            }
#if DEBUG
            importer.AttachLogStream(new ConsoleLogStream());
            importer.VerboseLoggingEnabled = true;
#endif
            var postProcessFlags = PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.CalculateTangentSpace;
            if (flipUV)
            {
                postProcessFlags |= PostProcessSteps.FlipUVs;
            }
            var model = importer.ImportFile(filename, postProcessFlags);


            var min = new Vector3(float.MaxValue);
            var max = new Vector3(float.MinValue);

            foreach (var mesh in model.Meshes)
            {
                var verts  = new List <PosNormalTexTan>();
                var subset = new MeshGeometry.Subset {
                    VertexCount = mesh.VertexCount,
                    VertexStart = Vertices.Count,
                    FaceStart   = Indices.Count / 3,
                    FaceCount   = mesh.FaceCount
                };
                Subsets.Add(subset);
                // bounding box corners


                for (var i = 0; i < mesh.VertexCount; i++)
                {
                    var pos = mesh.HasVertices ? mesh.Vertices[i].ToVector3() : new Vector3();
                    min = Vector3.Minimize(min, pos);
                    max = Vector3.Maximize(max, pos);

                    var norm = mesh.HasNormals ? mesh.Normals[i] : new Vector3D();
                    var texC = mesh.HasTextureCoords(0) ? mesh.GetTextureCoords(0)[i] : new Vector3D();
                    var tan  = mesh.HasTangentBasis ? mesh.Tangents[i] : new Vector3D();
                    var v    = new PosNormalTexTan(pos, norm.ToVector3(), texC.ToVector2(), tan.ToVector3());
                    verts.Add(v);
                }

                Vertices.AddRange(verts);

                var indices = mesh.GetIndices().Select(i => (short)(i + (uint)subset.VertexStart)).ToList();
                Indices.AddRange(indices);

                var mat      = model.Materials[mesh.MaterialIndex];
                var material = mat.ToMaterial();

                Materials.Add(material);

                var diffusePath = mat.GetTexture(TextureType.Diffuse, 0).FilePath;
                if (Path.GetExtension(diffusePath) == ".tga")
                {
                    // DirectX doesn't like to load tgas, so you will need to convert them to pngs yourself with an image editor
                    diffusePath = diffusePath.Replace(".tga", ".png");
                }
                if (!string.IsNullOrEmpty(diffusePath))
                {
                    DiffuseMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, diffusePath)));
                }
                var normalPath = mat.GetTexture(TextureType.Normals, 0).FilePath;
                if (!string.IsNullOrEmpty(normalPath))
                {
                    NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath)));
                }
                else
                {
                    var normalExt = Path.GetExtension(diffusePath);
                    normalPath = Path.GetFileNameWithoutExtension(diffusePath) + "_nmap" + normalExt;

                    NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath)));
                }
            }
            BoundingBox = new BoundingBox(min, max);
            ModelMesh.SetSubsetTable(Subsets);
            ModelMesh.SetVertices(device, Vertices);
            ModelMesh.SetIndices(device, Indices);
        }
Exemple #22
0
        protected override void OnLoad(EventArgs e)
        {
            GraphicsDevice graphicsDevice = new GraphicsDevice(this);

            VSync = VSyncMode.On;

            GL.ClearColor(0.1f, 0.2f, 0.5f, 0.0f);
            GL.Enable(EnableCap.DepthTest);

            float aspectRatio = ClientSize.Width / (float)(ClientSize.Height);

            Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspectRatio, 1, 100, out projectionMatrix);
            modelviewMatrix = Matrix4.LookAt(new Vector3(0, 3, 5), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
            Matrix4 scale = Matrix4.Scale(0.5f, 0.5f, 0.5f);

            Matrix4.Mult(ref scale, ref modelviewMatrix, out modelviewMatrix);
            Matrix4 translate = Matrix4.CreateTranslation(0f, -2.5f, 0f);

            Matrix4.Mult(ref translate, ref modelviewMatrix, out modelviewMatrix);

            shader = new Program(vertexShaderSource, fragmentShaderSource);
            shader.Bind();
            shader.UniformMatrix4("camera", false, ref projectionMatrix);
            shader.UniformMatrix4("model", false, ref modelviewMatrix);
            shader.Unbind();

            skeletonShader = new Program(skeletonVertexShaderSource, skeletonFragmentShaderSource);
            skeletonShader.Bind();
            skeletonShader.UniformMatrix4("camera", false, ref projectionMatrix);
            skeletonShader.UniformMatrix4("model", false, ref modelviewMatrix);
            skeletonShader.Unbind();

            // load model with ASSIMP.NET
            AssimpImporter importer = new AssimpImporter();
            Scene          scene    = importer.ImportFile(@"..\..\..\Resources\dwarf2.x", PostProcessPreset.TargetRealTimeMaximumQuality);

            List <ModelMeshPart> meshParts = new List <ModelMeshPart>();

            foreach (Mesh mesh in scene.Meshes)
            {
                ModelMeshPart part = new ModelMeshPart();
                List <VertexPositionNormalTexture> vertices = new List <VertexPositionNormalTexture>();
                List <int> indices = new List <int>();
                for (int i = 0; i < mesh.VertexCount; i++)
                {
                    vertices.Add(new VertexPositionNormalTexture(mesh.Vertices[i].X, mesh.Vertices[i].Y, mesh.Vertices[i].Z, mesh.Normals[i].X, mesh.Normals[i].Y, mesh.Normals[i].Z, mesh.GetTextureCoords(0)[i].X, 1 - mesh.GetTextureCoords(0)[i].Y));
                }
                foreach (Face face in mesh.Faces)
                {
                    foreach (uint i in face.Indices)
                    {
                        indices.Add((int)i);
                    }
                }
                part.VertexArray    = new VertexArray(VertexBuffer.Create(VertexFormat.PositionNormalTexture, vertices.ToArray()), IndexBuffer.Create(indices.ToArray()));
                part.NumVertices    = (uint)mesh.VertexCount;
                part.PrimitiveCount = (uint)mesh.FaceCount;
                meshParts.Add(part);
            }

            // create skeleton
            List <Minotaur.Graphics.Bone> bones = new List <Minotaur.Graphics.Bone>();

            CreateSkeleton(bones, scene.RootNode);

            ModelMesh modelMesh = new ModelMesh(meshParts);

            dwarf = new Model(new Skeleton(bones), new List <ModelMesh>()
            {
                modelMesh
            });

            Bitmap bmp = new Bitmap(@"..\..\..\Resources\dwarf.jpg");

            texture1 = Texture2D.Create(bmp, TextureMinFilter.Linear, TextureMagFilter.Linear);
            bmp      = new Bitmap(@"..\..\..\Resources\axe.jpg");
            texture2 = Texture2D.Create(bmp, TextureMinFilter.Linear, TextureMagFilter.Linear);
        }
Exemple #23
0
        private static IModel LoadModelFromAssimp <VertexFormat, IndexFormat>(FileInfo fi, string modelName, Device device)
            where VertexFormat : IModelMeshComponents, new()
            where IndexFormat : struct
        {
            //Get Assimp Scene
            Scene scene;

            using (AssimpImporter importer = new AssimpImporter())
            {
                //is imported, loaded into managed memory. Then the unmanaged memory is released, and everything is reset.
                scene = importer.ImportFile(fi.FullName, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessPreset.ConvertToLeftHanded);
            }

            //Get components
            var components = ((IModelMeshComponents) new VertexFormat()).Components;

            //Build custom buffer format from passed in components
            bool isP = (components & ModelMesh.ModelMesh.ModelMeshComponents.P) == ModelMesh.ModelMesh.ModelMeshComponents.P;
            bool isN = (components & ModelMesh.ModelMesh.ModelMeshComponents.N) == ModelMesh.ModelMesh.ModelMeshComponents.N;
            bool isT = (components & ModelMesh.ModelMesh.ModelMeshComponents.T) == ModelMesh.ModelMesh.ModelMeshComponents.T;
            bool isC = (components & ModelMesh.ModelMesh.ModelMeshComponents.C) == ModelMesh.ModelMesh.ModelMeshComponents.C;

            //index Format
            TypeCode typeCode = Type.GetTypeCode(typeof(IndexFormat));
            IModel   model    = null;

            if (isP && !(isN || isT || isC))
            {
                if (typeCode == TypeCode.UInt16)
                {
                    model = Generate_P_UINT16(scene, device);
                }
                if (typeCode == TypeCode.UInt32)
                {
                    model = Generate_P_UINT32(scene, device);
                }
            }

            if (isP && isC && !(isN || isT))
            {
                if (typeCode == TypeCode.UInt16)
                {
                    model = Generate_PC_UINT16(scene, device);
                }
                if (typeCode == TypeCode.UInt32)
                {
                    model = Generate_PC_UINT32(scene, device);
                }
            }

            if (isP && isN && !(isT || isC))
            {
                if (typeCode == TypeCode.UInt16)
                {
                    model = Generate_PN_UINT16(scene, device);
                }
                if (typeCode == TypeCode.UInt32)
                {
                    model = Generate_PN_UINT32(scene, device);
                }
            }

            if (isP && isN && isC && !(isT))
            {
                if (typeCode == TypeCode.UInt16)
                {
                    model = Generate_PNC_UINT16(scene, device);
                }
                if (typeCode == TypeCode.UInt32)
                {
                    model = Generate_PNC_UINT32(scene, device);
                }
            }

            if (isP && isN && isT && isC)
            {
                if (typeCode == TypeCode.UInt16)
                {
                    model = Generate_PNTC_UINT16(scene, device);
                }
                if (typeCode == TypeCode.UInt32)
                {
                    model = Generate_PNTC_UINT32(scene, device);
                }
            }

            if (model == null)
            {
                return(null);
            }

            model.ModelFilePath = fi.FullName;
            model.Name          = modelName;
            return(model);
        }
        private void LoadSceneA()
        {
            Console.WriteLine("Thread A: Starting import.");
            AssimpImporter importer = new AssimpImporter();
            String path = Path.Combine(TestHelper.RootPath, "TestFiles\\Bob.md5mesh");

            importer.AttachLogStream(new ConsoleLogStream("Thread A:"));
            Console.WriteLine("Thread A: Importing");
            Scene scene = importer.ImportFile(path);
            Console.WriteLine("Thread A: Done importing");
        }
Exemple #25
0
        public SkinnedModel(Device device, TextureManager texMgr, string filename, string texturePath, bool flipTexY = false)
        {
            var importer = new AssimpImporter();

        #if DEBUG
            importer.AttachLogStream(new ConsoleLogStream());
            importer.VerboseLoggingEnabled = true;
        #endif
            var model = importer.ImportFile(filename, PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.CalculateTangentSpace);

            // Load animation data
            Animator = new SceneAnimator();
            Animator.Init(model);

            // create our vertex-to-boneweights lookup
            var vertToBoneWeight = new Dictionary <uint, List <VertexWeight> >();
            // create bounding box extents
            _min = new Vector3(float.MaxValue);
            _max = new Vector3(float.MinValue);

            foreach (var mesh in model.Meshes)
            {
                ExtractBoneWeightsFromMesh(mesh, vertToBoneWeight);
                var subset = new MeshGeometry.Subset {
                    VertexCount = mesh.VertexCount,
                    VertexStart = Vertices.Count,
                    FaceStart   = Indices.Count / 3,
                    FaceCount   = mesh.FaceCount
                };
                Subsets.Add(subset);

                var verts = ExtractVertices(mesh, vertToBoneWeight, flipTexY);
                Vertices.AddRange(verts);
                // extract indices and shift them to the proper offset into the combined vertex buffer
                var indices = mesh.GetIndices().Select(i => (short)(i + (uint)subset.VertexStart)).ToList();
                Indices.AddRange(indices);

                // extract materials
                var mat      = model.Materials[mesh.MaterialIndex];
                var material = mat.ToMaterial();
                Materials.Add(material);

                // extract material textures
                var diffusePath = mat.GetTexture(TextureType.Diffuse, 0).FilePath;
                if (!string.IsNullOrEmpty(diffusePath))
                {
                    DiffuseMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, diffusePath)));
                }
                var normalPath = mat.GetTexture(TextureType.Normals, 0).FilePath;
                if (!string.IsNullOrEmpty(normalPath))
                {
                    NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath)));
                }
                else
                {
                    // for models created without a normal map baked, we'll check for a texture with the same
                    // filename as the diffure texture, and _nmap suffixed
                    // this lets us add our own normal maps easily
                    var normalExt = Path.GetExtension(diffusePath);
                    normalPath = Path.GetFileNameWithoutExtension(diffusePath) + "_nmap" + normalExt;
                    if (File.Exists(Path.Combine(texturePath, normalPath)))
                    {
                        NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath)));
                    }
                }
            }
            BoundingBox = new BoundingBox(_min, _max);

            ModelMesh.SetSubsetTable(Subsets);
            ModelMesh.SetVertices(device, Vertices);
            ModelMesh.SetIndices(device, Indices);
        }
        private void LoadSceneB()
        {
            Console.WriteLine("Thread B: Starting import.");
            AssimpImporter importer = new AssimpImporter();
            String path = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae");

            importer.AttachLogStream(new ConsoleLogStream("Thread B:"));
            importer.SetConfig(new NormalSmoothingAngleConfig(55.0f));
            Console.WriteLine("Thread B: Importing");
            Scene scene = importer.ImportFile(path);
            Console.WriteLine("Thread B: Done importing");
        }
Exemple #27
0
        public static void MeshToStaticModel(string file)
        {
            AssimpImporter importer = new AssimpImporter();

            try
            {
                Scene scene = importer.ImportFile(file, PostProcessSteps.Triangulate);

                if (scene.MeshCount == 1)
                {
                    Vector3D[] vertices = scene.Meshes[0].Vertices;
                    Vector3D[] uvCoords = scene.Meshes[0].GetTextureCoords(0);
                    Vector3D[] normals  = null;
                    short[]    indices  = scene.Meshes[0].GetShortIndices();

                    if (!scene.Meshes[0].HasNormals)
                    {
                        MessageBox.Show("Mesh doesn't have normals. Check if the mesh has been exported correctly.",
                                        "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        Application.Exit();
                    }

                    normals = scene.Meshes[0].Normals;

                    // 4 byte floats * 3 dimensions
                    byte[] vertexData = new byte[12 * vertices.Length];

                    // 4 byte floats * 2 dimensions
                    byte[] uvData = new byte[8 * uvCoords.Length];

                    // 4 byte normals * 3 dimensions
                    byte[] normalData = new byte[12 * normals.Length];

                    int vertexOffset = 0, uvOffset = 0, normalOffset = 0;

                    // Extract vertex data
                    for (int i = 0; i < vertices.Length; ++i)
                    {
                        byte[] x, y, z;
                        x = BitConverter.GetBytes(vertices[i].X);
                        y = BitConverter.GetBytes(vertices[i].Y);
                        z = BitConverter.GetBytes(vertices[i].Z);

                        Buffer.BlockCopy(x, 0, vertexData, vertexOffset, 4);
                        Buffer.BlockCopy(y, 0, vertexData, vertexOffset + 4, 4);
                        Buffer.BlockCopy(z, 0, vertexData, vertexOffset + 8, 4);

                        vertexOffset += 12;
                    }

                    // Extract UV coordinates data
                    for (int i = 0; i < uvCoords.Length; ++i)
                    {
                        byte[] s, t;
                        s = BitConverter.GetBytes(uvCoords[i].X);
                        t = BitConverter.GetBytes(uvCoords[i].Y);

                        Buffer.BlockCopy(s, 0, uvData, uvOffset, 4);
                        Buffer.BlockCopy(t, 0, uvData, uvOffset + 4, 4);

                        uvOffset += 8;
                    }

                    // Extract normal data
                    for (int i = 0; i < normals.Length; ++i)
                    {
                        byte[] x, y, z;
                        x = BitConverter.GetBytes(normals[i].X);
                        y = BitConverter.GetBytes(normals[i].Y);
                        z = BitConverter.GetBytes(normals[i].Z);

                        Buffer.BlockCopy(x, 0, normalData, normalOffset, 4);
                        Buffer.BlockCopy(y, 0, normalData, normalOffset + 4, 4);
                        Buffer.BlockCopy(z, 0, normalData, normalOffset + 8, 4);

                        normalOffset += 12;
                    }

                    // Save the raw mesh file
                    byte[] binary = new byte[MESH_HEADER_LENGTH + vertexData.Length + uvData.Length + normalData.Length + 2 * indices.Length];

                    // Set the vertex count
                    binary[0] = BitConverter.GetBytes((UInt16)vertices.Length)[0];
                    binary[1] = BitConverter.GetBytes((UInt16)vertices.Length)[1];

                    // Copy the vertices
                    Buffer.BlockCopy(vertexData, 0, binary, MESH_HEADER_LENGTH, vertexData.Length);

                    // Copy the UV coordinates
                    Buffer.BlockCopy(uvData, 0, binary, MESH_HEADER_LENGTH + vertexData.Length, uvData.Length);

                    // Copy the normals
                    Buffer.BlockCopy(normalData, 0, binary, MESH_HEADER_LENGTH + vertexData.Length + uvData.Length, normalData.Length);

                    // Copy the indices
                    Buffer.BlockCopy(indices, 0, binary, MESH_HEADER_LENGTH + vertexData.Length + uvData.Length + normalData.Length, 2 * indices.Length);

                    // Save the converted file
                    File.WriteAllBytes(file.Split('.')[0] + ".mesh", binary);
                }
                else
                {
                    MessageBox.Show("Model has " + scene.MeshCount +
                                    " submeshes. Only models with one submesh can be processed",
                                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (AssimpException assExp)
            {
                MessageBox.Show(assExp.Message, "Error converting mesh", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Exemple #28
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: ModelCompiler.exe model.dae");
                return;
            }

            foreach (string filename in args)
            {
                AssimpImporter   importer = new AssimpImporter();
                PostProcessSteps steps    = PostProcessPreset.TargetRealTimeMaximumQuality;
                steps |= PostProcessSteps.OptimizeMeshes | PostProcessSteps.SplitLargeMeshes | PostProcessSteps.Triangulate
                         | PostProcessSteps.FlipUVs | PostProcessSteps.LimitBoneWeights;
                importer.SetConfig(new VertexBoneWeightLimitConfig(2));
                Scene scene = importer.ImportFile(filename, steps);

                Vector3D bbMin = new Vector3D(float.MaxValue, float.MaxValue, float.MaxValue);
                Vector3D bbMax = new Vector3D(float.MinValue, float.MinValue, float.MinValue);

                Node meshNode = scene.RootNode;

                while (!meshNode.HasMeshes)
                {
                    meshNode = meshNode.Children[0];
                }

                Mesh            nodeGeometry        = scene.Meshes[meshNode.MeshIndices[0]];
                List <Vector3D> transformedVertices = new List <Vector3D>();

                foreach (Vector3D vertex in nodeGeometry.Vertices)
                {
                    Vector4 tempv = new Vector4(vertex.X, vertex.Y, vertex.Z, 1.0f);
                    Matrix  tempm = Matrix.Scaling(0.1f) * Matrix.RotationYawPitchRoll(((float)Math.PI / 2.0f), ((float)Math.PI / 2.0f), 0.0f) *
                                    new Matrix(meshNode.Transform.A1, meshNode.Transform.A2, meshNode.Transform.A3, meshNode.Transform.A3,
                                               meshNode.Transform.B1, meshNode.Transform.B2, meshNode.Transform.B3, meshNode.Transform.B3,
                                               meshNode.Transform.C1, meshNode.Transform.C2, meshNode.Transform.C3, meshNode.Transform.C3,
                                               meshNode.Transform.D1, meshNode.Transform.D2, meshNode.Transform.D3, meshNode.Transform.D3);
                    Vector4 finalvec = Vector4.Transform(tempv, tempm);

                    transformedVertices.Add(new Vector3D(finalvec.X, finalvec.Y, finalvec.Z));
                }

                using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(filename + ".mdl")))
                {
                    foreach (Vector3D vector in transformedVertices)
                    {
                        bbMin.X = Math.Min(vector.X, bbMin.X);
                        bbMin.Y = Math.Min(vector.Y, bbMin.Y);
                        bbMin.Z = Math.Min(vector.Z, bbMin.Z);

                        bbMax.X = Math.Max(vector.X, bbMax.X);
                        bbMax.Y = Math.Max(vector.Y, bbMax.Y);
                        bbMax.Z = Math.Max(vector.Z, bbMax.Z);
                    }

                    writer.Write(bbMin.X);
                    writer.Write(bbMin.Y);
                    writer.Write(bbMin.Z);

                    writer.Write(bbMax.X);
                    writer.Write(bbMax.Y);
                    writer.Write(bbMax.Z);

                    //writer.Write(scene.Meshes.Length);
                    writer.Write(1);

                    Mesh currentMesh = nodeGeometry;

                    if (!currentMesh.HasTextureCoords(0))
                    {
                        Console.WriteLine("ERROR: model must have texture coordinates");
                        return;
                    }

                    Vector3D[] texCoords = currentMesh.GetTextureCoords(0);

                    writer.Write(currentMesh.VertexCount);

                    for (int j = 0; j < currentMesh.VertexCount; j++)
                    {
                        writer.Write(transformedVertices[j].X);
                        writer.Write(transformedVertices[j].Y);
                        writer.Write(transformedVertices[j].Z);

                        writer.Write(texCoords[j].X);
                        writer.Write(texCoords[j].Y);
                    }

                    writer.Write(currentMesh.Faces.Length * 3);
                    for (int j = 0; j < currentMesh.Faces.Length; j++)
                    {
                        Face currentFace = currentMesh.Faces[j];

                        if (currentFace.IndexCount != 3)
                        {
                            Console.WriteLine("ERROR: non-triangle found!");
                            Console.ReadKey();
                            return;
                        }

                        foreach (uint index in currentFace.Indices)
                        {
                            writer.Write((int)index);
                        }
                    }

                    //writer.Write(currentMesh.Faces.Length * 3);
                    //for (int j = 0; j < currentMesh.Faces.Length; j++)
                    //{
                    //    Face currentFace = currentMesh.Faces[j];

                    //    if (currentFace.IndexCount != 3)
                    //    {
                    //        Console.WriteLine("ERROR: non-triangle found!");
                    //        Console.ReadKey();
                    //        return;
                    //    }

                    //    foreach (uint index in currentFace.Indices)
                    //    {
                    //        writer.Write(transformedVertices[(int)index].X);
                    //        writer.Write(transformedVertices[(int)index].Y);
                    //        writer.Write(transformedVertices[(int)index].Z);

                    //        writer.Write(texCoords[index].X);
                    //        writer.Write(texCoords[index].Y);
                    //    }
                    //}
                }
            }
        }
Exemple #29
0
        public override NodeContent Import(string filename, ContentImporterContext context)
        {
            ContentIdentity identity = new ContentIdentity(filename, GetType().Name);

            const int MAX_BONE_WEIGHTS             = 4;
            VertexBoneWeightLimitConfig boneConfig = new VertexBoneWeightLimitConfig(MAX_BONE_WEIGHTS);

            AssimpImporter importer = new AssimpImporter();

            importer.SetConfig(boneConfig);

            importer.AttachLogStream(new LogStream((msg, userData) => context.Logger.LogMessage(msg)));
            Scene scene = importer.ImportFile(filename,
                                              PostProcessSteps.FlipUVs |
                                              PostProcessSteps.JoinIdenticalVertices |
                                              PostProcessSteps.Triangulate |
                                              PostProcessSteps.SortByPrimitiveType |
                                              PostProcessSteps.FindInvalidData |
                                              PostProcessSteps.LimitBoneWeights |
                                              PostProcessSteps.FixInFacingNormals);


            // Root node
            NodeContent rootNode = new NodeContent
            {
                Name      = scene.RootNode.Name,
                Identity  = identity,
                Transform = Matrix.Transpose(ToXna(scene.RootNode.Transform))
            };


            // Materials
            MaterialContent[] materials = new MaterialContent[scene.MaterialCount];

            for (int m = 0; m < scene.MaterialCount; m++)
            {
                materials[m] = new BasicMaterialContent();

                materials[m].Identity = identity;
                // For some reason, there is all kinds of nasty junk in this string:
                materials[m].Name = CleanInput(scene.Materials[m].Name);

                for (int t = 0; t < scene.Materials[m].GetTextureCount(TextureType.Diffuse); t++)
                {
                    TextureSlot diffuseMap = scene.Materials[m].GetTexture(TextureType.Diffuse, t);
                    if (!String.IsNullOrEmpty(diffuseMap.FilePath))
                    {
                        materials[m].Textures.Add("Texture" + (t > 0 ? t.ToString() : ""),
                                                  new ExternalReference <TextureContent>(diffuseMap.FilePath, identity));
                    }
                }
            }


            // Bones

            // We find 'mesh container' nodes with the best names for those meshes while looking for the bones,
            // and will need them later when we create the MeshContents. I have a feeling that this won't work
            // in general, and may need to be made more robust.
            Dictionary <Mesh, string>      meshNames     = new Dictionary <Mesh, string>();
            Dictionary <Node, BoneContent> nodeToBoneMap = new Dictionary <Node, BoneContent>();
            BoneContent skeleton = null;    // The root bone for the model.

            List <Node> hierarchyNodes = scene.RootNode.Children.SelectDeep(n => n.Children).ToList();

            foreach (Node node in hierarchyNodes)
            {
                BoneContent bone = new BoneContent
                {
                    Name      = node.Name,
                    Transform = Matrix.Transpose(ToXna(node.Transform))
                };


                if (node.MeshIndices != null)
                {
                    // This node is a 'mesh container' instead of a bone, so we only care about extracting the name of the mesh.
                    foreach (int meshIndex in node.MeshIndices)
                    {
                        if (!meshNames.ContainsKey(scene.Meshes[meshIndex]))
                        {
                            meshNames.Add(scene.Meshes[meshIndex], node.Name);
                        }
                    }
                }
                else if (node.Parent == scene.RootNode)
                {
                    if (skeleton == null)
                    {
                        // This will be our skeleton so put the animations here:
                        if (scene.HasAnimations)
                        {
                            foreach (Animation assimpAnim in scene.Animations)
                            {
                                if (assimpAnim.HasNodeAnimations)
                                {
                                    AnimationContent newAnim = new AnimationContent();
                                    newAnim.Identity = identity;
                                    newAnim.Duration = TimeSpan.FromSeconds(assimpAnim.DurationInTicks / assimpAnim.TicksPerSecond);
                                    newAnim.Name     = assimpAnim.Name;

                                    foreach (NodeAnimationChannel nac in assimpAnim.NodeAnimationChannels)
                                    {
                                        Node animatedNode = hierarchyNodes.Find(n => n.Name == nac.NodeName);

                                        AnimationChannel newChan = BuildAnimtionChannel(animatedNode, nac);

                                        newAnim.Channels.Add(nac.NodeName, newChan);
                                    }

                                    if (String.IsNullOrEmpty(assimpAnim.Name))
                                    {
                                        bone.Animations.Add("SkelematorNoAnimationName", newAnim);
                                    }
                                    else
                                    {
                                        bone.Animations.Add(assimpAnim.Name, newAnim);
                                    }
                                }
                            }
                        }
                        rootNode.Children.Add(bone);
                        skeleton = bone;
                    }
                    else
                    {
                        context.Logger.LogWarning(null, identity, "Found multiple skeletons in the model, throwing extras away...");
                    }
                }
                else
                {
                    BoneContent parent = nodeToBoneMap[node.Parent];
                    parent.Children.Add(bone);
                }

                nodeToBoneMap.Add(node, bone);
            }


            // Meshes
            Dictionary <Mesh, MeshContent> meshes = new Dictionary <Mesh, MeshContent>();

            foreach (Mesh sceneMesh in scene.Meshes)
            {
                // See comment about meshNames at the beginning of the bone section.
                MeshBuilder mb = MeshBuilder.StartMesh(meshNames[sceneMesh]);

                mb.SwapWindingOrder = true; // Appears to require this...

                int positionIndex = -1;

                for (int v = 0; v < sceneMesh.VertexCount; v++)
                {
                    Vector3D vert = sceneMesh.Vertices[v];

                    // CreatePosition should just return a 0-based index of the newly added vertex.
                    positionIndex = mb.CreatePosition(new Vector3(vert.X, vert.Y, vert.Z));

                    if (positionIndex != v)
                    {
                        throw new InvalidContentException("Something unexpected happened while building a MeshContent from the Assimp scene mesh's vertices.  The scene mesh may contains duplicate vertices.");
                    }
                }

                if (positionIndex + 1 < 3)
                {
                    throw new InvalidContentException("There were not enough vertices in the Assimp scene mesh.");
                }



                // Create vertex channels
                int normalVertexChannelIndex = mb.CreateVertexChannel <Vector3>(VertexChannelNames.Normal());

                int[] texCoordVertexChannelIndex = new int[sceneMesh.TextureCoordsChannelCount];
                for (int x = 0; x < sceneMesh.TextureCoordsChannelCount; x++)
                {
                    texCoordVertexChannelIndex[x] = mb.CreateVertexChannel <Vector2>(VertexChannelNames.TextureCoordinate(x));
                }

                int boneWeightVertexChannelIndex = -1;

                if (sceneMesh.HasBones)
                {
                    boneWeightVertexChannelIndex = mb.CreateVertexChannel <BoneWeightCollection>(VertexChannelNames.Weights());
                }


                // Prepare vertex channel data
                BoneWeightCollection[] boneWeightData = null;
                if (sceneMesh.HasBones)
                {
                    boneWeightData = new BoneWeightCollection[sceneMesh.VertexCount];

                    for (int v = 0; v < sceneMesh.VertexCount; v++)
                    {
                        boneWeightData[v] = new BoneWeightCollection();
                    }

                    foreach (Bone sceneMeshBone in sceneMesh.Bones)
                    {
                        // We have to assume that the bone's name matches up with a node, and therefore one of our BoneContents.
                        foreach (VertexWeight sceneMeshBoneWeight in sceneMeshBone.VertexWeights)
                        {
                            boneWeightData[sceneMeshBoneWeight.VertexID].Add(new BoneWeight(sceneMeshBone.Name, sceneMeshBoneWeight.Weight));
                        }
                    }

                    for (int v = 0; v < sceneMesh.VertexCount; v++)
                    {
                        if (boneWeightData[v].Count <= 0)
                        {
                            throw new InvalidContentException("Encountered vertices without bone weights.");
                        }

                        boneWeightData[v].NormalizeWeights();
                    }
                }

                // Set the per-geometry data
                mb.SetMaterial(materials[sceneMesh.MaterialIndex]);
                mb.SetOpaqueData(new OpaqueDataDictionary());

                // Add each vertex
                for (int f = 0; f < sceneMesh.FaceCount; f++)
                {
                    if (sceneMesh.Faces[f].IndexCount != 3)
                    {
                        throw new InvalidContentException("Only triangular faces allowed.");
                    }

                    for (int t = 0; t < 3; t++)
                    {
                        mb.SetVertexChannelData(normalVertexChannelIndex, ToXna(sceneMesh.Normals[sceneMesh.Faces[f].Indices[t]]));

                        for (int x = 0; x < sceneMesh.TextureCoordsChannelCount; x++)
                        {
                            mb.SetVertexChannelData(texCoordVertexChannelIndex[x], ToXnaVector2((sceneMesh.GetTextureCoords(x))[sceneMesh.Faces[f].Indices[t]]));
                        }

                        if (sceneMesh.HasBones)
                        {
                            mb.SetVertexChannelData(boneWeightVertexChannelIndex, boneWeightData[sceneMesh.Faces[f].Indices[t]]);
                        }

                        mb.AddTriangleVertex((int)(sceneMesh.Faces[f].Indices[t]));
                    }
                }

                MeshContent mesh = mb.FinishMesh();
                rootNode.Children.Add(mesh);
                meshes.Add(sceneMesh, mesh);
            }

            return(rootNode);
        }
        public void TestImportFromFile()
        {
            String path = Path.Combine(TestHelper.RootPath, "TestFiles\\sphere.obj");

            AssimpImporter importer = new AssimpImporter();

            importer.SetConfig(new NormalSmoothingAngleConfig(55.0f));
            importer.Scale = .5f;
            importer.XAxisRotation = 25.0f;
            importer.YAxisRotation = 50.0f;
            importer.VerboseLoggingEnabled = true;

            Assert.IsTrue(importer.ContainsConfig(NormalSmoothingAngleConfig.NormalSmoothingAngleConfigName));

            importer.RemoveConfigs();

            Assert.IsFalse(importer.ContainsConfig(NormalSmoothingAngleConfig.NormalSmoothingAngleConfigName));

            importer.SetConfig(new NormalSmoothingAngleConfig(65.0f));
            importer.SetConfig(new NormalSmoothingAngleConfig(22.5f));
            importer.RemoveConfig(NormalSmoothingAngleConfig.NormalSmoothingAngleConfigName);

            Assert.IsFalse(importer.ContainsConfig(NormalSmoothingAngleConfig.NormalSmoothingAngleConfigName));

            importer.SetConfig(new NormalSmoothingAngleConfig(65.0f));

            Scene scene = importer.ImportFile(path, PostProcessPreset.TargetRealTimeMaximumQuality);

            Assert.IsNotNull(scene);
            Assert.IsTrue((scene.SceneFlags & SceneFlags.Incomplete) != SceneFlags.Incomplete);
        }