Demo with Ammo.js Physics Engine

Recommended Posts

On ‎1‎/‎8‎/‎2018 at 4:23 AM, JohnK said:

@RaananW you probably are well aware of the following information but in case you are not you may find what I have learned useful.

Info on using BJS with Ammo

Threejs demos with Ammo from this github




Thanks JK for the bjs samples for ammo.js. Now that I feel very comfortable with this whole wasm, empscripten tool chain, js<->c++ interops, I am going to look into this with excitement! :)

Share this post

Link to post
Share on other sites
On 6/4/2018 at 8:26 AM, HoloLite said:

Thanks JK for the bjs samples for ammo.js. Now that I feel very comfortable with this whole wasm, empscripten tool chain, js<->c++ interops, I am going to look into this with excitement! :)

Holy crap... that bjs demo code looks good... I only have one question if you can do all the stuff with the ammo.js api and babylon.js api... WHY IS IT NOT A PLUGIN ???

I cant believe no one in the community has made this a plugin... wow

Share this post

Link to post
Share on other sites

Hey Mackey, good to hear from you again :)

Well there are problems with plugin:

- non standard, breaking cross browser compatibility, security issues etc. In the end, people won't use it. Remember silverlight? 

Not to mention the hassles of installing the plug in, which is against the spirit of webapp app development. 

I have high hopes for webassembly! 

Share this post

Link to post
Share on other sites

I been messin around with PlayCanvas to see what the other guys are doing... And man o man ... there Ammo.js implementation is KILLING our Cannon.js

Way faster, especially on mobile... much better heightmap and terrain imposters

cant tell how they do collision groups l. But that type of collision filtering has gotta be support in bullet physics... got to

i dont have the time to go figure out the whole time step and synchronize thing the cannon plugin does. With all the stuff I am trying to get the toolkit production ready.

again was hoping that would be a priority the community would be working on seeing how your physics engine does everything for you ... You NEED it for ANY type of presice movement with collision and collision detection and really ray casting ... I think a good C++ port of bullet ray cast will perform a bit better the Pick With Ray... especially when you Have to have mutiple rays casting from multiple characters in the scene. I’m just guessing... 

but PlayCanvas says they are achieving 1.5 x native speed ... that’s near full native performance

we should be working on this... for real 😳 

Share this post

Link to post
Share on other sites

Man ... I don’t really have time to figure out the whole would stepping and updating all the positions enough where I would be confident that it’s working right. But those guys over at PlayCanvas got a pretty smooth implementation of ammo.js 

So I know we can do it 

Share this post

Link to post
Share on other sites

Hi girls.  I just wanted to keep this thread alive and bother ya'll.

Been thinkin'... 'bout physics.  I hear a rumor the @trevordev has jumped into the ammo.js "fire"... along with @JohnK and other ammo-testing pioneers.

Good to have you, t-dev!  @RaananW has been a bit real-life busy, but I'm wondering if any of you know about his "BJS Ammo Plugin" progress-so far? 

Tdev... are you building an ammo plugin... that started with his?  Just curious.  I'd love to hear a report about what you've been doing with Ammo, @trevordev.  Thx.

Have you guys seen this?

Looks a little stale, but... hmm.

Anyway, based upon names, I think Oimo is a basic clone of Ammo.  It's not important, but I wanted to talk about two parameters that we do not "honor" in our current Oimo plugin:

- collidesWith
- belongsTo

There is a guy over in another thread... wanting info about how to physics-activate a skeleton.  I know @Raggar was doing some playground work on activating @Samuel Girardin's ragdoll.  It's a good one.  Its joint work pretty well.  Rags' demos are currently broken.  Maybe he'll visit and teach us stuff.  Raggar is not scared to "go native"... talking-around the BJS plugins, and speaking in native rigidBody and joint language.

belongsTo and collidesWith - it is no problem that they are not DIRECTLY supported in the Oimo plugin.  @RaananW installed an easy system to send native calls directly to physics engines/objects.  SO, you can set collidesWith and belongsTo... just fine.

