How can I limit a HingeJoint with ammoJS plugin

Hi there,

I felt in love with BabylonJS right away but it gives me (total newbie) a hard time with ammoJSPlugin and joints :wink: I’m using the AmmoJSPlugin and I want to create a car. The rear axis was no problem: HingeJoint to the car body and accelerate with .setMotor(…). But I can’t figure out how to build the front axis with steering. Maybe someone could give me some clues to do so?

In front I have a wheel connected to a suspension (HingeJoint), so the wheels can be accelerated as well with .setMotor(…). For steering I added a HingeJoint from the suspension to the car body, which also works fine, but …

(1) I can’t figure out how to lock the left and the right suspension together (technically the two steer independently from each other). How can this be locked?

(2) When the wheels steer to one side, they will sooner or later touch the cars body. How can I limit the max steering angle? Somewhere I saw that the OimoJSPlugin you can use native params for this, but I cannot use Oimo because it has no MeshImpostor (:persevere:).

There are so little examples for this, so thanks a lot to all who can lead me to the right direction with this!

Hi G! Welcome to the forum. Let’s ping @Cedric , as he is darned good at physics engines.

One way that might work… is to “watch” wheel.rotationQuaternion (or possibly wheel.rotationQuaternion.toEulerAngles().y). As you steer the wheels, wheel.rotationQuaternion should be changing, and you may be able to do some IF/THEN testing there.

For example, if (wheel.rotationQuaternion.toEulerAngles().y < something) {allow further steering) else { don’t }.

You may also be able to “sync” the steer-amount of the two wheels… with this same method. Every time the steer-amount changes on wheel1, wheel2.rotationQuaternion = new BABYLON.Quaternion( wheel2.rotationQuaternion.x, wheel1.rotationQuaternion.y, wheel2.rotationQuaternion.z, wheel2.rotationQuaternion.w); (Notice that I made a new wheel2.rotationQuaternion, exactly the same as its PREVIOUS one, except I used a .Y value copied from wheel1.rotationQuaternion.y.)

I replaced old one with new one… because… Quaternions really don’t like to be “edited”. It’s best to replace them with a new one. Quats DO like being added, subtracted, multipled, divided, and scaled, though (mostly by/with/from/to OTHER quats).

We/you MIGHT need to do a “forceUpdate()?” on wheel2.physicsImpostor.physicsBody.quaternion… after we change wheel2.rotationQuaternion… so that the physicsBODY.quaternion (a AmmoJS native object) exactly matches the newly-installed wheel2.rotationQuaternion.

I’m not real familiar with the (multiple) ways to re-sync a mesh.physicsImpostor.physicsBody.quaternion… with a fresh mesh.rotationQuaternion… but essentially, the forceUpdate() is a removal of the old impostor, and replacing it.

We COULD have used wheel1.rotationQuaternion.copy() or .clone() or similar…(for installing on wheel2.rotationQuaternion) but… that could affect the wheel’s x-rotation, too. (“Goodyear” lettering on tires might be printed on the TOP of wheel1 but on the bottom of wheel2 - caused by differing tire spins - possibly after leaving a jumping ramp.) Maybe nobody will notice tiny details like that, though.

Anyway, SOME values on steerwheel1.rotationQuaternion and steerwheel2.rotationQuaternion SHOULD be changing as you steer the wheels. You might be able to use those values as both a steering limit, and a turn-amount sync method.

Also, keep in mind that distance joints and lock joints… are invisible, so a lockJoint “rod” might be able to be connected between “nose” of wheel1 and “nose” of wheel2. (nose == leading edge). Lock joints have no mainAxis and connectedAxis, as far as I know… but they DO have mainPivot and connectedPivot… and in this case… you will want them to be very accurate. It should be simple, though. Set mainPivot 0, 0, 3 and connectedPivot 0,0,3 also. That means… 3 units forward of mesh origin (center of mesh) on BOTH connected shapes. Essentailly you made a steering arm… connecting the two wheels.

BUT… I am worried about this idea. This connecting rod MIGHT spin-around X… as the wheels “roll”. Depending upon where the user stops the car, the rod that was once 3 units “forward” +z of wheel hubs… might be 3 units above or below hubs . If you were to turn steering wheel when connecting rod was above or below hubs… wheel2 will not steer same as wheel1. (connecting rod failed because rod connect pivot-points… rotated (rolled) around x… when wheels/tires rotated around x)

Hard to describe.

Anyway, watch your wheel.rotationQuaternion, and even watch wheel.physicsImpostor.physicsBody.quaternion (puke them to console as you steer one wheel)… see what the values are doing… and start playing with those). Oh, by the way, Quaternion values sort of suck… but heavy medication and deep meditation… can help. :smiley:

Stay tuned for other ideas, and please report test results… to help teach others. Thanks!

Hi @ggschelling

  1. You don’t have to lock left and right. If you apply the same motor/forces to both, you’ll get the same result on both.

  2. Bodies connected by joints have their collision disabled (I say that from memory).

Here is a little example showing hinge joint that may help you : https://playground.babylonjs.com/#TYD4D6#3

It’s using CannonJS but I think you can adapt it to Ammo without toomuch trouble. Hardest part is to properly set the joint axis.