counter-intuitive contact point position (plane & primitive)

Post Reply
kangd
Posts: 9
Joined: Tue Oct 24, 2017 11:51 am

counter-intuitive contact point position (plane & primitive)

Post by kangd »

Hi,

I am building a contact simulator with collision detection by bullet physics.

As I tested collision between static plane vs primitives (sphere, box, cone, cylinder), I found that position of contact points are counter-intuitive when the surface of plane and surface of primitives are faced.

Fox box, I expected center of lower surface would be a contact point but actually, one of the corner is the contact point,

and for cylinder, contact point is not a center of lower surface, but edge of the lower surface.


I've obtained contacts as follows:

Code: Select all

  // bullet collision detecting
  collisionWorld_->performDiscreteCollisionDetection();

  // search colliding objects
  int numManiforlds = collisionDispatcher_->getNumManifolds();

  for (int i = 0; i < numManiforlds; i++) {
    btPersistentManifold *contactManifold = collisionDispatcher_->getManifoldByIndexInternal(i);

    const auto *bulletObjectA = contactManifold->getBody0();
    const auto *bulletObjectB = contactManifold->getBody1();
    int objectIndexA = bulletObjectA->getWorldArrayIndex();
    int objectIndexB = bulletObjectB->getWorldArrayIndex();
    int numContacts = contactManifold->getNumContacts();

    for (int j = 0; j < numContacts; j++) {
      btManifoldPoint &pt = contactManifold->getContactPoint(j);
      ...(get position from pt.getPositionsWorldOnA(), and pt.getPositionWorldOnB)
    }
  }

But, for instance, the best scenario for me is getting 1 collision point at the center of lower surface.

(even better if I can get 4 collision points for box vs plane situation which are the corner points of lower surface of box.)

I found I can get 4 collision point between box vs box collision, but in this case, collision point of cylinder and cone are not the center of lower surface.

Is there any way to do what I want?

FYI, I attached screenshot from my visualization tool.
Attachments
bullet.png
bullet.png (85.7 KiB) Viewed 5890 times
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: counter-intuitive contact point position (plane & primit

Post by drleviathan »

I think the number of points in the btContactManifold between two objects ranges from 0 to 4 points and this number may vary from frame to frame. When a bouncy object with a flat face is rattling around on a flat surface it is typically only touching on a single point. Perhaps when it finally comes to rest will its manifold have multiple points.

If you're looking for the effective center of the manifold you may need to perform some filtering/averaging to obtain it. A single frame's worth of data might not provide enough info to measure it with confidence.

Alternatively, perhaps you could get higher point count in your manifolds by zeroing the restitution of your objects such that bounces are reduced (do it for floor and dynamic objects):

Code: Select all

body->setRestitution(0.0);
kangd
Posts: 9
Joined: Tue Oct 24, 2017 11:51 am

Re: counter-intuitive contact point position (plane & primit

Post by kangd »

@drleviathan

Thank you so much again for your response.

For this task, I only use collision detection not any dynamics. So there's no rattling and also no restitution.

Concretely speaking, the situaltion is,

there's static plane shaped object (normal = (0, 0, 1), and constant = 0) and I put every primitive object to touch the plane.

There's no motion and no dynamics.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: counter-intuitive contact point position (plane & primit

Post by drleviathan »

I don't know the contact manifold and contact point code well, so there is some guesswork in what I'm about to say. Take it for what it is worth:

The class name for the contact manifold is btPersistentManifold. I believe the "persistent" aspect is that the manifold lives longer than a single simulation frame: Bullet takes advantage of temporal and spatial coherence of object-object interaction to maintain a manifold between two objects over several frames. I know that older versions of the Havok physics engine definitely did this.

New btPersistentManifold instances are created in btCollisionDispatcher::getNewManifold(), and they start with zero contact points. Contact points are added/removed later using the API of btPersistentManifold. Specifically these methods:

Code: Select all

int addManifoldPoint(const btManifoldPoint& newPoint, bool isPredictive=false);
void removeContactPoint(int index);
void replaceContactPoint(const btManifoldPoint& newPoint, int insertIndex);
void refreshContactPoints(const btTransform& trA,const btTransform& trB);
Since you aren't running the dynamics it is probably the case that the manifolds you are looking at have not yet "matured" to multi-point manifolds.
kangd
Posts: 9
Joined: Tue Oct 24, 2017 11:51 am

Re: counter-intuitive contact point position (plane & primit

Post by kangd »

thank you very much for explanation.

but can you elaborate what "matured" means? Do you mean it needs more steps of simulation (I think it's not the case, because I already tried a number of simulation step)?

(should I put dynamcis world for this case? I really need only collision detection feature, since I will implement my own collision solver)
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: counter-intuitive contact point position (plane & primit

Post by drleviathan »

What I meant by "matured" is that there must be a code path that add/removes/changes contact points in the manifold. This evolution of the manifold probably happens over multiple frames of simulation (which includes the collision detection, the constraint solver, and the integration of motion). I dunno where exactly is the code that adds/removes/changes the contact points, but I was guessing it would live in the collision detection stage of subsequent frames, applied after the object had actually moved around. I would guess the GJK "get nearest point" narrow-phase algorithm only adds one new point per substep. Old contact points are kept around until: they cease to be valid (e.g. when the distance between pointOnA and pointOnB get too big), they are replaced (there is probably logic that will not add new points that duplicate others, but instead update existing points) or culled (removed for distance being too far).

But really, for most of this stuff I'm just guessing or filling in gaps of what I glimpsed during my code exploration. Your questions are outside my own expertise. If you're writing your own solver then you should probably take the plunge and get elbows deep into the Bullet code. Maybe insert your own debugging hooks so you can see where and when contact points are actually added.
kangd
Posts: 9
Joined: Tue Oct 24, 2017 11:51 am

Re: counter-intuitive contact point position (plane & primit

Post by kangd »

Thank you so much!

Your hint has been a great help.

I found I can set the number of iteration (for face to face collision) by modifying btDefaultCollisionConfiguration object with setPlaneConvexMultipointIterations() function as I did step-by-step debugging.

5 iteration shows the result what I've wanted.

Still I have to take a look how it works, but seems fine.


FYI, I quoted comment from source code

Code: Select all

	///Use this method to allow to generate multiple contact points between at once, between two objects using the generic convex-convex algorithm.
	///By default, this feature is disabled for best performance.
	///@param numPerturbationIterations controls the number of collision queries. Set it to zero to disable the feature.
	///@param minimumPointsPerturbationThreshold is the minimum number of points in the contact cache, above which the feature is disabled
	///3 is a good value for both params, if you want to enable the feature. This is because the default contact cache contains a maximum of 4 points, and one collision query at the unperturbed orientation is performed first.
	///See Bullet/Demos/CollisionDemo for an example how this feature gathers multiple points.
	///@todo we could add a per-object setting of those parameters, for level-of-detail collision detection.
Attachments
box 4points.png
box 4points.png (248.33 KiB) Viewed 5810 times
Post Reply