Jump to content

Ways to Achieve Ragdoll Effect using Cannon.js?


Raggar
 Share

Recommended Posts

So, I'm looking for ways to create a ragdoll effect using Cannon.js, and (preferably) a skinned, imported mesh.

I tried the following 2 methods:

#1: Use getRotation/position/absolute.. etc on the bones, to match with the Cannon bodies.

This doesn't seem to work like it does the other way around (Match Cannon body to bone position and rotation).

#2: Split my model into the different body parts, so each and every limp can be used seperately.

This 'can' work, but requires a lot of work, and won't look as good as on a skinned model.

Here is an example of a ragdoll, shamelessly stolen from the Cannon.js Three.js Ragdoll example:

http://www.babylonjs-playground.com/index.html#XVETC#3

I'm looking for creative ways of achieving this very same ragdoll effect, but with a model.

Edit: Forgot to mention, press A to start the ragdoll by enabling the stepping of the Cannon world.

 

Link to comment
Share on other sites

It does look a bit cooler than key frame based death animations.

I thought about dismemberment, too.

I guess the easiest way is to chop up your model in limps, and then remove/replace them.

You would even be able to take the vertices of, let's say the head of a model, scale and move them inside the body, and then set a second model of a bloody head to visible in it's place, and apply some gravity using a physics engine or something like that.

When I read about ragdolls in some older threads, someone mentioned matrices and stuff, so I got scared and closed the tab :o

Link to comment
Share on other sites

http://www.babylonjs-playground.com/index.html#XVETC#7

This is the closest I've come to a ragdoll, and it's Very wrong :P Press A for ragdoll. The rotations will of course be off, as all I do is applying the quaternions from the physics bodies to the bones, which doesn't make much sense.

I even thought about taking the quaternion from when the ragdoll is first created, then every frame calculate the difference between that quaternion and the current quaternion, then apply the difference to the rotationQuaternion of the bone. That gave undesired results aswell :P

 

Link to comment
Share on other sites

@BitOfGold

Gave the IKController a go, and ended up with the following raggardoll:

http://www.babylonjs-playground.com/#0DE8F4#4

(Hold down A when you want to run the simulation)

It needs tweaking, but it's getting better :D

The dude model has a bit too many bones in the head area, but as I have some issues using IKControllers using my own model, I'll have to figure that out first.

So the head isn't moving at this time. But the upper body is.

Here's one with a little added impulse:

http://www.babylonjs-playground.com/#0DE8F4#5

The code might be a bit too prototype-ish. :P

Making the constraints more rigid messes with the realism, so a stiffy doll seems easier to tweak.

Link to comment
Share on other sites

http://www.html5gamedevs.com/topic/16984-bones-ragdoll/

Might be worth a read.  Unfortunately, @Samuel Girardin's http://www.visualiser.fr/ site... is DOWN.  Oh no!  He has a pretty nice ragdoll and its .ts source, zipped and released.  Darn.  Quite an advanced coder, but possibly BJS 1.18 code, or older, so far.  He made his raggies 2+ years ago, I think.

What happened to Sammy?  That guy... phew... he's one of them SUPER "big dogs".  He's probably living the good life, on the beach, with the fancy things, these days.  He used to hang out with puppies like me... before he became a French Riviera superstar.  :)  (okay, likely NONE of that is true).

Raggar, you're doing quite well!  Thanks for showing us what you've done.  You're teaching many!

Link to comment
Share on other sites

Well, wayback machine archived some code from this multitalented @Samuel Girardin.
https://web.archive.org/web/20161122211718/http://www.visualiser.fr/Babylon/character/dev.js

Some of visualiser.fr is saved. But not the ragdoll with cannon.js :(
https://web.archive.org/web/20161101113136/http://www.visualiser.fr/index.php

Link to comment
Share on other sites

48 minutes ago, BitOfGold said:

Awesome. Just downloaded the source. It looks advanced :P

1 hour ago, Wingnut said:

http://www.html5gamedevs.com/topic/16984-bones-ragdoll/

Might be worth a read.  Unfortunately, @Samuel Girardin's http://www.visualiser.fr/ site... is DOWN.  Oh no!  He has a pretty nice ragdoll and its .ts source, zipped and released.  Darn.  Quite an advanced coder, but possibly BJS 1.18 code, or older, so far.  He made his raggies 2+ years ago, I think.

What happened to Sammy?  That guy... phew... he's one of them SUPER "big dogs".  He's probably living the good life, on the beach, with the fancy things, these days.  He used to hang out with puppies like me... before he became a French Riviera superstar.  :)  (okay, likely NONE of that is true).