Now let's talk about collidesWith, which allows "belongsTo groups"... as values/settings (in hex).  Let's imagine a knee joint on a skeleton... and its bend limits and hinge type.  Let's roll-up a joint:
var myJoint = new BABYLON.HingeJoint({
    mainPivot: new BABYLON.Vector3(50, 0, 0),
    connectedPivot: new BABYLON.Vector3(-2, 0, 0),
    mainAxis: new BABYLON.Vector3(1, 0, 0),
    connectedAxis: new BABYLON.Vector3(1, 0, 0),
// this might be same as collidesWith 0x00000000 (nothing)
    nativeParams : {
        limit: [0, Math.PI], 
// not sure if same thing as min/max.
        min: 0,
        max: 100, 
// radians?  degrees?, who knows?
        // belongsTo: 0x00000010,
        // collidesWith: 0x00000011

source.physicsImpostor.addJoint(target.physicsImpostor, myJoint);
// late settings preferred?  Like this:
myJoint.setLimit(10, 10);
myJoint.setMotor(10, 100);
// research this
myJoint.executeNativeCall(yyyyyy);  // research this

When thinking about an upper leg and lower leg - connected by a hinge joint, we tend to want to make the mainPivot and the connectedPivot... NEAR each other.  We want a "tight hinge".

BUT... if your leg meshes are rectangular boxes(-impostors)... with some significant thickness... bending the hinge will collideWith the OTHER leg mesh... easily... due to low (vertical) distance between upper and lower leg (impostors).  (in humans, same as:  limited knee bend due-to too much thigh and calf fat)  (vomit)

See how the amount of allowed hinge-swing... was limited by a "tight hinge"? (pivot points vertically near each other).   The upper/lower leg mesh... collided with each other... after very little knee-bend allowed.  CollidesWith and grouping-tool BelongsTo... start becoming important properties/parameters, eh?

Lots of ragdoll makers... are happy using these collisions... as the motor limits (angle limits) for their ragdoll hinges.  Unfortunately... if another user comes along one day, and makes the upper and lower leg mesh be REAL SKINNY, all of a sudden.... the joint becomes very wobbly and unable to "stand up".  OR, if a future user decides to increase the distance between the two pivot points, ragdoll knee will ALSO go wobbly and faw-down-go-boom.  :)

The only way... to ensure that the knee joint ALWAYS acts like a knee joint... is to use setLimit calls (or, likely, min/max params)... and NOT depend upon collidesWith (lower leg mesh to upper leg mesh) to do your bend/rotation limits.  With setLimits on the joints, future users can spread the pivots apart or closer, or change leg mesh diameters, and the knee still acts like a knee.  It has math-set bend-limits and not impostor-collide bend-limits.

Heavy, eh?  So how do we turn a skeleton into a physics-active "jointed" skeleton?  Lots of friggin' work, I suspect.  A joint-add at the end of each bone, right?  Ow.

No real purpose or point to this post.  Just thinking about (Oimo) belongsTo and collidesWith... two parameters that, likely, we will ALSO see... in AmmoJS. 

Just thinking about how to keep ragdolls standing on their own... without having car-sized feet.  :)   In Sammy Girardin's Old Man ragdoll, I think he held them upright with an invisible mesh above their heads... and a single hinge2Joint dangling-down to their head-impostors.  The arms hung naturally, the legs did the same... setLimits or min/max on each joint.... and careful mainAxis and connectedAxis settings (natural limb-hang angles).  Phew.  Magical.

In humans, a joint's allowed bend-angles and upper/lower limits... are set by bone locations and/or muscle-extension abilities.  I haven't talked much about setMotor... but... setMotor calls are how you get a stretched muscle... to return itself to natural limb-hang.  Gravity on the limb impostors CAN do all the work... but a SWEET ragdoll... will keep increasing setMotor back-force IF another force is trying to move the hinge-angle beyond a limit.  In fact... the motor should start counter-forcing well-before the motor limit or hinge angle limit (same thing?).  Muscle stretch-ability.  Elasticity.  GRUESOME!

Constraints.  Everything is a "constraint".  Mesh are free to fly anywhere, unless they are constrained by forces such as impostors and joints.  FUN!  Mesh wrangling and roundups!  Mesh corrals.  Cowboy stuff!  I got cow poop on my boots!  Ki-Yi-Yippi-Yi-Ay, lil dowggies!  (spit)  (toothless grin)

And we're still NOT talking about skinning and weighted vertices.  This is ALL armatures.  BLECH!  :D

SO MUCH to think about, eh?  Good luck with the AmmoJS progress, guys.  I cannot find an API/docs for that thing, but I'm going to assume that it has some belongsTo and collidesWith stuff inside... along with setMotors and setLimits.  Should be a GOOD TIME!  PARTY!  Thanks for your work, guys! 

Warning:  There's still a guy/gal out there on the forum... asking how to physics-up his skeleton.  QUICK, EVERYONE HIDE... PRETEND NOBODY IS HOME!!!  heh

Somebody was doing SOMETHING... here:

Found it with playground search for mainAxis.  Its PG metadata has "Walker" in the name.  hmm.

Share this post

Link to post
Share on other sites

@Wingnut My current progress is here:

I have basic physics features working right now (Shapes, forces, etc) so this scene is good when using ammo (, whats left is collision events, parenting/joint types, gltf support and more testing/examples (eg. driving a car).

I still have an issue I am trying to solve: but havn't figured it out yet.

I may try to get a PR out soon and add additional requested features as desired. There is a lot of area to cover, I would like to support things shown here eventually:

Share this post

Link to post
Share on other sites

Thanks tDev... nice work.  Thx for the links, too.

lo-th?  That's the folks who made Oimo, right?  Interesting.  We're among friends.

Note:  If you are "on" the Firefox "ESR" update channel, like myself and other Firefox Quantum haters, you'll need to update to FF... oh... v60.0.3esr... to get your WASM activated (for the above lo-th links to work).

Their ragdolls are doing exactly as I described.  The mesh on each side of the joints are SO CLOSE TOGETHER, that the mesh impostor collisions make them "stiff".  None of the joints flex as well as a real human.  Hinge angle limits caused by colliding impostors - suck. 

The International Rag-Doll Society would give them a C- rating, at best.  :)

Smuck those ragdolls with a high-speed train, and we would probably yawn to death.  :o  About as flexible as a Pillsbury Dough-boy or Stay-Puft Marshmallow guy.

Generally speaking, if a fast-tumbling ragdoll carcass can't kick itself in the head a few times... before wrapping itself "around" a telephone pole, it hasn't met my stringent flexibility requirements. 

When that dragon grabs that medieval guardsman by the head... and starts SLAPPING his body repeatedly onto the brick floor, we need some limbs floppin' and bouncin'... violently.  And sounds, too.  We need to HEAR them bones bangin' on those bricks... SO morbidly demented!  ;)

Share this post

Link to post
Share on other sites

Likely off-topic, but there's two more impostor parameters: move and density.  I don't know what their story is, but I've seen them laying around in various playgrounds.  Just another interesting parameter.  As you can see by these lines in the Oimo plugin, we sort-of quick-bind them... to the mass parameter.  When we see things like these "safe default values", we can lightly assume that CannonJS doesn't have comparable/similar parameters.  These two parameters could be an Oimo-only thing.

density likely becomes more-pertinent... in soft-body operations.

@trevordev - are you attempting to make the Ammo plugin... have the same basic API... as the Oimo and Cannon plugins?

That "universal API for basic physics" is a good idea, but Ammo is the first physics engine at OUR JS level... to offer soft bodies.  So, the Ammo plugin's API really CANNOT mirror the other two plugin API's.  The other two have no soft-bodies.

So now, Ammo plugin coders try to mirror SOME of the API from the other two.  In doing that, does it FEEL like we are needing to de-power the new Ammo plugin API... simply because of this "pull" to mirror the API of the older/long-established plugins?  Does anyone think about that?  Yes, the nativeParams "portal"/feature... allows us to dive as deeply into the engine as we choose... but... hmm.

When someone experienced with Bullet or Ammo... views our Ammo plugin for the first time... they might say... "Oh wow, this is Ammo LITE.  It looks like they have a stripped-down plugin, and are not honoring the new powers of Ammo."  The user got this first-impression attitude, simply because we tried to mirror the API's from older, established plugins.

For example, let's say the new Ammo plugin... has no soft-body calls/tools.  That's likely how it is right now.  Let's say ammo plugin developers NEVER add any softbody tools, and ONLY allow softbodies via nativeParams and nativeCalls options.  What if? 

Now... the Ammo plugin CAN mirror the Oimo and Cannon plugins... tightly/accurately.  The Ammo plugin devvers have FAR less work to do, and everyone who uses the Ammo plugin... understands that we MUST crawl beneath the floor of the plugin... to exploit Ammo's full power and newest features.  In other words, the plugin doesn't hand-hold the user AT ALL, as far as the new Ammo features/power.  It is understood... that the Ammo plugin is basics ONLY.  To get-to the "big beef", programmers MUST talk directly to Ammo native level.

I think tDev says to himself..  "How in the heck can I honor ALL the possible configs/options of the new Ammo features?".  And then, he asks "How can I do some basic syntax and type-checking to help the programmer use this command?".  Likely, it gets a bit overwhelming.  Instead... maybe... anything beyond basic physics... ya GOTTA go native.  Thoughts, anyone?

tDev.... IF you were to honor/cover all the "power" of the Ammo engine... wrap ALL its tools in your tool... the plugin would be what?  About 3 times the size of the Cannon and Oimo plugins?  Maybe more?  And in 2020, the new WAMMO engine arrives.  :)  Oh no!

