Baffiling Event on an AmmoJS joint

Currently I am working on learning about physics engines, what they can do and the differences between the three plugins with the intention of writing what I discover in the documentation. Starting with the HingeJoint I made a PG to show how it works. Cannon and Oimo worked as expected but a strange phenomenon occurred with Ammo that I cannot see any explanation for.

I constructed a sphere and a box joined with a hinge that allows movement around the z axis, with the box positioned so that only an impulse in the x direction could rotate the box around the sphere. Just click the Apply Impulse button.

With Cannon and Oimo you can see that this works as expected https://www.babylonjs-playground.com/#F15U0G#2 just change which line 27 or 28 is commented.

With Ammo https://www.babylonjs-playground.com/#F15U0G#1 it does not always work, though weirdly sometimes if you hit RUN again (or again and again) it sometimes does work. Just as strangely if you remove the comment on line 50 and apply the same impulse directly it always rotates the box around the sphere and clicking the Apply Impulse button will apply an additional impulse.

NOTE It is worth pointing out that whilst the contact point for an impulse in Cannon and Oimo is given in world space the contact point for Ammo is in the local space of the mesh it is applied to.

Issue is the same across FF, Chrome and Edge browsers.

1 Like

Hi JK! Thx for the physics work… good luck on your learning.

Wingnut plays: pg #7

Line 55 … tried to do a setLinearVelocity instead of applyImpulse (when button pressed).

Same symptoms seen… as John describes.

Activating line 61… starts the box rotating at RUN time… a-ok. pg #6 hmm.

Same “pattern” is seen, using joint1.setMotor()… instead of impulse or linearVel. pg #9

Call these funcs from scene onReady observer… all works fine. Call them from the button press, and all 3 fail. Interesting.

Could it be a GUI issue? hmm.

Aside: I finally took a little “tour” of the Ammo plugin TS file. (I wish I had a raw JS version… to hijack-into our playgrounds, for testing fun). All in all, it’s friggin’ SWEET!!! REAL NICE “mirroring” of other/previous physics plugins. MUCH more mirrored than I EVER thought was Ammo-possible. Yay t-dev! (and yay helpers, if there were some)

[Wingnut offers John… a can of 3M Joint Lube… from a 24-pack case he bought for another project.]

Speaking-of baffling… a Hinge2Joint… is a hinge, with another hinge welded to one side of the first hinge (possibly rotated).

To get to the point, a hinge2joint has TWO motor-drive-able axes, I believe. Soooo… yeah. Possibly, our setMotor() isn’t ready for hinge2joints. (all plugins)

Hinge2joints are sort of “sketchy”, eh? TECHNICALLY, if you want a hinge2joint, you should use two hinge joints… with a tiny invisible micro-mesh between them.

Am I STILL talking? Geez! :slight_smile:

It is worth noting that on a non-hinged object an impulse works fine using a button https://www.babylonjs-playground.com/#YUNAST#7

There is a problem with setting friction to zero on imposter creation and I have raised this as an issue on BJS Github.

1 Like

Further strangeness.

Add this line scene.getPhysicsEngine().getPhysicsPlugin();
either in the function called when button is clicked https://www.babylonjs-playground.com/#F15U0G#10
or just after the physics engine is created https://www.babylonjs-playground.com/#F15U0G#11

Increases the frequency of the Apply Impulse button working.

for #10 and #11 it is likely to work on first loading and then not likely to work after a new RUN. However changing the camera angle before hitting RUN then increases the likelyhood of it working on the next RUN
:woozy_face::woozy_face::woozy_face::woozy_face:

1 Like

It’s a little hard for me to recreate. I’ve only seen the issue in maybe 2-3 out of 50 runs.

https://raw.githubusercontent.com/kripken/ammo.js/master/builds/ammo.js

BUT it is minified so very hard to do anything with.

In a local version I managed to add some console.logs onto this line

