5
\$\begingroup\$

I am new to MonoGame and to 3d and I'm stuck on how to import a model. It seems the best way to import a mesh model and 3d animations in Monogame in Windows 8 is through AssimpNet. I can't find a basic-level tutorial on this.

I am looking for code to import in a format Blender supports (DAE, OBJ, 3DS), view the imported mesh and perform something basic like a camera rotation around it.

Is there a way to load data imported through AssimpNet into the Model object in Monogame?

\$\endgroup\$
  • \$\begingroup\$ "From what I can see the best way to import a mesh model and 3d animations in Monogame in Windows 8 is through AssimpNet." What led you to that conclusion? I belive the normal thing to do is use the XNA content compiler. \$\endgroup\$ – ClassicThunder May 5 '14 at 14:05
  • \$\begingroup\$ Well, I've tried adding FBX and OBJ files using Content.Load<Model> and get the "Could not load asset as non-content file" exception in Xna.Framework.Content \$\endgroup\$ – user1278255 May 5 '14 at 15:03
  • \$\begingroup\$ Sorry I thought you meant the Pipeline. I'll check out the compiler thanks. \$\endgroup\$ – user1278255 May 5 '14 at 15:10
  • \$\begingroup\$ "The imported project "C:\Program Files (x86)\MSBuild\Microsoft\XNA Game Studio\v4.0\Microsoft.Xna.GameStudio.ContentPipeline.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk." I get this error since I don't have XNA installed. I can't install XNA since I'm on Windows 8 \$\endgroup\$ – user1278255 May 5 '14 at 15:16
  • \$\begingroup\$ "I can't install XNA since I'm on Windows 8" Yes you can. msxna.codeplex.com/… \$\endgroup\$ – ClassicThunder May 5 '14 at 15:20
2
\$\begingroup\$

So I took a look through the MonoGame content pipeline code to see how it works and turns out its using AssImpNET. So importing your models via the MonoGame pipeline is a solution to your question.

Just from reading the AssImp documentation it looks like this code could handle formats other than ".fbx", ".x" dictated by the annotation. Issues would arise if different file structures would alter how the _scene is laid out which would require you to transform the scene so that it lines up with what MonoGame requires.

    [ContentImporter(".fbx", ".x", DisplayName = "Open Asset Import Library - MonoGame", DefaultProcessor = "ModelProcessor")]

MonoGame:OpenAssetImporter.cs

    public override NodeContent Import(string filename, ContentImporterContext context)
    {
        var identity = new ContentIdentity(filename, string.IsNullOrEmpty(ImporterName) ? GetType().Name : ImporterName);

        using (var importer = new AssimpContext())
        {
            _scene = importer.ImportFile(filename,
                //PostProcessSteps.FindInstances | // No effect + slow?
                PostProcessSteps.FindInvalidData |
                PostProcessSteps.FlipUVs |
                PostProcessSteps.FlipWindingOrder |
                //PostProcessSteps.MakeLeftHanded | // Appears to just mess things up
                PostProcessSteps.JoinIdenticalVertices |
                PostProcessSteps.ImproveCacheLocality |
                PostProcessSteps.OptimizeMeshes |
                //PostProcessSteps.OptimizeGraph | // Will eliminate helper nodes
                PostProcessSteps.RemoveRedundantMaterials |
                PostProcessSteps.Triangulate
                );

            _globalInverseXform = _scene.RootNode.Transform;
            _globalInverseXform.Inverse();

            _rootNode = new NodeContent
            {
                Name = _scene.RootNode.Name,
                Identity = identity,
                Transform = ToXna(_scene.RootNode.Transform)
            };

            _materials = ImportMaterials(identity, _scene);

            FindMeshes(_scene.RootNode, _scene.RootNode.Transform);

            if (_scene.HasAnimations)
            {
                var skeleton = CreateSkeleton();
                CreateAnimation(skeleton);
            }

            // If we have a simple hierarchy with no bones and just the one
            // mesh, we can flatten it out so the mesh is the root node.
            if (_rootNode.Children.Count == 1 && _rootNode.Children[0] is MeshContent)
            {
                var absXform = _rootNode.Children[0].AbsoluteTransform;
                _rootNode = _rootNode.Children[0];
                _rootNode.Identity = identity;
                _rootNode.Transform = absXform;
            }

            _scene.Clear();
        }

        return _rootNode;
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.