Heightfield DG_MAX_COLLIDING_FACES

Report any bugs here and we'll post fixes

Moderators: Sascha Willems, Thomas

Heightfield DG_MAX_COLLIDING_FACES

Postby jamesm6162 » Mon Dec 12, 2016 4:02 am

Hi

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
jamesm6162
 
Posts: 49
Joined: Wed Aug 12, 2015 8:50 am

Re: Heightfield DG_MAX_COLLIDING_FACES

Postby Julio Jerez » Mon Dec 12, 2016 9:31 am

yes I can place a check that stop collecting face ass soon as it reaches the max count, but other that that if the grid is too big, there is no enough information to figure out what face to collect.

do you want that check?

notice that the face count is 512 already, check for so many face brute force is a slow process.

a better solutions can be:
-use a lower LOD of you terrain for collision.
-partition your colliding object into a compound collision.

These makes the number of collected faces smaller.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Heightfield DG_MAX_COLLIDING_FACES

Postby jamesm6162 » Tue Dec 13, 2016 8:24 am

I agree completely.

But just in case it still happens, it would be nice to have a safe guard in place like the check you mentioned.

Thanks
jamesm6162
 
Posts: 49
Joined: Wed Aug 12, 2015 8:50 am


Return to Bugs and Fixes

Who is online

Users browsing this forum: No registered users and 7 guests