I dunno my point, as usual.  Maybe, there is a "point of diminishing returns".  At some point... maybe we do less in the plugins... keep those basic, always.  Then... maybe write our own tutorials about "How To Talk Native" to ANY of our physics engines.  THEN... perhaps... hire some SERIOUS physics expert... to write those docs... even in sloppy form.

Cannon is the only one of our big 3 engines... that has a published API docs, right?  But it's a JsDoc-generated thing, so it doesn't teach.  For any engine, if we seek to teach how to talk-native to it, we also need to describe the way the engine does what it does.  What are 'lc'?  What are 'r3c'?  What are solvers, islands, broadphase, narrowphase, etc.  What's the rules for allowSleep?

Guess-timate of the tutorial length for teaching how each physics engine works, and teaching how to make native calls to it:   8 miles:)  *sigh*  (2 million LBS of text + 300 gfx/diagrams)

Ammo could go obsolete in 2 years... especially if "physics engine in hardware" becomes available to us, here in JS land.  Is WASM an indicator that we are reaching with all our might... for more physics speed?  What happens if some idiot invents a physics sub-processor for $12... that plugs-into a USB 3 port, and suddenly makes JS physics... quadruple in speed and with no need for software physics engine?  What if?  TrevorDev would start crying and have a nervous breakdown.

