Waggling Rope

Topics: Developer Forum, User Forum
Jun 9, 2009 at 9:00 AM

Hi there. Still working on my small project, like a lot of other people here, I'm implementing a rope. First I used the Path generator, but I ended creating my own for making a nice animation, pooling objects and for the collision detection for stopping adding links to the rope. So far it works well (see video), but even I'm using Revolute Joints, the rope seems to extend when swinging (as you can see in the above video), and the rope's links waggle a lot. Does anyone has an idea how to avoid that and have a stiffer rope. I checked this thread but I'm not sure to understand what RogueCommander suggests, I added angle springs, but it makes the rope waggle more :S

Cheers!

Jun 9, 2009 at 9:38 AM

Joints calculate their force according only to the mass of the 2 connected objects, not to any other objects that are connected to those objects, so the more connections you have the more mass there is that isnt held together.

To make it stiffer you can increase the mass of the bodies (although there is a point where this doesnt work, I think it depends on the length of the chain). This doesnt sound right, making each body lighter sounds more logical, but its worked for me, and kind of makes sense with my understanding of joints. Sometimes making it lighter has also helped, so maybe Im mixed up and theres another explanation :D

And/Or  you can space the bodies further apart. That makes less un-accounted for force.

Jun 9, 2009 at 10:12 AM

Amazing! Thanks Robert, it works! I made the links heavier and added a little more space between them and it works great. The only problem I have now is that when I fire the rope and it doesn't attach to anything, the character becomes too heavy and it can't jump or move (even it "sinks" a little on the floor, because it's bottom part is a circle, not a rectangle) I have to figure it out how to solve this now, but now it looks like a great swinging game :)

Jun 9, 2009 at 1:57 PM

If anyone cares, here's the result assigning more mass to each link in the rope (well... chain, I mean) and separating them.

Jun 30, 2009 at 11:46 AM

I made some improvements and I think now is far better. I'll explain if somenone wants to know.

Each link of the rope (or chain) is sticked together with a LinearSpring, and with a SliderJoint, whose values are 1 for the minimum (when the rope is totally "compressed") and the default maximum space between links when the rope is extended to its maximum. Now I have a steady and nice elastic rope :)

BTW robertdodd: I just checked BoxyCraft and I'm truly amazed, ¡is awesome!

Jul 2, 2009 at 10:08 PM

you should do another video, I'm excited to see what it looks like now.

Jul 3, 2009 at 1:08 PM

Thanks for your interest mechaghost :) I'm not sure if it's notiecable enough through a video, but I'll upload it anyway. Now with the linearspring is a lot more "elastic" but not chewing-gum-elastic thanks to the sliderjoint which prevents the rope to not stretching too much. This is more noticeable when the character is falling at high speed and hooks him up.

As soon as I return home I'll upload the video :)

Nov 2, 2009 at 9:54 PM

Ive come up with a good solution to this problem that works really well, as long as you dont need the rope to collide with objects.

Use a slider joint, between the 2 objects. Then create a rope like you did before, but set the geoms so they don't collide with anything(collision categories). Then Fix the 2 ends of the rope with FixedRevoluteJoints and then on every update set the anchors of the 2 Fixedrevolutejoints to the world positons of the anchors of the sliderjoint.

The advantages of this approach is that the rope does'nt weigh anything, so doesnt effect the swinging or the objects. It also looks good and realistic. And the rope can still break if you want it too when it stretches too far.

The disadvantages are that if the objects are swinging fast, the rope sometimes lags a bit behind. And the rope doesn't collide with stuff.

Nov 3, 2009 at 9:37 AM

Nice idea, but instead of setting the geoms that don't collide with anything, you can simply not use geoms at all. Only bodys :)

I'm using this approach right now with ropes and works well (anyway for my grappling hook it does use geoms as I need them to collide).

Dec 15, 2009 at 8:35 PM

Hi all,

I'm currently facing the same issues you had for implementing correct rope dynamics in Farseer. I'm trying to produce a steady rope, but this only happens when I increase link mass. However, if I do this, when I throw the rope the character is pulled by its links and "flies" away with it...

That said, I have a number of questions:

1) I've been studying the approaches proposed in this thread, and I tried to approach them using the Farseer Path class. Here's how I'm doing it:

 

// Create path and control points
var min = 1;
var max = 3;
var springConstant = 200;
var dampingConstant = 4;
var path = new Path(Width, Height, Mass, false);
path.Add(parentTransform.Position);
path.Add(Vertices.FindMidpoint(parentTransform.Position, transform.Position));
path.Add(transform.Position);
path.Update();

// Link bodies and create geoms
path.LinkBodies(LinkType.LinearSpring, min, max, springConstant, dampingConstant);
path.LinkBodies(LinkType.SliderJoint, min, max, springConstant, dampingConstant);
path.AddToPhysicsSimulator(simulator);
path.CreateGeoms(CollisionCategories, CollidesWith, simulator);

Is this a valid approximation to achieve your level of performance?

2) In your current method, what is the difference between link mass and agent mass? In my case, the agent has a total mass of 2, and each link had a mass of .04. Is this too much of a difference?

3) I'm yet to experiment the last method robertdodd suggested. As I understand it, in this method the mass of the body hanging in the rope doesn't matter, since you're using a fixed joint. Is this interpretation correct? If it is, it may in fact be the best method.

Thanks so much for your patience and support :)

Best regards,

Gonçalo

 

Dec 16, 2009 at 8:22 AM

