Object squeezed

Topics: User Forum
Feb 1, 2012 at 9:41 AM

let's assume the following:

I have three boxes lined up on a floor : A, B and C

C is static and A is controlled manually. So if I move A, it pushes B toward C. Once B has touched C, moving A manually will force B to enter C as it has nowhere else to go. How can I determine that B is blocked so I stop moving the A box?

You can look at it as a player pushing a box into a wall, although it's not exactly like that it's a perfectly good analogy: I would like to know that the box can't move any further and stop the object that will push it further (and the real case is more complex that 3 items unfortunately).


Feb 1, 2012 at 5:29 PM

If a player pushes against a wall the wall won't move and neither will the player (as per Newton's third law of motion). In the same way box B would not "enter" C if C is a static body (static in the Farseer sense). And A will not enter B - they will just get stuck to each other. That might actually be what you need.

Anyways in the general case you should check that B has collided with C and then check if A collides with B so as to cancel the forces acting on A.

Feb 1, 2012 at 6:10 PM

Essentially what I have is:

C: static structure, in practice walls and floors

B: dynamic box, several of those

A: kinematic player

Currently A is pushing B and B is partially entering C.


There are a few points I can think of:

- The static structure (C) is not only the arresting wall, but also the static object that the dynamic (B) ones are gliding over; it is walls and floor; so I wouldn't really know that (C) has collided with (B) because it always does as part of it's normal behavior. Even if I split vertical walls from the ground, the same problem happen if the kinematic object (A)was on top of the dynamic one (B) resting somewhere on (C). This brings one question: is there a way to know what an object is 'blocked'?

- If I found a way to know that (B) is stuck against (C), then I could cancel the action from (A); unfortunately, I may get the (A)-(B) collision before knowing about the (B)-(C) collision. At this time it would be too late, I would already have applied the force.

- Would it make sense to turn (A) into a fully dynamic object that is tightly bound (maybe by a spring?) to a kinematic (A') object that wouldn't collide with anything? In that case, I would detect that (A) is not reaching (A') and infer that objects it collide with (B type) are blocked?

Feb 1, 2012 at 6:46 PM

Let's say you have gravity and B is resting on C.  Then the contact force impulse calculated by the engine and given to you in the callback will be the expression of the weight (G=mass*gravity) of B over the timestep. Even though B and C are touching they won't move since the force is not enough to "lift" B nor to "sink" C - again Newton's third law of motion - in reality the objects deform slightly but since here we deal with rigid bodies it's as if the forces cancel each other.

Now if you push on top of B then in your contact handler you'll get a bigger impulse equal to the "push" force + B's weight. If then there is a contact between B and Actor A (and you have detected that the impulse between B and C is bigger that simply the weight of B hence something must be acting on B in addition to gravity) then you can cancel the force produced by A since he's responsible.  Same story for lateral movement only gravity doesn't participate (or same for world with no gravity).

Would that work for you? Try logging the actual values you get in the contact callback to see. In a few words what I'm trying to suggest is to look at the magnitudes of the impulses and not just the simple collision yes/no. Some things are still unclear though - why does B "enter" C - they should not overlap, there's something fishy and this invalidates the whole physics argument. If B is "stuck" and I apply a force to it I should get in the contact the exact opposite impulse (so in fact they cancel and B and C are stationary).

Feb 1, 2012 at 7:24 PM
Edited Feb 1, 2012 at 7:34 PM

I confirmed that the dynamic body gets into the static one when push by a kinematic object.

Now, if I understand properly, I could, using the OnCollision / OnSeparation callbacks know which dynamic objects the kinematic object is contacting; then, during the contact phase, the idea is to monitor the forces applied to the objects, to see if the force I am applying through the kinematic object gets cancelled by the force resulting from the contact with the static object.

Am I getting this right?

If so, there are two problems at hand:

- There is penetration between B and C, although it is not huge, it is present, so it would indicate that the forces do not cancel one another; they eventually do when the penetration stops (with my object's it's about 1/3 of the object's volume that goes into C)

- Which fields specifically should I monitor one I know which objects are in contact?


In the meantime, I tried the following: I logged the linear velocity of the object and here is what I found:

if I push the B object into C, there is a linear velocity that points away from the contact, so B wants to be out of C; this could work to detect the collision as it pushes back against my impulse.

When the penetration is not too large, the result log is a bit odd though:

V:{X:-6.579969E-09 Y:-6.357368E-09}
V:{X:-1.941603E-06 Y:0.001058688}
V:{X:7.85031E-05 Y:-0.0001649377}
V:{X:7.05757E-05 Y:-0.0002163502}

in this case, you can see that the sign is changing; the numbers are almost null, so it could just be a precision issue, but at the same time, I'm a little bit puzzled that the sign bounces back and forth.

This doesn't entirely solve the problem because I do not know the force A is applying on B and B may get a composite force from several sources, so it is hard to look at the reaction from B and determine A's responsibility.

Feb 1, 2012 at 7:36 PM

Won't it be easier to convert body A into a dynamic object and not kinematic since kinematic objects have infinite mass and therefore generate infinite forces thus interfere with the physics causing exactly what you observe - bodies passing through each other.

Feb 1, 2012 at 7:42 PM

yes, I think that's most likely the way to go; I'd rather have things clean and stable rather than having to find workarounds which will eventually break :)

Do you think the spring method I mentioned on my second post would work?

"- Would it make sense to turn (A) into a fully dynamic object that is tightly bound (maybe by a spring?) to a kinematic (A') object that wouldn't collide with anything? In that case, I would detect that (A) is not reaching (A') and infer that objects it collide with (B type) are blocked?"

Feb 1, 2012 at 8:08 PM

I think the spring (distance joint I assume) will become unstable and will accumulate a lot of force but in principle it will work.

Feb 1, 2012 at 8:15 PM

It may work because I would just use it to know if something's blocking the way and then track back on the next frame.

So if I move the kinematic handle and the dynamic object stays behind after a collision, I would assume it's been blocked. I wouldn't move further, but reset the kinematic handle to where the dynamic object is and reset the force between the two.

I'm going to try an implementation to see what happens :)

In any case, thanks a lot for your help!