Be careful, tDev.  In my opinion, don't break your brain trying to honor all the newest, coolest Ammo stuff... in the new plugin.  Just point the advanced-features idiots to the nativeParameters portal, then go get a meal and some sleep, eh?  The plugin already looks pretty damned nice... thx for your work!  Don't kill yourself on/over that thing.  It's called "Ammo" for a reason, ya know?  :D

Share this post

Link to post
Share on other sites

Yep, that'll work.

Note:  I made a mistake in an earlier post.  belongsTo and collidesWith are IMPOSTOR parameters/settings, not for joints.

My point with these discussions COULD be:   How is it determined... WHICH settings get a plugin wrapper-method, and which don't?

For example, friction was a parameter chosen to be one of the allowed constructor parameters... for Oimo (and Cannon).  There are late-call functions such as setFriction and getFriction, and friction is a member of impostor._options

Why didn't Oimo's collidesWith and belongsTo... get included in those?  What made them somehow lesser, and thus determined/relegated to be native-set ONLY?

You see, there is a pattern emerging.  SOME things are honored by the plugin, and SOME things are blown-off, and native-set only.  The more "features" that get blown-off and relegated to be native-set only... the smaller the plugin.... and the less that can go wrong/be bugged... with it.  Plugins start to get LESS "effective", and Tools.AmmoNativeCommandHelper becomes MORE "effective".  Maybe.

What is a plugin?  Is it already a AmmoNativeCommandHelper?  Maybe.  But users might want to "see" the native command that is being issued, and our plugin methods are not coded to do such things.  They just issue the native commands, behind the scenes, for the user.  No teaching of native commands.  Can't see the native commands that are getting issued/sent.  I think only setNativeParam() and makeNativeCall() allow the user to see the native text... because the user/programmer needs to type it into the parentheses. 

Really, does a plugin NEED anything MORE THAN setNativeParam() and makeNativeCall()?  IF we had ONE plugin that had only those two calls, BJS gets to wash its hands of ever-evolving physics engines, and instead... delegatesd the physics engine learning... to programmer/user.  Just one plugin... does it all... because it is a very thin layer.  Just thoughts.  Back on-track...

How do plugin authors determine WHAT gets handled by native, and what gets plugin support/wrapping?  Is that done via "educated guess" of usefulness?

Sorry if I'm off topic.  I'm sort-of talking about plugin dev, and not about John's Ammo demo.  *shrug*  But hey, I gotta follow my curiosity.  It helps me learn things.  :)  Sorry if it seems that I have a "pushy" mannerism/personality.  Not my intent.