Raggar, you're doing quite well!  Thanks for showing us what you've done.  You're teaching many!

I remember trying it out some time ago. Less than a year, though.

And then recently again, as I made this thread. What turned me off of his way of doing it, was that I needed to unlink the bones, and that would complicate my already made animations.

However, it might be possible to create a secondary skeleton with individual bones with no parents, and then link these indivual bones to their corresponding bones in the first skeleton. By doing this, they'll follow the animations, while still maintaining the power to modify the vertices on their own.

Now, I guess the reason he did this was, that when you move or rotate a bone, let's say the shoulder, all children will move along according to that bone. So the upper arm, lower arm and hand bones will all move according to the shoulder, and then move Again according to their own bodies in the ragdoll setup. I'll certainly give this method shot.

Link to comment
Share on other sites

  • 2 months later...

@Wingnut @BitOfGold

I gave it a go again this evening, and downloaded @Samuel Girardin's source.

I first ported it to use CannonJS instead of OimoJS, and as it uses the impostor system it wasn't that much work. Then I did some back and forthing to get it to work with BabylonJS 3.0.1 Beta. I believe the version I successfully tested with was 2.0.2. It has some weird issues, almost soft-body like, which also seem to impact performance. But most features of the original have been restored. And based on the .max-file, I can see that he did what I mentioned earlier on. Linking the individual bones to his base-skeleton.

After updating to, hmm, 2.2.0 I think, the CannonJS shapes were somehow particles, but now they are all proper boxes. There is too big of a difference between this and the original, though.

The old man is almost 'flowing' in the air, no matter the gravity and mass. It might be an idea to limit the rotation of the bodies, but right now I can't figure out why he is ghosting the way he does.

I'm hoping I'll have time this weekend to create a basic, slimmed-down PG version to do some further testing. I'll see if I can do it with the impostor system first, although I'll need it in native CannonJS for one of my projects.

 

http://92.222.89.13/oldman/

http://92.222.89.13/oldman/oldman.rar

Link to comment
Share on other sites

Cool!  Thx, Rags! 

It looks slow.  Have you tried the "adjustment" that speeds-up CannonJS heightmapImpostors for BJS 3+?  It probably works for all CannonJS stuff.

//-----------------------------------------
BABYLON.CannonJSPlugin.prototype.executeStep = function (delta, impostors) {
    this.world.step(this._fixedTimeStep, this._useDeltaForWorldStep ? delta * 1000 : 0, 3);
};
//-----------------------------------------

Just paste that into your code somewhere... see if you get a 300% physics speed increase.  *shrug*  Worth a try.  :)  It is the exact same code as default, but when you bring it "up" into your mainline, CannonJS speeds up nicely.  It's the 6162 issue:)  It has been unsolved SO LONG, that it has earned a place on my bookmarks toolbar.

Link to comment
Share on other sites

Hmmm.

On 7/5/2017 at 9:42 PM, schteppe said:

Hi, I played the game and it's cool, and very easy to get hooked :D

Had a quick look at the "too fast rolling ball" problem and it seems like it needs to be fixed in Babylon.js, specifically in the CannonJSPlugin. If you change this line so "delta * 1000" becomes just "delta" it should run at the same speed on all platforms (cannon.js uses time in seconds, but the number passed seems to be in milliseconds). /cc @RaananW

 

Well. Doing just "delta" seems to be the normal speed, and giving it * 1000 seems to be A Lot better. It's not quite heavy enough, but that can be tweaked using gravity and mass.

Now, the second issue 'might' be due to the joints being able to freely move without any restriction. In my other tests, I used a ConeTwistConstraint, which I don't seem to be able to find in the impostors system, which in this case uses the HingeJoint instead. I think there might be an issue with the way I'm passing the limitations I want to the impostor system. I'm passing them as native options, and that might seem to be an issue somehow. For some reason, I can't get the limp-impostors to collide, with or without setting native parameters.

Link to comment
Share on other sites

This is a tough one, even with all the code basically laid out in front of me :P

I first started out trying to port the code to native CannonJS, which so far is a small success. The bones are influenced by the CannonJS bodies, although it's not quite a ragdoll yet. More like a cluster of fruit going bat shit insane. :D

Now, I'm not sure what I'm missing in porting both native CannonJS, and Impostor to the playground. I started recreating the code, and later copied it as much as possible to avoid mistakes.

Somehow the bones don't give many F's about the bodies. Here's the Impostor version(No joints applied yet, baby steps - Ragdoll mode starts after a few seconds):