'I.prototype.applyImpulse=function(a,b){console.log(“in ammo”, a, b);var e=this.a;console.log(“a and”, a&&“object”===typeof a&&(a=a.a));a&&“object”===typeof a&&(a=a.a);b&&“object”===typeof b&&(b=b.a);console.log(“after ammo”, a, b, e);Oq(e,a,b)};

Two problems

  1. The console results are the same for a direct call to applyImpulse or one from hitting the button;
  2. A search for an ‘Oq’ function bring up just one but it has only two parameters.

Actually three problems - 3. I do not know what I am doing?

1 Like

Interesting - for me the ratio is the other way round, it appears 47-48 times out of 50 runs. More like your ratio when the line scene.getPhysicsEngine().getPhysicsPlugin(); is added. Thank you for having a go.

Thanks John, but I was talking about a raw JS version of the Ammo plugin, not the physics engine.

Ironically, I DID use an online JS-beautify… to make a “nice” version of AmmoJS, and pasted it into a playground. The playground editor got a tumor with line numbers over 90,000… etc. It was a ridiculous attempt… but, ridiculous is MY middle name. :slight_smile:

I usually get my raw code for hijacks… from https://raw.githubusercontent.com/BabylonJS/Babylon.js/master/dist/babylon.max.js … but… no AmmoJS plugin in there, as best I can tell.

In which case it is in https://raw.githubusercontent.com/BabylonJS/Babylon.js/master/dist/preview%20release/babylon.max.js from around line 100136

1 Like

Oh, in the PREVIEW version. Duh, Wingy. Thanks JK!

Here’s a recent-testing playground with the AmmoPlugin hijacked-in, if anyone needs one: link

1 Like

A solution but very hacky - add direct impulse with a smallish size (that does not overcome inertia) after joint construction.

impostor.applyImpulse(impulseDirection.scale(0.01), contactLocalRefPoint);

https://www.babylonjs-playground.com/#F15U0G#24

1 Like

Interesting find, JK. Same works for rot around x… https://www.babylonjs-playground.com/#F15U0G#28

To remind others: This PG HAD a problem… with the button. The impulse from the button… was working poorly/inconsistently… until he added his little rotational ‘nudge’ in line 52. After adding that, button works consistently.

This smells like an epsilon issue. Keep in mind (other readers)… that John does this micro-impulse “nudge”… LONG BEFORE the button press impulse. (line 52 of #24 PG)

Note: Epsilons are tiny values inserted into ANYTHING that could accidentally get a value of 0.0000000, and thus be subject-to a divide-by-zero error. (How’s that for an explanation from a noob, for noobs?) :slight_smile: An epsilon value is used at the ‘north pole’ of arcRotateCameras… to keep camera.beta from ever being perfectly 0.

With his “nudge”, John moves joint1 a TINY amount… away-from 0.000000 joint-angle. He moves the box… slightly away-from being perfectly atop the sphere.

Here’s another interesting thing. Change John’s nudge-line to…

box.physicsImpostor.applyImpulse(impulseDirection.scale(0.01).negate(), contactLocalRefPoint);

(negating the ‘nudge’ impulse direction… into being OPPOSITE of the button impulse direction).

The button still works consistently.

This might indicate that Ammo joints REFUSE to take an impulse on their attached shapes… if the joint has 0.00000000 rotation. :slight_smile: Interesting!

If someone knows how to manually set the angle of a joint (without impulsing an attached shape/impostor)… then maybe we would know more. hmm.

@Raggar’s AmmoCar MIGHT have enough “native” in it… to learn how to manually set joint angles.

PS: You can press the button MANY times. Notice how the button-impulse moves the box/joint in the opposite direction… after box crosses sphere equator? Fun! This could be changed… by adjusting the impulse direction… based-upon the current box.rotationQuaternion.

Adding @trevordev to the party

@trevordev has solved this in his work on the plugins