Colliders under physicsRoot

Hi,

I am new to babylonjs (and physics libraries in general).

I have made a demo to illustrate my problem https://playground.babylonjs.com/#1XWKCR#1

I am trying to model a square grid that behaves like there is space in the middle, as in, if an object happens to be in the middle of it, the grid should be hanging onto it.

Following the example here Babylon.js Playground, I have created 4 boxes, positioned 90deg to each other, added a PhysicsImpostor.BoxImpostor, and parented them under a physicsRoot with PhysicsImpostor.NoImpostor.

The grid behaves like there is only one collider, right in the center of the grid.

Can someone please explain what is going on there?

Thank you,

vinz

Invoking the almighty @Cedric

1 Like

Hi @vinz

This looks weird indeed! Let me try to find a fix.

Hi @Cedric, thank you for looking into it!

Not sure if this helps but If I enable physics helpers from the inspector this is what I see
image

The colliders for the grid are definitely not wrapping the meshes properly, while the colliders for the bars are tightly placed around the bars surface.
Are the physics helpers representative of the colliders volume or just an approximate visualisation not to be worried about?

Anyway, if I “unparent” the grid bits from the physicsRoot then the colliders look and behave as expected, yet of course independently from each other, which is not what I am after…

Scaling is used to determine the impostor size.
That’s fixed in this PG:
https://playground.babylonjs.com/#1XWKCR#2

But the physics still behaves weirdly.

1 Like

Hey @RaananW , IIRC you fixed an issue with compounds some time ago. Is it something that looked like this one?

Yep, seems very much related.

I fixed it for cannon.js - https://playground.babylonjs.com/#1XWKCR#4 seems to be working correctly. I haven’t looked into the ammo.js plugin…

1 Like

Awesome, thank you both!

https://playground.babylonjs.com/#1XWKCR#6 that looks pretty good :smiley:

@RaananW I believe your fix is related to this issue right? Physics compound body size calculation · Issue #7407 · BabylonJS/Babylon.js · GitHub

That would explain why I have been trying with no avail to replicate the online demo in local (where I have the babylonjs npm package, v 4.0.3). Now I have installed from github repo and I can replicate perfectly.

One question, would you happen to know which cannon.js is in the online editor? I have different behaviours if I use cannonjs from github or from preview.babylonjs. They both seem “correct”, yet they are different. Both scripts read version 6.0.2 which dates 5 years ago, so I really don’t get it…

