Bounce from joint of 2 triangleMeshes

Hi,

I create 2 triangleMeshes with exactly the same height, closely to each other.
Then I slide an object on this surface. But when the first triangleMesh ends, and the second starts, a large force appears.

The similar situation is described in PhysX help (Contact Modification).
But I don’t undestand how I can use contact modification.
And how I can differentiate this collision with bottom from collisions with walls?

External Media

Hi.

Which version of PhysX are you using?
A question: Why are you using 2 planes instead of one?

Contact modification:
Read the PhysX Guide, it says that you need to code a class which inherts from
PxContactModifyCallback.

Inside this class, you need to implement
void onContactModify(PxContactModifyPair* const pairs, PxU32 count);

You also have to register your callback via the contactModifyCallback member of PxSceneDesc or the setContactModifyCallback() method of PxScene.

When you did it right, the you will get an callback while something is colliding.

You could modify the contacts like this:

void YourCallbackClass::onContactModify(PxContactModifyPair* const pairs, PxU32 count)
{
for (PxU32 a = 0; a < count; a	++)
    {
for (unsigned int b = 0; b <  pairs[a].contacts.size(); b++) // All contacts are going to ignore..
	pairs[a].contacts.ignore(b);
    }
}

— So you need to add to your shape or actor special data to the void * userData member to
identificate your collision objects. (This is the way I did it)

Like this:

shape->userData = new ActorUserData(“Wall”); // Create a new class ActorUserData or what ever…
… etc

Or you could take the normals of the contact and do some fancy stuff with it :D No, that wont work…
I guess its the best way to use the void pointer to do what ever you want with it.

Or just filter these to collisions in a special callback - the first one goes to the ship, the other one to the wall / ground / what ever … there are other ways to archiev it.

Or only generate contacts inside your filterCallback using special filtergroups …

Thank you very much for your answer.

But there are several problems:

  1. Bottom and walls are in one triangle mesh. And there are in one actor, so setting ActorUserData doesn’t solve the problem
  2. Checking the normals of the contact is good solution. Maybe checking forces is better soluion, as a large horizontal force appears. But I don’t know how I can extract contact forces or normals.
    Which structure of NxContactCallbackData should I use?

I tried to use “error” field, but it’s only 1-dimensional data.

We have a haptic simulation in which we sometimes als have objects organized in a similar way. Then we feel what you probably see. Once we also implemented a manikin with a body and a full 6 dof arm. When the upper arm or lower arm hit the body (al made out of shape edged triangular meshes) we often got a huge shock.

For the first case we noted that decreasing the skinwith/rest depth ( px2.x/px3.x), but also using chamfered edges helps. For the second case we changed the mesh of the manikins body to a capsule (an other analitical physx shape could also be used), which completely stoped the shocks. Looking at your scene I cannot tell how thin the skinwith is but I can see an shap edged (concave?) ship. Consider putting a sphere or capsule in front.

Ship hull is auto-generated. It’s hard to put capsule in the front.

Instead, I am ignoring contats, which are close to an edge of a triangle mesh.
It works!

virtual bool  onContactConstraint  ( NxU32 &  changeFlags,
      const NxShape *  shape0,
      const NxShape *  shape1,
      const NxU32  featureIndex0,
      const NxU32  featureIndex1,
      NxContactCallbackData &  data
      )

  {
    NxVec3 error = data.error;

    NxActor &actor0 = shape0->getActor();
    NxActor &actor1 = shape1->getActor();

    NxVec3 localpos;
    NxActor* actor =  NULL;

    // Find which object is ship, and which is terrain.
    if (getActorType(&actor0) == NxActorEx::TYPE_TERRAIN)
    {
      localpos = data.localpos0;
      actor = &actor0;
    }
    else if (getActorType(&actor1) == NxActorEx::TYPE_TERRAIN)
    {
      localpos = data.localpos1;
      actor = &actor1;
    }

    if (!actor)
      return true;

    const NxVec3 actorPos = actor->getGlobalPosition();
    const NxVec3 pos = localpos - actorPos;

    // Filter contacts on an edge.
    static const double FILTER_DISTANCE = 0.05;

    double cellSize = 1000; //1 km.

    const double dx = cellSize / 2 - abs(pos.x);
    const double dy = cellSize / 2 - abs(pos.z);

    if (dx < FILTER_DISTANCE ||
        dy < FILTER_DISTANCE)
    {
      return false; // ignore contacts
    }

    return true;
  }