Sphere collider for intersection trigger?

I’m using ActionManager.OnIntersectionEnterTrigger to get notified when two balloons collide. However, it seems that Babylon uses a box collider by default. Which causes intersection to trigger when in fact the two balloons didn’t even touch each other (but their “edges” did).

Is there an easy way to use a sphere collider instead, without having to write a lot of code?
I mean, I’m already using CreateSphere() to create my balloons, so Babylon actually knows it’s a sphere - not sure why it attaches a box collider to a sphere… I’ve also tried usePreciseIntersection: true;, but it doesn’t make any difference.

cc @Cedric

I do not think there is an easy way to change it :frowning: the only difference between precise or not here is AAB B or OBB (axis aligned vs oriented bounding boxes) I added Cedric to know if there was another mode which I do not think so.

I’ve never used ActionManager. But looking at the code, it seems intersection test filters with bounding sphere :

Is your bounding sphere too big so it doesn’t fit exactly the balloons?

I don’t have a bounding sphere - at least not one that I’ve created myself. I only used CreateSphere(). I don’t know what Babylon does with that under the hood. But from a theoretical perspective, it makes total sense that Babylon thinks the two balloons touched when it uses boxes instead of spheres - see screenshot.

From a Babylon-consumer’s perspective, it’d be nice if Babylon automatically uses spheres instead of boxes to detect intersection (or collisions) when using CreateSphere().

Bildschirmfoto 2023-03-28 um 14.00.31

the bounding sphere is computed from bounding x,y,z min/ax. it means bounding sphere will be bigger that the sphere you’ve created

If you want to check spheres only, you can compute the distance between both positions and check its value is < radius1 + radius2. It’s a one line check: very fast and easy.

I don’t think the bounding sphere is bigger, because when the balloons touch at the exact center, the collision happens correctly. If they were bigger, it’d happen before they touch, right?

Bildschirmfoto 2023-03-28 um 14.00.31

Ok but judging from the code, it was at least intended to work with bounding spheres. Question remains why it isn’t applied.

@Cedric where exactly would you apply your distance calculation? In onBeforeRenderObservable()? Also you’ve said you’re not using ActionManager. What do you use instead and why? Sorry I’m new.

bsphere is used to filter. if bsphere do not intersect, then no need to check with bbox.
Yes, I would try in onBeforeRenderObservable .ActionManager has a feature set. if it doesn’t do what you need, then try to find another solution :slight_smile:

1 Like

Shouldn’t it be the other way around? If box doesn’t intersect, then no need to check with sphere?

sphere check is faster than box check. so, filter first with fast method then use finer/more costly algorithms.

At first i supposed what happens is sphere doesn’t intersect, so it continue to check box, which does intersect.

But now checking in a simple PG, a 1 diameter sphere mesh have a boundingSphere radius of 0.86 ? aka diameter of 1.72…

{
“center”: {
“_isDirty”: true,
“_x”: 0,
“_y”: 0,
“_z”: 0
},
“centerWorld”: {
“_isDirty”: true,
“_x”: 0,
“_y”: 1,
“_z”: 0
},
“minimum”: {
“_isDirty”: true,
“_x”: -0.5,
“_y”: -0.5,
“_z”: -0.5
},
“maximum”: {
“_isDirty”: true,
“_x”: 0.5,
“_y”: 0.5,
“_z”: 0.5
},
“radius”: 0.8660254037844386,
“radiusWorld”: 0.8660254037844386
}

How that makes sense, i don’t know :slight_smile: same result in babylonjs 4.2.1

Edit;
Ok the intersect code is a bit confusing setup for performance reasons, i suppose it’s that big to fit the boundingBox corners rather than the actual mesh, since sphere is checked first and ends the function if no intersection is found.
Using your image, spheres look like this.
ad7ee4568a88da318a7f571039b59788f087f7f0

A custom distance check (since your meshes are always round i assume) would be the best solution for sure :slight_smile:

a sphere of radius 1 fit in a box that has min/max of (-1,-1,-1) to (1,1,1). Then the bounding sphere is computed from that bbox. and sqrt(11 + 11 + 1*1) = sqrt(3) = 1.732050…

2 Likes

@aWeirdo I don‘t think so, see my 2nd image above where the spheres collide correctly (a.k.a. „on touch“).

Okay, time for a PG that clearly demonstrates the issue:

This is because the boundingSphere check is a fast but inaccurate check to see if the meshes are even within range of each other.

it does not decide if the meshes collide, just if the function should continue with a more expensive collision check (boundingBox), this is why the spheres can be next to each other without colliding, but still collide on boundingBox corners.

Here’s an example using a distance check and the spheres actual radii

Remove BABYLON.Engine.CollisionsEpsilon from line #27 if you want collision on touch rather than a slight overlap (BABYLON.Engine.CollisionsEpsilon is 0.001 unit, just be aware of js floating point errors)