I am trying to make bounding boxes for my models. My code works fine if the model is imported as a COLLADA (.dae) file. When I try to import a model that has .fbx extension, my bounding box messes up. Here's a screenshot (purple cylinder is imported as .dae and the red jet is imported as .fbx):
As you can see the box is perfect for the cylinder but for the jet it's massive. It extends beyond the playing field. I don't understand why this is happening. Here's my code for generating a bounding box:
class MeshModel
{
public List<BoundingBox> boundingBoxes;
public MeshModel(Model model)
{
// Set up model data
boundingBoxes = new List<BoundingBox>();
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);
foreach (ModelMesh mesh in model.Meshes)
{
Matrix meshTransform = transforms[mesh.ParentBone.Index];
boundingBoxes.Add(BuildBoundingBox(mesh, meshTransform));
}
}
private BoundingBox BuildBoundingBox(ModelMesh mesh, Matrix meshTransform)
{
// Create initial variables to hold min and max xyz values for the mesh
Vector3 meshMax = new Vector3(float.MinValue);
Vector3 meshMin = new Vector3(float.MaxValue);
foreach (ModelMeshPart part in mesh.MeshParts)
{
// The stride is how big, in bytes, one vertex is in the vertex buffer
// We have to use this as we do not know the make up of the vertex
int stride = part.VertexBuffer.VertexDeclaration.VertexStride;
VertexPositionTexture[] vertexData = new VertexPositionTexture[part.NumVertices];
part.VertexBuffer.GetData(part.VertexOffset * stride, vertexData, 0, part.NumVertices, stride);
// Find minimum and maximum xyz values for this mesh part
Vector3 vertPosition = new Vector3();
for (int i = 0; i < vertexData.Length; i++)
{
vertPosition = vertexData[i].Position;
// update our values from this vertex
meshMin = Vector3.Min(meshMin, vertPosition);
meshMax = Vector3.Max(meshMax, vertPosition);
}
}
// transform by mesh bone matrix
meshMin = Vector3.Transform(meshMin, meshTransform);
meshMax = Vector3.Transform(meshMax, meshTransform);
// Create the bounding box
BoundingBox box = new BoundingBox(meshMin, meshMax);
return box;
}
public void Draw(BasicEffect boxEffect, Matrix View, Matrix Projection, Matrix World, GraphicsDevice device)
{
// Initialize an array of indices for the box. 12 lines require 24 indices
short[] bBoxIndices = {
0, 1, 1, 2, 2, 3, 3, 0, // Front edges
4, 5, 5, 6, 6, 7, 7, 4, // Back edges
0, 4, 1, 5, 2, 6, 3, 7 // Side edges connecting front and back
};
// Use inside a drawing loop
foreach (BoundingBox box in boundingBoxes)
{
Vector3[] corners = box.GetCorners();
VertexPositionColor[] primitiveList = new VertexPositionColor[corners.Length];
// Assign the 8 box vertices
for (int i = 0; i < corners.Length; i++)
{
primitiveList[i] = new VertexPositionColor(corners[i], Color.White);
}
boxEffect.World = World;
boxEffect.View = View;
boxEffect.Projection = Projection;
boxEffect.TextureEnabled = false;
// Draw the box with a LineList
foreach (EffectPass pass in boxEffect.CurrentTechnique.Passes)
{
pass.Apply();
device.DrawUserIndexedPrimitives(PrimitiveType.LineList, primitiveList, 0, 8, bBoxIndices, 0, 12);
}
}
}
}
I draw my models like this:
public void Draw(GraphicsDevice graphicsDevice)
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.View = camera.View;
effect.World = worldMatrix;
effect.Projection = camera.Projection;
effect.EnableDefaultLighting();
mesh.Draw();
// Debug: Draw bounding boxes
modelBox.Draw(effect, camera.View, camera.Projection, effect.World, graphicsDevice);
}
}
}
Any help would be appreciated!