Tutorial: How to get XNA's SkinnedSample working with MonoGame

Thanks for the answer.

Tried that but no dice.
But let me ask you:
Must it be the very first animation in the file?
What configuration you leave in the Foward and Up dropboxes?

I’ll try again with a new model tomorrow and see what happens.

I always do “selected”, and have my armature + the mesh which it uses selected.

I don’t know about the “first animation” part, but it does help as Blender can be a bit wonky when it comes to assigning animations to multiple different armatures (this is likely not the problem with yours, as this bug just makes certain animations not export).

As for Forward and Up, I leave those unchanged and it works fine I think.

This could also potentially be the issue: The origin of each mesh in the armature has to be at [0,0,0].

If you’re still having trouble, you can upload the .blend file and I’ll have a look at it.

If you don’t mind taking a look.
There you go:
https://1drv.ms/u/s!AtearECqJxyXiuJo2taKO0H4h-ni0g

I’m very grateful for your help.

edit:
Forgot the textures: https://1drv.ms/u/s!AtearECqJxyXiuJpFb9eBKLkwIpGHg

edit 2:
After correcting some stuff I noticed that the Y and Z axes are switched in the animation (Rotating the root bone along Y axis makes the model rotate along Z axis in game and vice versa), did I do something wrong?
The code is now exactly the same as delivered by Microsoft

edit 3:
I drawed the bones using getWorldTransforms() and I got the right positions, but the skin transform seems to be broken

Hm… well I won’t be able to test this fully until I get home much later today, but I had a quick look-over your file, and one thing which sticks out to me is that if I move the mesh, it doesn’t warp when moved away from the armature as mine does. Maybe it needs to be parented to it? I’ll check more when I get home.

Just an aside, but how did you go about showing the names of your bones? I’m still using SkinnedSample, but I couldn’t find where, if at all, the names of bones were stored.

Edit: Also, if you want a potential (not the best, and might not work) fix, maybe try setting the scale of your mesh to half before applying the bone transforms to it?

The names are not stored by default, but you can make it do so:

  • In the SkinningData Class add a new property as List to keep the names and set it in the constructor. Decorate the property with [ContentSerializer] attribute.

  • In the file “SkinnedModelProcessor”, around the line 65 theres a loop iterating through the bones, create a list and add bone.Name into the list.

  • In theline where it sets model.Tag = new SkinningData, you include this list.

  • Build the content and the output will have this new data, you can access it at runtime now through the same property.

1 Like

Hey. So I had a look see (I don’t know much about this stuff myself). I didn’t have time to test it, but try parenting the mesh to the armature, selecting “automatic weights” when Blender prompts you, and then seeing how that goes. Also, if you don’t already, try getting the latest Blender just to be safe.

By the way, here are the export settings I use (that I know work). Ignore the “scale” part. I’ve set that to many values and all it does is grow/shrink the model (without causing the issue you’re having).

I did once have a distorting model like you’ve shown. Unfortunately, my solution was to re-make it from scratch (as I didn’t quite like how it was turning out anyway). The most notable thing I did differently when I remade it however was automatically applying weights.

I wish you the best of luck.

2 Likes

I’ll try doing everything you say and using the same configurations, if I success I inform you.

Thank you for you attention!

I finally made it work! With workarounds, but I’m ok with even so! I bet it is a bug in the Blender exporter and not in the Monogame importer.
I did it by rotating the bone -90º in the X axis and applying the transform (Y becames up) and then applying 90º back, without applying this time (Now whenever I edit in the Z axis, I the bone updates its Y axis, this made the Y and Z axis swap go away) and scaled 0.1 the model in relation to the bones (and it made the deform go away), now this is exactly I was expecting:

Milun, so many thanks to you, without your help and patience I wouldn’t be able to figure it out. You’re awesome.
Tonight I sleep listening to “We’re the champions” in my head. hahahaha

1 Like

I’ve not looked in to this subject for some time (so I’m no expert today).
But there were always a few tips and tricks in the past to getting Blender to export nice to XNA (other engines have similar issues). From Blender 2.59 the XNA importer was included with Blender but I’ve not checked where it’s up to of late so I’m downloading the latest 2.78 RC to verify.

The post on the blender site with all the info about exporting XNA FBX fro Blender is here:
https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/Blender-toXNA

Most of the points have been covered in this post but there are some additional bits and also links off to other supporting information (including some the awesome Shawn Hargreaves posts).

Will report back if I find anything shocking, or more likely, focus one of my next tutorials on this area on my new tutorial site:

Hope this helps.

2 Likes

good tutorial, I’ve got it working in just a few minutes without any problems.

However, the skinned sample is problematic in the way that it only displays keyframes - it does not blend between them! So if the keyframes are captured at low frequency the animation is super blocky.

A much improved version of the original XNA release can be found here. It blends between keyframes (linearly) and supports more stuff. And it deletes obsolete keyframes afaik.
http://metlab.cse.msu.edu/betterskinned.html

and it can be used in monogame in the same way as skinnedsample (as ContentPipelineExtensions!) and generally just keeping the structure from the xna sample solution.

Maybe one should start a discussion again whether or not that could come as default, but either way if there is a lot of demand I might make another sample class for monogame.

1 Like

I wrote a blog post once in how to double loading times of the original SkinnedSample. As with all samples, SkinnedSample focuses on one subject and might ignore other areas and practises you would normally use on a project.

Here is the Animation Processor + test/sample I currently use.
It can autogenerate keyframes & remove the fake root bone (emulate the behavior of XNA Model processor).

2 Likes

I think it should. This is pretty basic when you’re doing a 3D game

2 Likes

I agree, but then there has to be a “proper” implementation and the way basic things are handled has to be discussed (do we use quaternions for rotations? Dual quaternions? How many bones can our model have (is 72 enough / too much?) etc.

Plus the samples include no animation classes themselves, there is no handling of different animations build-in. So that would have to be done in a good way.

There was a discussion to add parts of the SkinnedSample to MonoGame on GitHub https://github.com/MonoGame/MonoGame/issues/3825
Looks like @nkast implemented some of it, but it got dropped eventually.

Yes, some decision would have to be made. I think it’s best if we open an issue on GitHub for discussion.

I think we should let users decide that. The built-in SkinnedEffect is available to everyone, so it’s easy to change the nr of bones. I think for flexibility it would be nice to allow either CPU skinning, the default SkinnedEffect or a custom effect.

just curious: What are the benefits of CPU skinning?

Heh, that’s a good point :stuck_out_tongue: I’m not sure if there are any actually. Can be nice if you have models with just a few bones to reduce effect switching cost maybe?

I was thinking it wouldn’t be too hard to make a content processor that lets you set the max number of bones. Actually it might be nice to have an effectprocessor that allows you to define any macros (key-value pairs). It would just add them at the top of your fx file before sending it through the regular effectprocessor.

It’s not like the effect isn’t called anyways - but with less bandwidth consumption i guess. Passing the arrays of bones to the shader and having more data per vertex might be a point, but I don’t think on current hardware it will ever be more expensive on GPU

Custom effects are currently not created for anything right?

Yeah that would be pretty simple, simply change the #define MAXBONES and done

What do you mean by that?

*created

I mean right now if a model is imported it gets an effect assigned from the ones that are already created, but it’s not specifically tailored to this model data, right? Nothing custom, nothing newly compiled

Nope. It’s just the stock effects. So yeah, it would be nice to have some more flexibility in this case