PhysX sometimes encounter assert error for moving a character to height fields.


As the title, when I moved a character on a height field, an assert error occurred.

I debugged the program and I found there was an illegal access for a Ps::Array. It was accessed for an index which is blocked by PX_ASSERT(i < mSize);

And the access occurred here, in the CctCharacterControllerCallbacks.cpp, line 766, in the getTriangle() function:

		visualizeTouchedTriangles(touchedMesh->mNbTris, touchedMesh->mIndexWorldTriangles, &worldTriangles.getTriangle(0), renderBuffer, offset, params.mUpDirection);

It is interesting that I am not using “PhysX Debug Visualization” but the gVisualizeTouchedTris flag had a value of “true”. I searched the flag and it looks like it is always true. So maybe it is a miss I think.

Thanks for any advise !


I am not aware of this specific bug but it is strange that gVisualizeTouchedTris is true. It’s an internal debug tool so I suspect it has been set to true by accident before a release, at some point. I suggest setting it to false. I will do that in our trunk ASAP.

Meanwhile I will also try to reproduce this bug, but it doesn’t happen in our internal tests so far.

  • Pierre

I suppose it can only happen when the array is empty. Could you check that when it happens for you, touchedMesh->mNbTris is 0 ?

In that case the fix would be either to test touchedMesh->mNbTris as well before calling visualizeTouchedTriangles, or maybe replace &getTriangle(0) with some other function like begin(). I will do one or the other and submit this to our trunk.

Thanks for the report.

Hi Pierre,

I tried to reproduce the bug and I found that it happens when I move a character controller to a height field’s back face.

Hope it helps.

P.S. I tested moving CCT to a height field’s back face by my test program of PhysX 3.4.1 and it works well. So maybe the reason of assert is my code, not the PhysX’s.

I tested for other situation and I found another bug that may relate to the question above.

When I drop a rigid dynamic(with geometry of sphere or convex mesh) to a height field which have grids for specific tesselation flags, assert of GuPCMContactMeshCallback.h line 164 will take an error.

PX_ASSERT(inds[0] == vertIndices[a] || inds[1] == vertIndices[a] || inds[2] == vertIndices[a]);

The specific pattern is for flags like this:


For tesselation flags like:


It happens with the smallest height field for 3x3 height samples. And I reproduced it in a very simple test code.

The error above occurred for a height field has same tesselation flags, but I am sorry that I don’t have enough time to test it.

Hope it helps.

Thanks for reporting the assert in GuPCMContactMeshCallback.h. That assert is assuming a particular tessellation format, which you aren’t using. The assert is confirming that the adjacent triangle shares an edge and coming to the conclusion that the vertices it expects to be shared are not shared.

Feel free to comment out or ignore that assert as it is incorrect. We will fix it up in a future release. The actual code computing the edge activity flags is correct, it is just the assert that is not correct.

Hi kstorey,

Thanks for you advise !

But by the way, I found that in the header “GuHeightField.h”, the triangles’ index writed in the comment around line 774 and line 829 are different from the PhysX user guide.

//      <---- COL  
//      0----2  1 R
//      | 1 /  /| O
//      |  /  / | W
//      | /  /  | |
//      |/  / 0 | |
//      1  2----0 V

External Media

And if the source code is correct, it seems that the algorithm(around line 837) for calculating triangles’ adjacency index is wrong.

if (isFirstTriangle(triangleIndex))
			adjacencyIndex0 = 0xFFFFFFFF;
			adjacencyIndex1 = triangleIndex + 1;
			adjacencyIndex2 = 0xFFFFFFFF;

			if((cell % (mData.columns) != 0))
				adjacencyIndex0 = triangleIndex - 1;

			if((cell / mData.columns != mData.rows - 2))
				adjacencyIndex2 = ((cell + mData.columns) * 2) + 1;
			adjacencyIndex0 = 0xFFFFFFFF;
			adjacencyIndex1 = triangleIndex - 1;
			adjacencyIndex2 = 0xFFFFFFFF;

			if(cell % (mData.columns) < (mData.columns - 2))
				adjacencyIndex0 = triangleIndex + 1;

			if(cell >= mData.columns - 1)
				adjacencyIndex2 = (cell - mData.columns) * 2;

Although, as what you said, maybe it is not used but I thing it should be reported.

Indeed there seems to be a bug in the adjacency code. Will fix it in next patch update.
Thanks for reporting,

Hi AlesBorovicka,

Thanks for your reply ! I will check it in next version of PhysX.