Tutorial 106: - Mesh Collision

From Newton Wiki
Jump to: navigation, search

With this tutorial I introduce how create complex mesh geometry for the background collision. Select project Tutorial_106_MeshCollision as Startup project in visual studio and open file CreateScene in the editor and find function CreateScene. Function Scene Mesh is very much identical to any of the Scene mesh of previous tutorials with the exception that instead of using a big flat box as our static environment collision, we will use a more artist generated mesh for environed collision. This happens almost at the beginning of function CreateScene by calling function CreateMeshCollision

	// Create a large body to be the floor
	floor = sceneManager->CreateEntity();
	floor->LoadMesh ("LevelMesh.dat");

	// add static floor Physics
	shape = CreateMeshCollision (world, floor, NULL);
	floorBody = CreateRigidBody (world, floor, shape, 0.0f);
	NewtonReleaseCollision (world, shape);

The function CreateMeshCollision is part of a series of utility functions that create many of the various trimesh collision shapes the engine supports and the application uses. We recommend the application programmer to include it in their code. The function looks like this:

NewtonCollision* CreateMeshCollision (NewtonWorld* world, Entity* ent, int* shapeIdArray)
	NewtonCollision* collision;

	// now create and empty collision tree
	collision = NewtonCreateTreeCollision (world, 0);

	// start adding faces to the collision tree 
	NewtonTreeCollisionBeginBuild (collision);
	// step over the collision geometry and add all faces to the collision tree 
	for (int i = 0; i <  ent->m_subMeshCount; i ++) {
		// add each sub mesh as a face id, will will use this later for a multi material sound effect in and advanced tutorial
		for (int j = 0; j < ent->m_subMeshes[i].m_indexCount; j += 3 ) {
			int index;
			dVector face[3];

			index = ent->m_subMeshes[i].m_indexArray[j + 0] * 3;
			face[0] = dVector (ent->m_vertex[index + 0], ent->m_vertex[index + 1], ent->m_vertex[index + 2]);

			index = ent->m_subMeshes[i].m_indexArray[j + 1] * 3;
			face[1] = dVector (ent->m_vertex[index + 0], ent->m_vertex[index + 1], ent->m_vertex[index + 2]);

			index = ent->m_subMeshes[i].m_indexArray[j + 2] * 3;
			face[2] = dVector (ent->m_vertex[index + 0], ent->m_vertex[index + 1], ent->m_vertex[index + 2]);

			if (shapeIdArray) {
				NewtonTreeCollisionAddFace(collision, 3, &face[0].m_x, sizeof (dVector), shapeIdArray[i]);
			} else {
				NewtonTreeCollisionAddFace(collision, 3, &face[0].m_x, sizeof (dVector), i + 1);

	// end adding faces to the collision tree, also optimize the mesh for best performance
	NewtonTreeCollisionEndBuild (collision, 1);

	return collision;

A collision tree can be seen as an array of convex faces that form a mesh object, each face is single sided and can have collision ID.

The function first create and empty collision tree by calling function NewtonCreateTreeCollision,

Then it starts adding face to the Mesh by calling NewtonTreeCollisionBeginBuild. Then iterates over each and every one of the face of the mesh adding them to the collision object. Faces do not have to be triangles, but since this is a graphics entity that can only render triangle we know they are triangles.

The function implements two ways to specify the face ID, the first is by enumerating the in and ascending order the mesh render material, the second is more advance and it is the by reading an ID from an indirect lookup table of material IDs passed by the application. This second method is the more general because it can map render material to physics Materials, plus any application can write exported to save these kind of information to tag face in a visual mesh.

After all of the faces are added to the collision shape it is finalized by a call to NewtonTreeCollisionEndBuild function.

Collision trees have the ability to optimize the collision mesh by removing shared edges of faces that are convex and coplanar, in such cases the edge is removed. These properties greatly improve the performance of the collision since each time two faces are combined into one, the amount of work by the collision engine is reduced by half. Plus in addition the engine does not have to spend time figuring out if and edge contact is part of the final set of contact with some other object. Optimizing the collision tree is optional.

After this is done the function return s the collision mesh, and the application can use it to attach it to any rigid body.

There is one more thing, that is not specified in the scene function, and that is, that in the Newton engine when a collision tree or any polygonal mesh is assigned to a rigid body, the body becomes automatically static, newton only supports static collision trees.

With this we finish this tutorial and now you should be ready to make scenes with normal collision trees for your application. In the Next tutorial I will explain how to use another common static data structure use in games the Height field collision shape.