1
\$\begingroup\$

I'm taking a crack at a minecraft clone in Monogame, and I am trying to get my model to render as it's shown in Blender 2.9.1. When I look at the model in Blender, it looks great. When displaying in Monogame, the head is distinct but the body, arms, and legs are all mashed together. When I inspect the ParentBone for each ModelMesh, all except for the head have the same ModelTransform and Transform (but ModelTransform != Transform).

This is what I made in Blender: enter image description here

But this is how it renders in Monogame:

enter image description here

I then tried creating an armature and adding bones, but did not seem to change anything other than the model in Monogame had a lot more bones in it. I thought it had something to do with how I exported, but I tried both FBX All and Local All for scaling with no change. I've also tried exporting as DAE instead of FBX (still need to use the FBX Importer for this to work) and no change there either. enter image description here

Where I am missing a step that is causing what looks to be a translation issue? Minimally reproduceable code is below. I did find something on this site about storing the transforms for the bones, but when I tried to use that all I could see was the top of the head and couldn't rotate it? Or maybe I'm holding it wrong, I left it the code below commented out.

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace test
{
    public class Game1 : Game
    {
        private GraphicsDeviceManager _graphics;
        private Model model;
        private Texture2D texture;
        private Vector3 position;
        private Matrix world = Matrix.CreateTranslation(new Vector3(0, 0, 0));
        private Matrix view = Matrix.CreateLookAt(new Vector3(0, 0, 10), new Vector3(0, 0, 0), Vector3.UnitY);
        private Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800/480f, 0.1f, 100f);

        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            IsMouseVisible = true;
        }

        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            base.Initialize();
        }

        protected override void LoadContent()
        {
            model = Content.Load<Model>("human");
            texture = Content.Load<Texture2D>("human_texture");;
            position = new Vector3(0, 0, 0);
            world = Matrix.CreateRotationX(-0.5f) * Matrix.CreateRotationY(0.5f) * Matrix.CreateRotationZ(0.1f)  * Matrix.CreateTranslation(position);

            // TODO: use this.Content to load your game content here
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();
                world = Matrix.CreateRotationX(-0.5f) * Matrix.CreateRotationY(0.5f) * Matrix.CreateRotationZ(0.1f)  * Matrix.CreateTranslation(position);
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            // pixelate textures
            GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap;

            // lifted this from somewhere on the internet, but all I see is the top of the head and can't rotate when I use it?
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = world;//transforms[mesh.ParentBone.Index];
                    effect.View = view;
                    effect.Projection = projection;
                    effect.Texture = texture;
                }
                mesh.Draw();
            }

            base.Draw(gameTime);
        }
    }
}

I've also uploaded my full .blend file, the generated FBX, and the texture here.

\$\endgroup\$
3
\$\begingroup\$

I’m not an expert. I only just recently got into modding using Blender.

I had a similar issue with a custom model I imported into MonoGame using FXB format. What fixed it for me was downgrading to Blender 2.79b. In 2.8, Blender stopped supporting the FXB 7.4 binary export format, which also had something to do with how the program handles bounding boxes.

I’d start there and see if it fixes your issue. Be warned, you will have to relearn/rebind a lot of controls and it will be frustrating.

\$\endgroup\$
0
\$\begingroup\$

Ah, I forgot to update this with the answer I found. I was still able to keep the current blender version, but I needed to do this:

effect.World = transforms[mesh.ParentBone.Index] * world; // (don’t forget - order is important)

The answer source is from the monogame forums here: https://community.monogame.net/t/exported-fbx-to-monogame-doesnt-translate-all-meshes/14887

(AlienScribble, if you're on here post your answer and I'll mark yours as accepted)

\$\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.