I have an interaction where a user can grab and drag around a physics object and noticed, when upgrading to v6 and havok physics, the way things moves feels very unnatural. I broke everything down to a simple playground to be able to compare it with cannon physics. The playground creates a box and a small sphere connected with a ball and socket constraint. The sphere moves around with the horizontal mouse position. There are no differences except the necessary adjustments for the different engines of course:
Screencast Cannon:
Playground:
https://playground.babylonjs.com/#46UCV9#2
Screencast Havok:
- Box is flapping weirdly
- Sometimes the box is leading the way in the direction of movement, which should be the other way around, doing some kind of spiraling motion
I refuse to believe that a AAA physics engine is supposed to behave like this. The movements feels very weird and not natural, I can’t really put my finger on it though. I tried a lot of things like damping, different motion types, etc but it basically changed nothing. So either I’m doing something wrong, the plugin does something wrong or the physics engine of the planet ist broken and I’m used to wrong behaviour
Any help appreciated
Have you checked Earth’s patch notes to see if they haven’t updated the engine? (1) Earth Updates (@Earth_Updates) / Twitter
Jokes asides, I did some changes in the Havok PG and I think it’s behaving more as expected? Mainly in addConstraint, instead of calling the function on the box, I called on the sphere, so the sphere is the parent body of the constraint. And since the sphere is being moved constantly by us, I’m using disablePreStep
false and just setting the sphere mesh position directly: Physics Drag Havok | Babylon.js Playground (babylonjs.com). I don’t think the latter makes any difference through, just the former.
1 Like
@carolhmj Thanks for your input, yes switching the order of how the constraints are attached is actually something I have tried aswell. But honestly, while it’s a bit different it still does not feel right somehow. I managed to move 3x to the left and right without the box actually switching directions Still feels really weird somehow …
I had the suspicion that little jumps in the mouse movements could be an issue and I tried to mitigate this by lerping the position, but basically same result: https://playground.babylonjs.com/#P5XN43#9
I managed to create the same example with the rapier physics engine:
Playground:
https://playground.babylonjs.com/#9AHKZZ#4
For me this feels a lot more natural and how I’d expect a real world object to behave.
@carolhmj Do you agree on this one?
The rapier example is a good one to compare with, thanks for it! I tried swapping the constraint type to 6DOF which allows you to set axis friction, I think it looks a tad better but not quite there yet: Physics Drag Havok | Babylon.js Playground (babylonjs.com)
I’ll ask the Havok guys to see what else we can do, thanks a lot for trying the engine out as it’s valuable information for us! I’ll keep you posted when I have an answer.
Thank‘s for your support @carolhmj I‘m curious if anything comes around.
I‘ll check your example when I‘m back on a computer
SO not Havok but when doing stuff like this with Box2D. I didn’t use a 1-1 anchor/joint with the mouse because things would act how your showing in Havok (Weirdflipping around) .
My solution was I made two joints, one on the Target, one that follows the mouse and connect them with a stiff elastic joint.Thats made things act more naturally (kinda how the Cannon Physics looks, where the Target is dragged behind the mouse.
I think Havok is having trouble taking the Digital Input of mouse movement and translating that, it should be softened with a physics middleman like a spring/elastic joint IMO.
@jamessimo Thanks for your input! Yes I had similar thoughts and tried to do something similar by lerping the mouse position to the joint position: Havok physics behaves unnatural when moving a box with a constraint - #4 by thomasaull
Although not exactely the same but the effect should be similar? Also rapier seems to be find with the 1:1 mapping :-/
I wouldn’t use the Lerp but instead use a spring/elastic joint and let that do the lerping for you. I may try to mimick it later if I get time at my pc.
Not sure if it’ll make a difference, since the lerp already acts like a spring with a lot of damping applied. But I’ll be happy to have been wrong
I’d say even without the axis friction the 6DOF constraint is a lot better. Looking at the implementation of the Ball and socket joint (Babylon.js/havokPlugin.ts at master · BabylonJS/Babylon.js · GitHub) maybe using constraints on each axis instead of a single distance constraint (effectively the same thing?) makes the engine behaves so weirdly…?
Ok, talked with the Havok people!
They pointed that Rapier doesn’t seem to be conserving any momentum (which is not physically correct), because on this example that moves only once, the rapier box stays stuck in midair: Babylon.js Playground (babylonjs.com)
While the Havok version keeps momentum: Physics Drag Havok | Babylon.js Playground (babylonjs.com)
But regardless, they showed me a way to make it behave more like Rapier, increasing the linear damping and gravity factor of the body: Physics Drag Havok | Babylon.js Playground (babylonjs.com). It’s also not updating the sphere position directly, it’s using the sphere as an animated body and updating the velocity instead of the position.
5 Likes
@carolhmj Wow thank you so much, this is a lot of valuable information right there!
Yes, when looking at the rapier example again in fact the built-up momentum in fact is missing. Not sure if this is a problem on the engine itself or in my specific example with the constraints (actually there is a big red warning for setting the position directly in the rapier docs: Rigid-bodies | Rapier)
Updating the position by setting the velocity also seems a key point for behaving naturally.
Thanks again, this is really helpful
1 Like
@carolhmj should this figure in the doc somehow ?
Good point Seb! We should also add setGravityFactor
as a method on the body itself to not need to call the plugin directly.
1 Like