I would like to get back to a topic asked earlier.
The assert in dgCollisionHeightField.cpp:1161 gets hit whenever a collision shape's AABB intersects with more than DG_MAX_COLLIDING_FACES of the heightfield. I understand the need for the check and the performance hit so many intersecting triangles will cause.
In release config, however the assert is ignored, but I get an access violation deeper down.
To reproduce, see the demo code below where I place a large box over a dense heightfield.
- Code: Select all
// bug repro demo
void LoadHeights(dFloat* elevation, int width, int height)
{
dFloat max_height = 0.2f;
for (int i = 0; i < width*height; ++i) {
elevation[i] = rand() * max_height / RAND_MAX;
}
}
void HeightFieldCollision(DemoEntityManager* const scene)
{
// load the sky box
scene->CreateSkyBox();
int size = 64;
dFloat* elevation = new dFloat[size * size];
LoadHeights(elevation, size, size);
dFloat extent = 20.0f; // world size
dFloat horizontal_scale = 20.0f / (size - 1);
// create the attribute map
char* const attibutes = new char[size * size];
memset(attibutes, 0, size * size * sizeof (char));
NewtonCollision* height_field = NewtonCreateHeightFieldCollision(scene->GetNewton(), size, size, 0, 0, elevation, attibutes, 1.0f, horizontal_scale, 0);
NewtonStaticCollisionSetDebugCallback(height_field, ShowMeshCollidingFaces);
float offset = -extent * 0.5f;
dMatrix mLocal(dGetIdentityMatrix());
mLocal.m_posit = dVector(offset, 0, offset);
NewtonCollisionSetMatrix(height_field, &mLocal[0][0]);
dMatrix matrix(dGetIdentityMatrix());
NewtonBody* terrain_body = NewtonCreateDynamicBody(scene->GetNewton(), height_field, &matrix[0][0]);
NewtonBodySetMassProperties(terrain_body, 0.0, NewtonBodyGetCollision(terrain_body));
NewtonDestroyCollision(height_field);
NewtonCollision* col = NewtonCreateBox(scene->GetNewton(), 20, 1, 20, 0, nullptr);
NewtonBody* body = NewtonCreateDynamicBody(scene->GetNewton(), col, &matrix[0][0]);
NewtonBodySetForceAndTorqueCallback(body, PhysicsApplyGravityForce);
NewtonBodySetMassProperties(body, 1.0, NewtonBodyGetCollision(body));
delete[] attibutes;
delete[] elevation;
dMatrix locationTransform(dGetIdentityMatrix());
locationTransform.m_posit.m_y = 2.0f;
scene->SetCameraMatrix(dQuaternion(locationTransform), locationTransform.m_posit + dVector(0, 5, 0));
NewtonDemos* const mainWindow = scene->GetRootWindow();
mainWindow->m_debugDisplayMode = 1;
}
There is simply no way to 100% guarantee that this state will not occur in production. Shouldn't there be a safer exit strategy for this?
Thanks
James