Hello everyone,

I have been trying to export models from 3DS max for use in my XNA program. The trouble I keep running into is that the axis keep getting rotated and/or flipped from what's in Max.

In order to test this, I have created a model that acts as an axis gizmo, with a cone pointing down the X axis, a Rectangle down the Y and a cylinder down the Z.

I have exported the model three different ways:

Max's built in .fbx exporter - The X points correctly, but Max's Z is now XNA's Y, and Max's Y is now XNA's -Z (Left-Handed).

PandaSoft DirectX Exporter (with Left-Handed coordinates turned ON) - The same as the FBX exporter

PandaSoft DirectX Exporter ( with Left-Handed coordinates turned OFF) - The X points correctly, the Y points correctly, but the Z has been flipped (Max's Z == XNA's -Z).

So far the PandaSoft DirectX Exporter with Left-Handed coordinates turned off produces the closest results, with the Z axis flipped. Has anybody else run into this problem What was your solution. I would really like to be able to model something in Max, and have the X,Y, and Z coordinates remain the same after the export.

Thanks in advance!

Re: XNA Game Studio Express 3DS Max export

Shawn Hargreaves - MSFT

This behavior is actually intentional.

3D packages all disagree about which way 'up' is. In Max, Z is up, but in many other packages, Y is up.

We wanted to make it easy for XNA games to use content from any package, and easy to reuse code from one XNA game to another, so we had to standardise on one particular direction for 'up'. We picked Y, which means we have to change any files that come in with Z as up to make them conform to this standard convention.

If you don't like that, you could write a custom content pipeline processor to flip them back again, but the easiest thing is probably just to stick with the XNA standard and use Y as up in your game (even if that means you have to build you models with Z as up in Max).

Re: XNA Game Studio Express 3DS Max export


Thanks for responding Shawn :)

I saw that XNA does indeed use Y=Up, and just as you've said, this would make sense since XNA is right-handed.

This can be really confusing when modelling in Max, since I will need to model my character rotated 90 degrees, so your idea of a new content pipeline processor sounds interesting to me, though I have a few questions:

If I write a new content pipeline processor, all I would want to do is rotate my exported model 90 degrees before it gets loaded as an XNA model. When in the pipeline is the processor called, and if I write my own, what will I need to rewrite (ie, do I need to write a .X file parser to create a new XNA Model Can I just slip my processor into a chain )


Re: XNA Game Studio Express 3DS Max export

Shawn Hargreaves - MSFT

You shouldn't really need to do any rotation. Just model your graphics with their top facing in the direction Max thinks is up (which happens to be Z), then when you render them in XNA, use the direction XNA thinks is up (Y) and they will come out the right way up. It won't be the same axis, but as long as the top of the object still faces upwards, surely that's what you want

Re: XNA Game Studio Express 3DS Max export


I know I'm being a pain in having my game mirror Max, but I set up the coordinate system with Z=up, Y=forward, X=right before I decided on using Max because that's what makes the most sense to me. Being able to edit verts in max, and know what the x,y,z position of the vert will be in-game is very useful to me. I followed your suggestion of a custom ContentProcessor, and now I have exactly what I want. Thanks very much for you help :)

Now I just set my models to use my MaxProcessor, and use the coordinate system that I like.

For anybody who is interested, here is the code for my 3ds max content processor. It's very simple and just rotates the scene back to how it was in Max.

#region using_statements
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;

class MaxProcessor : ModelProcessor
public override ModelContent Process(
NodeContent input, ContentProcessorContext context)
MeshHelper.TransformScene(input, Matrix.CreateRotationX( MathHelper.ToRadians( 90.0f )));
return base.Process(input, context);