Wide ellipsoids and stairs

A mesh’s ellipsoid needs to be wide enough to contain the mesh, but a larger ellipsoid radius makes it hard to climb steps. This is compounded by slow movement speeds… So short, wide, slow meshes get stuck over ridiculously-low obstacles. What to do?

Some options:

  • smaller ellipsoid radius, but that causes meshes to get clipped by others
  • taller ellipsoids to maintain width/height ratio. Bad, but it can probably work in my case, as there are few overhead obstacles
  • faster movement speed, but we can’t have all characters move as fast as the player
  • lower gravity. That could work, if applied per-mesh, since most characters don’t jump off tall places, where the low gravity would look wrong.
  • lower steps, but they are already “reasonably low”. A 6" step shouldn’t be an issue for for a 6’ mesh.
  • slopes instead of steps. Looks wrong, especially for curbs. And it’s impractical to smooth out all ledges across the game maps.

cc @Cedric our physix expert

There is no fits-all solution.
You can mix collision with raycast and change gravity force depending on height…or stuck the character on the ground.
The engine provides a palette or tools. it’s something difficult to pick up the correct set to do the intended.
One solution I like and use a lot in my side project is to not rely on physics for character but on the navigation mesh instead. then, I stick the character position on the navmesh. so I can control where the character can go and nowhere else.

I’d like to bounce on that. I had the same idea, but then in the case of i.e. stairs (with a first person camera), how would you reduce the effect of ‘jumping’ from step to step. I was thinking of creating a smoother stairs navmesh (with kind of a slope between each step) or else, would you work this through the camera animation? Just wondering…

depending on your navmesh creation, a stepped stair can be simplified to a sloped plan

1 Like

Thanks, yes. I thought this could work and would be the easier. I’m gonna try this out.
Actually not really a simple sloped plan, more like a slightly waved slope plan to try keep with this some sort of feeling that you are taking steps (yet compensate with your view like you do in real). I will share the result no matter if its any good or not. We’ll see…

1 Like

can’t wait to see it :slight_smile:

1 Like

Neither can I :grin: :sweat_smile:
Will let you know :hourglass_flowing_sand:

1 Like

There is a whole bunch of parameters which one needs to consider.
Still I think that you need to mark you stairs meshes with some name or tag and apply needed changes to ellipsoid when it is going upstairs/downstairs.
In addition you may create a better collider so the movement would be realistic but smooth.

Interesting. So you would apply changes to the ellipsoid on a trigger area? + some other parameters if I understand correctly?

The best way is to create a model where all these things (like colliders, slopes, etc) would suit your intentions.
I mean, that with a good model you don’t need to do a lot of other things, like here - https://playground.babylonjs.com/#0VHCTL#32 (check stairs movement, it is quite realistic).

Also, as @Cedric mentioned, one may use sloped plane as stairs collider. This is what we do here - https://portal.metadojo.io/

The thing with stairs trigger is, for example, that one may use stairs animations there - Mixamo

2 Likes

The biggest factors in obstacle climbing seems to be speed and gravity: if I increase the speed, the meshes are able to climb curbs. But the reason you need speed, is to overcome gravity. So I’m trying to find a way to temporarily lower gravity with code - I don’t want to tag every step and ledge in the game maps by hand.

Smoothness is not really an issue, because the FollowCamera’s inertia smooths out bumps.

Just wanted to let you know that I have started doing my homework :grinning: and… as it turns out, the navmesh ‘waved’ shape seems to provide the most satisfactory result (in my opinion).

I’m currently setting-up a PG with some variants of mesh colliders to test. It’s almost done except I need to quickly create a GUI to give the ability to select from the variants of colliders, visualize them and tweek some parameters that (as @labris said) all have an influence. These parameters are speed, gravity and size of the elipsoid for the most basic. So I will add these in a simple interface. One thing I noticed in particular (and is actually quite logic when you think of how you climb stairs in real life) is ‘speed’. No matter the shape of the collider except if it is just a slope, when you increase speed you would also increase bumps, unless…

unless you make it so that when in ‘running’ mode your collider changes to account two steps instead of one… because, that’s just exactly how you would run up stairs, isn’t it? So, in this scenario, I made an instance of my ‘wave shaped’ collider and rescaled it. When running mode is active, this instanced mesh becomes the collider and when walking is active, the collider returns to the original.

Here’s a first taste of what’s coming.

Press kb ‘2’ to switch to the first person camera. Press ‘shift’ to toggle between walk and run.
Press ‘1’ for the arc rotate camera.

I also made it so that you can scale the stairs with colliders to make higher, smaller, thinner or wider steps. Of course, the size (height and depth) of the stair/steps also have a major influence.
The camera is set for an average size human eye height. I will also add a silhouette in the PG to better understand the scaling of these stairs.

Probably tomorrow I will add these last parts and the GUI with the parameters exposed above and next will also post elsewhere (because I don’t want to further ‘polute’ this topic that isn’t mine :wink:)
@alekop Sry about that and btw. how is it going on your side? Any progress?

2 Likes

It’s unable to load the .obj file.

Really? Can you give it another try? What browser is it? Could you kindly make a screenshot.
Nobody else reported this issue and I couldn’t reproduce and it’s supposed to load async with a promise.

I ended up doing a hack to lower gravity based on speed. Through experimentation I found a speed/gravity ratio that works well in almost all my scenarios.

// moveWithCollisions takes gravity into account, which causes slow or
// short-wide ellipsoids to be unable to climb even the smallest obstacles.
// So we scale gravity based on speed to compensate for that. This weird
// constant seems to work in most cases.
const GRAVITY = 9.81 / 60
const GRAVITY_SPEED_RATIO = GRAVITY / (6 / 60)

const gravity = Math.abs(velocity.z) * GRAVITY_SPEED_RATIO
const displacement = mesh.calcMovePOV(
    velocity.x,
    velocity.y - gravity,
    velocity.z)
mesh.moveWithCollisions(displacement)
1 Like

I noticed the earth gravity based on FPS such as explained in the doc seems incorrect. Even at 60 FPS when you set the earthGravity divided by 60, it doesn’t feel correct at all. At least, not without a physiX engine.

You’re right, dividing by 60 isn’t right. (My use case is going down hills/curbs/stairs, where it’s not very noticeable)
Dividing gravity by 20 seems more correct (https://playground.babylonjs.com/#KHJB32#1), but like you said, without a physics engine it’s never going to be exactly right.

1 Like