Ragdoll Physics
Another point- when you update your position, you add the velocity, when you should be adding the velocity * timeElapsed.
Justin Ficarrotta
http://www.justinfic.com
"It is better to be The Man than to work for The Man." - Alexander Seropian
The link that Justin left me (about Verlet integration), that isn't the same thing that Najdorf was describing, was it? It doesn't seem that way. Considering all ups and downs, should I go with the position/velocity approach or position/lastposition approach? I don't want to rewrite all my code (even if it only sort of works) if it is a decent way to go.
Ok, that's good, only 1 problem, you write
shift[i].x += (circlePos[i+1].x - circlePos[i].x) / 4;
this tries to squeeze them all in 1 point!
I was wrong, you actually have to find the distance between the balls after all: the right code for the shifts is:
for(i = 1; i < NUM_CIRCLES - 1; i++)
{
distance=sqrt( (circlePos[i+1].x - circlePos[i].x)^2+(circlePos[i+1].y - circlePos[i].y)^2+(circlePos[i+1].z - circlePos[i].z)^2)
shift[i].x += (distance-2*radius) / 4*((circlePos[i+1].x - circlePos[i].x)/distance);
shift[i].y +=(distance-2*radius) / 4*((circlePos[i+1].y - circlePos[i].y)/distance);;
shift[i].z += (distance-2*radius) / 4*((circlePos[i+1].z - circlePos[i].z)/distance);
shift[i+1].x = -shift[i].x;
shift[i+1].y = -shift[i].y;
shift[i+1].z = -shift[i].z;
}
should work this way (hopefully...)
this way every ball is going to stay at a distance 2*radius from the linked balls(which is what you want)
edit: oh, and after all also I implicitely use the position-last position approach, since when you update v you are just using position-lastposition
shift[i].x += (circlePos[i+1].x - circlePos[i].x) / 4;
this tries to squeeze them all in 1 point!
I was wrong, you actually have to find the distance between the balls after all: the right code for the shifts is:
for(i = 1; i < NUM_CIRCLES - 1; i++)
{
distance=sqrt( (circlePos[i+1].x - circlePos[i].x)^2+(circlePos[i+1].y - circlePos[i].y)^2+(circlePos[i+1].z - circlePos[i].z)^2)
shift[i].x += (distance-2*radius) / 4*((circlePos[i+1].x - circlePos[i].x)/distance);
shift[i].y +=(distance-2*radius) / 4*((circlePos[i+1].y - circlePos[i].y)/distance);;
shift[i].z += (distance-2*radius) / 4*((circlePos[i+1].z - circlePos[i].z)/distance);
shift[i+1].x = -shift[i].x;
shift[i+1].y = -shift[i].y;
shift[i+1].z = -shift[i].z;
}
should work this way (hopefully...)
this way every ball is going to stay at a distance 2*radius from the linked balls(which is what you want)
edit: oh, and after all also I implicitely use the position-last position approach, since when you update v you are just using position-lastposition
©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
I put that code in and now I get some weird outcomes. They're too hard to describe so I uploaded the code to my site so someone can help.
Download Link
Edit: Scratch that. I forgot to fix the velocities based on the distance actually moved. You can still get the code if you want it (it doesn't work) though I don't know why you would.
Edit 2: I did update the file. There's just a weird glitch if you push a button or drag the mouse on the screen. I'm not sure why. I'm not sure what else to enhance my little system. Any ideas?
Edit 3: Forgot to mention, press P to pause/unpause the simulation.
Download Link
Edit: Scratch that. I forgot to fix the velocities based on the distance actually moved. You can still get the code if you want it (it doesn't work) though I don't know why you would.
Edit 2: I did update the file. There's just a weird glitch if you push a button or drag the mouse on the screen. I'm not sure why. I'm not sure what else to enhance my little system. Any ideas?
Edit 3: Forgot to mention, press P to pause/unpause the simulation.
Argh, I dunno... this is the nightmare of coding physics :-(
Ok, so if you're really into it you can work out how to handle collisions, rotations and everything of a rigid shape- not circle. I still havent go into that, my world is made by balls so far ;-)
or better try to turn your rope into a game
Ok, so if you're really into it you can work out how to handle collisions, rotations and everything of a rigid shape- not circle. I still havent go into that, my world is made by balls so far ;-)
or better try to turn your rope into a game
©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
I'd like to add more such as collisions and rotations and getting the rope to swing back and forth (as opposed to just falling and sitting straight up and down). I'm just not sure where to look for information as to how that all works.
hmmm, if the rope stays down instead of swinging you got something wrong... this algorithm should make a very realistic rope, you can also propagate waves in it.
Probably the velocity update is the problem
Or maybe try to delete the code that avoids the circles overlapping
Probably the velocity update is the problem
Or maybe try to delete the code that avoids the circles overlapping
©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
I'm not doing the check for overlaps anymore. Here's my entire circle updating code:
Code:
- (void)updateCircles
{
int i,j;
SEVector shift[NUM_CIRCLES];
SEVector tempVector;
SEVector oldPos[NUM_CIRCLES];
float tempFloat,tempFloat2;
//apply gravity to all of the circles except one
for(i = 0; i < NUM_CIRCLES - 1; i++)
circleVel[i].y -= GRAVITY * elapsedTime;
//add the velocities to the circles
for(i = 0; i < NUM_CIRCLES - 2; i++)
{
oldPos[i] = circlePos[i];
circlePos[i].x += circleVel[i].x * elapsedTime;
circlePos[i].y += circleVel[i].y * elapsedTime;
circlePos[i].z += circleVel[i].z * elapsedTime;
}
//figure out shifts for circles
for(i = 0; i < NUM_CIRCLES - 1; i++)
{
tempFloat = sqrt(pow(circlePos[i+1].x - circlePos[i].x,2) +
pow(circlePos[i+1].y - circlePos[i].y,2) +
pow(circlePos[i+1].z - circlePos[i].z,2));
shift[i].x += ((tempFloat - (CIRCLE_RADIUS * 2)) / 4) * ((circlePos[i+1].x - circlePos[i].x) / tempFloat);
shift[i].y += ((tempFloat - (CIRCLE_RADIUS * 2)) / 4) * ((circlePos[i+1].y - circlePos[i].y) / tempFloat);
shift[i].z += ((tempFloat - (CIRCLE_RADIUS * 2)) / 4) * ((circlePos[i+1].z - circlePos[i].z) / tempFloat);
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 = 0; i < NUM_CIRCLES - 2; i++)
{
circlePos[i].x += shift[i].x;
circlePos[i].y += shift[i].y;
circlePos[i].z += shift[i].z;
}
//reset the velocities based on actual movement
for(i = 0; i < NUM_CIRCLES - 1; i++)
{
circleVel[i].x = circlePos[i].x - oldPos[i].x;
circleVel[i].y = circlePos[i].y - oldPos[i].y;
circleVel[i].z = circlePos[i].z - oldPos[i].z;
}
}
hmmm... bad stuff...
So there are two ways of doing this, WITH the "elapsedTime" or WITHOUT, if you do it WITH you gotta be careful:
you wrote
circleVel[i].x = circlePos[i].x - oldPos[i].x;
while it should be
circleVel[i].x = (circlePos[i].x - oldPos[i].x)/elapsedTime;
(and of course the same for y and z)
(so either you do
x=x+xv and then xv=currentx-oldx
either
x=x+xv*elapsedtime and then xv=(currentx-oldx)/elapsedtime,
while you mixed, i.e. you did
x=x+xv*elapsedtime and then xv=currentx-oldx
)
hope you finally get it working :-)
(then try to put the ability of grabbing balls with the mouse)
So there are two ways of doing this, WITH the "elapsedTime" or WITHOUT, if you do it WITH you gotta be careful:
you wrote
circleVel[i].x = circlePos[i].x - oldPos[i].x;
while it should be
circleVel[i].x = (circlePos[i].x - oldPos[i].x)/elapsedTime;
(and of course the same for y and z)
(so either you do
x=x+xv and then xv=currentx-oldx
either
x=x+xv*elapsedtime and then xv=(currentx-oldx)/elapsedtime,
while you mixed, i.e. you did
x=x+xv*elapsedtime and then xv=currentx-oldx
)
hope you finally get it working :-)
(then try to put the ability of grabbing balls with the mouse)
©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Try downloading the files once and changing that part. When I do it, I get a real big mess of things. It doesn't work as planned but I don't have time to upload a new version to show you because I have work in the morning (12:30 am here, my work starts at 7
).
).
sorry, I dont have a mac here, post your code again and I'm sure I'll spot something else :/
©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Ok. I've updated my code so you can grab it here and check it out.
Here's the code in case you don't want to download anything. It still doesn't swing or sway like real rope. Just falls from horizontal to vertical and sits there.
There's also some weird glitch where any keyboard input will cause the whole thing to jitter. Hard to explain. You'll just have to download the code and build it yourself. I think it might just be slowing the app down and causing the elapsedTime to jump a bit and cause the circles to move too much.
Thanks for all the help.
Code:
- (void)updateCircles
{
int i,j;
SEVector shift[NUM_CIRCLES];
SEVector tempVector;
SEVector oldPos[NUM_CIRCLES];
float tempFloat,tempFloat2;
//apply gravity to all of the circles except one
for(i = 0; i < NUM_CIRCLES - 1; i++)
circleVel[i].y -= GRAVITY * elapsedTime;
//add the velocities to the circles
for(i = 0; i < NUM_CIRCLES - 1; i++)
{
oldPos[i] = circlePos[i];
circlePos[i].x += circleVel[i].x * elapsedTime;
circlePos[i].y += circleVel[i].y * elapsedTime;
circlePos[i].z += circleVel[i].z * elapsedTime;
}
//figure out shifts for circles
for(i = 0; i < NUM_CIRCLES - 1; i++)
{
tempFloat = sqrt(pow(circlePos[i+1].x - circlePos[i].x,2) +
pow(circlePos[i+1].y - circlePos[i].y,2) +
pow(circlePos[i+1].z - circlePos[i].z,2));
shift[i].x += ((tempFloat - (CIRCLE_RADIUS * 2)) / 4) * ((circlePos[i+1].x - circlePos[i].x) / tempFloat);
shift[i].y += ((tempFloat - (CIRCLE_RADIUS * 2)) / 4) * ((circlePos[i+1].y - circlePos[i].y) / tempFloat);
shift[i].z += ((tempFloat - (CIRCLE_RADIUS * 2)) / 4) * ((circlePos[i+1].z - circlePos[i].z) / tempFloat);
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 = 0; i < NUM_CIRCLES - 1; i++)
{
circlePos[i].x += shift[i].x;
circlePos[i].y += shift[i].y;
circlePos[i].z += shift[i].z;
}
//reset the velocities based on actual movement
for(i = 0; i < NUM_CIRCLES - 1; i++)
{
circleVel[i].x = circlePos[i].x - oldPos[i].x;
circleVel[i].y = circlePos[i].y - oldPos[i].y;
circleVel[i].z = circlePos[i].z - oldPos[i].z;
}
}There's also some weird glitch where any keyboard input will cause the whole thing to jitter. Hard to explain. You'll just have to download the code and build it yourself. I think it might just be slowing the app down and causing the elapsedTime to jump a bit and cause the circles to move too much.
Thanks for all the help.
you wrote
circleVel[i].x = circlePos[i].x - oldPos[i].x;
while it should be
circleVel[i].x = (circlePos[i].x - oldPos[i].x)/elapsedTime;
(and of course the same for y and z)
If you say this does not work (it gets unstable), try deleting "elapsed time" from all the formulas (and also decreasing the gravity, o/w it would be too high), and see if that works, the system should be more stable.
(In this kind of stuff, if the elapsed time jumps from 1/60th of a second to 1/50th, you have big problems (caused by the velocity updating), that's why it's better to keep stuff "loop based", not "time based")\
If it's still unstable try putting
circleVel[i].x = (circlePos[i].x - oldPos[i].x)*0.99
(and of course the same for y and z)
And yes, probably the jumping thing is caused by the pressing buttons to change the "elapsed time"
circleVel[i].x = circlePos[i].x - oldPos[i].x;
while it should be
circleVel[i].x = (circlePos[i].x - oldPos[i].x)/elapsedTime;
(and of course the same for y and z)
If you say this does not work (it gets unstable), try deleting "elapsed time" from all the formulas (and also decreasing the gravity, o/w it would be too high), and see if that works, the system should be more stable.
(In this kind of stuff, if the elapsed time jumps from 1/60th of a second to 1/50th, you have big problems (caused by the velocity updating), that's why it's better to keep stuff "loop based", not "time based")\
If it's still unstable try putting
circleVel[i].x = (circlePos[i].x - oldPos[i].x)*0.99
(and of course the same for y and z)
And yes, probably the jumping thing is caused by the pressing buttons to change the "elapsed time"
©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Hm. I deleted all of the elapsedTimes from the equations and lowered the gravity (from 3000 to 10 to 5 to 1 to .098) and none made it stable. I also tried the *.99 for the new velocities but still nothing. I'm confused as heck. I'll try some things and get back. If anyone else spots something, let me know. I'm on AIM all the time.
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Ragdoll Physics | merrill541 | 1 | 2,295 |
Feb 5, 2009 09:09 AM Last Post: JustinFic |
|
| Ragdoll Physic's: (For GML).. | Master_Computer | 0 | 2,159 |
Jan 27, 2008 11:55 AM Last Post: Master_Computer |
|
| Bullet Physics Library / COLLADA physics viewer | erwincoumans | 14 | 11,230 |
Aug 12, 2006 12:59 AM Last Post: Fenris |
|
| Ragdoll Physics | Duane | 3 | 3,715 |
Jul 7, 2005 09:55 AM Last Post: Duane |
|
| Ragdoll and cloth physics | Skorche | 28 | 12,001 |
Jun 10, 2003 03:12 PM Last Post: Fenris |
|