http://www.babylonjs-playground.com/#CRFZZF#5

Take a look at line 477. This is where the magic happens.

But for some reason, unknown to me, even as the matrices of the individual bones are manipulated to take into account the position and orientation of the impostors, they still stand absolutely still.

Although after a few minutes, he starts jiggling like crazy...

Any help would be appreciated.

Link to comment
Share on other sites

Maybe some of the big boys like @RaananW or @adam can figure out why the following doesn't work:

http://www.babylonjs-playground.com/#VADCKV#6

Here is the very same PG, just with line 335 (bundle.bone.updateMatrix(m);) commented out:

http://www.babylonjs-playground.com/#VADCKV#7

Press A to stop the animation and turn into ragdoll mode. No impostors have been added to this version, as I'm trying to figure out why the matrices of the bones don't match up with the boxes.

The following function applies new matrices to the bones based on the matrices of the boxes:

setBoneMatrix = function (bundle, v, o) {
        
        var t = bundle.offset;
        //console.log(this.helper.position);
        bundle.helper.locallyTranslate(new BABYLON.Vector3(-t.x, -t.y, -t.z));
        //console.log(this.helper.position);
        var world2 = bundle.helper.getWorldMatrix();
        world2.invert();
        var m = bundle.bone.getWorldMatrix().multiply(world2);
        
        if (!bundle.wait) {
           // console.log(this.bone);
            //this.bone.update(m);
            //console.log("matrix", m);
            //console.log(this.bone.getWorldMatrix());
            bundle.bone.updateMatrix(m);
            //console.log(this.bone.getWorldMatrix());
        }

        var qinvert = BABYLON.Quaternion.Inverse(bundle.qset);
        var r = bundle.mesh.rotationQuaternion;
        bundle.helper.rotationQuaternion = r.multiply(qinvert);

        var t = new BABYLON.Vector3(bundle.mesh.position.x - v.x, bundle.mesh.position.y - v.y, bundle.mesh.position.z - v.z);
        bundle.helper.position = t;

        bundle.wait = false;
};

The bundle is simply an object with an id, the box mesh, an empty "helper"/dummy mesh and a bone.

The bundle.offset is simply the position of the bundle.mesh (The box).

The bundle.qset is the rotationQuaternion of bundle.mesh

These are set every frame, while the animation is playing.

The v and o are the position and rotationQuaternion of a dummy (empty mesh) object of the main model itself. These are not changed anywhere in the original code. Only reset to 0 when going from ragdoll mode to animation mode.

The function is called on line 94 like this:

setBoneMatrix(bundles, oldMan.dummy.position, oldMan.dummy.rotationQuaternion);

Link to comment
Share on other sites

Hi @adam, 

About the old'man ragdoll demo. Just few things, it was developped  with and for oimo, You cannnot switch to cannon without re-developped all. Babylon physic plugin is just a sort of wrapper which try to unified call to 'similar function' you have in cannon and oimo. In fact there are only similar and the result of those functions is different if you use one or the other.

I totally agree with @adam, in fact oldman demo began with a cylinder and 4 bones to simulate a rope.   

Link to comment
Share on other sites

Yo @Samuel Girardin :D

The demo at http://92.222.89.13/oldman/ is in fact using CannonJS. I changed it from OimoJS, as I prefer CannonJS myself.

It doesn't come even close to your original demo, but it works. It has some performance issues when doing multiple ragdolls, as well as needing some limitation of the joints. That's why I'm trying to recreate it in the playground, to get Just the basics running, and going from there.

I believe  http://www.babylonjs-playground.com/#VADCKV#10 is the least amount of code I need to make it work, although it doesn't at this point :P

But I still think it's very important to get a working, simple example of a ragdoll on the Playground, as this is essential in a game engine, and from what I see, most people using physics in BabylonJS use CannonJS.

Link to comment
Share on other sites

YOU... are a God, Raggar!  Holy crapolas!  Sammy's "Old Man Ragdoll" IN A PLAYGROUND!  Excellent x 1000!

See?  Raggar - ragdoll, it was inevitable destiny!  Way way way way COOL, Rags!  Oh my God.

Ok, JS-controlled Rock'em Sock'em robots, YEAH!   Random outcomes.   Betting-on your favorite fighter... for shots of booze... against your buddies!  Cool.  :)

"That Old Man Ragdoll... that Old Man Raggar... he just keeps rollin'... he won't stop flowin'.  That Old Man Ragdoll... he just keeps rollin'... a-long." :)

(Especially true after I fire a 4000-mass Cannonjsball at him!  POOM!  Got joints?)  ;)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...