Model with multiple meshes on xbox360

Topics: Developer Forum, Project Management Forum, User Forum
Apr 15, 2007 at 12:23 PM
Hello,

Has anybody tried loading a Model consisting of multiple meshes on the Xbox? I have it working in windows just fine, i'm testing with a .x file containing two cubes both rotating in a different direction. The thing is, when i load my code on my xbox, my screen turns black :D.

If in the meantime i find out why this is happening, i will post it here. It's probably smart to post this test model here for reference, so here we go :).

http://www.pjstyle.net/xnatest.x
http://www.pjstyle.net/xnatestanimation.xml

Thanks!
Coordinator
Apr 15, 2007 at 3:29 PM
I'll take a look at this as soon as my xbox gets back from a land far, far away. So much for the exact same code working the same on both platforms :-/
Apr 15, 2007 at 7:47 PM
Hey dastle,

This is a problem i'm very anxious to see fixed. Maybe you can give me some pointers as to what might be going wrong, i'll have a look at the current source.

Thanks
Coordinator
Apr 15, 2007 at 10:38 PM
hmm... It's tough because the code for both is exactly the same, except for the limit on the palette size (40). But even then, the pipeline should split your model up if it has too many bones.

When your screen turns black, does that mean the game crashes? I hope so, because that will make it easier to debug :)

Other than that, I really don't know without stepping through with a debugger. As I said, the code is identical except for the palette size and strings of the type readers.
Apr 16, 2007 at 10:43 AM
The game doesn't actually crash, i can still debug it when i get my black screen :)! I've set some breakpoints in the Draw method and got the following exception after base.Draw():

A first chance exception of type 'Microsoft.Xna.Framework.Graphics.DriverInternalErrorException' occurred in Microsoft.Xna.Framework.dll

It really seems to be a problem with model containing more meshes, the test model i'm using contains three meshes, two of these meshes both have one bone doing some animation.
Apr 16, 2007 at 10:45 AM
That said, i now also have an issue of performance on my xbox. My collision detection (using your bone example) runs just fine on Windows but suffers extreme slowdowns on my xbox. I really hope the next XNA release resolved some of these incompatibilies :)
Coordinator
Apr 16, 2007 at 1:56 PM
Edited Apr 16, 2007 at 2:03 PM
The part of the collision detection that will run slow is the visualization. I really didn't focus at all out about performance for that (for example, the cube uses DrawUserPrimitives and the color on each vertex is changed when you change the color). The performance should be fine when you take out the cube and just access the bone transforms.

I've heard strange problems people are getting with xbox performance, but fortunately, at least last time I checked, the core animation library seems to run fine on it.

I'm curious to check this issue out. I should have all my parts back tomorrow.
May 5, 2007 at 8:33 PM
Edited May 5, 2007 at 9:11 PM
There are some performance problems with the library on the Xbox. However those are pretty easy to fix. They are caused by the Garbage Collection. The Xbox GC is non-generational unlike Windows. Because of this Windows handles GC really nice, the Xbox don't. On the Xbox it is best just not to create garbage if it can be avoided. I changed ModelAnimator.cs as follows and there are no more performance issues at least for me:

Added:
SkinInfoCollection infoCollection;
static ModelMesh mesh;
static ModelMeshPart currentPart;
static GraphicsDevice device;
static int numParts;
static int j;
static Effect currentEffect;
static EffectPassCollection passes;
static int k;
static EffectPass pass;
static int numPasses;

Changed Update to:
bonePoses.CopyAbsoluteTransformsTo(pose);
for (i = 0; i < skinInfo.Length; i ++)
{
if (palettei == null)
continue;
infoCollection = skinInfoi;
for( ii = 0; ii < infoCollection.Count; ++ii)
// foreach (SkinInfo info in infoCollection)
{
skinTransform = infoCollectionii.InverseBindPoseTransform;
Matrix.Multiply( ref skinTransform, ref poseinfoCollection[ii].BoneIndex,
out paletteiinfoCollection[ii].PaletteIndex );
}
}

if ( attachedObjects.Count > 0 )
{
foreach ( IAttachable attached in attachedObjects )
{
attached.CombinedTransform = attached.LocalTransform *
Matrix.Invert( posemodel.Meshes[0].ParentBone.Index ) *
poseattached.AttachedBone.Index * world;
}
}


and Draw to:
int index = 0;
// Update all the effects with the palette and world and draw the meshes
for (i = 0; i < numMeshes; i++)
{
mesh = model.Meshesi;
// The starting index for the modelEffects array
int effectStartIndex = index;
if (matrixPaletteParamsindex != null)
{
for ( ii = 0; ii < mesh.Effects.Count; ++ii )
// foreach (Effect effect in mesh.Effects)
{

worldParamsindex.SetValue( world );

matrixPaletteParamsindex.SetValue( palettei );
index++;
}
}
else
{
for ( ii = 0; ii < mesh.Effects.Count; ++ii )
// foreach ( Effect effect in mesh.Effects )
{

worldParamsindex.SetValue(posemesh.ParentBone.Index * world);
index++;
}
}
numParts = mesh.MeshParts.Count;
device = mesh.VertexBuffer.GraphicsDevice;
device.Indices = mesh.IndexBuffer;
for (j = 0; j < numParts; j++ )
{
currentPart = mesh.MeshPartsj;
if (currentPart.NumVertices == 0 || currentPart.PrimitiveCount == 0)
continue;
currentEffect = modelEffectseffectStartIndex+j;


device.VertexDeclaration = currentPart.VertexDeclaration;
device.Vertices0.SetSource(mesh.VertexBuffer, currentPart.StreamOffset,
currentPart.VertexStride);

currentEffect.Begin();
passes = currentEffect.CurrentTechnique.Passes;
numPasses = passes.Count;
for (k = 0; k < numPasses; k++)
{
pass = passesk;
pass.Begin();
device.DrawIndexedPrimitives(PrimitiveType.TriangleList, currentPart.BaseVertex,
0, currentPart.NumVertices, currentPart.StartIndex, currentPart.PrimitiveCount);
pass.End();
}

currentEffect.End();
}

Pretty programming it's not but it creates no garbage and best of all no Boxing. Boxing is just plain evil on the Xbox as it creates massive amounts of garbage and the Xbox sucks at Garbage Collection.

The multiple mesh problem I could not solve. As stated it crashes with a device exception after loading a multiple mesh animated model. If the mesh does not have multiple meshes it works fine. Depending on how you load it will crash differently. If you load a regular plain ole model immediately after the animated one it will crash there instead of in the drawing routine so it must be messing something up in load.

Edit:
Actually it seems to be that if you access a Effect after loading a animated model with multiple meshes it crashes.
Coordinator
May 8, 2007 at 6:53 PM
Edited May 8, 2007 at 6:55 PM
I've been quite busy with finals in the last couple of weeks but this is my first priority when I have the chance to look at it.