Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm working on a level-based survival game and I want to design my scenes in Maya and export them as a single model (with multiple meshes) into XNA.

My problem is that when I try to create Bounding Boxes(for Collision purposes) for each of the meshes, the are calculated from origin to the far-end of the current mesh, so to speak.

I'm thinking that it might have something to do with the position each mesh brings from Maya and that it's interpreted wrongly... or something.

Here's the code for when I create the boxes:

private static BoundingBox CreateBoundingBox(Model model, ModelMesh mesh)
    {

        Matrix[] boneTransforms = new Matrix[model.Bones.Count];
        model.CopyAbsoluteBoneTransformsTo(boneTransforms);

        BoundingBox result = new BoundingBox();

        foreach (ModelMeshPart meshPart in mesh.MeshParts)
        {
            BoundingBox? meshPartBoundingBox = GetBoundingBox(meshPart, boneTransforms[mesh.ParentBone.Index]);
            if (meshPartBoundingBox != null)
                result = BoundingBox.CreateMerged(result, meshPartBoundingBox.Value);
        }
        result = new BoundingBox(result.Min, result.Max);
        return result;
    }
    private static BoundingBox? GetBoundingBox(ModelMeshPart meshPart, Matrix transform)
    {
        if (meshPart.VertexBuffer == null)
            return null;

        Vector3[] positions = VertexElementExtractor.GetVertexElement(meshPart, VertexElementUsage.Position);
        if (positions == null)
            return null;

        Vector3[] transformedPositions = new Vector3[positions.Length];
        Vector3.Transform(positions, ref transform, transformedPositions);

        for (int i = 0; i < transformedPositions.Length; i++)
        {
            Console.WriteLine(" " + transformedPositions[i]);
        }
        return BoundingBox.CreateFromPoints(transformedPositions);
    }


public static class VertexElementExtractor
{
    public static Vector3[] GetVertexElement(ModelMeshPart meshPart, VertexElementUsage usage)
    {
        VertexDeclaration vd = meshPart.VertexBuffer.VertexDeclaration;
        VertexElement[] elements = vd.GetVertexElements();

        Func<VertexElement, bool> elementPredicate = ve => ve.VertexElementUsage == usage && ve.VertexElementFormat == VertexElementFormat.Vector3;
        if (!elements.Any(elementPredicate))
            return null;

        VertexElement element = elements.First(elementPredicate);

        Vector3[] vertexData = new Vector3[meshPart.NumVertices];
        meshPart.VertexBuffer.GetData((meshPart.VertexOffset * vd.VertexStride) + element.Offset,
            vertexData, 0, vertexData.Length, vd.VertexStride);

        return vertexData;
    }
}

Here's a link to the picture of the mesh(The model holds six meshes, but I'm only rendering one and it's bounding box to make it clearer: http://www.gsodergren.se/portfolio/wp-content/uploads/2011/10/Screen-shot-2011-10-24-at-1.16.37-AM.png The mesh that I'm refering to is the Cubelike one. The cylinder is a completely different model and not part of any bounding box calculation.

I've double- (and tripple-)-checked that this mesh corresponds to this bounding box.

Any thoughts on what I'm doing wrong?

share|improve this question

2 Answers 2

up vote 6 down vote accepted

I have found the solution to this problem of yours.

Instead of doing just the following in CreateBoundingBox:

BoundingBox result = new BoundingBox();

do this:

BoundingBox result = new BoundingBox();
result.Min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
result.Max = new Vector3(float.MinValue, float.MinValue, float.MinValue);

When you create a new BoundingBox, the Min value is set to 0,0,0. Then later where you merge the boundingbox with result, one of the values (x,y,z) stays 0, depending on the mesh's position. This causes the box to stretch to 0,0,0 when you draw the bounding box.

So setting the Max to the minimum possible, and Min to the maximum possible, the situation is avoided.

In my tests it did fix the issue.

share|improve this answer
    
+1 to finding that error, but also +1 to Jonathon Hobbs and the hint "In fact, it's drawing from the exact centre of that cylinder. This very unlikely to be a coincidence". What is the bet that cylinder is drawn at 0,0,0. :) –  Daniel Mar 1 '12 at 4:43

My insights on your situation:

  1. Your bounding box isn't bigger. It's exactly the right size to encompass those meshes, except it's offset by a certain amount along two axes. In fact, it's drawing from the exact centre of that cylinder. This very unlikely to be a coincidence, and in fact it's probably telling you exactly what the problem is.
  2. It's not necessarily the bounding box code that's doing something wrong. The meshes or bounding box could be using the wrong coordinates, or either one could be drawn incorrectly.
  3. You made no mention of walking through what your code does in the debugger. This will tell you where the problem is.
    • What are the bounding box and mesh values after you've calculated them?
    • Are they correct? If not, there's your problem.
    • If they're fine, you're drawing them wrong.

I'm not going to diagnose the problem in your code since that's a lot of different logic to look through that I can't run.

share|improve this answer
    
1. My apologies, the image is not completely correct. The cylinder and the cube(ish) are two different models. The cube is part of a bigger model and is one of six meshes, where only one is visible: the cylinder has nothing to do with that mesh. So... Ignore the cylinder is what I'm trying to say. :) 2-3. I've looked through the transformation Matrix of each mesh and they look to be correct. I've also run through a collision detection(with the cylinder in fact) and it collides within the drawn Bounding box. I'm on a laptop without XNA right now, but once I get back home, I'll provide more. –  Gunnar Södergren Oct 24 '11 at 7:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.