Simultaneous Colliding Contact
#1
Posted 17 December 2004 - 06:19 PM
Suppose there is a box in the virtual world. This box has an infinite mass (1/Mass = 0). Another box, with a mass of 1, is placed directly above that box and dropped straight down due to the force of gravity. Upon detecting collision, 4 contact points are determined, once at each corner.
That all works fine, but if I understand the laws of physics correctly, the upper box should bounce straight up without any rotation. Unfortunately, my simulation causes the box to rotate. It appears that the force applied by the last contact causes significantly more torque than any of the other contacts and hence the box rotates. If I reverse the order of these contacts, the box spins the same amount in the opposite direction. Order of contact should be insignificant.
My code is essentially the same as the “collision” and “find_all_collisions” functions presented in the paper linked above. I will post code snippets if the pseudo-code presented is not sufficient.
Am I correct in assuming the box should bounce straight up because the order of the contacts shouldn’t matter? If so, what could I be doing wrong, and how can I go about fixing it?
Thanks in advanced,
Brandon Bloom
http://brandonbloom.name
#2
Posted 18 December 2004 - 07:43 AM
#3
Posted 19 December 2004 - 03:57 AM
When using an elasticty of 0%, the box dropped on top correctly stops instantly (although shows a tiny hint of rotation). With an elasticity of 100%, the box correctly bounces back to its original height, but has incorrect angular velocity.
I have an ApplyImpulse method which accepts the impulse vector as well as a position in body space. It calls ApplyLinearImpulse as well as ApplyAngularImpulse. Since the box jumps to its original height with 100% elasticity, the ApplyLinearImpulse call is clearly correct. Either ApplyAngularImpulse is flawed, or the value passed to ApplyImpulse is flawed.
Here is some of the code:
/// <summary>
/// Instantaneously changed the linear and angular velocity of this body by applying an impulse.
/// </summary>
/// <param name="impulse">Impulse to be applied.</param>
/// <param name="at">Position in body space where this impulse is to be applied.</param>
public void ApplyImpulse(Vector3 impulse, Vector3 at)
{
this.ApplyLinearImpulse(impulse);
this.ApplyAngularImpulse(Vector3.Cross(at, impulse));
}
/// <summary>
/// Instantaneously changed the angular velocity of this body by applying an impulse.
/// </summary>
/// <param name="impulse">Impulse to be applied.</param>
public void ApplyAngularImpulse(Vector3 impulse)
{ // Does this function even make sense? Should it be this.angularVelocity += Vector3.TransformCoordinate(torque, this.InertiaTensorInverse) * duration;
// Is InertiaTensorInverse body space? or world space? or does that not make sense at all?
this.angularVelocity += Vector3.TransformCoordinate(impulse, this.InertiaTensorInverse);
}
/// <summary>
/// Instantaneously changed the linear velocity of this body by applying an impulse.
/// </summary>
/// <param name="impulse">Impulse to be applied. Measured in Newton * Seconds</param>
public void ApplyLinearImpulse(Vector3 impulse)
{
this.linearVelocity += impulse * this.MassInverse;
}
Maybe someone could double check this functions for my sanity?
http://brandonbloom.name
#4
Posted 20 December 2004 - 10:08 PM
http://brandonbloom.name
#5
Posted 21 December 2004 - 06:45 AM
I would try writing your ApplyImpulse function like the following:
Vector3 parallel = at * (Vector3.Dot(at, impulse) / Vector3.Dot(at, at)); Vector3 perp = impulse - parallel; this.ApplyLinearImpulse(parallel); this.ApplyAngularImpulse(Vector3.Cross(at, perp));
I believe that's the right projection formula...parallel and perp should be the components of impulse parallel and perpendicular to the at vector.
#6
Posted 21 December 2004 - 05:46 PM
Now suppose that the same force F is applied off-center to the body as shown in figure 11. Since the force acting on the body is the same, the acceleration of the center of mass is the same.
That would lead me to beleive that this.ApplyLinearImpulse(impulse); would be correct. Also, as I stated earlier, the box does bounce back up to the correct height (according to its elasticity). So then it is the angular impulse that is primarily in question here. I believe my code is correct, but I am not certain.
Thanks for all the help so far, still trying to sort this out.
http://brandonbloom.name
#7
Posted 22 December 2004 - 07:30 AM
The only other thing I can think of is to make sure that your InertiaTensorInverse is corrected for the body's current orientation - that is, InertiaTensorInverse = RotationMatrix * InertiaBodyTensorInverse * Transpose(RotationMatrix) where the InertiaBodyTensorInverse is as described in section 2.10, pgs 14-15 of the Baraff paper. The InertiaBodyTensorInverse is a constant, but the InertiaTensorInverse has to be recalculated each time the body's orientation changes.
#8
Posted 26 December 2004 - 07:37 PM
Thank you for your help.
Now I'm totally stumped...
http://brandonbloom.name
#9
Posted 20 February 2006 - 02:07 PM
http://3rdprogress.n...chive/num7.html
In a nutshell, you need to take into account ALL contact points at the same time.
Cheers,
Baktash.
#10
Posted 25 February 2006 - 11:07 PM
Baktash A. Shamshirsaz said:
In a nutshell, you need to take into account ALL contact points at the same time.
Yup, thats correct. There is an explicit solution to this, which results in solving a LCP (Linear complementarity problem). The LCP is unfortunally a quadratic optimization problem, but there are specific algortihms (the fastest is probably an algorithm by dantzig, which is what ODE uses).
However, the most common method (IIRC Novodex does this) is probably something close to http://graphics.stan...d_bodies-sig03/ , it is easier on the math (does not involve an LCP) and is fairly easy to implement. It is a nice read too, something that is kind of seldom in the field of computer science IMO.
-si
#11
Posted 08 March 2006 - 04:14 AM
#12
Posted 08 March 2006 - 11:07 AM
Baktash A. Shamshirsaz said:
hmm, your link doesn't seem to work here, so I'm not sure exactly what you're talking about. Are you basicly finding the amount of force to apply to avoid penetration ,using a linear system? I should really play with thison paper before I ask these questions ;). Or are you simply inverting the interia matrix (I usally store the inverse of the interia matrix with the body).
I was somehow mistaken this discussion of being about contacts and not collisions (collisions is actually quite simple when you know what to do ;) I think you'll find the solution in any dynamics book ). Do your method extend to include friction? (wich is a must IMO).
-si
#13
Posted 08 March 2006 - 07:22 PM
First off, sorry for the link being down. The server was down for a few hours last night thanks to my no good ISP :S. You can check it out now.
Now let me clear up a few things about the analytical aproach and Impulses and Contact Forces.
----------The Analytical Method----------
For solving for contact forces, basically people like Baraff chose the analytical method (the same one I'm talking about) to calculate contact forces that exist at 'RESTING' objects. So first they go through the trouble of finding out whether they're resting or not and then for probably 'educational' purposes they go the extra mile to calculate the normal forces
Man that was a handful
#14
Posted 10 March 2006 - 02:26 AM
In general, Af + b = 0 is the form of our equation for colliding contacts for two objects (if we ignore the greater than zero possibility) 'f' is the matrix or should I say the array of contact forces/impulses that we want to calculate. Here's a nice way:
1. Af = -b
2. f = A_inverse * (-
Therefore, f = A_inverse * (-
Researchers are right now working on finding out what types of contact nodes create an 'A' matrix that is not invertible so they can make this method bullet proof. Until then you're advised to use LCP.
#15
Posted 10 March 2006 - 08:34 PM
Mirtich is talking about using singular value decomposition (SVD) to find
what he calls an "inverse" (not the real inverse). I'm not really sure what he means by this, but he is possibly reffering to an approximate inverse. The nice thing with the SVD is that you get two orthogonal matrices (i.e. non-singular) and one possibly singular diagonal matrix (which 'measures' the singularity of the matrix). My guess would be that he multiplies the right side with the orthogonal matrices, and solves with respect to the diagonal matrix (putting possibly zero where the value of the matrix is close to zero). I may be wrong, I just skimmed the article just now.
Anyways, if you really want to avoid solving an LCP, you should really read the paper I linked above. It provides a very nice solution, and simple to implement compared to alot of other techniques. From section 5 an onwards they really described very detailed how to create a robust rigid body simulator (for a realtime implementation you probably want to cut down on all the iterative stuff). They do not treat all collision points at once as you do though.
-si
#16
Posted 10 March 2006 - 09:55 PM
SigKILL said:
what he calls an "inverse" (not the real inverse). I'm not really sure what he means by this, but he is possibly reffering to an approximate inverse. The nice thing with the SVD is that you get two orthogonal matrices (i.e. non-singular) and one possibly singular diagonal matrix (which 'measures' the singularity of the matrix). My guess would be that he multiplies the right side with the orthogonal matrices, and solves with respect to the diagonal matrix (putting possibly zero where the value of the matrix is close to zero). I may be wrong, I just skimmed the article just now.
For objects sliding on each other, again, as I said, solving friction using culomb's friction law is a breeze and the 'resting' part is solved using micro collision as I also mentioned before. You should try reading some of Mirtich's papers on Impulse-based method for dynamic simulation or even his Ph.D thesis which is on the subject. You will see that contact 'forces' and LCP are not the only approaches that we can take. Aside from all this there are also energy based approaches that I unfortunately never got to look through. Anyway, thinking of EVERY thing as impulses works as well, if we do it over small time steps.
SigKILL said:
If you read the 1st post in this thread, you will realize how WRONG NOT doing that is with more than 1 simultaneous collision point. That is mostly what my tutorial is trying to teach the reader. You can refer to the 1st reference mentioned in my tutorial for more information. Although you can solve impulses separately inbetween different 'pairs' of objects and apply impulses.
-------------------
Also from what I've observed, I know where our fundamental differences of thoughts arise from
#17
Posted 11 March 2006 - 04:44 PM
-si
#18
Posted 11 March 2006 - 05:08 PM
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users












