PhysicsJoint: translation/rotation limits not only for DistanceJoint, but also for other joints like HingeJoint, SliderJoint, PrismaticJoint...?

Hello there,

I’m experimenting with the PhyicsEngine PhysicsJoints (Use Joints - Babylon.js Documentation) and motorized joints as well.
For example when building a crane or vehicle that is constructed of several PhysicsJoints and some motors to operate them.
I’m looking for ways to limit the joint’s translation/rotation further on a joint.

For example, the DistanceJoint has a minDistance & maxDistance option.
Very nice to use to simulate a weight on a hanging rope.

In some of the GitHub code for the different PhysicsEngines (Cannon.js, Oimo.js, Ammo.js…) I see some code that also limits translation/rotation on joints for other types than the DistanceJoint.

How can one set from Babylon.js PhysicsJoint code an optional limit on these other joints as well?

Some examples of what to do:

  • HingeJoint: constraint the rotational angle (min/max)
  • SliderJoint: constraint the axis (set min/max position on the axis the connected body must be kept between) and/or constraint the rotation angle (min/max)
  • PrismaticJoint: constraint the axis (set min/max position on the axis the connected body must be kept between)
  • etc.

Hope to hear your ideas.

Q

Hi QH! Um… I know of one working demo… for Oimo. https://www.babylonjs-playground.com/#8PQK71#11 Use clicks and shifted-clicks to see these hinge joint min/max settings.

OimoPlugin/Joints have a setMotor(speed, maxForce) on the “limitMotors”… but we have done some struggling with maxForce, recently. It’s not working correctly, AFAIK.

MaxForce is the point where the motor slips… and can actually back-turn if too much counter-mass/counter-force is added to the motor’s torque equation (perfect for cranes). But… if maxForce is “acting-up”… it might be best to avoid Oimo motors/joints. (Joints are often called ‘constraints’, so don’t accidentally mistake the term ‘constraint’… for a joint-motor upper/lower limit.)

According to AmmoPlugin… AmmoJSPlugin - Babylon.js Documentation… AmmoPlugin also has a setMotor. It also has a setLimit: AmmoJSPlugin - Babylon.js Documentation. I have not tested either… but maybe others have.

Just for fun, let’s try an Ammo joint setLimit (via lines 31 and 72):
https://www.babylonjs-playground.com/#8PQK71#12

Console reports: setLimit is not currently supported by the Ammo physics plugin. Darn.

Ok, perhaps we need native calls… setAngularUpperLimit and setAngularLowerLimit… not sure how to “install” those. Web search for Bullet setAngularUpperLimit returns pretty good results.

@JohnK , @trevordev , and @MackeyK24 have all done recent AmmoJS work, so I’ll ping those guys. JohnK might actually be writing docs about AmmoJS joints at this time, so he could be on the bleeding edge of all this good stuff. Trevor might have an Ammo joint-testing playground, as he wrote the code for the AmmoJS plugin. Stay tuned.

PS: Here is JohnK’s AmmoJS motor/hinge demo… https://www.babylonjs-playground.com/#5W5B6W#61 It has a swell setMotor running at line 110, but lines 101/102 likely do nothing. Still, it might be a good playground to test some native setAngular calls. Change line 110 to joint1.setMotor(3, 1); and you can see the limited-slip of the 2nd param (maxForce) in action and behaving correctly.

Thanks for your ideas @Wingnut and the shared demos/links!

The differences between the 3 PhysicsEngines make it a challenge to find a ‘generic’ standard for setting angular and translation limits. One engine supports more settings than the other and there is also the difference between the bodies that can be used.

I’ve been working with the CannonJS mostly (because of the HeightMap impostor support and because it is the default of BabylonJS).

For OimoJS, I see in de GitHub project code that the min and max parameters in the nativeParams are consumed by most types of joints:

nativeParams: { min: -45, max: 45 } //min and max are in degrees

That is also the setting of the first playground demo you talk about:

https://www.babylonjs-playground.com/#8PQK71#11

So I’ll start experimenting with these two values first.

In my GeekTrains game, the level ‘Oval Double Side #1’ contains most of the cranes structures currently available. They are quite static at the moment (unless connected to a player with a keyboard/gamepad), but as my understanding of the joints and motors increases, I’ll be able to make them automatically operate and pick up / load goods on and off train wagons… (= computer AI controlling the motors)

Q

1 Like

Exactly! Well said. Historically, using my bad memory and low knowledge… it all started with Oimo… and Temechon and DeltaKowboy… wrote the first basic plugin. It was a year-long party… because it was big big big. Basic “physics engine API” was established.

Then… perhaps Oimo got another version, and Raanan (and possibly others)… did an Oimo re-factor… added more power… but still tried to mirror the “PE-API” (physics engine API).

