PhysX materials with NxHeightFieldSample

Started by
7 comments, last by jezham 15 years, 9 months ago
I need many different materials to use with my terrain, and I have no idea on how to upload them to the NxHeightFieldSample vs. the examples I am seeing are for NxTriangleMeshDesc. the sample that physx shows is this

NxTriangleMeshDesc terrainDesc;
//add the mesh material data:
terrainDesc.materialIndexStride			= sizeof(NxMaterialIndex);
terrainDesc.materialIndices				= gTerrainMaterials;

but I don't see this in the NxHeightFieldSample. what I have is this

const int matrixSize = 3;
	const NxMaterialIndex matrix[9][3] =
	{
		// {tesselation, material0, material1}
		{0,1,1}, {0,1,1}, {0,1,1}, 
		{0,1,1}, {0,1,1}, {0,1,1}, 
		{0,1,1}, {0,1,1}, {0,1,1} 
	};
	int size = mapData.mapSize * mapData.mapSize;//size of map width * height
	NxHeightFieldSample* auiSample = new NxHeightFieldSample[size];
	NxHeightFieldSample* currentSample = auiSample;
	unsigned int index = 0;
	for(unsigned int row = 0; row < mapData.mapSize; ++row)
	{
		for(unsigned int column = 0; column < mapData.mapSize; ++column)
		{
			NxU32 matrixOffset            = (row % matrixSize) * matrixSize + (column % matrixSize);
			currentSample->height         = terrain->height_imageData[index];
			currentSample->materialIndex0 = matrix[matrixOffset][1];
			currentSample->materialIndex1 = matrix[matrixOffset][2];
			currentSample->tessFlag       = matrix[matrixOffset][0];
			currentSample++; index++;
		}
	}
	NxHeightFieldDesc kHeightFieldDesc;
	kHeightFieldDesc.format              = NX_HF_S16_TM;
	kHeightFieldDesc.nbRows              = mapData.mapSize;//width
	kHeightFieldDesc.nbColumns           = mapData.mapSize;//height
	kHeightFieldDesc.thickness           = -255.0f * heightScale;
	kHeightFieldDesc.convexEdgeThreshold = 0;
	kHeightFieldDesc.samples             = auiSample;
	kHeightFieldDesc.sampleStride        = sizeof(NxHeightFieldSample);

	NxHeightField* pkHeightField = pSDK->createHeightField(kHeightFieldDesc);
	delete []auiSample;

	// description
	NxHeightFieldShapeDesc kHeightFieldShapeDesc;
	kHeightFieldShapeDesc.heightField  = pkHeightField;
	kHeightFieldShapeDesc.shapeFlags   = NX_SF_FEATURE_INDICES;
	kHeightFieldShapeDesc.heightScale  = heightScale;
	kHeightFieldShapeDesc.rowScale     = rowScale; 
	kHeightFieldShapeDesc.columnScale  = colScale;
	kHeightFieldShapeDesc.holeMaterial = 0;
	kHeightFieldShapeDesc.meshFlags    = NX_MESH_SMOOTH_SPHERE_COLLISIONS;

and would like to add these terrain materials to the NxHeightField example

NxMaterialDesc m;
	m.restitution        = 0.0;
	m.staticFriction     = 0.5;
	m.dynamicFriction	 = 0.5;
	NxMaterial* material = physXScene->getMaterialFromIndex(0);
	material->loadFromDesc(m);

	//terrain materials
	m.restitution		= 1.0f;
	m.staticFriction	= 0.0f;
	m.dynamicFriction	= 0.0f;
	materialIce = physXScene->createMaterial(m)->getMaterialIndex();
	m.restitution		= 0.3f;
	m.staticFriction	= 1.2f;
	m.dynamicFriction	= 1.0f;
	materialRock = physXScene->createMaterial(m)->getMaterialIndex();
	m.restitution		= 0.0f;
	m.staticFriction	= 3.0f;
	m.dynamicFriction	= 1.0f;
	materialMud = physXScene->createMaterial(m)->getMaterialIndex();
	m.restitution		= 0.0f;
	m.staticFriction	= 0.0f;
	m.dynamicFriction	= 0.0f;
	materialGrass = physXScene->createMaterial(m)->getMaterialIndex();

Advertisement
In each current sample, store the required material index for both triangles (0/1).

currentSample->materialIndex0 = materialGrass;
currentSample->materialIndex1 = materialGrass;
...

Personally I assign a texture to each vertex, so this means that each triangle will be a mixture of materials. Blending textures is fine for gfx, but for physics material you have to take an average and apply it to the whole triangle. And iirc you can only have 128 materials...a rough guide would be 16 'shades' of grass, mud...etc if you get my drift :)
Thanks for the reply Jezham.

What I am trying to do is stop my vehicle from going up steep cliffs. It's still not working.

