Problem importing .fbx mesh

Mar 2, 2009 at 11:48 AM
Hey again. So I've been integrating 1.5 and all good so far except for one problem. Can't load my test mesh! The model contains a single mesh which the XNA model processor has no problem with. Using the Xen model processor I get a .xnb file containing only header info. For some reason it's not importing the geom data.

I tested the ship from the non-photorealistic xna sample and the lizard from the normal mapping sample. The ship has the same problem but the lizard works.

Printf debugging within the model processor reveals that the input node is named after the mesh but contains 0 children, likewise with the sample ship. The lizard however had an input node named RootNode and 3 children matching its 3 meshes.

Had my artist import the lizard but he didn't notice anything named RootNode.

Any ideas? Is there a particular way the model needs to be set up in Maya? We're using the 2009.3 fbx exporter.

Thanks in advance :)
Coordinator
Mar 2, 2009 at 9:10 PM

Thanks for reporting this, I'll check it out. I mostly test with .X models, as I have few .fbx models (So I guess I have always assumed they imported the same - the .fbx files I've tested with at least have always worked).

Coordinator
Mar 2, 2009 at 9:32 PM
Edited Mar 2, 2009 at 9:35 PM

I just had a quick debug of the mesh processor and the mistake was really obvious, you are right, if everything is in the root node it's ignored. (I'm amazed I've never run into it already, or anyone else for that matter):

The two important methods are 'ProcessSkeletonNodes' and 'ProcessMeshNodes'. The problem is, they check their children for content, but not the node itself. So the fix is quite simple, change:

		void ProcessSkeletonNodes(NodeContent node, ContentProcessorContext context, List<SkeletonData> skeletons)
		{
			foreach (NodeContent child in node.Children)
			{
				if (child is BoneContent)
				{
					skeletons.Add(ProcessSkeleton(child as BoneContent, context));
					continue;
				}

				ProcessSkeletonNodes(child, context, skeletons);
			}
		}

		void ProcessMeshNodes(NodeContent node, ContentProcessorContext context, List<MeshData> meshes, string rootPath, Dictionary<string> processedContent, SkeletonData skeleton, AnimationData[] animations)
		{
			foreach (NodeContent child in node.Children)
			{
				if (child is BoneContent && !importBoneContentMehses)
					continue;
				if (child is MeshContent)
				{
					meshes.Add(ProcessMesh(child as MeshContent, context, rootPath, processedContent, skeleton, animations));
					continue;
				}

				ProcessMeshNodes(child, context, meshes, rootPath, processedContent, skeleton, animations);
			}
		}

To:

		void ProcessSkeletonNodes(NodeContent node, ContentProcessorContext context, List<skeletondata> skeletons)
		{
			if (node is BoneContent)
			{
				skeletons.Add(ProcessSkeleton(node as BoneContent, context));
				return;
			}

			foreach (NodeContent child in node.Children)
			{
				ProcessSkeletonNodes(child, context, skeletons);
			}
		}

		void ProcessMeshNodes(NodeContent node, ContentProcessorContext context, List<meshdata> meshes, string rootPath, Dictionary<string> processedContent, SkeletonData skeleton, AnimationData[] animations)
		{
			if (node is BoneContent && !importBoneContentMehses)
				return;

			if (node is MeshContent)
			{
				meshes.Add(ProcessMesh(node as MeshContent, context, rootPath, processedContent, skeleton, animations));
				return;
			}

			foreach (NodeContent child in node.Children)
			{
				ProcessMeshNodes(child, context, meshes, rootPath, processedContent, skeleton, animations);
			}
		}

When I get home (I'm at work :) I'll commit it properly

Mar 2, 2009 at 10:57 PM
Cool, thought it might be something to do with it not being parented to a root bone. Thanks for that, I'll give it a try tonight.
Mar 2, 2009 at 11:40 PM
This is a content pipeline gotcha. ;)

Xna will only add a root node if the scene contains more than one object, so there often needs to be explicit code to deal with it.

Mar 3, 2009 at 9:50 AM
Good to know. Cheers guys, all good now :)