(Originally posted on Mastodon)

To make wheels “roll”, I actually want to use fixed wheels with anisotropic friction.

The idea is that having a cylinder rotate at high speed is usually a bad thing for the stability of a physics engine. Instead, the cylinder would be fixed, slide easily forward, but have a lot of lateral friction. With an effect to make the wheel appear to rotate visually it’s completely convincing for players, even though it’s physically closer to skiing than rolling.

This is what I did in the first prototype of the game (which used Unreal Engine and PhysX as physics engine, but I have now switched to Godot)

A video presenting various scenes in a work-in-progress game. It takes place in a green landscape near a river, under a blue sky, in first-person view. First the player designs a vehicle by placing wheels and a seat on a frame. Then the vehicle is spawned in the world and the player can drive it. After that the player cuts down a tree and removes branches and shapes the trunk into a square wood piece. Then we see the player constructing a big building forming a bridge over a river, and the vehicle can also cross the bridge. And finally the player adds a water wheel under the bridge, and places rods to link it to a big circular saw, that is then used to cut down the wood piece into planks.

I shortly hoped that Jolt (the physics engine used by Godot) would already implement anisotropic friction. But nope, I’ll have to implement that again, like I did for PhysX.

The difficulty is not to make something that works approximately, but something that works exactly enough that for example a vehicle parked perpendicular to the slope direction will stop moving completely and won’t either slide slowly downwards, or, worse, slide upwards or vibrate.

Here is another video showing the old prototype. The physics wheel slides, it does not rotate. But the mesh used for rendering does rotate (according to the movement speed). And as is visible at the beginning, the vehicle can remain stable if perpendicular to the slope.

Now I basically need to reproduce this in Godot.

A video in first person view where we see the player create a vehicle, then get on the driving seat, and drive around on grassy hills. The player also collides with trees, which make them fall down, which also break the branches.

This anisotropic friction thing proved an interesting challenge.

The old implementation I made relied on PhysX providing the normal force applied to each contact point, which I need to compute friction. The more you press objects one against the other, the more friction forces prevent them to slide relatively to the other.

Sadly, #Jolt does not provide this information 😬

My remaining options were:

  • see if I could do something with the VehicleConstraint of Jolt
  • try to implement proper anisotropic friction (according to the documentation, the Contact constraints are “considered an internal class” so I’d have to modify Jolt)
  • use a different physics engine
  • try to use a cylinder collider with a hinge joint to make a wheel that actually rolls and see if that’s stable or not

The cleanest way seemed to implement proper anisotropic friction in Jolt. So it’s what I did ☺️ The result seems smooth and stable so hopefully I’ve not messed anything.

Here is a test showing a square metal tube, modified to make it extra slippery, but in only one direction.

First person view video where a small metal part is on the ground, and the player walks on it to push it. The metal part slides very easily in the direction of its length, but has otherwise normal friction laterally, like a ski on snow.

Here are the code changes if anyone is interested (most interesting part is in ContactConstraintManager)

And here is the result after configuring anisotropic friction on the wheels. It works! Still have to make them visually rotate to complete the system.

First person view video where the base of a four-wheeled vehicle is pushed by the player and slides down a slope. The trajectory seems correct for wheels that would force the vehicle to go forward, excepted in this video the wheels are not turning.