2
\$\begingroup\$

I'm developing a 3D physics engine (I know, I should use one of the many good existing physics libraries, however my collision detection is optimised for objects with highly ordered highly complex substructure which seems to be unusual and slow in the engines I've tried).

Collision detection is working really nicely, as are bouncing type behaviours but contact behaviours are not behaving nicely at all. Initially I had the problem that an object would spin up out of control if it had prolonged contact with a surface; I found that the reason for this was that an object was falling under gravity into collision, then getting a "free ride" upwards while it was pushed out of collision; giving the object free energy. If a significant portion of this energy made it into rotational degrees of freedom then considerable energy could be imparted before eventually the object was flung outwards. My solution to this was to impart an energy penalty when pushing out of collision equal to:

 EnergyPenalty=mass * gravity dotted with the push-out-of-collision vector (i.e the E=m*g*h it has gained for free)

This improved matters considerably, but now objects "get stuck" on their corners just before the shape relaxes into its resting position; presumably because too much energy seems to be being taken away.

A loop round the engine works as following

-Collisions detected
-Pushed out of collision (energy penalty if pushed up against gravity)
-Collisional forces applied if object are still approaching (may not be the case if push energy penalty slowed to 0)
-Gravity applied
-Contact forces applied if object are still approaching (as collision but with elasticity = 0)
-Move and rotate objects

I've taken friction out of the equation for the time being

I’ve found that while in contact with the surface the contact forces correctly bring the two objects at their collision points to zero relative velocity (taking into account both translation and rotation) but that that balance of translational movement balancing rotation is instantaneous. I.e. over a complete physics step the rotational component changes to be no longer in perfect balance with the translational. So a very small push-out-of-collision is required even when in ‘contact mode’ with a very small energy penalty to boot. However this energy penalty seems too large; freezing the object in position.

Which brings me to my question; what is the correct way to deal with the “free energy” imparted by a push-out-of-collision in a collision resolution step? (Even if the answer is; what you're doing is the correct way to deal with it i'll know this is a debugging issue not an algorithmic issue)

Object stuck on edge

\$\endgroup\$
3
  • \$\begingroup\$ Are you subtracting the gravitational potential energy (E=m*g*h) from the object's kinetic energy? Although that might produce a passable damping visual effect, I don't think it is valid physics. Does your engine otherwise track potential energy at all? If not, I would rethink the science you are trying to apply to this problem. \$\endgroup\$ May 14, 2013 at 17:53
  • \$\begingroup\$ @SethBattin It doesn't directly track energy at all, primarily it runs on impulses, velocities and angular velocities but it converts from velocity to kinetic energy back to velocity solely for this purpose. Preferentially stealing translational energy but stealing rotational if necessary. The whole thing always seemed a little unpleasant and I’m very much open to alternative suggestions \$\endgroup\$ May 14, 2013 at 18:17
  • \$\begingroup\$ P.s. im subtracting just the extra gravitational potential energy from the push, not the objects whole gravitational potential energy \$\endgroup\$ May 14, 2013 at 18:36

2 Answers 2

3
\$\begingroup\$

If I understand, you currently apply a collision impulse--an instant change to linear and angular velocity--with the goal of bringing the relative velocity of the contact point to zero.

However, the point may still be penetrating, so you try to "push out" of collision using either force (over time) or another impulse. A problem with this approach is that, once the contact point is free of penetration after the next frame or so, it continues moving away (undesired for resting contact).

To resolve the penetration, instead of an impulse, you may consider applying an "offset". (I don't know the correct physics term here because I've never seen this discussed.) I just mean an instant change to linear and angular position, with the goal of bringing the penetration depth to zero. The math (how much to translate the COM? How much to rotate?) is similar to your impulse calculation (involving mass and inertia tensor).

\$\endgroup\$
8
  • \$\begingroup\$ At present I apply collision forces to bring contact point to zero closing speed (or bounce if appropriate), but then previously I did as you suggested and made a "forceless movement" to move the shape out of collision. This however caused the object to "spin up out of control". My interpretation of this was that the object was effectively falling continuously. Falling a few millimetres downwards, experiencing a collision, being "forceless moved" upwards and then falling again. \$\endgroup\$ May 15, 2013 at 11:01
  • \$\begingroup\$ So on a larger scale this is equivalent to me falling down a mountain (accelerating under gravity), hitting the ground and bouncing. Then being forcelessly moved back up to the top of the mountain where I’m moving upwards slightly (having just bounced off the ground) and then when I hit the ground a second time im going faster than before. Repeat 60 times a second and the energy grows uncontrollably the longer contact continues. This was why I introduced the energy penalty. \$\endgroup\$ May 15, 2013 at 11:02
  • \$\begingroup\$ Differentiating between collision and contact helps this problem because while in contact the forceless movement is very small, but the problem still exists \$\endgroup\$ May 15, 2013 at 11:03
  • \$\begingroup\$ True, objects in resting contact are "falling continuously" in a sense, but you're detecting the resting contact every single frame and applying a contact impulse to stop the falling. An object should never get a chance to pick up any speed as described in your falling-down-a-mountain case. \$\endgroup\$ May 15, 2013 at 12:07
  • \$\begingroup\$ Just a shot in the dark here: how do you process your contact points? Do you loop through all contact points, processing each in isolation? Or do you solve the whole system at once? I'm thinking about the case of a box resting on the ground, presumably with a contact point at each of the 4 corners. \$\endgroup\$ May 15, 2013 at 12:10
0
\$\begingroup\$

I'm going to ignore angular effects here for simplicity.

In your contact resolution function, do the following: calculate relative velocity of the two bodies. if the relative velocity dot normal < 0 apply no force (moving apart) else correct position, to make penetration distance == 0 calculate normal force based on relative velocity / combined inverse mass apply impulses to bodies.

Google "physics engine slop" for more info.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the answer but my problem was just a coding bug which I've got sorted \$\endgroup\$ Feb 13, 2016 at 22:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .