Blog

How to Load a 3D Collision Model Using the XNA Content Pipeline

Jan 4

Written by:
Tuesday, January 04, 2011  RssIcon


In almost all 3D games collisions between complex shaped objects must be detected. For collision detection the triangle meshes can be used directly but this is a lot slower than using boxes, spheres or convex shapes. Therefore, for each model a collision model should be created that consists only of simple primitives. This collection of shapes approximates the shape of the detailed 3D graphics model. This blog posts discusses how we can use the XNA content pipeline to load shapes from a collision model created in a 3D modeling tool. The example source code can be downloaded.

The Graphics Model

Here is the space ship model from the AppHub Chase Camera Example opened in Blender:

Model-In-Blender

It consists of several thousand faces – not ideal for collision detection Sad smile 

The Collision Model

For practical collision detection we have created a collision model that consists only of a few boxes, spheres and convex shapes. It is a crude approximation of the detailed graphics model – but sufficiently detailed for most cases.

Collision-Model-In-Blender

Using a 3D modeling tool for placing the approximated collision shapes is a lot more practical than defining the collision shapes in source code.

Now, we need a way to load this data in our XNA game. With the standard XNA model processor we can load the model but at runtime this leaves us only with the triangle mesh data. What we really need are boxes, spheres, etc. Therefore, we need a custom content processor for the XNA content pipeline.

Naming Scheme

When a collision model is imported in the content pipeline, triangle mesh data is imported. That means, instead of a box the content processor sees a triangle mesh with 8 vertices. To make the work easier for our content processor we apply a naming scheme to the collision model that is created in Blender. The name of each box collision shape ends with “Box”; for example “LeftFin_Box” (click the screen-shot above to see an enlarged version). Similarly, each sphere is named “XxxSphere” and each convex shape is named “XxxConvex”. This naming scheme allows the content processor to know which shape it must create for each mesh in the model.

CollisionModelSample

The rest is best explained in the source code directly. Download CollisionModelSample (The download is at the bottom of the Download page. In future releases of the DigitalRune Physics Bundle it will be included in the samples of the bundle. Update: The sample and source code is included in the DigitalRune Engine.)

Here is screenshot of the example. The model that is used for the fancy graphics.

CollisionModelSample0

The collision model that is used for collision detection:

CollisionModelSample1

6 comment(s) so far...


Gravatar

Re: How to Load a 3D Collision Model Using the XNA Content Pipeline

This is great. It guess its possible to setup ragdoll collisions boxes for skinned characters as well. :)

By Nelxon on   Wednesday, January 05, 2011
Gravatar

Re: How to Load a 3D Collision Model Using the XNA Content Pipeline

What a great sample! Thanks a lot!

By Nennig on   Wednesday, January 05, 2011
Gravatar

Re: How to Load a 3D Collision Model Using the XNA Content Pipeline

Is there anyway this content pipeline could be extended to handle meshes that were concave as well?

I'm trying to offload this process into the content pipeline as doing at run time is taking upwards of 3 minutes to finish:

_terrainCollisionModel = _content.Load("Models/Worlds/GreenWorld/terrain_collision");

// Extract the triangle mesh from the model.
// Note: XNA uses clockwise winding for triangle front sides and DigitalRune Physics uses
// counter-clockwise winding for front sides. FromModel() automatically flips the
// winding order.
TriangleMesh mesh = TriangleMesh.FromModel(_terrainCollisionModel);

// If you have a "thin" triangle mesh and you want both sides of the mesh to be solid,
// you can duplicate all triangles and reverse the winding order of the duplicated triangles.
// Add backsides:
var numberOfTriangles = mesh.NumberOfTriangles;
for (int i = 0; i ()); // A spatial partition to increase performance.

// Create a static rigid body with the mesh shape.
var terrainBody = new RigidBody(meshShape)
{
Name = "Terrain",
Pose = new DigitalRune.Geometry.Pose(new Vector3F()),
MotionType = MotionType.Static,
CcdEnabled = true
};

_simulation.RigidBodies.Add(terrainBody);

By winterkewl on   Tuesday, January 25, 2011
Gravatar

Re: How to Load a 3D Collision Model Using the XNA Content Pipeline

@winterkewl: I have moved your question to the forum:
www.digitalrune.com/Support/Forum/tabid/586/forumid/20/threadid/1878/scope/posts/Default.aspx

By HelmutG on   Tuesday, January 25, 2011
Gravatar

Re: How to Load a 3D Collision Model Using the XNA Content Pipeline

Can anyone recommend me a good tutorial how to implement content pipeline into project? it's just not working for me.

By Martin on   Sunday, March 24, 2013
Gravatar

Re: How to Load a 3D Collision Model Using the XNA Content Pipeline

I am not aware of any good tutorials. I have learned it from the XNA documentation and by going through the AppHub samples.

By HelmutG on   Monday, March 25, 2013

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment   Cancel 

Article Collection

A collection of the most useful blog articles can be found here:

Article Collection
(on Documentation page
)