Physics air walking

Hola Amigos!

I think I need a quick sanity check, I’m getting havok’ed atm.

Coming from Ammo WASM, V1 Physics API, heading to Havok & V2 API.

Its taken me a day to work this out, but back in old v1 ammo, I could just move the x & y of an imposter and things were generally good, you’d get strong collisions and feel like you hit a wall.

In V2 land, it feels like everything is jelly and imposters were using impulses, super easy to clip through things etc, I solved this one with physics sub steps but I don’t think it’s the problem here

I looked through a couple of demos, and I found this:

Which is super useful, so I got the whole moving the imposter with setLinearVelocity thing, but, as I already have this open:

And did a dirty setMassProperties to stop the avatar falling over, but now the avatar also air walks better than jordan like in the demo playground. I think a PG with physics plus player movement would be mighty helpful for n00bs like me. Obviously the old way was to use setAngularFactor on the imposter but we seem to have lost that method now.

            inertia: new Vector3(0, 0, 0)

Hello @potato_noob

Part of that movement code is mine, I shared it from some tests I’m doing with HAVOK.
I just saw that using the movement with LinearVelocity is indeed always moving the character, so two viable options occur to me:

  • Detect with an observable when the character is “onGround” and when it is not.
  • Apply some method of physics so that it overrides the Y axis in the LinearVelocity movement

I’m going to take a look

You are the man @DRLeria I feel like something we’re missing in the Babylon docs beyond the raw technical examples are a couple of practical examples like player movement.

I’ll admit I went back and tried applyForce this afternoon, but looking back at v1 I think the linear velocity is the right choice.

Thank you again for the playground example, it was really helpful.

1 Like

That’s a good point! We focused on “simpler” examples to test/demonstrate the Havok features, but more complete examples are always welcome on the docs :smiley:

1 Like

Maybe another option would be to use collisions to detect when the character is “onGround”

const observable = dummyAggregate.body.getCollisionObservable();
const observer = observable.add((collisionEvent) => {
     // Collision Detection
     if ("ground"))
         onFloor = true;

Another option that I used a while ago in a project is using “intersects”.
Simply creating a Box type object attached to the bottom character, when that cube detects the ground, ramp… set onGround = true;
Otherwise the character would be in the air and we deactivate the keyboard function that LinearVelocity sends

Although now I’m a bit more concerned about HAVOK’s compatibility with older Apple devices, on some models with iOS version lower than 16 it doesn’t work and gives a WebAssembly error.

In my case it would make it impossible for me to work on projects with HAVOK until I find a possible solution, I have no doubt that they will find it. :pray: :pray: :pray:

I mentioned this the other day trying to figure out a WASM memory out of bounds issue, I’m IOS 16.1.1 and also can’t load havok PGs.

@carolhmj once I have the basics down for movement, I’ll add an example of player movement to the docs, I think a sort of “notes from fellow traveler” might be good, because essentially we all have to learn this and we probably all have our little tricks.

I know I’ve got a bunch of gotchas from v1 like parenting and imposters, it wasn’t clear if that still applied or the aggregate did some magic.


Testing with IntersectsMesh
If it seems absurd but it works, it is not absurd :rofl:

Plot twist, I’m on iPhone so it won’t load haha, I’ll head to the desktop after I finish this episode of caprica. I don’t know how I feel about intersection testing, ammo on v1 never needed that for gravity to do it’s thing.

1 Like

Caprica. Very trendy AI. I have not seen it, to the list :grin:
Using intersects I don’t think it’s the most viable option, I’m going to review the documentation well

Usually you would simply cast a ray down from your physics body to determine ground contact.
Another way is to use observers, or otherwise get the collision contacts between your player and static and kinematic bodies. Check all contact normals, and if you find one pointing up, you know you are in grounded. You can use the dot product between your world up axis and the normal if you want broader angles

My own rigidbody controller uses forces though, so I don’t have to artificially add gravity. I still need to know whether or not the character is grounded, otherwise you’ll be able to jump mid-air


Totally agree.
We are going a bit crazy, the best option would be using Raycast or observers

@DRLeria I tried it, falling was glorious! but the thing I thought would happen, happened, turn around on the stairs and run down and you get the struggle to figure out if you’re falling or walking down stairs, ammo v1 did this super well.

As I said, we are playing a little crazy.

To design a good character controller we have to be more meticulous and first of all think about the different States that we’re going to use (idle, walk, run, jump, fall…)
Taking these states, the logical operation as @Raggar said, would be to define the physics of the player using Raycast or obervers, also considering the normals of the surfaces so that it acts accordingly…

Initially it was an exercise to study HAVOK a little more, if we continue like this we end up with a Tomb Raider :joy::joy::joy:

Honestly I appreicate the discourse, maybe you can explain something to me, When I was using ammo, I kind of took it for granted that gravity would always be enacting on imposters, so even if you apply a force, after that force, the engine would still apply gravity and any downward velocity accurued.

With the playground demo, it feels like the gravity calculations don’t get applied if we’re setting linear velocity, which makes me thing there might be another way to do this. We’re beating gravity at the moment haha

When you set the linear velocity, you can just make sure, that the Y-component is that of the body’s current velocity. That way, you won’t lose the effects of other forces like gravity and jumping.
Using forces and impulses would still be better, though. What happens if a force pushes you away? Like an explosion or something. As soon as you push forwards or backwards, you’ll stop right away. Fixing this while still setting velocities is a mess

1 Like

Ah, that makes more sense @Raggar I’ll give it a go on that playground and report back here.

1 Like

More testing…

As @Raggar commented, with physics it’s more precise and we don’t complicate the situation by fixing what already works.

This code was based on a previous exercise just for testing HAVOK Physics:
And it is true that in this specific case it works great since the movement is carried out only in the X-Z axes

Now my question would be, how can we limit the speed of impulse or force? mainly to prevent it from continuing to increase indefinitely or to make the acceleration faster and maintain continuous motion.

Mutually I’ve been messing around with this a bit more this evening, I wish we could just grab the linearVelocity inplace but meh, so if we grab the current LV using this: getLinearVelocityToRef, calculate our new velocity the way we’re doing in the playground, but then grab the y component of the existing velocity, then gravity is working totaly fine, so setLinearVelocity is obviously totally wiping out existing velocity.

TLDR; exactly as @Raggar said!

One more test…

In this case, considering that the linearVelocity is a Vector3, we can simply add the Y axis that exerts the force of gravity, let’s say “simulated”

I understand that it is not the finest method, but I particularly like the movement of the character using linearVelocity and now it seems to work better

We are still having fun :smile:

1 Like