In my now-predominently-broken physics LEG-WORK demo... you can see me actually add collidesWith and belongsTo into the Oimo IMPOSTOR (lines 125/126)... and into the PLUGIN (lines 984-996).

What was so difficult about allowing those... from the start? 

I bet I know.  If CannonJS doesn't use/understand belongsTo and collidesWIth, then the adjusted-for-Oimo BJS PhysicsImpostor base class... can't be used by Cannon.  BJS PhysicsImpostor class becomes non-universal.  We'd need to separate... OimoPhysicsImpostor class, and CannonPhysicsImpostor class.  And now, we might need AmmoPhysicsImpostor class.  I dunno.  I'm just trying to find a policy... for what/how-much to dumb-down things... in order to make them re-usable/universal.

The BJS physicsImpostor was dumbed-down so it could handle both Cannon and Oimo (and thus lost its collidesWIth and belongsTo).  The BJS physicEngine class might also be dumbed-down to make it universal for both Oimo and Cannon.  Will we need a BJS AmmoPhysicsEngine, now?  Or are the plugin programmers trying to bang Ammo with a hammer until it "fits" our current BJS PhysicsEngine class?

Should our PhysicsEngine class... have a native-setting portal as well, so we can get max power/features from Ammo?  Our physicsEngine class is currently coded for Oimo and Cannon.  Because of this wobbly mess, super-thin plugins start to make sense, with almost everything done via native.  And it is/could-be the user's responsibility for learning how to talk native to whatever engine they are using, and not BJS's duty to wrap some of the functionality of each particular engine.

It's just a theory.  A FULL POWER Ammo plugin... could take a year to code.  Maybe two.  This is because we MIGHT need a "proprietary" (special) BJS PhysicsImpostor and PhysicsEngine class... to accomplish that "full power".  At what point... do we stop hand-holding the physics users with fat full-power plugins, and instead.... teach users how to talk native to all of our engines?  (and then de-power the plugins)  Will this alleviate the need for more BJS physics experts?

Maybe I should stop thinking so much, eh?  But I actually ran-into the situation... needing belongsTo and collidesWith in my project.  I could have used them via talking native.  But instead, I decided to modify the BJS plugin and impostor classes.  I have actually SEEN the impact of two important Oimo properties... ignored by the plugin and relegated to native-use only.

Now others have seen it, too.  Thoughts?

Share this post

Link to post
Share on other sites

I recently ported the physics engine of an "old-ish" BabylonJS project of mine from CannonJS to AmmoJS. I did this as CannonJS is no longer maintained, has buggy convex collisions and a limited concave implementation. AmmoJS can be compiled to WASM as well, which is no doubt the way things are moving when it comes to physics. Chrome even just started their trial for WASM threads. I'm using a worker, though, as my game requires every bit of juice it can possibly get. I won't have time to help with the plugin, and you know.... What is TypeScript? :P .. But I really think AmmoJS should be included as a plugin, as well as the playground, as it is a beast. Just make sure to re-use quaternions, vectors, transforms etc. as AmmoJS otherwise leaks and builds up memory pretty fast. I think a proper implementation will be far superior to what BabylonJS  already supports.

Share this post

Link to post
Share on other sites

Hey guys, what’s the main difference between a heightmap collision type vs just a mesh collision type... if you make a terrain for example by creating a mesh from a heightmap image, it’s a mesh then... so why wouldn’t you use a mesh collider... just would like to clear on what exactly the heightmap collision type gives you and the best case to use it

Share this post

Link to post
Share on other sites

Heightfields are generally more performant, but lacks features that concave shapes have.

If you are creating a giant island-map, you'll want the extra performance of the heightfield, if all of the map is to be used for collision detection and dynamics.

If you, however, want to create a racing track, a heightfield could result in A LOT of unused geometry in your physics shape. In this case a concave shape would be more performant, and allow for such features as holes in the ground, which heightfields do not. Generally, if you want dynamic concave shapes, you are way better off converting to/generating a compound body of convex shapes.

It all really depends on your project, and there's no reason not to use both heightfield, concave, convex and primitive shapes all at once. You'll squeeze out some extra performance if you groups all static shape types together as well, making big compound bodies out of all static concave shapes, making compound bodies out of all static convex shapes, etc, etc. <- Same thing with CannonJS.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.