Interesting. As far as I know, 0.6.2 is the last version, and we haven’t modified it. We are injecting a different worldStep function in the plugin, but that should happen to each version of cannon you are loading (and actually shouldnt affect the physics implementation that much.

with github you mean the cannonjs github?

I know, well weird.

These are my dependencies:

“babylonjs”: “github:BabylonJS/Babylon.js”,
“babylonjs-loaders”: “^4.0.3”,
“cannon”: “github:schteppe/cannon.js”

I am going to make a demo. or probably a good screenshot to illustrate what I mean with the different behaviours

1 Like

Ok, so,
first is cannon from preview.babylonjs, accessible as window.CANNON
second is cannon from github:schteppe/cannon.js accessible in module scope as Cannon

As you can see the grid bounces down differently.
All the rest of the code is the same… so any difference in behaviour must come for the cannonjs file…

This is the change I injected into cannon 3 years ago:

The world step is a bit different as there was an issue when using interpolation. This might have been fixed since then, but i honestly haven’t tested it. Try setting CANNON.World.prototype.step with Cannon.World.prototype.step and i can only assume it will act the same (we havent made changed to cannon.js at all)

Hi @RaananW,

Sorry I didn’t try that because I have been facing a series of problems.
Actually, I have so many issues that I don’t really even know where to begin. I have tried a bunch of things and pretty much nothing works.

Let’s start with the classic example https://playground.babylonjs.com/#66PS52#31
If Ammo is replaced with Cannon the weirdShape bounces off an apparently invisible object before touching the ground, then sinks into the ground.
image

The weirdShape is initially set to (0?) - .9, then the position is overriden to +3.
image
That’s weird, would it not be the same setting it at 2.1 once?
Well, it’s not https://playground.babylonjs.com/#66PS52#32
To make it even more evident I have set the initial position to -= 10
https://playground.babylonjs.com/#66PS52#34
What on Earth is going on there?

I have then replaced the weirdShape with a shape I made. A torus with 4 bars in grid form so to act as colliders.
https://playground.babylonjs.com/#66PS52#35
Sometimes the ring will pass through the ground, sometimes not.
With Cannon, the ring will go through the ground and then swing, hanging from some unknown point, which is not a collider.
https://playground.babylonjs.com/#66PS52#36
image

I have tried many more things, with additional elements but the results are even weirder than those.
My feeling is that physics just doesn’t work in Babylon. I am looking for a framework to build a complex scene with physics and even trying to implement these simple proofs of concept to build upon are proving incredibly frustrating. I just don’t understand what is going on there.

PLEASE prove me wrong! :smiley:

Hey!

So! A few things:

Well, you are setting the objects with physics impostors to be invisible. If you do that, this is what you get :slight_smile:

Your condition for the invisible objects is: m.name.indexOf("box") != -1, and those are the ones you set to have a physics impostor later.

Having said that, there is another issue - the method addChild is working differently than setting the object’s parent. It also applies its transformation to the object, which, in your case, is not wanted. Setting the parent using m.parent instead of physicsRoot.addChild will solve the other problem.

There seems to be an issue with the way we are dealing with local vs. global transformation of child objects, which I will have to check.

image

You are setting the initial position to -10, and then setting it again to be = 2.1. So… works as expected :slight_smile:

Here is a working example (both cannon and ammo works correctly).

https://playground.babylonjs.com/#66PS52#37

I will need to check where exactly we are taking local position vs. global position with the Ammo plugin, but in general it seems to be working as expected. Unless I totally missed something?

1 Like

Sorry, never answered about the ring. I am checking this now, will get back to you asap

1 Like

So, about the ring - It seems like some physics engines don’t like small values :slight_smile:

I agree that it is weird that ammo sometimes throw the object down as if the ground doesn’t exist. might be also the minimum thickness of the box impostor (that is applied to the ground), I will have to check that as well.

The scaling is the one making cannon go a bit berserk, but with scaling 1 both engines work as expected:

https://playground.babylonjs.com/#66PS52#38

That’s a bit far fetched, especially since many users release physics-scenes all the time. There might be issues, which we keep on fixing (and are always happy to fix and thankful for those who report them).

Again, I am not saying everything is perfect. If something is not working as expected, we are more than happy to solve it.

1 Like

Hi @RaananW,

First off, thanks a lot for getting back to me, and for spending the time to investigate the issues I raised. Very much appreciated!
Also let me apologise for my statement about physics not working, it was in no way meant to sound harsh. I was a bit frustrated after having spent quite a lot of time trying again and again and getting pretty much nowhere.

Now, regarding your points,

Bear in mind that all I did there was to take the example referenced in documentation image and change the physics engine from Ammo to Cannon.

Also, I see what you mean about impostors to be invisible and not seeing the point of contact between the two surfaces :smiley:, but what I mean is more drastic than that.
If I take your working example and just change the camera angle https://playground.babylonjs.com/#66PS52#39 you will see that it really bounces off way before it gets in contact with the ground. That doesn’t happen with Ammo.

That’s a fair point, I will look it up and play around with it to grasp the difference with transform hierarchy.

True, but I am doing that before returning the scene. So I thought that once scene is returned the last value set in physicsRoot.position wins. Unless position values somehow cumulate (I will look into it) I am still confused about it.

I think I might understand what is going on there. It should have to do with when the physics calculation is executed and where the colliders in the ring and the ground happen to be in that moment. If I decrease gravity, using -1 instead of -10 as the Y component (so objects move slower between one frame and the other) then the ring never passes through. Also, as you said, the thickness of the colliders may have to do with that too.

With Cannon https://playground.babylonjs.com/#66PS52#40 the ring flips over once before touching the ground. I would not expect that! :smiley:
That is actually something I noticed, and that I have no idea why it happens, sometimes with Cannon, objects in free fall seem to be affected by some torque (might be wrong) that should reasonably not be there…

That’s a great attitude. Fully appreciated and says a lot about the framework in general. Thank you!

2 Likes

:+1:

Seems to be related to the transforming (scaling, positioning) the parent root prior to constructing the physics impostor. If eliminating the transformation on the root node:

https://playground.babylonjs.com/#66PS52#42

(I added a rotation to the ground, just in case you are wondering)

I will add that as an issue. Compound with transformation should still be working correctly.

Yeah! I noticed that as well. I am not sure if this is a bug in cannon or with us, but I found that setting the ground’s position to anything other than 0 will work wonders on the rotating ring (well, will make it not rotate):

https://playground.babylonjs.com/#66PS52#43

At the beginning i thought it was related to the objects being initialized at position 0 together with the ground, but it works even when setting the ground’s position to be 0.1, so i doubt this is the case. I will investigate into that, but can’t promise a fix

So, let’s call it a “feature” :slight_smile: . Cannon’s beforeStep event, which we use to execute our own before-step process (which copies the object’s position to the impostor’s position) is executed after the impostor’s velocity is calculate (by cannon).

When initializing the impostor, a position already set is copied to the initializing impostor. So if you set the mesh’s position before creating the impostor, it works. But after the impostor is set, the next time the position is copied from the mesh to the impostor is in next frame’s beforeStep, which is executed after the velocity was calculated.

A solution to that is to execute babylon’s beforeStep loop before executing the physics step, but then cannon’s preStep event won’t be registered in the framework, which is the reason we did it in the first place. I agree that it is weird thou. I will ask the team internally what they think about changing it.

1 Like

Hey @RaananW,

Sorry for the late reply. Thanks a lot once again for your insight!
Yes that does indeed make sense! :+1:

So I believe that the flipping effect on the ring when ground is 0 is due to velocity being calculated with ring impostor at 0, before beforeStep can update the impostor to have the same position as the mesh position (which in the code is set after the physicsImpostor is initialized).
I had the feeling that the ring would appear with a torque that is the result of the ring “bouncing off” the ground, and you explanation I think that confirms that.

I tried

  • setting position before impostor :heavy_check_mark:
    image
  • On formed physicsRoot, removing the impostor, changing position, setting the impostor again :heavy_check_mark:
    image
  • set the ground physicsImpostor with delay :heavy_check_mark:
    image

All of the above work fine

Only thing which doesn’t work is first setting the position on the physicsRoot, add children and impostors on children, then add impostor on physicsRoot. Not sure why but I can live with that.

Other thing that works is also setting position on physicsImpostor.physicsBody
image

All in all, your explanation about communication between babylon and cannon via bound beforeStep event makes loads of sense.

Thank you again for your time and for you kind support!

1 Like