for(unsigned int row = 0; row < mapData.mapSize; ++row)	{		for(unsigned int column = 0; column < mapData.mapSize; ++column)		{			NxU32 matrixOffset            = (row % matrixSize) * matrixSize + (column % matrixSize);			currentSample->height         = terrain->height_imageData[index];			float heightLimit = .25f * currentSample->height;			if(currentSample->height > heightLimit)			{				currentSample->materialIndex0 = materialRock;				currentSample->materialIndex1 = materialRock;			}			else			{				currentSample->materialIndex0 = materialGrass;				currentSample->materialIndex1 = materialGrass;			}			currentSample->tessFlag = matrix[matrixOffset][0];			currentSample++; index++;		}	}//terrain materials	NxMaterialDesc materialDescIce;	materialDescIce.restitution		= 1.0f;	materialDescIce.staticFriction	= 0.0f;	materialDescIce.dynamicFriction	= 0.0f;	materialIce = physXScene->createMaterial(materialDescIce)->getMaterialIndex();	NxMaterialDesc materialDescRock;	materialDescRock.restitution	= 0.3f;	materialDescRock.staticFriction	= 1.2f;	materialDescRock.dynamicFriction= 1.0f;	materialRock = physXScene->createMaterial(materialDescRock)->getMaterialIndex();	NxMaterialDesc materialDescMud;	materialDescMud.restitution		= 0.0f;	materialDescMud.staticFriction	= 3.0f;	materialDescMud.dynamicFriction	= 1.0f;	materialMud = physXScene->createMaterial(materialDescMud)->getMaterialIndex();	NxMaterialDesc materialDescGrass;	materialDescGrass.restitution		= 0.0f;	materialDescGrass.staticFriction	= 0.0f;	materialDescGrass.dynamicFriction	= 0.0f;	materialGrass = physXScene->createMaterial(materialDescGrass)->getMaterialIndex();


No prob, but iirc you are using the wheelShape? If so, again iirc (as I use sphere's and joints for wheels), the wheelShape does *not* take in to consideration the material at the contact point! You should be able to manually detect it somehow, and then update your parameters.

This was one of the reasons that I gave up on the shape, and went about making wheels manually. But perhaps there was something I missed at the time as I've not seen any mention of this before?
I remember posting a similar question about wheelShape and steep gradients, but there were no replies...Think I called the post Spider Car!

Try testing the friction with a box shape, just to check your materials are correctly configured. The code looks fine. Are you 100% sure that the currentSample->height value is what you expect it to be?
I will have to look into it, BTW this is on 2.7.3 if that matters.
Well from the looks of it the car will go up hills still with 2.7.3. SO what, check the hills for to steep of a cliff myself now?

As for the correct height values they must be, as the car drives up the hill side, and traverses the terrain correctly.
I really know how frustrating this is for you.

The side effect you're experiencing has exactly the same symptoms as when a sphere touches a heightfield with the "NX_MESH_SMOOTH_SPHERE_COLLISIONS" flag enabled. Just roll a single sphere over a "hilly" terrain with this flag and watch the wonders of reverse gravity...disable the flag and all is perfect!

But with the wheelShape I could never find a solution? I tried: counter-acting positive vertical acceleration. Even with my sphere/joint vehicle - a zero-material would not prevent this 2D phenomenon.

If I had to work on wheelShape code now (apart from strongly suggesting that the sphere/joint combo is the way to go), I would have a vertical barrier preventing the wheelShape from getting near a steep gradient. Plus I would find a way to disable collision with the wheelShape and barrier...hence not much of an off-road sim left - sphere/joint is the way to go, results are perfect then.

Why not create a second vehicle using the suggested method, chances are you will prefer it's characteristics so much that you will stick with it.
Hye jezham, you must have read my mind, I was thinking of using some kind of static actor shape and putting that around the steep hills, to stop the movement up the hills. Yeah it will not be perfect, but this is more of a 3D arcade 3rd person collect coins game. Not a simulator. Have you tried this on 2.8.1? Does the same issue still show up there?
Quote:Original post by MARS_999
Hye jezham, you must have read my mind, I was thinking of using some kind of static actor shape and putting that around the steep hills, to stop the movement up the hills. Yeah it will not be perfect, but this is more of a 3D arcade 3rd person collect coins game. Not a simulator. Have you tried this on 2.8.1? Does the same issue still show up there?


Hi MARS_999, the barrier method will still require the vehicle to have bumpers which prevents the wheelShape's "ray" from ever penetrating the barrier. Else you will find the car literally drives up the wall still!

Reducing your longitudal stiffnessFactor helps allow wheelspin, but then you can't have nice acceleration...so a juggling act trying to find good values.
I guess you could try lowering this rapidly, based on the ground normal dot( up ), but again this will require some tuning...e.g. you want to be able to accelerate down hills, but not up!

Overall, the wheelShape requires workarounds.

This topic is closed to new replies.

Advertisement