Jump to content
  • Advertisement
Sign in to follow this  
LGAB

Angular constraints

This topic is 4845 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all, I'm seeking a way to have a solid angular constraint for my 2D verlet-based physics sim, it's for making arms and legs not bending in the wrong direction. The search for this has reached near mystical proportions, as I'm now stumped after trying all ideas I can come up with. Finding if the angle is outside it's boundary is simple, but responding to it always make the entire body being jerked, as the other constraints try to compensate for it. I've searched a lot for answers on this topic, but I haven't been able to find any answers, or even a pointer in the right direction, perhaps angles isn't the way to go at all, but I just can't seem to wrap my head around this one - possibly something very simple that I'm just overlooking.. but I need some fresh idea at this point. I bet some of you've seen this floating around the internet: http://pekkasandborg.com/portfolio/?id=2 There's some solid looking angular constraints, and it uses the same base as I do, except that the famous Jacobssen article he mentions doesn't actually stretch as far as explaining angular constraints, so I guess he solved it himself. Any ideas, pointers? Much appreciated.

Share this post


Link to post
Share on other sites
Advertisement
Unless I'm missing something, I believe I've tried that, and it sends "shivers" through the rest of the character as it's settling down. Forcefully moving a particle is the same thing as introducing a force, right, so instead of just stopping the particle when it goes to far, it's jerking it back violently, creating wild bounces of the limb in question. I tried moving the "old position" an equal ammount as to preserve velocity, but that didn't seem to help either.. I can't really tell why this is a problem.

edit:
There are 3 particles involved, t1, t2, t3 in this func, for example t1=shoulder joint, t2=elbow, t3=wrist, with vector properties pos, oldpos etc. for verlet

Vector top = t1.pos - t2.pos; // vector of upper arm
Vector bot = t2.pos - t3.pos; // vector of wrist
float da = top.AngleBetween(bot); // returns angle from -PI to PI
if (da>0) // ie. more than 180 degrees
{
float len = bot.Length(); // store length of wrist
bot = top.UnitVector(); // set to same angle as upper arm
bot.Mult(-len); // restore length of wrist
t3.pos = t2.pos+bot; // move wristpoint to elbow+wrist
}



Well, that's what I have at the moment, very jerky indeed :) When the lower limb moves beyond the constraint, there's a violent kick backwards, which brings the entire character with it.

[Edited by - LGAB on August 5, 2005 1:12:21 PM]

Share this post


Link to post
Share on other sites
I was using 4, for no particular reason, but even up to 20 there's no change in this particular behaviour..
The code is based on the Jacobsen article, so you can find pseudo code of it there, I've just adapted it to my needs, the integration part is the same, and the part where constraints are satisfied goes something like this..


if (any particles, or any constraints)
for number_of_iterations
for all constraints
case constraint.type
NONE: (do nothing)
NAIL: CnsNail(params)
SPRING: CnsSpring(params)
etc, etc.
/case
/for
/for
/if

Nothing spectacular here :)

Share this post


Link to post
Share on other sites

Sure no problem, let me know if I was being to unspecific, and I'll elaborate for you! Just trying to spare you from somewhat longish pieces of source code :)

I commented out the Verlet() part of the update, and you're right! It's like dragging the character through mud, but the constrain really works, it stays straight when it should, and bends when it should, so that was very useful!

Now to figure out how to correct this problem with the velocity.. is there a flaw in the integration described by Jacobsen?

Share this post


Link to post
Share on other sites

I've tried a bunch of things, but mocking about with the velocity/oldpos invariably results in either violent spinning, or unnatural slow-downs of the feet/hands, so they drag behind instead. I think I've seen all kinds of weird behaviour!
Looking at the code in my second post, how would you change it to take velocity in to account?

Thanks for your efforts!

Share this post


Link to post
Share on other sites

I'm afraid I've tried every conceivable combination of what've talked about, none works any better than the original code.
So I'm sort of back to square one with this. I can't help but think there's a different approach to angular constraints, one that's stable and solid regardless of velocities :) I need to do some serious algo-sketching and think this over one more time.

skittleo, your input on this is much, much appreciated! This battle aint over :)

Share this post


Link to post
Share on other sites
I've solved the angular constraint problem in 3d:
1) a "keep 2 particles at least a min distance apart" constraint for min angle
2) a "keep particle on one side of a plane" constraint for max angle.

You could easily apply a similar solution for the 2d case:

1) a "keep 2 particles at least a min distance apart" constraint for min angle
2) a "keep particle on one side of a line" constraint for max angle.

For example, to keep the lower leg from bending the knee backwards, stop the foot particle from going on the outer side of the upper leg line (hip -> knee particle). To do this, just compute the normal pointing out from the hip->knee line and check to see which side (via the dot product) the foot particle is. Also instead of just moving the foot particle to correct the error, move the foot particle 50% one direction and the knee particle 50% the other direction, otherwise you'll introduce rotational velocity (taking particle mass into account is a simple extension - the ratios will no longer be 50% each)

The big advantage of a "keep on side of plane/line" constraint for a max angle is that it is always stable (ie. the normal of the plane/line never flips). The only tricky part is computing the line/plane normals from the particle configuration, but it all boils down to simple math (cross products in 3d).

Does this make sense?

See this thread for my 3d implementation source:
http://www.gamedev.net/community/forums/topic.asp?topic_id=324795


hope that helps-Steve.

Share this post


Link to post
Share on other sites
That made a lot of sense! Moving back the knee was the solution! Thanks a lot, I'll see if using your plane/line method is faster or better, but detecting the angle in radians works fine too :)

The revised code is this, in case someone might find it useful in the future:


Vector top = t1.pos - t2.pos; // thigh/upper arm
Vector bot = t2.pos - t3.pos; // lower leg/wrist
float da = top.AngleBetween(bot); // angle in -PI to PI
if (da>0)
{
float l = bot.Length(); // store length of wrist
bot = top.UnitVector(); // copy orientation
bot.Mult(-l); // scale to original length

// difference of where it is, and where it should be:
Vector diff = t3.pos - (t2.pos+bot);

// scale it to half length:
diff.Mult(0.5);

// give knee and foot one push each in opposite dirs:
t3.pos = t3.pos - diff;
t2.pos = t2.pos + diff;
}



It's rock solid, thanks a bunch!!!

Share this post


Link to post
Share on other sites
Cool - glad that worked out.

Isn't it funny how the paper skips the hardest part! I burnt many hours of my life getting verlet ragdolls working - you can keep on tweaking for ever...

Share this post


Link to post
Share on other sites
Very true.. my ragdoll feels pretty competent now, and I can have hundreds flying around, getting their limbs blasted off :)


Doll.SplitDoll();
BloodSquirt(Doll.GetJoint(4));


:)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!