I've been looking at the code for cpPivotJoint lately, to see if I can figure out how joints work, and maybe write a joint or two myself. It's a lot easier to understand after the recent refactoring, and I think I get most of it except for joint->jAcc.
I can see that all the forces that are calculated and applied in applyImpulse are added into jAcc. Then, in the preStep function, the whole jAcc is applied. I guess my questions are:
1) What purpose does the jAcc have?
2) How come it's never reset to cpvzero?
Accumulated Impulses
-
- Posts: 56
- Joined: Tue Sep 11, 2007 2:30 pm
- Contact:
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: Accumulated Impulses
That's the neat trick I learned from Erin Catto's Box2D solver when I started Chipmunk. Very ingenious.
When calculating impulses iteratively the old way, you start with all impulses at 0 and then each iteration converges more towards the ideal solution. Because the impulses start at 0, they will always be slightly too small. Let's say that in a particular simulation with deep stacking, 10 iterations gets you 90% of the way to the ideal. 90% is a really crummy number in reality. Things will be mushing and sliding all over. You could increase the number of iterations, but that makes the simulation more expensive.
Now this particular stack of objects is sitting still, resting. It's not flying around smashing into things. This means that the solution from the frame before is going to be very similar to the solution needed this frame. By storing the solution from the previous frame and using it as the starting point instead of zero, you are already near 90% of the way to a good solution. 10 iterations later, you are perhaps more like 99% of the way to the ideal solution. Repeat this for a few more frames and things are looking pretty solid.
This can cause some small negative artifacts for fast moving collisions with stacks of objects, but not enough to offset the advantages. Watch the pyramid stack demo for instance. The boxes will all bounce a little when they strike the circle shape. This is because the initial collision impulse was much larger than the impulses needed to stack the objects. In this case instead of starting a too low (0) and ending low, it's starting way too high (the large collision impulse) and ending high.
When calculating impulses iteratively the old way, you start with all impulses at 0 and then each iteration converges more towards the ideal solution. Because the impulses start at 0, they will always be slightly too small. Let's say that in a particular simulation with deep stacking, 10 iterations gets you 90% of the way to the ideal. 90% is a really crummy number in reality. Things will be mushing and sliding all over. You could increase the number of iterations, but that makes the simulation more expensive.
Now this particular stack of objects is sitting still, resting. It's not flying around smashing into things. This means that the solution from the frame before is going to be very similar to the solution needed this frame. By storing the solution from the previous frame and using it as the starting point instead of zero, you are already near 90% of the way to a good solution. 10 iterations later, you are perhaps more like 99% of the way to the ideal solution. Repeat this for a few more frames and things are looking pretty solid.
This can cause some small negative artifacts for fast moving collisions with stacks of objects, but not enough to offset the advantages. Watch the pyramid stack demo for instance. The boxes will all bounce a little when they strike the circle shape. This is because the initial collision impulse was much larger than the impulses needed to stack the objects. In this case instead of starting a too low (0) and ending low, it's starting way too high (the large collision impulse) and ending high.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
-
- Posts: 56
- Joined: Tue Sep 11, 2007 2:30 pm
- Contact:
Re: Accumulated Impulses
Ah, of course. I've seen mention of this technique before, but I was not able to connect it to this bit of the code. Thanks for the excellent explanation, Scott!
I feel I'm on a roll when it comes to asking dumb questions now, so I'll have a go at another one. I'm still in cpPivotJoint.c;
The following code multiplies the relative velocity of the two anchor points with the mass/moment at the points of the anchors, in order to get a force, right? Then this force is combined with the bias velocity in order to get the total force. Shouldn't the bias velocity also be multiplied with the mass tensor?
Why does this code not look like this:
I feel I'm on a roll when it comes to asking dumb questions now, so I'll have a go at another one. I'm still in cpPivotJoint.c;
The following code multiplies the relative velocity of the two anchor points with the mass/moment at the points of the anchors, in order to get a force, right? Then this force is combined with the bias velocity in order to get the total force. Shouldn't the bias velocity also be multiplied with the mass tensor?
Code: Select all
// compute normal impulse
cpVect j = cpvsub(joint->bias, mult_k(vr, joint->k1, joint->k2));
Code: Select all
// compute normal impulse
cpVect j = mult_k(cpvsub(joint->bias, vr), joint->k1, joint->k2);
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: Accumulated Impulses
I'd say that's far from a dumb question. :p The answer is sorta dumb though.
I don't really remember off the top of my head. It might be a bug, but assuming that it's not, it's probably because the bias velocity shouldn't be affected by the mass. I'm not sure if that makes sense though... I'll think about it.
I don't really remember off the top of my head. It might be a bug, but assuming that it's not, it's probably because the bias velocity shouldn't be affected by the mass. I'm not sure if that makes sense though... I'll think about it.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
-
- Posts: 56
- Joined: Tue Sep 11, 2007 2:30 pm
- Contact:
Re: Accumulated Impulses
I tried both versions of the code, and they both work for very simple cases. I bet one of them would behave better than the other under stressful conditions, though. Maybe there would be a visible difference for something like a long rope made of bodies and pivots.
That the bias velocity shouldn't be affected by the mass does sound a bit weird to me. It's been a long time since I had my last physics lesson, but my gut feeling says that adding something with the unit m/s to something with the unit kg*m/s will give invalid results.
That the bias velocity shouldn't be affected by the mass does sound a bit weird to me. It's been a long time since I had my last physics lesson, but my gut feeling says that adding something with the unit m/s to something with the unit kg*m/s will give invalid results.
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: Accumulated Impulses
Looking at some of my older code, you were right. It was supposed to be salting the velocity. The units don't work out otherwise.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Who is online
Users browsing this forum: No registered users and 10 guests