Tutorial 107: - Height Field Collision

From Newton Wiki
Jump to: navigation, search

With this tutorial I introduce another popular collision shape called HeightField Collision.

Select project Tutorial_107_HeightFieldCollision as Startup project in visual studio, open file CreateScene in the editor and find function CreateScene.

Function CreateScene 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 procedural rolling terrain made out of a height field stored into a bitmap.

This happens almost at the beginning of function CreateScene by calling function CreateHeightFieldCollision

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

	// add scene collision from a level mesh
	shape = CreateHeightFieldCollision (world, "h2.raw", 0);
	floorBody = CreateRigidBody (world, floor, shape, 0.0f);
	NewtonReleaseCollision (world, shape);

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

The function looks like this:

// Create a height field collision form a elevation file
NewtonCollision* CreateHeightFieldCollision (NewtonWorld* world, char* fileName, int* shapeIdArray)
	int width;
	int height;
	char* attributes;
	unsigned short* elevations;
	FILE* file;
	NewtonCollision* collision;
	char fullPathName[2048];

	#define CELL_SIZE				12.0f
	#define ELEVATION_SCALE			256.0f 
	#define TEXTURE_SCALE			(1.0f / 16.0f)

	//load from raw data
	GetWorkingFileName (fileName, fullPathName);
	file = fopen (fullPathName, "rb");
	_ASSERTE (file);

	width = 256;
	height = 256;

	// load the data
	elevations = malloc (width * height * sizeof (unsigned short));
	attributes = malloc (width * width * sizeof (char));
	fread (elevations, sizeof (unsigned short), width * height, file);

	memset (attibutes, 1, width * height * sizeof (char));
	if (shapeIdArray) {
		for (int i = 0; i < width * height; i ++) {
			attibutes[i] = char(shapeIdArray[0]);

	collision = NewtonCreateHeightFieldCollision (world, width, height, 0, elevations, attributes, CELL_SIZE, ELEVATION_SCALE_INV, 0);
	free (elevations);
	free (attibutes);
	fclose (file);

	return collision;

A height Field collision is a procedural mesh, that can be built very easily by conversion each cell of an elevation map to two triangles sharing a mid diagonal

The function first reads the Elevation map from a file. The dimensions of the map are hard-coded to 256 x 256 in the demo, but can be of any desired size.

The first are two streams of information, the Elevation data, and the attribute data. The Elevation data must be a 16 bit unsigned map, and attribute data is a 8 bit channel of cell Id, The cell ID are the face Id the will be reported back by the Material system when a body collide with the terrain.

In this case and since we do not have and Terrain editor we simple save the value of 1 into each attribute ID

Then once we have this information we call function NewtonCreateHeightFieldCollision to have the engine making the collision shape.

There are two ways to set the cell diagonal, and this is from lower left to upper right, of from lower right to upper left.

The rest of the parameters are just the horizon and vertical spacing of each cell and the vertical scale factor of each elevation.

Then the function returns the collision shape to the caller.

With this we complete this tutorials and I hope users can have an easy time adding terrain mesh collision to their own projects.

Later in an advanced tutorial we will use the function with other types of collision shapes like Collision Trees, convex hull, compound collision etc, to make a complex collision shape called SceneCollision which will contain many other shapes as child shapes.