Then Cannon came along, and I think some “maintain the pe-api scrambling” had to happen… because there were differences between Oimo and Cannon.

Energy physics engine plugin happened about this time… in history. Many yawned over it, because most of us hadn’t even learned to drive Oimo yet… no time to learn more… barely/no time to write advanced-feature docs.

Now… Ammo… which has much more power… but… in order to fully exercise that power… I think we might need a NEW BJS PhysicsEngine, PhysicsImpostor, PhysicsJoint, etc… things that require LEAVING BEHIND the legacy pe-api. I believe that the current AmmoJsPlugin is still an attempt to mirror the legacy plugin API… and understandably, it can only meet “most” of the criteria to “fit” that.

Writing a new AmmoJsPlugin “system”, which fully exposes all the newest powers of AmmoJS… is quite a task, I imagine. It will need to evolve and have multiple smart contributors… could be a 3-year project to fully flesh. And what IS “fully flesh”. We will ACTUALLY be establishing a “2nd gen” pe-api… upon which many future physics plugin api’s COULD be modeled after. It needs to be sweet, but in doing that… it might need to stay Ammo, even if other more-powerful physics engines come-along.

And of course… maintenance hell.

I once proposed DE-powering all the plugins… just providing a “get a ref to the physics world object” and not much more power. Then make people do native calls to the PE, whichever they were using. No/few helper funcs on the plugins, no BJS-wrapped impostor or joint classes… just make the user talk native from within their code. LOTS less maintenance for the BJS core physics team.

So, where does it go from here? Who knows? I think I have to heartily thank the devvers mentioned earlier… for their excellent work bringing AmmoJSPlugin to life… it’s real nice… including the docs. That is a lot of hard work, done well.

And… oh geez… we should ponder IF/NOT… physics engines will become part of next-gen computer hard/firm ware (PhysX?). Can JS even process the return-values from a hardware-speed physics engine… getting them to the scene impostors fast-enough to benefit from the added speeds?

In short… how much work, and how much features-exposing (such as making soft-bodies easy)… SHOULD be put-into things? If we “wrap” 75% of AmmoJS… so users never/rarely need to make any native calls, will people ever use 50% of that advanced feature exposure?

And maybe the BIGGEST question… Why am I still typing? :smiley:

Ya know… for GeekTrains… are you going to make the crane-loads “swing” on cables? If not… (straight cables only, yet still need to carefully align loads with flatbed railcars), then I would consider NOT using a physics engine, and faking it all. Perhaps make views from multiple cameras… pop-open… for crane operator, and then just make them cursor-key that puppy into place. Perhaps add a simple inertia system… so the load tends to over-shoot a bit when rotating… and then returns. All your loads could still have mass values… and they affect a few things in your fake-physics loading system.

I’m sure you’ve thought about this. And yes, I’m STILL typing. sigh. :slight_smile: Sorry if I’ve side-tracked [sic] the topic.

The docs are the full extension of my knowledge of physics engines. I was working on the edge of my abilities when I last edited them. Where I started to have difficulties such as applying two joints then I decided I had no more useful knowledge to impart. Sorry cannot be more helpful.

QH… one more idea. “stoppers”. By using stopper blocks (invisible physics-active parented boxes, perhaps)… you can create limits on rotating “arms”. When a hinge/slider/distance joint travels XX distance or angle… these invisible blocks collide, disallowing further motion.

Ammo setMotor works. Ammo setLimit doesn’t. So, possibly, with these invisible stopper-blocks… you could make your own limiters. You could even incorporate them into the game itself… allowing a “show crane stopper-blocks” and perhaps allow them to be drag-adjusted.

joint.getAngle() or .getDistance()… might still be a challenge… if you ever need those.

Anyway, I just wanted to remind you of another limiting method… via “compound” (parented or lockjoint-linked) mesh/impostors. I prefer a “tight” lockJoint (low-flex distance joint) to hook stopper-blocks to other impostors… but that is a bit of a pain. (setting many joint connected pivot points and axes)… and dragging a stopper is WAY more difficult (using joint-attached stopper-blocks).

But… lockJoints… work better than parenting, in my opinion. They have SOME flex… so when your crane arm hits a stopper-block… its an eased-stop. Not much eased, but SOME. The stopper block will move a tiny bit… when crane-arm hits it (it’s invisible, so user doesn’t care). It will probably give you some spingy-ness at stopper-block impact, too… making the crane arm wobble back and forth a bit, after impact. Realistic!

You can still calc a crane arm angle… from the crane arm mesh. But, asking the joint to REPORT it’s current position… might be rough (unless willing to native-dive). :slight_smile: Sorry, SO talkie I am.