Hi Gonçalo (Portuguese? Brazilian? :) ) I don't have the code right now in front of me, so I'll have to confirm some of the answers later ;)

1) I implemented my own path class combining spring joints and slider joints, but your code does something quite similar to mine. Anyway, taking a look at the code you used for creating the path, I think it should do the trick, it depends on the exact visual and physical effect you want to achieve, so this is quite a try & error excersise.

2) As far I remember my agent has a mass of 2 and the links 0.5, so I guess we are pretty close in these numbers :) I also had the problem that the character is "dragged" by the links' weight, but king of solved it increasing the character's friction coefficient.

3) Robertdodd's method should work nicely (as most of the suggestions and code he submits), only if you don't need collision for the rope. Unfortunately collision was mandatory for my game and I had to go back to my original implementation :(

Hope I helped you somehow, cheers!

Dec 16, 2009 at 1:41 PM

Thanks for the reply :-) I'm actually from Portugal.

I think I'll go for the Slider Joint based method as well, as I would very much appreciate rope collisions. The only problem seems to be the fine tuning of the SliderJoint Min and Max, so that when the Slider is at its Max it actually feels like the rope is stretched.

I can't seem to find the right way to do this, as the rope's lower segments (those closest to the player), always seem to be loose (forming a little belly) and the upper segments are already stretched beyond their limits.

Also, our mass differences are a bit different in that my link mass is 0.04, which is an order of magnitude less than 0.5. Maybe this accounts for the incorrect stretching, but if I don't keep it that way, it becomes impossible for my character to jump while holding the rope (just too heavy).

Thanks for all the help. I'll do further experimentation when I get home.

Dec 16, 2009 at 2:11 PM

Ooops, I saw 0.4 instead of 0.04.

For the jumping, you can modify the impulse when the rope is being hold. Is a dirty trick, but maybe that should do it. In my game, when the character jumps, it drops the rope (well, the grappling hook).

Dec 17, 2009 at 10:28 AM
Edited Dec 17, 2009 at 10:32 AM

Ok, I finally got to a rope setup which is quite pleasing and has no tricks :D It's really a combination of stuff which has been said in this post, but works like a charm.

Suppose you have body A and body B you want to connect by an ellastic rope. The setup is as follows:

  • create the rope between A and B using the regular Path class or other similar method (in my case works best by linking rope elements using slider joints, but any other joint is fine). the rope links can have any mass you require them to (you can make either heavy chains or light ropes with ease)
  • (optional - shooting) if you want to shoot the rope, it's best to add an object with larger mass to the rope's end (e.g. a circle body) and apply the throwing impulse to that body
  • attach the first link of the rope to body A (usually the throwing agent)
  • eventually attach the last element of the rope (e.g. the circle body in the case of shooting ropes/hookshots) to body B using a joint (usually this is done on collision event)
  • now here's the magic spice:
    • connect bodies A and B using a LinearSpring with RestLength set to the distance between A and B (this is the default)
    • during the time the connection is active, update RestLength on each frame to be min(distanceAB, maxRopeLength), where maxRopeLength is the maximum length of the rope when completely stretched

With this setup I achieved perfect flexibility and robustness for my system.

I can have different masses between the rope links and connected objects. In my case A and B have a mass of 1 and each rope link has a mass of 0.04, thus solving both the jumping problem (if the links are too heavy, the character can't jump his usual height without extra impulse) and the throwing problem (in some previous methods throwing the rope would pull the character along with the rope).

I can also have collisions between the rope links and the environment, which will react appropriately given the mass of those links (e.g. lighter ropes will react softer than heavy chains).

The generality of the setup was tested with a variety of situations, including swinging off things, pulling stuff with it and rappeling down from ledges. The rope is also climbable by dynamically and smoothly controlling RestLength on the spring between A and B.

I'm still on some minor fine-tuning stages, but I'm pretty satisfied and confident with the setup, basically because it intuitively models what's happening in the real physical model (the linear spring is exactly made to simulate rubber bands, which is really what a rope is if you account for slack (which I basically did by updating RestLength dynamically).

This setup could be made even easier to implement if the LinearSpring also had Min/Max values for resting the spring instead of a single RestLength, but it's really just a convenience.

Hope this wrap-up of techniques is useful to anyone, it sure was useful to me :) Thanks for all the help and attention, this community is really great!

Best regards,

Gonçalo

Dec 17, 2009 at 11:14 AM

Very nice Chance!

Could be possible to watch a video with the resulting effect? I think I'll try your approach to see if it works better than mine :) 

Apr 13, 2010 at 12:05 PM
Edited Apr 13, 2010 at 12:22 PM

pnikosis, I've been watching your videos and I really dig your ropes/grappling hook! Did you end up using Chance's approach?

I'm in need of a variable length rope for my project, but have minimal experience with the path class and techniques described in this thread.

I understand all the concepts, but don't know where to begin without some hands-on code examples.

If anyone wants to share some proof-of-concept code it would really be appreciated.

Apr 14, 2010 at 9:12 AM

Hi Zms, as you can see from the video, the rope can be streched once the hook has been fixed (so it has a variable lenght). I used a combination of my approach and Chance's (I added an additional spring attaching the two ends of the rope). I didn't use the path factory as I needed more flexibility on removing links. The rope is made with a series of small geoms linked with springjoints, and as I said before, an additional springjoint attaching the two ends. When I want to stretch the rope I remove a link, and then modify the anchor points of the previous and following link (as they were attched to the removed link), then the "large" springjoint restlenght is reduced in the lenght of the removed link.