Ragdoll Physics
Slightly inspired by ragdoll masters and my own desire to make an absurdly complex sidescroller, where might I find a good starting point to ragdoll physics? I know I need a skeletal structure (or at least break the body into masses) but what is an efficient way to do that? Where do I go from there? I would like to find answers to these questions. Any hints or links would be absolutely fantastic.
Try searching, this has been covered multiple times. I did it for you in less than 30 seconds
Search 
http://www.idevgames.com/forum/search.ph...chid=86086
Relevant Thread
http://www.idevgames.com/forum/showthrea...ht=ragdoll
Search 
http://www.idevgames.com/forum/search.ph...chid=86086
Relevant Thread
http://www.idevgames.com/forum/showthrea...ht=ragdoll
I'm sorry I dont have links to give, many programs just use the physics of some library, but I can tell you how I approached the thing (though I really dont know if it's the "right" way!)
imo, the basic of ragdoll is a chain of balls:
So first thing you need to do is be confident on how to put a number of balls on the screen and have them affected by gravity. ok, I assume you can do that ;).
Then, you need to link the balls. There is THE fundamental trick here: you move the balls as if there was NO link between them, THEN through iterated steps, you link them back.
How to link the balls: with only 2 balls, it's easy, you shift one ball half way towards the other and the second half way towards the first, and you're done. Problem: you cant do this with 3 or more balls: or at lest you need more iterations of this procedure.
So my procedure is: consider all couples of linked balls: for every couple, compute a "virtual shift" that one ball induces on the other. This "virtual shift" must be proportional to the distance between the two balls (it does not have to be 1/2 of the distance (the natural way to do it), it can be less, like 1/4 of the distance or even less). It's "virtual" because you dont shift the balls right after you computed it, you calculate ALL virtual shifts applied to each ball (by all other balls to which it is linked), then you sum them up (vector sum), and finally you move the balls by this amount. And all this procedure must be iterated, about 1 iteration for every ball you put in.
Ok, that's most of it, the final trick is then to update the velocity vector of each ball, on the base of the actual distance it travelled in the frame.
Summing up the procedure is :
balls have position x1,y1
move balls based on their velocity vector (ie. x2=x1+vx, y2=y1+vy)
balls have position x2,y2,
link back balls (changes their position to x3,y3)
balls have position x3,y3,
update velocity i.e. vx=(x3x1), vy=(y3y1)
That's it!
try to get a rope going on, it's pretty impressive by it's own.
Then you will need joint rigidities, but I'm not that happy with my algorithms to do that, so you should look for a better source.
imo, the basic of ragdoll is a chain of balls:
So first thing you need to do is be confident on how to put a number of balls on the screen and have them affected by gravity. ok, I assume you can do that ;).
Then, you need to link the balls. There is THE fundamental trick here: you move the balls as if there was NO link between them, THEN through iterated steps, you link them back.
How to link the balls: with only 2 balls, it's easy, you shift one ball half way towards the other and the second half way towards the first, and you're done. Problem: you cant do this with 3 or more balls: or at lest you need more iterations of this procedure.
So my procedure is: consider all couples of linked balls: for every couple, compute a "virtual shift" that one ball induces on the other. This "virtual shift" must be proportional to the distance between the two balls (it does not have to be 1/2 of the distance (the natural way to do it), it can be less, like 1/4 of the distance or even less). It's "virtual" because you dont shift the balls right after you computed it, you calculate ALL virtual shifts applied to each ball (by all other balls to which it is linked), then you sum them up (vector sum), and finally you move the balls by this amount. And all this procedure must be iterated, about 1 iteration for every ball you put in.
Ok, that's most of it, the final trick is then to update the velocity vector of each ball, on the base of the actual distance it travelled in the frame.
Summing up the procedure is :
balls have position x1,y1
move balls based on their velocity vector (ie. x2=x1+vx, y2=y1+vy)
balls have position x2,y2,
link back balls (changes their position to x3,y3)
balls have position x3,y3,
update velocity i.e. vx=(x3x1), vy=(y3y1)
That's it!
try to get a rope going on, it's pretty impressive by it's own.
Then you will need joint rigidities, but I'm not that happy with my algorithms to do that, so you should look for a better source.
Â©hâ‚¬ck Ã¸ut Âµy stuÆ’Æ’ Ã¥t ragdollsoft.com
New game in development Rubber Ninjas  Mac Games Downloads
I did a search for ragdoll that came up with nothing (I did restrict to the game programming forums only figuring a safe bet but I guess not). Thanks.
Najdorf: I did notice that your game starts and you can see all the balls. What did you do to make them look like sticks? Just draw over them? (off topic but i guess I'll need it even for my rope).
Najdorf: I did notice that your game starts and you can see all the balls. What did you do to make them look like sticks? Just draw over them? (off topic but i guess I'll need it even for my rope).
yeah just draw over it. the core are the balls really
Is the algorithm clear enough?
Is the algorithm clear enough?
Â©hâ‚¬ck Ã¸ut Âµy stuÆ’Æ’ Ã¥t ragdollsoft.com
New game in development Rubber Ninjas  Mac Games Downloads
Seems clear enough. I'm going to check it out either later tonight or tomorrow and see if I can get a little rope going.
Edit: For drawing balls did you just use a triangle fan or did you actually make balls somehow?
How did you draw over all the balls? Just put some textured quads using the balls' positions to base the vertices off? Seems like that'd work well enough.
Thanks for the help. If anyone else has any resources, they're still appreciated. I'll check back up and let you know how it's all going.
Edit: For drawing balls did you just use a triangle fan or did you actually make balls somehow?
How did you draw over all the balls? Just put some textured quads using the balls' positions to base the vertices off? Seems like that'd work well enough.
Thanks for the help. If anyone else has any resources, they're still appreciated. I'll check back up and let you know how it's all going.
Why not just use the balls as simulation objects and draw the quads in their place? That way you don't have to do the overdraw?
I draw also the balls to get smooth edges
Â©hâ‚¬ck Ã¸ut Âµy stuÆ’Æ’ Ã¥t ragdollsoft.com
New game in development Rubber Ninjas  Mac Games Downloads
Najdorf Wrote:I draw also the balls to get smooth edges
That's a bit strange when taken out of context.
"Yes, well, that's the sort of blinkered, Philistine pigignorance I've come to expect from you noncreative garbage."
Najdorf Wrote:So my procedure is: consider all couples of linked balls: for every couple, ...Would the couples be like 1&2, 2&3, 3&4 or would it be 1&2, 1&3, 2&3? I'm just trying to figure out if I have to reference every ball to every ball or down the line like the first set.
Also could you help me with vector sums. I know that I add the components and convert to polar but won't that leave me with just an angle (one number)? Don't I still need a vector? Or did I miss something in math class... Either way thanks for the help.
well if you want to do a chain of balls the couples linked are [1,2], [2,3], [3,4]
For other kind of figures the couples linked are different. [1,2],[2,3],[1,3] produces a circle.
(Just to show off, a man is:
joints[][]=[[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9,10],[10,11],[6,12],[12,13],[13,14],[14,15],[15,16],[14,17],[17,18],[18,19],[19,20],[14,21],[21,22],[22,23],[23,24],[1,25],[11,26]]
)
suppose you moved the balls, and they end up like this (Ignore the dots, focus on the balls (the numbers) and the links (the lines)
....2
.../
./..
1...
....
43
You want to get the balls attached (i.e. you want to eliminate the space between them)
say ball1 has position x1,y1, ball2 has position x2,y2...
Consider ball 1:it's linked only to ball 2: Compute the "virtual shift" that ball 2 applies on ball1, i.e. ball 2 "pulls" ball1 in it's direction, say by 1/4 of the distance.
Then the virtual shift on ball1 is :
virtualShiftX1=(x2x1)/4
virtualShiftY1=(y2y1)/4
similarly ball2 is attracted by ball1
virtualShiftX2=(x2x1)/4
virtualShiftY2=(y2y1)/4
Now, ball2 is also attracted by ball3, so you "add" to the current the virtual shift (this is what I meant for vector sum)
virtualShiftX2=virtualShiftX2+(x3x2)/4
virtualShiftY2=virtualShiftY2+(y3y2)/4
then you do the same for all the chain of balls.
When you computed the virtual shifts for all balls, you apply them (i.e. you do x[i]=x[i]+virtualshiftX[i] and the same for y)
And you iterate the whole procedure for a number of times.
That's it!
Also, at the beginning of the main loop (not during this iterative procedure), you can put gravity, and say for instance that the position of ball1 must be that of the mouse, so you can drag the chain around.
For other kind of figures the couples linked are different. [1,2],[2,3],[1,3] produces a circle.
(Just to show off, a man is:
joints[][]=[[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9,10],[10,11],[6,12],[12,13],[13,14],[14,15],[15,16],[14,17],[17,18],[18,19],[19,20],[14,21],[21,22],[22,23],[23,24],[1,25],[11,26]]
)
suppose you moved the balls, and they end up like this (Ignore the dots, focus on the balls (the numbers) and the links (the lines)
....2
.../
./..
1...
....
43
You want to get the balls attached (i.e. you want to eliminate the space between them)
say ball1 has position x1,y1, ball2 has position x2,y2...
Consider ball 1:it's linked only to ball 2: Compute the "virtual shift" that ball 2 applies on ball1, i.e. ball 2 "pulls" ball1 in it's direction, say by 1/4 of the distance.
Then the virtual shift on ball1 is :
virtualShiftX1=(x2x1)/4
virtualShiftY1=(y2y1)/4
similarly ball2 is attracted by ball1
virtualShiftX2=(x2x1)/4
virtualShiftY2=(y2y1)/4
Now, ball2 is also attracted by ball3, so you "add" to the current the virtual shift (this is what I meant for vector sum)
virtualShiftX2=virtualShiftX2+(x3x2)/4
virtualShiftY2=virtualShiftY2+(y3y2)/4
then you do the same for all the chain of balls.
When you computed the virtual shifts for all balls, you apply them (i.e. you do x[i]=x[i]+virtualshiftX[i] and the same for y)
And you iterate the whole procedure for a number of times.
That's it!
Also, at the beginning of the main loop (not during this iterative procedure), you can put gravity, and say for instance that the position of ball1 must be that of the mouse, so you can drag the chain around.
Â©hâ‚¬ck Ã¸ut Âµy stuÆ’Æ’ Ã¥t ragdollsoft.com
New game in development Rubber Ninjas  Mac Games Downloads
Heres an old demo I did to teach myself verlet integration 
http://nuclearnova.com/temp/Jakes Verlet Demo.sit
Code is included in if you have METAL, or use a text editor to read it, its very simple. I did this on a 45 minute car ride after reading tutorials .
http://nuclearnova.com/temp/Jakes Verlet Demo.sit
Code is included in if you have METAL, or use a text editor to read it, its very simple. I did this on a 45 minute car ride after reading tutorials .
I'm trying to get this all down. My rope is starting to act right but is falling apart and collapsing on itself. I've decided there are two factors: 1) my collision code (to keep circles from overlapping) is incorrect and 2) my shift calculations are bad. I also have realized that all my circles have broken away from the anchor (a circle that gets no shift nor gravity). Here's some of my code if anyone could look over it and offer suggestions:
Code:
//apply gravity to all of the circles except one
for(i = 1; i < NUM_CIRCLES; i++)
circleVel[i].y = 9.8 * elapsedTime;
//add the velocities to the circles
for(i = 1; i < NUM_CIRCLES; i++)
{
circlePos[i].x += circleVel[i].x;
circlePos[i].y += circleVel[i].y;
circlePos[i].z += circleVel[i].z;
}
//figure out shifts for circles
for(i = 1; i < NUM_CIRCLES; i++)
{
shift[i].x += (circlePos[i+1].x  circlePos[i].x) / 4;
shift[i].y += (circlePos[i+1].y  circlePos[i].y) / 4;
shift[i].z += (circlePos[i+1].z  circlePos[i].z) / 4;
shift[i+1].x = shift[i].x;
shift[i+1].y = shift[i].y;
shift[i+1].z = shift[i].z;
}
//apply the shifts
for(i = 1; i < NUM_CIRCLES; i++)
{
circlePos[i].x += shift[i].x;
circlePos[i].y += shift[i].y;
circlePos[i].z += shift[i].z;
}
//prevent circles from overlapping
for(i = 1; i < NUM_CIRCLES; i++)
{
if((tempFloat = (pow((circlePos[i].x  circlePos[i1].x),2) +
pow((circlePos[i].y  circlePos[i1].y),2) +
pow((circlePos[i].z  circlePos[i1].z),2))) < (pow((CIRCLE_RADIUS * 2),2)))
{
tempVector.x = (circlePos[i].x  circlePos[i1].x) / tempFloat;
tempVector.y = (circlePos[i].y  circlePos[i1].y) / tempFloat;
tempVector.z = (circlePos[i].z  circlePos[i1].z) / tempFloat;
circlePos[i].x += tempVector.x;
circlePos[i].y += tempVector.y;
circlePos[i].z += tempVector.z;
circlePos[i].x = tempVector.x * CIRCLE_RADIUS * 2;
circlePos[i].y = tempVector.y * CIRCLE_RADIUS * 2;
circlePos[i].z = tempVector.z * CIRCLE_RADIUS * 2;
}
}
Here's an article on physics simulations using Verlet Integration as Jake mentioned:
http://www.gamasutra.com/resource_guide/...on_pfv.htm
As far as your code it would help if you showed us via a build or screenshot what it was doing that was wonky. Just from looking at it though, it seems like you're going out of the bounds of your array when you access i+1 in the for loop with i going from 1 to NUM_CIRCLES.
http://www.gamasutra.com/resource_guide/...on_pfv.htm
As far as your code it would help if you showed us via a build or screenshot what it was doing that was wonky. Just from looking at it though, it seems like you're going out of the bounds of your array when you access i+1 in the for loop with i going from 1 to NUM_CIRCLES.
Justin Ficarrotta
http://www.justinfic.com
"It is better to be The Man than to work for The Man."  Alexander Seropian
I changed the code a little bit. Here's the new code I'm using:
And here you can find images of the problem. The screens are just pics I took, in order, while the program was going. I hope someone can help me. Obviously there are no collisions but the particles all seem to gravitate to the wrong point. Perhaps there's a way I'm doing something backwards? Also if someone could help me write a quick little collision detection for() loop, I'd be really happy. I tried writing one (see the first post) but it just caused the particles to go crazy. Thanks for all the help. I plan to go read JustinFics link now.
Code:
 (void)updateCircles
{
int i;
SEVector shift[NUM_CIRCLES];
SEVector tempVector;
float tempFloat;
//apply gravity to all of the circles except one
for(i = 1; i < NUM_CIRCLES; i++)
circleVel[i].y = 9.8 * elapsedTime;
//add the velocities to the circles
for(i = 1; i < NUM_CIRCLES; i++)
{
circlePos[i].x += circleVel[i].x;
circlePos[i].y += circleVel[i].y;
circlePos[i].z += circleVel[i].z;
}
//figure out shifts for circles
for(i = 1; i < NUM_CIRCLES  1; i++)
{
shift[i].x += (circlePos[i+1].x  circlePos[i].x) / 4;
shift[i].y += (circlePos[i+1].y  circlePos[i].y) / 4;
shift[i].z += (circlePos[i+1].z  circlePos[i].z) / 4;
shift[i+1].x = shift[i].x;
shift[i+1].y = shift[i].y;
shift[i+1].z = shift[i].z;
}
//apply the shifts
for(i = 1; i < NUM_CIRCLES; i++)
{
circlePos[i].x += shift[i].x;
circlePos[i].y += shift[i].y;
circlePos[i].z += shift[i].z;
}
//prevent circles from dropping off screen
for(i = 1; i < NUM_CIRCLES; i++)
if(circlePos[i].y < 70)
circlePos[i].y = 70;
}
Possibly Related Threads...
Thread:  Author  Replies:  Views:  Last Post  
Ragdoll Physics  merrill541  1  3,613 
Feb 5, 2009 09:09 AM Last Post: JustinFic 

Ragdoll Physic's: (For GML)..  Master_Computer  0  3,508 
Jan 27, 2008 11:55 AM Last Post: Master_Computer 

Bullet Physics Library / COLLADA physics viewer  erwincoumans  14  19,658 
Aug 12, 2006 12:59 AM Last Post: Fenris 

Ragdoll Physics  Duane  3  5,752 
Jul 7, 2005 09:55 AM Last Post: Duane 

Ragdoll and cloth physics  Skorche  28  20,822 
Jun 10, 2003 03:12 PM Last Post: Fenris 